Purchase design

This commit is contained in:
2026-06-08 19:52:14 +02:00
parent 02a15c93de
commit c2f3d3995f
2 changed files with 123 additions and 25 deletions

View File

@@ -330,9 +330,11 @@ class Purchase(metaclass=PoolMeta):
forex = fields.One2Many('forex.cover.physical.contract','contract',"Forex",readonly=True)
plan = fields.Many2One('workflow.plan',"Name")
estimated_date = fields.One2Many('pricing.estimated','purchase',"Estimated date")
group_pnl = fields.Boolean("Group Pnl")
viewer = fields.Function(fields.Text(""),'get_viewer')
doc_template = fields.Many2One('doc.template',"Template")
group_pnl = fields.Boolean("Group Pnl")
viewer = fields.Function(fields.Text(""),'get_viewer')
execution_summary_viewer = fields.Function(
fields.Text(""), 'get_execution_summary_viewer')
doc_template = fields.Many2One('doc.template',"Template")
required_documents = fields.Many2Many(
'contract.document.type', 'purchase', 'doc_type', 'Required Documents')
analytic_dimensions = fields.One2Many(
@@ -638,7 +640,7 @@ class Purchase(metaclass=PoolMeta):
}
return "d3:" + json.dumps(data)
def get_viewer(self, name=None):
def get_viewer(self, name=None):
country_start = ''
dep_name = ''
arr_name = ''
@@ -690,10 +692,117 @@ class Purchase(metaclass=PoolMeta):
"departures": [departure],
"arrivals": [arrival]
}
return "d3:" + json.dumps(data)
def getLots(self):
return "d3:" + json.dumps(data)
def _execution_summary_quantity(self, value):
if value is None:
return 0.0
try:
return float(value)
except (TypeError, ValueError):
return 0.0
def get_execution_summary_viewer(self, name=None):
LotQt = Pool().get('lot.qt')
rows = []
totals = defaultdict(float)
for line in (self.lines or []):
if getattr(line, 'type', 'line') != 'line':
continue
quantity = self._execution_summary_quantity(
getattr(line, 'quantity_theorical', None)
or getattr(line, 'quantity', None))
matched = 0.0
shipped = 0.0
lots_count = 0
shipped_routes = []
line_lots = list(getattr(line, 'lots', None) or [])
lot_ids = [lot.id for lot in line_lots if getattr(lot, 'id', None)]
lot_qts = LotQt.search([('lot_p', 'in', lot_ids)]) if lot_ids else []
for lqt in lot_qts:
lots_count += 1
lot_quantity = self._execution_summary_quantity(
getattr(lqt, 'lot_quantity', None)
or getattr(lqt, 'lot_qt', None))
if getattr(lqt, 'lot_s', None):
matched += lot_quantity
shipment = (
getattr(lqt, 'lot_shipment_in', None)
or getattr(lqt, 'lot_shipment_internal', None)
or getattr(lqt, 'lot_shipment_out', None))
if shipment:
shipped += lot_quantity
route_from = getattr(
getattr(shipment, 'from_location', None),
'rec_name', None)
route_to = getattr(
getattr(shipment, 'to_location', None),
'rec_name', None)
if route_from or route_to:
shipped_routes.append(
'%s -> %s' % (route_from or '-', route_to or '-'))
if not lot_qts:
for lot in line_lots:
lots_count += 1
lot_quantity = self._execution_summary_quantity(
getattr(lot, 'lot_qt', None))
if getattr(lot, 'lot_s', None) or getattr(lot, 'sale_line', None):
matched += lot_quantity
shipment = (
getattr(lot, 'lot_shipment_in', None)
or getattr(lot, 'lot_shipment_internal', None)
or getattr(lot, 'lot_shipment_out', None))
if shipment:
shipped += lot_quantity
route_from = getattr(
getattr(shipment, 'from_location', None),
'rec_name', None)
route_to = getattr(
getattr(shipment, 'to_location', None),
'rec_name', None)
if route_from or route_to:
shipped_routes.append(
'%s -> %s' % (route_from or '-', route_to or '-'))
unit = getattr(getattr(line, 'unit', None), 'rec_name', '') or ''
product = getattr(getattr(line, 'product', None), 'rec_name', '') or ''
route = (shipped_routes[0] if shipped_routes else '%s -> %s' % (
getattr(getattr(self, 'from_location', None), 'rec_name', None)
or '-',
getattr(getattr(self, 'to_location', None), 'rec_name', None)
or '-'))
rows.append({
'product': product,
'quantity': quantity,
'matched': matched,
'shipped': shipped,
'open': max(quantity - shipped, 0.0),
'unit': unit,
'lots': lots_count,
'route': route,
})
totals['quantity'] += quantity
totals['matched'] += matched
totals['shipped'] += shipped
totals['open'] += max(quantity - shipped, 0.0)
totals['lines'] += 1
data = {
'type': 'execution-summary',
'title': 'Execution snapshot',
'unit': rows[0]['unit'] if rows else '',
'totals': dict(totals),
'rows': rows[:4],
}
return "d3:" + json.dumps(data)
def getLots(self):
if self.lines:
if self.lines.lots:
return [l for l in self.lines.lots]

View File

@@ -79,7 +79,7 @@ this repository contains the full copyright notices and license terms. -->
<group id="purchase_tolerance" string="Tolerance"
colspan="1" col="6" panel="card" icon="tryton-switch"
xalign="0" yalign="0"
col_widths="120px,120px,120px,120px,140px,1fr">
col_widths="105px,120px,105px,120px,135px,200px">
<label name="tol_min"/>
<field name="tol_min"/>
<label name="tol_max"/>
@@ -87,7 +87,7 @@ this repository contains the full copyright notices and license terms. -->
<label name="tolerance_used"/>
<field name="tolerance_used" widget="tolerance_gauge"
min_field="tolerance_min" max_field="tolerance_max"
xexpand="1" xfill="1"/>
width="190" xexpand="0" xfill="0"/>
<field name="tolerance_min" invisible="1"/>
<field name="tolerance_max" invisible="1"/>
</group>
@@ -101,22 +101,11 @@ this repository contains the full copyright notices and license terms. -->
<field name="viewer" widget="html_viewer" height="170"/>
</group>
<group id="purchase_recap" string="Récapitulatif"
colspan="1" col="4" panel="sidebar" icon="tryton-note"
colspan="1" col="1" panel="sidebar" icon="tryton-note"
xalign="0" yalign="0"
col_widths="min-content,1fr,min-content,1fr">
<label name="state"/>
<field name="state"/>
<label name="invoice_state"/>
<field name="invoice_state"/>
<label name="shipment_state"/>
<field name="shipment_state"/>
<newline/>
<label name="untaxed_amount"/>
<field name="untaxed_amount" width="120" xexpand="0" xfill="0"/>
<label name="tax_amount"/>
<field name="tax_amount" width="100" xexpand="0" xfill="0"/>
<label name="total_amount"/>
<field name="total_amount" width="120" xexpand="0" xfill="0"/>
col_widths="1fr">
<field name="execution_summary_viewer" widget="html_viewer"
height="165"/>
</group>
</group>
</xpath>