[IMP] stock: add revert inventory adjustment feature

Purpose of the task is to be able to click on inventory adjustment
history and do a reverse adjustment by using `Revert Inventory` action.

`Revert Inventory` action is available in Inventory Adjustments > History
and Product Moves > select some lines > actions dropdown. This
method creates a new move that reverts the quantity (including negative
values) with prefix `[reverted]`.

TaskID - 2859490

closes odoo/odoo#95720

Signed-off-by: Tiffany Chang <tic@odoo.com>
This commit is contained in:
debu-odoo
2022-09-21 01:29:49 +02:00
committed by Tiffany Chang (tic)
parent ffb94e9be8
commit f02b21771c
3 changed files with 97 additions and 0 deletions
+53
View File
@@ -860,3 +860,56 @@ class StockMoveLine(models.Model):
'views': [[False, "form"]],
'res_id': self.id,
}
def _get_revert_inventory_move_values(self):
self.ensure_one()
return {
'name':_('%s [reverted]', self.reference),
'product_id': self.product_id.id,
'product_uom': self.product_uom_id.id,
'product_uom_qty': self.qty_done,
'company_id': self.company_id.id or self.env.company.id,
'state': 'confirmed',
'location_id': self.location_dest_id.id,
'location_dest_id': self.location_id.id,
'is_inventory': True,
'move_line_ids': [(0, 0, {
'product_id': self.product_id.id,
'product_uom_id': self.product_uom_id.id,
'qty_done': self.qty_done,
'location_id': self.location_dest_id.id,
'location_dest_id': self.location_id.id,
'company_id': self.company_id.id or self.env.company.id,
'lot_id': self.lot_id.id,
'package_id': self.package_id.id,
'result_package_id': self.package_id.id,
'owner_id': self.owner_id.id,
})]
}
def action_revert_inventory(self):
move_vals = []
processed_move_line = self.env['stock.move.line']
for move_line in self:
if move_line.is_inventory and not float_is_zero(move_line.qty_done, precision_digits=move_line.product_uom_id.rounding):
processed_move_line += move_line
move_vals.append(move_line._get_revert_inventory_move_values())
if not processed_move_line:
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'type': 'danger',
'message': _("There are no inventory adjustments to revert."),
}
}
moves = self.env['stock.move'].create(move_vals)
moves._action_done()
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'type': 'success',
'message': _("The inventory adjustments have been reverted."),
}
}
@@ -294,3 +294,37 @@ class TestEditableQuant(TransactionCase):
warning = dupe_sn._onchange_serial_number()
self.assertTrue(warning, 'Reuse of existing serial number not detected')
self.assertEqual(list(warning.keys())[0], 'warning', 'Warning message was not returned')
def test_revert_inventory_adjustment(self):
"""Try to revert inventory adjustment"""
default_wh = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
default_stock_location = default_wh.lot_stock_id
quant = self.Quant.create({
'product_id': self.product.id,
'location_id': default_stock_location.id,
'inventory_quantity': 100,
})
quant.action_apply_inventory()
move_lines = self.env['stock.move.line'].search([('product_id', '=', self.product.id), ('is_inventory', '=', True)])
self.assertEqual(len(move_lines), 1, "One inventory adjustment move lines should have been created")
self.assertEqual(self.product.qty_available, 100, "Before revert inventory adjustment qty is 100")
move_lines.action_revert_inventory()
self.assertEqual(self.product.qty_available, 0, "After revert inventory adjustment qty is not zero")
def test_multi_revert_inventory_adjustment(self):
"""Try to revert inventory adjustment with multiple lines"""
default_wh = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
default_stock_location = default_wh.lot_stock_id
quant = self.Quant.create({
'product_id': self.product.id,
'location_id': default_stock_location.id,
'inventory_quantity': 100,
})
quant.action_apply_inventory()
quant.inventory_quantity = 150
quant.action_apply_inventory()
move_lines = self.env['stock.move.line'].search([('product_id', '=', self.product.id), ('is_inventory', '=', True)])
self.assertEqual(self.product.qty_available, 150, "Before revert multi inventory adjustment qty is 150")
self.assertEqual(len(move_lines), 2, "Two inventory adjustment move lines should have been created")
move_lines.action_revert_inventory()
self.assertEqual(self.product.qty_available, 0, "After revert multi inventory adjustment qty is not zero")
@@ -192,6 +192,16 @@
</field>
</record>
<record id="action_revert_inventory_adjustment" model="ir.actions.server">
<field name="name">Revert Inventory Adjustment</field>
<field name="model_id" ref="stock.model_stock_move_line"/>
<field name="binding_model_id" ref="stock.model_stock_move_line"/>
<field name="state">code</field>
<field name="code">
action = records.action_revert_inventory()
</field>
</record>
<record id="stock_move_line_action" model="ir.actions.act_window">
<field name="name">Moves History</field>
<field name="res_model">stock.move.line</field>