Active Record

This commit is contained in:
Cédric Krier
2012-09-24 22:18:21 +02:00
parent bcaba928dc
commit 088e87a3af
3 changed files with 83 additions and 87 deletions
+15
View File
@@ -1,5 +1,20 @@
#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 trytond.pool import Pool
from .stock import *
from .product import *
def register():
Pool.register(
Lot,
LotType,
Move,
ShipmentIn,
ShipmentOut,
ShipmentOutReturn,
Template,
Product,
TemplateLotType,
module='stock_lot', type_='model')
+12 -14
View File
@@ -1,11 +1,15 @@
#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 trytond.model import Model, ModelSQL, fields
from trytond.model import ModelSQL, fields
from trytond.pyson import Eval
from trytond.pool import PoolMeta
__all__ = ['Template', 'Product', 'TemplateLotType']
__metaclass__ = PoolMeta
class Template(Model):
_name = 'product.template'
class Template:
__name__ = 'product.template'
# TODO to replace with a Multiple Selection
lot_required = fields.Many2Many('product.template-stock.lot.type',
@@ -16,28 +20,22 @@ class Template(Model):
},
depends=['type'])
Template()
class Product:
__name__ = 'product.product'
class Product(Model):
_name = 'product.product'
def lot_is_required(self, product, from_, to):
def lot_is_required(self, from_, to):
'Is product lot required for move with "from_" and "to" location ?'
lot_required = [t.code for t in product.lot_required]
lot_required = [t.code for t in self.lot_required]
for location in (from_, to):
if location.type in lot_required:
return True
Product()
class TemplateLotType(ModelSQL):
'Template - Stock Lot Type'
_name = 'product.template-stock.lot.type'
__name__ = 'product.template-stock.lot.type'
template = fields.Many2One('product.template', 'Template', required=True,
select=True)
type = fields.Many2One('stock.lot.type', 'Type', required=True)
TemplateLotType()
+56 -73
View File
@@ -1,36 +1,31 @@
#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 trytond.model import Model, ModelView, ModelSQL, Workflow, fields
from trytond.model import ModelView, ModelSQL, Workflow, fields
from trytond.pyson import Eval
from trytond.pool import Pool
from trytond.pool import Pool, PoolMeta
__all__ = ['Lot', 'LotType', 'Move', 'ShipmentIn', 'ShipmentOut',
'ShipmentOutReturn']
__metaclass__ = PoolMeta
class Lot(ModelSQL, ModelView):
"Stock Lot"
_name = 'stock.lot'
_description = __doc__
__name__ = 'stock.lot'
_rec_name = 'number'
number = fields.Char('Number', required=True, select=True)
product = fields.Many2One('product.product', 'Product', required=True)
Lot()
class LotType(ModelSQL, ModelView):
"Stock Lot Type"
_name = 'stock.lot.type'
_description = __doc__
__name__ = 'stock.lot.type'
name = fields.Char('Name', required=True, translate=True)
code = fields.Char('Code', required=True)
LotType()
class Move(Model):
_name = 'stock.move'
class Move:
__name__ = 'stock.move'
lot = fields.Many2One('stock.lot', 'Lot',
domain=[
('product', '=', Eval('product')),
@@ -40,66 +35,61 @@ class Move(Model):
},
depends=['state', 'product'])
def __init__(self):
super(Move, self).__init__()
self._error_messages.update({
@classmethod
def __setup__(cls):
super(Move, cls).__setup__()
cls._error_messages.update({
'lot_required': 'Lot is required for move of product "%s"!',
})
def check_lot(self, ids):
@classmethod
def check_lot(cls, moves):
"Check if lot is required"
pool = Pool()
product_obj = pool.get('product.product')
for move in self.browse(ids):
for move in moves:
if (move.state == 'done'
and not move.lot
and product_obj.lot_is_required(move.product,
and move.product.lot_is_required(
move.from_location, move.to_location)):
self.raise_user_error('lot_required', (move.product.rec_name,))
cls.raise_user_error('lot_required', (move.product.rec_name,))
def create(self, values):
new_id = super(Move, self).create(values)
self.check_lot([new_id])
return new_id
@classmethod
def create(cls, values):
move = super(Move, cls).create(values)
cls.check_lot([move])
return move
def write(self, ids, values):
result = super(Move, self).write(ids, values)
if isinstance(ids, (int, long)):
ids = [ids]
self.check_lot(ids)
return result
Move()
@classmethod
def write(cls, moves, values):
super(Move, cls).write(moves, values)
cls.check_lot(moves)
class ShipmentIn(Model):
_name = 'stock.shipment.in'
class ShipmentIn:
__name__ = 'stock.shipment.in'
def _get_inventory_moves(self, incoming_move):
result = super(ShipmentIn, self)._get_inventory_moves(incoming_move)
if result:
@classmethod
def _get_inventory_moves(cls, incoming_move):
result = super(ShipmentIn, cls)._get_inventory_moves(incoming_move)
if result and incoming_move.lot:
result['lot'] = incoming_move.lot.id
return result
ShipmentIn()
class ShipmentOut:
__name__ = 'stock.shipment.out'
class ShipmentOut(Model):
_name = 'stock.shipment.out'
@classmethod
@ModelView.button
@Workflow.transition('packed')
def pack(self, ids):
def pack(cls, shipments):
pool = Pool()
uom_obj = pool.get('product.uom')
move_obj = pool.get('stock.move')
Uom = pool.get('product.uom')
Move = pool.get('stock.move')
super(ShipmentOut, self).pack(ids)
shipments = self.browse(ids)
super(ShipmentOut, cls).pack(shipments)
# Unassign move to allow update
move_obj.write([m.id for s in shipments for m in s.outgoing_moves
Move.write([m for s in shipments for m in s.outgoing_moves
if m.state not in ('done', 'cancel')], {
'state': 'draft',
})
@@ -112,47 +102,40 @@ class ShipmentOut(Model):
for move in shipment.inventory_moves:
if not move.lot:
continue
quantity = uom_obj.compute_qty(move.uom, move.quantity,
quantity = Uom.compute_qty(move.uom, move.quantity,
move.product.default_uom, round=False)
outgoing_moves = outgoing_by_product[move.product.id]
while outgoing_moves and quantity > 0:
out_move = outgoing_moves.pop()
out_quantity = uom_obj.compute_qty(out_move.uom,
out_quantity = Uom.compute_qty(out_move.uom,
out_move.quantity, out_move.product.default_uom,
round=False)
if quantity < out_quantity:
outgoing_moves.append(move_obj.browse(
move_obj.copy(out_move.id, default={
'quantity': out_quantity - quantity,
})))
move_obj.write(out_move.id, {
outgoing_moves.extend(Move.copy([out_move], default={
'quantity': out_quantity - quantity,
}))
Move.write([out_move], {
'quantity': quantity,
})
move_obj.write(out_move.id, {
Move.write([out_move], {
'lot': move.lot.id,
})
quantity -= out_quantity
assert quantity <= 0
# Reset function field cache
shipments = self.browse(ids)
move_obj.write([m.id for s in shipments for m in s.outgoing_moves
Move.write([m for s in shipments for m in s.outgoing_moves
if m.state != 'cancel'], {
'state': 'assigned',
})
ShipmentOut()
class ShipmentOutReturn:
__name__ = 'stock.shipment.out.return'
class ShipmentOutReturn(Model):
_name = 'stock.shipment.out.return'
def _get_inventory_moves(self, incoming_move):
@classmethod
def _get_inventory_moves(cls, incoming_move):
result = super(ShipmentOutReturn,
self)._get_inventory_moves(incoming_move)
if result:
cls)._get_inventory_moves(incoming_move)
if result and incoming_move.lot:
result['lot'] = incoming_move.lot.id
return result
ShipmentOutReturn()