confirm Revoke, confirm and revoke documents actions
This commit is contained in:
parent
8a797f079b
commit
c8b0c56bbb
|
@ -280,7 +280,9 @@ class RevokeDocumentDef(ActionDef):
|
|||
SCHEMA = schemas.RevokeDocument
|
||||
|
||||
|
||||
|
||||
class ConfirmRevokeDocumentDef(ActionDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.ConfirmRevokeDocument
|
||||
|
||||
|
||||
class CancelTradeDef(ActionDef):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Reference in a new issue