new Recycling document
This commit is contained in:
parent
9217f7392a
commit
f1220dd756
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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'})
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import copy
|
|
||||||
from citext import CIText
|
from citext import CIText
|
||||||
from flask import g
|
from flask import g
|
||||||
|
|
||||||
|
|
|
@ -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']
|
||||||
|
|
Reference in New Issue