19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:32:12 +01:00
parent 79f83631d5
commit 73afc09215
6267 changed files with 1534193 additions and 1130106 deletions

View file

@ -1,29 +1,59 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
_inherit = 'sale.order.line'
_description = "Sales Order Line"
sale_order_option_ids = fields.One2many('sale.order.option', 'line_id', 'Optional Products Lines')
# Section-related fields
is_optional = fields.Boolean(
string="Optional Line",
copy=True,
default=False,
) # Whether this section's lines are optional in the portal.
# === COMPUTE METHODS === #
@api.depends('product_id')
def _compute_name(self):
# Take the description on the order template if the product is present in it
super()._compute_name()
for line in self:
if line.product_id and line.order_id.sale_order_template_id:
if line.product_id and line.order_id.sale_order_template_id and line._use_template_name():
for template_line in line.order_id.sale_order_template_id.sale_order_template_line_ids:
if line.product_id == template_line.product_id:
if line.product_id == template_line.product_id and template_line.name:
# If a specific description was set on the template, use it
# Otherwise the description is handled by the super call
lang = line.order_id.partner_id.lang
line.name = template_line.with_context(lang=lang).name + line.with_context(lang=lang)._get_sale_order_line_multiline_description_variants()
break
def _compute_price_unit(self):
# Avoid recomputing the price with pricelist rules, use the initial price
# used in the optional product line.
optional_product_lines = self.filtered('sale_order_option_ids')
super(SaleOrderLine, self - optional_product_lines)._compute_price_unit()
def _use_template_name(self):
""" Allows overriding to avoid using the template lines descriptions for the sale order lines descriptions.
This is typically useful for 'configured' products, such as event_ticket or event_booth, where we need to have
specific configuration information inside description instead of the default values.
"""
self.ensure_one()
return True
# === TOOLING ===#
def _is_line_optional(self):
""" Returns whether the line is optional or not.
A line is optional if it is directly under an optional (sub)section, or under a subsection
which is itself under an optional section.
"""
self.ensure_one()
return (
self.parent_id.is_optional
or (
self.parent_id.display_type == 'line_subsection'
and self.parent_id.parent_id.is_optional
)
)
def _can_be_edited_on_portal(self):
return super()._can_be_edited_on_portal() and self._is_line_optional()