changeset c6a604d35422 in modules/product_cost_fifo:default
details: 
https://hg.tryton.org/modules/product_cost_fifo?cmd=changeset;node=c6a604d35422
description:
        Use all moves to compute FIFO

        We must consider any incoming moves (ex: inventory) for the computation 
of the
        FIFO otherwise the back computation to find first in moves does not 
pick enough
        moves. As not all incoming moves have a unit price, we use the current 
cost
        price as fallback.
        Also in re-computation, the in or out move test should only rely on the 
storage
        location usage in order to properly compute the average cost.

        issue9274
        review321471002
diffstat:

 move.py    |  16 +++++++++-------
 product.py |  39 ++++++++++++++++++++++-----------------
 2 files changed, 31 insertions(+), 24 deletions(-)

diffs (105 lines):

diff -r a4616319fa96 -r c6a604d35422 move.py
--- a/move.py   Sat Jun 06 10:30:11 2020 +0100
+++ b/move.py   Fri Jun 19 00:24:56 2020 +0200
@@ -81,13 +81,15 @@
         to_save = []
         for move, move_qty in fifo_moves:
             consumed_qty += move_qty
-
-            with Transaction().set_context(date=move.effective_date):
-                move_unit_price = Currency.compute(
-                    move.currency, move.unit_price,
-                    self.company.currency, round=False)
-            move_unit_price = Uom.compute_price(move.uom, move_unit_price,
-                    move.product.default_uom)
+            if move.from_location.type in {'supplier', 'production'}:
+                with Transaction().set_context(date=move.effective_date):
+                    move_unit_price = Currency.compute(
+                        move.currency, move.unit_price,
+                        self.company.currency, round=False)
+                move_unit_price = Uom.compute_price(
+                    move.uom, move_unit_price, move.product.default_uom)
+            else:
+                move_unit_price = move.cost_price or 0
             cost_price += move_unit_price * Decimal(str(move_qty))
 
             move_qty = Uom.compute_qty(self.product.default_uom, move_qty,
diff -r a4616319fa96 -r c6a604d35422 product.py
--- a/product.py        Sat Jun 06 10:30:11 2020 +0100
+++ b/product.py        Fri Jun 19 00:24:56 2020 +0200
@@ -31,7 +31,7 @@
         domain = [
             ('product', '=', self.id),
             self._domain_moves_cost(),
-            ('from_location.type', 'in', ['supplier', 'production']),
+            ('from_location.type', '!=', 'storage'),
             ('to_location.type', '=', 'storage'),
             ]
         if not date:
@@ -137,11 +137,10 @@
                 quantity = Decimal(str(quantity))
 
         def in_move(move):
-            return (move.from_location.type in ['supplier', 'production']
-                    or move.to_location.type == 'supplier')
+            return move.to_location.type == 'storage'
 
         def out_move(move):
-            return not in_move(move)
+            return move.from_location.type == 'storage'
 
         def compute_fifo_cost_price(quantity, date):
             fifo_moves = self.get_fifo_move(
@@ -152,12 +151,15 @@
             consumed_qty = 0
             for move, move_qty in fifo_moves:
                 consumed_qty += move_qty
-                with Transaction().set_context(date=move.effective_date):
-                    unit_price = Currency.compute(
-                        move.currency, move.unit_price,
-                        move.company.currency, round=False)
-                unit_price = Uom.compute_price(
-                    move.uom, unit_price, move.product.default_uom)
+                if move.from_location.type in {'supplier', 'production'}:
+                    with Transaction().set_context(date=move.effective_date):
+                        unit_price = Currency.compute(
+                            move.currency, move.unit_price,
+                            move.company.currency, round=False)
+                    unit_price = Uom.compute_price(
+                        move.uom, unit_price, move.product.default_uom)
+                else:
+                    unit_price = move.cost_price or 0
                 cost_price += unit_price * Decimal(str(move_qty))
             if consumed_qty:
                 return round_price(cost_price / Decimal(str(consumed_qty)))
@@ -204,12 +206,15 @@
             if move.from_location.type == 'storage':
                 qty *= -1
             if in_move(move):
-                with Transaction().set_context(date=move.effective_date):
-                    unit_price = Currency.compute(
-                        move.currency, move.unit_price,
-                        move.company.currency, round=False)
-                unit_price = Uom.compute_price(
-                    move.uom, unit_price, self.default_uom)
+                if move.from_location.type in {'supplier', 'production'}:
+                    with Transaction().set_context(date=move.effective_date):
+                        unit_price = Currency.compute(
+                            move.currency, move.unit_price,
+                            move.company.currency, round=False)
+                    unit_price = Uom.compute_price(
+                        move.uom, unit_price, self.default_uom)
+                else:
+                    unit_price = cost_price
                 if quantity + qty > 0 and quantity >= 0:
                     cost_price = (
                         (cost_price * quantity) + (unit_price * qty)
@@ -217,7 +222,7 @@
                 elif qty > 0:
                     cost_price = unit_price
                 current_cost_price = round_price(cost_price)
-            else:
+            elif out_move(move):
                 current_out_qty += -qty
             quantity += qty
 

Reply via email to