fixing models and build views for revokeDocument
This commit is contained in:
parent
77000882f5
commit
8a797f079b
|
@ -115,8 +115,20 @@ def upgrade():
|
|||
op.create_index(op.f('ix_trade_document_created'), 'trade_document', ['created'], unique=False, schema=f'{get_inv()}')
|
||||
op.create_index(op.f('ix_trade_document_updated'), 'trade_document', ['updated'], unique=False, schema=f'{get_inv()}')
|
||||
|
||||
op.create_table('confirm_document',
|
||||
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||
sa.Column('action_id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||
|
||||
sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ),
|
||||
sa.ForeignKeyConstraint(['action_id'], [f'{get_inv()}.action.id'], ),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['common.user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
schema=f'{get_inv()}'
|
||||
)
|
||||
|
||||
def downgrade():
|
||||
op.drop_table('action_trade_document', schema=f'{get_inv()}')
|
||||
op.drop_table('confirm_document', schema=f'{get_inv()}')
|
||||
op.drop_table('trade_document', schema=f'{get_inv()}')
|
||||
|
||||
|
|
|
@ -270,6 +270,19 @@ class TradeDef(ActionDef):
|
|||
SCHEMA = schemas.Trade
|
||||
|
||||
|
||||
class ConfirmDocumentDef(ActionDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.ConfirmDocument
|
||||
|
||||
|
||||
class RevokeDocumentDef(ActionDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.RevokeDocument
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CancelTradeDef(ActionDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.CancelTrade
|
||||
|
|
|
@ -296,7 +296,7 @@ class ActionDevice(db.Model):
|
|||
primary_key=True)
|
||||
|
||||
|
||||
class ActionWithMultipleTradeDocuments(Action):
|
||||
class ActionWithMultipleTradeDocuments(ActionWithMultipleDevices):
|
||||
documents = relationship(TradeDocument,
|
||||
backref=backref('actions_docs', lazy=True, **_sorted_actions),
|
||||
secondary=lambda: ActionTradeDocument.__table__,
|
||||
|
@ -1466,14 +1466,18 @@ class ConfirmDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
|||
lazy=True,
|
||||
order_by=lambda: Action.end_time,
|
||||
collection_class=list),
|
||||
primaryjoin='Confirm.action_id == Action.id')
|
||||
primaryjoin='ConfirmDocument.action_id == Action.id')
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self.action.t in ['Trade']:
|
||||
origin = 'To'
|
||||
if self.user == self.action.user_from:
|
||||
origin = 'From'
|
||||
return '<{0.t} {0.id} accepted by {1}>'.format(self, origin)
|
||||
return '<{0.t}app/views/inventory/ {0.id} accepted by {1}>'.format(self, origin)
|
||||
|
||||
|
||||
class RevokeDocument(ConfirmDocument):
|
||||
pass
|
||||
|
||||
|
||||
class Confirm(JoinedTableMixin, ActionWithMultipleDevices):
|
||||
|
@ -1516,7 +1520,7 @@ class ConfirmRevoke(Confirm):
|
|||
return '<{0.t} {0.id} accepted by {0.user}>'.format(self)
|
||||
|
||||
|
||||
class Trade(JoinedTableMixin, ActionWithMultipleDevices):
|
||||
class Trade(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
||||
"""Trade actions log the political exchange of devices between users.
|
||||
Every time a trade action is performed, the old user looses its
|
||||
political possession, for example ownership, in favor of another
|
||||
|
|
|
@ -55,15 +55,19 @@ class Action(Thing):
|
|||
|
||||
|
||||
class ActionWithOneDevice(Action):
|
||||
__doc__ = m.ActionWithOneDevice.__doc__
|
||||
doc = NestedOn(s_document.TradeDocument, only_query='id')
|
||||
|
||||
|
||||
class ActionWithOneDocument(Action):
|
||||
__doc__ = m.ActionWithOneDevice.__doc__
|
||||
device = NestedOn(s_device.Device, only_query='id')
|
||||
|
||||
|
||||
class ActionWithMultipleDocuments(Action):
|
||||
__doc__ = m.ActionWithMultipleTradeDocuments.__doc__
|
||||
documents = NestedOn(s_document.TradeDocument,
|
||||
many=True,
|
||||
required=True, # todo test ensuring len(devices) >= 1
|
||||
only_query='id',
|
||||
collection_class=OrderedSet)
|
||||
|
||||
|
||||
class ActionWithMultipleDevices(Action):
|
||||
__doc__ = m.ActionWithMultipleDevices.__doc__
|
||||
devices = NestedOn(s_device.Device,
|
||||
|
@ -476,7 +480,7 @@ class Confirm(ActionWithMultipleDevices):
|
|||
raise ValidationError(txt)
|
||||
|
||||
|
||||
class ConfirmDocument(ActionWithOneDocument):
|
||||
class ConfirmDocument(ActionWithMultipleDocuments):
|
||||
__doc__ = m.Confirm.__doc__
|
||||
action = NestedOn('Action', only_query='id')
|
||||
|
||||
|
@ -580,8 +584,8 @@ class Revoke(ActionWithMultipleDevices):
|
|||
raise ValidationError(txt)
|
||||
|
||||
|
||||
class RevokeDocument(ActionWithOneDocument):
|
||||
__doc__ = m.Revoke.__doc__
|
||||
class RevokeDocument(ActionWithMultipleDocuments):
|
||||
__doc__ = m.RevokeDocument.__doc__
|
||||
action = NestedOn('Action', only_query='id')
|
||||
|
||||
@validates_schema
|
||||
|
@ -598,7 +602,8 @@ class RevokeDocument(ActionWithOneDocument):
|
|||
This is not checked in the view becouse the list of documents is inmutable
|
||||
|
||||
"""
|
||||
if not data['devices'] == OrderedSet():
|
||||
import pdb; pdb.set_trace()
|
||||
if not data['documents'] == OrderedSet():
|
||||
return
|
||||
|
||||
documents = []
|
||||
|
@ -684,7 +689,7 @@ class ConfirmRevoke(ActionWithMultipleDevices):
|
|||
raise ValidationError(txt)
|
||||
|
||||
|
||||
class ConfirmRevokeDocument(ActionWithOneDocument):
|
||||
class ConfirmRevokeDocument(ActionWithMultipleDocuments):
|
||||
__doc__ = m.ConfirmRevoke.__doc__
|
||||
action = NestedOn('Action', only_query='id')
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ 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
|
||||
from ereuse_devicehub.resources.action.models import (Trade, Confirm, ConfirmRevoke,
|
||||
Revoke, RevokeDocument, ConfirmDocument)
|
||||
from ereuse_devicehub.resources.user.models import User
|
||||
from ereuse_devicehub.resources.lot.views import delete_from_trade
|
||||
|
||||
|
@ -152,7 +153,7 @@ class ConfirmMixin():
|
|||
self.schema = schema
|
||||
a = resource_def.schema.load(data)
|
||||
self.validate(a)
|
||||
if not a['devices'] and not a['documents']:
|
||||
if not a['devices']:
|
||||
raise ValidationError('Devices not exist.')
|
||||
self.model = self.Model(**a)
|
||||
|
||||
|
@ -267,3 +268,134 @@ class ConfirmRevokeView(ConfirmMixin):
|
|||
dev.reset_owner()
|
||||
|
||||
trade.lot.devices.difference_update(devices)
|
||||
|
||||
|
||||
class ConfirmDocumentMixin():
|
||||
"""
|
||||
Very Important:
|
||||
==============
|
||||
All of this Views than inherit of this class is executed for users
|
||||
than is not owner of the Trade action.
|
||||
|
||||
The owner of Trade action executed this actions of confirm and revoke from the
|
||||
lot
|
||||
|
||||
"""
|
||||
|
||||
Model = None
|
||||
|
||||
def __init__(self, data, resource_def, schema):
|
||||
# import pdb; pdb.set_trace()
|
||||
self.schema = schema
|
||||
a = resource_def.schema.load(data)
|
||||
self.validate(a)
|
||||
if not a['documents']:
|
||||
raise ValidationError('Documents not exist.')
|
||||
self.model = self.Model(**a)
|
||||
|
||||
def post(self):
|
||||
db.session().final_flush()
|
||||
ret = self.schema.jsonify(self.model)
|
||||
ret.status_code = 201
|
||||
db.session.commit()
|
||||
return ret
|
||||
|
||||
|
||||
class ConfirmDocumentView(ConfirmDocumentMixin):
|
||||
"""Handler for manager the Confirmation register from post
|
||||
|
||||
request_confirm = {
|
||||
'type': 'Confirm',
|
||||
'action': trade.id,
|
||||
'devices': [device_id]
|
||||
}
|
||||
"""
|
||||
|
||||
Model = Confirm
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class RevokeDocumentView(ConfirmDocumentMixin):
|
||||
"""Handler for manager the Revoke register from post
|
||||
|
||||
request_revoke = {
|
||||
'type': 'Revoke',
|
||||
'action': trade.id,
|
||||
'devices': [device_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."""
|
||||
|
||||
### check ###
|
||||
if not data['documents']:
|
||||
raise ValidationError('Documents not exist.')
|
||||
|
||||
for doc in data['documents']:
|
||||
if not doc.trading == 'Confirmed':
|
||||
txt = 'Some of documents do not have enough to confirm for to do a revoke'
|
||||
ValidationError(txt)
|
||||
### End check ###
|
||||
|
||||
|
||||
class ConfirmRevokeDocumentView(ConfirmDocumentMixin):
|
||||
"""Handler for manager the Confirmation register from post
|
||||
|
||||
request_confirm_revoke = {
|
||||
'type': 'ConfirmRevoke',
|
||||
'action': action_revoke.id,
|
||||
'devices': [device_id]
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
Model = ConfirmRevoke
|
||||
|
||||
def validate(self, data):
|
||||
"""All devices need to have the status of revoke."""
|
||||
|
||||
if not data['action'].type == 'Revoke':
|
||||
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'
|
||||
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)
|
||||
|
|
|
@ -625,11 +625,11 @@ class Computer(Device):
|
|||
It is a subset of the Linux definition of DMI / DMI decode.
|
||||
"""
|
||||
amount = Column(Integer, check_range('amount', min=0, max=100), default=0)
|
||||
owner_id = db.Column(UUID(as_uuid=True),
|
||||
db.ForeignKey(User.id),
|
||||
nullable=False,
|
||||
default=lambda: g.user.id)
|
||||
author = db.relationship(User, primaryjoin=owner_id == User.id)
|
||||
# owner_id = db.Column(UUID(as_uuid=True),
|
||||
# db.ForeignKey(User.id),
|
||||
# nullable=False,
|
||||
# default=lambda: g.user.id)
|
||||
# author = db.relationship(User, primaryjoin=owner_id == User.id)
|
||||
transfer_state = db.Column(IntEnum(TransferState), default=TransferState.Initial, nullable=False)
|
||||
transfer_state.comment = TransferState.__doc__
|
||||
receiver_id = db.Column(UUID(as_uuid=True),
|
||||
|
|
|
@ -94,8 +94,9 @@ 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"""
|
||||
|
||||
confirm = 'Confirm'
|
||||
to_confirm = 'ToConfirm'
|
||||
# import pdb; pdb.set_trace()
|
||||
confirm = 'ConfirmDocument'
|
||||
to_confirm = 'To Confirm'
|
||||
revoke = 'Revoke'
|
||||
|
||||
if not self.actions:
|
||||
|
@ -105,16 +106,13 @@ class TradeDocument(Thing):
|
|||
actions = list(reversed(actions))
|
||||
ac = actions[0]
|
||||
|
||||
if ac.type == confirm:
|
||||
return confirm
|
||||
|
||||
if ac.type == revoke:
|
||||
return revoke
|
||||
|
||||
if ac.type == confirm:
|
||||
if ac.user == self.owner:
|
||||
return confirm
|
||||
return to_confirm
|
||||
return 'Confirmed'
|
||||
|
||||
def last_action_of(self, *types):
|
||||
"""Gets the last action of the given types.
|
||||
|
|
|
@ -6,7 +6,7 @@ from teal.resource import View
|
|||
|
||||
from ereuse_devicehub.db import db
|
||||
from ereuse_devicehub.resources.tradedocument.models import TradeDocument
|
||||
from ereuse_devicehub.resources.action.models import Confirm, Revoke
|
||||
from ereuse_devicehub.resources.action.models import ConfirmDocument
|
||||
from ereuse_devicehub.resources.hash_reports import ReportHash
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@ class TradeDocumentView(View):
|
|||
trade = doc.lot.trade
|
||||
if trade:
|
||||
trade.documents.add(doc)
|
||||
confirm = Confirm(action=trade,
|
||||
confirm = ConfirmDocument(action=trade,
|
||||
user=g.user,
|
||||
devices=set(),
|
||||
documents={doc})
|
||||
|
|
Reference in New Issue