fixing supplier and receiver

This commit is contained in:
Cayo Puigdefabregas 2021-06-04 19:27:01 +02:00
parent a0824f986b
commit 80e74b6d3d
3 changed files with 104 additions and 53 deletions

View File

@ -7,6 +7,7 @@ from teal.marshmallow import ValidationError
from ereuse_devicehub.db import db 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
from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.resources.lot.models import Lot
class TradeView(): class TradeView():
@ -221,28 +222,55 @@ class RevokeView(ConfirmMixin):
Model = Revoke Model = Revoke
def __init__(self, data, resource_def, schema):
self.schema = schema
a = resource_def.schema.load(data)
self.validate(a)
def validate(self, data): def validate(self, data):
"""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
""" """
real_devices = [] ### check ###
devs_confirm = []
if not data['devices']:
raise ValidationError('Devices not exist.')
for dev in data['devices']: for dev in data['devices']:
actions = copy.copy(dev.actions) if dev.last_action_trading.type == 'Confirm':
actions.reverse() devs_confirm.append(dev)
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 devices dont have a confirmation
break
if ac.t == 'Revoke' and ac.user == g.user: if not len(data['devices']) == len(devs_confirm):
break txt = "Some of this devices can't be reboked"
raise ValidationError(txt)
### End check ###
if ac.t == Confirm.t and ac.user == g.user: lot = data['action'].lot
real_devices.append(dev) devices = set(data['devices'])
break without_confirms = set() # set of devs without confirms of user2
data['devices'] = OrderedSet(real_devices) if g.user == lot.trade.author:
for dev in devices:
ac = dev.last_action_trading
if ac.type == 'Confirm' and ac.user == g.user:
without_confirms.add(dev)
# we need to mark one revoke for every devs
revoke = Revoke(action=lot.trade, user=g.user, devices=devices)
db.session.add(revoke)
if without_confirms:
confirm_revoke = ConfirmRevoke(
action=revoke,
user=g.user,
devices=without_confirms
)
db.session.add(confirm_revoke)
lot.devices.difference_update(without_confirms)
lot.trade.devices = lot.devices
self.model = revoke
class ConfirmRevokeView(ConfirmMixin): class ConfirmRevokeView(ConfirmMixin):

View File

@ -254,39 +254,32 @@ class Device(Thing):
from ereuse_devicehub.resources.action.models import Price from ereuse_devicehub.resources.action.models import Price
return self.last_action_of(Price) return self.last_action_of(Price)
@property
def last_action_trading(self):
"""which is the last action trading"""
from ereuse_devicehub.resources.device import states
with suppress(LookupError, ValueError):
return self.last_action_of(*states.Trading.actions())
@property @property
def trading(self): def trading(self):
"""The trading state, or None if no Trade action has """The trading state, or None if no Trade action has
ever been performed to this device. This extract the posibilities for to do""" ever been performed to this device. This extract the posibilities for to do"""
# import pdb; pdb.set_trace()
trade = 'Trade' trade = 'Trade'
confirm = 'Confirm' confirm = 'Confirm'
revoke = 'Revoke' revoke = 'Revoke'
revoke_pending = 'RevokePending' revoke_pending = 'RevokePending'
confirm_revoke = 'ConfirmRevoke' confirm_revoke = 'ConfirmRevoke'
revoke_confirmed = 'RevokeConfirmed' # revoke_confirmed = 'RevokeConfirmed'
types = [trade, confirm, revoke, confirm_revoke]
actions = copy.copy(self.actions)
actions.sort(key=lambda x: x.created)
actions.reverse()
actions_trade = []
# get only the actions trade of the last trade
for ac in actions:
if ac.type in types:
actions_trade.append(ac)
if ac.type == trade:
break
# return the correct status of trade depending of the user # return the correct status of trade depending of the user
##### CASES ##### ##### CASES #####
## User1 == owner of trade (This user have automatic Confirmation) ## User1 == owner of trade (This user have automatic Confirmation)
## ======================= ## =======================
## if the last action is => only allow to do
## ==========================================
## Confirmation not User1 => Revoke ## Confirmation not User1 => Revoke
## Confirmation User1 => Revoke ## Confirmation User1 => Revoke
## Revoke not User1 => ConfirmRevoke ## Revoke not User1 => ConfirmRevoke
@ -296,32 +289,35 @@ class Device(Thing):
## ##
## User2 == Not owner of trade ## User2 == Not owner of trade
## ======================= ## =======================
## if the last action is => only allow to do
## ==========================================
## Confirmation not User2 => Confirm ## Confirmation not User2 => Confirm
## Confirmation User2 => Revoke ## Confirmation User2 => Revoke
## Revoke not User2 => ConfirmRevoke ## Revoke not User2 => ConfirmRevoke
## Revoke User2 => RevokePending ## Revoke User2 => RevokePending
## RevokeConfirmation => RevokeConfirmed ## RevokeConfirmation => RevokeConfirmed
for ac in actions_trade: ac = self.last_action_trading
if ac.type == confirm_revoke:
# can to do revoke_confirmed
return confirm_revoke
if ac.type == revoke and ac.user == g.user: if ac.type == confirm_revoke:
# can todo revoke_pending # can to do revoke_confirmed
return revoke_pending return confirm_revoke
if ac.type == revoke and ac.user != g.user: if ac.type == revoke and ac.user == g.user:
# can to do confirm_revoke # can todo revoke_pending
return revoke return revoke_pending
if ac.type == confirm and (ac.user == g.user or ac.action.author == g.user): if ac.type == revoke and ac.user != g.user:
# can to do revoke # can to do confirm_revoke
return confirm return revoke
if ac.type == confirm and ac.user != g.user: if ac.type == confirm and (ac.user == g.user or ac.action.author == g.user):
# can to do confirm # can to do revoke
return trade return confirm
if ac.type == confirm and ac.user != g.user:
# can to do confirm
return trade
@property @property
def revoke(self): def revoke(self):

View File

@ -13,7 +13,7 @@ from teal.resource import View
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.query import things_response from ereuse_devicehub.query import things_response
from ereuse_devicehub.resources.device.models import Device, Computer from ereuse_devicehub.resources.device.models import Device, Computer
from ereuse_devicehub.resources.action.models import Trade, Confirm, Revoke from ereuse_devicehub.resources.action.models import Trade, Confirm, Revoke, ConfirmRevoke
from ereuse_devicehub.resources.lot.models import Lot, Path from ereuse_devicehub.resources.lot.models import Lot, Path
@ -254,6 +254,7 @@ class LotDeviceView(LotBaseChildrenView):
return return
users = [g.user.id] users = [g.user.id]
# import pdb; pdb.set_trace()
if lot.trade: if lot.trade:
# all users involved in the trade action can modify the lot # all users involved in the trade action can modify the lot
trade_users = [lot.trade.user_from.id, lot.trade.user_to.id] trade_users = [lot.trade.user_from.id, lot.trade.user_to.id]
@ -263,10 +264,36 @@ class LotDeviceView(LotBaseChildrenView):
devices = set(Device.query.filter(Device.id.in_(ids)).filter( devices = set(Device.query.filter(Device.id.in_(ids)).filter(
Device.owner_id.in_(users))) Device.owner_id.in_(users)))
lot.devices.difference_update(devices) if not lot.trade:
lot.devices.difference_update(devices)
return
if lot.trade: # if is a trade
if not g.user in [lot.trade.user_from, lot.trade.user_to]:
# theoretically this case is impossible
return
# Now we need to know which devices we need extract of the lot
without_confirms = set() # set of devs without confirms of user2
if g.user == lot.trade.author:
for dev in devices:
ac = dev.last_action_trading
if ac.type == 'Confirm' and ac.user == g.user:
without_confirms.add(dev)
# we need to mark one revoke for every devs
revoke = Revoke(action=lot.trade, user=g.user, devices=devices)
db.session.add(revoke)
if without_confirms:
confirm_revoke = ConfirmRevoke(
action=revoke,
user=g.user,
devices=without_confirms
)
db.session.add(confirm_revoke)
lot.devices.difference_update(without_confirms)
lot.trade.devices = lot.devices lot.trade.devices = lot.devices
if g.user in [lot.trade.user_from, lot.trade.user_to]:
revoke = Revoke(action=lot.trade, user=g.user, devices=devices)
db.session.add(revoke)