Use Workflow for Stock Move

review600002
This commit is contained in:
Cédric Krier
2012-12-27 21:53:07 +01:00
parent 117620f88d
commit 75bbef0077
6 changed files with 246 additions and 343 deletions
+2
View File
@@ -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
+2 -4
View File
@@ -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
+106 -115
View File
@@ -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)
+30 -105
View File
@@ -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)
+1 -1
View File
@@ -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::
+105 -118
View File
@@ -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({