129 lines
4.6 KiB
Python
Executable File
129 lines
4.6 KiB
Python
Executable File
# Copyright 2018 Tecnativa - Sergio Teruel
|
|
# Copyright 2019 Tecnativa - Pedro M. Baeza
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
def _execute_onchanges(records, field_name):
|
|
"""Helper methods that executes all onchanges associated to a field."""
|
|
for onchange in records._onchange_methods.get(field_name, []):
|
|
for record in records:
|
|
onchange(record)
|
|
|
|
|
|
class SaleOrder(models.Model):
|
|
_inherit = "sale.order"
|
|
|
|
def _create_elaboration_line(self, product, qty):
|
|
"""Create a sale order line from a elaboration product, search a line
|
|
with the same elaboration product to add qty
|
|
:param product:
|
|
:param qty:
|
|
:return: the sale order line record created
|
|
"""
|
|
SaleOrderLine = self.env["sale.order.line"]
|
|
sol_for_product = self.order_line.filtered(lambda x: x.product_id == product)[
|
|
:1
|
|
]
|
|
if sol_for_product:
|
|
sol_for_product.product_uom_qty += qty
|
|
return sol_for_product
|
|
sol = SaleOrderLine.new(
|
|
{"order_id": self.id, "product_id": product.id, "is_elaboration": True}
|
|
)
|
|
_execute_onchanges(sol, "product_id")
|
|
sol.update({"product_uom_qty": qty})
|
|
_execute_onchanges(sol, "product_uom_qty")
|
|
vals = sol._convert_to_write(sol._cache)
|
|
if self.order_line:
|
|
vals["sequence"] = self.order_line[-1].sequence + 1
|
|
return SaleOrderLine.sudo().create(vals)
|
|
|
|
|
|
class SaleOrderLine(models.Model):
|
|
_inherit = ["sale.order.line", "product.elaboration.mixin"]
|
|
_name = "sale.order.line"
|
|
|
|
date_order = fields.Datetime(related="order_id.date_order", string="Date")
|
|
route_id = fields.Many2one(compute="_compute_route_id", store=True, readonly=False)
|
|
elaboration_profile_id = fields.Many2one(
|
|
comodel_name="product.elaboration.profile",
|
|
compute="_compute_elaboration_profile_id",
|
|
)
|
|
elaboration_price_unit = fields.Float(
|
|
"Elab. Price", compute="_compute_elaboration_price_unit", store=True
|
|
)
|
|
is_prepared = fields.Boolean(
|
|
compute=lambda self: None,
|
|
search="_search_is_prepared",
|
|
help=("Dummy field to be able to find prepared lines"),
|
|
)
|
|
|
|
@api.depends("product_id")
|
|
def _compute_elaboration_profile_id(self):
|
|
"""Order of applicability: product profile > category profile > no profile"""
|
|
self.elaboration_profile_id = False
|
|
for line in self.filtered("product_id"):
|
|
line.elaboration_profile_id = (
|
|
line.product_id.elaboration_profile_id
|
|
or line.product_id.categ_id.elaboration_profile_id
|
|
)
|
|
|
|
def get_elaboration_stock_route(self):
|
|
self.ensure_one()
|
|
return self.elaboration_ids.route_ids[:1]
|
|
|
|
@api.depends("elaboration_ids")
|
|
def _compute_route_id(self):
|
|
for line in self:
|
|
route_id = line.get_elaboration_stock_route()
|
|
if route_id:
|
|
line.route_id = route_id
|
|
|
|
@api.depends("elaboration_ids", "order_id.pricelist_id")
|
|
def _compute_elaboration_price_unit(self):
|
|
for line in self:
|
|
if not line.order_id.pricelist_id:
|
|
line.elaboration_price_unit = 0
|
|
else:
|
|
line.elaboration_price_unit = sum(
|
|
line.order_id.pricelist_id._get_products_price(
|
|
line.elaboration_ids.product_id,
|
|
quantity=1,
|
|
).values()
|
|
)
|
|
|
|
def _prepare_invoice_line(self, **optional_values):
|
|
vals = super()._prepare_invoice_line(**optional_values)
|
|
if self.is_elaboration:
|
|
vals["name"] = f"{self.order_id.name} - {self.name}"
|
|
return vals
|
|
|
|
def _search_is_prepared(self, operator, value):
|
|
if operator != "=":
|
|
raise UserError(
|
|
_("Unsupported operator %s for searching on is_prepared") % (operator,)
|
|
)
|
|
moves = self.env["stock.move"].search(
|
|
[
|
|
(
|
|
"state",
|
|
"not in" if value else "in",
|
|
[
|
|
"draft",
|
|
"waiting",
|
|
"confirmed",
|
|
"partially_available",
|
|
"assigned",
|
|
],
|
|
),
|
|
(
|
|
"location_dest_id",
|
|
"=",
|
|
self.env.ref("stock.stock_location_customers").id,
|
|
),
|
|
]
|
|
)
|
|
return [("move_ids", "in", moves.ids)]
|