actions trade for documents

This commit is contained in:
Cayo Puigdefabregas 2021-05-21 13:16:30 +02:00
parent 74dd300cad
commit 2a66fb94a3
3 changed files with 176 additions and 24 deletions

View File

@ -16,6 +16,7 @@ from ereuse_devicehub.resources import enums
from ereuse_devicehub.resources.action import models as m from ereuse_devicehub.resources.action import models as m
from ereuse_devicehub.resources.agent import schemas as s_agent from ereuse_devicehub.resources.agent import schemas as s_agent
from ereuse_devicehub.resources.device import schemas as s_device from ereuse_devicehub.resources.device import schemas as s_device
from ereuse_devicehub.resources.tradedocument import schemas as s_document
from ereuse_devicehub.resources.enums import AppearanceRange, BiosAccessRange, FunctionalityRange, \ from ereuse_devicehub.resources.enums import AppearanceRange, BiosAccessRange, FunctionalityRange, \
PhysicalErasureMethod, R_POSITIVE, RatingRange, \ PhysicalErasureMethod, R_POSITIVE, RatingRange, \
Severity, SnapshotSoftware, TestDataStorageLength Severity, SnapshotSoftware, TestDataStorageLength
@ -67,6 +68,14 @@ class ActionWithMultipleDevices(Action):
collection_class=OrderedSet) collection_class=OrderedSet)
class ActionWithMultipleTradeDocuments(ActionWithMultipleDevices):
documents = NestedOn(s_document.TradeDocument,
many=True,
required=False,
only_query='id',
collection_class=OrderedSet)
class Add(ActionWithOneDevice): class Add(ActionWithOneDevice):
__doc__ = m.Add.__doc__ __doc__ = m.Add.__doc__
@ -457,7 +466,7 @@ class CancelReservation(Organize):
__doc__ = m.CancelReservation.__doc__ __doc__ = m.CancelReservation.__doc__
class Confirm(ActionWithMultipleDevices): class Confirm(ActionWithMultipleTradeDocuments):
__doc__ = m.Confirm.__doc__ __doc__ = m.Confirm.__doc__
action = NestedOn('Action', only_query='id') action = NestedOn('Action', only_query='id')
@ -469,8 +478,55 @@ class Confirm(ActionWithMultipleDevices):
txt = "Device {} not exist in the trade".format(dev.devicehub_id) txt = "Device {} not exist in the trade".format(dev.devicehub_id)
raise ValidationError(txt) raise ValidationError(txt)
for doc in data.get('documents', []):
# if document not exist in the Trade, then this query is wrong
if not doc in data['action'].documents:
txt = "Document {} not exist in the trade".format(doc.file_name)
raise ValidationError(txt)
class Revoke(ActionWithMultipleDevices): @validates_schema
def validate_docs(self, data):
"""If there are one device than have one confirmation,
then remove the list this device of the list of devices of this action
"""
if not data['devices'] == OrderedSet():
return
documents = []
for doc in data['documents']:
actions = copy.copy(doc.actions)
actions.reverse()
for ac in actions:
if ac == data['action']:
# If document have the last action the action Trade
documents.append(doc)
break
if ac.t == Confirm.t and not ac.user == g.user:
# If document is confirmed but is not for g.user, then need confirm
documents.append(doc)
break
if ac.t == 'Revoke' and not ac.user == g.user:
# If document is revoke before from other user
# it's not possible confirm now
break
if ac.t == 'ConfirmRevoke' and ac.user == g.user:
# if the last action is a ConfirmRevoke this mean than not there are
# other confirmation from the real owner of the trade
break
if ac.t == Confirm.t and ac.user == g.user:
# If dodument is confirmed we don't need confirmed again
break
if not documents:
txt = 'No there are documents to confirm'
raise ValidationError(txt)
class Revoke(ActionWithMultipleTradeDocuments):
__doc__ = m.Revoke.__doc__ __doc__ = m.Revoke.__doc__
action = NestedOn('Action', only_query='id') action = NestedOn('Action', only_query='id')
@ -482,20 +538,103 @@ class Revoke(ActionWithMultipleDevices):
txt = "Device {} not exist in the trade".format(dev.devicehub_id) txt = "Device {} not exist in the trade".format(dev.devicehub_id)
raise ValidationError(txt) raise ValidationError(txt)
for doc in data.get('documents', []):
# if document not exist in the Trade, then this query is wrong
if not doc in data['action'].documents:
txt = "Document {} not exist in the trade".format(doc.file_name)
raise ValidationError(txt)
class ConfirmRevoke(ActionWithMultipleDevices): @validates_schema
def validate_documents(self, data):
"""Check if there are or no one before confirmation,
This is not checked in the view becouse the list of documents is inmutable
"""
if not data['devices'] == OrderedSet():
return
documents = []
for doc in data['documents']:
actions = copy.copy(doc.actions)
actions.reverse()
for ac in actions:
if ac == data['action']:
# data['action'] is a Trade action, if this is the first action
# to find mean that this document don't have a confirmation
break
if ac.t == 'Revoke' and ac.user == g.user:
# this doc is confirmation jet
break
if ac.t == Confirm.t and ac.user == g.user:
documents.append(doc)
break
if not documents:
txt = 'No there are documents to revoke'
raise ValidationError(txt)
class ConfirmRevoke(ActionWithMultipleTradeDocuments):
__doc__ = m.ConfirmRevoke.__doc__ __doc__ = m.ConfirmRevoke.__doc__
action = NestedOn('Action', only_query='id') action = NestedOn('Action', only_query='id')
@validates_schema @validates_schema
def validate_revoke(self, data: dict): def validate_revoke(self, data: dict):
# import pdb; pdb.set_trace()
for dev in data['devices']: for dev in data['devices']:
# if device not exist in the Trade, then this query is wrong # if device not exist in the Trade, then this query is wrong
if not dev in data['action'].devices: if not dev in data['action'].devices:
txt = "Device {} not exist in the revoke action".format(dev.devicehub_id) txt = "Device {} not exist in the trade".format(dev.devicehub_id)
raise ValidationError(txt) raise ValidationError(txt)
for doc in data.get('documents', []):
# if document not exist in the Trade, then this query is wrong
if not doc in data['action'].documents:
txt = "Document {} not exist in the trade".format(doc.file_name)
raise ValidationError(txt)
@validates_schema
def validate_docs(self, data):
"""Check if there are or no one before confirmation,
This is not checked in the view becouse the list of documents is inmutable
"""
if not data['devices'] == OrderedSet():
return
documents = []
for doc in data['documents']:
actions = copy.copy(doc.actions)
actions.reverse()
for ac in actions:
if ac == data['action']:
# If document have the last action the action for confirm
documents.append(doc)
break
if ac.t == 'Revoke' and not ac.user == g.user:
# If document is revoke before you can Confirm now
# and revoke is an action of one other user
documents.append(doc)
break
if ac.t == ConfirmRevoke.t and ac.user == g.user:
# If document is confirmed we don't need confirmed again
break
if ac.t == Confirm.t:
# if onwer of trade confirm again before than this user Confirm the
# revoke, then is not possible confirm the revoke
#
# If g.user confirm the trade before do a ConfirmRevoke
# then g.user can not to do the ConfirmRevoke more
break
if not documents:
txt = 'No there are documents with revoke for confirm'
raise ValidationError(txt)
class Trade(ActionWithMultipleDevices): class Trade(ActionWithMultipleDevices):
__doc__ = m.Trade.__doc__ __doc__ = m.Trade.__doc__

