diff --git a/modules/purchase_trade/purchase.py b/modules/purchase_trade/purchase.py
index 974b0da..1fdf136 100755
--- a/modules/purchase_trade/purchase.py
+++ b/modules/purchase_trade/purchase.py
@@ -383,6 +383,8 @@ class Purchase(metaclass=PoolMeta):
viewer = fields.Function(fields.Text(""),'get_viewer')
execution_summary_viewer = fields.Function(
fields.Text(""), 'get_execution_summary_viewer')
+ purchase_summary_data = fields.Function(
+ fields.Text("Purchase Summary"), 'get_purchase_summary_data')
doc_template = fields.Many2One('doc.template',"Template")
required_documents = fields.Many2Many(
'contract.document.type', 'purchase', 'doc_type', 'Required Documents')
@@ -965,6 +967,48 @@ class Purchase(metaclass=PoolMeta):
return 0.0
def get_execution_summary_viewer(self, name=None):
+ data = self._get_purchase_execution_summary_data()
+ data = dict(data, type='execution-summary')
+ return "d3:" + json.dumps(data)
+
+ @staticmethod
+ def _summary_number(value):
+ if value is None:
+ return None
+ try:
+ return float(value)
+ except (TypeError, ValueError):
+ return None
+
+ def _get_purchase_map_summary_data(self):
+ dep_name = ''
+ arr_name = ''
+ departure = None
+ arrival = None
+ if self.from_location:
+ dep_name = self.from_location.name or self.from_location.rec_name
+ departure = {
+ "name": dep_name,
+ "lat": self._summary_number(self.from_location.lat),
+ "lon": self._summary_number(self.from_location.lon),
+ }
+ if self.to_location:
+ arr_name = self.to_location.name or self.to_location.rec_name
+ arrival = {
+ "name": arr_name,
+ "lat": self._summary_number(self.to_location.lat),
+ "lon": self._summary_number(self.to_location.lon),
+ }
+ route = '%s > %s' % (dep_name or '-', arr_name or '-')
+ return {
+ "from": dep_name,
+ "to": arr_name,
+ "route": route,
+ "departures": [departure] if departure else [],
+ "arrivals": [arrival] if arrival else [],
+ }
+
+ def _get_purchase_execution_summary_data(self):
LotQt = Pool().get('lot.qt')
rows = []
totals = defaultdict(float)
@@ -1064,13 +1108,117 @@ class Purchase(metaclass=PoolMeta):
totals['open'] += max(quantity - shipped, 0.0)
totals['lines'] += 1
- data = {
- 'type': 'execution-summary',
+ return {
'unit': rows[0]['unit'] if rows else '',
'totals': dict(totals),
'rows': rows[:4],
}
- return "d3:" + json.dumps(data)
+
+ @staticmethod
+ def _json_decimal(value):
+ if value in (None, ''):
+ return None
+ return float(value)
+
+ def _get_purchase_pnl_summary_data(self):
+ currency = getattr(getattr(self, 'currency', None), 'code', None) or ''
+ graph = list(getattr(self, 'pnl_graph', None) or [])
+ graph = sorted(
+ graph, key=lambda line: (
+ getattr(line, 'valuation_date', None) or datetime.date.min,
+ getattr(line, 'id', 0) or 0))
+ if graph:
+ current = graph[-1]
+ previous = graph[-2] if len(graph) > 1 else None
+ pnl_value = getattr(current, 'pnl', None)
+ mtm_value = getattr(current, 'mtm', None)
+ previous_pnl = getattr(previous, 'pnl', None) if previous else None
+ previous_mtm = getattr(previous, 'mtm', None) if previous else None
+ pnl_change = (
+ pnl_value - previous_pnl
+ if pnl_value is not None and previous_pnl is not None
+ else None)
+ mtm_change = (
+ mtm_value - previous_mtm
+ if mtm_value is not None and previous_mtm is not None
+ else None)
+ return {
+ "pnl": {
+ "value": self._json_decimal(pnl_value),
+ "currency": currency,
+ "change_d1": self._json_decimal(pnl_change),
+ },
+ "mtm": {
+ "value": self._json_decimal(mtm_value),
+ "currency": currency,
+ "change": self._json_decimal(mtm_change),
+ },
+ }
+
+ pnl_value = Decimal('0')
+ mtm_value = Decimal('0')
+ if self.group_pnl:
+ lines = getattr(self, 'pnl', None) or []
+ for line in lines:
+ pnl_value += Decimal(str(getattr(line, 'r_pnl', 0) or 0))
+ mtm_value += Decimal(str(getattr(line, 'r_mtm', 0) or 0))
+ else:
+ lines = getattr(self, 'pnl_', None) or []
+ for line in lines:
+ pnl_value += Decimal(str(getattr(line, 'pnl', 0) or 0))
+ mtm_value += Decimal(str(getattr(line, 'mtm', 0) or 0))
+ return {
+ "pnl": {
+ "value": self._json_decimal(pnl_value),
+ "currency": currency,
+ "change_d1": None,
+ },
+ "mtm": {
+ "value": self._json_decimal(mtm_value),
+ "currency": currency,
+ "change": None,
+ },
+ }
+
+ def _get_purchase_activity_summary_data(self):
+ if not getattr(self, 'id', None):
+ return []
+ Log = Pool().get('ir.model.log')
+ logs = Log.search([
+ ('resource', '=', 'purchase.purchase,%s' % self.id),
+ ], limit=4)
+ event_types = {
+ 'write': 'info',
+ 'transition': 'approved',
+ 'button': 'success',
+ 'wizard': 'info',
+ 'delete': 'warning',
+ }
+ activity = []
+ for log in logs:
+ date = getattr(log, 'create_date', None)
+ user = getattr(getattr(log, 'user', None), 'rec_name', None) or ''
+ text = getattr(log, 'action', None) or getattr(log, 'target', None)
+ if not text:
+ text = getattr(log, 'event_string', None) or log.event
+ activity.append({
+ "type": event_types.get(log.event, 'info'),
+ "text": text,
+ "date": date.strftime('%d/%m/%Y') if date else '',
+ "user": user,
+ })
+ return activity
+
+ def get_purchase_summary_data(self, name=None):
+ data = {
+ "currency": getattr(getattr(self, 'currency', None), 'code', None)
+ or '',
+ "map": self._get_purchase_map_summary_data(),
+ "execution": self._get_purchase_execution_summary_data(),
+ "activity": self._get_purchase_activity_summary_data(),
+ }
+ data.update(self._get_purchase_pnl_summary_data())
+ return json.dumps(data)
def getLots(self):
if self.lines:
@@ -1078,9 +1226,15 @@ class Purchase(metaclass=PoolMeta):
return [l for l in self.lines.lots]
- @fields.depends('party','from_location','to_location')
- def on_change_with_viewer(self):
- return self.get_viewer()
+ @fields.depends('party','from_location','to_location')
+ def on_change_with_viewer(self):
+ return self.get_viewer()
+
+ @fields.depends(
+ 'currency', 'from_location', 'to_location', 'lines', 'pnl', 'pnl_',
+ 'pnl_graph', 'group_pnl')
+ def on_change_with_purchase_summary_data(self, name=None):
+ return self.get_purchase_summary_data()
@fields.depends('doc_template','required_documents')
def on_change_with_required_documents(self):
diff --git a/modules/purchase_trade/view/purchase_form.xml b/modules/purchase_trade/view/purchase_form.xml
index 16fea73..07ed28c 100755
--- a/modules/purchase_trade/view/purchase_form.xml
+++ b/modules/purchase_trade/view/purchase_form.xml
@@ -22,20 +22,14 @@ this repository contains the full copyright notices and license terms. -->
-