Skip to content

Commit

Permalink
[FIX] purchase: ensure all vendor bills are gathered from purchase order
Browse files Browse the repository at this point in the history
The 'vendor bills' stat button on purchase order, once clicked, will
have a specific behavior depending on the invoice count :
    0 : open a new invoice with pre filled fields (not saved yet)
    1 : open the form view of the invoice
    2+: open the list view of the invoices.

Before this commit, the invoice count was computed with an environment on
the current user. That means a record rule could make the invoice count
lower than the real count and so give an unwanted behavior. Ex: create a
new invoice even if there is already one created because the user cannot
see the other people's invoices.

After this commit, the action_view_invoice with make an explicit read()
in database to fill the cache with all the purchase order's invoices and
make sure the count is the real one.

Task : 2206969

closes odoo#48240

Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
  • Loading branch information
Whenrow committed Mar 24, 2020
1 parent 28ae3fb commit e3101d9
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
4 changes: 4 additions & 0 deletions addons/purchase/models/purchase.py
Expand Up @@ -416,6 +416,10 @@ def action_view_invoice(self):
'default_company_id': self.company_id.id,
'default_purchase_id': self.id,
}
# Invoice_ids may be filtered depending on the user. To ensure we get all
# invoices related to the purchase order, we read them in sudo to fill the
# cache.
self.sudo()._read(['invoice_ids'])
# choose the view_mode accordingly
if len(self.invoice_ids) > 1 and not create_bill:
result['domain'] = "[('id', 'in', " + str(self.invoice_ids.ids) + ")]"
Expand Down
39 changes: 39 additions & 0 deletions addons/purchase/tests/test_access_rights.py
Expand Up @@ -95,3 +95,42 @@ def test_read_purchase_order(self):
purchase_order_user1 = purchase_order_user1.save()
vendor_bill_user1 = Form(vendor_bill_user2.with_user(self.purchase_user))
vendor_bill_user1 = vendor_bill_user1.save()

def test_read_purchase_order_2(self):
""" Check that a 2 purchase users with open the vendor bill the same
way even with a 'own documents only' record rule. """

# edit the account.move record rule for purchase user in order to ensure
# a user can only see his own invoices
rule = self.env.ref('purchase.purchase_user_account_move_rule')
rule.domain_force = "['&', ('type', 'in', ('in_invoice', 'in_refund', 'in_receipt')), ('invoice_user_id', '=', user.id)]"

# create a purchase and make a vendor bill from it as purchase user 2
purchase_user_2 = self.purchase_user.copy({
'name': 'Purchase user 2',
'login': 'purchaseUser2',
'email': 'pu2@odoo.com',
})

purchase_order_form = Form(self.env['purchase.order'].with_user(purchase_user_2))
purchase_order_form.partner_id = self.vendor
with purchase_order_form.order_line.new() as line:
line.name = self.product.name
line.product_id = self.product
line.product_qty = 4
line.price_unit = 5

purchase_order_user2 = purchase_order_form.save()
action = purchase_order_user2.with_user(purchase_user_2).action_view_invoice()
invoice_form = Form(self.env['account.move'].with_user(purchase_user_2).with_context(action['context']))
vendor_bill_user2 = invoice_form.save()

# check user 1 cannot read the invoice
with self.assertRaises(AccessError):
Form(vendor_bill_user2.with_user(self.purchase_user))

# Check that calling 'action_view_invoice' return the same action despite the record rule
action_user_1 = purchase_order_user2.with_user(self.purchase_user).action_view_invoice()
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)

0 comments on commit e3101d9

Please sign in to comment.