[FIX] purchase_stock: fix unexpected access right issue

Prerequisites -->

1) Login with a user with just Inventory/User access rights
2) Product A with purchase policy set to `on ordered quantities`
3) Product category of A set to `AVCO` costing method

Steps -->

1) Create+confirm a PO with product A and create and confirm vendor bill
2) Switch to Inventory/User user
3) Try to validate picking
4) Access right error

This occurs due to the fact that `Inventory/User` does not have access to s`tock.valuation.layer` or `account.move.line`.

Solution -->

Add sudo to the lines where accesses to SVL and invoice lines are made.

opw-3357028

closes odoo/odoo#130929

X-original-commit: 8d2a77d1bdbe8f865d8f7177801786617e10058f
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
This commit is contained in:
adda-odoo
2023-08-09 17:04:41 +02:00
committed by Touati Djamel (otd)
parent ccc6b4827f
commit ef3c21255c
3 changed files with 48 additions and 3 deletions
+3 -3
View File
@@ -48,8 +48,8 @@ class StockMove(models.Model):
if self.state == 'done':
received_qty -= self.product_uom._compute_quantity(self.quantity_done, line.product_uom, rounding_method='HALF-UP')
if float_compare(line.qty_invoiced, received_qty, precision_rounding=line.product_uom.rounding) > 0:
move_layer = line.move_ids.stock_valuation_layer_ids
invoiced_layer = line.invoice_lines.stock_valuation_layer_ids
move_layer = line.move_ids.sudo().stock_valuation_layer_ids
invoiced_layer = line.sudo().invoice_lines.stock_valuation_layer_ids
# value on valuation layer is in company's currency, while value on invoice line is in order's currency
receipt_value = 0
if move_layer:
@@ -60,7 +60,7 @@ class StockMove(models.Model):
l.value, order.currency_id, order.company_id, l.create_date, round=False)))
invoiced_value = 0
invoiced_qty = 0
for invoice_line in line.invoice_lines:
for invoice_line in line.sudo().invoice_lines:
if invoice_line.tax_ids:
invoiced_value += invoice_line.tax_ids.with_context(round=False).compute_all(
invoice_line.price_unit, currency=invoice_line.currency_id, quantity=invoice_line.quantity)['total_void']
@@ -131,3 +131,41 @@ class TestAveragePrice(ValuationReconciliationTestCommon):
self.assertEqual(product_cable_management_box.qty_available, 20.5, 'Reception of purchase order in grams leads to wrong quantity in stock')
self.assertEqual(round(product_cable_management_box.standard_price, 2), 78.05,
'Standard price as average price of third reception with other UoM incorrect! Got %s instead of 78.05' % (round(product_cable_management_box.standard_price, 2)))
def test_inventory_user_svl_access(self):
""" Test to check if Inventory/User is able to validate a
transfer when the product has been invoiced already """
avco_product = self.env['product.product'].create({
'name': 'Average Ice Cream',
'type': 'product',
'categ_id': self.stock_account_product_categ.id,
'purchase_method': 'purchase',
})
avco_product.categ_id.property_cost_method = 'average'
purchase_order = self.env['purchase.order'].create({
'partner_id': self.partner_a.id,
'order_line': [(0, 0, {
'product_id': avco_product.id,
'product_qty': 1.0,
})]
})
purchase_order.button_confirm()
purchase_order.action_create_invoice()
bill = purchase_order.invoice_ids[0]
bill.invoice_date = time.strftime('%Y-%m-%d')
bill.invoice_line_ids[0].quantity = 1.0
bill.action_post()
self.assertEqual(purchase_order.order_line[0].qty_invoiced, 1.0, 'QTY invoiced should have been set to 1 on the purchase order line')
picking = purchase_order.picking_ids[0]
picking.action_set_quantities_to_reservation()
# clear cash to ensure access rights verification
self.env.invalidate_all()
picking.with_user(self.res_users_stock_user).button_validate()
self.assertEqual(picking.state, 'done', 'Transfer should be in the DONE state')
@@ -48,6 +48,13 @@ class ValuationReconciliationTestCommon(AccountTestInvoicingCommon):
'uom_po_id': uom_unit.id,
})
cls.res_users_stock_user = cls.env['res.users'].create({
'name': "Inventory User",
'login': "su",
'email': "stockuser@yourcompany.com",
'groups_id': [(6, 0, [cls.env.ref('stock.group_stock_user').id])],
})
@classmethod
def setup_company_data(cls, company_name, chart_template=None, **kwargs):
company_data = super().setup_company_data(company_name, chart_template=chart_template, **kwargs)