From 7f0ea2d9ae459ba9ac830abfecda2778c30e45da Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 3 Aug 2021 11:28:18 +0200 Subject: [PATCH 01/16] new test for trade document --- tests/test_documents.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/tests/test_documents.py b/tests/test_documents.py index 1f89d96b..d8bf8a96 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -33,14 +33,16 @@ def test_erasure_certificate_public_one(user: UserClient, client: Client): snapshot, _ = user.post(s, res=Snapshot) doc, response = user.get(res=documents.DocumentDef.t, - item='erasures/{}'.format(snapshot['device']['id']), - accept=ANY) + item='erasures/{}'.format( + snapshot['device']['id']), + accept=ANY) assert 'html' in response.content_type assert ' Date: Tue, 3 Aug 2021 13:08:03 +0200 Subject: [PATCH 02/16] test --- tests/test_documents.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/tests/test_documents.py b/tests/test_documents.py index d8bf8a96..6cc77e38 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -16,6 +16,7 @@ from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.resources.user.models import Session from ereuse_devicehub.resources.action.models import Snapshot, Allocate, Live from ereuse_devicehub.resources.documents import documents +from ereuse_devicehub.resources.tradedocument.definitions import TradeDocumentDef from ereuse_devicehub.resources.device import models as d from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.tag.model import Tag @@ -679,19 +680,6 @@ def test_get_wbconf(user: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_trade_documents(user: UserClient): - """Tests for get env file for usb wb.""" + """Tests upload one document""" - env, _ = user.get(res=documents.DocumentDef.t, item='wbconf/usodyrate', accept=ANY) - assert 'WB_ERASE =' in env - - env, _ = user.get(res=documents.DocumentDef.t, item='wbconf/usodywipe', accept=ANY) - assert 'WB_ERASE =' in env - # assert 'WB_ERASE = True' in env - - session = Session.query.filter_by(user_id=user.user['id'], - type=SessionType.Internal).first() - token = session.token - token = auth.Auth.encode(session.token) - assert token in env - user.user['token'] = token - snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) + doc, _ = user.post(res=TradeDocumentDef.t, item='wbconf/usodyrate', accept=ANY) From 9b2936c7951a4a122ca744a79d49f97c25180681 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 3 Aug 2021 16:40:17 +0200 Subject: [PATCH 03/16] adding weight to trade documents --- ...c1897ce_adding_weight_to_tradedocuments.py | 31 ++++++++++++++++++ .../resources/tradedocument/models.py | 2 ++ .../resources/tradedocument/schemas.py | 3 +- tests/test_documents.py | 32 +++++++++++++++++-- 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py diff --git a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py new file mode 100644 index 00000000..bb5d4b6f --- /dev/null +++ b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py @@ -0,0 +1,31 @@ +"""adding weight to tradedocuments + +Revision ID: 3ac2bc1897ce +Revises: 3a3601ac8224 +Create Date: 2021-08-03 16:28:38.719686 + +""" +from alembic import op +import sqlalchemy as sa +from alembic import context + + +# revision identifiers, used by Alembic. +revision = '3ac2bc1897ce' +down_revision = '0103a9c96b2d' +branch_labels = None +depends_on = None + + +def get_inv(): + INV = context.get_x_argument(as_dictionary=True).get('inventory') + if not INV: + raise ValueError("Inventory value is not specified") + return INV + +def upgrade(): + op.add_column("trade_document", sa.Column("weight", sa.Float(decimal_return_scale=2), nullable=True), schema=f'{get_inv()}') + + +def downgrade(): + op.drop_column('trade_document', 'weight', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/resources/tradedocument/models.py b/ereuse_devicehub/resources/tradedocument/models.py index 9c743244..e1326613 100644 --- a/ereuse_devicehub/resources/tradedocument/models.py +++ b/ereuse_devicehub/resources/tradedocument/models.py @@ -71,6 +71,8 @@ class TradeDocument(Thing): file_hash.comment = """This is the hash of the file produced from frontend.""" url = db.Column(URL()) url.comment = """This is the url where resides the document.""" + weight = db.Column(db.Float(nullable=True)) + weight.comment = """This is the weight of one container than this document express.""" __table_args__ = ( db.Index('document_id', id, postgresql_using='hash'), diff --git a/ereuse_devicehub/resources/tradedocument/schemas.py b/ereuse_devicehub/resources/tradedocument/schemas.py index fab95dc4..cfa74637 100644 --- a/ereuse_devicehub/resources/tradedocument/schemas.py +++ b/ereuse_devicehub/resources/tradedocument/schemas.py @@ -1,4 +1,4 @@ -from marshmallow.fields import DateTime, Integer, validate +from marshmallow.fields import DateTime, Integer, Float, validate from teal.marshmallow import SanitizedStr, URL # from marshmallow import ValidationError, validates_schema @@ -29,3 +29,4 @@ class TradeDocument(Thing): url = URL(description=m.TradeDocument.url.comment) lot = NestedOn('Lot', only_query='id', description=m.TradeDocument.lot.__doc__) trading = SanitizedStr(dump_only=True, description='') + weight = Float(required=False, description=m.TradeDocument.weight.comment) diff --git a/tests/test_documents.py b/tests/test_documents.py index 6cc77e38..b227f280 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -16,7 +16,7 @@ from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.resources.user.models import Session from ereuse_devicehub.resources.action.models import Snapshot, Allocate, Live from ereuse_devicehub.resources.documents import documents -from ereuse_devicehub.resources.tradedocument.definitions import TradeDocumentDef +from ereuse_devicehub.resources.tradedocument.models import TradeDocument from ereuse_devicehub.resources.device import models as d from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.tag.model import Tag @@ -682,4 +682,32 @@ def test_get_wbconf(user: UserClient): def test_trade_documents(user: UserClient): """Tests upload one document""" - doc, _ = user.post(res=TradeDocumentDef.t, item='wbconf/usodyrate', accept=ANY) + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + request_post = { + 'filename': 'test.pdf', + 'hash': 'bbbbbbbb', + 'url': 'http://www.ereuse.org/', + 'lot': lot['id'] + } + doc, _ = user.post(res=TradeDocument, data=request_post) + assert doc['filename'] == request_post['filename'] + assert doc['url'] == request_post['url'] + assert doc['hash'] == request_post['hash'] + assert doc['lot']['name'] == lot['name'] + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_trade_documents_with_weight(user: UserClient): + """Tests upload one document""" + + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + request_post = { + 'filename': 'test.pdf', + 'hash': 'bbbbbbbb', + 'url': 'http://www.ereuse.org/', + 'weight': 15, + 'lot': lot['id'] + } + doc, _ = user.post(res=TradeDocument, data=request_post) + assert doc['weight'] == request_post['weight'] From f1220dd75639eef903936c162c3aa740e13c2422 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 10 Aug 2021 12:45:03 +0200 Subject: [PATCH 04/16] new Recycling document --- ...c1897ce_adding_weight_to_tradedocuments.py | 2 +- .../resources/action/views/documents.py | 8 ++-- .../resources/documents/documents.py | 26 +++++++++++++ .../resources/documents/models.py | 38 +++++++++++++++++-- .../resources/documents/schemas.py | 31 ++++++++++++++- .../resources/tradedocument/models.py | 1 - tests/test_documents.py | 30 ++++++++++++++- 7 files changed, 124 insertions(+), 12 deletions(-) diff --git a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py index bb5d4b6f..38fa9b69 100644 --- a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py +++ b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py @@ -12,7 +12,7 @@ from alembic import context # revision identifiers, used by Alembic. revision = '3ac2bc1897ce' -down_revision = '0103a9c96b2d' +down_revision = '7ecb8ff7abad' branch_labels = None depends_on = None diff --git a/ereuse_devicehub/resources/action/views/documents.py b/ereuse_devicehub/resources/action/views/documents.py index 3f3aaa84..4224f69f 100644 --- a/ereuse_devicehub/resources/action/views/documents.py +++ b/ereuse_devicehub/resources/action/views/documents.py @@ -3,7 +3,7 @@ import copy from ereuse_devicehub.db import db from ereuse_devicehub.resources.action.models import DataWipe from ereuse_devicehub.resources.documents.models import DataWipeDocument -from ereuse_devicehub.resources.device.models import DataStorage +from ereuse_devicehub.resources.device.models import DataStorage from ereuse_devicehub.resources.documents.schemas import DataWipeDocument as sh_document from ereuse_devicehub.resources.hash_reports import ReportHash @@ -29,17 +29,17 @@ class ErasedView(): schema = sh_document() [data.pop(x, None) for x in ['severity', 'devices', 'name', 'description']] doc_data = schema.load(data) - doc_data['type'] = 'DataWipe' + # doc_data['type'] = 'DataWipe' self.document = DataWipeDocument(**doc_data) db.session.add(self.document) - + db_hash = ReportHash(hash3=self.document.file_hash) db.session.add(db_hash) def insert_action(self, data): [data.pop(x, None) for x in ['url', 'documentId', 'filename', 'hash', 'software', 'success']] self.data = self.schema.load(data) - + for dev in self.data['devices']: if not hasattr(dev, 'components'): continue diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index f45cf808..079d763d 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -283,6 +283,28 @@ class StampsView(View): result=result) +class RecycleDocumentView(View): + """ + This view allow save one document as a proof of one container with some weight was send to recycling. + """ + + def post(self): + from flask import jsonify + from ereuse_devicehub.resources.documents.models import RecycleDocument + from ereuse_devicehub.resources.documents.schemas import RecycleDocument as sh_document + data = request.get_data() + schema = sh_document() + doc = schema.loads(data) + document = RecycleDocument(**doc) + db.session.add(document) + + db.session().final_flush() + ret = jsonify(document) + ret.status_code = 201 + db.session.commit() + return ret + + class InternalStatsView(DeviceView): @cache(datetime.timedelta(minutes=1)) def find(self, args: dict): @@ -428,3 +450,7 @@ class DocumentDef(Resource): auth=app.auth) wbconf_view = app.auth.requires_auth(wbconf_view) self.add_url_rule('/wbconf/', view_func=wbconf_view, methods=get) + + recycle_doc_view = RecycleDocumentView.as_view('RecycleDocumentView', definition=self, auth=app.auth) + self.add_url_rule('/recycle/', defaults={}, view_func=recycle_doc_view, methods={'POST'}) + diff --git a/ereuse_devicehub/resources/documents/models.py b/ereuse_devicehub/resources/documents/models.py index ee2ac071..bf2ae1a5 100644 --- a/ereuse_devicehub/resources/documents/models.py +++ b/ereuse_devicehub/resources/documents/models.py @@ -1,14 +1,23 @@ -from citext import CIText from flask import g +from citext import CIText +from sortedcontainers import SortedSet from sqlalchemy import BigInteger, Column, Sequence, Unicode, Boolean, ForeignKey from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.dialects.postgresql import UUID -from teal.db import URL +from sqlalchemy.orm import backref +from teal.db import CASCADE_OWN, URL + from ereuse_devicehub.db import db from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.resources.models import Thing, STR_SM_SIZE +_sorted_documents = { + 'order_by': lambda: Document.created, + 'collection_class': SortedSet +} + + class Document(Thing): """This represent a generic document.""" @@ -16,7 +25,7 @@ class Document(Thing): id.comment = """The identifier of the device for this database. Used only internally for software; users should not use this. """ - type = Column(Unicode(STR_SM_SIZE), nullable=False) + document_type = Column(Unicode(STR_SM_SIZE), nullable=False) date = Column(db.DateTime, nullable=True) date.comment = """The date of document, some documents need to have one date """ @@ -55,3 +64,26 @@ class DataWipeDocument(JoinedTableMixin, Document): def __str__(self) -> str: return '{0.file_name}'.format(self) + + +from ereuse_devicehub.resources.tradedocument.models import TradeDocument +class RecycleDocument(JoinedTableMixin, Document): + """Document than proof how any of weight go to recycling.""" + + weight = db.Column(db.Float(nullable=True)) + weight.comment = """Weight than go to recycling""" + trade_document_id = db.Column(db.BigInteger, db.ForeignKey(TradeDocument.id)) + trade_document_id.comment = """This is the trade document used for send material to recyle""" + lot_id = db.Column(UUID(as_uuid=True), + db.ForeignKey('lot.id'), + nullable=False) + lot_id.comment = """This lot is the input lot if the material that will then go definitively to recycling""" + lot = db.relationship('Lot', + backref=backref('recycling_documents', + lazy=True, + cascade=CASCADE_OWN, + **_sorted_documents), + primaryjoin='RecycleDocument.lot_id == Lot.id') + + def __str__(self) -> str: + return '{0.file_name}'.format(self) diff --git a/ereuse_devicehub/resources/documents/schemas.py b/ereuse_devicehub/resources/documents/schemas.py index c9df245f..4ead41f0 100644 --- a/ereuse_devicehub/resources/documents/schemas.py +++ b/ereuse_devicehub/resources/documents/schemas.py @@ -1,13 +1,16 @@ -from marshmallow.fields import DateTime, Integer, validate, Boolean +from marshmallow.fields import DateTime, Integer, validate, Boolean, Float +from marshmallow import post_load +from marshmallow.validate import Range from teal.marshmallow import SanitizedStr, URL +from ereuse_devicehub.marshmallow import NestedOn from ereuse_devicehub.resources.schemas import Thing +from ereuse_devicehub.resources.tradedocument.models import TradeDocument from ereuse_devicehub.resources.documents import models as m class DataWipeDocument(Thing): __doc__ = m.DataWipeDocument.__doc__ id = Integer(description=m.DataWipeDocument.id.comment, dump_only=True) - type = SanitizedStr(default='DataWipeDocument') url = URL(required= False, description=m.DataWipeDocument.url.comment) success = Boolean(required=False, default=False, description=m.DataWipeDocument.success.comment) software = SanitizedStr(description=m.DataWipeDocument.software.comment) @@ -26,3 +29,27 @@ class DataWipeDocument(Thing): default='', description=m.DataWipeDocument.file_hash.comment, validate=validate.Length(max=64)) + + @post_load + def get_trade_document(self, data): + data['document_type'] = 'DataWipeDocument' + + +class RecycleDocument(Thing): + __doc__ = m.DataWipeDocument.__doc__ + file_hash = SanitizedStr(data_key='hash', + default='', + description=m.RecycleDocument.file_hash.comment, + validate=validate.Length(max=64)) + weight = Float(required=False, validate=Range(0.1), description=m.RecycleDocument.weight.comment) + lot = NestedOn('Lot', only_query='id', description=m.RecycleDocument.lot.__doc__) + + @post_load + def get_trade_document(self, data): + tradedocument = TradeDocument.query.filter_by(file_hash=data['file_hash']).one() + data['trade_document_id'] = tradedocument.id + data['file_name'] = tradedocument.file_name + data['date'] = tradedocument.date + data['id_document'] = tradedocument.id_document + data['url'] = tradedocument.url + data['document_type'] = 'RecycleDocument' diff --git a/ereuse_devicehub/resources/tradedocument/models.py b/ereuse_devicehub/resources/tradedocument/models.py index e1326613..354fbb4d 100644 --- a/ereuse_devicehub/resources/tradedocument/models.py +++ b/ereuse_devicehub/resources/tradedocument/models.py @@ -1,4 +1,3 @@ -import copy from citext import CIText from flask import g diff --git a/tests/test_documents.py b/tests/test_documents.py index 9f80b5ea..9ed874b2 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -705,12 +705,40 @@ def test_trade_documents_with_weight(user: UserClient): """Tests upload one document""" lot, _ = user.post({'name': 'MyLot'}, res=Lot) + # long url + url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa', request_post = { 'filename': 'test.pdf', 'hash': 'bbbbbbbb', - 'url': 'http://www.ereuse.org/', + 'url': url, 'weight': 15, 'lot': lot['id'] } doc, _ = user.post(res=TradeDocument, data=request_post) assert doc['weight'] == request_post['weight'] + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_recycle_document(user: UserClient): + """Tests upload one document""" + + lotIn, _ = user.post({'name': 'MyLotIn'}, res=Lot) + lotOut, _ = user.post({'name': 'MyLotOut'}, res=Lot) + url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa', + request_post = { + 'filename': 'test.pdf', + 'hash': 'bbbbbbbb', + 'url': url, + 'weight': 15, + 'lot': lotOut['id'] + } + tradedocument, _ = user.post(res=TradeDocument, data=request_post) + # import pdb; pdb.set_trace() + request_post2 = { + 'weight': 15, + 'hash': tradedocument['hash'], + 'lot': lotIn['id'] + } + doc, _ = user.post(res=documents.DocumentDef.t, item='recycle/', data=request_post2) + assert doc == request_post['filename'] From e82358d5dce4fb9172eb49ec0eaf0bc1cb884baa Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 10 Aug 2021 13:21:39 +0200 Subject: [PATCH 05/16] fixing basic test --- tests/test_basic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_basic.py b/tests/test_basic.py index c04e8fb6..ac7537a8 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -43,6 +43,7 @@ def test_api_docs(client: Client): '/documents/wbconf/{wbtype}', '/documents/internalstats/', '/documents/stock/', + '/documents/recycle/', '/documents/check/', '/documents/lots/', '/versions/', From 5799be2a3a7144a2bcf41fb599df6e0419e9d187 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 10 Aug 2021 13:56:33 +0200 Subject: [PATCH 06/16] fixing foreingkey --- ereuse_devicehub/resources/documents/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ereuse_devicehub/resources/documents/models.py b/ereuse_devicehub/resources/documents/models.py index bf2ae1a5..3deb9784 100644 --- a/ereuse_devicehub/resources/documents/models.py +++ b/ereuse_devicehub/resources/documents/models.py @@ -66,13 +66,13 @@ class DataWipeDocument(JoinedTableMixin, Document): return '{0.file_name}'.format(self) -from ereuse_devicehub.resources.tradedocument.models import TradeDocument + class RecycleDocument(JoinedTableMixin, Document): """Document than proof how any of weight go to recycling.""" weight = db.Column(db.Float(nullable=True)) weight.comment = """Weight than go to recycling""" - trade_document_id = db.Column(db.BigInteger, db.ForeignKey(TradeDocument.id)) + trade_document_id = db.Column(db.BigInteger, db.ForeignKey('trade_document.id')) trade_document_id.comment = """This is the trade document used for send material to recyle""" lot_id = db.Column(UUID(as_uuid=True), db.ForeignKey('lot.id'), From b56e9b106f676b12e00e6ebfa75c353e2ceb50e9 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 10 Aug 2021 13:57:18 +0200 Subject: [PATCH 07/16] adding migration for recycle document model --- ...c1897ce_adding_weight_to_tradedocuments.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py index 38fa9b69..6e259684 100644 --- a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py +++ b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py @@ -8,6 +8,7 @@ Create Date: 2021-08-03 16:28:38.719686 from alembic import op import sqlalchemy as sa from alembic import context +from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. @@ -26,6 +27,24 @@ def get_inv(): def upgrade(): op.add_column("trade_document", sa.Column("weight", sa.Float(decimal_return_scale=2), nullable=True), schema=f'{get_inv()}') + # DataWipeDocument table + op.create_table('recycle_document', + sa.Column('id', sa.BigInteger(), nullable=False), + sa.Column('trade_document_id', sa.BigInteger(), nullable=False), + sa.Column( + 'lot_id', + postgresql.UUID(as_uuid=True), + nullable=False + ), + sa.Column("weight", sa.Float(decimal_return_scale=2), nullable=True), + sa.ForeignKeyConstraint(['lot_id'], [f'{get_inv()}.lot.id'],), + sa.ForeignKeyConstraint(['trade_document_id'], [f'{get_inv()}.trade_document.id'], ), + sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.document.id'], ), + sa.PrimaryKeyConstraint('id'), + schema=f'{get_inv()}' + ) + def downgrade(): op.drop_column('trade_document', 'weight', schema=f'{get_inv()}') + op.drop_table('recycle_document', schema=f'{get_inv()}') From de727f264551dcb744416c333d323ebb12fd9f80 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 11 Aug 2021 13:40:37 +0200 Subject: [PATCH 08/16] pdbs --- ereuse_devicehub/resources/documents/documents.py | 6 +++--- ereuse_devicehub/resources/documents/schemas.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 079d763d..c8507098 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -33,6 +33,8 @@ from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash +from ereuse_devicehub.resources.documents.models import RecycleDocument +from ereuse_devicehub.resources.documents.schemas import RecycleDocument as sh_document class Format(enum.Enum): @@ -289,9 +291,7 @@ class RecycleDocumentView(View): """ def post(self): - from flask import jsonify - from ereuse_devicehub.resources.documents.models import RecycleDocument - from ereuse_devicehub.resources.documents.schemas import RecycleDocument as sh_document + # import pdb; pdb.set_trace() data = request.get_data() schema = sh_document() doc = schema.loads(data) diff --git a/ereuse_devicehub/resources/documents/schemas.py b/ereuse_devicehub/resources/documents/schemas.py index 4ead41f0..66bc2f20 100644 --- a/ereuse_devicehub/resources/documents/schemas.py +++ b/ereuse_devicehub/resources/documents/schemas.py @@ -36,7 +36,7 @@ class DataWipeDocument(Thing): class RecycleDocument(Thing): - __doc__ = m.DataWipeDocument.__doc__ + __doc__ = m.RecycleDocument.__doc__ file_hash = SanitizedStr(data_key='hash', default='', description=m.RecycleDocument.file_hash.comment, From 1aaf0a9ae7edb0d6efc2746b69e6fb2be6662b43 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 3 Sep 2021 16:05:55 +0200 Subject: [PATCH 09/16] build tests for moveon --- tests/test_action.py | 46 +++++++++++++++++++++++++++++++++++++++++ tests/test_documents.py | 46 ++++++++++++++++++++--------------------- 2 files changed, 69 insertions(+), 23 deletions(-) diff --git a/tests/test_action.py b/tests/test_action.py index 03868c3c..7de78e3b 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -28,6 +28,7 @@ from ereuse_devicehub.resources.action import models from ereuse_devicehub.resources.device import states from ereuse_devicehub.resources.device.models import Desktop, Device, GraphicCard, HardDrive, \ RamModule, SolidStateDrive +from ereuse_devicehub.resources.tradedocument.models import TradeDocument from ereuse_devicehub.resources.enums import ComputerChassis, Severity, TestDataStorageLength from tests import conftest from tests.conftest import create_user, file, yaml2json, json_encode @@ -2438,3 +2439,48 @@ def test_action_web_erase(user: UserClient, client: Client): assert "alert alert-info" in response assert "100% coincidence." in response assert not "alert alert-danger" in response + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_moveonContainer(user: UserClient, user2: UserClient): + lotIn, _ = user.post({'name': 'MyLotIn'}, res=Lot) + lotOut, _ = user.post({'name': 'MyLotOut'}, res=Lot) + url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa', + request_post1 = { + 'filename': 'test.pdf', + 'hash': 'bbbbbbbb', + 'url': url, + 'weight': 150, + 'lot': lotIn['id'] + } + tradedocument_from, _ = user.post(res=TradeDocument, data=request_post1) + request_post2 = { + 'filename': 'test.pdf', + 'hash': 'bbbbbbbb', + 'url': url, + 'weight': 0, + 'lot': lotOut['id'] + } + tradedocument_to, _ = user.post(res=TradeDocument, data=request_post2) + + request_trade = { + 'type': 'Trade', + 'devices': [], + 'userFromEmail': user2.email, + 'userToEmail': user.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'lot': lotIn['id'], + 'confirms': True, + } + + user.post(res=models.Action, data=request_trade) + + request_moveOn = { + 'weight': 15, + 'container_from': tradedocument_from['id'], + 'container_to': tradedocument_to['id'] + } + import pdb; pdb.set_trace() + doc, _ = user.post(res=models.Action, data=request_moveOn) diff --git a/tests/test_documents.py b/tests/test_documents.py index 9ed874b2..043ebaa5 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -718,27 +718,27 @@ def test_trade_documents_with_weight(user: UserClient): assert doc['weight'] == request_post['weight'] -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.app_context.__name__) -def test_recycle_document(user: UserClient): - """Tests upload one document""" +# @pytest.mark.mvp +# @pytest.mark.usefixtures(conftest.app_context.__name__) +# def test_recycle_document(user: UserClient): +# """Tests upload one document""" - lotIn, _ = user.post({'name': 'MyLotIn'}, res=Lot) - lotOut, _ = user.post({'name': 'MyLotOut'}, res=Lot) - url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa', - request_post = { - 'filename': 'test.pdf', - 'hash': 'bbbbbbbb', - 'url': url, - 'weight': 15, - 'lot': lotOut['id'] - } - tradedocument, _ = user.post(res=TradeDocument, data=request_post) - # import pdb; pdb.set_trace() - request_post2 = { - 'weight': 15, - 'hash': tradedocument['hash'], - 'lot': lotIn['id'] - } - doc, _ = user.post(res=documents.DocumentDef.t, item='recycle/', data=request_post2) - assert doc == request_post['filename'] +# lotIn, _ = user.post({'name': 'MyLotIn'}, res=Lot) +# lotOut, _ = user.post({'name': 'MyLotOut'}, res=Lot) +# url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa', +# request_post = { +# 'filename': 'test.pdf', +# 'hash': 'bbbbbbbb', +# 'url': url, +# 'weight': 15, +# 'lot': lotOut['id'] +# } +# tradedocument, _ = user.post(res=TradeDocument, data=request_post) +# # import pdb; pdb.set_trace() +# request_post2 = { +# 'weight': 15, +# 'hash': tradedocument['hash'], +# 'lot': lotIn['id'] +# } +# doc, _ = user.post(res=documents.DocumentDef.t, item='recycle/', data=request_post2) +# assert doc == request_post['filename'] From 0d73bb1f630058eb5281c0db45f4451adc84591e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 3 Sep 2021 16:06:53 +0200 Subject: [PATCH 10/16] Build action moveOn --- ...c1897ce_adding_weight_to_tradedocuments.py | 1 + ereuse_devicehub/resources/action/models.py | 38 +++++++++++++++++ .../resources/documents/documents.py | 41 +++++++++---------- .../resources/documents/models.py | 23 ----------- .../resources/documents/schemas.py | 34 +++++++-------- 5 files changed, 76 insertions(+), 61 deletions(-) diff --git a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py index 6e259684..9be818e1 100644 --- a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py +++ b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py @@ -24,6 +24,7 @@ def get_inv(): raise ValueError("Inventory value is not specified") return INV + def upgrade(): op.add_column("trade_document", sa.Column("weight", sa.Float(decimal_return_scale=2), nullable=True), schema=f'{get_inv()}') diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index fdbdf1fa..16098ead 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -62,6 +62,15 @@ _sorted_actions = { 'order_by': lambda: Action.end_time, 'collection_class': SortedSet } + + +def sorted_actions_by(data): + return { + 'order_by': lambda: data, + 'collection_class': SortedSet + } + + """For db.backref, return the actions sorted by end_time.""" @@ -1642,6 +1651,35 @@ class MakeAvailable(ActionWithMultipleDevices): pass +class MoveOnContainer(JoinedTableMixin, ActionWithMultipleTradeDocuments): + """Action than certify one movement of some indescriptible material of + one container to an other.""" + + weight = db.Column(db.Float(nullable=True)) + weight.comment = """Weight than go to recycling""" + container_from_id = db.Column( + db.BigInteger, + db.ForeignKey('trade_document.id'), + nullable=False + ) + container_from = db.relationship( + 'TradeDocument', + primaryjoin='MoveOnContainer.container_from_id == TradeDocument.id', + ) + container_from_id.comment = """This is the trade document used as container in a incoming lot""" + + container_to_id = db.Column( + db.BigInteger, + db.ForeignKey('trade_document.id'), + nullable=False + ) + container_to = db.relationship( + 'TradeDocument', + primaryjoin='MoveOnContainer.container_to_id == TradeDocument.id', + ) + container_to_id.comment = """This is the trade document used as container in a outgoing lot""" + + class Migrate(JoinedTableMixin, ActionWithMultipleDevices): """Moves the devices to a new database/inventory. Devices cannot be modified anymore at the previous database. diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index cfee0c12..50c0162f 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -33,8 +33,8 @@ from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash -from ereuse_devicehub.resources.documents.models import RecycleDocument -from ereuse_devicehub.resources.documents.schemas import RecycleDocument as sh_document +# from ereuse_devicehub.resources.documents.models import RecycleDocument +# from ereuse_devicehub.resources.documents.schemas import RecycleDocument as sh_document class Format(enum.Enum): @@ -291,24 +291,24 @@ class StampsView(View): result=result) -class RecycleDocumentView(View): - """ - This view allow save one document as a proof of one container with some weight was send to recycling. - """ +# class RecycleDocumentView(View): +# """ +# This view allow save one document as a proof of one container with some weight was send to recycling. +# """ - def post(self): - # import pdb; pdb.set_trace() - data = request.get_data() - schema = sh_document() - doc = schema.loads(data) - document = RecycleDocument(**doc) - db.session.add(document) +# def post(self): +# # import pdb; pdb.set_trace() +# data = request.get_data() +# schema = sh_document() +# doc = schema.loads(data) +# document = RecycleDocument(**doc) +# db.session.add(document) - db.session().final_flush() - ret = jsonify(document) - ret.status_code = 201 - db.session.commit() - return ret +# db.session().final_flush() +# ret = jsonify(document) +# ret.status_code = 201 +# db.session.commit() +# return ret class InternalStatsView(DeviceView): @@ -457,6 +457,5 @@ class DocumentDef(Resource): wbconf_view = app.auth.requires_auth(wbconf_view) self.add_url_rule('/wbconf/', view_func=wbconf_view, methods=get) - recycle_doc_view = RecycleDocumentView.as_view('RecycleDocumentView', definition=self, auth=app.auth) - self.add_url_rule('/recycle/', defaults={}, view_func=recycle_doc_view, methods={'POST'}) - + # recycle_doc_view = RecycleDocumentView.as_view('RecycleDocumentView', definition=self, auth=app.auth) + # self.add_url_rule('/recycle/', defaults={}, view_func=recycle_doc_view, methods={'POST'}) diff --git a/ereuse_devicehub/resources/documents/models.py b/ereuse_devicehub/resources/documents/models.py index 3deb9784..9c557b3e 100644 --- a/ereuse_devicehub/resources/documents/models.py +++ b/ereuse_devicehub/resources/documents/models.py @@ -64,26 +64,3 @@ class DataWipeDocument(JoinedTableMixin, Document): def __str__(self) -> str: return '{0.file_name}'.format(self) - - - -class RecycleDocument(JoinedTableMixin, Document): - """Document than proof how any of weight go to recycling.""" - - weight = db.Column(db.Float(nullable=True)) - weight.comment = """Weight than go to recycling""" - trade_document_id = db.Column(db.BigInteger, db.ForeignKey('trade_document.id')) - trade_document_id.comment = """This is the trade document used for send material to recyle""" - lot_id = db.Column(UUID(as_uuid=True), - db.ForeignKey('lot.id'), - nullable=False) - lot_id.comment = """This lot is the input lot if the material that will then go definitively to recycling""" - lot = db.relationship('Lot', - backref=backref('recycling_documents', - lazy=True, - cascade=CASCADE_OWN, - **_sorted_documents), - primaryjoin='RecycleDocument.lot_id == Lot.id') - - def __str__(self) -> str: - return '{0.file_name}'.format(self) diff --git a/ereuse_devicehub/resources/documents/schemas.py b/ereuse_devicehub/resources/documents/schemas.py index 66bc2f20..d2302866 100644 --- a/ereuse_devicehub/resources/documents/schemas.py +++ b/ereuse_devicehub/resources/documents/schemas.py @@ -35,21 +35,21 @@ class DataWipeDocument(Thing): data['document_type'] = 'DataWipeDocument' -class RecycleDocument(Thing): - __doc__ = m.RecycleDocument.__doc__ - file_hash = SanitizedStr(data_key='hash', - default='', - description=m.RecycleDocument.file_hash.comment, - validate=validate.Length(max=64)) - weight = Float(required=False, validate=Range(0.1), description=m.RecycleDocument.weight.comment) - lot = NestedOn('Lot', only_query='id', description=m.RecycleDocument.lot.__doc__) +# class RecycleDocument(Thing): +# __doc__ = m.RecycleDocument.__doc__ +# file_hash = SanitizedStr(data_key='hash', +# default='', +# description=m.RecycleDocument.file_hash.comment, +# validate=validate.Length(max=64)) +# weight = Float(required=False, validate=Range(0.1), description=m.RecycleDocument.weight.comment) +# lot = NestedOn('Lot', only_query='id', description=m.RecycleDocument.lot.__doc__) - @post_load - def get_trade_document(self, data): - tradedocument = TradeDocument.query.filter_by(file_hash=data['file_hash']).one() - data['trade_document_id'] = tradedocument.id - data['file_name'] = tradedocument.file_name - data['date'] = tradedocument.date - data['id_document'] = tradedocument.id_document - data['url'] = tradedocument.url - data['document_type'] = 'RecycleDocument' +# @post_load +# def get_trade_document(self, data): +# tradedocument = TradeDocument.query.filter_by(file_hash=data['file_hash']).one() +# data['trade_document_id'] = tradedocument.id +# data['file_name'] = tradedocument.file_name +# data['date'] = tradedocument.date +# data['id_document'] = tradedocument.id_document +# data['url'] = tradedocument.url +# data['document_type'] = 'RecycleDocument' From f398c50288f24f5ef9e7c420f08a04614a7a4075 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 6 Sep 2021 12:44:57 +0200 Subject: [PATCH 11/16] clean old code as documents --- .../resources/documents/documents.py | 24 ----------------- .../resources/documents/schemas.py | 20 -------------- tests/test_documents.py | 26 ------------------- 3 files changed, 70 deletions(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 50c0162f..f6de8884 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -33,8 +33,6 @@ from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash -# from ereuse_devicehub.resources.documents.models import RecycleDocument -# from ereuse_devicehub.resources.documents.schemas import RecycleDocument as sh_document class Format(enum.Enum): @@ -291,26 +289,6 @@ class StampsView(View): result=result) -# class RecycleDocumentView(View): -# """ -# This view allow save one document as a proof of one container with some weight was send to recycling. -# """ - -# def post(self): -# # import pdb; pdb.set_trace() -# data = request.get_data() -# schema = sh_document() -# doc = schema.loads(data) -# document = RecycleDocument(**doc) -# db.session.add(document) - -# db.session().final_flush() -# ret = jsonify(document) -# ret.status_code = 201 -# db.session.commit() -# return ret - - class InternalStatsView(DeviceView): @cache(datetime.timedelta(minutes=1)) def find(self, args: dict): @@ -457,5 +435,3 @@ class DocumentDef(Resource): wbconf_view = app.auth.requires_auth(wbconf_view) self.add_url_rule('/wbconf/', view_func=wbconf_view, methods=get) - # recycle_doc_view = RecycleDocumentView.as_view('RecycleDocumentView', definition=self, auth=app.auth) - # self.add_url_rule('/recycle/', defaults={}, view_func=recycle_doc_view, methods={'POST'}) diff --git a/ereuse_devicehub/resources/documents/schemas.py b/ereuse_devicehub/resources/documents/schemas.py index d2302866..d62cec41 100644 --- a/ereuse_devicehub/resources/documents/schemas.py +++ b/ereuse_devicehub/resources/documents/schemas.py @@ -33,23 +33,3 @@ class DataWipeDocument(Thing): @post_load def get_trade_document(self, data): data['document_type'] = 'DataWipeDocument' - - -# class RecycleDocument(Thing): -# __doc__ = m.RecycleDocument.__doc__ -# file_hash = SanitizedStr(data_key='hash', -# default='', -# description=m.RecycleDocument.file_hash.comment, -# validate=validate.Length(max=64)) -# weight = Float(required=False, validate=Range(0.1), description=m.RecycleDocument.weight.comment) -# lot = NestedOn('Lot', only_query='id', description=m.RecycleDocument.lot.__doc__) - -# @post_load -# def get_trade_document(self, data): -# tradedocument = TradeDocument.query.filter_by(file_hash=data['file_hash']).one() -# data['trade_document_id'] = tradedocument.id -# data['file_name'] = tradedocument.file_name -# data['date'] = tradedocument.date -# data['id_document'] = tradedocument.id_document -# data['url'] = tradedocument.url -# data['document_type'] = 'RecycleDocument' diff --git a/tests/test_documents.py b/tests/test_documents.py index 043ebaa5..b18e4c99 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -716,29 +716,3 @@ def test_trade_documents_with_weight(user: UserClient): } doc, _ = user.post(res=TradeDocument, data=request_post) assert doc['weight'] == request_post['weight'] - - -# @pytest.mark.mvp -# @pytest.mark.usefixtures(conftest.app_context.__name__) -# def test_recycle_document(user: UserClient): -# """Tests upload one document""" - -# lotIn, _ = user.post({'name': 'MyLotIn'}, res=Lot) -# lotOut, _ = user.post({'name': 'MyLotOut'}, res=Lot) -# url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa', -# request_post = { -# 'filename': 'test.pdf', -# 'hash': 'bbbbbbbb', -# 'url': url, -# 'weight': 15, -# 'lot': lotOut['id'] -# } -# tradedocument, _ = user.post(res=TradeDocument, data=request_post) -# # import pdb; pdb.set_trace() -# request_post2 = { -# 'weight': 15, -# 'hash': tradedocument['hash'], -# 'lot': lotIn['id'] -# } -# doc, _ = user.post(res=documents.DocumentDef.t, item='recycle/', data=request_post2) -# assert doc == request_post['filename'] From 74af5add3c20173ee70eb387a432bbed276e184f Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 6 Sep 2021 12:45:47 +0200 Subject: [PATCH 12/16] adding action moveOn endpoint --- ereuse_devicehub/resources/action/__init__.py | 5 +++++ ereuse_devicehub/resources/action/schemas.py | 7 +++++++ tests/test_action.py | 7 ++++++- tests/test_basic.py | 3 +-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ereuse_devicehub/resources/action/__init__.py b/ereuse_devicehub/resources/action/__init__.py index bdc55014..f33fa0df 100644 --- a/ereuse_devicehub/resources/action/__init__.py +++ b/ereuse_devicehub/resources/action/__init__.py @@ -313,3 +313,8 @@ class MigrateToDef(ActionDef): class MigrateFromDef(ActionDef): VIEW = None SCHEMA = schemas.MigrateFrom + + +class MoveOnContainerDef(ActionDef): + VIEW = None + SCHEMA = schemas.MoveOnContainer diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 3232f11b..efe4df74 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -840,3 +840,10 @@ class MigrateTo(Migrate): class MigrateFrom(Migrate): __doc__ = m.MigrateFrom.__doc__ + + +class MoveOnContainer(Migrate): + __doc__ = m.MoveOnContainer.__doc__ + weight = Integer() + container_from = NestedOn('TradeDocument', only_query='id') + container_to = NestedOn('TradeDocument', only_query='id') diff --git a/tests/test_action.py b/tests/test_action.py index 7de78e3b..345e7101 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -2478,9 +2478,14 @@ def test_moveonContainer(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_trade) request_moveOn = { + 'type': 'MoveOnContainer', 'weight': 15, + 'devices': [], 'container_from': tradedocument_from['id'], 'container_to': tradedocument_to['id'] } - import pdb; pdb.set_trace() doc, _ = user.post(res=models.Action, data=request_moveOn) + + assert doc['weight'] == request_moveOn['weight'] + assert doc['container_from']['id'] == tradedocument_from['id'] + assert doc['container_to']['id'] == tradedocument_to['id'] diff --git a/tests/test_basic.py b/tests/test_basic.py index ac7537a8..c3dc44d3 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -43,7 +43,6 @@ def test_api_docs(client: Client): '/documents/wbconf/{wbtype}', '/documents/internalstats/', '/documents/stock/', - '/documents/recycle/', '/documents/check/', '/documents/lots/', '/versions/', @@ -123,4 +122,4 @@ def test_api_docs(client: Client): 'scheme': 'basic', 'name': 'Authorization' } - assert len(docs['definitions']) == 126 + assert len(docs['definitions']) == 127 From 6cd28a3e3a8c20099a57ad1d6c1c032c99b21bc6 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 8 Sep 2021 13:54:10 +0200 Subject: [PATCH 13/16] Adding MoveOnDocument in migration and fixing schema --- ...c1897ce_adding_weight_to_tradedocuments.py | 20 ++++++++----------- ereuse_devicehub/resources/action/__init__.py | 4 ++-- ereuse_devicehub/resources/action/models.py | 6 +++--- ereuse_devicehub/resources/action/schemas.py | 19 +++++++++++++++--- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py index 9be818e1..19f4571c 100644 --- a/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py +++ b/ereuse_devicehub/migrations/versions/3ac2bc1897ce_adding_weight_to_tradedocuments.py @@ -29,18 +29,14 @@ def upgrade(): op.add_column("trade_document", sa.Column("weight", sa.Float(decimal_return_scale=2), nullable=True), schema=f'{get_inv()}') # DataWipeDocument table - op.create_table('recycle_document', - sa.Column('id', sa.BigInteger(), nullable=False), - sa.Column('trade_document_id', sa.BigInteger(), nullable=False), - sa.Column( - 'lot_id', - postgresql.UUID(as_uuid=True), - nullable=False - ), + op.create_table('move_on_document', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column("weight", sa.Float(decimal_return_scale=2), nullable=True), - sa.ForeignKeyConstraint(['lot_id'], [f'{get_inv()}.lot.id'],), - sa.ForeignKeyConstraint(['trade_document_id'], [f'{get_inv()}.trade_document.id'], ), - sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.document.id'], ), + sa.Column('container_from_id', sa.BigInteger(), nullable=False), + sa.Column('container_to_id', sa.BigInteger(), nullable=False), + sa.ForeignKeyConstraint(['container_from_id'], [f'{get_inv()}.trade_document.id'], ), + sa.ForeignKeyConstraint(['container_to_id'], [f'{get_inv()}.trade_document.id'], ), + sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ), sa.PrimaryKeyConstraint('id'), schema=f'{get_inv()}' ) @@ -48,4 +44,4 @@ def upgrade(): def downgrade(): op.drop_column('trade_document', 'weight', schema=f'{get_inv()}') - op.drop_table('recycle_document', schema=f'{get_inv()}') + op.drop_table('move_on_document', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/resources/action/__init__.py b/ereuse_devicehub/resources/action/__init__.py index f33fa0df..0c3d3e9c 100644 --- a/ereuse_devicehub/resources/action/__init__.py +++ b/ereuse_devicehub/resources/action/__init__.py @@ -315,6 +315,6 @@ class MigrateFromDef(ActionDef): SCHEMA = schemas.MigrateFrom -class MoveOnContainerDef(ActionDef): +class MoveOnDocumentDef(ActionDef): VIEW = None - SCHEMA = schemas.MoveOnContainer + SCHEMA = schemas.MoveOnDocument diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index 16098ead..603462b8 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -1651,7 +1651,7 @@ class MakeAvailable(ActionWithMultipleDevices): pass -class MoveOnContainer(JoinedTableMixin, ActionWithMultipleTradeDocuments): +class MoveOnDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments): """Action than certify one movement of some indescriptible material of one container to an other.""" @@ -1664,7 +1664,7 @@ class MoveOnContainer(JoinedTableMixin, ActionWithMultipleTradeDocuments): ) container_from = db.relationship( 'TradeDocument', - primaryjoin='MoveOnContainer.container_from_id == TradeDocument.id', + primaryjoin='MoveOnDocument.container_from_id == TradeDocument.id', ) container_from_id.comment = """This is the trade document used as container in a incoming lot""" @@ -1675,7 +1675,7 @@ class MoveOnContainer(JoinedTableMixin, ActionWithMultipleTradeDocuments): ) container_to = db.relationship( 'TradeDocument', - primaryjoin='MoveOnContainer.container_to_id == TradeDocument.id', + primaryjoin='MoveOnDocument.container_to_id == TradeDocument.id', ) container_to_id.comment = """This is the trade document used as container in a outgoing lot""" diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index efe4df74..9021862f 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -2,7 +2,7 @@ import copy from datetime import datetime, timedelta from dateutil.tz import tzutc from flask import current_app as app, g -from marshmallow import Schema as MarshmallowSchema, ValidationError, fields as f, validates_schema +from marshmallow import Schema as MarshmallowSchema, ValidationError, fields as f, validates_schema, pre_load from marshmallow.fields import Boolean, DateTime, Decimal, Float, Integer, Nested, String, \ TimeDelta, UUID from marshmallow.validate import Length, OneOf, Range @@ -25,6 +25,7 @@ from ereuse_devicehub.resources.models import STR_BIG_SIZE, STR_SIZE from ereuse_devicehub.resources.schemas import Thing from ereuse_devicehub.resources.user import schemas as s_user from ereuse_devicehub.resources.user.models import User +from ereuse_devicehub.resources.tradedocument.models import TradeDocument class Action(Thing): @@ -842,8 +843,20 @@ class MigrateFrom(Migrate): __doc__ = m.MigrateFrom.__doc__ -class MoveOnContainer(Migrate): - __doc__ = m.MoveOnContainer.__doc__ +class MoveOnDocument(Action): + __doc__ = m.MoveOnDocument.__doc__ weight = Integer() container_from = NestedOn('TradeDocument', only_query='id') container_to = NestedOn('TradeDocument', only_query='id') + + @pre_load + def extract_container(self, data): + id_hash = data['container_to'] + docs = TradeDocument.query.filter_by(owner=g.user, file_hash=id_hash).all() + if len(docs) > 1: + txt = 'This document it is associated in more than one lot' + raise ValidationError(txt) + if len(docs) < 1: + txt = 'This document not exist' + raise ValidationError(txt) + data['container_to'] = docs[0].id From 1e8651539193017c95556012eb76013b5e230449 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 8 Sep 2021 14:17:48 +0200 Subject: [PATCH 14/16] fixing test moveOnDocument --- tests/test_action.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/test_action.py b/tests/test_action.py index 345e7101..1333fe78 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -2443,7 +2443,7 @@ def test_action_web_erase(user: UserClient, client: Client): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) -def test_moveonContainer(user: UserClient, user2: UserClient): +def test_moveOnDocument(user: UserClient, user2: UserClient): lotIn, _ = user.post({'name': 'MyLotIn'}, res=Lot) lotOut, _ = user.post({'name': 'MyLotOut'}, res=Lot) url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa', @@ -2455,9 +2455,10 @@ def test_moveonContainer(user: UserClient, user2: UserClient): 'lot': lotIn['id'] } tradedocument_from, _ = user.post(res=TradeDocument, data=request_post1) + id_hash = 'aaaaaaaaa' request_post2 = { 'filename': 'test.pdf', - 'hash': 'bbbbbbbb', + 'hash': id_hash, 'url': url, 'weight': 0, 'lot': lotOut['id'] @@ -2478,14 +2479,16 @@ def test_moveonContainer(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_trade) request_moveOn = { - 'type': 'MoveOnContainer', + 'type': 'MoveOnDocument', 'weight': 15, - 'devices': [], 'container_from': tradedocument_from['id'], - 'container_to': tradedocument_to['id'] + 'container_to': id_hash } doc, _ = user.post(res=models.Action, data=request_moveOn) assert doc['weight'] == request_moveOn['weight'] assert doc['container_from']['id'] == tradedocument_from['id'] assert doc['container_to']['id'] == tradedocument_to['id'] + + tradedocument_to, _ = user.post(res=TradeDocument, data=request_post2) + user.post(res=models.Action, data=request_moveOn, status=422) From b7396b4f234dfe27adebc280eb9a9e0c56ae9201 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 9 Sep 2021 13:34:24 +0200 Subject: [PATCH 15/16] adding action moveOn inside of tradeDocuments --- ereuse_devicehub/resources/action/schemas.py | 11 ++++++++++- ereuse_devicehub/resources/tradedocument/models.py | 14 +++++++++----- tests/test_action.py | 10 +++++++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 9021862f..ec11dd8f 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -2,7 +2,7 @@ import copy from datetime import datetime, timedelta from dateutil.tz import tzutc from flask import current_app as app, g -from marshmallow import Schema as MarshmallowSchema, ValidationError, fields as f, validates_schema, pre_load +from marshmallow import Schema as MarshmallowSchema, ValidationError, fields as f, validates_schema, pre_load, post_load from marshmallow.fields import Boolean, DateTime, Decimal, Float, Integer, Nested, String, \ TimeDelta, UUID from marshmallow.validate import Length, OneOf, Range @@ -856,7 +856,16 @@ class MoveOnDocument(Action): if len(docs) > 1: txt = 'This document it is associated in more than one lot' raise ValidationError(txt) + if len(docs) < 1: txt = 'This document not exist' raise ValidationError(txt) data['container_to'] = docs[0].id + + @post_load + def adding_documents(self, data): + """Adding action in the 2 TradeDocuments""" + docs = OrderedSet() + docs.add(data['container_to']) + docs.add(data['container_from']) + data['documents'] = docs diff --git a/ereuse_devicehub/resources/tradedocument/models.py b/ereuse_devicehub/resources/tradedocument/models.py index 354fbb4d..28f4a8cf 100644 --- a/ereuse_devicehub/resources/tradedocument/models.py +++ b/ereuse_devicehub/resources/tradedocument/models.py @@ -101,9 +101,8 @@ class TradeDocument(Thing): revoke = 'Revoke' revoke_pending = 'Revoke Pending' confirm_revoke = 'Document Revoked' - if not self.actions: - return + return ac = self.actions[-1] @@ -111,7 +110,7 @@ class TradeDocument(Thing): # can to do revoke_confirmed return confirm_revoke - if ac.type == 'RevokeDocument': + if ac.type == 'RevokeDocument': if ac.user == g.user: # can todo revoke_pending return revoke_pending @@ -131,9 +130,14 @@ class TradeDocument(Thing): # can to do revoke return double_confirm - def _warning_actions(self, actions): - return sorted(ev for ev in actions if ev.severity >= Severity.Warning) + @property + def total_weight(self): + """Return all weight than this container have.""" + return sum([x.weight for x in self.actions if x.type == 'MoveOnDocument']) + self.weight + def _warning_actions(self, actions): + """Show warning actions""" + return sorted(ev for ev in actions if ev.severity >= Severity.Warning) def __lt__(self, other): return self.id < other.id diff --git a/tests/test_action.py b/tests/test_action.py index 1333fe78..4d2520c0 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -2478,11 +2478,13 @@ def test_moveOnDocument(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_trade) + description = 'This is a good description' request_moveOn = { 'type': 'MoveOnDocument', 'weight': 15, 'container_from': tradedocument_from['id'], - 'container_to': id_hash + 'container_to': id_hash, + 'description': description } doc, _ = user.post(res=models.Action, data=request_moveOn) @@ -2490,5 +2492,11 @@ def test_moveOnDocument(user: UserClient, user2: UserClient): assert doc['container_from']['id'] == tradedocument_from['id'] assert doc['container_to']['id'] == tradedocument_to['id'] + mvs= models.MoveOnDocument.query.filter().first() + trade_from = TradeDocument.query.filter_by(id=tradedocument_from['id']).one() + trade_to = TradeDocument.query.filter_by(id=tradedocument_to['id']).one() + assert trade_from in mvs.documents + assert trade_to in mvs.documents + assert description == mvs.description tradedocument_to, _ = user.post(res=TradeDocument, data=request_post2) user.post(res=models.Action, data=request_moveOn, status=422) From bcaf907255b808f611cbbdff423554a5d683ba0c Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 10 Sep 2021 14:07:35 +0200 Subject: [PATCH 16/16] adding total weight in lots --- ereuse_devicehub/resources/tradedocument/models.py | 10 +++++++++- ereuse_devicehub/resources/tradedocument/schemas.py | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/tradedocument/models.py b/ereuse_devicehub/resources/tradedocument/models.py index 28f4a8cf..36ae370a 100644 --- a/ereuse_devicehub/resources/tradedocument/models.py +++ b/ereuse_devicehub/resources/tradedocument/models.py @@ -133,7 +133,15 @@ class TradeDocument(Thing): @property def total_weight(self): """Return all weight than this container have.""" - return sum([x.weight for x in self.actions if x.type == 'MoveOnDocument']) + self.weight + weight = self.weight or 0 + for x in self.actions: + if not x.type == 'MoveOnDocument' or not x.weight: + continue + if self == x.container_from: + continue + weight += x.weight + + return weight def _warning_actions(self, actions): """Show warning actions""" diff --git a/ereuse_devicehub/resources/tradedocument/schemas.py b/ereuse_devicehub/resources/tradedocument/schemas.py index cfa74637..99aa9ab6 100644 --- a/ereuse_devicehub/resources/tradedocument/schemas.py +++ b/ereuse_devicehub/resources/tradedocument/schemas.py @@ -30,3 +30,4 @@ class TradeDocument(Thing): lot = NestedOn('Lot', only_query='id', description=m.TradeDocument.lot.__doc__) trading = SanitizedStr(dump_only=True, description='') weight = Float(required=False, description=m.TradeDocument.weight.comment) + total_weight = Float(required=False, description=m.TradeDocument.weight.comment)