Use reference fields
Merge all shipment Many2One into shipment Reference Add origin Reference on Stock Move issue2642 review717002
This commit is contained in:
1 parent
388aed5112
commit
c7326c55fb
5 files changed
+96
-58
No files matched your search
@@ -1,3 +1,5 @@
|
||||
* Merge all shipment Many2One into shipment Reference
|
||||
* Add origin Reference on Stock Move
|
||||
* Add workflow to stock move
|
||||
|
||||
Version 2.6.0 - 2012-10-22
|
||||
|
||||
+1
-1
@@ -16,6 +16,7 @@ def register():
|
||||
Location,
|
||||
Party,
|
||||
ProductsByLocationsStart,
|
||||
Move,
|
||||
ShipmentIn,
|
||||
ShipmentInReturn,
|
||||
ShipmentOut,
|
||||
@@ -27,7 +28,6 @@ def register():
|
||||
AssignShipmentInReturnAssignFailed,
|
||||
Period,
|
||||
Cache,
|
||||
Move,
|
||||
Template,
|
||||
Product,
|
||||
ProductByLocationStart,
|
||||
|
||||
@@ -50,30 +50,17 @@ class Move(Workflow, ModelSQL, ModelView):
|
||||
to_location = fields.Many2One("stock.location", "To Location", select=True,
|
||||
required=True, states=STATES, depends=DEPENDS,
|
||||
domain=[('type', 'not in', ('warehouse', 'view'))])
|
||||
shipment_in = fields.Many2One('stock.shipment.in', 'Supplier Shipment',
|
||||
domain=[('company', '=', Eval('company'))], depends=['company'],
|
||||
readonly=True, select=True, ondelete='CASCADE')
|
||||
shipment_out = fields.Many2One('stock.shipment.out', 'Customer Shipment',
|
||||
domain=[('company', '=', Eval('company'))], depends=['company'],
|
||||
readonly=True, select=True, ondelete='CASCADE')
|
||||
shipment_out_return = fields.Many2One('stock.shipment.out.return',
|
||||
'Customer Return Shipment', readonly=True, select=True,
|
||||
domain=[('company', '=', Eval('company'))], depends=['company'],
|
||||
ondelete='CASCADE')
|
||||
shipment_in_return = fields.Many2One('stock.shipment.in.return',
|
||||
'Supplier Return Shipment', readonly=True, select=True,
|
||||
domain=[('company', '=', Eval('company'))], depends=['company'],
|
||||
ondelete='CASCADE')
|
||||
shipment_internal = fields.Many2One('stock.shipment.internal',
|
||||
'Internal Shipment', readonly=True, select=True, ondelete='CASCADE',
|
||||
domain=[('company', '=', Eval('company'))], depends=['company'])
|
||||
shipment = fields.Reference('Shipment', selection='get_shipment',
|
||||
readonly=True, select=True)
|
||||
origin = fields.Reference('Origin', selection='get_origin', select=True,
|
||||
states={
|
||||
'readonly': Eval('state') != 'draft',
|
||||
},
|
||||
depends=['state'])
|
||||
planned_date = fields.Date("Planned Date", states={
|
||||
'readonly': (In(Eval('state'), ['cancel', 'assigned', 'done'])
|
||||
| Eval('shipment_in') | Eval('shipment_out')
|
||||
| Eval('shipment_in_return') | Eval('shipment_out_return')
|
||||
| Eval('shipment_internal'))
|
||||
}, depends=['state', 'shipment_in', 'shipment_out',
|
||||
'shipment_in_return', 'shipment_out_return', 'shipment_internal'],
|
||||
| Eval('shipment'))
|
||||
}, depends=['state', 'shipment'],
|
||||
select=True)
|
||||
effective_date = fields.Date("Effective Date", readonly=True, select=True)
|
||||
state = fields.Selection([
|
||||
@@ -122,18 +109,6 @@ class Move(Workflow, ModelSQL, ModelView):
|
||||
('check_from_to_locations',
|
||||
'CHECK(from_location != to_location)',
|
||||
'Source and destination location must be different'),
|
||||
('check_shipment',
|
||||
('CHECK((COALESCE(shipment_in, 0) / COALESCE(shipment_in, 1) '
|
||||
'+ COALESCE(shipment_out, 0) / '
|
||||
'COALESCE(shipment_out, 1) '
|
||||
'+ COALESCE(shipment_internal, 0) / '
|
||||
'COALESCE(shipment_internal, 1) '
|
||||
'+ COALESCE(shipment_in_return, 0) / '
|
||||
'COALESCE(shipment_in_return, 1) '
|
||||
'+ COALESCE(shipment_out_return, 0) / '
|
||||
'COALESCE(shipment_out_return, 1)) '
|
||||
'<= 1)'),
|
||||
'Move can be on only one Shipment'),
|
||||
]
|
||||
cls._order[0] = ('id', 'DESC')
|
||||
cls._error_messages.update({
|
||||
@@ -213,6 +188,22 @@ class Move(Workflow, ModelSQL, ModelView):
|
||||
table = TableHandler(cursor, cls, module_name)
|
||||
table.drop_constraint('check_packing_in_out')
|
||||
|
||||
# Migration from 2.6: merge all shipments
|
||||
table.drop_constraint('check_shipment')
|
||||
shipments = {
|
||||
'shipment_in': 'stock.shipment.in',
|
||||
'shipment_out': 'stock.shipment.out',
|
||||
'shipment_out_return': 'stock.shipment.out.return',
|
||||
'shipment_in_return': 'stock.shipment.in.return',
|
||||
'shipment_internal': 'stock.shipment.internal',
|
||||
}
|
||||
for column, model in shipments.iteritems():
|
||||
if table.column_exist(column):
|
||||
cursor.execute('UPDATE "' + cls._table + '" '
|
||||
'SET shipment = \'' + model + ',\' || "' + column + '" '
|
||||
'WHERE "' + column + '" IS NOT NULL')
|
||||
table.drop_column(column)
|
||||
|
||||
# Add index on create_date
|
||||
table.index_action('create_date', action='add')
|
||||
|
||||
@@ -306,6 +297,40 @@ class Move(Workflow, ModelSQL, ModelView):
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _get_shipment():
|
||||
'Return list of Model names for shipment Reference'
|
||||
return [
|
||||
'stock.shipment.in',
|
||||
'stock.shipment.out',
|
||||
'stock.shipment.out.return',
|
||||
'stock.shipment.in.return',
|
||||
'stock.shipment.internal',
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_shipment(cls):
|
||||
Model = Pool().get('ir.model')
|
||||
models = cls._get_shipment()
|
||||
models = Model.search([
|
||||
('model', 'in', models),
|
||||
])
|
||||
return [(None, '')] + [(m.model, m.name) for m in models]
|
||||
|
||||
@staticmethod
|
||||
def _get_origin():
|
||||
'Return list of Model names for origin Reference'
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def get_origin(cls):
|
||||
Model = Pool().get('ir.model')
|
||||
models = cls._get_origin()
|
||||
models = Model.search([
|
||||
('model', 'in', models),
|
||||
])
|
||||
return [(None, '')] + [(m.model, m.name) for m in models]
|
||||
|
||||
@classmethod
|
||||
def validate(cls, moves):
|
||||
super(Move, cls).validate(moves)
|
||||
|
||||
@@ -52,7 +52,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<record model="ir.action.act_window.domain" id="act_move_form_domain_from_supplier_waiting">
|
||||
<field name="name">From Suppliers Waiting</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain">[('from_location.type', '=', 'supplier'), ('state', '=', 'draft'), ('shipment_in', '=', None)]</field>
|
||||
<field name="domain">[('from_location.type', '=', 'supplier'), ('state', '=', 'draft'), ('shipment', '=', None)]</field>
|
||||
<field name="act_window" ref="act_move_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_move_form_domain_to_customer">
|
||||
|
||||
+33
-22
@@ -80,7 +80,7 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
incoming_moves = fields.Function(fields.One2Many('stock.move', None,
|
||||
'Incoming Moves',
|
||||
add_remove=[
|
||||
('shipment_in', '=', None),
|
||||
('shipment', '=', None),
|
||||
('from_location', '=', Eval('supplier_location')),
|
||||
('state', '=', 'draft'),
|
||||
('to_location', '=', Eval('warehouse_input')),
|
||||
@@ -111,7 +111,7 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
depends=['state', 'warehouse', 'warehouse_input',
|
||||
'warehouse_storage', 'company']),
|
||||
'get_inventory_moves', setter='set_inventory_moves')
|
||||
moves = fields.One2Many('stock.move', 'shipment_in', 'Moves',
|
||||
moves = fields.One2Many('stock.move', 'shipment', 'Moves',
|
||||
domain=[('company', '=', Eval('company'))], readonly=True,
|
||||
depends=['company'])
|
||||
code = fields.Char("Code", size=None, select=True, readonly=True)
|
||||
@@ -196,10 +196,11 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
and TableHandler.table_exist(cursor, Move._table)):
|
||||
cursor.execute('SELECT shipment.id, MAX(move.company) '
|
||||
'FROM "%s" AS shipment '
|
||||
'INNER JOIN "%s" AS move ON shipment.id = move.shipment_in '
|
||||
'INNER JOIN "%s" AS move '
|
||||
'ON \'%s,\' || shipment.id = move.shipment '
|
||||
'GROUP BY shipment.id '
|
||||
'ORDER BY MAX(move.company)'
|
||||
% (cls._table, Move._table))
|
||||
% (cls._table, Move._table, cls.__name__))
|
||||
for company_id, values in itertools.groupby(cursor.fetchall(),
|
||||
operator.itemgetter(1)):
|
||||
shipment_ids = [x[0] for x in values]
|
||||
@@ -357,7 +358,7 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
move.uom = incoming_move.uom
|
||||
move.quantity = incoming_move.quantity
|
||||
move.from_location = incoming_move.to_location
|
||||
move.to_location = incoming_move.shipment_in.warehouse.storage_location
|
||||
move.to_location = incoming_move.shipment.warehouse.storage_location
|
||||
move.state = Move.default_state()
|
||||
# Product will be considered in stock only when the inventory
|
||||
# move will be made:
|
||||
@@ -381,11 +382,13 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def delete(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
# Cancel before delete
|
||||
cls.cancel(shipments)
|
||||
for shipment in shipments:
|
||||
if shipment.state != 'cancel':
|
||||
cls.raise_user_error('delete_cancel', shipment.rec_name)
|
||||
Move.delete([m for s in shipments for m in s.moves])
|
||||
super(ShipmentIn, cls).delete(shipments)
|
||||
|
||||
@classmethod
|
||||
@@ -461,7 +464,7 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView):
|
||||
Bool(Eval('moves'))),
|
||||
}, domain=[('type', '=', 'supplier')],
|
||||
depends=['state', 'moves'])
|
||||
moves = fields.One2Many('stock.move', 'shipment_in_return', 'Moves',
|
||||
moves = fields.One2Many('stock.move', 'shipment', 'Moves',
|
||||
states={
|
||||
'readonly': And(Or(Not(Equal(Eval('state'), 'draft')),
|
||||
Not(Bool(Eval('from_location')))),
|
||||
@@ -552,10 +555,10 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView):
|
||||
cursor.execute('SELECT shipment.id, MAX(move.company) '
|
||||
'FROM "%s" AS shipment '
|
||||
'INNER JOIN "%s" AS move '
|
||||
'ON shipment.id = move.shipment_in_return '
|
||||
'ON \'%s,\' || shipment.id = move.shipment '
|
||||
'GROUP BY shipment.id '
|
||||
'ORDER BY MAX(move.company)'
|
||||
% (cls._table, Move._table))
|
||||
% (cls._table, Move._table, cls.__name__))
|
||||
for company_id, values in itertools.groupby(cursor.fetchall(),
|
||||
operator.itemgetter(1)):
|
||||
shipment_ids = [x[0] for x in values]
|
||||
@@ -621,11 +624,13 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def delete(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
# Cancel before delete
|
||||
cls.cancel(shipments)
|
||||
for shipment in shipments:
|
||||
if shipment.state != 'cancel':
|
||||
cls.raise_user_error('delete_cancel', shipment.rec_name)
|
||||
Move.delete([m for s in shipments for m in s.moves])
|
||||
super(ShipmentInReturn, cls).delete(shipments)
|
||||
|
||||
@classmethod
|
||||
@@ -795,7 +800,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
depends=['state', 'warehouse', 'warehouse_storage',
|
||||
'warehouse_output', 'company']),
|
||||
'get_inventory_moves', setter='set_inventory_moves')
|
||||
moves = fields.One2Many('stock.move', 'shipment_out', 'Moves',
|
||||
moves = fields.One2Many('stock.move', 'shipment', 'Moves',
|
||||
domain=[('company', '=', Eval('company'))], depends=['company'],
|
||||
readonly=True)
|
||||
code = fields.Char("Code", size=None, select=True, readonly=True)
|
||||
@@ -889,10 +894,11 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
and TableHandler.table_exist(cursor, Move._table)):
|
||||
cursor.execute('SELECT shipment.id, MAX(move.company) '
|
||||
'FROM "%s" AS shipment '
|
||||
'INNER JOIN "%s" AS move ON shipment.id = move.shipment_out '
|
||||
'INNER JOIN "%s" AS move '
|
||||
'ON \'%s,\' || shipment.id = move.shipment '
|
||||
'GROUP BY shipment.id '
|
||||
'ORDER BY MAX(move.company)'
|
||||
% (cls._table, Move._table))
|
||||
% (cls._table, Move._table, cls.__name__))
|
||||
for company_id, values in itertools.groupby(cursor.fetchall(),
|
||||
operator.itemgetter(1)):
|
||||
shipment_ids = [x[0] for x in values]
|
||||
@@ -1015,12 +1021,12 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
continue
|
||||
to_create.append({
|
||||
'from_location': (
|
||||
move.shipment_out.warehouse.storage_location.id),
|
||||
move.shipment.warehouse.storage_location.id),
|
||||
'to_location': move.from_location.id,
|
||||
'product': move.product.id,
|
||||
'uom': move.uom.id,
|
||||
'quantity': move.quantity,
|
||||
'shipment_out': shipment.id,
|
||||
'shipment': str(shipment),
|
||||
'planned_date': move.planned_date,
|
||||
'state': 'draft',
|
||||
'company': move.company.id,
|
||||
@@ -1085,7 +1091,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
'product': move.product.id,
|
||||
'uom': move.uom.id,
|
||||
'quantity': out_quantity,
|
||||
'shipment_out': shipment.id,
|
||||
'shipment': str(shipment),
|
||||
'state': 'draft',
|
||||
'planned_date': shipment.planned_date,
|
||||
'company': move.company.id,
|
||||
@@ -1189,11 +1195,13 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def delete(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
# Cancel before delete
|
||||
cls.cancel(shipments)
|
||||
for shipment in shipments:
|
||||
if shipment.state != 'cancel':
|
||||
cls.raise_user_error('delete_cancel', shipment.rec_name)
|
||||
Move.delete([m for s in shipments for m in s.moves])
|
||||
super(ShipmentOut, cls).delete(shipments)
|
||||
|
||||
@staticmethod
|
||||
@@ -1310,7 +1318,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
depends=['state', 'warehouse', 'warehouse_input',
|
||||
'warehouse_storage', 'company']),
|
||||
'get_inventory_moves', setter='set_inventory_moves')
|
||||
moves = fields.One2Many('stock.move', 'shipment_out_return', 'Moves',
|
||||
moves = fields.One2Many('stock.move', 'shipment', 'Moves',
|
||||
domain=[('company', '=', Eval('company'))], depends=['company'],
|
||||
readonly=True)
|
||||
code = fields.Char("Code", size=None, select=True, readonly=True)
|
||||
@@ -1379,10 +1387,10 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
cursor.execute('SELECT shipment.id, MAX(move.company) '
|
||||
'FROM "%s" AS shipment '
|
||||
'INNER JOIN "%s" AS move '
|
||||
'ON shipment.id = move.shipment_out_return '
|
||||
'ON \'%s,\' || shipment.id = move.shipment '
|
||||
'GROUP BY shipment.id '
|
||||
'ORDER BY MAX(move.company)'
|
||||
% (cls._table, Move._table))
|
||||
% (cls._table, Move._table, cls.__name__))
|
||||
for company_id, values in itertools.groupby(cursor.fetchall(),
|
||||
operator.itemgetter(1)):
|
||||
shipment_ids = [x[0] for x in values]
|
||||
@@ -1532,11 +1540,13 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def delete(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
# Cance before delete
|
||||
cls.cancel(shipments)
|
||||
for shipment in shipments:
|
||||
if shipment.state != 'cancel':
|
||||
cls.raise_user_error('delete_cancel', shipment.rec_name)
|
||||
Move.delete([m for s in shipments for m in s.moves])
|
||||
super(ShipmentOutReturn, cls).delete(shipments)
|
||||
|
||||
@classmethod
|
||||
@@ -1587,8 +1597,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
move.uom = incoming_move.uom
|
||||
move.quantity = incoming_move.quantity
|
||||
move.from_location = incoming_move.to_location
|
||||
move.to_location = incoming_move.shipment_out_return.warehouse.\
|
||||
storage_location
|
||||
move.to_location = incoming_move.shipment.warehouse.storage_location
|
||||
move.state = Move.default_state()
|
||||
# Product will be considered in stock only when the inventory
|
||||
# move will be made:
|
||||
@@ -1699,7 +1708,7 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView):
|
||||
('type', 'not in',
|
||||
['supplier', 'customer', 'warehouse', 'view']),
|
||||
], depends=['state', 'moves'])
|
||||
moves = fields.One2Many('stock.move', 'shipment_internal', 'Moves',
|
||||
moves = fields.One2Many('stock.move', 'shipment', 'Moves',
|
||||
states={
|
||||
'readonly': ((Eval('state') != 'draft')
|
||||
| ~Eval('from_location') | ~Eval('to_location')),
|
||||
@@ -1796,10 +1805,10 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView):
|
||||
cursor.execute('SELECT shipment.id, MAX(move.company) '
|
||||
'FROM "%s" AS shipment '
|
||||
'INNER JOIN "%s" AS move '
|
||||
'ON shipment.id = move.shipment_internal '
|
||||
'ON \'%s,\' || shipment.id = move.shipment '
|
||||
'GROUP BY shipment.id '
|
||||
'ORDER BY MAX(move.company)'
|
||||
% (cls._table, Move._table))
|
||||
% (cls._table, Move._table, cls.__name__))
|
||||
for company_id, values in itertools.groupby(cursor.fetchall(),
|
||||
operator.itemgetter(1)):
|
||||
shipment_ids = [x[0] for x in values]
|
||||
@@ -1838,11 +1847,13 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def delete(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
# Cancel before delete
|
||||
cls.cancel(shipments)
|
||||
for shipment in shipments:
|
||||
if shipment.state != 'cancel':
|
||||
cls.raise_user_error('delete_cancel', shipment.rec_name)
|
||||
Move.delete([m for s in shipments for m in s.moves])
|
||||
super(ShipmentInternal, cls).delete(shipments)
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in new issue
Block a user