diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index dadf32bedeac95a1cb37e617a69e5b1b0f5b10bc..3132e85958e3de4c0231cf30a1e72c16d9db81bf 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -373,6 +373,7 @@ class PurchaseOrder(models.Model): return self.env.ref('purchase.report_purchase_quotation').report_action(self) def button_approve(self, force=False): + self = self.filtered(lambda order: order._approval_allowed()) self.write({'state': 'purchase', 'date_approve': fields.Datetime.now()}) self.filtered(lambda p: p.company_id.po_lock == 'lock').write({'state': 'done'}) return {} @@ -387,11 +388,7 @@ class PurchaseOrder(models.Model): continue order._add_supplier_to_product() # Deal with double validation process - if order.company_id.po_double_validation == 'one_step'\ - or (order.company_id.po_double_validation == 'two_step'\ - and order.amount_total < self.env.company.currency_id._convert( - order.company_id.po_double_validation_amount, order.currency_id, order.company_id, order.date_order or fields.Date.today()))\ - or order.user_has_groups('purchase.group_purchase_manager'): + if order._approval_allowed(): order.button_approve() else: order.write({'state': 'to approve'}) @@ -709,6 +706,17 @@ class PurchaseOrder(models.Model): date = confirmed_date or self.date_planned.date() order.message_post(body="%s confirmed the receipt will take place on %s." % (order.partner_id.name, date)) + def _approval_allowed(self): + """Returns whether the order qualifies to be approved by the current user""" + self.ensure_one() + return ( + self.company_id.po_double_validation == 'one_step' + or (self.company_id.po_double_validation == 'two_step' + and self.amount_total < self.env.company.currency_id._convert( + self.company_id.po_double_validation_amount, self.currency_id, self.company_id, + self.date_order or fields.Date.today())) + or self.user_has_groups('purchase.group_purchase_manager')) + def _confirm_reception_mail(self): for order in self: if order.state in ['purchase', 'done'] and not order.mail_reception_confirmed: diff --git a/addons/purchase/tests/test_access_rights.py b/addons/purchase/tests/test_access_rights.py index ee79ec0f5e3eabbd93630b3a7474ddce5d00c1c3..855b0270b66d7649e5451110d79a4b0be19d91d1 100644 --- a/addons/purchase/tests/test_access_rights.py +++ b/addons/purchase/tests/test_access_rights.py @@ -137,3 +137,24 @@ class TestPurchaseInvoice(AccountTestInvoicingCommon): purchase_order_user2.invalidate_cache() action_user_2 = purchase_order_user2.with_user(purchase_user_2).action_view_invoice() self.assertEqual(action_user_1, action_user_2) + + def test_double_validation(self): + """Only purchase managers can approve a purchase order when double + validation is enabled""" + group_purchase_manager = self.env.ref('purchase.group_purchase_manager') + order = self.env.ref("purchase.purchase_order_1") + company = order.sudo().company_id + company.po_double_validation = 'two_step' + company.po_double_validation_amount = 0 + self.purchase_user.write({ + 'company_ids': [(4, company.id)], + 'company_id': company.id, + 'groups_id': [(3, group_purchase_manager.id)], + }) + order.with_user(self.purchase_user).button_confirm() + self.assertEqual(order.state, 'to approve') + order.with_user(self.purchase_user).button_approve() + self.assertEqual(order.state, 'to approve') + self.purchase_user.groups_id += group_purchase_manager + order.with_user(self.purchase_user).button_approve() + self.assertEqual(order.state, 'purchase') diff --git a/addons/purchase_stock/models/purchase.py b/addons/purchase_stock/models/purchase.py index 62dc6d5e72397775965880b4d372ba656c820642..46b6a1eee8dca96a88be63bfbaa66107ed220643 100644 --- a/addons/purchase_stock/models/purchase.py +++ b/addons/purchase_stock/models/purchase.py @@ -221,7 +221,7 @@ class PurchaseOrder(models.Model): def _create_picking(self): StockPicking = self.env['stock.picking'] - for order in self: + for order in self.filtered(lambda po: po.state in ('purchase', 'done')): if any(product.type in ['product', 'consu'] for product in order.order_line.product_id): order = order.with_company(order.company_id) pickings = order.picking_ids.filtered(lambda x: x.state not in ('done', 'cancel')) diff --git a/addons/purchase_stock/tests/test_create_picking.py b/addons/purchase_stock/tests/test_create_picking.py index a63443e15b7de4c5c0f29746e5cef45f7c15d9f2..9ab50671cbdf430586684d90d8f4b9b472c1a45c 100644 --- a/addons/purchase_stock/tests/test_create_picking.py +++ b/addons/purchase_stock/tests/test_create_picking.py @@ -90,6 +90,7 @@ class TestCreatePicking(common.TestProductCommon): self.assertEqual(self.po.state, 'to approve', 'Purchase: PO state should be "to approve".') # PO approved by manager + self.po.env.user.groups_id += self.env.ref("purchase.group_purchase_manager") self.po.button_approve() self.assertEqual(self.po.state, 'purchase', 'PO state should be "Purchase".')