changeset 64bfe27634dd in modules/purchase:default
details: https://hg.tryton.org/modules/purchase?cmd=changeset;node=64bfe27634dd
description:
Add actual quantity on line
The actual quantity is computed once the order is processing. We take
the
biggest quantity between the shipped and invoiced and ignore the
cancelled.
issue9191
review319091002
diffstat:
CHANGELOG | 1 +
purchase.py | 35 +++++++++++++++++++++++++++++++++++
tests/scenario_purchase.rst | 5 +++++
3 files changed, 41 insertions(+), 0 deletions(-)
diffs (96 lines):
diff -r d857a4932508 -r 64bfe27634dd CHANGELOG
--- a/CHANGELOG Mon Apr 13 17:25:02 2020 +0200
+++ b/CHANGELOG Tue Apr 14 09:27:53 2020 +0200
@@ -1,3 +1,4 @@
+* Add actual quantity on line
* Add return wizard
* Add employee on purchases for some states
* Add contact and invoice party on purchase
diff -r d857a4932508 -r 64bfe27634dd purchase.py
--- a/purchase.py Mon Apr 13 17:25:02 2020 +0200
+++ b/purchase.py Tue Apr 14 09:27:53 2020 +0200
@@ -909,6 +909,9 @@
@classmethod
@ModelView.button
def process(cls, purchases):
+ pool = Pool()
+ Line = pool.get('purchase.line')
+ lines = []
process, done = [], []
cls.lock(purchases)
for purchase in purchases:
@@ -921,6 +924,11 @@
if return_moves:
purchase.create_return_shipment(return_moves)
purchase.set_shipment_state()
+
+ for line in purchase.lines:
+ line.set_actual_quantity()
+ lines.append(line)
+
if purchase.is_done():
if purchase.state != 'done':
if purchase.state == 'confirmed':
@@ -928,6 +936,7 @@
done.append(purchase)
elif purchase.state != 'processing':
process.append(purchase)
+ Line.save(lines)
if process:
cls.proceed(process)
if done:
@@ -987,6 +996,12 @@
'readonly': Eval('purchase_state') != 'draft',
},
depends=['unit_digits', 'type', 'purchase_state'])
+ actual_quantity = fields.Float(
+ "Actual Quantity", digits=(16, Eval('unit_digits', 2)), readonly=True,
+ states={
+ 'invisible': Eval('type') != 'line',
+ },
+ depends=['unit_digits', 'type'])
unit = fields.Many2One('product.uom', 'Unit',
ondelete='RESTRICT',
states={
@@ -1600,6 +1615,26 @@
else:
return [l for l in self.invoice_lines if not l.stock_moves]
+ def set_actual_quantity(self):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ if self.type != 'line':
+ return
+ moved_quantity = 0
+ for move in self.moves:
+ if move.state != 'cancel':
+ moved_quantity += Uom.compute_qty(
+ move.uom, move.quantity, self.unit)
+ if self.quantity < 0:
+ moved_quantity *= -1
+ invoiced_quantity = 0
+ for invoice_line in self.invoice_lines:
+ if (not invoice_line.invoice
+ or invoice_line.invoice.state != 'cancel'):
+ invoiced_quantity += Uom.compute_qty(
+ invoice_line.unit, invoice_line.quantity, self.unit)
+ self.actual_quantity = max(moved_quantity, invoiced_quantity, key=abs)
+
def get_rec_name(self, name):
pool = Pool()
Lang = pool.get('ir.lang')
diff -r d857a4932508 -r 64bfe27634dd tests/scenario_purchase.rst
--- a/tests/scenario_purchase.rst Mon Apr 13 17:25:02 2020 +0200
+++ b/tests/scenario_purchase.rst Tue Apr 14 09:27:53 2020 +0200
@@ -204,6 +204,11 @@
>>> stock_move2.invoice_lines == [invoice_line2]
True
+Check actual quantity::
+
+ >>> all(l.quantity == l.actual_quantity for l in purchase.lines)
+ True
+
Post invoice and check no new invoices::
>>> invoice.invoice_date = today