-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[16.0][MIG] sale_order_line_packaging_qty #2567
base: 16.0
Are you sure you want to change the base?
[16.0][MIG] sale_order_line_packaging_qty #2567
Conversation
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Fixes after review Signed-off-by: Carmen Bianca BAKKER <[email protected]>
The inverse method only updates the value when we save the form. The onchange gives a direct feedback. Also add a unit of measure on the qty. Signed-off-by: Carmen Bianca BAKKER <[email protected]>
… packaging Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
**Context:** We want to be able to only sell by packaging some product (forbidden to sell by unit). Also, we want to choose which packaging is eligible to sell. **Usage** When I encode a sale order line, I must fill up the packaging and related quantity if the product is set as "Only sell by packaging". I cannot enter a quantity in the standard Odoo field quantity that is not a multiple of a sellable packaging (product.packaging can be sold = True). Is the product is not configured as "Only sell by packaging", then I am allowed to fill up a line with no packaging. On every packaging I can chose if it is sellable or not. By default it is. I can chose at product level if i restrict the quantity to sell to existing sellable packaging. **Dev** * Add a check box in product "Only sell by packaging multiple" (default False), aside of "Can be sold" in the header * Add a boolean on the packaging "Can be sold" (default True) * On the list of available packaging in a SO line, only display packaging with "can be sold = True" * When a SO line is encoded *with a product that can only be sold by packaging*: * The quantity field cannot contain a quantity that is not a multiple of a sellable packaging (can be sold = True) -> raise a warning (triggered on the on_change please, not create/write as we still want to be able to save it e.g. in case of an EDI order) -> "The quantity is not a multiple of a defined sellable packaging. Please complete the packaging first." * On create / write method, *if packaging and packaging quantity is empty*, fulfill the info if a multiple of an existing sellable packaging (can be sold = True) is found * e.g. if my product is sold by packaging only and I have packaging of box: 10, Karton: 200, and pallet:1000, if the quantity entered is 400, I expect the system to complete the packaging with Karton and packaging quantity with 2 * e.g. if my product is sold by packaging only and I have packaging of box: 10, Karton: 200, and pallet:1000, if the quantity entered is 420, I expect the system to complete the packaging with box and packaging quantity with 42 * e.g.. if my product is sold by packaging only and I have packaging of box: 10, Karton: 200, and pallet:1000, if the quantity entered is 405, I expect the system to leave it empty * Make the message "You must define a package before setting a quantity of said package." a user warning and not a blocking point AND only raise this warning for product that have "Only sell by packaging multiple = True" Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
…ackaging" This reverts commit 5eece31. Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Currently translated at 100.0% (4 of 4 strings) Translation: sale-workflow-13.0/sale-workflow-13.0-sale_order_line_packaging_qty Translate-URL: https://translation.odoo-community.org/projects/sale-workflow-13-0/sale-workflow-13-0-sale_order_line_packaging_qty/es/ Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
When a quantity is set on the sale order line before or at the same time than the product itself, the onchange triggered will replace the line set quantity with the default size of the package. This is especially problematic for sales order created programmatically. So to improve the solution, if the quantity fits with the package quantity it is kept. Signed-off-by: Carmen Bianca BAKKER <[email protected]>
The product_product_packaging_qty on sale.order.line should always be an integer, no ? Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
If a packaging as a quantity set to zero it should not be available for selection on a sale order line. Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
…heck if qty packaged must be reset + unit test Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Merged in 14.0 odoo/odoo#78405 Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
Signed-off-by: Carmen Bianca BAKKER <[email protected]>
874b2a0
to
6f07edd
Compare
This case is impossible because of product.constraint_product_packaging_positive_qty. Signed-off-by: Carmen Bianca BAKKER <[email protected]>
6f07edd
to
58c13e3
Compare
@bealdav ping :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
product_packaging was renamed to product_packaging_id in Odoo 15 (and moved from sale_stock to sale).
product_packaging_id became a computed field in Odoo 16.
I was able to work with the former, but the latter implies a not-insignificant refactoring. I'll get back to this later.
@api.onchange("product_packaging_id") | ||
def _onchange_product_packaging_id(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may not make any sense, because product_packaging_id became a computed field in Odoo 16.
"product_uom_qty": 3.0, | ||
} | ||
) | ||
order_line.write({"product_packaging_id": self.packaging.id}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't write to a computed field. For some reason this doesn't throw an error, but the behaviour here (and in other tests) is incorrect.
Thanks for your deep check |
Writing down my findings before proceeding with a refactoring. Here's the definition of the product_packaging_id = fields.Many2one(
comodel_name='product.packaging',
string="Packaging",
compute='_compute_product_packaging_id',
store=True, readonly=False, precompute=True,
domain="[('sales', '=', True), ('product_id','=',product_id)]",
check_company=True) In spite of being a computed field, it is set The compute method is as follows: @api.depends('product_id', 'product_uom_qty', 'product_uom')
def _compute_product_packaging_id(self):
for line in self:
# remove packaging if not match the product
if line.product_packaging_id.product_id != line.product_id:
line.product_packaging_id = False
# Find biggest suitable packaging
if line.product_id and line.product_uom_qty and line.product_uom:
line.product_packaging_id = line.product_id.packaging_ids.filtered(
'sales')._find_suitable_product_packaging(line.product_uom_qty, line.product_uom) or line.product_packaging_id Special attention to two lines. First, Furthermore, this method exists in @api.onchange('product_packaging_id')
def _onchange_product_packaging_id(self):
if self.product_packaging_id and self.product_uom_qty:
newqty = self.product_packaging_id._check_qty(self.product_uom_qty, self.product_uom, "UP")
if float_compare(newqty, self.product_uom_qty, precision_rounding=self.product_uom.rounding) != 0:
return {
'warning': {
'title': _('Warning'),
'message': _(
"This product is packaged by %(pack_size).2f %(pack_name)s. You should sell %(quantity).2f %(unit)s.",
pack_size=self.product_packaging_id.qty,
pack_name=self.product_id.uom_id.name,
quantity=newqty,
unit=self.product_uom.name
),
},
} I have to assume that the user can write to this computed field. The user-defined value is written to the database. But when the compute function is triggered, the user-defined value is (potentially) overwritten. This matches with my functional testing. I created a product Foo which has packaging for 1 item, 5 items, and 100 items. When I type '10' into the sale order line quantity, it automagically sets the packaging quantity to 2 and the packaging to 'Five items' Now I can click on 'Five items', and select 'One item'. This results in the packaging quantity being set to 10 (I assume because The above findings imply that this module may not need quite as much refactoring as I thought, because we can still write to the field, and still do onchange methods. I'll just need to validate that everything in this module still makes sense given the above context. |
Well this is awkward. I hadn't thought to check whether the functionality of this module already existed in Odoo. Since Odoo 15, the identically named field @api.depends('product_packaging_id', 'product_uom', 'product_uom_qty')
def _compute_product_packaging_qty(self):
for line in self:
if not line.product_packaging_id:
line.product_packaging_qty = False
else:
packaging_uom = line.product_packaging_id.product_uom_id
packaging_uom_qty = line.product_uom._compute_quantity(line.product_uom_qty, packaging_uom)
line.product_packaging_qty = float_round(
packaging_uom_qty / line.product_packaging_id.qty,
precision_rounding=packaging_uom.rounding) Here is the compute function from this module (given the current state of the PR): @api.depends(
"product_uom_qty",
"product_uom",
"product_packaging_id",
"product_packaging_id.qty",
)
def _compute_product_packaging_qty(self):
for sol in self:
if (
not sol.product_packaging_id
or sol.product_uom_qty == 0
or sol.product_packaging_id.qty == 0
):
sol.product_packaging_qty = 0
continue
# Consider uom
if sol.product_id.uom_id != sol.product_uom:
product_qty = sol.product_uom._compute_quantity(
sol.product_uom_qty, sol.product_id.uom_id
)
else:
product_qty = sol.product_uom_qty
# Provide default values in case of missing product.
# Odoo does not prevent you to modify product packaging
# that are already linked to a sale order.
# If by chance the product is removed (yes, you can do it)
# this computation will be broken w/out this default.
precision = sol.product_packaging_id.product_uom_id.rounding or 0.01
qty_mod = float_round(
product_qty % sol.product_packaging_id.qty,
precision_rounding=precision,
)
# After the rounding, the value could be equals to
# sol.product_packaging_id.qty.
# So just re-apply the '%'
qty_mod = qty_mod % sol.product_packaging_id.qty
if not float_is_zero(
qty_mod,
precision_digits=precision,
):
# If qty does not fit in package reset package qty
sol.product_packaging_qty = 0
else:
# Maybe that product_packaging_qty should be an Integer, no ?
qty = product_qty / sol.product_packaging_id.qty
sol.product_packaging_qty = qty These two methods are almost identical (although the latter is more verbose), barring a few implementation details:
The question, then, is do we port this module to overwrite the default behaviour in |
Good catch, I haven't seen the odoo side. |
@grindtildeath Hi, you're the author of this module and the module I'm trying to port in #2570, which depends on this module. Would you like to review the above comments? Specifically, my question is as follows, quoted from my last comment:
I am inclined to the latter. Let's not port this module, and let's make changes (if necessary) in #2570 to work with upstream Odoo |
Hello @carmenbianca To me as well, this module is not needed anymore if there's a standard field in Odoo with the same purpose. AFAICS the fields exists in standard since v15.0 so #1919 should not be needed neither. BTW, the documentation of the computed fields is lacking the last changes in ORM, where it's allowed to have a computed field that is writeable by setting |
FYI #2570 (comment) |
/ocabot migration sale_order_line_packaging_qty |
I agree, IMO this PR should closed. |
Includes #2239
Internal task: https://gestion.coopiteasy.be/web#id=10668&action=475&active_id=486&model=project.task&view_type=form&menu_id=