summaryrefslogtreecommitdiff
path: root/addons/purchase
diff options
context:
space:
mode:
authorStefan Rijnhart <stefan@opener.am>2021-02-22 10:11:15 +0000
committerStefan Rijnhart <stefan@opener.am>2021-02-22 10:11:15 +0000
commit99f891f0d1614b7a783fd55c0a9fdcb1ae6251da (patch)
tree0c2b9d953c786da958f2a74a8fef9ea6026a357e /addons/purchase
parent29be97615554337591f0b31ba34942c2d728cbef (diff)
[FIX] Purchase double validation can be circumvented by RPC call
closes odoo/odoo#66505 Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
Diffstat (limited to 'addons/purchase')
-rw-r--r--addons/purchase/models/purchase.py18
-rw-r--r--addons/purchase/tests/test_access_rights.py21
2 files changed, 34 insertions, 5 deletions
diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py
index dadf32bedea..3132e85958e 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 ee79ec0f5e3..855b0270b66 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')