Purchase form

This commit is contained in:
2026-07-25 18:16:13 +02:00
parent 42d02cc6f8
commit 8088fd5254
2 changed files with 91 additions and 15 deletions

View File

@@ -971,6 +971,63 @@ class Purchase(metaclass=PoolMeta):
data = dict(data, type='execution-summary')
return "d3:" + json.dumps(data)
@staticmethod
def _summary_link(model, records):
unique = []
seen = set()
for record in records:
record_id = getattr(record, 'id', None)
if not record_id:
continue
key = (model, record_id)
if key in seen:
continue
seen.add(key)
unique.append(record)
link = {
"model": model,
"count": len(unique),
}
if len(unique) == 1:
link["res_id"] = unique[0].id
return link
@staticmethod
def _summary_mixed_link(records):
unique = []
seen = set()
for model, record in records:
record_id = getattr(record, 'id', None)
if not model or not record_id:
continue
key = (model, record_id)
if key in seen:
continue
seen.add(key)
unique.append((model, record))
link = {
"count": len(unique),
}
if len(unique) == 1:
model, record = unique[0]
link.update({
"model": model,
"res_id": record.id,
})
elif unique:
link["model"] = unique[0][0]
return link
@staticmethod
def _summary_shipment_record(record):
if getattr(record, 'lot_shipment_in', None):
return ('stock.shipment.in', record.lot_shipment_in)
if getattr(record, 'lot_shipment_internal', None):
return ('stock.shipment.internal', record.lot_shipment_internal)
if getattr(record, 'lot_shipment_out', None):
return ('stock.shipment.out', record.lot_shipment_out)
return (None, None)
@staticmethod
def _summary_number(value):
if value is None:
@@ -1013,10 +1070,9 @@ class Purchase(metaclass=PoolMeta):
rows = []
totals = defaultdict(float)
for line in (self.lines or []):
if getattr(line, 'type', 'line') != 'line':
continue
for index, line in enumerate((
l for l in (self.lines or [])
if getattr(l, 'type', 'line') == 'line'), 1):
quantity = self._execution_summary_quantity(
getattr(line, 'quantity_theorical', None)
or getattr(line, 'quantity', None))
@@ -1024,6 +1080,8 @@ class Purchase(metaclass=PoolMeta):
shipped = 0.0
lots_count = 0
shipped_routes = []
sales = []
shipments = []
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 []
@@ -1035,11 +1093,13 @@ class Purchase(metaclass=PoolMeta):
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))
sale_line = getattr(lqt.lot_s, 'sale_line', None)
sale = getattr(sale_line, 'sale', None)
if sale:
sales.append(sale)
shipment_model, shipment = self._summary_shipment_record(lqt)
if shipment:
shipments.append((shipment_model, shipment))
shipped += lot_quantity
route_from = getattr(
getattr(shipment, 'from_location', None),
@@ -1062,11 +1122,15 @@ class Purchase(metaclass=PoolMeta):
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))
sale_line = getattr(lot, 'sale_line', None)
if getattr(lot, 'lot_s', None):
sale_line = getattr(lot.lot_s, 'sale_line', None)
sale = getattr(sale_line, 'sale', None)
if sale:
sales.append(sale)
shipment_model, shipment = self._summary_shipment_record(lot)
if shipment:
shipments.append((shipment_model, shipment))
shipped += lot_quantity
route_from = getattr(
getattr(shipment, 'from_location', None),
@@ -1084,6 +1148,12 @@ class Purchase(metaclass=PoolMeta):
shipped_routes.append(
'%s > %s' % (route_from or '-', route_to or '-'))
invoices = [
invoice_line.invoice
for invoice_line in (getattr(line, 'invoice_lines', None) or [])
if (getattr(invoice_line, 'invoice', None)
and getattr(invoice_line.invoice, 'state', None) != 'cancelled')
]
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' % (
@@ -1093,7 +1163,9 @@ class Purchase(metaclass=PoolMeta):
or '-'))
rows.append({
'index': index,
'product': product,
'physical': shipped,
'quantity': quantity,
'matched': matched,
'shipped': shipped,
@@ -1101,6 +1173,9 @@ class Purchase(metaclass=PoolMeta):
'unit': unit,
'lots': lots_count,
'route': route,
'sales': self._summary_link('sale.sale', sales),
'shipments': self._summary_mixed_link(shipments),
'invoices': self._summary_link('account.invoice', invoices),
})
totals['quantity'] += quantity
totals['matched'] += matched
@@ -1111,7 +1186,7 @@ class Purchase(metaclass=PoolMeta):
return {
'unit': rows[0]['unit'] if rows else '',
'totals': dict(totals),
'rows': rows[:4],
'rows': rows[:3],
}
@staticmethod

View File

@@ -100,8 +100,9 @@ this repository contains the full copyright notices and license terms. -->
</group>
</group>
<field name="lines" colspan="4" mode="form,tree"
view_ids="purchase.purchase_line_view_form,purchase.purchase_line_view_tree_sequence"/>
<field name="lines" colspan="4"
line_chips="quantity,del_period,product"
line_chips_label="{quantity}mt {del_period}&#10;{product}"/>
<notebook colspan="6">
<page string="State" id="state">
<group col="2" colspan="2" id="states" yfill="1">