diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index e562652e30a..de208f79881 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -296,9 +296,16 @@ class purchase_order(osv.osv): def set_order_line_status(self, cr, uid, ids, status, context=None): line = self.pool.get('purchase.order.line') + order_line_ids = [] + proc_obj = self.pool.get('procurement.order') for order in self.browse(cr, uid, ids, context=context): - order_line_ids = [order_line.id for order_line in order.order_line] + order_line_ids += [po_line.id for po_line in order.order_line] + if order_line_ids: line.write(cr, uid, order_line_ids, {'state': status}, context=context) + if order_line_ids and status == 'cancel': + procs = proc_obj.search(cr, uid, [('purchase_line_id', 'in', order_line_ids)], context=context) + if procs: + proc_obj.write(cr, uid, procs, {'state': 'exception'}, context=context) return True def button_dummy(self, cr, uid, ids, context=None): @@ -613,10 +620,6 @@ class purchase_order(osv.osv): return True return False - def wkf_action_cancel(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'state': 'cancel'}) - self.set_order_line_status(cr, uid, ids, 'cancel', context=context) - def action_cancel(self, cr, uid, ids, context=None): for purchase in self.browse(cr, uid, ids, context=context): for pick in purchase.picking_ids: @@ -630,7 +633,7 @@ class purchase_order(osv.osv): if inv and inv.state not in ('cancel', 'draft'): raise osv.except_osv( _('Unable to cancel this purchase order.'), - _('You must first cancel all receptions related to this purchase order.')) + _('You must first cancel all invoices related to this purchase order.')) self.pool.get('account.invoice') \ .signal_invoice_cancel(cr, uid, map(attrgetter('id'), purchase.invoice_ids)) self.write(cr, uid, ids, {'state': 'cancel'}) @@ -764,6 +767,15 @@ class purchase_order(osv.osv): def picking_done(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'shipped':1,'state':'approved'}, context=context) + # Do check on related procurements: + proc_obj = self.pool.get("procurement.order") + po_lines = [] + for po in self.browse(cr, uid, ids, context=context): + po_lines += [x.id for x in po.order_line] + if po_lines: + procs = proc_obj.search(cr, uid, [('purchase_line_id', 'in', po_lines)], context=context) + if procs: + proc_obj.check(cr, uid, procs, context=context) self.message_post(cr, uid, ids, body=_("Products received"), context=context) return True diff --git a/addons/purchase/purchase_workflow.xml b/addons/purchase/purchase_workflow.xml index fe6b5a3f045..810c0a74064 100644 --- a/addons/purchase/purchase_workflow.xml +++ b/addons/purchase/purchase_workflow.xml @@ -37,7 +37,7 @@ cancel function True - wkf_action_cancel() + action_cancel() diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index 0214eef6da1..49a9d0e0894 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -364,8 +364,8 @@ class procurement_order(osv.osv): if qty <= 0: continue - if op.product_id.type not in ('consu'): - qty -= orderpoint_obj.subtract_procurements(cr, uid, op, context=context) + + qty -= orderpoint_obj.subtract_procurements(cr, uid, op, context=context) if qty > 0: proc_id = procurement_obj.create(cr, uid, diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 3cfb10ac05d..d38f6f5cd5f 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -3851,12 +3851,16 @@ class stock_warehouse_orderpoint(osv.osv): '''This function returns quantity of product that needs to be deducted from the orderpoint computed quantity because there's already a procurement created with aim to fulfill it. ''' qty = 0 + uom_obj = self.pool.get("product.uom") for procurement in orderpoint.procurement_ids: - if procurement in ('cancel', 'done'): + if procurement.state in ('cancel', 'done'): continue + procurement_qty = uom_obj._compute_qty_obj(cr, uid, procurement.product_uom, procurement.product_qty, procurement.product_id.uom_id, context=context) for move in procurement.move_ids: if move.state not in ('draft', 'cancel'): - qty += move.product_qty + #if move is already confirmed, assigned or done, the virtual stock is already taking this into account so it shouldn't be deducted + procurement_qty -= move.product_qty + qty += procurement_qty return qty def _check_product_uom(self, cr, uid, ids, context=None): @@ -3891,7 +3895,7 @@ class stock_warehouse_orderpoint(osv.osv): 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"), 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"), 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type', '=', 'product')]), - 'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True), + 'product_uom': fields.related('product_id', 'uom_id', type='many2one', relation='product.uom', string='Product Unit of Measure', readonly=True, required=True), 'product_min_qty': fields.float('Minimum Quantity', required=True, help="When the virtual stock goes below the Min Quantity specified for this field, OpenERP generates "\ "a procurement to bring the forecasted quantity to the Max Quantity."),