Skip to content
Extraits de code Groupes Projets
Valider 3b27d99d rédigé par Benjamin - Le Filament's avatar Benjamin - Le Filament
Parcourir les fichiers

[REF] move models to abstract models

parent a4829405
Branches
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de
avec 273 ajouts et 401 suppressions
......@@ -17,9 +17,9 @@
"views/financial_contract.xml",
"views/financial_external_guarantee.xml",
"views/financial_funding.xml",
"views/financial_product_category.xml",
"views/financial_product_template.xml",
"views/financial_suspensive_condition.xml",
"views/res_partner.xml",
# views menu
"views/menus.xml",
# wizard
......@@ -31,6 +31,7 @@
"web.assets_tests": [],
"web.assets_qweb": [],
},
"application": True,
"installable": True,
"auto_install": False,
}
from . import financial_contract_mixin
from . import financial_contract
from . import financial_contract_suspensive_condition
from . import financial_external_guarantee
from . import financial_funding
from . import financial_product_category
from . import financial_product_suspensive_condition
from . import financial_product_template
from . import financial_suspensive_condition
from . import res_company
from . import res_partner
......@@ -5,18 +5,43 @@ from odoo import _, api, fields, models
from odoo.exceptions import AccessError, UserError
class FinancialContract(models.Model):
class FinancialContract(models.AbstractModel):
_name = "financial.contract"
_description = "Financial Contract"
_inherit = ["financial.contract.mixin"]
_order = "create_date desc"
tool = fields.Selection(
[],
string="Outil",
name = fields.Char(compute="_compute_name")
number = fields.Char("Numéro", readonly=True)
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Client",
required=True,
)
tool_id = fields.Many2oneReference("ID Outil", model_field="tool", required=True,)
active = fields.Boolean(
default=True,
)
amount = fields.Monetary("Montant")
company_id = fields.Many2one(
comodel_name="res.company",
string="Société",
default=lambda self: self.env.company,
)
currency_id = fields.Many2one(
comodel_name="res.currency", related="company_id.currency_id"
)
comment = fields.Text("Commentaire")
expiration_date = fields.Date("Date d'expiration")
guarantee_id = fields.Many2one(
comodel_name="financial.external.guarantee",
string="Garantie",
ondelete="restrict",
)
funding_id = fields.Many2one(
comodel_name="financial.funding",
string="Fonds financeur",
ondelete="restrict",
)
state = fields.Selection(
[
("init", "Initialisation"),
......@@ -39,41 +64,18 @@ class FinancialContract(models.Model):
for contract in self:
if contract.state in ["proposal", "contract", "done", "cancel"]:
if contract.company_id not in self.env.user.company_ids:
raise AccessError(_(
"vous n'êtes pas autorisé à modifier ce contrat"
))
raise AccessError(
_("Vous n'êtes pas autorisé à modifier ce contrat.")
)
# ------------------------------------------------------
# Computed fields / Search Fields
# ------------------------------------------------------
@api.depends("tool", "tool_id")
def _compute_contract_fields(self):
for contract in self:
contract_id = contract._get_tool_object()
if contract_id:
contract.company_id = contract_id.company_id
contract.product_id = contract_id.product_id
contract.amount = contract_id.amount
@api.depends("product_id")
def _compute_suspensive_condition_ids(self):
def _compute_name(self):
for contract in self:
# contract.suspensive_condition_ids.unlink()
condition_to_create = [(5, 0, 0)]
if contract.product_id:
for condition in self.product_id.suspensive_condition_ids:
condition_to_create.append(
(
0,
None,
{
"condition_id": condition.id,
"condition_comment": condition.condition_comment,
},
contract.name = (
f"{contract.number or '#'} - " f"{contract.partner_id.name} "
)
)
if condition_to_create:
contract.update({"suspensive_condition_ids": condition_to_create})
# ------------------------------------------------------
# Onchange
......@@ -86,6 +88,16 @@ class FinancialContract(models.Model):
# ------------------------------------------------------
# CRUD (Override ORM)
# ------------------------------------------------------
def unlink(self):
"""
Restrict contract deletion depending on state
"""
for contract in self:
if contract.state != "init":
raise UserError(
_("Seuls les deals à l'état Projet peuvent être supprimés")
)
return super().unlink()
# ------------------------------------------------------
# Override ORM
......@@ -94,6 +106,3 @@ class FinancialContract(models.Model):
# ------------------------------------------------------
# Business functions
# ------------------------------------------------------
def _get_tool_object(self):
self.ensure_one()
return self.env[self.tool].browse(self.tool_id) if self.tool else False
# © 2024 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import AccessError, UserError
class FinancialContractMixin(models.AbstractModel):
_name = "financial.contract.mixin"
_inherit = ["mail.thread", "mail.activity.mixin"]
_description = "Financial Contract Mixin"
name = fields.Char(compute="_compute_name")
number = fields.Char("Numéro", readonly=True)
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Client",
required=True,
)
product_id = fields.Many2one(
comodel_name="financial.product.template",
string="Gamme",
)
active = fields.Boolean(
default=True,
tracking=1,
)
amount = fields.Monetary("Montant")
company_id = fields.Many2one(
comodel_name="res.company",
string="Société",
default=lambda self: self.env.company,
)
currency_id = fields.Many2one(
comodel_name="res.currency", compute="_compute_currency_id"
)
suspensive_condition_ids = fields.One2many(
comodel_name="financial.contract.suspensive.condition",
inverse_name="contract_id",
string="Conditions suspensives",
compute="_compute_suspensive_condition_ids",
store=True,
readonly=False,
)
comment = fields.Text("Commentaire")
expiration_date = fields.Date("Date d'expiration")
guarantee_id = fields.Many2one(
comodel_name="financial.external.guarantee",
string="Garantie",
ondelete="restrict",
)
funding_id = fields.Many2one(
comodel_name="financial.funding",
string="Fonds financeur",
ondelete="restrict",
)
# ------------------------------------------------------
# Constrains
# ------------------------------------------------------
@api.constrains("state", "company_id")
def _check_user_company(self):
for contract in self:
if contract.state in ["proposal", "contract", "done", "cancel"]:
if contract.company_id not in self.env.user.company_ids:
raise AccessError(_(
"vous n'êtes pas autorisé à modifier ce contrat"
))
# ------------------------------------------------------
# Computed fields / Search Fields
# ------------------------------------------------------
def _compute_currency_id(self):
for contract in self:
contract.currency_id = self.env.company.currency_id
def _compute_name(self):
for contract in self:
contract.name = (
f"{contract.number or '#'} - "
f"{contract.partner_id.name} "
)
@api.depends("product_id")
def _compute_suspensive_condition_ids(self):
for contract in self:
# contract.suspensive_condition_ids.unlink()
condition_to_create = [(5, 0, 0)]
if contract.product_id:
for condition in self.product_id.suspensive_condition_ids:
condition_to_create.append(
(
0,
None,
{
"condition_id": condition.id,
"condition_comment": condition.condition_comment,
},
)
)
if condition_to_create:
contract.update({"suspensive_condition_ids": condition_to_create})
# ------------------------------------------------------
# Onchange
# ------------------------------------------------------
# ------------------------------------------------------
# Actions
# ------------------------------------------------------
# ------------------------------------------------------
# CRUD (Override ORM)
# ------------------------------------------------------
@api.model_create_multi
def create(self, vals):
tools = super().write(vals)
for tool in tools:
contract = self.env["financial.contract"].create({
"tool": self._name,
"tool_id": tool.id,
})
tool.contract_id = contract.id
return tools
def unlink(self):
"""
Restrict contract deletion depending on state
"""
for contract in self:
if contract.state != "init":
raise UserError(
_("Seuls les deals à l'état Projet peuvent être supprimés")
)
return super().unlink()
# ------------------------------------------------------
# Override ORM
# ------------------------------------------------------
def unlink(self):
if self.contract_id:
self.contract_id.unlink()
return super().unlink()
# ------------------------------------------------------
# Business functions
# ------------------------------------------------------
# © 2019 Le Filament (<http://www.le-filament.com>)
# © 2024 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class FinancialContractSuspensiveCondition(models.Model):
class FinancialContractSuspensiveCondition(models.AbstractModel):
_name = "financial.contract.suspensive.condition"
_description = "Financial contract suspensive condition"
......
# © 2019 Le Filament (<http://www.le-filament.com>)
# © 2024 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
......
# Copyright 2023- Le Filament (https://le-filament.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
# © 2024 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class ResPartner(models.Model):
_inherit = "res.partner"
class FinancialProductTemplate(models.Model):
_name = "financial.product.category"
_description = "Financial product category"
# ------------------------------------------------------
# Fields declaration
# ------------------------------------------------------
financial_contract_ids = fields.One2many(
comodel_name="financial.contract",
inverse_name="partner_id",
string="Contrats",
name = fields.Char("Nom de la gamme", required=True)
active = fields.Boolean(
default=True,
)
financial_contract_count = fields.Integer(
compute="_compute_financial_contract_count"
company_id = fields.Many2one(
comodel_name="res.company",
string="Société",
change_default=True,
required=True,
readonly=True,
default=lambda self: self.env.company,
)
# ------------------------------------------------------
# SQL Constraints
# ------------------------------------------------------
# ------------------------------------------------------
# Default methods
# Constrains functions
# ------------------------------------------------------
# ------------------------------------------------------
# Computed fields / Search Fields
# ------------------------------------------------------
def _compute_financial_contract_count(self):
for partner in self:
partner.financial_contract_count = partner.financial_contract_ids.__len__()
# ------------------------------------------------------
# Onchange / Constraints
# Actions
# ------------------------------------------------------
# ------------------------------------------------------
# CRUD methods (ORM overrides)
# Override ORM
# ------------------------------------------------------
# ------------------------------------------------------
# Actions
# CRUD (Override ORM)
# ------------------------------------------------------
def action_view_contract(self):
self.ensure_one()
return {
"type": "ir.actions.act_window",
"name": "Contrats",
"res_model": "financial.contract",
"view_mode": "tree,form",
"domain": [("partner_id", "=", self.id)],
"flags": {"mode": "readonly"},
}
# ------------------------------------------------------
# Business methods
# Business functions
# ------------------------------------------------------
# © 2019 Le Filament (<http://www.le-filament.com>)
# © 2024 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class FinancialProductSuspensiveCondition(models.Model):
class FinancialProductSuspensiveCondition(models.AbstractModel):
_name = "financial.product.suspensive.condition"
_description = "Financial product suspensive condition"
......
......@@ -5,28 +5,22 @@ from odoo import _, api, fields, models
from odoo.exceptions import UserError
class FinancialProductTemplate(models.Model):
class FinancialProductTemplate(models.AbstractModel):
_name = "financial.product.template"
_inherit = ["mail.thread", "mail.activity.mixin",]
_description = "Financial product template"
name = fields.Char(required=True)
category_id = fields.Many2one(
comodel_name="financial.product.category",
string="Nom de la gamme",
required=True,
ondelete="restrict",
)
active = fields.Boolean(
default=True,
tracking=1,
)
tool = fields.Selection(
[],
string="Type d'outil",
required=True,
)
tool_id = fields.Many2oneReference("ID Outil", model_field="tool", required=True,)
description = fields.Text()
suspensive_condition_ids = fields.One2many(
comodel_name="financial.product.suspensive.condition",
inverse_name="product_id",
string="Conditions suspensives",
)
company_id = fields.Many2one(
comodel_name="res.company",
string="Société",
......@@ -38,10 +32,23 @@ class FinancialProductTemplate(models.Model):
currency_id = fields.Many2one(
comodel_name="res.currency", related="company_id.currency_id"
)
date_start = fields.Date("Début de validité")
date_end = fields.Date("Fin de validité")
# ------------------------------------------------------
# Constrains functions
# ------------------------------------------------------
@api.constrains("date_start", "date_end")
def _check_date_validity(self):
for product in self:
if (
product.date_start
and product.date_end
and product.date_end <= product.date_start
):
raise UserError(
_("La date de fin doit être supérieure à la date de début")
)
# ------------------------------------------------------
# Computed fields / Search Fields
......@@ -58,22 +65,6 @@ class FinancialProductTemplate(models.Model):
# ------------------------------------------------------
# CRUD (Override ORM)
# ------------------------------------------------------
def unlink(self):
"""
Restrict product deletion if used in
"""
for product in self:
contract_ids = self.env["financial.contract"].search(
[("product_id", "=", product.id)]
)
if contract_ids:
raise UserError(
_(
"Ce produit est utilisé dans un ou plusieurs dossiers, il n'est "
"pas possible de le supprimer. Il peut être archivé."
)
)
return super().unlink()
# ------------------------------------------------------
# Business functions
......
# © 2019 Le Filament (<http://www.le-filament.com>)
# © 2024 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
......
# Copyright 2023- Le Filament (https://le-filament.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
from odoo import api, fields, models
class ResCompany(models.Model):
_inherit = "res.company"
contract_sequence_id = fields.Many2one("ir.sequence")
# ------------------------------------------------------
# Fields declaration
# ------------------------------------------------------
# ------------------------------------------------------
# SQL Constraints
# ------------------------------------------------------
# ------------------------------------------------------
# Default methods
# ------------------------------------------------------
# ------------------------------------------------------
# Computed fields / Search Fields
# ------------------------------------------------------
# ------------------------------------------------------
# Onchange / Constraints
# ------------------------------------------------------
# ------------------------------------------------------
# CRUD methods (ORM overrides)
# ------------------------------------------------------
@api.model
def create(self, values):
# Crée une séquence dédiée à la société
res = super().create(values)
res.contract_sequence_id = self.env["ir.sequence"].create(
{
"name": f"Contrats Financiers - {res.name}",
"company_id": res.id,
"number_next": 1,
"number_increment": 1,
"use_date_range": True,
"prefix": "C%(year)s%(month)s",
"padding": 4,
"implementation": "no_gap",
"code": f"financial.contract.company_{res.id}",
}
)
return res
# ------------------------------------------------------
# Actions
# ------------------------------------------------------
# ------------------------------------------------------
# Business methods
# ------------------------------------------------------
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_financial_contract,access_financial_contract,model_financial_contract,group_financial_user,1,1,1,1
access_financial_contract_suspensive_condition,access_financial_contract_suspensive_condition,model_financial_contract_suspensive_condition,group_financial_user,1,1,1,1
access_financial_product_category,access_financial_product_category,model_financial_product_category,group_financial_user,1,0,0,0
access_financial_product_category_admin,access_financial_product_category_admin,model_financial_product_category,group_financial_admin,1,1,1,1
access_financial_product_template,access_financial_product_template,model_financial_product_template,group_financial_user,1,0,0,0
access_financial_product_template_admin,access_financial_product_template_admin,model_financial_product_template,group_financial_admin,1,1,1,1
access_financial_product_suspensive_condition,access_financial_product_suspensive_condition,model_financial_product_suspensive_condition,group_financial_user,1,0,0,0
......
......@@ -26,6 +26,36 @@
<!--
Group rules
-->
<record id="financial_product_category_multi_company_rule" model="ir.rule">
<field name="name">Financial Product Category Multi Company</field>
<field name="model_id" ref="model_financial_product_category" />
<field
name="domain_force"
>[('company_id', 'in', company_ids + [False])]</field>
<field
name="groups"
eval="[(6, 0, [ref('financial_contract.group_financial_user')])]"
/>
<field name="perm_read" eval="False" />
<field name="perm_write" eval="True" />
<field name="perm_create" eval="True" />
<field name="perm_unlink" eval="True" />
</record>
<record id="financial_product_template_multi_company_rule" model="ir.rule">
<field name="name">Financial Product Template Multi Company</field>
<field name="model_id" ref="model_financial_product_template" />
<field
name="domain_force"
>[('company_id', 'in', company_ids + [False])]</field>
<field
name="groups"
eval="[(6, 0, [ref('financial_contract.group_financial_user')])]"
/>
<field name="perm_read" eval="False" />
<field name="perm_write" eval="True" />
<field name="perm_create" eval="True" />
<field name="perm_unlink" eval="True" />
</record>
<record id="financial_contract_multi_company_rule" model="ir.rule">
<field name="name">Financial Contract Multi Company</field>
<field name="model_id" ref="model_financial_contract" />
......
......@@ -5,17 +5,16 @@
<field name="name">financial.contract.tree</field>
<field name="model">financial.contract</field>
<field name="arch" type="xml">
<tree>
<tree create="0" edit="0" delete="0">
<field name="partner_id" />
<field name="tool" />
<field name="product_id" />
<field name="amount" string="Montant" />
<field name="company_id" />
<field name="currency_id" invisible="1" />
</tree>
</field>
</record>
<!-- From -->
<!-- Form -->
<record id="financial_contract_form_view" model="ir.ui.view">
<field name="name">financial.contract.form</field>
<field name="model">financial.contract</field>
......@@ -24,29 +23,25 @@
<sheet>
<group>
<group>
<field name="partner_id" />
<field name="tool" />
<field name="product_id" />
</group>
<group>
<field name="amount" string="Montant" />
<field name="company_id" />
<field
name="partner_id"
options="{'no_create': 1}"
/>
<field
name="company_id"
options="{'no_create': 1}"
/>
<field name="currency_id" invisible="1" />
<field name="amount" string="Montant emprunté" />
</group>
</group>
<separator string="Description" />
<field name="comment" />
<separator string="Conditions suspensives" />
<field name="suspensive_condition_ids" />
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" />
<field name="activity_ids" />
<field name="message_ids" />
</div>
</form>
</field>
</record>
<!-- Search -->
<record id="financial_contract_search_view" model="ir.ui.view">
<field name="name">financial.contract.search</field>
......@@ -95,22 +90,8 @@
string="Statut"
context="{'group_by': 'state'}"
/>
<filter
string="Type d'outil"
name="group_toll"
context="{'group_by':'tool'}"
/>
</group>
</search>
</field>
</record>
<!--
Actions
-->
<!-- All -->
<record model="ir.actions.act_window" id="financial_contract_action">
<field name="name">Tous les contrats</field>
<field name="res_model">financial.contract</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>
<?xml version="1.0" ?>
<!-- Copyright 2024 Le Filament
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<!-- Search -->
<record model="ir.ui.view" id="financial_product_category_search_view">
<field name="name">financial.product.category.search</field>
<field name="model">financial.product.category</field>
<field name="arch" type="xml">
<search>
<field name="name" />
<filter
string="Archivé"
name="inactive"
domain="[('active','=',False)]"
/>
<filter
string="Tous"
name="all"
domain="['|', ('active','=',False), ('active','=',True)]"
/>
</search>
</field>
</record>
<!-- Tree -->
<record model="ir.ui.view" id="financial_product_category_tree_view">
<field name="name">financial.product.category.tree</field>
<field name="model">financial.product.category</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="active" invisible="1" />
<field name="company_id" />
</tree>
</field>
</record>
<!-- Form -->
<record model="ir.ui.view" id="financial_product_category_form_view">
<field name="name">financial.product.category.form</field>
<field name="model">financial.product.category</field>
<field name="arch" type="xml">
<form>
<sheet>
<field name="active" invisible="1" />
<widget
name="web_ribbon"
title="Archived"
bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<!-- Title -->
<div class="oe_title">
<label for="name" string="Nom" />
<h1>
<field
name="name"
default_focus="1"
placeholder="Nom du produit"
/>
</h1>
</div>
<group>
<group>
<field name="company_id" />
</group>
</group>
<!-- <separator string="Produits" />-->
<!-- <field name="product_ids" readonly="1" />-->
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record
model="ir.actions.act_window"
id="financial_product_category_act_window"
>
<field name="name">Gammes de produits</field>
<field name="res_model">financial.product.category</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>
......@@ -5,9 +5,11 @@
<field name="name">financial.product.template.tree</field>
<field name="model">financial.product.template</field>
<field name="arch" type="xml">
<tree>
<tree create="0" edit="0" delete="0">
<field name="name" />
<field name="tool" />
<field name="category_id" />
<field name="date_start" />
<field name="date_end" />
<field
name="company_id"
options="{'no_create': 1, 'no_edit': 1}"
......@@ -23,6 +25,7 @@
<field name="model">financial.product.template</field>
<field name="arch" type="xml">
<form>
<header />
<sheet>
<field name="active" invisible="1" />
<widget
......@@ -38,14 +41,19 @@
<field
name="name"
default_focus="1"
placeholder="Nom de la gamme"
placeholder="Nom du produit"
/>
</h1>
</div>
<!-- Product Type -->
<group>
<group>
<field name="tool" widget="radio" />
<field
name="category_id"
options="{'no_create': 1, 'no_edit': 1}"
/>
<field name="date_start" />
<field name="date_end" />
</group>
<group>
<field
......@@ -60,43 +68,10 @@
<page string="Description" name="description">
<field name="description" />
</page>
<page
string="Conditions suspensives"
name="suspensive_condition"
>
<field
name="suspensive_condition_ids"
context="{'default_product_id': active_id}"
>
<tree editable="top">
<field name="product_id" invisible="1" />
<field
name="condition_id"
options="{'no_create': 1, 'no_edit': 1}"
/>
<field name="condition_comment" />
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" />
<field name="activity_ids" />
<field name="message_ids" />
</div>
</form>
</field>
</record>
<!-- Action -->
<record
model="ir.actions.act_window"
id="financial_product_template_act_window"
>
<field name="name">Catalogue</field>
<field name="res_model">financial.product.template</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>
......@@ -9,18 +9,10 @@
/>
<!-- Menu -->
<menuitem
id="menu_financial_contract_all"
name="Tous les contrats"
parent="financial_contract_menu_root"
action="financial_contract_action"
sequence="10"
/>
<menuitem
id="menu_financial_product_template"
name="Catalogue"
parent="financial_contract_menu_root"
action="financial_product_template_act_window"
sequence="100"
/>
......@@ -31,6 +23,13 @@
parent="financial_contract_menu_root"
sequence="100"
/>
<menuitem
id="menu_financial_product_category"
name="Gammes de produits"
parent="menu_financial_contract_configuration"
action="financial_product_category_act_window"
sequence="10"
/>
<menuitem
id="menu_financial_suspensive_condition"
name="Conditions suspensives"
......@@ -53,6 +52,4 @@
sequence="40"
/>
</odoo>
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023- Le Filament (https://le-filament.com)
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<!-- Form View -->
<record id="res_partner_financial_contract_form" model="ir.ui.view">
<field name="name">res.partner.financial.contract.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button
name="action_view_contract"
class="oe_stat_button"
icon="fa-file-text-o"
attrs="{'invisible': [('financial_contract_count', '=', 0)]}"
type="object"
>
<field
name="financial_contract_count"
widget="statinfo"
string="Contrat(s)"
/>
</button>
</xpath>
<xpath expr="//notebook" position="inside">
<page name="contracts" string="Contracts">
<field name="financial_contract_ids" readonly="1" />
</page>
</xpath>
</field>
</record>
</odoo>
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter