From 75bbef00773cffb75d12d6787cc8a1ced2962eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 27 Dec 2012 21:53:07 +0100 Subject: [PATCH] Use Workflow for Stock Move review600002 --- CHANGELOG | 2 + inventory.py | 6 +- move.py | 221 ++++++++++++------------- shipment.py | 135 ++++------------ tests/scenario_stock_shipment_out.rst | 2 +- tests/test_stock.py | 223 ++++++++++++-------------- 6 files changed, 246 insertions(+), 343 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 907a61ccc7..6cdd2bbc8d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Add workflow to stock move + Version 2.6.0 - 2012-10-22 * Bug fixes (see mercurial logs for details) * Add Product Quantities By Warehouse diff --git a/inventory.py b/inventory.py index 1817fd533f..ed297265da 100644 --- a/inventory.py +++ b/inventory.py @@ -263,9 +263,7 @@ class InventoryLine(ModelSQL, ModelView): @classmethod def cancel_move(cls, lines): Move = Pool().get('stock.move') - Move.write([l.move for l in lines if l.move], { - 'state': 'cancel', - }) + Move.cancel([l.move for l in lines if l.move]) Move.delete([l.move for l in lines if l.move]) cls.write([l for l in lines if l.move], { 'move': None, @@ -297,9 +295,9 @@ class InventoryLine(ModelSQL, ModelView): 'product': self.product.id, 'uom': self.uom.id, 'company': self.inventory.company.id, - 'state': 'done', 'effective_date': self.inventory.date, }) + Move.do([move]) self.move = move self.save() return move.id diff --git a/move.py b/move.py index 199ad19e26..c9cdab23b0 100644 --- a/move.py +++ b/move.py @@ -2,7 +2,7 @@ #this repository contains the full copyright notices and license terms. from decimal import Decimal from functools import reduce -from trytond.model import ModelView, ModelSQL, fields +from trytond.model import Workflow, ModelView, ModelSQL, fields from trytond.backend import TableHandler from trytond.pyson import In, Eval, Not, Equal, If, Get, Bool from trytond.transaction import Transaction @@ -16,7 +16,7 @@ STATES = { DEPENDS = ['state'] -class Move(ModelSQL, ModelView): +class Move(Workflow, ModelSQL, ModelView): "Stock Move" __name__ = 'stock.move' _order_name = 'product' @@ -149,6 +149,28 @@ class Move(ModelSQL, ModelView): 'modify_assigned_done_cancel': ('You can not modify a move ' 'in the state: "Assigned", "Done" or "Cancel"'), }) + cls._transitions |= set(( + ('draft', 'assigned'), + ('draft', 'done'), + ('draft', 'cancel'), + ('assigned', 'draft'), + ('assigned', 'done'), + ('assigned', 'cancel'), + )) + cls._buttons.update({ + 'cancel': { + 'invisible': ~Eval('state').in_(['draft', 'assigned']), + }, + 'draft': { + 'invisible': ~Eval('state').in_(['assigned']), + }, + 'assign': { + 'invisible': ~Eval('state').in_(['assigned']), + }, + 'do': { + 'invisible': ~Eval('state').in_(['draft', 'assigned']), + }, + }) @classmethod def __register__(cls, module_name): @@ -306,13 +328,10 @@ class Move(ModelSQL, ModelView): def search_rec_name(cls, name, clause): return [('product',) + clause[1:]] - @classmethod - def _update_product_cost_price(cls, product_id, quantity, uom, unit_price, - currency, company, date): + def _update_product_cost_price(self, direction): """ Update the cost price on the given product. - The quantity must be positive if incoming and negative if outgoing. - The date is for the currency rate calculation. + The direction must be "in" if incoming and "out" if outgoing. """ pool = Pool() Uom = pool.get('product.uom') @@ -320,24 +339,20 @@ class Move(ModelSQL, ModelView): ProductTemplate = pool.get('product.template') Location = pool.get('stock.location') Currency = pool.get('currency.currency') - Company = pool.get('company.company') Date = pool.get('ir.date') - if isinstance(uom, (int, long)): - uom = Uom(uom) - if isinstance(currency, (int, long)): - currency = Currency(currency) - if isinstance(company, (int, long)): - company = Company(company) - + if direction == 'in': + quantity = self.quantity + elif direction == 'out': + quantity = -self.quantity context = {} context['locations'] = Location.search([ ('type', '=', 'storage'), ]) context['stock_date_end'] = Date.today() with Transaction().set_context(context): - product = Product(product_id) - qty = Uom.compute_qty(uom, quantity, product.default_uom) + product = Product(self.product.id) + qty = Uom.compute_qty(self.uom, quantity, product.default_uom) qty = Decimal(str(qty)) if hasattr(Product, 'cost_price'): @@ -346,11 +361,12 @@ class Move(ModelSQL, ModelView): product_qty = product.template.quantity product_qty = Decimal(str(product_qty)) # convert wrt currency - with Transaction().set_context(date=date): - unit_price = Currency.compute(currency, unit_price, - company.currency, round=False) + with Transaction().set_context(date=self.effective_date): + unit_price = Currency.compute(self.currency, self.unit_price, + self.company.currency, round=False) # convert wrt to the uom - unit_price = Uom.compute_price(uom, unit_price, product.default_uom) + unit_price = Uom.compute_price(self.uom, unit_price, + product.default_uom) if product_qty + qty != Decimal('0.0'): new_cost_price = ( (product.cost_price * product_qty) + (unit_price * qty) @@ -378,44 +394,78 @@ class Move(ModelSQL, ModelView): return internal_quantity @classmethod - def create(cls, vals): + @ModelView.button + @Workflow.transition('draft') + def draft(cls, moves): + pass + + @classmethod + @ModelView.button + @Workflow.transition('assigned') + def assign(cls, moves): pool = Pool() - Location = pool.get('stock.location') - Product = pool.get('product.product') - Uom = pool.get('product.uom') Date = pool.get('ir.date') today = Date.today() + for move in moves: + if not move.effective_date: + move.effective_date = today + move.save() + + @classmethod + @ModelView.button + @Workflow.transition('done') + def do(cls, moves): + pool = Pool() + Date = pool.get('ir.date') + + today = Date.today() + for move in moves: + if not move.effective_date: + move.effective_date = today + if (move.from_location.type in ('supplier', 'production') + and move.to_location.type == 'storage' + and move.product.cost_price_method == 'average'): + move._update_product_cost_price('in') + elif (move.to_location.type == 'supplier' + and move.from_location.type == 'storage' + and move.product.cost_price_method == 'average'): + move._update_product_cost_price('out') + if not move.cost_price: + move.cost_price = move.product.cost_price + move.save() + + @classmethod + @ModelView.button + @Workflow.transition('cancel') + def cancel(cls, moves): + pool = Pool() + Date = pool.get('ir.date') + + today = Date.today() + for move in moves: + move.effective_date = today + if (move.from_location.type in ('supplier', 'production') + and move.to_location.type == 'storage' + and move.product.cost_price_method == 'average'): + move._update_product_cost_price('out') + elif (move.to_location.type == 'supplier' + and move.from_location.type == 'storage' + and move.product.cost_price_method == 'average'): + move._update_product_cost_price('in') + move.effective_date = None + move.save() + + @classmethod + def create(cls, vals): + pool = Pool() + Product = pool.get('product.product') + Uom = pool.get('product.uom') + + assert vals.get('state', 'draft') == 'draft' vals = vals.copy() - effective_date = vals.get('effective_date') or today product = Product(vals['product']) - if vals.get('state') == 'done': - vals['effective_date'] = effective_date - currency_id = vals.get('currency', cls.default_currency()) - company_id = vals.get('company', cls.default_company()) - from_location = Location(vals['from_location']) - to_location = Location(vals['to_location']) - if (from_location.type in ('supplier', 'production') - and to_location.type == 'storage' - and product.cost_price_method == 'average'): - cls._update_product_cost_price(vals['product'], - vals['quantity'], vals['uom'], vals['unit_price'], - currency_id, company_id, effective_date) - if (to_location.type == 'supplier' - and from_location.type == 'storage' - and product.cost_price_method == 'average'): - cls._update_product_cost_price(vals['product'], - -vals['quantity'], vals['uom'], vals['unit_price'], - currency_id, company_id, effective_date) - if not vals.get('cost_price'): - # Re-read product to get the updated cost_price - product = Product(vals['product']) - vals['cost_price'] = product.cost_price - - elif vals.get('state') == 'assigned': - vals['effective_date'] = effective_date - uom = Uom(vals['uom']) internal_quantity = cls._get_internal_quantity(vals['quantity'], uom, product) @@ -424,57 +474,6 @@ class Move(ModelSQL, ModelView): @classmethod def write(cls, moves, vals): - Date = Pool().get('ir.date') - - today = Date.today() - effective_date = vals.get('effective_date') or today - - if 'state' in vals: - for move in moves: - if vals['state'] == 'cancel': - vals['effective_date'] = None - if (move.from_location.type in ('supplier', 'production') - and move.to_location.type == 'storage' - and move.state != 'cancel' - and move.product.cost_price_method == 'average'): - cls._update_product_cost_price(move.product.id, - -move.quantity, move.uom, move.unit_price, - move.currency, move.company, today) - if (move.to_location.type == 'supplier' - and move.from_location.type == 'storage' - and move.state != 'cancel' - and move.product.cost_price_method == 'average'): - cls._update_product_cost_price(move.product.id, - move.quantity, move.uom, move.unit_price, - move.currency, move.company, today) - - elif vals['state'] == 'draft': - if move.state == 'done': - cls.raise_user_error('set_state_draft') - elif vals['state'] == 'assigned': - if move.state in ('cancel', 'done'): - cls.raise_user_error('set_state_assigned') - vals['effective_date'] = effective_date - elif vals['state'] == 'done': - if move.state in ('cancel'): - cls.raise_user_error('set_state_done') - vals['effective_date'] = effective_date - - if (move.from_location.type in ('supplier', 'production') - and move.to_location.type == 'storage' - and move.state != 'done' - and move.product.cost_price_method == 'average'): - cls._update_product_cost_price(move.product.id, - move.quantity, move.uom, move.unit_price, - move.currency, move.company, effective_date) - if (move.to_location.type == 'supplier' - and move.from_location.type == 'storage' - and move.state != 'done' - and move.product.cost_price_method == 'average'): - cls._update_product_cost_price(move.product.id, - -move.quantity, move.uom, move.unit_price, - move.currency, move.company, effective_date) - if reduce(lambda x, y: x or y in vals, ('product', 'uom', 'quantity', 'from_location', 'to_location', 'company', 'unit_price', 'currency'), False): @@ -482,26 +481,18 @@ class Move(ModelSQL, ModelView): if move.state in ('assigned', 'done', 'cancel'): cls.raise_user_error('modify_assigned_done_cancel') if reduce(lambda x, y: x or y in vals, - ('planned_date', 'effective_date'), False): + ('planned_date', 'effective_date', 'state'), False): for move in moves: if move.state in ('done', 'cancel'): cls.raise_user_error('modify_assigned_done_cancel') super(Move, cls).write(moves, vals) - if vals.get('state', '') == 'done': - for move in moves: - if not move.cost_price: - cls.write([move], { - 'cost_price': move.product.cost_price, - }) - for move in moves: internal_quantity = cls._get_internal_quantity(move.quantity, move.uom, move.product) if internal_quantity != move.internal_quantity: - # Use super to avoid infinite loop - super(Move, cls).write([move], { + cls.write([move], { 'internal_quantity': internal_quantity, }) @@ -595,13 +586,13 @@ class Move(ModelSQL, ModelView): values = { 'from_location': from_location.id, 'quantity': qty, - 'state': 'assigned', } if first: cls.write([move], values) + cls.assign([move]) first = False else: - cls.copy([move], default=values) + cls.assign(cls.copy([move], default=values)) qty_default_uom = Uom.compute_qty(move.uom, qty, move.product.default_uom, round=False) diff --git a/shipment.py b/shipment.py index c80f7bd09b..2503b61eb3 100644 --- a/shipment.py +++ b/shipment.py @@ -390,21 +390,15 @@ class ShipmentIn(Workflow, ModelSQL, ModelView): @Workflow.transition('cancel') def cancel(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments - for m in s.incoming_moves + s.inventory_moves - if m.state not in ('cancel', 'done')], { - 'state': 'cancel', - }) + Move.cancel([m for s in shipments + for m in s.incoming_moves + s.inventory_moves]) @classmethod @ModelView.button @Workflow.transition('draft') def draft(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.incoming_moves - if m.state not in ('draft', 'done')], { - 'state': 'draft', - }) + Move.draft([m for s in shipments for m in s.incoming_moves]) Move.delete([m for s in shipments for m in s.inventory_moves if m.state in ('draft', 'cancel')]) @@ -413,10 +407,7 @@ class ShipmentIn(Workflow, ModelSQL, ModelView): @Workflow.transition('received') def receive(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.incoming_moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.incoming_moves]) cls.create_inventory_moves(shipments) @classmethod @@ -426,10 +417,7 @@ class ShipmentIn(Workflow, ModelSQL, ModelView): pool = Pool() Move = pool.get('stock.move') Date = pool.get('ir.date') - Move.write([m for s in shipments for m in s.inventory_moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.inventory_moves]) cls.write(shipments, { 'effective_date': Date.today(), }) @@ -641,10 +629,7 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView): @Workflow.transition('draft') def draft(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('draft', 'done')], { - 'state': 'draft', - }) + Move.draft([m for s in shipments for m in s.moves]) @classmethod @ModelView.button @@ -652,20 +637,14 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView): def wait(cls, shipments): Move = Pool().get('stock.move') for shipment in shipments: - Move.write([m for m in shipment.moves - if m.state not in ('cancel', 'draft', 'done')], { - 'state': 'draft', - 'planned_date': shipment._move_planned_date, - }) + Move.draft([m for m in shipment.moves]) + cls._set_move_planned_date(shipments) @classmethod @Workflow.transition('assigned') def assign(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('assigned', 'cancel', 'done')], { - 'state': 'assigned', - }) + Move.assign([m for s in shipments for m in s.moves]) @classmethod @ModelView.button @@ -675,10 +654,7 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView): Move = pool.get('stock.move') Date = pool.get('ir.date') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.moves]) cls.write(shipments, { 'effective_date': Date.today(), }) @@ -688,10 +664,7 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView): @Workflow.transition('cancel') def cancel(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('cancel', 'done')], { - 'state': 'cancel', - }) + Move.cancel([m for s in shipments for m in s.moves]) @classmethod @ModelView.button_action('stock.wizard_shipment_in_return_assign') @@ -1014,11 +987,8 @@ class ShipmentOut(Workflow, ModelSQL, ModelView): @Workflow.transition('draft') def draft(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments - for m in s.inventory_moves + s.outgoing_moves - if m.state not in ('draft', 'done')], { - 'state': 'draft', - }) + Move.draft([m for s in shipments + for m in s.inventory_moves + s.outgoing_moves]) @classmethod @ModelView.button @@ -1030,10 +1000,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView): """ Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.inventory_moves - if m.state not in ('draft', 'done')], { - 'state': 'draft', - }) + Move.draft([m for s in shipments for m in s.inventory_moves]) Move.delete([m for s in shipments for m in s.inventory_moves if m.state in ('draft', 'cancel')]) @@ -1068,10 +1035,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView): pool = Pool() Move = pool.get('stock.move') Uom = pool.get('product.uom') - Move.write([m for s in shipments for m in s.inventory_moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.inventory_moves]) for shipment in shipments: # Sum all outgoing quantities @@ -1136,10 +1100,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView): }) outgoing_qty[move.product.id] -= removed_qty - Move.write([m for s in shipments for m in s.outgoing_moves - if m.state not in ('cancel', 'done')], { - 'state': 'assigned', - }) + Move.assign([m for s in shipments for m in s.outgoing_moves]) @classmethod @ModelView.button @@ -1149,10 +1110,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView): Move = pool.get('stock.move') Date = pool.get('ir.date') - Move.write([m for s in shipments for m in s.outgoing_moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.outgoing_moves]) cls.write(shipments, { 'effective_date': Date.today(), }) @@ -1162,11 +1120,8 @@ class ShipmentOut(Workflow, ModelSQL, ModelView): @Workflow.transition('cancel') def cancel(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments - for m in s.outgoing_moves + s.inventory_moves - if m.state not in ('cancel', 'done')], { - 'state': 'cancel', - }) + Move.cancel([m for s in shipments + for m in s.outgoing_moves + s.inventory_moves]) @property def _move_planned_date(self): @@ -1263,10 +1218,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView): @ModelView.button def assign_force(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.inventory_moves - if m.state not in ('cancel', 'done')], { - 'state': 'assigned', - }) + Move.assign([m for s in shipments for m in s.inventory_moves]) cls.assign(shipments) @@ -1580,10 +1532,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): @Workflow.transition('draft') def draft(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.incoming_moves - if m.state not in ('draft', 'done')], { - 'state': 'draft', - }) + Move.draft([m for s in shipments for m in s.incoming_moves]) Move.delete([m for s in shipments for m in s.inventory_moves if m.state in ('draft', 'cancel')]) @@ -1592,10 +1541,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): @Workflow.transition('received') def receive(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.incoming_moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.incoming_moves]) cls.create_inventory_moves(shipments) @classmethod @@ -1605,10 +1551,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): pool = Pool() Move = pool.get('stock.move') Date = pool.get('ir.date') - Move.write([m for s in shipments for m in s.inventory_moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.inventory_moves]) cls.write(shipments, { 'effective_date': Date.today(), }) @@ -1618,11 +1561,8 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): @Workflow.transition('cancel') def cancel(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments - for m in s.incoming_moves + s.inventory_moves - if m.state not in ('cancel', 'done')], { - 'state': 'cancel', - }) + Move.cancel([m for s in shipments + for m in s.incoming_moves + s.inventory_moves]) @staticmethod def _get_inventory_moves(incoming_move): @@ -1893,10 +1833,7 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView): @Workflow.transition('draft') def draft(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('draft', 'done')], { - 'state': 'draft', - }) + Move.draft([m for s in shipments for m in s.moves]) @classmethod @ModelView.button @@ -1904,10 +1841,7 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView): def wait(cls, shipments): Move = Pool().get('stock.move') # First reset state to draft to allow update from and to location - Move.write([m for s in shipments for m in s.moves - if m.state not in ('draft', 'done')], { - 'state': 'draft', - }) + Move.draft([m for s in shipments for m in s.moves]) for shipment in shipments: Move.write([m for m in shipment.moves if m.state != 'done'], { @@ -1928,10 +1862,7 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView): pool = Pool() Move = pool.get('stock.move') Date = pool.get('ir.date') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('done', 'cancel')], { - 'state': 'done', - }) + Move.do([m for s in shipments for m in s.moves]) cls.write(shipments, { 'effective_date': Date.today(), }) @@ -1941,10 +1872,7 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView): @Workflow.transition('cancel') def cancel(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('cancel', 'done')], { - 'state': 'cancel', - }) + Move.cancel([m for s in shipments for m in s.moves]) @classmethod @ModelView.button_action('stock.wizard_shipment_internal_assign') @@ -1966,10 +1894,7 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView): @ModelView.button def assign_force(cls, shipments): Move = Pool().get('stock.move') - Move.write([m for s in shipments for m in s.moves - if m.state not in ('assigned', 'done')], { - 'state': 'assigned', - }) + Move.assign([m for s in shipments for m in s.moves]) cls.assign(shipments) diff --git a/tests/scenario_stock_shipment_out.rst b/tests/scenario_stock_shipment_out.rst index 62d2c066a5..bfceb9ae55 100644 --- a/tests/scenario_stock_shipment_out.rst +++ b/tests/scenario_stock_shipment_out.rst @@ -132,11 +132,11 @@ Make 1 unit of the product available:: >>> incoming_move.to_location = storage_loc >>> incoming_move.planned_date = today >>> incoming_move.effective_date = today - >>> incoming_move.state = 'done' >>> incoming_move.company = company >>> incoming_move.unit_price = Decimal('1') >>> incoming_move.currency = currency >>> incoming_move.save() + >>> StockMove.do([incoming_move.id], config.context) Assign the shipment now:: diff --git a/tests/test_stock.py b/tests/test_stock.py index 548fd35f9d..25d658c929 100644 --- a/tests/test_stock.py +++ b/tests/test_stock.py @@ -136,19 +136,18 @@ class StockTestCase(unittest.TestCase): today = datetime.date.today() - self.move.create({ - 'product': product.id, - 'uom': kg.id, - 'quantity': 5, - 'from_location': supplier.id, - 'to_location': storage.id, - 'planned_date': today + relativedelta(days=-5), - 'effective_date': today + relativedelta(days=-5), - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': kg.id, + 'quantity': 5, + 'from_location': supplier.id, + 'to_location': storage.id, + 'planned_date': today + relativedelta(days=-5), + 'effective_date': today + relativedelta(days=-5), + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + })]) self.move.create({ 'product': product.id, 'uom': kg.id, @@ -156,11 +155,22 @@ class StockTestCase(unittest.TestCase): 'from_location': supplier.id, 'to_location': storage.id, 'planned_date': today + relativedelta(days=-4), - 'state': 'draft', 'company': company.id, 'unit_price': Decimal('1'), 'currency': currency.id, }) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': kg.id, + 'quantity': 1, + 'from_location': storage.id, + 'to_location': customer.id, + 'planned_date': today, + 'effective_date': today, + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + })]) self.move.create({ 'product': product.id, 'uom': kg.id, @@ -168,20 +178,6 @@ class StockTestCase(unittest.TestCase): 'from_location': storage.id, 'to_location': customer.id, 'planned_date': today, - 'effective_date': today, - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) - self.move.create({ - 'product': product.id, - 'uom': kg.id, - 'quantity': 1, - 'from_location': storage.id, - 'to_location': customer.id, - 'planned_date': today, - 'state': 'draft', 'company': company.id, 'unit_price': Decimal('1'), 'currency': currency.id, @@ -193,7 +189,6 @@ class StockTestCase(unittest.TestCase): 'from_location': storage.id, 'to_location': customer.id, 'planned_date': today + relativedelta(days=5), - 'state': 'draft', 'company': company.id, 'unit_price': Decimal('1'), 'currency': currency.id, @@ -205,7 +200,6 @@ class StockTestCase(unittest.TestCase): 'from_location': supplier.id, 'to_location': storage.id, 'planned_date': today + relativedelta(days=7), - 'state': 'draft', 'company': company.id, 'unit_price': Decimal('1'), 'currency': currency.id, @@ -293,19 +287,18 @@ class StockTestCase(unittest.TestCase): today + relativedelta(days=-2), ] - self.move.create({ - 'product': product.id, - 'uom': g.id, - 'quantity': 1, - 'from_location': supplier.id, - 'to_location': storage.id, - 'planned_date': today + relativedelta(days=-5), - 'effective_date': today + relativedelta(days=-5), - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': g.id, + 'quantity': 1, + 'from_location': supplier.id, + 'to_location': storage.id, + 'planned_date': today + relativedelta(days=-5), + 'effective_date': today + relativedelta(days=-5), + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + })]) # Nothing should change when adding a small quantity test_products_by_location() @@ -355,17 +348,16 @@ class StockTestCase(unittest.TestCase): 'parent': storage.id, }) - self.move.create({ - 'product': product.id, - 'uom': unit.id, - 'quantity': 1, - 'from_location': lost_found.id, - 'to_location': storage.id, - 'planned_date': today, - 'effective_date': today, - 'state': 'done', - 'company': company.id, - }) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': unit.id, + 'quantity': 1, + 'from_location': lost_found.id, + 'to_location': storage.id, + 'planned_date': today, + 'effective_date': today, + 'company': company.id, + })]) products_by_location = self.product.products_by_location( [warehouse.id], [product.id], with_childs=True) @@ -402,45 +394,42 @@ class StockTestCase(unittest.TestCase): today = datetime.date.today() - self.move.create({ - 'product': product.id, - 'uom': unit.id, - 'quantity': 10, - 'from_location': supplier.id, - 'to_location': storage.id, - 'planned_date': today + relativedelta(days=-5), - 'effective_date': today + relativedelta(days=-5), - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) - self.move.create({ - 'product': product.id, - 'uom': unit.id, - 'quantity': 15, - 'from_location': supplier.id, - 'to_location': storage.id, - 'planned_date': today + relativedelta(days=-4), - 'effective_date': today + relativedelta(days=-4), - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) - self.move.create({ - 'product': product.id, - 'uom': unit.id, - 'quantity': 5, - 'from_location': storage.id, - 'to_location': customer.id, - 'planned_date': today + relativedelta(days=-3), - 'effective_date': today + relativedelta(days=-3), - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': unit.id, + 'quantity': 10, + 'from_location': supplier.id, + 'to_location': storage.id, + 'planned_date': today + relativedelta(days=-5), + 'effective_date': today + relativedelta(days=-5), + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + })]) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': unit.id, + 'quantity': 15, + 'from_location': supplier.id, + 'to_location': storage.id, + 'planned_date': today + relativedelta(days=-4), + 'effective_date': today + relativedelta(days=-4), + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + })]) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': unit.id, + 'quantity': 5, + 'from_location': storage.id, + 'to_location': customer.id, + 'planned_date': today + relativedelta(days=-3), + 'effective_date': today + relativedelta(days=-3), + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + })]) tests = [ (-5, { @@ -470,33 +459,31 @@ class StockTestCase(unittest.TestCase): quantities[cache.location.id]) # Test check_period_closed - self.move.create({ - 'product': product.id, - 'uom': unit.id, - 'quantity': 10, - 'from_location': supplier.id, - 'to_location': storage.id, - 'planned_date': today, - 'effective_date': today, - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) + self.move.do([self.move.create({ + 'product': product.id, + 'uom': unit.id, + 'quantity': 10, + 'from_location': supplier.id, + 'to_location': storage.id, + 'planned_date': today, + 'effective_date': today, + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + })]) self.assertRaises(Exception, self.move.create, { - 'product': product.id, - 'uom': unit.id, - 'quantity': 10, - 'from_location': supplier.id, - 'to_location': storage.id, - 'planned_date': today + relativedelta(days=-5), - 'effective_date': today + relativedelta(days=-5), - 'state': 'done', - 'company': company.id, - 'unit_price': Decimal('1'), - 'currency': currency.id, - }) + 'product': product.id, + 'uom': unit.id, + 'quantity': 10, + 'from_location': supplier.id, + 'to_location': storage.id, + 'planned_date': today + relativedelta(days=-5), + 'effective_date': today + relativedelta(days=-5), + 'company': company.id, + 'unit_price': Decimal('1'), + 'currency': currency.id, + }) # Test close period check period = self.period.create({