[FIX] purchase_stock: set qty_received_method to manual on uninstall
After uninstalling the stock module on a database which also has the purchase (and purchase_stock) module installed, the qty_received_method is removed for purchase order lines handling the reception of the products through the stock module (qty_received_method = 'stock_moves'). Because of this, a recompute is triggered on the qty_received, setting it to zero. This leaves the purchase order in an invalid state (the received quantity did not change through the uninstallation of the stock module), additionally the problem cannot be corrected, since the receiving method is not set to manual. Functionally, the uninstallation shouldn't update the purchase orders, instead they should be decoupled from the associated stock moves. To this end, an ondelete handler is added for the stock_moves selection option. Steps to reproduce: - Install Purchases app - Install Inventory app - Create a purchase order with purchase lines and quantity > 0 - Confirm the purchase order - Click on receive products - Click on validate - Uninstall Inventory app - Check that the purchase order lines have the received field set to zero and it is not editable opw-3006951 closes odoo/odoo#121549 X-original-commit: cedd0603a24aa0c0e6716c2e0f49e89c870eae04 Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com> Signed-off-by: De Caluwé Tom (tdc) <tdc@odoo.com> Co-authored-by: Pedro Manuel Calheiros Lima de Sousa (peso) <peso@odoo.com>
This commit is contained in:
co-authored by
Pedro Manuel Calheiros Lima de Sousa
parent
085fd873d6
commit
5d084bcf88
@@ -293,7 +293,20 @@ class PurchaseOrder(models.Model):
|
||||
class PurchaseOrderLine(models.Model):
|
||||
_inherit = 'purchase.order.line'
|
||||
|
||||
qty_received_method = fields.Selection(selection_add=[('stock_moves', 'Stock Moves')])
|
||||
def _ondelete_stock_moves(self):
|
||||
modified_fields = ['qty_received_manual', 'qty_received_method']
|
||||
self.flush_recordset(fnames=['qty_received', *modified_fields])
|
||||
self.invalidate_recordset(fnames=modified_fields, flush=False)
|
||||
query = f'''
|
||||
UPDATE {self._table}
|
||||
SET qty_received_manual = qty_received, qty_received_method = 'manual'
|
||||
WHERE id IN %(ids)s
|
||||
'''
|
||||
self.env.cr.execute(query, {'ids': self._ids or (None,)})
|
||||
self.modified(modified_fields)
|
||||
|
||||
qty_received_method = fields.Selection(selection_add=[('stock_moves', 'Stock Moves')],
|
||||
ondelete={'stock_moves': _ondelete_stock_moves})
|
||||
|
||||
move_ids = fields.One2many('stock.move', 'purchase_line_id', string='Reservation', readonly=True, copy=False)
|
||||
orderpoint_id = fields.Many2one('stock.warehouse.orderpoint', 'Orderpoint', copy=False, index='btree_not_null')
|
||||
|
||||
@@ -19,3 +19,4 @@ from . import test_move_cancel_propagation
|
||||
from . import test_product_template
|
||||
from . import test_routes
|
||||
from . import test_purchase_stock_accrued_entries
|
||||
from . import test_uninstall
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from unittest.mock import patch
|
||||
|
||||
from odoo import fields
|
||||
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
|
||||
from odoo.addons.purchase_stock.models.purchase import PurchaseOrderLine
|
||||
from odoo.tests.common import tagged
|
||||
|
||||
from .common import PurchaseTestCommon
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestUninstallPurchaseStock(PurchaseTestCommon):
|
||||
def test_qty_received_method(self):
|
||||
partner = self.env['res.partner'].create({'name': 'Test Partner'})
|
||||
purchase_order = self.env['purchase.order'].create({
|
||||
'partner_id': partner.id,
|
||||
'state': 'purchase',
|
||||
'order_line': [fields.Command.create({
|
||||
'product_id': self.product_1.id,
|
||||
})],
|
||||
})
|
||||
order_line = purchase_order.order_line
|
||||
stock_move = order_line.move_ids
|
||||
|
||||
self.assertEqual(order_line.product_id.detailed_type, 'product')
|
||||
|
||||
stock_move.quantity_done = 1
|
||||
stock_move.picking_id.button_validate()
|
||||
|
||||
self.assertEqual(purchase_order.order_line.qty_received, 1)
|
||||
|
||||
stock_moves_option = self.env['ir.model.fields.selection'].search([
|
||||
('field_id.model', '=', 'purchase.order.line'),
|
||||
('field_id.name', '=', 'qty_received_method'),
|
||||
('value', '=', 'stock_moves'),
|
||||
])
|
||||
|
||||
original_compute = PurchaseOrderLine._compute_qty_received
|
||||
def _compute_qty_received(records):
|
||||
records.read()
|
||||
with self.assertQueryCount(0):
|
||||
original_compute(records)
|
||||
records.flush_recordset()
|
||||
|
||||
with patch.object(PurchaseOrderLine, '_compute_qty_received', _compute_qty_received):
|
||||
stock_moves_option.sudo().with_context(**{
|
||||
MODULE_UNINSTALL_FLAG: True
|
||||
}).unlink()
|
||||
|
||||
self.assertEqual(order_line.qty_received_method, 'manual')
|
||||
self.assertEqual(order_line.qty_received, 1)
|
||||
Reference in New Issue
Block a user