View File

@ -27,7 +27,6 @@ class TradeView():
""" """
def __init__(self, data, resource_def, schema): def __init__(self, data, resource_def, schema):
# import pdb; pdb.set_trace()
self.schema = schema self.schema = schema
a = resource_def.schema.load(data) a = resource_def.schema.load(data)
self.trade = Trade(**a) self.trade = Trade(**a)
@ -49,28 +48,34 @@ class TradeView():
# if the confirmation is mandatory, do automatic confirmation only for # if the confirmation is mandatory, do automatic confirmation only for
# owner of the lot # owner of the lot
if self.trade.confirm: if self.trade.confirm:
confirm_devs = Confirm(user=g.user, if self.trade.devices:
action=self.trade, confirm_devs = Confirm(user=g.user,
devices=self.trade.devices) action=self.trade,
devices=self.trade.devices)
db.session.add(confirm_devs)
confirm_docs = Confirm(user=g.user, if self.trade.documents:
action=self.trade, confirm_docs = Confirm(user=g.user,
documents=self.trade.documents) action=self.trade,
db.session.add(confirm_devs, confirm_docs) documents=self.trade.documents)
db.session.add(confirm_docs)
return return
# check than the user than want to do the action is one of the users # check than the user than want to do the action is one of the users
# involved in the action # involved in the action
assert g.user.id in [self.trade.user_from_id, self.trade.user_to_id] assert g.user.id in [self.trade.user_from_id, self.trade.user_to_id]
confirm_from = Confirm(user=self.trade.user_from, if self.trade.user_from == g.user or self.trade.user_from.phantom:
action=self.trade, confirm_from = Confirm(user=self.trade.user_from,
devices=self.trade.devices) action=self.trade,
confirm_to = Confirm(user=self.trade.user_to, devices=self.trade.devices)
action=self.trade, db.session.add(confirm_from)
devices=self.trade.devices)
db.session.add(confirm_from) if self.trade.user_to == g.user or self.trade.user_to.phantom:
db.session.add(confirm_to) confirm_to = Confirm(user=self.trade.user_to,
action=self.trade,
devices=self.trade.devices)
db.session.add(confirm_to)
def create_phantom_account(self) -> None: def create_phantom_account(self) -> None:
""" """
@ -141,7 +146,7 @@ class ConfirmMixin():
self.schema = schema self.schema = schema
a = resource_def.schema.load(data) a = resource_def.schema.load(data)
self.validate(a) self.validate(a)
if not a['devices']: if not a['devices'] and not a['documents']:
raise ValidationError('Devices not exist.') raise ValidationError('Devices not exist.')
self.model = self.Model(**a) self.model = self.Model(**a)
@ -169,7 +174,6 @@ class ConfirmView(ConfirmMixin):
"""If there are one device than have one confirmation, """If there are one device than have one confirmation,
then remove the list this device of the list of devices of this action then remove the list this device of the list of devices of this action
""" """
# import pdb; pdb.set_trace()
real_devices = [] real_devices = []
for dev in data['devices']: for dev in data['devices']:
actions = copy.copy(dev.actions) actions = copy.copy(dev.actions)
@ -181,7 +185,7 @@ class ConfirmView(ConfirmMixin):
break break
if ac.t == Confirm.t and not ac.user == g.user: if ac.t == Confirm.t and not ac.user == g.user:
# If device is confirmed we don't need confirmed again # If device is confirmed but is not for g.user, then need confirm
real_devices.append(dev) real_devices.append(dev)
break break

View File

@ -6,6 +6,7 @@ from teal.resource import View
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.resources.tradedocument.models import TradeDocument from ereuse_devicehub.resources.tradedocument.models import TradeDocument
from ereuse_devicehub.resources.action.models import Confirm, Revoke
from ereuse_devicehub.resources.hash_reports import insert_hash from ereuse_devicehub.resources.hash_reports import insert_hash
@ -52,6 +53,14 @@ class TradeDocumentView(View):
insert_hash(bfile) insert_hash(bfile)
doc = TradeDocument(**data) doc = TradeDocument(**data)
trade = doc.lot.trade
if trade:
trade.documents.add(doc)
confirm = Confirm(action=trade,
user=g.user,
devices=set(),
documents={doc})
db.session.add(confirm)
db.session.add(doc) db.session.add(doc)
db.session().final_flush() db.session().final_flush()
ret = self.schema.jsonify(doc) ret = self.schema.jsonify(doc)