new Recycling document

This commit is contained in:
Cayo Puigdefabregas 2021-08-10 12:45:03 +02:00
parent 9217f7392a
commit f1220dd756
7 changed files with 124 additions and 12 deletions

View File

@ -12,7 +12,7 @@ from alembic import context
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '3ac2bc1897ce' revision = '3ac2bc1897ce'
down_revision = '0103a9c96b2d' down_revision = '7ecb8ff7abad'
branch_labels = None branch_labels = None
depends_on = None depends_on = None

View File

@ -29,7 +29,7 @@ class ErasedView():
schema = sh_document() schema = sh_document()
[data.pop(x, None) for x in ['severity', 'devices', 'name', 'description']] [data.pop(x, None) for x in ['severity', 'devices', 'name', 'description']]
doc_data = schema.load(data) doc_data = schema.load(data)
doc_data['type'] = 'DataWipe' # doc_data['type'] = 'DataWipe'
self.document = DataWipeDocument(**doc_data) self.document = DataWipeDocument(**doc_data)
db.session.add(self.document) db.session.add(self.document)

View File

@ -283,6 +283,28 @@ class StampsView(View):
result=result) 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): class InternalStatsView(DeviceView):
@cache(datetime.timedelta(minutes=1)) @cache(datetime.timedelta(minutes=1))
def find(self, args: dict): def find(self, args: dict):
@ -428,3 +450,7 @@ class DocumentDef(Resource):
auth=app.auth) auth=app.auth)
wbconf_view = app.auth.requires_auth(wbconf_view) wbconf_view = app.auth.requires_auth(wbconf_view)
self.add_url_rule('/wbconf/<string:wbtype>', view_func=wbconf_view, methods=get) self.add_url_rule('/wbconf/<string:wbtype>', 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'})

View File

@ -1,14 +1,23 @@
from citext import CIText
from flask import g from flask import g
from citext import CIText
from sortedcontainers import SortedSet
from sqlalchemy import BigInteger, Column, Sequence, Unicode, Boolean, ForeignKey from sqlalchemy import BigInteger, Column, Sequence, Unicode, Boolean, ForeignKey
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.dialects.postgresql import UUID 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.db import db
from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.resources.models import Thing, STR_SM_SIZE from ereuse_devicehub.resources.models import Thing, STR_SM_SIZE
_sorted_documents = {
'order_by': lambda: Document.created,
'collection_class': SortedSet
}
class Document(Thing): class Document(Thing):
"""This represent a generic document.""" """This represent a generic document."""
@ -16,7 +25,7 @@ class Document(Thing):
id.comment = """The identifier of the device for this database. Used only id.comment = """The identifier of the device for this database. Used only
internally for software; users should not use this. 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 = Column(db.DateTime, nullable=True)
date.comment = """The date of document, some documents need to have one date 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: def __str__(self) -> str:
return '{0.file_name}'.format(self) 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)

View File

@ -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 teal.marshmallow import SanitizedStr, URL
from ereuse_devicehub.marshmallow import NestedOn
from ereuse_devicehub.resources.schemas import Thing from ereuse_devicehub.resources.schemas import Thing
from ereuse_devicehub.resources.tradedocument.models import TradeDocument
from ereuse_devicehub.resources.documents import models as m from ereuse_devicehub.resources.documents import models as m
class DataWipeDocument(Thing): class DataWipeDocument(Thing):
__doc__ = m.DataWipeDocument.__doc__ __doc__ = m.DataWipeDocument.__doc__
id = Integer(description=m.DataWipeDocument.id.comment, dump_only=True) id = Integer(description=m.DataWipeDocument.id.comment, dump_only=True)
type = SanitizedStr(default='DataWipeDocument')
url = URL(required= False, description=m.DataWipeDocument.url.comment) url = URL(required= False, description=m.DataWipeDocument.url.comment)
success = Boolean(required=False, default=False, description=m.DataWipeDocument.success.comment) success = Boolean(required=False, default=False, description=m.DataWipeDocument.success.comment)
software = SanitizedStr(description=m.DataWipeDocument.software.comment) software = SanitizedStr(description=m.DataWipeDocument.software.comment)
@ -26,3 +29,27 @@ class DataWipeDocument(Thing):
default='', default='',
description=m.DataWipeDocument.file_hash.comment, description=m.DataWipeDocument.file_hash.comment,
validate=validate.Length(max=64)) 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'

View File

@ -1,4 +1,3 @@
import copy
from citext import CIText from citext import CIText
from flask import g from flask import g

View File

@ -705,12 +705,40 @@ def test_trade_documents_with_weight(user: UserClient):
"""Tests upload one document""" """Tests upload one document"""
lot, _ = user.post({'name': 'MyLot'}, res=Lot) lot, _ = user.post({'name': 'MyLot'}, res=Lot)
# long url
url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa',
request_post = { request_post = {
'filename': 'test.pdf', 'filename': 'test.pdf',
'hash': 'bbbbbbbb', 'hash': 'bbbbbbbb',
'url': 'http://www.ereuse.org/', 'url': url,
'weight': 15, 'weight': 15,
'lot': lot['id'] 'lot': lot['id']
} }
doc, _ = user.post(res=TradeDocument, data=request_post) doc, _ = user.post(res=TradeDocument, data=request_post)
assert doc['weight'] == request_post['weight'] 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']