From f322e6303d3a1afb0956b82ea50546d3668cfc35 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 18 Apr 2014 14:14:26 +0200 Subject: [PATCH 1/5] [WIP] Fix orderpoint bzr revid: jco@openerp.com-20140418121426-bebr3h2l96hf1ro7 --- addons/stock/procurement.py | 1 + addons/stock/stock.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index b9d8a52b4c6..cf60f9646b7 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -386,6 +386,7 @@ class procurement_order(osv.osv): if op.product_id.type not in ('consu'): qty -= orderpoint_obj.subtract_procurements(cr, uid, op, context=context) + print op.product_id.name, qty if qty > 0: proc_id = procurement_obj.create(cr, uid, self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context), diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 046b6a4944e..963f974173e 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -3860,11 +3860,13 @@ class stock_warehouse_orderpoint(osv.osv): ''' qty = 0 for procurement in orderpoint.procurement_ids: - if procurement in ('cancel', 'done'): + if procurement.state in ('cancel', 'done'): continue + qty2 = procurement.product_qty for move in procurement.move_ids: if move.state not in ('draft', 'cancel'): - qty += move.product_qty + qty2 -= move.product_qty + qty += qty2 return qty def _check_product_uom(self, cr, uid, ids, context=None): From c0f2b01dab045e7a593a9d5f098ba71df6697b39 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 18 Apr 2014 18:02:08 +0200 Subject: [PATCH 2/5] [IMP] Warehouse orderpoint uom is related, take into account procurement uom for orderpoint calc bzr revid: jco@openerp.com-20140418160208-4tn1uxdnlecpdi3m --- addons/stock/procurement.py | 5 ++--- addons/stock/stock.py | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index cf60f9646b7..e86181fdbdf 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -383,10 +383,9 @@ 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) - print op.product_id.name, qty + qty -= orderpoint_obj.subtract_procurements(cr, uid, op, context=context) + if qty > 0: proc_id = procurement_obj.create(cr, uid, self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context), diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 963f974173e..a676df0bba4 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -3859,10 +3859,11 @@ 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.state in ('cancel', 'done'): continue - qty2 = procurement.product_qty + qty2 = uom_obj._compute_qty_obj(cr, uid, procurement.uom_id, procurement.product_qty, procurement.product_id.uom_id, context=context) for move in procurement.move_ids: if move.state not in ('draft', 'cancel'): qty2 -= move.product_qty @@ -3901,7 +3902,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."), From 0a9f288fb58872ebc4d740ced40856353b154d47 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Tue, 22 Apr 2014 09:39:23 +0200 Subject: [PATCH 3/5] [FIX] Use correct uom field bzr revid: jco@openerp.com-20140422073923-5p91eyg3tlc354oa --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index a676df0bba4..08547c9c687 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -3863,7 +3863,7 @@ class stock_warehouse_orderpoint(osv.osv): for procurement in orderpoint.procurement_ids: if procurement.state in ('cancel', 'done'): continue - qty2 = uom_obj._compute_qty_obj(cr, uid, procurement.uom_id, procurement.product_qty, procurement.product_id.uom_id, context=context) + qty2 = 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'): qty2 -= move.product_qty From 16adb0d75d53b5d83e68afafca9d0222bb58a98a Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Tue, 22 Apr 2014 17:34:00 +0200 Subject: [PATCH 4/5] [WIP] Purchase order cancel or done results in procurement state being changed immediately bzr revid: jco@openerp.com-20140422153400-5ei2c4h4hti7up1i --- addons/purchase/purchase.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index e562652e30a..f3304c8020d 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') + lines = [] + 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] + lines += order_line_ids line.write(cr, uid, order_line_ids, {'state': status}, context=context) + if lines: + procs = proc_obj.search(cr, uid, [('purchase_line_id', 'in', lines)], context=context) + if procs: + proc_obj.write(cr, uid, procs, {'state': 'cancel'}, context=context) return True def button_dummy(self, cr, uid, ids, context=None): @@ -616,6 +623,7 @@ class purchase_order(osv.osv): 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): @@ -764,6 +772,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 From 6748d2818dd20b7c84b3df964fb925192b0d6411 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Wed, 23 Apr 2014 10:28:08 +0200 Subject: [PATCH 5/5] [IMP] Make sure procurement goes only in exception on cancel + simplify wkf bzr revid: jco@openerp.com-20140423082808-2gjgowz6h89l5alu --- addons/purchase/purchase.py | 11 ++++------- addons/purchase/purchase_workflow.xml | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index f3304c8020d..4fe26020b39 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -302,10 +302,10 @@ class purchase_order(osv.osv): order_line_ids = [order_line.id for order_line in order.order_line] lines += order_line_ids line.write(cr, uid, order_line_ids, {'state': status}, context=context) - if lines: + if lines and status == 'cancel': procs = proc_obj.search(cr, uid, [('purchase_line_id', 'in', lines)], context=context) if procs: - proc_obj.write(cr, uid, procs, {'state': 'cancel'}, context=context) + proc_obj.write(cr, uid, procs, {'state': 'exception'}, context=context) return True def button_dummy(self, cr, uid, ids, context=None): @@ -620,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): @@ -638,11 +634,12 @@ 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'}) self.set_order_line_status(cr, uid, ids, 'cancel', context=context) + self.signal_purchase_cancel(cr, uid, ids) 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()