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

Reply via email to