From 35e891bf5d0618210865f6f39766487dad15bba2 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 11 Oct 2021 14:11:56 +0200 Subject: [PATCH 1/7] trace in metrics --- ereuse_devicehub/resources/device/models.py | 43 ++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index f27a97d8..2b21734f 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -467,7 +467,7 @@ class Device(Thing): """ actions = copy.copy(self.actions) actions.sort(key=lambda x: x.created) - allocates = [] + allocates = [] lifetime = 0 for act in actions: if act.type == 'Snapshot': @@ -479,6 +479,12 @@ class Device(Thing): if act.type == 'Allocate': allo = {'type': 'Allocate', + 'action_type': 'Status', + 'status_receiver': 'Use', + 'trade_supplier': '', + 'trade_receiver': '', + 'trade_confirmed': '', + 'action_create_by': 'Receiver', 'devicehubID': self.devicehub_id, 'finalUserCode': act.final_user_code, 'numEndUsers': act.end_users, @@ -501,6 +507,12 @@ class Device(Thing): if act.type == 'Deallocate': deallo = {'type': 'Deallocate', 'devicehubID': self.devicehub_id, + 'action_type': 'Status', + 'status_receiver': 'Use', + 'trade_supplier': '', + 'trade_receiver': '', + 'trade_confirmed': '', + 'action_create_by': 'Receiver', 'finalUserCode': '', 'numEndUsers': '', 'hid': self.hid, @@ -510,6 +522,35 @@ class Device(Thing): 'usageTimeAllocate': 0} allocates.append(deallo) + if act.type == 'Trade': + confirm = False + if hasattr(act, 'acceptances'): + accept = act.acceptances[-1] + if accept.t == 'Confirm' and accept.user == act.user_to: + confirm = True + + action_create_by = 'Receiver' + if act.author == act.user_from: + action_create_by = 'Supplier' + trade = {'type': 'Trade', + 'action_type': 'Trade', + 'trade_supplier': act.user_from, + 'trade_receiver': act.user_to, + 'trade_confirmed': confirm, + 'action_create_by': action_create_by, + 'trade_confirmed': confirm, + 'devicehubID': self.devicehub_id, + 'finalUserCode': '', + 'numEndUsers': '', + 'hid': self.hid, + 'liveCreate': 0, + 'usageTimeHdd': lifetime, + 'start': act.start_time, + 'status_receiver': 'Use', + 'usageTimeAllocate': 0 + } + allocates.append(trade) + return allocates def __lt__(self, other): From 5e9b9bf08ddf127ed56c7b27d8f896843822d0fb Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 14 Oct 2021 12:56:33 +0200 Subject: [PATCH 2/7] new metrics --- ereuse_devicehub/resources/device/metrics.py | 174 +++++++++++++++++++ ereuse_devicehub/resources/device/models.py | 102 +---------- tests/test_metrics.py | 54 ++++++ 3 files changed, 237 insertions(+), 93 deletions(-) create mode 100644 ereuse_devicehub/resources/device/metrics.py diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py new file mode 100644 index 00000000..c8646775 --- /dev/null +++ b/ereuse_devicehub/resources/device/metrics.py @@ -0,0 +1,174 @@ +import copy + + +class Metrics: + """we want get the data metrics of one device""" + + def __init__(self, device): + self.hid = device.hid + self.devicehub_id = device.devicehub_id + self.actions = copy.copy(device.actions) + self.actions.sort(key=lambda x: x.created) + self.rows = [] + self.lifetime = 0 + self.last_trade = None + self.action_create_by = 'Receiver' + self.status_receiver = 'Use' + self.status_supplier = '' + self.act = None + self.end_users = 0 + self.final_user_code = '' + + def get_template_row(self): + """ + This is a template of a row. + """ + return {'type': '', + 'action_type': 'Status', + 'status_receiver': self.status_receiver, + 'status_supplier': self.status_supplier, + 'trade_supplier': '', + 'trade_receiver': self.act.author, + 'trade_confirmed': '', + 'action_create_by': self.action_create_by, + 'devicehubID': self.devicehub_id, + 'hid': self.hid, + 'finalUserCode': '', + 'numEndUsers': 0, + 'liveCreate': 0, + 'usageTimeHdd': self.lifetime, + 'start': self.act.created, + 'usageTimeAllocate': 0} + + def get_action_status(self): + """ + Mark the status of one device. + If exist one trade before this action, then modify the trade action + else, create one row new. + """ + self.status_receiver = self.act.type + self.status_supplier = '' + if self.act.author != self.act.rol_user: + # It is neccesary exist one trade action before + self.last_trade['status_supplier'] = self.act.type + self.last_trade['status_supplier_created'] = self.act.created + return + + if self.last_trade: + # if exist one trade action before + self.last_trade['status_receiver'] = self.act.type + self.last_trade['status_receiver_created'] = self.act.created + return + + # If not exist any trade action for this device + self.action_create_by = 'Receiver' + row = self.get_template_row() + row['type'] = 'Status' + self.rows.append(row) + + def get_snapshot(self): + """ + If there are one snapshot get the last lifetime for to do a calcul of time of use. + """ + lifestimes = self.act.get_last_lifetimes() + if lifestimes: + self.lifetime = lifestimes[0]['lifetime'] + + def get_allocate(self): + """ + If the action is one Allocate, need modify the row base. + """ + self.end_users = self.act.end_users + self.final_user_code = self.act.final_user_code + row = self.get_template_row() + row['type'] = 'Allocate' + row['trade_supplier'] = '' + row['finalUserCode'] = self.final_user_code + row['numEndUsers'] = self.end_users + row['start'] = self.act.start_time + row['usageTimeAllocate'] = self.lifetime + self.rows.append(row) + + def get_live(self): + """ + If the action is one Live, need modify the row base. + """ + row = self.get_template_row() + row['type'] = 'Live' + row['finalUserCode'] = self.final_user_code + row['numEndUsers'] = self.end_users + row['start'] = self.act.start_time + row['usageTimeAllocate'] = self.lifetime + row['liveCreate'] = self.act.created + if self.act.usage_time_hdd: + row['usageTimeHdd'] = self.act.usage_time_hdd.total_seconds() / 3600 + self.rows.append(row) + + def get_deallocate(self): + """ + If the action is one Dellocate, need modify the row base. + """ + row = self.get_template_row() + row['type'] = 'Deallocate' + row['start'] = self.act.start_time + self.rows.append(row) + + def get_confirms(self): + """ + if the action is one trade action, is possible than have a list of confirmations. + Get the doble confirm for to know if this trade is confirmed or not. + """ + if hasattr(self.act, 'acceptances'): + accept = self.act.acceptances[-1] + if accept.t == 'Confirm' and accept.user == self.act.user_to: + return True + return False + + def get_trade(self): + """ + If this action is a trade action modify the base row. + """ + if self.act.author == self.act.user_from: + self.action_create_by = 'Supplier' + row = self.get_template_row() + self.last_trade = row + row['type'] = 'Trade' + row['action_type'] = 'Trade' + row['trade_supplier'] = self.act.user_from + row['trade_receiver'] = self.act.user_to + row['self.status_receiver'] = self.status_receiver + row['self.status_supplier'] = self.status_supplier + row['trade_confirmed'] = self.get_confirms() + self.rows.append(row) + + def get_metrics(self): + """ + This method get a list of values for calculate a metrics from a spreadsheet + """ + for act in self.actions: + self.act = act + if act.type in ['Use', 'Refurbish', 'Recycling', 'Management']: + self.get_action_status() + continue + + if act.type == 'Snapshot': + self.get_snapshot() + continue + + if act.type == 'Allocate': + self.get_allocate() + continue + + if act.type == 'Live': + self.get_live() + continue + + if act.type == 'Deallocate': + self.get_deallocate() + continue + + if act.type == 'Trade': + self.get_trade() + continue + + return self.rows diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 7c847cbf..d940534d 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -34,6 +34,7 @@ from ereuse_devicehub.resources.enums import BatteryTechnology, CameraFacing, Co DataStorageInterface, DisplayTech, PrinterTechnology, RamFormat, RamInterface, Severity, TransferState from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing, listener_reset_field_updated_in_actual_time from ereuse_devicehub.resources.user.models import User +from ereuse_devicehub.resources.device.metrics import Metrics def create_code(context): @@ -206,10 +207,10 @@ class Device(Thing): if isinstance(c, ColumnProperty) and not getattr(c, 'foreign_keys', None) and c.key not in self._NON_PHYSICAL_PROPS} - + @property def public_properties(self) -> Dict[str, object or None]: - """Fields that describe the properties of a device than next show + """Fields that describe the properties of a device than next show in the public page. :return A dictionary: @@ -341,7 +342,7 @@ class Device(Thing): ac = self.last_action_trading if not ac: - return + return first_owner = self.which_user_put_this_device_in_trace() @@ -349,7 +350,7 @@ class Device(Thing): # can to do revoke_confirmed return confirm_revoke - if ac.type == revoke: + if ac.type == revoke: if ac.user == g.user: # can todo revoke_pending return revoke_pending @@ -505,93 +506,8 @@ class Device(Thing): """ This method get a list of values for calculate a metrics from a spreadsheet """ - actions = copy.copy(self.actions) - actions.sort(key=lambda x: x.created) - allocates = [] - lifetime = 0 - for act in actions: - if act.type == 'Snapshot': - snapshot = act - lifestimes = snapshot.get_last_lifetimes() - lifetime = 0 - if lifestimes: - lifetime = lifestimes[0]['lifetime'] - - if act.type == 'Allocate': - allo = {'type': 'Allocate', - 'action_type': 'Status', - 'status_receiver': 'Use', - 'trade_supplier': '', - 'trade_receiver': '', - 'trade_confirmed': '', - 'action_create_by': 'Receiver', - 'devicehubID': self.devicehub_id, - 'finalUserCode': act.final_user_code, - 'numEndUsers': act.end_users, - 'hid': self.hid, - 'liveCreate': 0, - 'usageTimeHdd': 0, - 'start': act.start_time, - 'usageTimeAllocate': lifetime} - allocates.append(allo) - - if act.type == 'Live': - allocate = copy.copy(allo) - allocate['type'] = 'Live' - allocate['liveCreate'] = act.created - allocate['usageTimeHdd'] = 0 - if act.usage_time_hdd: - allocate['usageTimeHdd'] = act.usage_time_hdd.total_seconds()/3600 - allocates.append(allocate) - - if act.type == 'Deallocate': - deallo = {'type': 'Deallocate', - 'devicehubID': self.devicehub_id, - 'action_type': 'Status', - 'status_receiver': 'Use', - 'trade_supplier': '', - 'trade_receiver': '', - 'trade_confirmed': '', - 'action_create_by': 'Receiver', - 'finalUserCode': '', - 'numEndUsers': '', - 'hid': self.hid, - 'liveCreate': 0, - 'usageTimeHdd': lifetime, - 'start': act.start_time, - 'usageTimeAllocate': 0} - allocates.append(deallo) - - if act.type == 'Trade': - confirm = False - if hasattr(act, 'acceptances'): - accept = act.acceptances[-1] - if accept.t == 'Confirm' and accept.user == act.user_to: - confirm = True - - action_create_by = 'Receiver' - if act.author == act.user_from: - action_create_by = 'Supplier' - trade = {'type': 'Trade', - 'action_type': 'Trade', - 'trade_supplier': act.user_from, - 'trade_receiver': act.user_to, - 'trade_confirmed': confirm, - 'action_create_by': action_create_by, - 'trade_confirmed': confirm, - 'devicehubID': self.devicehub_id, - 'finalUserCode': '', - 'numEndUsers': '', - 'hid': self.hid, - 'liveCreate': 0, - 'usageTimeHdd': lifetime, - 'start': act.start_time, - 'status_receiver': 'Use', - 'usageTimeAllocate': 0 - } - allocates.append(trade) - - return allocates + metrics = Metrics(self) + return metrics.get_metrics() def __lt__(self, other): return self.id < other.id @@ -790,7 +706,7 @@ class Computer(Device): return urls def add_mac_to_hid(self, components_snap=None): - """Returns the Naming.hid with the first mac of network adapter, + """Returns the Naming.hid with the first mac of network adapter, following an alphabetical order. """ self.set_hid() @@ -923,7 +839,7 @@ class Component(Device): """ assert self.hid is None, 'Don\'t use this method with a component that has HID' component = self.__class__.query \ - .filter_by(parent=parent, hid=None, owner_id=self.owner_id, + .filter_by(parent=parent, hid=None, owner_id=self.owner_id, **self.physical_properties) \ .filter(~Component.id.in_(blacklist)) \ .first() diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 54544328..aca7808c 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -2,6 +2,7 @@ import pytest from ereuse_devicehub.client import UserClient from ereuse_devicehub.resources.action import models as ma +from ereuse_devicehub.resources.documents import documents from tests import conftest from tests.conftest import file, yaml2json, json_encode @@ -120,3 +121,56 @@ def test_metrics_with_live_null(user: UserClient): res, _ = user.get("/metrics/") assert res == metrics + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_metrics_action_status(user: UserClient, user2: UserClient): + """ Checks one standard query of metrics """ + # Insert computer + lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') + snap, _ = user.post(json_encode(lenovo), res=ma.Snapshot) + action = {'type': ma.Use.t, 'devices': [snap['device']['id']]} + action_use, _ = user.post(action, res=ma.Action) + # res, _ = user.get("/metrics/") + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + import pdb; pdb.set_trace() + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_complet_metrics(user: UserClient, user2: UserClient): + """ Checks one standard query of metrics """ + # Insert computer + lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') + acer = yaml2json('acer.happy.battery.snapshot') + snap1, _ = user.post(json_encode(lenovo), res=ma.Snapshot) + snap2, _ = user.post(json_encode(acer), res=ma.Snapshot) + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + devices = [('id', snap1['device']['id']), + ('id', snap2['device']['id']) + ] + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices) + # request_post = { + # 'type': 'Trade', + # 'devices': [span1['device']['id'], snap2['device']['id']], + # 'userFromEmail': user2.email, + # 'userToEmail': user.email, + # 'price': 10, + # 'date': "2020-12-01T02:00:00+00:00", + # 'lot': lot['id'], + # 'confirms': True, + # } + + # user.post(res=models.Action, data=request_post) + + # ============================== + # Check metrics + metrics = {'allocateds': 1, 'live': 1} + res, _ = user.get("/metrics/") + assert res == metrics From 17f8aebb94d75e36177c0c9441108722d7bbace6 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 14 Oct 2021 18:13:20 +0200 Subject: [PATCH 3/7] fixing rows --- ereuse_devicehub/resources/device/metrics.py | 14 +++++++++----- .../resources/documents/device_row.py | 17 ++++++++++++++--- tests/test_metrics.py | 7 ++++++- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index c8646775..68a790b4 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -25,11 +25,15 @@ class Metrics: """ return {'type': '', 'action_type': 'Status', + 'document_name': '', 'status_receiver': self.status_receiver, 'status_supplier': self.status_supplier, + 'status_receiver_created': '', + 'status_supplier_created': '', 'trade_supplier': '', - 'trade_receiver': self.act.author, + 'trade_receiver': self.act.author.email, 'trade_confirmed': '', + 'trade_weight': 0, 'action_create_by': self.action_create_by, 'devicehubID': self.devicehub_id, 'hid': self.hid, @@ -54,6 +58,7 @@ class Metrics: self.last_trade['status_supplier_created'] = self.act.created return + self.action_create_by = 'Receiver' if self.last_trade: # if exist one trade action before self.last_trade['status_receiver'] = self.act.type @@ -61,9 +66,8 @@ class Metrics: return # If not exist any trade action for this device - self.action_create_by = 'Receiver' row = self.get_template_row() - row['type'] = 'Status' + row['status_receiver_created'] = self.act.created self.rows.append(row) def get_snapshot(self): @@ -134,8 +138,8 @@ class Metrics: self.last_trade = row row['type'] = 'Trade' row['action_type'] = 'Trade' - row['trade_supplier'] = self.act.user_from - row['trade_receiver'] = self.act.user_to + row['trade_supplier'] = self.act.user_from.email + row['trade_receiver'] = self.act.user_to.email row['self.status_receiver'] = self.status_receiver row['self.status_supplier'] = self.status_supplier row['trade_confirmed'] = self.get_confirms() diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index 4e683ef9..36c93819 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -427,9 +427,20 @@ class ActionRow(OrderedDict): # General information about allocates, deallocate and lives self['DHID'] = allocate['devicehubID'] self['Hid'] = allocate['hid'] - self['Start'] = allocate['start'] - self['FinalUserCode'] = allocate['finalUserCode'] - self['NumEndUsers'] = allocate['numEndUsers'] + self['Document-Name'] = allocate['document_name'] + self['Action-Type'] = allocate['action_type'] + self['Action-User-LastOwner-Supplier'] = allocate['trade_supplier'] + self['Action-User-LastOwner-Receiver'] = allocate['trade_receiver'] + self['Action-Create-By'] = allocate['action_create_by'] + self['Trade-Confirmed'] = allocate['trade_confirmed'] + self['Status-Supplier'] = allocate['status_supplier'] + self['Status-Receiver'] = allocate['status_receiver'] + self['Status Supplier – Created Date'] = allocate['status_supplier_created'] + self['Status Receiver – Created Date'] = allocate['status_receiver_created'] + self['Trade-Weight'] = allocate['trade_weight'] + self['Allocate-Start'] = allocate['start'] + self['Allocate-User-Code'] = allocate['finalUserCode'] + self['Allocate-NumUsers'] = allocate['numEndUsers'] self['UsageTimeAllocate'] = allocate['usageTimeAllocate'] self['Type'] = allocate['type'] self['LiveCreate'] = allocate['liveCreate'] diff --git a/tests/test_metrics.py b/tests/test_metrics.py index aca7808c..46c2a20c 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -136,7 +136,11 @@ def test_metrics_action_status(user: UserClient, user2: UserClient): item='actions/', accept='text/csv', query=[('filter', {'type': ['Computer']})]) - import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() + head = 'DHID;Hid;Document-Name;Action-Type;Action-User-LastOwner-Supplier;Action-User-LastOwner-Receiver;Action-Create-By;Trade-Confirmed;Status-Supplier;Status-Receiver;Status Supplier – Created Date;Status Receiver – Created Date;Trade-Weight;Allocate-Start;Allocate-User-Code;Allocate-NumUsers;UsageTimeAllocate;Type;LiveCreate;UsageTimeHdd\n' + body = '93652;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Status;;foo@foo.com;Receiver;;;Use;;' + assert head in csv_str + assert body in csv_str @pytest.mark.mvp @@ -156,6 +160,7 @@ def test_complet_metrics(user: UserClient, user2: UserClient): res=Lot, item='{}/devices'.format(lot['id']), query=devices) + import pdb; pdb.set_trace() # request_post = { # 'type': 'Trade', # 'devices': [span1['device']['id'], snap2['device']['id']], From 0eed8330cef4fdcde30aa85f9a57de7835f70acd Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 15 Oct 2021 15:04:58 +0200 Subject: [PATCH 4/7] adding metrics for documents --- ereuse_devicehub/resources/action/models.py | 11 +++++++ ereuse_devicehub/resources/device/metrics.py | 33 ++++++++++++++++--- ereuse_devicehub/resources/device/models.py | 2 +- .../resources/documents/documents.py | 18 ++++++++++ tests/test_metrics.py | 2 +- 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index 853fd49b..f2df237d 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -49,6 +49,7 @@ from ereuse_devicehub.resources.enums import AppearanceRange, BatteryHealth, Bio from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.resources.tradedocument.models import TradeDocument +from ereuse_devicehub.resources.device.metrics import TradeMetrics class JoinedTableMixin: @@ -1633,6 +1634,16 @@ class Trade(JoinedTableMixin, ActionWithMultipleTradeDocuments): cascade=CASCADE_OWN), primaryjoin='Trade.lot_id == Lot.id') + def get_metrics(self): + """ + This method get a list of values for calculate a metrics from a spreadsheet + """ + metrics = [] + for doc in self.documents: + m = TradeMetrics(document=doc, Trade=self) + metrics.append(m.get_metrics()) + return metrics + def __repr__(self) -> str: return '<{0.t} {0.id} executed by {0.author}>'.format(self) diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index 68a790b4..80840b87 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -1,12 +1,10 @@ import copy -class Metrics: +class MetricsMix: """we want get the data metrics of one device""" - def __init__(self, device): - self.hid = device.hid - self.devicehub_id = device.devicehub_id + def __init__(self, *args, **kwargs): self.actions = copy.copy(device.actions) self.actions.sort(key=lambda x: x.created) self.rows = [] @@ -44,6 +42,22 @@ class Metrics: 'start': self.act.created, 'usageTimeAllocate': 0} + def get_metrics(self): + """ + This method get a list of values for calculate a metrics from a spreadsheet + """ + return self.rows + + +class Metrics(MetricsMix): + """we want get the data metrics of one device""" + + def __init__(self, *args, **kwargs): + device = kwargs.pop('device') + super().__init__(*args, **kwargs) + self.hid = device.hid + self.devicehub_id = device.devicehub_id + def get_action_status(self): """ Mark the status of one device. @@ -176,3 +190,14 @@ class Metrics: continue return self.rows + + +class TradeMetrics(MetricsMix): + """we want get the data metrics of one device""" + + def __init__(self, *args, **kwargs): + document = kwargs.pop('document') + super().__init__(*args, **kwargs) + self.hid = document.hash + self.devicehub_id = '' + diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index d940534d..2322326a 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -506,7 +506,7 @@ class Device(Thing): """ This method get a list of values for calculate a metrics from a spreadsheet """ - metrics = Metrics(self) + metrics = Metrics(device=self) return metrics.get_metrics() def __lt__(self, other): diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index f6de8884..41606d0b 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -159,13 +159,31 @@ class ActionsDocumentView(DeviceView): data = StringIO() cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"') first = True + devs_id = [] for device in query: + devs_id.append(device.id) for allocate in device.get_metrics(): d = ActionRow(allocate) if first: cw.writerow(d.keys()) first = False cw.writerow(d.values()) + from ereuse_devicehub.resources.action.models import Trade + from ereuse_devicehub.resources.device.models import Device + # import pdb; pdb.set_trace() + query_trade = Trade.query.filter(Trade.devices.any(Device.id.in_(devs_id))).all() + doc_metrics = [] + + for trade in query_trade: + doc_metrics.extend(trade.get_metrics()) + + for data_row in doc_metrics: + row = ActionRow(data_row) + if first: + cw.writerow(row.keys()) + first = False + cw.writerow(row.values()) + bfile = data.getvalue().encode('utf-8') output = make_response(bfile) insert_hash(bfile) diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 46c2a20c..70c728d2 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -160,7 +160,7 @@ def test_complet_metrics(user: UserClient, user2: UserClient): res=Lot, item='{}/devices'.format(lot['id']), query=devices) - import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() # request_post = { # 'type': 'Trade', # 'devices': [span1['device']['id'], snap2['device']['id']], From 87f30a1391521a463cd5a13394d3ae2cd10a5d2e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 19 Oct 2021 18:19:25 +0200 Subject: [PATCH 5/7] adding metrics for tradeDocuments --- ereuse_devicehub/resources/action/models.py | 2 +- ereuse_devicehub/resources/device/metrics.py | 52 ++++++- .../resources/documents/device_row.py | 2 + .../resources/documents/documents.py | 21 ++- tests/test_metrics.py | 129 ++++++++++++++---- 5 files changed, 156 insertions(+), 50 deletions(-) diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index ce6e4e70..fbc05234 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -1640,7 +1640,7 @@ class Trade(JoinedTableMixin, ActionWithMultipleTradeDocuments): metrics = [] for doc in self.documents: m = TradeMetrics(document=doc, Trade=self) - metrics.append(m.get_metrics()) + metrics.extend(m.get_metrics()) return metrics def __repr__(self) -> str: diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index 80840b87..62500b8d 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -5,7 +5,6 @@ class MetricsMix: """we want get the data metrics of one device""" def __init__(self, *args, **kwargs): - self.actions = copy.copy(device.actions) self.actions.sort(key=lambda x: x.created) self.rows = [] self.lifetime = 0 @@ -53,10 +52,11 @@ class Metrics(MetricsMix): """we want get the data metrics of one device""" def __init__(self, *args, **kwargs): - device = kwargs.pop('device') + self.device = kwargs.pop('device') + self.actions = copy.copy(self.device.actions) super().__init__(*args, **kwargs) - self.hid = device.hid - self.devicehub_id = device.devicehub_id + self.hid = self.device.hid + self.devicehub_id = self.device.devicehub_id def get_action_status(self): """ @@ -196,8 +196,46 @@ class TradeMetrics(MetricsMix): """we want get the data metrics of one device""" def __init__(self, *args, **kwargs): - document = kwargs.pop('document') - super().__init__(*args, **kwargs) - self.hid = document.hash + self.document = kwargs.pop('document') + self.actions = copy.copy(self.document.actions) + self.hid = self.document.file_hash self.devicehub_id = '' + super().__init__(*args, **kwargs) + def get_metrics(self): + self.last_trade = next(x for x in self.actions if x.t == 'Trade') + self.act = self.last_trade + row = self.get_template_row() + + row['type'] = 'Trade-Document' + row['action_type'] = 'Trade-Document' + if self.document.weight: + row['type'] = 'Trade-Container' + row['action_type'] = 'Trade-Document' + + row['document_name'] = self.document.file_name + row['trade_supplier'] = self.last_trade.user_from.email + row['trade_receiver'] = self.last_trade.user_to.email + row['trade_confirmed'] = self.get_confirms() + row['self.status_receiver'] = '' + row['self.status_supplier'] = '' + row['trade_weight'] = self.document.weight + if self.last_trade.author == self.last_trade.user_from: + row['action_create_by'] = 'Supplier' + elif self.last_trade.author == self.last_trade.user_to: + row['action_create_by'] = 'Receiver' + + self.rows.append(row) + + return self.rows + + def get_confirms(self): + """ + if the action is one trade action, is possible than have a list of confirmations. + Get the doble confirm for to know if this trade is confirmed or not. + """ + if hasattr(self.last_trade, 'acceptances'): + accept = self.last_trade.acceptances[-1] + if accept.t == 'Confirm' and accept.user == self.last_trade.user_to: + return True + return False diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index 36c93819..fe021c3d 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -414,6 +414,8 @@ def none2str(string): return '' return format(string) + + def get_action(component, action): """ Filter one action from a component or return None """ result = [a for a in component.actions if a.type == action] diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 41606d0b..4e25c007 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -32,6 +32,8 @@ from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow InternalStatsRow) from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot +from ereuse_devicehub.resources.action.models import Trade +from ereuse_devicehub.resources.device.models import Device from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash @@ -168,21 +170,16 @@ class ActionsDocumentView(DeviceView): cw.writerow(d.keys()) first = False cw.writerow(d.values()) - from ereuse_devicehub.resources.action.models import Trade - from ereuse_devicehub.resources.device.models import Device - # import pdb; pdb.set_trace() query_trade = Trade.query.filter(Trade.devices.any(Device.id.in_(devs_id))).all() - doc_metrics = [] for trade in query_trade: - doc_metrics.extend(trade.get_metrics()) - - for data_row in doc_metrics: - row = ActionRow(data_row) - if first: - cw.writerow(row.keys()) - first = False - cw.writerow(row.values()) + data_rows = trade.get_metrics() + for row in data_rows: + d = ActionRow(row) + if first: + cw.writerow(d.keys()) + first = False + cw.writerow(d.values()) bfile = data.getvalue().encode('utf-8') output = make_response(bfile) diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 70c728d2..c8641e3f 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -3,6 +3,8 @@ import pytest from ereuse_devicehub.client import UserClient from ereuse_devicehub.resources.action import models as ma from ereuse_devicehub.resources.documents import documents +from ereuse_devicehub.resources.lot.models import Lot +from ereuse_devicehub.resources.tradedocument.models import TradeDocument from tests import conftest from tests.conftest import file, yaml2json, json_encode @@ -21,8 +23,7 @@ def test_simple_metrics(user: UserClient): "finalUserCode": "abcdefjhi", "devices": [device_id], "description": "aaa", "startTime": "2020-11-01T02:00:00+00:00", - "endTime": "2020-12-01T02:00:00+00:00" - } + "endTime": "2020-12-01T02:00:00+00:00"} # Create Allocate user.post(res=ma.Allocate, data=post_request) @@ -66,8 +67,7 @@ def test_second_hdd_metrics(user: UserClient): "finalUserCode": "abcdefjhi", "devices": [device_id], "description": "aaa", "startTime": "2020-11-01T02:00:00+00:00", - "endTime": "2020-12-01T02:00:00+00:00" - } + "endTime": "2020-12-01T02:00:00+00:00"} # Create Allocate user.post(res=ma.Allocate, data=post_request) @@ -110,8 +110,7 @@ def test_metrics_with_live_null(user: UserClient): "finalUserCode": "abcdefjhi", "devices": [device_id], "description": "aaa", "startTime": "2020-11-01T02:00:00+00:00", - "endTime": "2020-12-01T02:00:00+00:00" - } + "endTime": "2020-12-01T02:00:00+00:00"} # Create Allocate user.post(res=ma.Allocate, data=post_request) @@ -125,18 +124,16 @@ def test_metrics_with_live_null(user: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_metrics_action_status(user: UserClient, user2: UserClient): - """ Checks one standard query of metrics """ + """ Checks one standard query of metrics.""" # Insert computer lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') snap, _ = user.post(json_encode(lenovo), res=ma.Snapshot) action = {'type': ma.Use.t, 'devices': [snap['device']['id']]} action_use, _ = user.post(action, res=ma.Action) - # res, _ = user.get("/metrics/") csv_str, _ = user.get(res=documents.DocumentDef.t, item='actions/', accept='text/csv', query=[('filter', {'type': ['Computer']})]) - # import pdb; pdb.set_trace() head = 'DHID;Hid;Document-Name;Action-Type;Action-User-LastOwner-Supplier;Action-User-LastOwner-Receiver;Action-Create-By;Trade-Confirmed;Status-Supplier;Status-Receiver;Status Supplier – Created Date;Status Receiver – Created Date;Trade-Weight;Allocate-Start;Allocate-User-Code;Allocate-NumUsers;UsageTimeAllocate;Type;LiveCreate;UsageTimeHdd\n' body = '93652;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Status;;foo@foo.com;Receiver;;;Use;;' assert head in csv_str @@ -145,8 +142,8 @@ def test_metrics_action_status(user: UserClient, user2: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) -def test_complet_metrics(user: UserClient, user2: UserClient): - """ Checks one standard query of metrics """ +def test_complet_metrics_with_trade(user: UserClient, user2: UserClient): + """ Checks one standard query of metrics in a trade enviroment.""" # Insert computer lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') acer = yaml2json('acer.happy.battery.snapshot') @@ -154,28 +151,100 @@ def test_complet_metrics(user: UserClient, user2: UserClient): snap2, _ = user.post(json_encode(acer), res=ma.Snapshot) lot, _ = user.post({'name': 'MyLot'}, res=Lot) devices = [('id', snap1['device']['id']), - ('id', snap2['device']['id']) - ] + ('id', snap2['device']['id'])] lot, _ = user.post({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices) - # import pdb; pdb.set_trace() - # request_post = { - # 'type': 'Trade', - # 'devices': [span1['device']['id'], snap2['device']['id']], - # 'userFromEmail': user2.email, - # 'userToEmail': user.email, - # 'price': 10, - # 'date': "2020-12-01T02:00:00+00:00", - # 'lot': lot['id'], - # 'confirms': True, - # } + request_post = { + 'type': 'Trade', + 'devices': [snap1['device']['id'], snap2['device']['id']], + 'userFromEmail': user.email, + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'lot': lot['id'], + 'confirms': True, + } - # user.post(res=models.Action, data=request_post) + user.post(res=ma.Action, data=request_post) - # ============================== - # Check metrics - metrics = {'allocateds': 1, 'live': 1} - res, _ = user.get("/metrics/") - assert res == metrics + action = {'type': ma.Refurbish.t, 'devices': [snap1['device']['id']]} + action_use, _ = user.post(action, res=ma.Action) + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + + body1_lenovo = '93652;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Trade;foo@foo.com;foo2@foo.com;Supplier;False;Refurbish;Use;' + body2_lenovo = ';;0;0;Trade;0;0\n' + + body1_acer = 'J2MA2;laptop-acer-aohappy-lusea0d010038879a01601-00:26:c7:8e:cb:8c;;Trade;foo@foo.com;foo2@foo.com;Supplier;False;;Use;;;0;' + body2_acer = ';;0;0;Trade;0;4692.0\n' + + assert body1_lenovo in csv_str + assert body2_lenovo in csv_str + assert body1_acer in csv_str + assert body2_acer in csv_str + + # User2 mark this device as Refurbish + action = {'type': ma.Refurbish.t, 'devices': [snap1['device']['id']]} + action_use2, _ = user2.post(action, res=ma.Action) + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + + body2_lenovo = ';Refurbish;0;0;Trade;0;0\n' + body2_acer = ';Refurbish;0;0;Trade;0;4692.0\n' + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_metrics_action_status_for_containers(user: UserClient, user2: UserClient): + """ Checks one standard query of metrics for a container.""" + # Insert computer + lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') + snap, _ = user.post(json_encode(lenovo), res=ma.Snapshot) + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + devices = [('id', snap['device']['id'])] + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices) + request_post = { + 'type': 'Trade', + 'devices': [snap['device']['id']], + 'userFromEmail': user.email, + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'lot': lot['id'], + 'confirms': True, + } + + user.post(res=ma.Action, data=request_post) + + request_post = { + 'filename': 'test.pdf', + 'hash': 'bbbbbbbb', + 'url': 'http://www.ereuse.org/', + 'weight': 150, + 'lot': lot['id'] + } + tradedocument, _ = user.post(res=TradeDocument, data=request_post) + action = {'type': ma.Recycling.t, 'devices': [], 'documents': [tradedocument['id']]} + action, _ = user.post(action, res=ma.Action) + trade = TradeDocument.query.one() + + assert str(trade.actions[-1].id) == action['id'] + + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + + body1 = '\n;bbbbbbbb;test.pdf;Trade-Document;foo@foo.com;foo2@foo.com;Supplier;False;;Use;;;150.0;' + body2 = ';;0;0;Trade-Container;0;0\n' + assert body1 in csv_str + assert body2 in csv_str From f099a579fbbb77d25875e0bd39346e932c205767 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 19 Oct 2021 19:25:17 +0200 Subject: [PATCH 6/7] fixing rows --- ereuse_devicehub/resources/device/metrics.py | 13 +++++++------ ereuse_devicehub/resources/documents/device_row.py | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index 62500b8d..eaa72f04 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -38,7 +38,8 @@ class MetricsMix: 'numEndUsers': 0, 'liveCreate': 0, 'usageTimeHdd': self.lifetime, - 'start': self.act.created, + 'created': self.act.created, + 'start': '', 'usageTimeAllocate': 0} def get_metrics(self): @@ -211,14 +212,14 @@ class TradeMetrics(MetricsMix): row['action_type'] = 'Trade-Document' if self.document.weight: row['type'] = 'Trade-Container' - row['action_type'] = 'Trade-Document' + row['action_type'] = 'Trade-Container' row['document_name'] = self.document.file_name row['trade_supplier'] = self.last_trade.user_from.email row['trade_receiver'] = self.last_trade.user_to.email row['trade_confirmed'] = self.get_confirms() - row['self.status_receiver'] = '' - row['self.status_supplier'] = '' + row['status_receiver'] = '' + row['status_supplier'] = '' row['trade_weight'] = self.document.weight if self.last_trade.author == self.last_trade.user_from: row['action_create_by'] = 'Supplier' @@ -234,8 +235,8 @@ class TradeMetrics(MetricsMix): if the action is one trade action, is possible than have a list of confirmations. Get the doble confirm for to know if this trade is confirmed or not. """ - if hasattr(self.last_trade, 'acceptances'): - accept = self.last_trade.acceptances[-1] + if hasattr(self.last_trade, 'acceptances_document'): + accept = self.last_trade.acceptances_document[-1] if accept.t == 'Confirm' and accept.user == self.last_trade.user_to: return True return False diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index fe021c3d..de550d91 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -440,6 +440,7 @@ class ActionRow(OrderedDict): self['Status Supplier – Created Date'] = allocate['status_supplier_created'] self['Status Receiver – Created Date'] = allocate['status_receiver_created'] self['Trade-Weight'] = allocate['trade_weight'] + self['Action-Create'] = allocate['created'] self['Allocate-Start'] = allocate['start'] self['Allocate-User-Code'] = allocate['finalUserCode'] self['Allocate-NumUsers'] = allocate['numEndUsers'] From 7c6b20597b4787ff3d0f5e0f20c637949ee2d9d1 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 20 Oct 2021 14:53:33 +0200 Subject: [PATCH 7/7] fixing supplier permitions --- .../resources/documents/documents.py | 20 +++---- tests/test_metrics.py | 59 +++++++++++++++++-- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 4e25c007..bb7a4834 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -3,11 +3,9 @@ import enum import uuid import time import datetime -import pathlib from collections import OrderedDict from io import StringIO from typing import Callable, Iterable, Tuple -from decouple import config import boltons import flask @@ -92,7 +90,6 @@ class DocumentView(DeviceView): res = flask.make_response(template) return res - @staticmethod def erasure(query: db.Query): def erasures(): @@ -153,7 +150,7 @@ class DevicesDocumentView(DeviceView): class ActionsDocumentView(DeviceView): @cache(datetime.timedelta(minutes=1)) def find(self, args: dict): - query = (x for x in self.query(args) if x.owner_id == g.user.id) + query = (x for x in self.query(args)) return self.generate_post_csv(query) def generate_post_csv(self, query): @@ -200,11 +197,11 @@ class LotsDocumentView(LotView): cw = csv.writer(data) first = True for lot in query: - l = LotRow(lot) + _lot = LotRow(lot) if first: - cw.writerow(l.keys()) + cw.writerow(_lot.keys()) first = False - cw.writerow(l.values()) + cw.writerow(_lot.values()) bfile = data.getvalue().encode('utf-8') output = make_response(bfile) insert_hash(bfile) @@ -290,7 +287,7 @@ class StampsView(View): ok = '100% coincidence. The attached file contains data 100% existing in \ to our backend' result = ('Bad', bad) - mime = ['text/csv', 'application/pdf', 'text/plain','text/markdown', + mime = ['text/csv', 'application/pdf', 'text/plain', 'text/markdown', 'image/jpeg', 'image/png', 'text/html', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.oasis.opendocument.spreadsheet', @@ -319,9 +316,9 @@ class InternalStatsView(DeviceView): create = '{}-{}'.format(ac.created.year, ac.created.month) user = ac.author.email - if not user in d: - d[user] = {} - if not create in d[user]: + if user not in d: + d[user] = {} + if create not in d[user]: d[user][create] = [] d[user][create].append(ac) @@ -449,4 +446,3 @@ class DocumentDef(Resource): auth=app.auth) wbconf_view = app.auth.requires_auth(wbconf_view) self.add_url_rule('/wbconf/', view_func=wbconf_view, methods=get) - diff --git a/tests/test_metrics.py b/tests/test_metrics.py index c8641e3f..afeeba8b 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -134,7 +134,7 @@ def test_metrics_action_status(user: UserClient, user2: UserClient): item='actions/', accept='text/csv', query=[('filter', {'type': ['Computer']})]) - head = 'DHID;Hid;Document-Name;Action-Type;Action-User-LastOwner-Supplier;Action-User-LastOwner-Receiver;Action-Create-By;Trade-Confirmed;Status-Supplier;Status-Receiver;Status Supplier – Created Date;Status Receiver – Created Date;Trade-Weight;Allocate-Start;Allocate-User-Code;Allocate-NumUsers;UsageTimeAllocate;Type;LiveCreate;UsageTimeHdd\n' + head = 'DHID;Hid;Document-Name;Action-Type;Action-User-LastOwner-Supplier;Action-User-LastOwner-Receiver;Action-Create-By;Trade-Confirmed;Status-Supplier;Status-Receiver;Status Supplier – Created Date;Status Receiver – Created Date;Trade-Weight;Action-Create;Allocate-Start;Allocate-User-Code;Allocate-NumUsers;UsageTimeAllocate;Type;LiveCreate;UsageTimeHdd\n' body = '93652;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Status;;foo@foo.com;Receiver;;;Use;;' assert head in csv_str assert body in csv_str @@ -244,7 +244,56 @@ def test_metrics_action_status_for_containers(user: UserClient, user2: UserClien accept='text/csv', query=[('filter', {'type': ['Computer']})]) - body1 = '\n;bbbbbbbb;test.pdf;Trade-Document;foo@foo.com;foo2@foo.com;Supplier;False;;Use;;;150.0;' - body2 = ';;0;0;Trade-Container;0;0\n' - assert body1 in csv_str - assert body2 in csv_str + body1 = ';bbbbbbbb;test.pdf;Trade-Container;foo@foo.com;foo2@foo.com;Supplier;False;;;;;150.0;' + body2 = ';;0;0;Trade-Container;0;0' + assert len(csv_str.split('\n')) == 4 + assert body1 in csv_str.split('\n')[-2] + assert body2 in csv_str.split('\n')[-2] + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_visual_metrics_for_old_owners(user: UserClient, user2: UserClient): + """ Checks if one old owner can see the metrics in a trade enviroment.""" + # Insert computer + lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') + snap1, _ = user.post(json_encode(lenovo), res=ma.Snapshot) + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + devices = [('id', snap1['device']['id'])] + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices) + request_post = { + 'type': 'Trade', + 'devices': [snap1['device']['id']], + 'userFromEmail': user.email, + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'lot': lot['id'], + 'confirms': True, + } + trade, _ = user.post(res=ma.Action, data=request_post) + + request_confirm = { + 'type': 'Confirm', + 'action': trade['id'], + 'devices': [snap1['device']['id']] + } + user2.post(res=ma.Action, data=request_confirm) + + action = {'type': ma.Refurbish.t, 'devices': [snap1['device']['id']]} + action_use, _ = user.post(action, res=ma.Action) + csv_supplier, _ = user.get(res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + csv_receiver, _ = user2.get(res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + body = ';;0;0;Trade;0;0\n' + + assert body in csv_receiver + assert body in csv_supplier