[IMP] product_contract: Add contract configurator instead of making tree not editable

Before this changes, when trying to edit a line of sale order, it was
opening the form of the line. But following the way to work of odoo
with sale event, we have make a new contract configurator that will
be opened when selecting a product of type contract.
This commit is contained in:
Carlos Roca
2024-08-26 11:29:09 +02:00
parent 7f7d947172
commit 88d2cb9a2f
10 changed files with 367 additions and 22 deletions

View File

@@ -0,0 +1 @@
from . import product_contract_configurator

View File

@@ -0,0 +1,124 @@
# Copyright 2024 Tecnativa - Carlos Roca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models
class ProductContractConfigurator(models.TransientModel):
_name = "product.contract.configurator"
_description = "Product Contract Configurator Wizard"
product_id = fields.Many2one("product.product")
partner_id = fields.Many2one("res.partner")
company_id = fields.Many2one("res.company")
product_uom_qty = fields.Float("Quantity")
contract_id = fields.Many2one(comodel_name="contract.contract", string="Contract")
contract_template_id = fields.Many2one(
comodel_name="contract.template",
string="Contract Template",
compute="_compute_contract_template_id",
)
recurring_rule_type = fields.Selection(
[
("daily", "Day(s)"),
("weekly", "Week(s)"),
("monthly", "Month(s)"),
("monthlylastday", "Month(s) last day"),
("quarterly", "Quarter(s)"),
("semesterly", "Semester(s)"),
("yearly", "Year(s)"),
],
default="monthly",
string="Invoice Every",
)
recurring_invoicing_type = fields.Selection(
[("pre-paid", "Pre-paid"), ("post-paid", "Post-paid")],
default="pre-paid",
string="Invoicing type",
help="Specify if process date is 'from' or 'to' invoicing date",
)
date_start = fields.Date()
date_end = fields.Date()
contract_line_id = fields.Many2one(
comodel_name="contract.line",
string="Contract Line to replace",
required=False,
)
is_auto_renew = fields.Boolean(
string="Auto Renew",
compute="_compute_auto_renew",
default=False,
store=True,
readonly=False,
)
auto_renew_interval = fields.Integer(
default=1,
string="Renew Every",
compute="_compute_auto_renew",
store=True,
readonly=False,
help="Renew every (Days/Week/Month/Year)",
)
auto_renew_rule_type = fields.Selection(
[
("daily", "Day(s)"),
("weekly", "Week(s)"),
("monthly", "Month(s)"),
("yearly", "Year(s)"),
],
default="yearly",
compute="_compute_auto_renew",
store=True,
readonly=False,
string="Renewal type",
help="Specify Interval for automatic renewal.",
)
@api.depends("product_id", "company_id")
def _compute_contract_template_id(self):
for rec in self:
rec.contract_template_id = rec.product_id.with_company(
rec.company_id
).property_contract_template_id
@api.depends("product_id")
def _compute_auto_renew(self):
for rec in self:
if rec.product_id.is_contract:
rec.product_uom_qty = rec.product_id.default_qty
rec.recurring_rule_type = rec.product_id.recurring_rule_type
rec.recurring_invoicing_type = rec.product_id.recurring_invoicing_type
rec.date_start = rec.date_start or fields.Date.today()
rec.date_end = rec._get_date_end()
rec.is_auto_renew = rec.product_id.is_auto_renew
if rec.is_auto_renew:
rec.auto_renew_interval = rec.product_id.auto_renew_interval
rec.auto_renew_rule_type = rec.product_id.auto_renew_rule_type
def _get_auto_renew_rule_type(self):
"""monthly last day don't make sense for auto_renew_rule_type"""
self.ensure_one()
if self.recurring_rule_type == "monthlylastday":
return "monthly"
return self.recurring_rule_type
def _get_date_end(self):
self.ensure_one()
contract_line_model = self.env["contract.line"]
date_end = (
self.date_start
+ contract_line_model.get_relative_delta(
self._get_auto_renew_rule_type(),
int(self.product_uom_qty),
)
- relativedelta(days=1)
)
return date_end
@api.onchange("date_start", "product_uom_qty", "recurring_rule_type")
def _onchange_date_start(self):
for rec in self.filtered("product_id.is_contract"):
rec.date_end = rec._get_date_end() if rec.date_start else False

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="product_contract_configurator_form" model="ir.ui.view">
<field name="model">product.contract.configurator</field>
<field name="arch" type="xml">
<form js_class="product_contract_configurator_form">
<group>
<field name="product_id" invisible="1" />
<field name="partner_id" invisible="1" />
<field name="contract_template_id" invisible="1" />
<group colspan="2">
<field name="product_uom_qty" />
</group>
<separator colspan="4" string="Recurrence Invoicing" />
<group>
<field name="recurring_rule_type" />
<field name="date_start" required="1" />
<field name="is_auto_renew" />
</group>
<group>
<field name="recurring_invoicing_type" />
<field name="date_end" required="1" />
<label
for="auto_renew_interval"
invisible="not is_auto_renew"
/>
<div invisible="not is_auto_renew">
<field
name="auto_renew_interval"
class="oe_inline"
nolabel="1"
required="is_auto_renew"
/>
<field
name="auto_renew_rule_type"
class="oe_inline"
nolabel="1"
required="is_auto_renew"
/>
</div>
</group>
<separator colspan="4" string="Contract" />
<group colspan="2">
<field
name="contract_id"
options='{"no_create": True}'
domain="['|',('contract_template_id','=',contract_template_id), ('contract_template_id','=',False), ('partner_id','=',partner_id), ('is_terminated','=',False),
]"
/>
<field
name="contract_line_id"
domain="[('contract_id','=',contract_id)]"
/>
</group>
</group>
<footer>
<button
string="Ok"
class="btn-primary"
special="save"
data-hotkey="q"
/>
<button
string="Cancel"
class="btn-secondary"
special="cancel"
data-hotkey="x"
/>
</footer>
</form>
</field>
</record>
<record id="product_contract_configurator_action" model="ir.actions.act_window">
<field name="name">Configure a contract</field>
<field name="res_model">product.contract.configurator</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="view_id" ref="product_contract_configurator_form" />
</record>
</odoo>