Files
test/stock_barcode/tests/test_barcode_client_action_inventory.py
qihao.gong@jikimo.com 3c89404543 质量模块和库存扫码
2023-07-24 11:42:15 +08:00

351 lines
17 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import tagged
from odoo.addons.stock_barcode.tests.test_barcode_client_action import TestBarcodeClientAction
@tagged('post_install', '-at_install')
class TestInventoryAdjustmentBarcodeClientAction(TestBarcodeClientAction):
def test_inventory_adjustment(self):
""" Simulate the following actions:
- Open the inventory from the barcode app.
- Scan twice the product 1.
- Edit the line.
- Add a product with the form view.
- Validate
"""
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_inventory_adjustment', login='admin', timeout=180)
inventory_moves = self.env['stock.move'].search([('product_id', 'in', [self.product1.id, self.product2.id]),
('is_inventory', '=', True)])
self.assertEqual(len(inventory_moves), 2)
self.assertEqual(inventory_moves.mapped('quantity_done'), [2.0, 2.0])
self.assertEqual(inventory_moves.mapped('state'), ['done', 'done'])
quants = self.env['stock.quant'].search([('product_id', 'in', [self.product1.id, self.product2.id]),
('location_id.usage', '=', 'internal')])
self.assertEqual(quants.mapped('quantity'), [2.0, 2.0])
self.assertEqual(quants.mapped('inventory_quantity'), [0, 0])
self.assertEqual(quants.mapped('inventory_diff_quantity'), [0, 0])
def test_inventory_adjustment_multi_location(self):
""" Simulate the following actions:
- Generate those lines with scan:
WH/stock product1 qty: 2
WH/stock product2 qty: 1
WH/stock/shelf1 product2 qty: 1
WH/stock/shelf2 product1 qty: 1
- Validate
"""
self.clean_access_rights()
grp_multi_loc = self.env.ref('stock.group_stock_multi_locations')
self.env.user.write({'groups_id': [(4, grp_multi_loc.id, 0)]})
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_inventory_adjustment_multi_location', login='admin', timeout=180)
inventory_moves = self.env['stock.move'].search([('product_id', 'in', [self.product1.id, self.product2.id]),
('is_inventory', '=', True)])
self.assertEqual(len(inventory_moves), 4)
self.assertEqual(inventory_moves.mapped('state'), ['done', 'done', 'done', 'done'])
inventory_move_in_WH_stock = inventory_moves.filtered(lambda l: l.location_dest_id == self.stock_location)
self.assertEqual(set(inventory_move_in_WH_stock.mapped('product_id')), set([self.product1, self.product2]))
self.assertEqual(inventory_move_in_WH_stock.filtered(lambda l: l.product_id == self.product1).quantity_done, 2.0)
self.assertEqual(inventory_move_in_WH_stock.filtered(lambda l: l.product_id == self.product2).quantity_done, 1.0)
inventory_move_in_shelf1 = inventory_moves.filtered(lambda l: l.location_dest_id == self.shelf1)
self.assertEqual(len(inventory_move_in_shelf1), 1)
self.assertEqual(inventory_move_in_shelf1.product_id, self.product2)
self.assertEqual(inventory_move_in_shelf1.quantity_done, 1.0)
inventory_move_in_shelf2 = inventory_moves.filtered(lambda l: l.location_dest_id == self.shelf2)
self.assertEqual(len(inventory_move_in_shelf2), 1)
self.assertEqual(inventory_move_in_shelf2.product_id, self.product1)
self.assertEqual(inventory_move_in_shelf2.quantity_done, 1.0)
def test_inventory_adjustment_tracked_product(self):
""" Simulate the following actions:
- Generate those lines with scan:
productlot1 with a lot named lot1 (qty 2)
productserial1 with serial1 (qty 1)
productserial1 with serial2 (qty 1)
productserial1 with serial3 (qty 1)
productlot1 with a lot named lot2 (qty 1)
productlot1 with a lot named lot3 (qty 1)
- Validate
"""
self.clean_access_rights()
grp_lot = self.env.ref('stock.group_production_lot')
self.env.user.write({'groups_id': [(4, grp_lot.id, 0)]})
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_inventory_adjustment_tracked_product', login='admin', timeout=180)
inventory_moves = self.env['stock.move'].search([('product_id', 'in', [self.productlot1.id, self.productserial1.id]),
('is_inventory', '=', True)])
self.assertEqual(len(inventory_moves), 6)
self.assertEqual(inventory_moves.mapped('state'), ['done', 'done', 'done', 'done', 'done', 'done'])
moves_with_lot = inventory_moves.filtered(lambda l: l.product_id == self.productlot1)
mls_with_lot = self.env['stock.move.line']
mls_with_sn = self.env['stock.move.line']
for move in moves_with_lot:
mls_with_lot |= move._get_move_lines()
moves_with_sn = inventory_moves.filtered(lambda l: l.product_id == self.productserial1)
for move in moves_with_sn:
mls_with_sn |= move._get_move_lines()
self.assertEqual(len(mls_with_lot), 3)
self.assertEqual(len(mls_with_sn), 3)
self.assertEqual(mls_with_lot.mapped('lot_id.name'), ['lot1', 'lot2', 'lot3'])
self.assertEqual(mls_with_lot.filtered(lambda ml: ml.lot_id.name == 'lot1').qty_done, 3)
self.assertEqual(mls_with_lot.filtered(lambda ml: ml.lot_id.name == 'lot2').qty_done, 1)
self.assertEqual(mls_with_lot.filtered(lambda ml: ml.lot_id.name == 'lot3').qty_done, 1)
self.assertEqual(set(mls_with_sn.mapped('lot_id.name')), set(['serial1', 'serial2', 'serial3']))
def test_inventory_nomenclature(self):
""" Simulate scanning a product and its weight
thanks to the barcode nomenclature """
self.clean_access_rights()
self.env.company.nomenclature_id = self.env.ref('barcodes.default_barcode_nomenclature')
product_weight = self.env['product.product'].create({
'name': 'product_weight',
'type': 'product',
'categ_id': self.env.ref('product.product_category_all').id,
'barcode': '2145631000000',
})
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_inventory_nomenclature', login='admin', timeout=180)
quantity = self.env['stock.move.line'].search([
('product_id', '=', product_weight.id),
('state', '=', 'done'),
('location_id', '=', product_weight.property_stock_inventory.id),
])
self.assertEqual(quantity.qty_done, 12.35)
def test_inventory_package(self):
""" Simulate an adjustment where a package is scanned and edited """
self.clean_access_rights()
grp_pack = self.env.ref('stock.group_tracking_lot')
self.env.user.write({'groups_id': [(4, grp_pack.id, 0)]})
pack = self.env['stock.quant.package'].create({
'name': 'PACK001',
})
self.env['stock.quant']._update_available_quantity(self.product1, self.stock_location, 7, package_id=pack)
self.env['stock.quant']._update_available_quantity(self.product2, self.stock_location, 3, package_id=pack)
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, "test_inventory_package", login="admin", timeout=180)
# Check the package is updated after adjustment
self.assertDictEqual(
{q.product_id: q.quantity for q in pack.quant_ids},
{self.product1: 7, self.product2: 21}
)
def test_inventory_owner_scan_package(self):
group_owner = self.env.ref('stock.group_tracking_owner')
group_pack = self.env.ref('stock.group_tracking_lot')
self.env.user.write({'groups_id': [(4, group_pack.id, 0)]})
self.env.user.write({'groups_id': [(4, group_owner.id, 0)]})
self.env['stock.quant']._update_available_quantity(self.product1, self.stock_location, 7, package_id=self.package, owner_id=self.owner)
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_inventory_owner_scan_package', login='admin', timeout=180)
inventory_moves = self.env['stock.move'].search([('product_id', '=', self.product1.id), ('is_inventory', '=', True)])
self.assertEqual(len(inventory_moves), 1)
self.assertEqual(inventory_moves.state, 'done')
self.assertEqual(inventory_moves._get_move_lines().owner_id.id, self.owner.id)
def test_inventory_using_buttons(self):
""" Creates an inventory from scratch, then scans products and verifies
the buttons behavior is right.
"""
# Adds some quantities for product2.
self.env['stock.quant']._update_available_quantity(self.product2, self.stock_location, 10)
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_inventory_using_buttons', login='admin', timeout=180)
product1_quant = self.env['stock.quant'].search([
('product_id', '=', self.product1.id),
('quantity', '>', 0)
])
self.assertEqual(len(product1_quant), 1)
self.assertEqual(product1_quant.quantity, 1.0)
self.assertEqual(product1_quant.location_id.id, self.stock_location.id)
productlot1_quant = self.env['stock.quant'].search([
('product_id', '=', self.productlot1.id),
('quantity', '>', 0)
])
self.assertEqual(len(product1_quant), 1)
self.assertEqual(productlot1_quant.quantity, 1.0)
self.assertEqual(productlot1_quant.lot_id.name, 'toto-42')
self.assertEqual(productlot1_quant.location_id.id, self.stock_location.id)
def test_gs1_inventory_gtin_8(self):
""" Simulate scanning a product with his gs1 barcode """
self.clean_access_rights()
self.env.company.nomenclature_id = self.env.ref('barcodes_gs1_nomenclature.default_gs1_nomenclature')
product = self.env['product.product'].create({
'name': 'PRO_GTIN_8',
'type': 'product',
'categ_id': self.env.ref('product.product_category_all').id,
'barcode': '82655853', # GTIN-8 format
'uom_id': self.env.ref('uom.product_uom_unit').id
})
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_gs1_inventory_gtin_8', login='admin', timeout=180)
# Checks the inventory adjustment correclty created a move line.
move_line = self.env['stock.move.line'].search([
('product_id', '=', product.id),
('state', '=', 'done'),
('location_id', '=', product.property_stock_inventory.id),
])
self.assertEqual(move_line.qty_done, 78)
def test_gs1_inventory_product_units(self):
""" Scans a product with a GS1 barcode containing multiple quantities."""
self.clean_access_rights()
self.env.company.nomenclature_id = self.env.ref('barcodes_gs1_nomenclature.default_gs1_nomenclature')
product = self.env['product.product'].create({
'name': 'PRO_GTIN_8',
'type': 'product',
'categ_id': self.env.ref('product.product_category_all').id,
'barcode': '82655853', # GTIN-8 format
'uom_id': self.env.ref('uom.product_uom_unit').id
})
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_gs1_inventory_product_units', login='admin', timeout=180)
quantity = self.env['stock.move.line'].search([
('product_id', '=', product.id),
('state', '=', 'done'),
('location_id', '=', product.property_stock_inventory.id),
])
self.assertEqual(quantity.qty_done, 102)
def test_gs1_inventory_package(self):
""" Scans existing packages and checks their products are correclty added
to the inventory adjustment. Then scans some products, scans a new package
and checks the package was created and correclty assigned to those products.
"""
self.clean_access_rights()
self.env.company.nomenclature_id = self.env.ref('barcodes_gs1_nomenclature.default_gs1_nomenclature')
grp_multi_loc = self.env.ref('stock.group_stock_multi_locations')
grp_pack = self.env.ref('stock.group_tracking_lot')
self.env.user.write({'groups_id': [(4, grp_multi_loc.id, 0)]})
self.env.user.write({'groups_id': [(4, grp_pack.id, 0)]})
product = self.env['product.product'].create({
'name': 'PRO_GTIN_8',
'type': 'product',
'categ_id': self.env.ref('product.product_category_all').id,
'barcode': '82655853', # GTIN-8 format
'uom_id': self.env.ref('uom.product_uom_unit').id
})
# Creates a first package in Section 1 and adds some products.
pack_1 = self.env['stock.quant.package'].create({'name': '987654123487568456'})
self.env['stock.quant']._update_available_quantity(self.product1, self.shelf1, 8, package_id=pack_1)
# Creates a second package in Section 2 and adds some other products.
pack_2 = self.env['stock.quant.package'].create({'name': '487325612456785124'})
self.env['stock.quant']._update_available_quantity(self.product2, self.shelf2, 6, package_id=pack_2)
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_gs1_inventory_package', login='admin', timeout=180)
pack_3 = self.env['stock.quant.package'].search([('name', '=', '122333444455555670')])
self.assertEqual(pack_3.location_id.id, self.shelf2.id)
self.assertEqual(pack_3.quant_ids.product_id.ids, [product.id])
def test_gs1_inventory_lot_serial(self):
""" Checks tracking numbers and quantites are correctly got from GS1
barcodes for tracked products."""
self.clean_access_rights()
self.env.company.nomenclature_id = self.env.ref('barcodes_gs1_nomenclature.default_gs1_nomenclature')
product_lot = self.env['product.product'].create({
'name': 'PRO_GTIN_12_lot',
'type': 'product',
'categ_id': self.env.ref('product.product_category_all').id,
'barcode': '111155555717', # GTIN-12 format
'uom_id': self.env.ref('uom.product_uom_unit').id,
'tracking': 'lot',
})
product_serial = self.env['product.product'].create({
'name': 'PRO_GTIN_14_serial',
'type': 'product',
'categ_id': self.env.ref('product.product_category_all').id,
'barcode': '15222222222219', # GTIN-14 format
'uom_id': self.env.ref('uom.product_uom_unit').id,
'tracking': 'serial',
})
action_id = self.env.ref('stock_barcode.stock_barcode_action_main_menu')
url = "/web#action=" + str(action_id.id)
self.start_tour(url, 'test_gs1_inventory_lot_serial', login='admin', timeout=180)
smls_lot = self.env['stock.move.line'].search([
('product_id', '=', product_lot.id),
('state', '=', 'done'),
('location_id', '=', product_lot.property_stock_inventory.id),
])
self.assertEqual(len(smls_lot), 3)
self.assertEqual(smls_lot[0].qty_done, 10)
self.assertEqual(smls_lot[1].qty_done, 15)
self.assertEqual(smls_lot[2].qty_done, 20)
self.assertEqual(
smls_lot.lot_id.mapped('name'),
['LOT-AAA', 'LOT-AAB', 'LOT-AAC']
)
smls_serial = self.env['stock.move.line'].search([
('product_id', '=', product_serial.id),
('state', '=', 'done'),
('location_id', '=', product_serial.property_stock_inventory.id),
])
self.assertEqual(len(smls_serial), 5)
self.assertEqual(smls_serial[0].qty_done, 1)
self.assertEqual(smls_serial[1].qty_done, 1)
self.assertEqual(smls_serial[2].qty_done, 1)
self.assertEqual(smls_serial[3].qty_done, 20)
self.assertEqual(smls_serial[4].qty_done, 1)
self.assertEqual(
smls_serial.lot_id.mapped('name'),
['Serial1', 'Serial2', 'Serial3', 'Serial4']
)