Keep cost of unused input products
We set the average cost price of the input products as the unit price of the output of the same product. This way the cost price computation for this product does not change. issue9637 review316051002
This commit is contained in:
1 parent
b546cb8f90
commit
172ab5efdf
3 files changed
+50
-14
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Keep cost of unused input products
|
||||
* Use the shipment assign wizard for production
|
||||
* Rename production state from cancel to cancelled
|
||||
|
||||
|
||||
+34
-4
@@ -1,5 +1,6 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from collections import defaultdict
|
||||
from decimal import Decimal
|
||||
from itertools import chain
|
||||
|
||||
@@ -529,7 +530,36 @@ class Production(ShipmentAssignMixin, Workflow, ModelSQL, ModelView):
|
||||
for production in productions:
|
||||
sum_ = Decimal(0)
|
||||
prices = {}
|
||||
cost = production.cost
|
||||
|
||||
input_quantities = defaultdict(Decimal)
|
||||
input_costs = defaultdict(Decimal)
|
||||
for input_ in production.inputs:
|
||||
if input_.cost_price is not None:
|
||||
cost_price = input_.cost_price
|
||||
else:
|
||||
cost_price = input_.product.cost_price
|
||||
input_quantities[input_.product] += (
|
||||
Decimal(str(input_.internal_quantity)))
|
||||
input_costs[input_.product] += (
|
||||
Decimal(str(input_.internal_quantity)) * cost_price)
|
||||
outputs = []
|
||||
for output in production.outputs:
|
||||
product = output.product
|
||||
if input_quantities.get(output.product):
|
||||
cost_price = (
|
||||
input_costs[product] / input_quantities[product])
|
||||
unit_price = round_price(Uom.compute_price(
|
||||
product.default_uom, cost_price, output.uom))
|
||||
if output.unit_price != unit_price:
|
||||
output.unit_price = unit_price
|
||||
moves.append(output)
|
||||
cost -= min(
|
||||
unit_price * Decimal(str(output.quantity)), cost)
|
||||
else:
|
||||
outputs.append(output)
|
||||
|
||||
for output in outputs:
|
||||
product = output.product
|
||||
with Transaction().set_context(production._list_price_context):
|
||||
list_price = product.list_price_used
|
||||
@@ -541,7 +571,7 @@ class Production(ShipmentAssignMixin, Workflow, ModelSQL, ModelView):
|
||||
|
||||
if not sum_ and production.product:
|
||||
prices.clear()
|
||||
for output in production.outputs:
|
||||
for output in outputs:
|
||||
if output.product == production.product:
|
||||
quantity = Uom.compute_qty(
|
||||
output.uom, output.quantity,
|
||||
@@ -550,13 +580,13 @@ class Production(ShipmentAssignMixin, Workflow, ModelSQL, ModelView):
|
||||
prices[output] = quantity
|
||||
sum_ += quantity
|
||||
|
||||
for output in production.outputs:
|
||||
for output in outputs:
|
||||
if sum_:
|
||||
ratio = prices.get(output, 0) / sum_
|
||||
else:
|
||||
ratio = Decimal(1) / len(production.outputs)
|
||||
ratio = Decimal(1) / len(outputs)
|
||||
quantity = Decimal(str(output.quantity))
|
||||
unit_price = round_price(production.cost * ratio / quantity)
|
||||
unit_price = round_price(cost * ratio / quantity)
|
||||
if output.unit_price != unit_price:
|
||||
output.unit_price = unit_price
|
||||
moves.append(output)
|
||||
|
||||
@@ -51,13 +51,13 @@ Create Bill of Material::
|
||||
>>> bom = BOM(name='product')
|
||||
>>> input = bom.inputs.new()
|
||||
>>> input.product = component
|
||||
>>> input.quantity = 2
|
||||
>>> input.quantity = 3
|
||||
>>> output = bom.outputs.new()
|
||||
>>> output.product = product
|
||||
>>> output.quantity = 1
|
||||
>>> bom.save()
|
||||
|
||||
Make a production::
|
||||
Make a production with 2 unused component::
|
||||
|
||||
>>> Production = Model.get('production')
|
||||
>>> production = Production()
|
||||
@@ -67,15 +67,20 @@ Make a production::
|
||||
>>> production.click('wait')
|
||||
>>> production.click('assign_force')
|
||||
>>> production.click('run')
|
||||
>>> output = production.outputs.new()
|
||||
>>> output.product = component
|
||||
>>> output.quantity = 2
|
||||
>>> output.unit_price = Decimal(0)
|
||||
>>> output.from_location = production.location
|
||||
>>> output.to_location = production.warehouse.storage_location
|
||||
>>> production.click('done')
|
||||
|
||||
Check output price::
|
||||
|
||||
>>> production.cost
|
||||
Decimal('20.0000')
|
||||
>>> output, = production.outputs
|
||||
>>> output.unit_price
|
||||
Decimal('10.0000')
|
||||
Decimal('30.0000')
|
||||
>>> sorted([o.unit_price for o in production.outputs])
|
||||
[Decimal('5.0000'), Decimal('10.0000')]
|
||||
|
||||
|
||||
Change cost of input::
|
||||
@@ -97,9 +102,9 @@ Launch cron task::
|
||||
>>> cron_set_cost.companies.append(Company(company.id))
|
||||
>>> cron_set_cost.click('run_once')
|
||||
|
||||
>>> output.reload()
|
||||
>>> output.unit_price
|
||||
Decimal('12.0000')
|
||||
>>> input.reload()
|
||||
>>> production.reload()
|
||||
>>> sorted([o.unit_price for o in production.outputs])
|
||||
[Decimal('6.0000'), Decimal('12.0000')]
|
||||
>>> input, = production.inputs
|
||||
>>> bool(input.production_cost_price_updated)
|
||||
False
|
||||
Reference in new issue
Block a user