Initial commit: Odoo 18.0-20251222 extra-addons
This commit is contained in:
4
sale_order_secondary_unit/models/__init__.py
Executable file
4
sale_order_secondary_unit/models/__init__.py
Executable file
@@ -0,0 +1,4 @@
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from . import product
|
||||
from . import product_template
|
||||
from . import sale_order
|
||||
17
sale_order_secondary_unit/models/product.py
Executable file
17
sale_order_secondary_unit/models/product.py
Executable file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2022 Tecnativa - Sergio Teruel
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
_inherit = "product.product"
|
||||
|
||||
sale_secondary_uom_id = fields.Many2one(
|
||||
comodel_name="product.secondary.unit",
|
||||
string="Default secondary unit for sales",
|
||||
help="In order to set a value, please first add at least one record"
|
||||
" in 'Secondary Unit of Measure'",
|
||||
domain="['|', ('product_id', '=', id),"
|
||||
"'&', ('product_tmpl_id', '=', product_tmpl_id),"
|
||||
" ('product_id', '=', False)]",
|
||||
)
|
||||
72
sale_order_secondary_unit/models/product_template.py
Executable file
72
sale_order_secondary_unit/models/product_template.py
Executable file
@@ -0,0 +1,72 @@
|
||||
# Copyright 2018-2020 Tecnativa - Sergio Teruel
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = "product.template"
|
||||
|
||||
sale_secondary_uom_id = fields.Many2one(
|
||||
comodel_name="product.secondary.unit",
|
||||
string="Default secondary unit for sales",
|
||||
compute="_compute_sale_secondary_uom_id",
|
||||
inverse="_inverse_sale_secondary_uom_id",
|
||||
help="In order to set a value, please first add at least one record"
|
||||
" in 'Secondary Unit of Measure'",
|
||||
domain="[('product_tmpl_id', '=', id), ('product_id', '=', False)]",
|
||||
store=True,
|
||||
)
|
||||
|
||||
@api.depends("product_variant_ids", "product_variant_ids.sale_secondary_uom_id")
|
||||
def _compute_sale_secondary_uom_id(self):
|
||||
unique_variants = self.filtered(lambda tmpl: tmpl.product_variant_count == 1)
|
||||
for template in unique_variants:
|
||||
template.sale_secondary_uom_id = (
|
||||
template.product_variant_ids.sale_secondary_uom_id
|
||||
)
|
||||
for template in self - unique_variants:
|
||||
if len(template.product_variant_ids.sale_secondary_uom_id) == 1:
|
||||
template.sale_secondary_uom_id = (
|
||||
template.product_variant_ids.sale_secondary_uom_id
|
||||
)
|
||||
else:
|
||||
template.sale_secondary_uom_id = False
|
||||
|
||||
def _inverse_sale_secondary_uom_id(self):
|
||||
for template in self:
|
||||
# if template.product_variant_count == 1:
|
||||
template.product_variant_ids.sale_secondary_uom_id = (
|
||||
template.sale_secondary_uom_id
|
||||
)
|
||||
|
||||
@api.onchange("sale_secondary_uom_id")
|
||||
def onchange_sale_secondary_uom_id(self):
|
||||
if len(self.product_variant_ids.sale_secondary_uom_id) > 1:
|
||||
return {
|
||||
"warning": {
|
||||
"title": self.env._("Warning"),
|
||||
"message": self.env._(
|
||||
"Product variants have distinct sale secondary uom:"
|
||||
"\n{secondary_uom}\n"
|
||||
"All variants will be written with new secondary uom"
|
||||
).format(
|
||||
secondary_uom="\n".join(
|
||||
self.product_variant_ids.mapped(
|
||||
"sale_secondary_uom_id.name"
|
||||
)
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
templates = super().create(vals_list)
|
||||
# This is needed to set given values to first variant after creation
|
||||
for template, vals in zip(templates, vals_list, strict=True):
|
||||
related_vals = {}
|
||||
if vals.get("sale_secondary_uom_id"):
|
||||
related_vals["sale_secondary_uom_id"] = vals["sale_secondary_uom_id"]
|
||||
if related_vals:
|
||||
template.write(related_vals)
|
||||
return templates
|
||||
64
sale_order_secondary_unit/models/sale_order.py
Executable file
64
sale_order_secondary_unit/models/sale_order.py
Executable file
@@ -0,0 +1,64 @@
|
||||
# Copyright 2018-2020 Tecnativa - Carlos Dauden
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = ["sale.order.line", "product.secondary.unit.mixin"]
|
||||
_name = "sale.order.line"
|
||||
_secondary_unit_fields = {
|
||||
"qty_field": "product_uom_qty",
|
||||
"uom_field": "product_uom",
|
||||
}
|
||||
|
||||
secondary_uom_unit_price = fields.Float(
|
||||
string="2nd unit price",
|
||||
digits="Product Price",
|
||||
compute="_compute_secondary_uom_unit_price",
|
||||
)
|
||||
|
||||
product_uom_qty = fields.Float(copy=True)
|
||||
|
||||
@api.depends(
|
||||
"display_type",
|
||||
"product_id",
|
||||
"product_packaging_qty",
|
||||
"secondary_uom_qty",
|
||||
"secondary_uom_id",
|
||||
"product_uom_qty",
|
||||
)
|
||||
def _compute_product_uom_qty(self):
|
||||
res = super()._compute_product_uom_qty()
|
||||
for line in self:
|
||||
line._compute_helper_target_field_qty()
|
||||
return res
|
||||
|
||||
@api.depends("product_id")
|
||||
def _compute_product_uom(self):
|
||||
res = super()._compute_product_uom()
|
||||
for line in self:
|
||||
line._onchange_helper_product_uom_for_secondary()
|
||||
return res
|
||||
|
||||
@api.onchange("product_id")
|
||||
def _onchange_product_id_warning(self):
|
||||
res = super()._onchange_product_id_warning()
|
||||
if self.product_id and not self.env.context.get("skip_secondary_uom_default"):
|
||||
self.secondary_uom_id = self.product_id.sale_secondary_uom_id
|
||||
if self.product_uom_qty == 1.0:
|
||||
self.secondary_uom_qty = 1.0
|
||||
self._onchange_helper_product_uom_for_secondary()
|
||||
return res
|
||||
|
||||
@api.depends("secondary_uom_qty", "product_uom_qty", "price_unit")
|
||||
def _compute_secondary_uom_unit_price(self):
|
||||
for line in self:
|
||||
if line.secondary_uom_id:
|
||||
try:
|
||||
line.secondary_uom_unit_price = (
|
||||
line.price_subtotal / line.secondary_uom_qty
|
||||
)
|
||||
except ZeroDivisionError:
|
||||
line.secondary_uom_unit_price = 0
|
||||
else:
|
||||
line.secondary_uom_unit_price = 0
|
||||
Reference in New Issue
Block a user