From 7ee4eb26563395ecf48afac3389dcdc7cc2188c5 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 19 Jul 2013 13:55:33 +0200 Subject: [PATCH] [WIP] Add removal and putaways in views bzr revid: jco@openerp.com-20130719115533-754m6591p3ykutea --- addons/procurement/procurement.py | 3 +- addons/purchase/stock.py | 8 ++- addons/stock/stock.py | 69 +++++-------------- addons/stock_location/stock_location.py | 30 ++++++-- addons/stock_location/stock_location_view.xml | 60 ++++++++++++++++ 5 files changed, 109 insertions(+), 61 deletions(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index e8a693bb37a..daeeb8f19d8 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -56,7 +56,8 @@ class procurement_group(osv.osv): _description = 'Procurement Requisition' _order = "id desc" _columns = { - 'name': fields.char('Reference'), + 'name': fields.char('Reference'), + 'partner_id': fields.many2one('res.partner', string = 'Partner'), #Sale should pass it here } _defaults = { 'name': lambda self, cr, uid, c: self.pool.get('ir.sequence').get(cr, uid, 'procurement.group') or '' diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py index b5faf909e3f..267e1b324fe 100644 --- a/addons/purchase/stock.py +++ b/addons/purchase/stock.py @@ -29,8 +29,12 @@ class stock_move(osv.osv): readonly=True), } - - + def action_done(self, cr ,uid, ids, context=None): + res = super(stock_move, self).action_done(cr, uid, ids, context) + wf_service = netsvc.LocalService('workflow') + for id in ids: + wf_service.trg_trigger(uid, 'stock.move', id, cr) + return res # # Inherit of picking to add the link to the PO # diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 48b948714ce..776098dc82b 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -187,11 +187,14 @@ class stock_quant(osv.osv): toreserve.append(quant.id) return self.write(cr, uid, toreserve, {'reservation_id': move.id}, context=context) - # add location_dest_id in parameters (False=use the desitnation of the move) + # add location_dest_id in parameters (False=use the destination of the move) def quants_move(self, cr, uid, quants, move, context=None): for quant, qty in quants: self.move_single_quant(cr, uid, quant, qty, move, context=context) + def check_preferred_location(self, cr, uid, move, context=None): + return move.location_dest_id + def move_single_quant(self, cr, uid, quant, qty, move, context=None): if not quant: quant = self._quant_create(cr, uid, qty, move, context=context) @@ -199,7 +202,7 @@ class stock_quant(osv.osv): self._quant_split(cr, uid, quant, qty, context=context) # FP Note: improve this using preferred locations location_to = move.location_dest_id - + location_to = self.check_preferred_location(cr, uid, move, context=context) self.write(cr, uid, [quant.id], { 'location_id': location_to.id, 'reservation_id': move.move_dest_id and move.move_dest_id.id or False, @@ -231,8 +234,8 @@ class stock_quant(osv.osv): elif removal_strategy=='lifo': result += self._quants_get_lifo(cr, uid, location, product, qty, domain, prefered_order=prefered_order, context=context) else: + print removal_strategy raise osv.except_osv(_('Error!'), _('Removal strategy %s not implemented.' % (removal_strategy,))) - return result @@ -2159,11 +2162,11 @@ class stock_picking_in(osv.osv): _table = "stock_picking" _description = "Incoming Shipments" - def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): - return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count) - - def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): - return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load) +# def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): +# return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count) +# +# def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): +# return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load) def check_access_rights(self, cr, uid, operation, raise_exception=True): #override in order to redirect the check of acces rights on the stock.picking object @@ -2173,26 +2176,6 @@ class stock_picking_in(osv.osv): #override in order to redirect the check of acces rules on the stock.picking object return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context) - def create_workflow(self, cr, uid, ids, context=None): - # overridden in order to trigger the workflow of stock.picking at the end of create, - # write and unlink operation instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').create_workflow(cr, uid, ids, context=context) - - def delete_workflow(self, cr, uid, ids, context=None): - # overridden in order to trigger the workflow of stock.picking at the end of create, - # write and unlink operation instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').delete_workflow(cr, uid, ids, context=context) - - def step_workflow(self, cr, uid, ids, context=None): - # overridden in order to trigger the workflow of stock.picking at the end of create, - # write and unlink operation instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').step_workflow(cr, uid, ids, context=context) - - def signal_workflow(self, cr, uid, ids, signal, context=None): - # overridden in order to fire the workflow signal on given stock.picking workflow instance - # instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context) - _columns = { 'backorder_id': fields.many2one('stock.picking.in', 'Back Order of', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True), 'state': fields.selection( @@ -2220,11 +2203,11 @@ class stock_picking_out(osv.osv): _table = "stock_picking" _description = "Delivery Orders" - def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): - return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count) - - def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): - return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load) +# def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): +# return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count) +# +# def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): +# return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load) def check_access_rights(self, cr, uid, operation, raise_exception=True): #override in order to redirect the check of acces rights on the stock.picking object @@ -2234,26 +2217,6 @@ class stock_picking_out(osv.osv): #override in order to redirect the check of acces rules on the stock.picking object return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context) - def create_workflow(self, cr, uid, ids, context=None): - # overridden in order to trigger the workflow of stock.picking at the end of create, - # write and unlink operation instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').create_workflow(cr, uid, ids, context=context) - - def delete_workflow(self, cr, uid, ids, context=None): - # overridden in order to trigger the workflow of stock.picking at the end of create, - # write and unlink operation instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').delete_workflow(cr, uid, ids, context=context) - - def step_workflow(self, cr, uid, ids, context=None): - # overridden in order to trigger the workflow of stock.picking at the end of create, - # write and unlink operation instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').step_workflow(cr, uid, ids, context=context) - - def signal_workflow(self, cr, uid, ids, signal, context=None): - # overridden in order to fire the workflow signal on given stock.picking workflow instance - # instead of its own workflow (which is not existing) - return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context) - _columns = { 'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True), 'state': fields.selection( diff --git a/addons/stock_location/stock_location.py b/addons/stock_location/stock_location.py index de27cd57eb5..7aa5fc46669 100644 --- a/addons/stock_location/stock_location.py +++ b/addons/stock_location/stock_location.py @@ -183,7 +183,8 @@ class product_putaway_strategy(osv.osv): _columns = { 'product_categ_id':fields.many2one('product.category', 'Product Category', required=True), 'location_id': fields.many2one('stock.location','Parent Location', help="Parent Destination Location from which a child bin location needs to be chosen", required=True), #domain=[('type', '=', 'parent')], - 'method': fields.selection([('empty', 'Empty'), ('fixed', 'Fixed Location')], "Method", required = True), + 'method': fields.selection([('fixed', 'Fixed Location')], "Method", required = True), + 'location_spec_id': fields.many2one('stock.location','Specific Location', help="When the location is specific, it will be put over there"), #domain=[('type', '=', 'parent')], } # TODO: move this on stock module @@ -193,8 +194,9 @@ class product_removal_strategy(osv.osv): _description = 'Removal Strategy' _order = 'sequence' _columns = { - 'product_categ_id': fields.many2one('product.removal', 'Category', required=True), + 'product_categ_id': fields.many2one('product.category', 'Category', required=True), 'sequence': fields.integer('Sequence'), + 'method': fields.selection([('fifo', 'FIFO'), ('lifo', 'LIFO')], "Method", required = True), 'location_id': fields.many2one('stock.location', 'Locations', required=True), } @@ -223,6 +225,18 @@ class stock_move_putaway(osv.osv): 'quantity': fields.float('Quantity', required=True), } + +class stock_quant(osv.osv): + _inherit = "stock.quant" + def check_preferred_location(self, cr, uid, move, context=None): + # moveputaway_obj = self.pool.get('stock.move.putaway') + if move.putaway_ids and move.putaway_ids[0]: + #Take only first suggestion for the moment + return move.putaway_ids[0].location_id + else: + return super(stock_quant, self).check_preferred_location(cr, uid, move, context=context) + + class stock_move(osv.osv): _inherit = 'stock.move' _columns = { @@ -244,10 +258,16 @@ class stock_move(osv.osv): # Create the stock.move.putaway records def _putaway_apply(self,cr, uid, ids, context=None): + moveputaway_obj = self.pool.get('stock.move.putaway') for move in self.browse(cr, uid, ids, context=context): - res = self.pool.get('stock.location').get_putaway_strategy(cr, uid, move.location_dest_id, move.product_id, context=context) - if res: - raise 'put away strategies not implemented yet!' + putaway = self.pool.get('stock.location').get_putaway_strategy(cr, uid, move.location_dest_id, move.product_id, context=context) + if putaway: + # Should call different methods here in later versions + # TODO: take care of lots + if putaway.method == 'fixed' and putaway.location_id: + moveputaway_obj.create(cr, uid, {'move_id': move.id, + 'location_id': putaway.location_id.id, + 'quantity': move.product_uom_qty}, context=context) return True def action_assign(self, cr, uid, ids, context=None): diff --git a/addons/stock_location/stock_location_view.xml b/addons/stock_location/stock_location_view.xml index 7f09f0b93a8..c136492367b 100644 --- a/addons/stock_location/stock_location_view.xml +++ b/addons/stock_location/stock_location_view.xml @@ -2,6 +2,63 @@ + + + stock.location.form + stock.location + + + +

+ Removal strategies define the method used for suggesting the + location to take the products from +

+ + + + + + +

+ +

+ + + + + + + +
+
+
+ + + product.putaway.form + product.putaway + +
+ + + + + + +
+ + + product.removal.form + product.removal + +
+ + + + + +
+ + stock.location.path.tree stock.location.path @@ -118,6 +175,9 @@ location.

+ + +