======================== Stock Average Cost Price ======================== Imports:: >>> import datetime as dt >>> from decimal import Decimal >>> from proteus import Model, Wizard >>> from trytond.modules.company.tests.tools import create_company >>> from trytond.modules.currency.tests.tools import get_currency >>> from trytond.tests.tools import activate_modules >>> today = dt.date.today() >>> next_day = today + dt.timedelta(days=1) Activate modules:: >>> config = activate_modules('stock', create_company) Get currency:: >>> currency = get_currency() Create product:: >>> ProductUom = Model.get('product.uom') >>> ProductTemplate = Model.get('product.template') >>> Product = Model.get('product.product') >>> unit, = ProductUom.find([('name', '=', 'Unit')]) >>> template = ProductTemplate() >>> template.name = 'Product' >>> template.default_uom = unit >>> template.type = 'goods' >>> template.list_price = Decimal('300') >>> template.cost_price_method = 'average' >>> product, = template.products >>> product.cost_price = Decimal('80') >>> template.save() >>> product, = template.products >>> template = ProductTemplate() >>> template.name = 'Negative Product' >>> template.default_uom = unit >>> template.type = 'goods' >>> template.list_price = Decimal('28') >>> template.cost_price_method = 'average' >>> negative_product, = template.products >>> negative_product.cost_price = Decimal('5.0000') >>> template.save() >>> negative_product, = template.products Get stock locations:: >>> Location = Model.get('stock.location') >>> supplier_loc, = Location.find([('code', '=', 'SUP')]) >>> storage_loc, = Location.find([('code', '=', 'STO')]) >>> storage_sub_loc = Location( ... name="Storage Sub", type='storage', parent=storage_loc) >>> storage_sub_loc.save() >>> customer_loc, = Location.find([('code', '=', 'CUS')]) Make 1 unit of the product available @ 100 :: >>> StockMove = Model.get('stock.move') >>> incoming_move = StockMove() >>> incoming_move.product = product >>> incoming_move.unit = unit >>> incoming_move.quantity = 1 >>> incoming_move.from_location = supplier_loc >>> incoming_move.to_location = storage_sub_loc >>> incoming_move.planned_date = today >>> incoming_move.effective_date = today >>> incoming_move.unit_price = Decimal('100') >>> incoming_move.currency = currency >>> incoming_move.click('do') Check Cost Price is 100:: >>> product.reload() >>> product.cost_price Decimal('100.0000') Add 1 more unit @ 200:: >>> incoming_move = StockMove() >>> incoming_move.product = product >>> incoming_move.unit = unit >>> incoming_move.quantity = 1 >>> incoming_move.from_location = supplier_loc >>> incoming_move.to_location = storage_loc >>> incoming_move.planned_date = today >>> incoming_move.effective_date = today >>> incoming_move.unit_price = Decimal('200') >>> incoming_move.currency = currency >>> incoming_move.click('do') Check Cost Price Average is 150:: >>> product.reload() >>> product.cost_price Decimal('150.0000') Add twice 1 more unit @ 200:: >>> incoming_moves = [] >>> incoming_move = StockMove() >>> incoming_move.product = product >>> incoming_move.unit = unit >>> incoming_move.quantity = 1 >>> incoming_move.from_location = supplier_loc >>> incoming_move.to_location = storage_loc >>> incoming_move.planned_date = today >>> incoming_move.effective_date = today >>> incoming_move.unit_price = Decimal('200') >>> incoming_move.currency = currency >>> incoming_move.save() >>> incoming_moves.append(incoming_move) >>> incoming_move = StockMove() >>> incoming_move.product = product >>> incoming_move.unit = unit >>> incoming_move.quantity = 1 >>> incoming_move.from_location = supplier_loc >>> incoming_move.to_location = storage_loc >>> incoming_move.planned_date = today >>> incoming_move.effective_date = today >>> incoming_move.unit_price = Decimal('200') >>> incoming_move.currency = currency >>> incoming_move.save() >>> incoming_moves.append(incoming_move) >>> StockMove.click(incoming_moves, 'do') Check Cost Price Average is 175:: >>> product.reload() >>> product.cost_price Decimal('175.0000') Reduce Cost Price by 80%, to force to write recomputed price later:: >>> modify_cost_price = Wizard('product.modify_cost_price', [product]) >>> modify_cost_price.form.cost_price = 'cost_price * 0.8' >>> modify_cost_price.form.date = next_day >>> modify_cost_price.execute('modify') >>> product.cost_price Decimal('140.0000') Increase Cost Price by 10% using Template wizard:: >>> modify_cost_price = Wizard( ... 'product.modify_cost_price', [product.template]) >>> modify_cost_price.form.cost_price = 'cost_price * 1.1' >>> modify_cost_price.form.date = next_day >>> modify_cost_price.execute('modify') >>> product.reload() >>> product.cost_price Decimal('154.0000') Send one product we don't have in stock:: >>> outgoing_move = StockMove() >>> outgoing_move.product = negative_product >>> outgoing_move.unit = unit >>> outgoing_move.quantity = 1 >>> outgoing_move.unit_price = Decimal('28') >>> outgoing_move.from_location = storage_loc >>> outgoing_move.to_location = customer_loc >>> outgoing_move.planned_date = today >>> outgoing_move.effective_date = today >>> outgoing_move.currency = currency >>> outgoing_move.click('do') Cost price should stay 5:: >>> negative_product.cost_price Decimal('5.0000') Return one product to the supplier:: >>> outgoing_move = StockMove() >>> outgoing_move.product = negative_product >>> outgoing_move.unit = unit >>> outgoing_move.quantity = 1 >>> outgoing_move.unit_price = Decimal('28') >>> outgoing_move.currency = currency >>> outgoing_move.from_location = storage_loc >>> outgoing_move.to_location = supplier_loc >>> outgoing_move.planned_date = today >>> outgoing_move.effective_date = today >>> outgoing_move.click('do') Cost price should stay 5:: >>> negative_product.cost_price Decimal('5.0000') Receive one unit of the product with negative stock so the stock stays negative:: >>> incoming_move = StockMove() >>> incoming_move.product = negative_product >>> incoming_move.unit = unit >>> incoming_move.quantity = 1 >>> incoming_move.from_location = supplier_loc >>> incoming_move.to_location = storage_loc >>> incoming_move.planned_date = today >>> incoming_move.effective_date = today >>> incoming_move.unit_price = Decimal('3') >>> incoming_move.currency = currency >>> incoming_move.click('do') Cost price should be set to last unit price:: >>> negative_product.reload() >>> negative_product.cost_price Decimal('3.0000') Receive two units of the product so the stock becomes positive:: >>> incoming_move = StockMove() >>> incoming_move.product = negative_product >>> incoming_move.unit = unit >>> incoming_move.quantity = 2 >>> incoming_move.from_location = supplier_loc >>> incoming_move.to_location = storage_loc >>> incoming_move.planned_date = today >>> incoming_move.effective_date = today >>> incoming_move.unit_price = Decimal('2') >>> incoming_move.currency = currency >>> incoming_move.click('do') Cost price should be set to last unit price:: >>> negative_product.reload() >>> negative_product.cost_price Decimal('2.0000') Recompute Cost Price:: >>> recompute = Wizard('product.recompute_cost_price', [negative_product]) >>> recompute.execute('recompute') >>> negative_product.cost_price Decimal('2.0000')