Purchase form
This commit is contained in:
@@ -966,6 +966,101 @@ class Purchase(metaclass=PoolMeta):
|
||||
except (TypeError, ValueError):
|
||||
return 0.0
|
||||
|
||||
@staticmethod
|
||||
def _summary_decimal(value):
|
||||
if value in (None, ''):
|
||||
return Decimal('0')
|
||||
try:
|
||||
return Decimal(str(value))
|
||||
except Exception:
|
||||
return Decimal('0')
|
||||
|
||||
@classmethod
|
||||
def _summary_percent(cls, part, total):
|
||||
total = cls._summary_decimal(total)
|
||||
if not total:
|
||||
return 0.0
|
||||
part = cls._summary_decimal(part)
|
||||
percent = (part / total) * Decimal('100')
|
||||
percent = max(Decimal('0'), min(Decimal('100'), percent))
|
||||
return float(round(percent, 2))
|
||||
|
||||
@classmethod
|
||||
def _line_priced_percent(cls, line):
|
||||
price_type = getattr(line, 'price_type', None)
|
||||
if price_type in {'cash', 'priced', 'efp'}:
|
||||
return 100.0
|
||||
progress = getattr(line, 'progress', None)
|
||||
if progress is None and hasattr(line, 'get_progress'):
|
||||
progress = line.get_progress('progress')
|
||||
return cls._summary_percent(progress or 0, 1)
|
||||
|
||||
@classmethod
|
||||
def _line_hedged_percent(cls, line, quantity):
|
||||
hedged_quantity = Decimal('0')
|
||||
for derivative in (getattr(line, 'derivatives', None) or []):
|
||||
der_quantity = getattr(derivative, 'quantity', None)
|
||||
if der_quantity is None and hasattr(derivative, 'get_qt'):
|
||||
der_quantity = derivative.get_qt('quantity')
|
||||
hedged_quantity += abs(cls._summary_decimal(der_quantity))
|
||||
return cls._summary_percent(hedged_quantity, quantity)
|
||||
|
||||
@classmethod
|
||||
def _line_invoice_quantity_percent(cls, line, quantity, states=None):
|
||||
invoiced_quantity = Decimal('0')
|
||||
Uom = Pool().get('product.uom')
|
||||
for invoice_line in (getattr(line, 'invoice_lines', None) or []):
|
||||
invoice = getattr(invoice_line, 'invoice', None)
|
||||
invoice_state = getattr(invoice, 'state', None)
|
||||
if (not invoice or invoice_state == 'cancelled'
|
||||
or (states and invoice_state not in states)
|
||||
or getattr(invoice_line, 'type', 'line') != 'line'):
|
||||
continue
|
||||
invoice_quantity = cls._summary_decimal(
|
||||
getattr(invoice_line, 'quantity', None))
|
||||
invoice_unit = getattr(invoice_line, 'unit', None) or getattr(
|
||||
line, 'unit', None)
|
||||
line_unit = getattr(line, 'unit', None)
|
||||
if invoice_unit and line_unit and invoice_unit != line_unit:
|
||||
invoice_quantity = cls._summary_decimal(Uom.compute_qty(
|
||||
invoice_unit, float(invoice_quantity), line_unit))
|
||||
invoiced_quantity += abs(invoice_quantity)
|
||||
return cls._summary_percent(invoiced_quantity, quantity)
|
||||
|
||||
@classmethod
|
||||
def _line_period_name(cls, line):
|
||||
period = getattr(line, 'del_period', None)
|
||||
return getattr(period, 'rec_name', None) or getattr(period, 'name', '') or ''
|
||||
|
||||
@classmethod
|
||||
def _line_amount_value(cls, line):
|
||||
amount = getattr(line, 'amount', None)
|
||||
if amount is None and hasattr(line, 'on_change_with_amount'):
|
||||
amount = line.on_change_with_amount()
|
||||
return cls._summary_decimal(amount)
|
||||
|
||||
@classmethod
|
||||
def _line_pnl_values(cls, purchase, line):
|
||||
line_id = getattr(line, 'id', None)
|
||||
pnl = Decimal('0')
|
||||
mtm = Decimal('0')
|
||||
records = (
|
||||
getattr(purchase, 'pnl', None)
|
||||
if getattr(purchase, 'group_pnl', False)
|
||||
else getattr(purchase, 'pnl_', None))
|
||||
for record in (records or []):
|
||||
record_line = getattr(record, 'r_line', None) or getattr(
|
||||
record, 'line', None)
|
||||
if line_id and getattr(record_line, 'id', None) != line_id:
|
||||
continue
|
||||
pnl += cls._summary_decimal(
|
||||
getattr(record, 'r_pnl', None)
|
||||
if hasattr(record, 'r_pnl') else getattr(record, 'pnl', None))
|
||||
mtm += cls._summary_decimal(
|
||||
getattr(record, 'r_mtm', None)
|
||||
if hasattr(record, 'r_mtm') else getattr(record, 'mtm', None))
|
||||
return pnl, mtm
|
||||
|
||||
def get_execution_summary_viewer(self, name=None):
|
||||
data = self._get_purchase_execution_summary_data()
|
||||
data = dict(data, type='execution-summary')
|
||||
@@ -1158,6 +1253,8 @@ class Purchase(metaclass=PoolMeta):
|
||||
]
|
||||
unit = getattr(getattr(line, 'unit', None), 'rec_name', '') or ''
|
||||
product = getattr(getattr(line, 'product', None), 'rec_name', '') or ''
|
||||
amount = self._line_amount_value(line)
|
||||
line_pnl, line_mtm = self._line_pnl_values(self, line)
|
||||
route = (shipped_routes[0] if shipped_routes else '%s > %s' % (
|
||||
getattr(getattr(self, 'from_location', None), 'rec_name', None)
|
||||
or '-',
|
||||
@@ -1169,8 +1266,17 @@ class Purchase(metaclass=PoolMeta):
|
||||
'product': product,
|
||||
'physical': shipped,
|
||||
'quantity': quantity,
|
||||
'period': self._line_period_name(line),
|
||||
'matched': matched,
|
||||
'shipped': shipped,
|
||||
'priced': self._line_priced_percent(line),
|
||||
'hedged': self._line_hedged_percent(line, quantity),
|
||||
'invoiced': self._line_invoice_quantity_percent(line, quantity),
|
||||
'paid': self._line_invoice_quantity_percent(
|
||||
line, quantity, states={'paid'}),
|
||||
'pnl': self._json_decimal(line_pnl),
|
||||
'amount': self._json_decimal(amount),
|
||||
'mtm': self._json_decimal(line_mtm),
|
||||
'open': max(quantity - shipped, 0.0),
|
||||
'unit': unit,
|
||||
'lots': lots_count,
|
||||
@@ -1185,6 +1291,9 @@ class Purchase(metaclass=PoolMeta):
|
||||
totals['shipped'] += shipped
|
||||
totals['open'] += max(quantity - shipped, 0.0)
|
||||
totals['lines'] += 1
|
||||
totals['amount'] += float(amount)
|
||||
totals['pnl'] += float(line_pnl)
|
||||
totals['mtm'] += float(line_mtm)
|
||||
|
||||
return {
|
||||
'unit': rows[0]['unit'] if rows else '',
|
||||
@@ -1295,11 +1404,15 @@ class Purchase(metaclass=PoolMeta):
|
||||
return activity
|
||||
|
||||
def get_purchase_summary_data(self, name=None):
|
||||
execution = self._get_purchase_execution_summary_data()
|
||||
data = {
|
||||
"currency": getattr(getattr(self, 'currency', None), 'code', None)
|
||||
or '',
|
||||
"map": self._get_purchase_map_summary_data(),
|
||||
"execution": self._get_purchase_execution_summary_data(),
|
||||
"execution": execution,
|
||||
"amount": {
|
||||
"value": execution.get('totals', {}).get('amount', 0),
|
||||
},
|
||||
"activity": self._get_purchase_activity_summary_data(),
|
||||
"approval": {
|
||||
"status": "need_approval",
|
||||
|
||||
@@ -148,6 +148,12 @@ this repository contains the full copyright notices and license terms. -->
|
||||
view_ids="purchase_trade.fee_view_tree_sequence,purchase_trade.fee_view_form"/>
|
||||
<button name="apply_default_fees" icon="tryton-launch"/>
|
||||
</group>
|
||||
<group id="line_pricing" string="Pricing"
|
||||
colspan="12" col="1" panel="card" icon="tryton-public"
|
||||
xalign="0" yalign="0"
|
||||
col_widths="1fr">
|
||||
<field name="price_pricing" colspan="1" height="180"/>
|
||||
</group>
|
||||
<group id="attributes_description" string="Description"
|
||||
colspan="12" col="1" panel="card" icon="tryton-note"
|
||||
xalign="0" yalign="0"
|
||||
@@ -242,12 +248,9 @@ this repository contains the full copyright notices and license terms. -->
|
||||
</page>
|
||||
<page string="Pricing" col="4" id="pricing">
|
||||
<notebook colspan="4">
|
||||
<page string="Components" col="4" id="components">
|
||||
<field name="price_components" mode="tree,form" view_ids="purchase_trade.component_view_tree_sequence,purchase_trade.component_view_form"/>
|
||||
</page>
|
||||
<page string="Pricing dates" col="4" id="pricing_date">
|
||||
<field name="price_pricing" />
|
||||
</page>
|
||||
<page string="Components" col="4" id="components">
|
||||
<field name="price_components" mode="tree,form" view_ids="purchase_trade.component_view_tree_sequence,purchase_trade.component_view_form"/>
|
||||
</page>
|
||||
<page string="Summary" col="4" id="summary">
|
||||
<field name="price_summary" />
|
||||
</page>
|
||||
|
||||
Reference in New Issue
Block a user