diff --git a/ereuse_devicehub/resources/action/__init__.py b/ereuse_devicehub/resources/action/__init__.py index 1e722a3c..13538f90 100644 --- a/ereuse_devicehub/resources/action/__init__.py +++ b/ereuse_devicehub/resources/action/__init__.py @@ -260,6 +260,11 @@ class TradeDef(ActionDef): SCHEMA = schemas.Trade +class OfferDef(ActionDef): + VIEW = None + SCHEMA = schemas.Offer + + class ToDisposeProductDef(ActionDef): VIEW = None SCHEMA = schemas.ToDisposeProduct diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index 9f3acc05..cf552ca7 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -48,7 +48,6 @@ from ereuse_devicehub.resources.enums import AppearanceRange, BatteryHealth, Bio TestDataStorageLength from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing from ereuse_devicehub.resources.user.models import User -# from ereuse_devicehub.resources.lot.models import Lot class JoinedTableMixin: @@ -1446,7 +1445,7 @@ class Trade(JoinedTableMixin, ActionWithMultipleDevices): This class and its inheritors extend `Schema's Trade `_. - """ + """ user_from_id = db.Column(UUID(as_uuid=True), db.ForeignKey(User.id), nullable=False, @@ -1461,11 +1460,28 @@ class Trade(JoinedTableMixin, ActionWithMultipleDevices): user_to_comment = """The user that gets the device due this deal.""" price = Column(Float(decimal_return_scale=2), nullable=True) date = Column(db.TIMESTAMP(timezone=True)) + # offer = relationship("Offer", uselist=False, back_populates="Trade") -class Offer(Trade): +# class Offer(Trade): +class Offer(JoinedTableMixin, ActionWithMultipleDevices): """ActionTrade Offer one lot for to do one Trade. """ + # from ereuse_devicehub.resources.lot.models import Lot + user_from_id = db.Column(UUID(as_uuid=True), + db.ForeignKey(User.id), + nullable=False, + default=lambda: g.user.id) + user_from = db.relationship(User, primaryjoin=user_from_id == User.id) + user_from_comment = """The user that offers the device due this deal.""" + user_to_id = db.Column(UUID(as_uuid=True), + db.ForeignKey(User.id), + nullable=False, + default=lambda: g.user.id) + user_to = db.relationship(User, primaryjoin=user_to_id == User.id) + user_to_comment = """The user that gets the device due this deal.""" + price = Column(Float(decimal_return_scale=2), nullable=True) + date = Column(db.TIMESTAMP(timezone=True)) document_id = Column(CIText()) document_id.comment = """The id of one document like invoice so they can be linked.""" accepted_by_from = Column(Boolean, default=False) @@ -1478,9 +1494,16 @@ class Offer(Trade): nullable=True) trade = db.relationship(Trade, primaryjoin=trade_id == Trade.id) lot_id = db.Column(UUID(as_uuid=True), - db.ForeignKey(Trade.id), + db.ForeignKey('information_schema.lot.id'), nullable=True) - # lot = db.relationship(Lot, primaryjoin=lot_id == Lot.id) + # lot = relationship("Lot", back_populates="offer") + # lot = db.relationship('Lot', primaryjoin='lot_id' == 'Lot.id') + # lot = relationship('Lot', + # backref=backref('lot_one', + # lazy=True, + # cascade=CASCADE_OWN, + # **_sorted_actions), + # primaryjoin=lot_id == 'Lot.id') class InitTransfer(Trade): diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index f3a3f1fa..00970291 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -470,6 +470,9 @@ class Trade(ActionWithMultipleDevices): data['user_to_id'] = user_to.id for dev in data['devices']: dev.owner_id = user_to.id + if hasattr(dev, 'components'): + for c in dev.components: + c.owner_id = user_to.id @validates_schema def validate_user_from_id(self, data: dict): @@ -481,10 +484,14 @@ class Trade(ActionWithMultipleDevices): class Offer(Trade): __doc__ = m.Trade.__doc__ document_id = SanitizedStr(validate=Length(max=STR_SIZE), data_key='documentID', required=False) - accepted_by_from = Boolean(missing=True, description=m.Offer.accepted_by_from.comment) - accepted_by_to = Boolean(missing=True, description=m.Offer.accepted_by_to.comment) + accepted_by_from = Boolean(missing=False, description=m.Offer.accepted_by_from.comment) + accepted_by_to = Boolean(missing=False, description=m.Offer.accepted_by_to.comment) lot = NestedOn('Lot', dump_only=True) trade = NestedOn('Trade', dump_only=True) + # lot = NestedOn('Lot', + # many=False, + # required=True, + # only_query='id') class InitTransfer(Trade): diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py index a8d9d09d..bb74493a 100644 --- a/ereuse_devicehub/resources/action/views.py +++ b/ereuse_devicehub/resources/action/views.py @@ -253,6 +253,9 @@ class ActionView(View): return self.transfer_ownership() a = resource_def.schema.load(json) Model = db.Model._decl_class_registry.data[json['type']]() + import pdb; pdb.set_trace() + # a['lot_id'] = a['lot'].id + # a.pop('lot') action = Model(**a) db.session.add(action) db.session().final_flush() diff --git a/ereuse_devicehub/resources/device/states.py b/ereuse_devicehub/resources/device/states.py index 031b45b6..cbd4b9f4 100644 --- a/ereuse_devicehub/resources/device/states.py +++ b/ereuse_devicehub/resources/device/states.py @@ -23,6 +23,8 @@ class Trading(State): """Trading states. :cvar Reserved: The device has been reserved. + :cvar Offer: The devices has been offered for to do a Trade. + :cvar Trade: The devices has been changed of owner. :cvar Cancelled: The device has been cancelled. :cvar Sold: The device has been sold. :cvar Donated: The device is donated. @@ -34,6 +36,7 @@ class Trading(State): """ Reserved = e.Reserve Offer = e.Offer + Trade = e.Trade Cancelled = e.CancelTrade Sold = e.Sell Donated = e.Donate diff --git a/tests/test_action.py b/tests/test_action.py index 6e6398fe..62338b7f 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -609,7 +609,7 @@ def test_save_live_json(app: Devicehub, user: UserClient, client: Client): shutil.rmtree(tmp_snapshots) assert snapshot['debug'] == debug - + @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) @@ -627,12 +627,12 @@ def test_allocate(user: UserClient): """ Tests allocate """ snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) device_id = snapshot['device']['id'] - post_request = {"transaction": "ccc", + post_request = {"transaction": "ccc", "finalUserCode": "aabbcc", - "name": "John", + "name": "John", "severity": "Info", "endUsers": 1, - "devices": [device_id], + "devices": [device_id], "description": "aaa", "startTime": "2020-11-01T02:00:00+00:00", "endTime": "2020-12-01T02:00:00+00:00", @@ -672,12 +672,12 @@ def test_allocate_bad_dates(user: UserClient): device_id = snapshot['device']['id'] delay = timedelta(days=30) future = datetime.now().replace(tzinfo=tzutc()) + delay - post_request = {"transaction": "ccc", + post_request = {"transaction": "ccc", "finalUserCode": "aabbcc", - "name": "John", + "name": "John", "severity": "Info", "end_users": 1, - "devices": [device_id], + "devices": [device_id], "description": "aaa", "start_time": future, } @@ -771,7 +771,7 @@ def test_trade2(action_model_state: Tuple[Type[models.Action], states.Trading], @pytest.mark.mvp -def test_trade(user: UserClient, user2: UserClient): +def test_trade_endpoint(user: UserClient, user2: UserClient): """Tests POST one simple Trade between 2 users of the system.""" snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) device, _ = user.get(res=Device, item=snapshot['device']['id']) @@ -791,6 +791,37 @@ def test_trade(user: UserClient, user2: UserClient): assert device2['id'] == device['id'] +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_offer(user: UserClient): + from ereuse_devicehub.resources.user.models import User + from ereuse_devicehub.resources.agent.models import Person + from ereuse_devicehub.resources.lot.models import Lot + + user2 = User(email='baz@baz.cxm', password='baz') + user2.individuals.add(Person(name='Tommy')) + db.session.add(user2) + db.session.commit() + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + lot = Lot('MyLot') + lot.owner_id = user.user['id'] + device = Device.query.filter_by(id=snapshot['device']['id']).one() + lot.devices.add(device) + db.session.add(lot) + db.session.flush() + request_post = { + 'type': 'Offer', + 'devices': [device.id], + 'userTo': user2.email, + 'price': 0, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'accepted_by_from': True, + 'lot': lot.id + } + import pdb; pdb.set_trace() + action, _ = user.post(res=models.Action, data=request_post) + @pytest.mark.mvp @pytest.mark.usefixtures(conftest.auth_app_context.__name__)