mirror of
https://github.com/bringout/oca-warehouse.git
synced 2026-04-24 14:02:06 +02:00
Initial commit: OCA Warehouse packages (12 packages)
This commit is contained in:
commit
af1eea7692
627 changed files with 55555 additions and 0 deletions
|
|
@ -0,0 +1,4 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from . import test_stock_barcodes
|
||||
from . import test_stock_barcodes_new_lot
|
||||
from . import test_stock_barcodes_picking
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
# Copyright 2108-2019 Francois Poizat <francois.poizat@gmail.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestCommonStockBarcodes(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
# Active group_stock_packaging and group_production_lot for user
|
||||
group_stock_packaging = cls.env.ref("product.group_stock_packaging")
|
||||
group_production_lot = cls.env.ref("stock.group_production_lot")
|
||||
cls.env.user.groups_id = [
|
||||
(4, group_stock_packaging.id),
|
||||
(4, group_production_lot.id),
|
||||
]
|
||||
# models
|
||||
cls.StockLocation = cls.env["stock.location"]
|
||||
cls.Product = cls.env["product.product"]
|
||||
cls.ProductPackaging = cls.env["product.packaging"]
|
||||
cls.WizScanReadPicking = cls.env["wiz.stock.barcodes.read.picking"]
|
||||
cls.WizScanReadInventory = cls.env["wiz.stock.barcodes.read.inventory"]
|
||||
cls.WizCandidatePicking = cls.env["wiz.candidate.picking"]
|
||||
cls.StockProductionLot = cls.env["stock.lot"]
|
||||
cls.StockPicking = cls.env["stock.picking"]
|
||||
cls.StockQuant = cls.env["stock.quant"]
|
||||
cls.StockBarcodeAction = cls.env["stock.barcodes.action"]
|
||||
|
||||
cls.company = cls.env.company
|
||||
|
||||
# Option groups for test
|
||||
cls.option_group = cls._create_barcode_option_group()
|
||||
|
||||
# warehouse and locations
|
||||
cls.warehouse = cls.env.ref("stock.warehouse0")
|
||||
cls.stock_location = cls.env.ref("stock.stock_location_stock")
|
||||
cls.location_1 = cls.StockLocation.create(
|
||||
{
|
||||
"name": "Test location 1",
|
||||
"usage": "internal",
|
||||
"location_id": cls.stock_location.id,
|
||||
"barcode": "8411322222568",
|
||||
}
|
||||
)
|
||||
cls.location_2 = cls.StockLocation.create(
|
||||
{
|
||||
"name": "Test location 2",
|
||||
"usage": "internal",
|
||||
"location_id": cls.stock_location.id,
|
||||
"barcode": "8470001809032",
|
||||
}
|
||||
)
|
||||
|
||||
# products
|
||||
cls.product_wo_tracking = cls.Product.create(
|
||||
{
|
||||
"name": "Product test wo lot tracking",
|
||||
"type": "product",
|
||||
"tracking": "none",
|
||||
"barcode": "8480000723208",
|
||||
"packaging_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": "Box 10 Units",
|
||||
"qty": 10.0,
|
||||
"barcode": "5099206074439",
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
cls.product_tracking = cls.Product.create(
|
||||
{
|
||||
"name": "Product test with lot tracking",
|
||||
"type": "product",
|
||||
"tracking": "lot",
|
||||
"barcode": "8433281006850",
|
||||
"packaging_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{"name": "Box 5 Units", "qty": 5.0, "barcode": "5420008510489"},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
cls.lot_1 = cls.StockProductionLot.create(
|
||||
{
|
||||
"name": "8411822222568",
|
||||
"product_id": cls.product_tracking.id,
|
||||
"company_id": cls.company.id,
|
||||
}
|
||||
)
|
||||
cls.quant_lot_1 = cls.StockQuant.create(
|
||||
{
|
||||
"product_id": cls.product_tracking.id,
|
||||
"lot_id": cls.lot_1.id,
|
||||
"location_id": cls.stock_location.id,
|
||||
"quantity": 100.0,
|
||||
}
|
||||
)
|
||||
cls.wiz_scan = cls.WizScanReadPicking.create(
|
||||
{"option_group_id": cls.option_group.id, "step": 1}
|
||||
)
|
||||
cls.wiz_scan_read_inventory = cls.WizScanReadInventory.create(
|
||||
{"option_group_id": cls.option_group.id, "step": 1}
|
||||
)
|
||||
|
||||
cls.wiz_scan_candidate_picking = cls.WizCandidatePicking.create(
|
||||
{"wiz_barcode_id": cls.wiz_scan.id}
|
||||
)
|
||||
|
||||
# Barcode actions
|
||||
cls.barcode_action_valid = cls.StockBarcodeAction.create(
|
||||
{
|
||||
"name": "Barcode action valid",
|
||||
"action_window_id": cls.env.ref("stock.stock_picking_type_action").id,
|
||||
"context": "{'search_default_barcode_options': 1}",
|
||||
}
|
||||
)
|
||||
|
||||
cls.barcode_action_invalid = cls.StockBarcodeAction.create(
|
||||
{
|
||||
"name": "Barcode action valid",
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _create_barcode_option_group(cls):
|
||||
return cls.env["stock.barcodes.option.group"].create(
|
||||
{
|
||||
"name": "option group for tests",
|
||||
"create_lot": True,
|
||||
"option_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 1,
|
||||
"name": "Location",
|
||||
"field_name": "location_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Product",
|
||||
"field_name": "product_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Packaging",
|
||||
"field_name": "packaging_id",
|
||||
"to_scan": True,
|
||||
"required": False,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Lot / Serial",
|
||||
"field_name": "lot_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
def action_barcode_scanned(self, wizard, barcode):
|
||||
wizard._barcode_scanned = barcode
|
||||
wizard._on_barcode_scanned()
|
||||
# Method to call all methods outside of onchange environment for pickings read
|
||||
if wizard._name != "wiz.stock.barcodes.new.lot":
|
||||
wizard.dummy_on_barcode_scanned()
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
# Copyright 2108-2019 Sergio Teruel <sergio.teruel@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import re
|
||||
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import tagged
|
||||
|
||||
from odoo.addons.stock_barcodes.models.stock_barcodes_action import FIELDS_NAME, REGEX
|
||||
|
||||
from .common import TestCommonStockBarcodes
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestStockBarcodes(TestCommonStockBarcodes):
|
||||
def test_wizard_scan_location(self):
|
||||
self.action_barcode_scanned(self.wiz_scan, "8411322222568")
|
||||
self.assertEqual(self.wiz_scan.location_id, self.location_1)
|
||||
|
||||
def test_wizard_scan_product(self):
|
||||
self.wiz_scan.location_id = self.location_1
|
||||
self.wiz_scan.action_show_step()
|
||||
self.action_barcode_scanned(self.wiz_scan, "8480000723208")
|
||||
self.assertEqual(self.wiz_scan.product_id, self.product_wo_tracking)
|
||||
self.assertEqual(self.wiz_scan.product_qty, 1.0)
|
||||
|
||||
def test_wizard_scan_product_manual_entry(self):
|
||||
# Test manual entry
|
||||
self.wiz_scan.manual_entry = True
|
||||
self.wiz_scan.location_id = self.location_1
|
||||
self.wiz_scan.action_show_step()
|
||||
self.action_barcode_scanned(self.wiz_scan, "8480000723208")
|
||||
self.assertEqual(self.wiz_scan.product_qty, 0.0)
|
||||
self.wiz_scan.product_qty = 50.0
|
||||
|
||||
def test_wizard_scan_package(self):
|
||||
self.wiz_scan.location_id = self.location_1
|
||||
self.wiz_scan.action_show_step()
|
||||
self.action_barcode_scanned(self.wiz_scan, "5420008510489")
|
||||
self.assertEqual(self.wiz_scan.product_id, self.product_tracking)
|
||||
self.assertEqual(self.wiz_scan.product_qty, 5.0)
|
||||
self.assertEqual(
|
||||
self.wiz_scan.packaging_id, self.product_tracking.packaging_ids
|
||||
)
|
||||
|
||||
# Manual entry
|
||||
self.wiz_scan.manual_entry = True
|
||||
self.wiz_scan.action_clean_values()
|
||||
self.action_barcode_scanned(self.wiz_scan, "5420008510489")
|
||||
self.assertEqual(self.wiz_scan.packaging_qty, 1.0)
|
||||
self.wiz_scan.packaging_qty = 3.0
|
||||
self.wiz_scan.onchange_packaging_qty()
|
||||
self.assertEqual(self.wiz_scan.product_qty, 15.0)
|
||||
self.wiz_scan.manual_entry = False
|
||||
|
||||
def test_wizard_scan_lot(self):
|
||||
self.wiz_scan.location_id = self.location_1.id
|
||||
self.wiz_scan.action_show_step()
|
||||
self.action_barcode_scanned(self.wiz_scan, "8411822222568")
|
||||
# Lot found for one product, so product_id is filled
|
||||
self.assertTrue(self.wiz_scan.product_id)
|
||||
self.action_barcode_scanned(self.wiz_scan, "8433281006850")
|
||||
self.action_barcode_scanned(self.wiz_scan, "8411822222568")
|
||||
self.assertEqual(self.wiz_scan.lot_id, self.lot_1)
|
||||
# After scan other product, set wizard lot to False
|
||||
self.action_barcode_scanned(self.wiz_scan, "8480000723208")
|
||||
self.assertFalse(self.wiz_scan.lot_id)
|
||||
|
||||
def test_wizard_scan_not_found(self):
|
||||
self.action_barcode_scanned(self.wiz_scan, "84118xxx22568")
|
||||
self.assertEqual(
|
||||
self.wiz_scan.message,
|
||||
"84118xxx22568 (Barcode not found with this screen values)",
|
||||
)
|
||||
|
||||
def test_wiz_clean_lot(self):
|
||||
self.wiz_scan.location_id = self.location_1.id
|
||||
self.wiz_scan.action_show_step()
|
||||
self.action_barcode_scanned(self.wiz_scan, "8433281006850")
|
||||
self.action_barcode_scanned(self.wiz_scan, "8411822222568")
|
||||
self.wiz_scan.action_clean_lot()
|
||||
self.assertFalse(self.wiz_scan.lot_id)
|
||||
|
||||
def test_barcode_action(self):
|
||||
self.assertTrue(self.barcode_action_valid.action_window_id)
|
||||
self.assertEqual(bool(self.barcode_action_invalid.action_window_id), False)
|
||||
|
||||
def test_action_back(self):
|
||||
result = self.wiz_scan.action_back()
|
||||
self.assertIn("name", result)
|
||||
self.assertIn("type", result)
|
||||
self.assertIn("res_model", result)
|
||||
self.assertEqual(result["type"], "ir.actions.act_window")
|
||||
|
||||
def test_barcode_context_action(self):
|
||||
context = self.barcode_action_valid.context
|
||||
self.assertTrue(bool(re.match(REGEX.get("context", ""), context)))
|
||||
self.assertGreater(len(context), 0)
|
||||
context = context.strip("{}").split(",")
|
||||
field_values = context[0].split(":")
|
||||
self.assertGreater(len(field_values), 1)
|
||||
field_name = field_values[0].split("search_default_")
|
||||
self.assertGreater(len(field_name), 1)
|
||||
field_value_format = field_values[1].replace("'", "").strip()
|
||||
self.assertTrue(field_value_format.isdigit())
|
||||
self.assertEqual(field_values[0].strip("'"), "search_default_barcode_options")
|
||||
self.assertTrue(len(field_values[0].split("search_default_")), 2)
|
||||
self.assertEqual(self.barcode_action_invalid._count_elements(), 0)
|
||||
self.barcode_action_invalid.context = False
|
||||
with self.assertRaises(TypeError):
|
||||
self.barcode_action_invalid._compute_count_elements()
|
||||
self.barcode_action_invalid.context = "{}"
|
||||
self.assertFalse("search_default_" in self.barcode_action_invalid.context)
|
||||
|
||||
self.assertEqual(self.barcode_action_invalid._count_elements(), 0)
|
||||
self.barcode_action_valid.context = "{'search_default_code': 1}"
|
||||
self.assertEqual(self.barcode_action_valid._count_elements(), 6)
|
||||
field_value_name = (
|
||||
self.barcode_action_valid.context.strip("{}").split(",")[0].split(":")
|
||||
)
|
||||
field_name = field_value_name[0].split("search_default_")[1].strip("'")
|
||||
self.assertTrue("search_default_" in self.barcode_action_valid.context)
|
||||
self.assertFalse(
|
||||
hasattr(
|
||||
self.barcode_action_valid.action_window_id.res_model,
|
||||
FIELDS_NAME.get(field_name, field_name),
|
||||
)
|
||||
)
|
||||
field_values = field_value_name[1].strip()
|
||||
self.assertTrue(field_values.isdigit())
|
||||
|
||||
with self.assertRaises(IndexError):
|
||||
self.barcode_action_invalid.context = "{'search_default_'}"
|
||||
self.assertEqual(self.barcode_action_invalid._count_elements(), 0)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.StockBarcodeAction.create(
|
||||
{
|
||||
"name": "Barcode action invalid with space",
|
||||
"context": "{'search_default_code': 'incoming'} ",
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Copyright 2108-2019 Sergio Teruel <sergio.teruel@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo.tests.common import tagged
|
||||
|
||||
from .common import TestCommonStockBarcodes
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestStockBarcodesNewLot(TestCommonStockBarcodes):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.ScanReadLot = cls.env["wiz.stock.barcodes.new.lot"]
|
||||
cls.wiz_scan_lot = cls.ScanReadLot.new()
|
||||
|
||||
def test_new_lot(self):
|
||||
self.action_barcode_scanned(self.wiz_scan_lot, "8433281006850")
|
||||
self.assertEqual(self.wiz_scan_lot.product_id, self.product_tracking)
|
||||
self.action_barcode_scanned(self.wiz_scan_lot, "8433281xy6850")
|
||||
self.assertEqual(self.wiz_scan_lot.lot_name, "8433281xy6850")
|
||||
self.wiz_scan_lot.with_context(
|
||||
active_model=self.wiz_scan._name,
|
||||
active_id=self.wiz_scan.id,
|
||||
).confirm()
|
||||
self.assertEqual(self.wiz_scan_lot.lot_name, self.wiz_scan.lot_id.name)
|
||||
|
|
@ -0,0 +1,539 @@
|
|||
# Copyright 2108-2019 Sergio Teruel <sergio.teruel@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo.exceptions import MissingError, UserError
|
||||
from odoo.tests.common import tagged
|
||||
|
||||
from .common import TestCommonStockBarcodes
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestStockBarcodesPicking(TestCommonStockBarcodes):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.ScanReadPicking = cls.env["wiz.stock.barcodes.read.picking"]
|
||||
cls.stock_picking_model = cls.env.ref("stock.model_stock_picking")
|
||||
|
||||
# Model Data
|
||||
cls.barcode_option_group_out = cls._create_barcode_option_group_outgoing()
|
||||
cls.barcode_option_group_in = cls._create_barcode_option_group_incoming()
|
||||
|
||||
cls.barcode_option_group_out.barcode_guided_mode = False
|
||||
cls.barcode_option_group_in.barcode_guided_mode = False
|
||||
cls.partner_agrolite = cls.env.ref("base.res_partner_2")
|
||||
cls.picking_type_in = cls.env.ref("stock.picking_type_in")
|
||||
cls.picking_type_in.barcode_option_group_id = cls.barcode_option_group_in
|
||||
cls.picking_type_out = cls.env.ref("stock.picking_type_out")
|
||||
cls.picking_type_out.reservation_method = "manual"
|
||||
cls.picking_type_out.barcode_option_group_id = cls.barcode_option_group_out
|
||||
cls.supplier_location = cls.env.ref("stock.stock_location_suppliers")
|
||||
cls.customer_location = cls.env.ref("stock.stock_location_customers")
|
||||
cls.stock_location = cls.env.ref("stock.stock_location_stock")
|
||||
cls.categ_unit = cls.env.ref("uom.product_uom_categ_unit")
|
||||
cls.categ_kgm = cls.env.ref("uom.product_uom_categ_kgm")
|
||||
cls.picking_out_01 = (
|
||||
cls.env["stock.picking"]
|
||||
.with_context(planned_picking=True)
|
||||
.create(
|
||||
{
|
||||
"location_id": cls.stock_location.id,
|
||||
"location_dest_id": cls.customer_location.id,
|
||||
"partner_id": cls.partner_agrolite.id,
|
||||
"picking_type_id": cls.picking_type_out.id,
|
||||
"move_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": cls.product_tracking.name,
|
||||
"product_id": cls.product_tracking.id,
|
||||
"product_uom_qty": 3,
|
||||
"product_uom": cls.product_tracking.uom_id.id,
|
||||
"location_id": cls.stock_location.id,
|
||||
"location_dest_id": cls.customer_location.id,
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
)
|
||||
cls.picking_out_02 = cls.picking_out_01.copy()
|
||||
cls.picking_in_01 = (
|
||||
cls.env["stock.picking"]
|
||||
.with_context(planned_picking=True)
|
||||
.create(
|
||||
{
|
||||
"location_id": cls.supplier_location.id,
|
||||
"location_dest_id": cls.stock_location.id,
|
||||
"partner_id": cls.partner_agrolite.id,
|
||||
"picking_type_id": cls.picking_type_in.id,
|
||||
"move_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": cls.product_wo_tracking.name,
|
||||
"product_id": cls.product_wo_tracking.id,
|
||||
"product_uom_qty": 3,
|
||||
"product_uom": cls.product_wo_tracking.uom_id.id,
|
||||
"location_id": cls.supplier_location.id,
|
||||
"location_dest_id": cls.stock_location.id,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": cls.product_wo_tracking.name,
|
||||
"product_id": cls.product_wo_tracking.id,
|
||||
"product_uom_qty": 5,
|
||||
"product_uom": cls.product_wo_tracking.uom_id.id,
|
||||
"location_id": cls.supplier_location.id,
|
||||
"location_dest_id": cls.stock_location.id,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": cls.product_tracking.name,
|
||||
"product_id": cls.product_tracking.id,
|
||||
"product_uom_qty": 3,
|
||||
"product_uom": cls.product_tracking.uom_id.id,
|
||||
"location_id": cls.supplier_location.id,
|
||||
"location_dest_id": cls.stock_location.id,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": cls.product_tracking.name,
|
||||
"product_id": cls.product_tracking.id,
|
||||
"product_uom_qty": 5,
|
||||
"product_uom": cls.product_tracking.uom_id.id,
|
||||
"location_id": cls.supplier_location.id,
|
||||
"location_dest_id": cls.stock_location.id,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
)
|
||||
cls.picking_in_01.action_confirm()
|
||||
action = cls.picking_in_01.action_barcode_scan()
|
||||
cls.wiz_scan_picking = cls.ScanReadPicking.browse(action["res_id"])
|
||||
|
||||
# Create a wizard for outgoing picking
|
||||
cls.picking_out_01.action_confirm()
|
||||
action = cls.picking_out_01.action_barcode_scan()
|
||||
cls.wiz_scan_picking_out = cls.ScanReadPicking.browse(action["res_id"])
|
||||
|
||||
def test_wiz_picking_values(self):
|
||||
self.assertEqual(
|
||||
self.wiz_scan_picking.location_id, self.picking_in_01.location_id
|
||||
)
|
||||
self.assertEqual(self.wiz_scan_picking.res_model_id, self.stock_picking_model)
|
||||
self.assertEqual(self.wiz_scan_picking.res_id, self.picking_in_01.id)
|
||||
self.assertIn(
|
||||
"Barcode reader - %s - " % (self.picking_in_01.name),
|
||||
self.wiz_scan_picking.display_name,
|
||||
)
|
||||
|
||||
def test_picking_wizard_scan_product(self):
|
||||
# self.wiz_scan_picking.manual_entry = True
|
||||
wiz_scan_picking = self.wiz_scan_picking.with_context(
|
||||
force_create_move=True, no_increase_qty_done=True
|
||||
)
|
||||
self.action_barcode_scanned(wiz_scan_picking, "8480000723208")
|
||||
sml = self.picking_in_01.move_line_ids.filtered(
|
||||
lambda x: x.product_id == self.product_wo_tracking
|
||||
)
|
||||
self.assertEqual(sml.qty_done, 1.0)
|
||||
# Scan product with tracking lot enable
|
||||
self.action_barcode_scanned(wiz_scan_picking, "8433281006850")
|
||||
sml = self.picking_in_01.move_line_ids.filtered(
|
||||
lambda x: x.product_id == self.product_tracking
|
||||
)
|
||||
self.assertEqual(sml.qty_done, 0.0)
|
||||
self.assertEqual(
|
||||
self.wiz_scan_picking.message,
|
||||
"8433281006850 (Scan Product, Packaging, Lot / Serial)",
|
||||
)
|
||||
# Scan a lot. Increment quantities if scan product or other lot from
|
||||
# this product
|
||||
self.action_barcode_scanned(wiz_scan_picking, "8411822222568")
|
||||
sml = self.picking_in_01.move_line_ids.filtered(
|
||||
lambda x: x.product_id == self.product_tracking and x.lot_id
|
||||
)
|
||||
self.assertEqual(sml.lot_id, self.lot_1)
|
||||
self.assertEqual(sml.qty_done, 1.0)
|
||||
self.action_barcode_scanned(wiz_scan_picking, "8433281006850")
|
||||
stock_move = sml.move_id
|
||||
self.assertEqual(sum(stock_move.move_line_ids.mapped("qty_done")), 1.0)
|
||||
self.action_barcode_scanned(wiz_scan_picking, "8411822222568")
|
||||
self.assertEqual(sum(stock_move.move_line_ids.mapped("qty_done")), 1.0)
|
||||
self.assertEqual(
|
||||
self.wiz_scan_picking.message,
|
||||
"8411822222568 (Scan Product, Packaging, Lot / Serial)",
|
||||
)
|
||||
# Scan a package
|
||||
self.action_barcode_scanned(wiz_scan_picking, "5420008510489")
|
||||
# Package of 5 product units. Already three unit exists
|
||||
self.assertEqual(sum(stock_move.move_line_ids.mapped("qty_done")), 5.0)
|
||||
|
||||
def test_picking_wizard_scan_product_manual_entry(self):
|
||||
wiz_scan_picking = self.wiz_scan_picking.with_context(
|
||||
force_create_move=True, no_increase_qty_done=True
|
||||
)
|
||||
wiz_scan_picking.manual_entry = True
|
||||
self.action_barcode_scanned(wiz_scan_picking, "8480000723208")
|
||||
sml = self.picking_in_01.move_line_ids.filtered(
|
||||
lambda x: x.product_id == self.product_wo_tracking
|
||||
)
|
||||
self.assertEqual(wiz_scan_picking.product_qty, 0.0)
|
||||
wiz_scan_picking.product_qty = 12.0
|
||||
wiz_scan_picking.action_confirm()
|
||||
self.assertEqual(sml.qty_done, 12.0)
|
||||
|
||||
def test_barcode_from_operation(self):
|
||||
picking_out_3 = self.picking_out_01.copy()
|
||||
self.picking_out_01.action_assign()
|
||||
self.picking_out_02.action_assign()
|
||||
self.picking_type_out.default_location_dest_id = self.customer_location
|
||||
|
||||
action = self.picking_type_out.action_barcode_scan()
|
||||
self.wiz_scan_picking = self.ScanReadPicking.browse(action["res_id"])
|
||||
self.wiz_scan_picking.manual_entry = True
|
||||
self.wiz_scan_picking.product_id = self.product_tracking
|
||||
self.wiz_scan_picking.lot_id = self.lot_1
|
||||
self.wiz_scan_picking.product_qty = 2
|
||||
|
||||
self.wiz_scan_picking.with_context(
|
||||
force_create_move=True, no_increase_qty_done=True
|
||||
).action_confirm()
|
||||
self.assertEqual(len(self.wiz_scan_picking.candidate_picking_ids[0:2]), 2)
|
||||
# Lock first picking
|
||||
candidate = self.wiz_scan_picking.candidate_picking_ids.filtered(
|
||||
lambda c: c.picking_id == self.picking_out_01
|
||||
)
|
||||
candidate_wiz = candidate.with_context(
|
||||
wiz_barcode_id=self.wiz_scan_picking.id, picking_id=self.picking_out_01.id
|
||||
)
|
||||
candidate_wiz.with_context(force_create_move=True).action_lock_picking()
|
||||
self.assertEqual(self.picking_out_01.move_ids.quantity_done, 2)
|
||||
self.wiz_scan_picking.product_qty = 2
|
||||
self.wiz_scan_picking.with_context(
|
||||
force_create_move=True, no_increase_qty_done=True
|
||||
).action_confirm()
|
||||
self.assertEqual(self.picking_out_01.move_ids.quantity_done, 2)
|
||||
|
||||
# Picking out 3 is in confirmed state, so until confirmed moves has
|
||||
# not been activated candidate pickings is 2
|
||||
picking_out_3.action_confirm()
|
||||
candidate_wiz.action_unlock_picking()
|
||||
self.wiz_scan_picking.product_qty = 2
|
||||
self.wiz_scan_picking.with_context(
|
||||
force_create_move=True, no_increase_qty_done=True
|
||||
).action_confirm()
|
||||
self.assertEqual(len(self.wiz_scan_picking.candidate_picking_ids[0:2]), 2)
|
||||
candidate_wiz.action_unlock_picking()
|
||||
self.wiz_scan_picking.product_qty = 2
|
||||
self.wiz_scan_picking.option_group_id.confirmed_moves = True
|
||||
self.wiz_scan_picking.with_context(
|
||||
force_create_move=True, no_increase_qty_done=True
|
||||
).action_confirm()
|
||||
self.assertEqual(len(self.wiz_scan_picking.candidate_picking_ids[0:3]), 3)
|
||||
|
||||
def test_picking_wizard_scan_product_auto_lot(self):
|
||||
# Prepare more data
|
||||
lot_2 = self.StockProductionLot.create(
|
||||
{
|
||||
"name": "8411822222578",
|
||||
"product_id": self.product_tracking.id,
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
lot_3 = self.StockProductionLot.create(
|
||||
{
|
||||
"name": "8411822222588",
|
||||
"product_id": self.product_tracking.id,
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
quant_lot_2 = self.StockQuant.create(
|
||||
{
|
||||
"product_id": self.product_tracking.id,
|
||||
"lot_id": lot_2.id,
|
||||
"location_id": self.stock_location.id,
|
||||
"quantity": 15.0,
|
||||
}
|
||||
)
|
||||
quant_lot_3 = self.StockQuant.create(
|
||||
{
|
||||
"product_id": self.product_tracking.id,
|
||||
"lot_id": lot_3.id,
|
||||
"location_id": self.stock_location.id,
|
||||
"quantity": 10.0,
|
||||
}
|
||||
)
|
||||
self.quant_lot_1.in_date = "2021-01-01"
|
||||
quant_lot_2.in_date = "2021-01-05"
|
||||
quant_lot_3.in_date = "2021-01-06"
|
||||
# Scan product with tracking lot enable
|
||||
self.action_barcode_scanned(self.wiz_scan_picking, "8433281006850")
|
||||
self.assertEqual(
|
||||
self.wiz_scan_picking.message,
|
||||
"8433281006850 (Scan Product, Packaging, Lot / Serial)",
|
||||
)
|
||||
|
||||
self.wiz_scan_picking.auto_lot = True
|
||||
# self.wiz_scan_picking.manual_entry = True
|
||||
|
||||
# Removal strategy FIFO
|
||||
|
||||
# No auto lot for incoming pickings
|
||||
self.action_barcode_scanned(self.wiz_scan_picking, "8433281006850")
|
||||
self.assertFalse(self.wiz_scan_picking.lot_id)
|
||||
|
||||
# Continue test with a outgoing wizard
|
||||
self.wiz_scan_picking_out.option_group_id.auto_lot = True
|
||||
self.wiz_scan_picking_out.auto_lot = True
|
||||
self.action_barcode_scanned(self.wiz_scan_picking_out, "8433281006850")
|
||||
self.assertEqual(self.wiz_scan_picking_out.lot_id, self.lot_1)
|
||||
|
||||
# Removal strategy LIFO
|
||||
self.wiz_scan_picking_out.lot_id = False
|
||||
self.product_tracking.categ_id.removal_strategy_id = self.env.ref(
|
||||
"stock.removal_lifo"
|
||||
)
|
||||
self.wiz_scan_picking_out.action_clean_values()
|
||||
self.action_barcode_scanned(self.wiz_scan_picking_out, "8433281006850")
|
||||
self.assertEqual(self.wiz_scan_picking_out.lot_id, lot_3)
|
||||
|
||||
@classmethod
|
||||
def _create_barcode_option_group_incoming(cls):
|
||||
return cls.env["stock.barcodes.option.group"].create(
|
||||
{
|
||||
"name": "option group incoming for tests",
|
||||
"option_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 1,
|
||||
"name": "Location",
|
||||
"field_name": "location_id",
|
||||
"filled_default": True,
|
||||
"to_scan": False,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Product",
|
||||
"field_name": "product_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
"clean_after_done": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Packaging",
|
||||
"field_name": "packaging_id",
|
||||
"to_scan": True,
|
||||
"required": False,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Lot / Serial",
|
||||
"field_name": "lot_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 3,
|
||||
"name": "Location Dest",
|
||||
"field_name": "location_dest_id",
|
||||
"filled_default": True,
|
||||
"to_scan": False,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 4,
|
||||
"name": "Quantity",
|
||||
"field_name": "product_qty",
|
||||
"required": True,
|
||||
"clean_after_done": True,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _create_barcode_option_group_outgoing(cls):
|
||||
return cls.env["stock.barcodes.option.group"].create(
|
||||
{
|
||||
"name": "option group outgoing for tests",
|
||||
"option_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 1,
|
||||
"name": "Location",
|
||||
"field_name": "location_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
"filled_default": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Product",
|
||||
"field_name": "product_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Packaging",
|
||||
"field_name": "packaging_id",
|
||||
"to_scan": True,
|
||||
"required": False,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 2,
|
||||
"name": "Lot / Serial",
|
||||
"field_name": "lot_id",
|
||||
"to_scan": True,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 3,
|
||||
"name": "Location Dest",
|
||||
"field_name": "location_dest_id",
|
||||
"filled_default": True,
|
||||
"to_scan": False,
|
||||
"required": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"step": 4,
|
||||
"name": "Quantity",
|
||||
"field_name": "product_qty",
|
||||
"required": True,
|
||||
"clean_after_done": True,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
def test_stock_picking_validate(self):
|
||||
self.picking_in_01.state = False
|
||||
with self.assertRaises(UserError):
|
||||
self.picking_in_01.with_context(
|
||||
stock_barcodes_validate_picking=True
|
||||
).button_validate()
|
||||
|
||||
def test_barcode_read_picking(self):
|
||||
self.picking_in_01.state = "done"
|
||||
self.wiz_scan_picking._compute_enable_add_product()
|
||||
self.assertFalse(self.wiz_scan_picking.enable_add_product)
|
||||
|
||||
self.wiz_scan_picking.show_detailed_operations = False
|
||||
self.wiz_scan_picking.action_show_detailed_operations()
|
||||
self.assertTrue(self.wiz_scan_picking.action_show_detailed_operations)
|
||||
|
||||
self.wiz_scan_picking.action_show_detailed_operations()
|
||||
self.assertFalse(self.wiz_scan_picking.show_detailed_operations)
|
||||
|
||||
def test_barcode_read_inventory(self):
|
||||
context = {
|
||||
"params": {
|
||||
"model": "wiz.stock.barcodes.read.inventory",
|
||||
"id": self.quant_lot_1.id,
|
||||
}
|
||||
}
|
||||
with self.assertRaises(MissingError):
|
||||
self.quant_lot_1.with_context(
|
||||
**context
|
||||
).action_barcode_inventory_quant_unlink()
|
||||
context = {
|
||||
"params": {
|
||||
"model": self.wiz_scan_read_inventory._name,
|
||||
"id": self.wiz_scan_read_inventory.id,
|
||||
}
|
||||
}
|
||||
self.quant_lot_1.with_context(**context).action_barcode_inventory_quant_unlink()
|
||||
self.assertIsNone(
|
||||
self.quant_lot_1.with_context(
|
||||
**context
|
||||
).action_barcode_inventory_quant_unlink()
|
||||
)
|
||||
self.assertIsNone(self.quant_lot_1.enable_current_operations())
|
||||
self.assertIsNone(self.quant_lot_1.action_barcode_inventory_quant_edit())
|
||||
with self.assertRaises(ValueError):
|
||||
self.quant_lot_1.write({"inventory_quantity": "test"})
|
||||
self.quant_lot_1.operation_quantities_rest()
|
||||
self.quant_lot_1.operation_quantities()
|
||||
self.assertEqual(
|
||||
type(self.picking_in_01.picking_type_id.get_action_picking_tree_ready()),
|
||||
dict,
|
||||
)
|
||||
self.assertEqual(
|
||||
type(
|
||||
self.picking_in_01.picking_type_id.with_context(
|
||||
**{"operations_mode": True}
|
||||
).get_action_picking_tree_ready()
|
||||
),
|
||||
dict,
|
||||
)
|
||||
self.assertIsNone(self.wiz_scan_candidate_picking._compute_picking_quantity())
|
||||
self.assertIsNone(self.wiz_scan_candidate_picking._compute_is_pending())
|
||||
self.assertEqual(
|
||||
self.wiz_scan_candidate_picking._get_picking_to_validate()._name,
|
||||
self.picking_in_01._name,
|
||||
)
|
||||
self.assertEqual(
|
||||
type(self.wiz_scan_candidate_picking.action_validate_picking()), tuple
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue