confirm Revoke, confirm and revoke documents actions

This commit is contained in:
Cayo Puigdefabregas 2021-06-28 16:06:07 +02:00
parent 8a797f079b
commit c8b0c56bbb
6 changed files with 147 additions and 200 deletions

View File

@ -280,7 +280,9 @@ class RevokeDocumentDef(ActionDef):
SCHEMA = schemas.RevokeDocument
class ConfirmRevokeDocumentDef(ActionDef):
VIEW = None
SCHEMA = schemas.ConfirmRevokeDocument
class CancelTradeDef(ActionDef):

View File

@ -1447,6 +1447,7 @@ class Reserve(Organize):
class CancelReservation(Organize):
"""The act of cancelling a reservation."""
class ConfirmDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments):
"""Users confirm the one action trade this confirmation it's link to trade
and the document that confirm
@ -1480,6 +1481,10 @@ class RevokeDocument(ConfirmDocument):
pass
class ConfirmRevokeDocument(ConfirmDocument):
pass
class Confirm(JoinedTableMixin, ActionWithMultipleDevices):
"""Users confirm the one action trade this confirmation it's link to trade
and the devices that confirm

View File

@ -480,60 +480,6 @@ class Confirm(ActionWithMultipleDevices):
raise ValidationError(txt)
class ConfirmDocument(ActionWithMultipleDocuments):
__doc__ = m.Confirm.__doc__
action = NestedOn('Action', only_query='id')
@validates_schema
def validate_revoke(self, data: dict):
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):
"""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(ActionWithMultipleDevices):
__doc__ = m.Revoke.__doc__
action = NestedOn('Action', only_query='id')
@ -584,17 +530,43 @@ class Revoke(ActionWithMultipleDevices):
raise ValidationError(txt)
class RevokeDocument(ActionWithMultipleDocuments):
__doc__ = m.RevokeDocument.__doc__
class ConfirmDocument(ActionWithMultipleDocuments):
__doc__ = m.Confirm.__doc__
action = NestedOn('Action', only_query='id')
@validates_schema
def validate_revoke(self, data: dict):
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)
def validate_documents(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
"""
# import pdb; pdb.set_trace()
if data['documents'] == OrderedSet():
return
documents = []
for doc in data['documents']:
if not doc.lot.trade:
return
data['action'] = doc.lot.trade
if not doc.actions:
continue
ac = doc.actions[-1]
if ac.t == 'ConfirmDocument' and not ac.user == g.user:
# If document is confirmed but is not for g.user, then need confirm
documents.append(doc)
if not documents:
txt = 'No there are documents to confirm'
raise ValidationError(txt)
class RevokeDocument(ActionWithMultipleDocuments):
__doc__ = m.RevokeDocument.__doc__
action = NestedOn('Action', only_query='id')
@validates_schema
def validate_documents(self, data):
@ -602,33 +574,63 @@ class RevokeDocument(ActionWithMultipleDocuments):
This is not checked in the view becouse the list of documents is inmutable
"""
import pdb; pdb.set_trace()
if not data['documents'] == OrderedSet():
if data['documents'] == 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 not doc.lot.trade:
return
if ac.t == 'Revoke' and ac.user == g.user:
# this doc is confirmation jet
break
data['action'] = doc.lot.trade
if ac.t == Confirm.t and ac.user == g.user:
documents.append(doc)
break
if not doc.actions:
continue
ac = doc.actions[-1]
if ac.t == 'ConfirmDocument' and ac.user == g.user:
documents.append(doc)
if not documents:
txt = 'No there are documents to revoke'
raise ValidationError(txt)
class ConfirmRevokeDocument(ActionWithMultipleDocuments):
__doc__ = m.ConfirmRevoke.__doc__
action = NestedOn('Action', only_query='id')
@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 data['documents'] == OrderedSet():
return
documents = []
for doc in data['documents']:
if not doc.lot.trade:
return
if not doc.actions:
continue
ac = doc.actions[-1]
if ac.t == 'RevokeDocument' and not ac.user == g.user:
# If document is revoke before you can Confirm now
# and revoke is an action of one other user
data['action'] = ac
documents.append(doc)
if not documents:
txt = 'No there are documents with revoke for confirm'
raise ValidationError(txt)
class ConfirmRevoke(ActionWithMultipleDevices):
__doc__ = m.ConfirmRevoke.__doc__
action = NestedOn('Action', only_query='id')
@ -689,60 +691,6 @@ class ConfirmRevoke(ActionWithMultipleDevices):
raise ValidationError(txt)
class ConfirmRevokeDocument(ActionWithMultipleDocuments):
__doc__ = m.ConfirmRevoke.__doc__
action = NestedOn('Action', only_query='id')
@validates_schema
def validate_revoke(self, data: dict):
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):
__doc__ = m.Trade.__doc__
date = DateTime(data_key='date', required=False)

View File

@ -1,12 +1,11 @@
import copy
from flask import g
from sqlalchemy.util import OrderedSet
from teal.marshmallow import ValidationError
from ereuse_devicehub.db import db
from ereuse_devicehub.resources.action.models import (Trade, Confirm, ConfirmRevoke,
Revoke, RevokeDocument, ConfirmDocument)
Revoke, RevokeDocument, ConfirmDocument,
ConfirmRevokeDocument)
from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.resources.lot.views import delete_from_trade
@ -307,28 +306,22 @@ class ConfirmDocumentView(ConfirmDocumentMixin):
request_confirm = {
'type': 'Confirm',
'action': trade.id,
'devices': [device_id]
'documents': [document_id],
}
"""
Model = Confirm
Model = ConfirmDocument
def validate(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
"""
real_devices = []
for dev in data['devices']:
ac = dev.last_action_trading
if ac.type == Confirm.t and not ac.user == g.user:
real_devices.append(dev)
data['devices'] = OrderedSet(real_devices)
# Change the owner for every devices
for dev in data['devices']:
user_to = data['action'].user_to
dev.change_owner(user_to)
for doc in data['documents']:
ac = doc.trading
if not doc.trading in ['Confirm', 'Need Confirmation']:
txt = 'Some of documents do not have enough to confirm for to do a Doble Confirmation'
ValidationError(txt)
### End check ###
class RevokeDocumentView(ConfirmDocumentMixin):
@ -337,18 +330,13 @@ class RevokeDocumentView(ConfirmDocumentMixin):
request_revoke = {
'type': 'Revoke',
'action': trade.id,
'devices': [device_id],
'documents': [document_id],
}
"""
Model = RevokeDocument
def __init__(self, data, resource_def, schema):
self.schema = schema
a = resource_def.schema.load(data)
self.validate(a)
def validate(self, data):
"""All devices need to have the status of DoubleConfirmation."""
@ -357,7 +345,7 @@ class RevokeDocumentView(ConfirmDocumentMixin):
raise ValidationError('Documents not exist.')
for doc in data['documents']:
if not doc.trading == 'Confirmed':
if not doc.trading in ['Document Confirmed', 'Confirm']:
txt = 'Some of documents do not have enough to confirm for to do a revoke'
ValidationError(txt)
### End check ###
@ -369,33 +357,21 @@ class ConfirmRevokeDocumentView(ConfirmDocumentMixin):
request_confirm_revoke = {
'type': 'ConfirmRevoke',
'action': action_revoke.id,
'devices': [device_id]
'documents': [document_id],
}
"""
Model = ConfirmRevoke
Model = ConfirmRevokeDocument
def validate(self, data):
"""All devices need to have the status of revoke."""
if not data['action'].type == 'Revoke':
if not data['action'].type == 'RevokeDocument':
txt = 'Error: this action is not a revoke action'
ValidationError(txt)
for dev in data['devices']:
if not dev.trading == 'Revoke':
txt = 'Some of devices do not have revoke to confirm'
for doc in data['documents']:
if not doc.trading == 'Revoke':
txt = 'Some of documents do not have revoke to confirm'
ValidationError(txt)
devices = OrderedSet(data['devices'])
data['devices'] = devices
# Change the owner for every devices
# data['action'] == 'Revoke'
trade = data['action'].action
for dev in devices:
dev.reset_owner()
trade.lot.devices.difference_update(devices)

View File

@ -202,6 +202,19 @@ class ActionView(View):
confirm_revoke = trade_view.ConfirmRevokeView(json, resource_def, self.schema)
return confirm_revoke.post()
if json['type'] == 'RevokeDocument':
revoke = trade_view.RevokeDocumentView(json, resource_def, self.schema)
return revoke.post()
if json['type'] == 'ConfirmDocument':
confirm = trade_view.ConfirmDocumentView(json, resource_def, self.schema)
return confirm.post()
if json['type'] == 'ConfirmRevokeDocument':
confirm_revoke = trade_view.ConfirmRevokeDocumentView(json, resource_def, self.schema)
return confirm_revoke.post()
# import pdb; pdb.set_trace()
a = resource_def.schema.load(json)
Model = db.Model._decl_class_registry.data[json['type']]()
action = Model(**a)

View File

@ -94,38 +94,41 @@ class TradeDocument(Thing):
"""The trading state, or None if no Trade action has
ever been performed to this device. This extract the posibilities for to do"""
# import pdb; pdb.set_trace()
confirm = 'ConfirmDocument'
to_confirm = 'To Confirm'
confirm = 'Confirm'
need_confirm = 'Need Confirmation'
double_confirm = 'Document Confirmed'
revoke = 'Revoke'
revoke_pending = 'Revoke Pending'
confirm_revoke = 'Document Revoked'
if not self.actions:
return
return
actions = copy.copy(self.actions)
actions = list(reversed(actions))
ac = actions[0]
ac = self.actions[-1]
if ac.type == revoke:
return revoke
if ac.type == 'ConfirmRevokeDocument':
# can to do revoke_confirmed
return confirm_revoke
if ac.type == confirm:
if ac.type == 'RevokeDocument':
if ac.user == g.user:
# can todo revoke_pending
return revoke_pending
else:
# can to do confirm_revoke
return revoke
if ac.type == 'ConfirmDocument':
if ac.user == self.owner:
return to_confirm
return 'Confirmed'
def last_action_of(self, *types):
"""Gets the last action of the given types.
:raise LookupError: Device has not an action of the given type.
"""
try:
# noinspection PyTypeHints
actions = self.actions
actions.sort(key=lambda x: x.created)
return next(e for e in reversed(actions) if isinstance(e, types))
except StopIteration:
raise LookupError('{!r} does not contain actions of types {}.'.format(self, types))
if self.owner == g.user:
# can to do revoke
return confirm
else:
# can to do confirm
return need_confirm
else:
# can to do revoke
return double_confirm
def _warning_actions(self, actions):
return sorted(ev for ev in actions if ev.severity >= Severity.Warning)