[FIX] Purchase double validation can be circumvented by RPC call
closes odoo/odoo#66606 X-original-commit: 99f891f0d1614b7a783fd55c0a9fdcb1ae6251da Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
This commit is contained in:
@@ -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'})
|
||||
@@ -753,6 +750,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:
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -214,7 +214,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'))
|
||||
|
||||
@@ -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".')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user