Sélectionner une révision Git
sale_intervention.py

Rémi - Le Filament authored
sale_intervention.py 36,25 Kio
# Copyright 2021-2022 Le Filament (https://le-filament.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
import math
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class SaleIntervention(models.Model):
_name = "sale.intervention"
_description = "Sale Intervention"
_inherit = ["mail.thread", "mail.activity.mixin"]
@api.model
def _default_city(self):
project_id = self.env.context.get("default_project_id")
if project_id:
return (
self.env["sale.project"]
.browse(project_id)
.sale_order_id.partner_id.city
)
# ------------------------------------------------------
# Fields declaration
# ------------------------------------------------------
name = fields.Char("Nom", group_operator="count")
sequence = fields.Integer("Sequence", default=10)
project_id = fields.Many2one(
comodel_name="sale.project", string="Projet", ondelete="cascade", required=True
)
project_subvention_id = fields.Many2one(
related="project_id.project_subvention_id", string="Subventions"
)
intervention_type_id = fields.Many2one(
comodel_name="product.template",
string="Type d'intervention",
domain=lambda self: [
(
"categ_id",
"=",
self.env.ref("ap_sale_project.product_category_forfait").id,
)
],
ondelete="restrict",
required=True,
group_operator="count_distinct",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
intervention_uom_name = fields.Char(
related="intervention_type_id.uom_name", string="Unité de mesure intervention"
)
latitude = fields.Float(string="Geo Latitude", digits=(16, 6))
longitude = fields.Float(string="Geo Longitude", digits=(16, 6))
financial_help_ids = fields.Many2many(
comodel_name="sale.financial.help",
relation="sale_financial_help_rel",
column1="financial_id",
column2="sale_order_id",
string="Aides financières",
)
# If calculated by meters
intervention_length = fields.Float(
string="Longueur de Haie (en m)",
group_operator="sum",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
plant_interval = fields.Float(
"Intervalle entre les plants (en m)",
group_operator="sum",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
# If calculated by units
plant_qty = fields.Integer(
string="Nombre de Plants",
group_operator="sum",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
surface = fields.Integer(
"Surface (en m2)",
help="Information ne rentrant pas dans les calculs",
group_operator="sum",
)
city = fields.Char(
string="Commune intervention",
default=_default_city,
)
# FOURNITURES
is_collarette = fields.Boolean(
string="Collerettes",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
collarette_qty = fields.Integer(
string="Nombre de collerettes",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
collarette_calc = fields.Boolean(
string="Collerette Haie",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
# Mulch Fields
mulch_id = fields.Many2one(
comodel_name="product.template",
string="Paillage",
domain=lambda self: [
("categ_id", "=", self.env.ref("ap_sale_project.product_category_mulch").id)
],
ondelete="restrict",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
mulch_qty = fields.Float(
string="Qté paillage 1",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
mulch_unit = fields.Many2one(
"uom.uom",
related="mulch_id.uom_id",
readonly=True,
string="Unité de mesure paillage 1",
)
mulch_has_staples = fields.Boolean(
string="Paillage 1 avec agrafes",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
mulch2_id = fields.Many2one(
comodel_name="product.template",
string="Paillage 2",
domain=lambda self: [
("categ_id", "=", self.env.ref("ap_sale_project.product_category_mulch").id)
],
ondelete="restrict",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
mulch2_qty = fields.Float(
string="Qté paillage 2",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
mulch2_unit = fields.Many2one(
"uom.uom",
related="mulch2_id.uom_id",
readonly=True,
string="Unité de mesure paillage 2",
)
mulch2_has_staples = fields.Boolean(
string="Paillage 2 avec agrafes",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
# High protection
high_protection_id = fields.Many2one(
comodel_name="product.template",
string="Protection haute",
domain=lambda self: [
(
"categ_id",
"=",
self.env.ref("ap_sale_project.product_category_protection_high").id,
)
],
ondelete="restrict",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
high_protection_qty = fields.Integer(
string="Qté protégée haut",
help="Qté de la plantation que l’on veut protéger par le haut \
(avec protections entrées au dessus)",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
stake_id = fields.Many2one(
comodel_name="product.template",
string="Piquets",
domain=lambda self: [
("categ_id", "=", self.env.ref("ap_sale_project.product_category_stake").id)
],
ondelete="restrict",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
stake_qty = fields.Integer(
string="Qté Piquets",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
# Low protection
low_protection_id = fields.Many2one(
comodel_name="product.template",
string="Protection basse",
domain=lambda self: [
(
"categ_id",
"=",
self.env.ref("ap_sale_project.product_category_protection_low").id,
)
],
ondelete="restrict",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
low_protection_qty = fields.Integer(
string="Qté protégée bas",
help="Qté de la plantation que l’on veut protéger par le bas \
(avec protections entrées au dessus)",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
bamboo_qty = fields.Integer(
string="Qté bambous",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
# Markers (Jalons)
marker_id = fields.Many2one(
comodel_name="product.template",
string="Jalons",
domain=lambda self: [
(
"categ_id",
"=",
self.env.ref("ap_sale_project.product_category_marker").id,
)
],
ondelete="restrict",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
marker_qty = fields.Integer(
string="Qté jalons",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
sequence_type = fields.Selection(
[("sequence", "Constuction en séquence"), ("list", "Construction en liste")],
string="Type de séquence",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
plant_sequence_ids = fields.One2many(
comodel_name="sale.intervention.plant.sequence",
inverse_name="intervention_id",
domain="[('is_list', '!=', True)]",
string="Séquences",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
plant_list_ids = fields.One2many(
comodel_name="sale.intervention.plant.sequence",
inverse_name="intervention_id",
domain="[('is_list', '=', True)]",
string="Listes",
readonly=True,
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
)
# Computed fields
plant_qty_per_seq = fields.Integer(
"Nombre de plants par séquence",
compute="_compute_quantities",
default=0,
store=True,
)
full_seq_qty = fields.Integer(
"Nombre de séquences entières",
compute="_compute_quantities",
default=0,
store=True,
)
extra_plants_qty = fields.Integer(
"Nombre de plants supplémentaires",
compute="_compute_quantities",
default=0,
store=True,
)
plants_qty = fields.Integer(
"Nombre total de plants (calculé)",
compute="_compute_quantities",
default=0,
group_operator="sum",
store=True,
)
plants_type_qty = fields.Integer(
"Nombre d'espèces différentes",
compute="_compute_quantities",
default=0,
store=True,
)
plants_local_qty = fields.Integer(
"Nombre de végétal local",
compute="_compute_quantities",
default=0,
group_operator="sum",
store=True,
)
plant_price = fields.Float(
"Prix d'un plant",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
collarette_price = fields.Float(
"Prix d'une collerette",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
mulch_price = fields.Float(
"Prix du paillage 1",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
mulch2_price = fields.Float(
"Prix du paillage 2",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
staple1_price = fields.Float(
"Prix des agrafes pour paillage 1",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
staple2_price = fields.Float(
"Prix des agrafes pour paillage 2",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
high_protection_price = fields.Float(
"Prix d'une protection haute",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
stake_price = fields.Float(
"Prix d'un piquet",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
low_protection_price = fields.Float(
"Prix d'une protection basse",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
marker_price = fields.Float(
"Prix d'un jalon",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
service_price = fields.Float(
"Prix du service",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
)
price = fields.Float(
"Prix de l'intervention",
compute="_compute_interventions_price",
store=True,
readonly=True,
default=0.0,
digits="Product Price",
group_operator="sum",
)
sale_order_id = fields.Many2one(
related="project_id.sale_order_id",
string="Devis/Commande",
)
partner_id = fields.Many2one(
related="project_id.partner_id", string="Client", store=True
)
state = fields.Selection(related="sale_order_id.state", store=True)
sale_intervention_stock_ids = fields.One2many(
comodel_name="sale.intervention.stock",
inverse_name="sale_intervention_id",
string="Articles à déstocker",
)
# ------------------------------------------------------
# SQL Constraints
# ------------------------------------------------------
# ------------------------------------------------------
# Default methods
# ------------------------------------------------------
# ------------------------------------------------------
# Computed fields / Search Fields
# ------------------------------------------------------
@api.depends(
"sequence_type",
"intervention_uom_name",
"intervention_length",
"plant_interval",
"plant_qty",
"plant_sequence_ids",
"plant_sequence_ids.product_id",
"plant_sequence_ids.product_alternance_id",
"plant_sequence_ids.is_local",
"plant_list_ids",
"plant_list_ids.product_alternance_id",
"plant_list_ids.is_local",
)
def _compute_quantities(self):
for rec in self:
plant_qty_per_seq = 0
full_seq_qty = 0
extra_plants_qty = 0
plants_qty = 0
plants_type_qty = 0
plants_local_qty = 0
if rec.sequence_type == "sequence":
if rec.intervention_uom_name == "m" and rec.plant_interval != 0.0:
plants_qty = (
math.ceil(rec.intervention_length / rec.plant_interval) + 1
)
elif rec.intervention_uom_name == "Unité(s)":
plants_qty = rec.plant_qty
plant_qty_per_seq = len(rec.plant_sequence_ids)
if plant_qty_per_seq != 0:
full_seq_qty = plants_qty // plant_qty_per_seq
extra_plants_qty = plants_qty % plant_qty_per_seq
plants_type_qty = len(
set(
rec.plant_sequence_ids.product_id
+ rec.plant_sequence_ids.product_alternance_id
)
)
local_ratio = (
len(rec.plant_sequence_ids.filtered("is_local"))
/ plant_qty_per_seq
)
plants_local_qty = math.ceil(local_ratio * plants_qty)
else:
plants_qty = sum(plant.qty for plant in rec.plant_list_ids)
plants_type_qty = len(set(rec.plant_list_ids.product_id))
plants_local_qty = sum(
plant.qty for plant in rec.plant_list_ids if plant.is_local
)
rec.plants_qty = plants_qty
rec.plant_qty_per_seq = plant_qty_per_seq
rec.full_seq_qty = full_seq_qty
rec.extra_plants_qty = extra_plants_qty
rec.plants_type_qty = plants_type_qty
rec.plants_local_qty = plants_local_qty
# ------------------------------------------------------
# Onchange / Constraints
# ------------------------------------------------------
@api.onchange("intervention_length", "plant_interval")
def _onchange_length(self):
if self.intervention_uom_name == "m" and self.plant_interval > 0:
plant_qty = math.ceil(self.intervention_length / self.plant_interval) + 1
self.plant_qty = plant_qty
self.collarette_qty = plant_qty
@api.onchange("plant_qty")
def _onchange_plant_qty(self):
if self.intervention_uom_name == "Unité(s)":
self.collarette_qty = self.plant_qty
@api.onchange("plant_qty", "intervention_length", "mulch_id")
def _onchange_mulch_id(self):
self.mulch_has_staples = False
if self.mulch_unit == self.env.ref("uom.product_uom_meter"):
self.mulch_qty = self.intervention_length
elif self.mulch_unit == self.env.ref("uom.product_uom_unit"):
self.mulch_qty = self.plant_qty
else:
self.mulch_qty = 0.0
@api.onchange("plant_qty", "intervention_length", "mulch2_id")
def _onchange_mulch2_id(self):
self.mulch2_has_staples = False
if self.mulch2_unit == self.env.ref("uom.product_uom_meter"):
self.mulch2_qty = self.intervention_length
elif self.mulch2_unit == self.env.ref("uom.product_uom_unit"):
self.mulch2_qty = self.plant_qty
else:
self.mulch2_qty = 0.0
@api.onchange("high_protection_qty")
def _onchange_high_protection_qty(self):
self.stake_qty = self.high_protection_qty
@api.onchange("low_protection_qty")
def _onchange_low_protection_qty(self):
self.bamboo_qty = self.low_protection_qty * 2
@api.constrains("plant_interval")
def _check_plant_interval(self):
for rec in self:
if rec.intervention_uom_name == "m" and (
rec.plant_interval < 0.7 or rec.plant_interval > 1.2
):
raise UserError(
_(
"L'intervalle entre 2 plants '%f' est incorrect: il doit être "
"entre 0,7m et 1,2m."
)
% rec.plant_interval
)
@api.constrains("plant_qty", "plants_qty")
def _check_plant_qty(self):
for rec in self:
if (
rec.plant_qty != rec.plants_qty
and rec.sequence_type == "list"
and rec.plant_list_ids
):
raise UserError(
_(
"La quantité de plants renseignée '%d' est différente de"
"la quantité de plants calculée '%d'.\n "
"Les quantités doivent être identiques, vérifier votre compositon."
)
% (rec.plant_qty, rec.plants_qty)
)
@api.depends(
"project_id.intervention_ids.intervention_length",
"project_subvention_id",
"intervention_length",
"plant_qty",
"plant_interval",
"intervention_type_id",
"intervention_uom_name",
"is_collarette",
"collarette_qty",
"mulch_id",
"mulch_qty",
"mulch_has_staples",
"mulch2_id",
"mulch2_qty",
"mulch2_has_staples",
"high_protection_id",
"high_protection_qty",
"stake_id",
"stake_qty",
"low_protection_id",
"low_protection_qty",
"bamboo_qty",
"marker_id",
"marker_qty",
)
def _compute_interventions_price(self):
plant_categ_id = self.env.ref("ap_sale_project.product_category_plant")
collarette_product_id = self.env.ref("ap_sale_project.ap_product_other_coll")
staples_product_id = self.env.ref("ap_sale_project.ap_product_other_staples")
service_product_id = self.env.ref("ap_sale_project.ap_product_service_service")
total_price = 0.0
for rec in self:
# multiplicator is the quantity to be used for computation
# either : length if computation is per meter
# or : number of plants if computation is per plant
multiplicator = (
rec.intervention_length
if rec.intervention_uom_name == "m"
else rec.plant_qty
)
partner = rec.sale_order_id.partner_id
forfait = rec.intervention_type_id
# CASE for computing based on forfait
if (
rec.project_subvention_id.type == "forfait"
and rec.project_subvention_id.product_pricelist_ids
):
# We retrieve the first pricelist linked to this subvention
pricelist = rec.project_subvention_id.product_pricelist_ids[0]
# We retrieve from pricelist the unit price of our forfait
unit_price = pricelist.get_product_price(
forfait, multiplicator, partner
)
# and we multiply by quantity
rec.price = multiplicator * unit_price
# CASE for computing based on grid
elif (
rec.project_subvention_id.type == "grid"
and rec.project_subvention_id.product_pricelist_ids
):
# We retrieve pricelist from subvention where
# intervention_type_id = our type of intervention
pricelist = rec.project_subvention_id.product_pricelist_ids.filtered(
lambda i: i.intervention_type_id == forfait
)[0]
if pricelist and pricelist.item_ids.filtered(
lambda i: i.categ_id == plant_categ_id
):
# First we retrieve price of a plant (since these are
# per categories we make something different here)
plant_pricelist_item = pricelist.item_ids.filtered(
lambda i: i.categ_id == plant_categ_id
)[0]
rec.plant_price = (
plant_pricelist_item.fixed_price
if plant_pricelist_item
else 0.0
)
# Then we create ordered lists with :
# products, quantities and partners
# Service
# For service we need to take into account the sumed length
# of all interventions of the same type
# Get all interventions of same type in the same project
interventions = self.project_id.intervention_ids.filtered(
lambda r: r.intervention_type_id == rec.intervention_type_id
)
service_qty = (
sum(interventions.mapped("intervention_length"))
if rec.intervention_uom_name == "m"
else multiplicator
)
products = [
service_product_id,
]
quantities = [
service_qty,
]
partners = [
partner,
]
# Collarette
coll_qty = rec.collarette_qty or 0
if rec.is_collarette:
# In case collarette price is calculated per meter iso unit
if rec.intervention_uom_name == "m" and rec.collarette_calc:
coll_qty = rec.intervention_length
products.append(collarette_product_id)
quantities.append(coll_qty or 0)
partners.append(partner)
# Mulch
if rec.mulch_id:
products.append(rec.mulch_id)
quantities.append(rec.mulch_qty or 0)
partners.append(partner)
# Mulch 2
if rec.mulch2_id:
products.append(rec.mulch2_id)
quantities.append(rec.mulch2_qty or 0)
partners.append(partner)
# Staples
if rec.mulch_has_staples or rec.mulch2_has_staples:
products.append(staples_product_id)
quantities.append(rec.mulch_qty * 2 or 0)
partners.append(partner)
# High Protections
if rec.high_protection_id:
products.append(rec.high_protection_id)
quantities.append(rec.high_protection_qty or 0)
partners.append(partner)
# Stakes
if rec.stake_id:
products.append(rec.stake_id)
quantities.append(rec.stake_qty or 0)
partners.append(partner)
# Low Protections
if rec.low_protection_id:
products.append(rec.low_protection_id)
quantities.append(rec.low_protection_qty or 0)
partners.append(partner)
# Markers
if rec.marker_id:
products.append(rec.marker_id)
quantities.append(rec.marker_qty or 0)
partners.append(partner)
# We retrieve all prices here
prices = pricelist.get_products_price(
products, quantities, partners
)
rec.collarette_price = (
prices[collarette_product_id.id] if rec.is_collarette else 0.0
)
rec.mulch_price = prices[rec.mulch_id.id] if rec.mulch_id else 0.0
rec.staple1_price = (
prices[staples_product_id.id] if rec.mulch_has_staples else 0.0
)
rec.mulch2_price = (
prices[rec.mulch2_id.id] if rec.mulch2_id else 0.0
)
rec.staple2_price = (
prices[staples_product_id.id] if rec.mulch2_has_staples else 0.0
)
rec.high_protection_price = (
prices[rec.high_protection_id.id]
if rec.high_protection_id
else 0.0
)
rec.stake_price = prices[rec.stake_id.id] if rec.stake_id else 0.0
rec.low_protection_price = (
prices[rec.low_protection_id.id]
if rec.low_protection_id
else 0.0
)
rec.marker_price = (
prices[rec.marker_id.id] if rec.marker_id else 0.0
)
rec.service_price = prices[service_product_id.id]
rec.price = (
multiplicator * (rec.plant_price + rec.service_price)
+ coll_qty * rec.collarette_price
+ rec.mulch_qty * (rec.mulch_price + 2 * rec.staple1_price)
+ rec.mulch2_qty * (rec.mulch2_price + 2 * rec.staple2_price)
+ rec.high_protection_qty * rec.high_protection_price
+ rec.stake_qty * rec.stake_price
+ rec.low_protection_qty * rec.low_protection_price
+ rec.marker_qty * rec.marker_price
)
else:
raise UserError(
_(
"Impossible de trouver la liste de prix correspondant "
"à ce programme de subvention : %s \n"
"et ce type d'intervention : %s"
)
% (rec.project_subvention_id.name, forfait.name)
)
else:
raise UserError(
_(
"Impossible de trouver la liste de prix correspondant "
"à ce programme de subvention %s"
)
% rec.project_subvention_id.name
)
total_price += rec.price
rec.project_id.update_order_lines()
return total_price
def _get_plants_qties(self):
# Method to get list of plants and quantities
self.ensure_one()
products = []
qty = []
if self.sequence_type == "sequence":
iteration = 0
for sequence in self.plant_sequence_ids:
products.append(sequence.product_id)
# add calculation for plants out of sequence, based on iteration
extra_plant = 0
extra_alter_plant = 0
if self.extra_plants_qty and iteration < self.extra_plants_qty:
# if the full number of sequence is odd
# (or no alternance plant is defined),
# we add the main plant
if self.full_seq_qty % 2 == 0 or not sequence.product_alternance_id:
extra_plant = 1
# otherwise, we add the alternance plant
else:
extra_alter_plant = 1
if sequence.product_alternance_id:
qty.append(math.ceil(self.full_seq_qty / 2) + extra_plant)
products.append(sequence.product_alternance_id)
qty.append(math.floor(self.full_seq_qty / 2) + extra_alter_plant)
else:
qty.append(self.full_seq_qty + extra_plant)
iteration += 1
elif self.sequence_type == "list":
products = self.plant_list_ids.mapped("product_id")
qty = self.plant_list_ids.mapped("qty")
return list(zip(products, qty))
def _create_sale_intervention_stock_lines(self):
self.ensure_one()
# Only perform calculation if quantities are set
if self.plants_qty > 0:
data = []
for product, qty in self._get_plants_qties():
if product and qty > 0:
data_vals = {
"sale_intervention_id": self.id,
"product_id": product.product_variant_id.id,
"product_uom_qty": qty,
"price_unit": self.plant_price,
}
data.append(data_vals)
staples_product_id = self.env.ref(
"ap_sale_project.ap_product_other_staples"
)
if self.mulch_id and self.mulch_qty > 0:
data.append(
{
"sale_intervention_id": self.id,
"product_id": self.mulch_id.product_variant_id.id,
"product_uom_qty": self.mulch_qty,
"price_unit": self.mulch_price,
}
)
if self.mulch_has_staples:
data.append(
{
"sale_intervention_id": self.id,
"product_id": staples_product_id.product_variant_id.id,
"product_uom_qty": self.mulch_qty * 2,
"price_unit": self.staple1_price,
}
)
if self.mulch2_id and self.mulch2_qty > 0:
data.append(
{
"sale_intervention_id": self.id,
"product_id": self.mulch2_id.product_variant_id.id,
"product_uom_qty": self.mulch2_qty,
"price_unit": self.mulch2_price,
}
)
if self.mulch2_has_staples:
data.append(
{
"sale_intervention_id": self.id,
"product_id": staples_product_id.product_variant_id.id,
"product_uom_qty": self.mulch2_qty * 2,
"price_unit": self.staple2_price,
}
)
if self.is_collarette and self.collarette_qty > 0:
collarette_product_id = self.env.ref(
"ap_sale_project.ap_product_other_coll"
)
data.append(
{
"sale_intervention_id": self.id,
"product_id": collarette_product_id.product_variant_id.id,
"product_uom_qty": self.collarette_qty,
"price_unit": self.collarette_price,
}
)
if self.high_protection_id and self.high_protection_qty > 0:
data.append(
{
"sale_intervention_id": self.id,
"product_id": self.high_protection_id.product_variant_id.id,
"product_uom_qty": self.high_protection_qty,
"price_unit": self.high_protection_price,
}
)
if self.stake_id and self.stake_qty > 0:
data.append(
{
"sale_intervention_id": self.id,
"product_id": self.stake_id.product_variant_id.id,
"product_uom_qty": self.stake_qty,
"price_unit": self.stake_price,
}
)
if self.low_protection_id and self.low_protection_qty > 0:
data.append(
{
"sale_intervention_id": self.id,
"product_id": self.low_protection_id.product_variant_id.id,
"product_uom_qty": self.low_protection_qty,
"price_unit": self.low_protection_price,
}
)
if self.bamboo_qty > 0:
bamboo_product_id = self.env.ref(
"ap_sale_project.ap_product_other_bamboo"
)
data.append(
{
"sale_intervention_id": self.id,
"product_id": bamboo_product_id.product_variant_id.id,
"product_uom_qty": self.bamboo_qty,
"price_unit": 0.0,
}
)
if self.marker_id and self.marker_qty > 0:
data.append(
{
"sale_intervention_id": self.id,
"product_id": self.marker_id.product_variant_id.id,
"product_uom_qty": self.marker_qty,
"price_unit": self.marker_price,
}
)
StockLine = self.env["sale.intervention.stock"]
StockLine.create(data)
# ------------------------------------------------------
# CRUD methods (ORM overrides)
# ------------------------------------------------------
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
for rec in res:
rec.project_id.intervention_sequence += 1
rec.name = "Séquence " + str(rec.project_id.intervention_sequence)
return res
def write(self, values):
res = super().write(values)
if self.sale_intervention_stock_ids:
self.sale_intervention_stock_ids.unlink()
self._create_sale_intervention_stock_lines()
return res
# ------------------------------------------------------
# Actions
# ------------------------------------------------------
# ------------------------------------------------------
# CRUD methods (ORM overrides)
# ------------------------------------------------------
def unlink(self):
project_id = self.project_id
res = super().unlink()
project_id.update_order_lines()
return res