Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

View 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

View 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)]",
)

View 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

View 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