166 lines
7.6 KiB
Python
Executable File
166 lines
7.6 KiB
Python
Executable File
# Copyright 2023 Moduon Team S.L.
|
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
|
|
from odoo import fields
|
|
from odoo.tests import Form
|
|
|
|
from odoo.addons.product.tests.common import ProductCommon
|
|
|
|
|
|
class SalePackagingDefaultCase(ProductCommon):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.env.user.groups_id |= cls.env.ref("product.group_stock_packaging")
|
|
with Form(cls.product) as product_f:
|
|
with product_f.packaging_ids.new() as packaging_f:
|
|
packaging_f.name = "Dozen"
|
|
packaging_f.qty = 12
|
|
packaging_f.sales = True
|
|
packaging_f.sequence = 20
|
|
with product_f.packaging_ids.new() as packaging_f:
|
|
packaging_f.name = "Big box"
|
|
packaging_f.qty = 100
|
|
packaging_f.sales = True
|
|
packaging_f.sequence = 10 # This is the default one
|
|
cls.big_box, cls.dozen = cls.product.packaging_ids
|
|
assert cls.dozen.name == "Dozen"
|
|
assert cls.big_box.name == "Big box"
|
|
cls.product2 = cls.env["product.product"].create(
|
|
{
|
|
"name": "Product 2",
|
|
"type": "consu",
|
|
"packaging_ids": [
|
|
fields.Command.create(
|
|
{
|
|
"name": "3-pack",
|
|
"qty": 3,
|
|
"sales": True,
|
|
"sequence": 10,
|
|
}
|
|
),
|
|
],
|
|
}
|
|
)
|
|
cls.p2_three_pack = cls.product2.packaging_ids[0]
|
|
assert cls.p2_three_pack.name == "3-pack"
|
|
cls.product_packaging_qty_no_integer = cls.env["product.product"].create(
|
|
{
|
|
"name": "Product packaging with qty not integer",
|
|
"type": "consu",
|
|
"packaging_ids": [
|
|
fields.Command.create(
|
|
{
|
|
"name": "1 Piece",
|
|
"qty": 1.6,
|
|
"sales": True,
|
|
"sequence": 10,
|
|
}
|
|
),
|
|
],
|
|
}
|
|
)
|
|
cls.packaging = cls.product_packaging_qty_no_integer.packaging_ids
|
|
|
|
def test_default_packaging_sale_order(self):
|
|
"""Check is packaging usage in sale order."""
|
|
# Create a sale order with the product
|
|
so_f = Form(self.env["sale.order"])
|
|
so_f.partner_id = self.partner
|
|
with so_f.order_line.new() as line_f:
|
|
line_f.product_id = self.product
|
|
# Automatically set the default packaging and the quantity
|
|
self.assertEqual(line_f.product_packaging_id, self.big_box)
|
|
self.assertEqual(line_f.product_packaging_qty, 1)
|
|
self.assertEqual(line_f.product_uom_qty, 100)
|
|
# Change the packaging, and qtys are recalculated
|
|
line_f.product_packaging_id = self.dozen
|
|
self.assertEqual(line_f.product_packaging_qty, 1)
|
|
self.assertEqual(line_f.product_uom_qty, 12)
|
|
# Change product qty, and packaging is recalculated
|
|
line_f.product_uom_qty = 1200
|
|
self.assertEqual(line_f.product_packaging_qty, 12)
|
|
self.assertEqual(line_f.product_packaging_id, self.big_box)
|
|
self.assertEqual(line_f.product_uom_qty, 1200)
|
|
# I want it in dozens, so I change the packaging
|
|
line_f.product_packaging_id = self.dozen
|
|
self.assertEqual(line_f.product_packaging_id, self.dozen)
|
|
self.assertEqual(line_f.product_uom_qty, 1200)
|
|
self.assertEqual(line_f.product_packaging_qty, 100)
|
|
# I want less dozens, so I change the packaging qty
|
|
line_f.product_packaging_qty = 90
|
|
self.assertEqual(line_f.product_packaging_id, self.dozen)
|
|
self.assertEqual(line_f.product_uom_qty, 1080)
|
|
# Change the packaging again, and qtys are recalculated
|
|
line_f.product_packaging_id = self.big_box
|
|
self.assertEqual(line_f.product_packaging_qty, 1)
|
|
self.assertEqual(line_f.product_uom_qty, 100)
|
|
# I want more units, so I change the uom qty
|
|
line_f.product_uom_qty = 120
|
|
self.assertEqual(line_f.product_packaging_qty, 10)
|
|
self.assertEqual(line_f.product_packaging_id, self.dozen)
|
|
# If I set a uom qty without packaging, it is emptied
|
|
line_f.product_uom_qty = 7
|
|
self.assertFalse(line_f.product_packaging_id)
|
|
self.assertEqual(line_f.product_packaging_qty, 0)
|
|
self.assertEqual(line_f.product_uom_qty, 7)
|
|
# Setting zero uom qty resets to the default packaging
|
|
line_f.product_uom_qty = 0
|
|
self.assertEqual(line_f.product_packaging_id, self.big_box)
|
|
self.assertEqual(line_f.product_packaging_qty, 0)
|
|
self.assertEqual(line_f.product_uom_qty, 0)
|
|
|
|
def test_sale_order_product_picker_compatibility(self):
|
|
"""Emulate a call done by the product picker module and see it works.
|
|
|
|
This test asserts support for cross-compatibility with
|
|
`sale_order_product_picker`.
|
|
"""
|
|
so_f = Form(
|
|
self.env["sale.order"].with_context(
|
|
default_product_id=self.product.id, default_price_unit=20
|
|
)
|
|
)
|
|
so_f.partner_id = self.partner
|
|
# User clicks on +1 button
|
|
with so_f.order_line.new() as line_f:
|
|
self.assertEqual(line_f.product_uom_qty, 1)
|
|
self.assertFalse(line_f.product_packaging_id)
|
|
|
|
def test_product_change(self):
|
|
"""Set one product, alter qtys, change product, qtys are reset."""
|
|
so_f = Form(self.env["sale.order"])
|
|
so_f.partner_id = self.partner
|
|
with so_f.order_line.new() as line_f:
|
|
line_f.product_id = self.product
|
|
self.assertEqual(line_f.product_packaging_id, self.big_box)
|
|
self.assertEqual(line_f.product_packaging_qty, 1)
|
|
self.assertEqual(line_f.product_uom_qty, 100)
|
|
line_f.product_uom_qty = 120
|
|
self.assertEqual(line_f.product_packaging_id, self.dozen)
|
|
self.assertEqual(line_f.product_packaging_qty, 10)
|
|
self.assertEqual(line_f.product_uom_qty, 120)
|
|
line_f.product_id = self.product2
|
|
self.assertEqual(line_f.product_packaging_id, self.p2_three_pack)
|
|
self.assertEqual(line_f.product_packaging_qty, 10)
|
|
self.assertEqual(line_f.product_uom_qty, 30)
|
|
|
|
def test_product_packaging_qty_no_integer(self):
|
|
"""Check behavior with float qty in packaging without using modulo operator.
|
|
|
|
If product_packaging_qty is multiple of qty pacakging, with modulo operator the
|
|
quantity per package might be a float. Example # 8 % 1.6 = 1.5999999999999996
|
|
"""
|
|
so_f = Form(self.env["sale.order"])
|
|
so_f.partner_id = self.partner
|
|
with so_f.order_line.new() as line_f:
|
|
line_f.product_id = self.product_packaging_qty_no_integer
|
|
# Automatically set the default packaging and the quantity
|
|
self.assertEqual(line_f.product_packaging_id, self.packaging)
|
|
self.assertEqual(line_f.product_packaging_qty, 1)
|
|
self.assertEqual(line_f.product_uom_qty, 1.6)
|
|
# Change qty to 8 to force calculate with modulo operator
|
|
# (8 % 1.6 = 1.5999999999999996)
|
|
line_f.product_packaging_qty = 5
|
|
self.assertEqual(line_f.product_packaging_id, self.packaging)
|
|
self.assertEqual(line_f.product_uom_qty, 8)
|