changeset 9fb0bdf9b193 in modules/stock:default
details: https://hg.tryton.org/modules/stock?cmd=changeset&node=9fb0bdf9b193
description:
        Exclude quantity coming back from production the same day

        This avoid to have a loop back that keeps the initial cost price of the
        production in the history.

        issue11265
        review386101002
diffstat:

 product.py                                                       |   21 +-
 tests/scenario_stock_recompute_average_cost_price_production.rst |  105 
++++++++++
 tests/test_stock.py                                              |    5 +
 3 files changed, 127 insertions(+), 4 deletions(-)

diffs (176 lines):

diff -r 4b8495cb0efd -r 9fb0bdf9b193 product.py
--- a/product.py        Thu Feb 17 00:37:39 2022 +0100
+++ b/product.py        Sun Mar 06 13:34:18 2022 +0100
@@ -382,8 +382,14 @@
         def out_move(move):
             return not in_move(move)
 
+        def production_move(move):
+            return (
+                move.from_location.type == 'production'
+                or move.to_location.type == 'production')
+
         current_moves = []
         current_cost_price = cost_price
+        qty_production = 0
         for move in moves:
             if (current_moves
                     and current_moves[-1].effective_date
@@ -393,6 +399,7 @@
                         if m.cost_price != current_cost_price],
                     dict(cost_price=current_cost_price))
                 current_moves.clear()
+                qty_production = 0
             current_moves.append(move)
 
             cost_price = Revision.apply_up_to(
@@ -402,15 +409,21 @@
             if out_move(move):
                 qty *= -1
             if in_move(move):
+                in_qty = qty
+                if production_move(move) and qty_production < 0:
+                    # Exclude quantity coming back from production
+                    in_qty -= min(abs(qty_production), in_qty)
                 unit_price = move.get_cost_price(product_cost_price=cost_price)
-                if quantity + qty > 0 and quantity >= 0:
+                if quantity + in_qty > 0 and quantity >= 0:
                     cost_price = (
-                        (cost_price * quantity) + (unit_price * qty)
-                        ) / (quantity + qty)
-                elif qty > 0:
+                        (cost_price * quantity) + (unit_price * in_qty)
+                        ) / (quantity + in_qty)
+                elif in_qty > 0:
                     cost_price = unit_price
                 current_cost_price = round_price(cost_price)
             quantity += qty
+            if production_move(move):
+                qty_production += qty
 
         Move.write([
                 m for m in current_moves
diff -r 4b8495cb0efd -r 9fb0bdf9b193 
tests/scenario_stock_recompute_average_cost_price_production.rst
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/scenario_stock_recompute_average_cost_price_production.rst  Sun Mar 
06 13:34:18 2022 +0100
@@ -0,0 +1,105 @@
+=============================================
+Stock Recompute Average Cost Price Production
+=============================================
+
+Imports::
+
+    >>> import datetime as dt
+    >>> from decimal import Decimal
+
+    >>> from proteus import Model, Wizard
+    >>> from trytond.tests.tools import activate_modules
+    >>> from trytond.modules.company.tests.tools import (
+    ...     create_company, get_company)
+
+    >>> today = dt.date.today()
+    >>> yesterday = today - dt.timedelta(days=1)
+
+Activate modules::
+
+    >>> config = activate_modules('stock')
+
+    >>> Location = Model.get('stock.location')
+    >>> ProductTemplate = Model.get('product.template')
+    >>> ProductUom = Model.get('product.uom')
+    >>> StockMove = Model.get('stock.move')
+
+Create company::
+
+    >>> _ = create_company()
+    >>> company = get_company()
+
+Create product::
+
+    >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+    >>> template = ProductTemplate()
+    >>> template.name = 'Product'
+    >>> template.default_uom = unit
+    >>> template.type = 'goods'
+    >>> template.list_price = Decimal('50.0000')
+    >>> template.cost_price_method = 'average'
+    >>> product, = template.products
+    >>> product.cost_price = Decimal('40.0000')
+    >>> template.save()
+    >>> product, = template.products
+
+Get stock locations::
+
+    >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+    >>> storage_loc, = Location.find([('code', '=', 'STO')])
+    >>> production_loc = Location(name="Production", type='production')
+    >>> production_loc.save()
+
+Consume product for production and reverse some::
+
+    >>> StockMove(
+    ...     product=product,
+    ...     quantity=10,
+    ...     from_location=storage_loc,
+    ...     to_location=production_loc,
+    ...     effective_date=today).click('do')
+    >>> StockMove(
+    ...     product=product,
+    ...     quantity=2,
+    ...     from_location=production_loc,
+    ...     to_location=storage_loc,
+    ...     unit_price=Decimal('40.0000'),
+    ...     effective_date=today).click('do')
+
+    >>> [m.cost_price for m in StockMove.find([])]
+    [Decimal('40.0000'), Decimal('40.0000')]
+
+Recompute cost price::
+
+    >>> recompute = Wizard('product.recompute_cost_price', [product])
+    >>> recompute.execute('recompute')
+
+    >>> [m.cost_price for m in StockMove.find([])]
+    [Decimal('0.0000'), Decimal('0.0000')]
+
+    >>> product.reload()
+    >>> product.cost_price
+    Decimal('0.0000')
+
+Receive product yesterday at new cost::
+
+    >>> StockMove(
+    ...     product=product,
+    ...     quantity=16,
+    ...     from_location=supplier_loc,
+    ...     to_location=storage_loc,
+    ...     unit_price=Decimal('20.0000'),
+    ...     effective_date=yesterday).click('do')
+
+Recompute cost price::
+
+    >>> recompute = Wizard('product.recompute_cost_price', [product])
+    >>> recompute.execute('recompute')
+
+    >>> [m.cost_price for m in StockMove.find([])]
+    [Decimal('20.0000'), Decimal('20.0000'), Decimal('20.0000')]
+
+    >>> product.reload()
+    >>> product.cost_price
+    Decimal('20.0000')
diff -r 4b8495cb0efd -r 9fb0bdf9b193 tests/test_stock.py
--- a/tests/test_stock.py       Thu Feb 17 00:37:39 2022 +0100
+++ b/tests/test_stock.py       Sun Mar 06 13:34:18 2022 +0100
@@ -1505,6 +1505,11 @@
             checker=doctest_checker,
             optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
     suite.addTests(doctest.DocFileSuite(
+            'scenario_stock_recompute_average_cost_price_production.rst',
+            tearDown=doctest_teardown, encoding='utf-8',
+            checker=doctest_checker,
+            optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+    suite.addTests(doctest.DocFileSuite(
             'scenario_stock_inventory.rst',
             tearDown=doctest_teardown, encoding='utf-8',
             checker=doctest_checker,

Reply via email to