[14.0][MIG] agreement_legal (Version 12.0 to 14.0)

[MIG] Black & Cleanup

[IMP] Reviewer Requested Changes

[IMP] Black

[IMP] Reviewer Suggestion

[FIX] Tests

[FIX] Multiple Issues

- Added 'is_old_version' field to better display old versions. Before these were marked as inactive therefore not showing in the agreement.
- 'is_template' field now copies when making a template revision or copying a template.
- New Versions now retain original create date.
- Moved version/revision and created on/by fields out of footer to top in order to have the save buttons when creating children.
- Moved demo data out of data folder into the demo.xml

[FIX] demo data

[FIX] Revert back to only migration

[FIX] Report dynamic field rendering

[FIX] Test
This commit is contained in:
Patrick Wilson
2021-05-04 11:38:03 -06:00
parent 1205bb7717
commit 5736d92ace
52 changed files with 2065 additions and 898 deletions

View File

@@ -1,12 +1,4 @@
# Copyright (C) 2018 - TODAY, Pavlov Media # Copyright (C) 2018 - TODAY, Pavlov Media
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, SUPERUSER_ID
from . import models from . import models
def post_init_agreement_legal(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, dict())
cr.execute('UPDATE agreement SET stage_id = %s WHERE stage_id IS NULL;',
(env.ref('agreement_legal.agreement_stage_new').id,))
return True

View File

@@ -11,7 +11,7 @@
"website": "https://github.com/OCA/contract", "website": "https://github.com/OCA/contract",
"category": "Partner", "category": "Partner",
"license": "AGPL-3", "license": "AGPL-3",
"version": "12.0.2.0.1", "version": "14.0.1.0.0",
"depends": ["contacts", "agreement", "product"], "depends": ["contacts", "agreement", "product"],
"data": [ "data": [
"data/ir_sequence.xml", "data/ir_sequence.xml",
@@ -36,14 +36,8 @@
"views/agreement.xml", "views/agreement.xml",
"views/menu.xml", "views/menu.xml",
], ],
"demo": [ "demo": ["demo/demo.xml"],
"demo/demo.xml"
],
"post_init_hook": "post_init_agreement_legal",
"application": True, "application": True,
"development_status": "Beta", "development_status": "Beta",
"maintainers": [ "maintainers": ["max3903", "ygol"],
"max3903",
"ygol"
],
} }

View File

@@ -1,4 +1,3 @@
<?xml version="1.0"?>
<odoo> <odoo>
<record id="agreement_stage_new" model="agreement.stage"> <record id="agreement_stage_new" model="agreement.stage">

View File

@@ -1,4 +1,3 @@
<?xml version="1.0"?>
<odoo> <odoo>
<record id="agreement_type_agreement" model="agreement.type"> <record id="agreement_type_agreement" model="agreement.type">

View File

@@ -1,146 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- <!--
© 2019 Ygol Internetwork (yves@ygol.com) © 2019 Ygol Internetwork (yves@ygol.com)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
--> -->
<odoo noupdate="1"> <odoo noupdate="1">
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market1')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market1')]"
/>
</function> </function>
<value eval="{'noupdate': False}" /> <value eval="{'noupdate': False}" />
</function> </function>
<record id="agreement.market1" model="agreement"> <record id="agreement.market1" model="agreement">
<field name="description">Hardware IT (C2C-IT0042)</field> <field name="description">Hardware IT (C2C-IT0042)</field>
<field name="agreement_type_id">1</field> <field name="agreement_type_id" ref="agreement_type_agreement" />
</record> </record>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market1')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market1')]"
/>
</function> </function>
<value eval="{'noupdate': True}" /> <value eval="{'noupdate': True}" />
</function> </function>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market2')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market2')]"
/>
</function> </function>
<value eval="{'noupdate': False}" /> <value eval="{'noupdate': False}" />
</function> </function>
<record id="agreement.market2" model="agreement"> <record id="agreement.market2" model="agreement">
<field name="description">Fiber access office Lausanne (C2C-IT0043)</field> <field name="description">Fiber access office Lausanne (C2C-IT0043)</field>
<field name="agreement_type_id">2</field> <field name="agreement_type_id" ref="agreement_type_contract" />
</record> </record>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market2')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market2')]"
/>
</function> </function>
<value eval="{'noupdate': True}" /> <value eval="{'noupdate': True}" />
</function> </function>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market3')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market3')]"
/>
</function> </function>
<value eval="{'noupdate': False}" /> <value eval="{'noupdate': False}" />
</function> </function>
<record id="agreement.market3" model="agreement"> <record id="agreement.market3" model="agreement">
<field name="description">Vétérinaire (AGR-VETO001)</field> <field name="description">Vétérinaire (AGR-VETO001)</field>
<field name="agreement_type_id">3</field> <field name="agreement_type_id" ref="agreement_type_loi" />
</record> </record>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market3')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market3')]"
/>
</function> </function>
<value eval="{'noupdate': True}" /> <value eval="{'noupdate': True}" />
</function> </function>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market4')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market4')]"
/>
</function> </function>
<value eval="{'noupdate': False}" /> <value eval="{'noupdate': False}" />
</function> </function>
<record id="agreement.market4" model="agreement"> <record id="agreement.market4" model="agreement">
<field name="description">Wazo IPBX deployment and maintenance (AGR-TEL001)</field> <field
<field name="agreement_type_id">3</field> name="description"
>Wazo IPBX deployment and maintenance (AGR-TEL001)</field>
<field name="agreement_type_id" ref="agreement_type_loi" />
</record> </record>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market4')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market4')]"
/>
</function> </function>
<value eval="{'noupdate': True}" /> <value eval="{'noupdate': True}" />
</function> </function>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market5')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market5')]"
/>
</function> </function>
<value eval="{'noupdate': False}" /> <value eval="{'noupdate': False}" />
</function> </function>
<record id="agreement.market5" model="agreement"> <record id="agreement.market5" model="agreement">
<field name="description">SIP Phones supply (BUY-VOIP012)</field> <field name="description">SIP Phones supply (BUY-VOIP012)</field>
<field name="agreement_type_id">1</field> <field name="agreement_type_id" ref="agreement_type_loi" />
</record> </record>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market5')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market5')]"
/>
</function> </function>
<value eval="{'noupdate': True}" /> <value eval="{'noupdate': True}" />
</function> </function>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market6')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market6')]"
/>
</function> </function>
<value eval="{'noupdate': False}" /> <value eval="{'noupdate': False}" />
</function> </function>
<record id="agreement.market6" model="agreement"> <record id="agreement.market6" model="agreement">
<field name="description">SIP-ISDN gateways (BUY-VOIP013)</field> <field name="description">SIP-ISDN gateways (BUY-VOIP013)</field>
<field name="agreement_type_id">2</field> <field name="agreement_type_id" ref="agreement_type_contract" />
</record> </record>
<function name="write" model="ir.model.data"> <function name="write" model="ir.model.data">
<function name="search" model="ir.model.data"> <function name="search" model="ir.model.data">
<value <value eval="[('module', '=', 'agreement'), ('name', '=', 'market6')]" />
eval="[('module', '=', 'agreement'), ('name', '=', 'market6')]"
/>
</function> </function>
<value eval="{'noupdate': True}" /> <value eval="{'noupdate': True}" />
</function> </function>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1"> <odoo noupdate="1">
<!-- Sequence for agreement --> <!-- Sequence for agreement -->
@@ -7,7 +6,7 @@
<field name="code">agreement</field> <field name="code">agreement</field>
<field name="prefix">AG</field> <field name="prefix">AG</field>
<field name="padding">3</field> <field name="padding">3</field>
<field name="company_id" eval="False"/> <field name="company_id" eval="False" />
</record> </record>
</odoo> </odoo>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<record id="agreement" model="ir.module.category"> <record id="agreement" model="ir.module.category">

View File

@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- <!--
© 2019 Ygol Internetwork (yves@ygol.com) © 2019 Ygol Internetwork (yves@ygol.com)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
--> -->
<odoo noupdate="1"> <odoo noupdate="1">
<record id="agreement.market1" model="agreement"> <record id="agreement.market1" model="agreement">
<field name="description">Hardware IT (C2C-IT0042)</field> <field name="description">Hardware IT (C2C-IT0042)</field>
<field name="agreement_type_id" ref="agreement_type_agreement"/> <field name="agreement_type_id" ref="agreement_type_agreement" />
</record> </record>
<record id="agreement.market2" model="agreement"> <record id="agreement.market2" model="agreement">
<field name="description">Fiber access office Lausanne (C2C-IT0043)</field> <field name="description">Fiber access office Lausanne (C2C-IT0043)</field>
<field name="agreement_type_id" ref="agreement_type_contract"/> <field name="agreement_type_id" ref="agreement_type_contract" />
</record> </record>
<record id="agreement.market3" model="agreement"> <record id="agreement.market3" model="agreement">
<field name="description">Vétérinaire (AGR-VETO001)</field> <field name="description">Vétérinaire (AGR-VETO001)</field>
<field name="agreement_type_id" ref="agreement_type_loi"/> <field name="agreement_type_id" ref="agreement_type_loi" />
</record> </record>
<record id="agreement.market4" model="agreement"> <record id="agreement.market4" model="agreement">
<field name="description">Wazo IPBX deployment and maintenance (AGR-TEL001)</field> <field
<field name="agreement_type_id" ref="agreement_type_loi"/> name="description"
>Wazo IPBX deployment and maintenance (AGR-TEL001)</field>
<field name="agreement_type_id" ref="agreement_type_loi" />
</record> </record>
<record id="agreement.market5" model="agreement"> <record id="agreement.market5" model="agreement">
<field name="description">SIP Phones supply (BUY-VOIP012)</field> <field name="description">SIP Phones supply (BUY-VOIP012)</field>
<field name="agreement_type_id" ref="agreement_type_agreement"/> <field name="agreement_type_id" ref="agreement_type_agreement" />
</record> </record>
<record id="agreement.market6" model="agreement"> <record id="agreement.market6" model="agreement">
<field name="is_template">True</field> <field name="is_template">True</field>
<field name="description">SIP-ISDN gateways (BUY-VOIP013)</field> <field name="description">SIP-ISDN gateways (BUY-VOIP013)</field>
<field name="agreement_type_id" ref="agreement_legal.agreement_type_contract"/> <field name="agreement_type_id" ref="agreement_legal.agreement_type_contract" />
</record> </record>
</odoo> </odoo>

View File

@@ -7,15 +7,15 @@ msgstr ""
"Project-Id-Version: Odoo Server 12.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-24 16:40+0000\n" "POT-Creation-Date: 2019-03-24 16:40+0000\n"
"PO-Revision-Date: 2021-01-04 11:44+0000\n" "PO-Revision-Date: 2019-09-12 11:23+0000\n"
"Last-Translator: Rémi <remi@le-filament.com>\n" "Last-Translator: Yves Goldberg <admin@ygol.com>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: fr\n" "Language: fr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.3.2\n" "X-Generator: Weblate 3.8\n"
#. module: agreement_legal #. module: agreement_legal
#. openerp-web #. openerp-web
@@ -338,6 +338,8 @@ msgstr "Informations sur la société"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_partner_id #: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_partner_id
#, fuzzy
#| msgid "Company Contact"
msgid "Company's Partner" msgid "Company's Partner"
msgstr "Contact de la société" msgstr "Contact de la société"
@@ -553,9 +555,10 @@ msgstr "Domaine"
#. openerp-web #. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83
#, python-format #, fuzzy, python-format
#| msgid "Domain"
msgid "Domain node" msgid "Domain node"
msgstr "Nœud de domaine" msgstr "Domaine"
#. module: agreement_legal #. module: agreement_legal
#: selection:agreement,state:0 #: selection:agreement,state:0
@@ -892,8 +895,10 @@ msgstr "Entretien"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement #: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement
#, fuzzy
#| msgid "Agreements"
msgid "Manage Agreements" msgid "Manage Agreements"
msgstr "Gérer les Accords" msgstr "Accords"
#. module: agreement_legal #. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form #: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form
@@ -986,12 +991,12 @@ msgstr "Adresse de notification"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__expiration_notice #: model:ir.model.fields,help:agreement_legal.field_agreement__expiration_notice
msgid "Number of Days before expiration to be notified." msgid "Number of Days before expiration to be notified."
msgstr "Nombre de jours avant l'expiration pour être notifié." msgstr "Nombre de jours avant expiration à notifier."
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__change_notice #: model:ir.model.fields,help:agreement_legal.field_agreement__change_notice
msgid "Number of Days to be notified before changes." msgid "Number of Days to be notified before changes."
msgstr "Nombre de jours pour être notifié avant les modifications." msgstr "Nombre de jours à notifier avant les modifications."
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__term #: model:ir.model.fields,help:agreement_legal.field_agreement__term
@@ -1350,8 +1355,10 @@ msgstr ""
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__agreement_type_id #: model:ir.model.fields,help:agreement_legal.field_agreement__agreement_type_id
#, fuzzy
#| msgid "Select the type of agreement."
msgid "Select the type of agreement" msgid "Select the type of agreement"
msgstr "Sélectionner le type d'accord" msgstr "Sélectionnez le type d'accord."
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__assigned_user_id #: model:ir.model.fields,help:agreement_legal.field_agreement__assigned_user_id

View File

@@ -553,6 +553,7 @@ msgstr "Domínio"
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83
#, fuzzy, python-format #, fuzzy, python-format
#| msgid "Domain"
msgid "Domain node" msgid "Domain node"
msgstr "Domínio" msgstr "Domínio"
@@ -885,6 +886,7 @@ msgstr "Manutenção"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement #: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement
#, fuzzy #, fuzzy
#| msgid "Agreements"
msgid "Manage Agreements" msgid "Manage Agreements"
msgstr "Acordos" msgstr "Acordos"

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 12.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2020-11-06 08:08+0000\n" "PO-Revision-Date: 2020-08-10 16:59+0000\n"
"Last-Translator: Eder Brito <britoederr@gmail.com>\n" "Last-Translator: Fernando Colus <fcolus1@gmail.com>\n"
"Language-Team: none\n" "Language-Team: none\n"
"Language: pt_BR\n" "Language: pt_BR\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -97,17 +97,17 @@ msgstr "Acordo"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model,name:agreement_legal.model_agreement_appendix #: model:ir.model,name:agreement_legal.model_agreement_appendix
msgid "Agreement Appendices" msgid "Agreement Appendices"
msgstr "Apêndices do acordo" msgstr "Adendos do acordo"
#. module: agreement_legal #. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.agreement_clause_search_view #: model_terms:ir.ui.view,arch_db:agreement_legal.agreement_clause_search_view
msgid "Agreement Clause Search" msgid "Agreement Clause Search"
msgstr "Pesquisa de Cláusulas do Acordo" msgstr "Busca de cláusulas"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model,name:agreement_legal.model_agreement_clause #: model:ir.model,name:agreement_legal.model_agreement_clause
msgid "Agreement Clauses" msgid "Agreement Clauses"
msgstr "Cláusulas do Acordo" msgstr "Cláusulas do acordo"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.actions.act_window,name:agreement_legal.partner_agreement_action_increasetype #: model:ir.actions.act_window,name:agreement_legal.partner_agreement_action_increasetype
@@ -421,7 +421,7 @@ msgstr "Criar um acordo quando a venda é confirmada."
#. module: agreement_legal #. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form #: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form
msgid "Create an agreement when the sales order is confirmed" msgid "Create an agreement when the sales order is confirmed"
msgstr "Crie um acordo quando a venda é confirmada" msgstr "Crie o acordo quando a venda é confirmada"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_appendix__create_uid #: model:ir.model.fields,field_description:agreement_legal.field_agreement_appendix__create_uid
@@ -457,7 +457,7 @@ msgstr "Moeda"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.ui.menu,name:agreement_legal.agreement_dashboard #: model:ir.ui.menu,name:agreement_legal.agreement_dashboard
msgid "Dashboard" msgid "Dashboard"
msgstr "Dashboard" msgstr "Painel"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__termination_requested #: model:ir.model.fields,help:agreement_legal.field_agreement__termination_requested
@@ -599,7 +599,7 @@ msgstr "Editar Domínio"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_contact_email #: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_contact_email
msgid "Email" msgid "Email"
msgstr "E-mail" msgstr "Email"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__end_date #: model:ir.model.fields,field_description:agreement_legal.field_agreement__end_date
@@ -632,7 +632,7 @@ msgstr "Expressão do Campo"
#. module: agreement_legal #. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form #: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form
msgid "Field Service" msgid "Field Service"
msgstr "Serviço de Campo" msgstr "Serviço em Campo"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__signed_contract_filename #: model:ir.model.fields,field_description:agreement_legal.field_agreement__signed_contract_filename

View File

@@ -336,6 +336,7 @@ msgstr "Empresa - Informações"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_partner_id #: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_partner_id
#, fuzzy #, fuzzy
#| msgid "Company Contact"
msgid "Company's Partner" msgid "Company's Partner"
msgstr "Empresa - Contacto" msgstr "Empresa - Contacto"
@@ -553,6 +554,7 @@ msgstr "Domínio"
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83
#, fuzzy, python-format #, fuzzy, python-format
#| msgid "Domain"
msgid "Domain node" msgid "Domain node"
msgstr "Domínio" msgstr "Domínio"
@@ -886,6 +888,7 @@ msgstr "Manutenção"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement #: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement
#, fuzzy #, fuzzy
#| msgid "Agreements"
msgid "Manage Agreements" msgid "Manage Agreements"
msgstr "Contratos" msgstr "Contratos"

View File

@@ -336,6 +336,7 @@ msgstr "公司信息"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_partner_id #: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_partner_id
#, fuzzy #, fuzzy
#| msgid "Company Contact"
msgid "Company's Partner" msgid "Company's Partner"
msgstr "公司联系人" msgstr "公司联系人"
@@ -551,6 +552,7 @@ msgstr "域"
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:79
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83 #: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:83
#, fuzzy, python-format #, fuzzy, python-format
#| msgid "Domain"
msgid "Domain node" msgid "Domain node"
msgstr "域" msgstr "域"
@@ -880,6 +882,7 @@ msgstr "维护"
#. module: agreement_legal #. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement #: model:ir.model.fields,field_description:agreement_legal.field_res_config_settings__module_fieldservice_agreement
#, fuzzy #, fuzzy
#| msgid "Agreements"
msgid "Manage Agreements" msgid "Manage Agreements"
msgstr "协议" msgstr "协议"

View File

@@ -1,10 +0,0 @@
# Copyright (C) 2020 Serpent Consulting Services
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
def migrate(env, version):
if not version:
return
env.execute("UPDATE agreement_stage SET stage_type = 'agreement' "
"WHERE stage_type IS NULL;")

View File

@@ -7,129 +7,144 @@ from odoo import _, api, fields, models
class Agreement(models.Model): class Agreement(models.Model):
_inherit = "agreement" _inherit = "agreement"
# General
name = fields.Char(string="Title", required=True) name = fields.Char(string="Title", required=True)
version = fields.Integer( version = fields.Integer(
string="Version", string="Version",
default=1, default=1,
copy=False, copy=False,
help="The versions are used to keep track of document history and " help="The versions are used to keep track of document history and "
"previous versions can be referenced.") "previous versions can be referenced.",
)
revision = fields.Integer( revision = fields.Integer(
string="Revision", string="Revision",
default=0, default=0,
copy=False, copy=False,
help="The revision will increase with every save event.") help="The revision will increase with every save event.",
)
description = fields.Text( description = fields.Text(
string="Description", string="Description", tracking=True, help="Description of the agreement"
track_visibility="onchange", )
help="Description of the agreement")
dynamic_description = fields.Text( dynamic_description = fields.Text(
compute="_compute_dynamic_description", compute="_compute_dynamic_description",
string="Dynamic Description", string="Dynamic Description",
help="Compute dynamic description") help="Compute dynamic description",
)
start_date = fields.Date( start_date = fields.Date(
string="Start Date", string="Start Date", tracking=True, help="When the agreement starts."
track_visibility="onchange", )
help="When the agreement starts.")
end_date = fields.Date( end_date = fields.Date(
string="End Date", string="End Date", tracking=True, help="When the agreement ends."
track_visibility="onchange", )
help="When the agreement ends.")
color = fields.Integer(string="Color") color = fields.Integer(string="Color")
active = fields.Boolean( active = fields.Boolean(
string="Active", string="Active",
default=True, default=True,
help="If unchecked, it will allow you to hide the agreement without " help="If unchecked, it will allow you to hide the agreement without "
"removing it.") "removing it.",
)
company_signed_date = fields.Date( company_signed_date = fields.Date(
string="Signed on", string="Signed on",
track_visibility="onchange", tracking=True,
help="Date the contract was signed by Company.") help="Date the contract was signed by Company.",
)
partner_signed_date = fields.Date( partner_signed_date = fields.Date(
string="Signed on (Partner)", string="Signed on (Partner)",
track_visibility="onchange", tracking=True,
help="Date the contract was signed by the Partner.") help="Date the contract was signed by the Partner.",
)
term = fields.Integer( term = fields.Integer(
string="Term (Months)", string="Term (Months)",
track_visibility="onchange", tracking=True,
help="Number of months this agreement/contract is in effect with the " help="Number of months this agreement/contract is in effect with the "
"partner.") "partner.",
)
expiration_notice = fields.Integer( expiration_notice = fields.Integer(
string="Exp. Notice (Days)", string="Exp. Notice (Days)",
track_visibility="onchange", tracking=True,
help="Number of Days before expiration to be notified.") help="Number of Days before expiration to be notified.",
)
change_notice = fields.Integer( change_notice = fields.Integer(
string="Change Notice (Days)", string="Change Notice (Days)",
track_visibility="onchange", tracking=True,
help="Number of Days to be notified before changes.") help="Number of Days to be notified before changes.",
)
special_terms = fields.Text( special_terms = fields.Text(
string="Special Terms", string="Special Terms",
track_visibility="onchange", tracking=True,
help="Any terms that you have agreed to and want to track on the " help="Any terms that you have agreed to and want to track on the "
"agreement/contract.") "agreement/contract.",
)
dynamic_special_terms = fields.Text( dynamic_special_terms = fields.Text(
compute="_compute_dynamic_special_terms", compute="_compute_dynamic_special_terms",
string="Dynamic Special Terms", string="Dynamic Special Terms",
help="Compute dynamic special terms") help="Compute dynamic special terms",
)
code = fields.Char( code = fields.Char(
string="Reference", string="Reference",
required=True, required=True,
default=lambda self: _("New"), default=lambda self: _("New"),
track_visibility="onchange", tracking=True,
copy=False, copy=False,
help="ID used for internal contract tracking.") help="ID used for internal contract tracking.",
)
increase_type_id = fields.Many2one( increase_type_id = fields.Many2one(
"agreement.increasetype", "agreement.increasetype",
string="Increase Type", string="Increase Type",
track_visibility="onchange", tracking=True,
help="The amount that certain rates may increase.") help="The amount that certain rates may increase.",
)
termination_requested = fields.Date( termination_requested = fields.Date(
string="Termination Requested Date", string="Termination Requested Date",
track_visibility="onchange", tracking=True,
help="Date that a request for termination was received.") help="Date that a request for termination was received.",
)
termination_date = fields.Date( termination_date = fields.Date(
string="Termination Date", string="Termination Date",
track_visibility="onchange", tracking=True,
help="Date that the contract was terminated.") help="Date that the contract was terminated.",
reviewed_date = fields.Date( )
string="Reviewed Date", track_visibility="onchange") reviewed_date = fields.Date(string="Reviewed Date", tracking=True)
reviewed_user_id = fields.Many2one( reviewed_user_id = fields.Many2one("res.users", string="Reviewed By", tracking=True)
"res.users", string="Reviewed By", track_visibility="onchange") approved_date = fields.Date(string="Approved Date", tracking=True)
approved_date = fields.Date( approved_user_id = fields.Many2one("res.users", string="Approved By", tracking=True)
string="Approved Date", track_visibility="onchange")
approved_user_id = fields.Many2one(
"res.users", string="Approved By", track_visibility="onchange")
currency_id = fields.Many2one("res.currency", string="Currency") currency_id = fields.Many2one("res.currency", string="Currency")
partner_id = fields.Many2one( partner_id = fields.Many2one(
"res.partner", "res.partner",
string="Partner", string="Partner",
required=False, required=False,
copy=True, copy=True,
help="The customer or vendor this agreement is related to.") help="The customer or vendor this agreement is related to.",
)
partner_contact_id = fields.Many2one( partner_contact_id = fields.Many2one(
"res.partner", "res.partner",
string="Partner Contact", string="Partner Contact",
copy=True, copy=True,
help="The primary partner contact (If Applicable).") help="The primary partner contact (If Applicable).",
)
partner_contact_phone = fields.Char( partner_contact_phone = fields.Char(
related="partner_contact_id.phone", string="Partner Phone") related="partner_contact_id.phone", string="Partner Phone"
)
partner_contact_email = fields.Char( partner_contact_email = fields.Char(
related="partner_contact_id.email", string="Partner Email") related="partner_contact_id.email", string="Partner Email"
)
company_contact_id = fields.Many2one( company_contact_id = fields.Many2one(
"res.partner", "res.partner",
string="Company Contact", string="Company Contact",
copy=True, copy=True,
help="The primary contact in the company.") help="The primary contact in the company.",
)
company_contact_phone = fields.Char( company_contact_phone = fields.Char(
related="company_contact_id.phone", string="Phone") related="company_contact_id.phone", string="Phone"
)
company_contact_email = fields.Char( company_contact_email = fields.Char(
related="company_contact_id.email", string="Email") related="company_contact_id.email", string="Email"
)
use_parties_content = fields.Boolean( use_parties_content = fields.Boolean(
string="Use parties content", string="Use parties content", help="Use custom content for parties"
help="Use custom content for parties") )
company_partner_id = fields.Many2one( company_partner_id = fields.Many2one(
related="company_id.partner_id", string="Company's Partner") related="company_id.partner_id", string="Company's Partner"
)
def _get_default_parties(self): def _get_default_parties(self):
deftext = """ deftext = """
@@ -158,147 +173,156 @@ class Agreement(models.Model):
parties = fields.Html( parties = fields.Html(
string="Parties", string="Parties",
track_visibility="onchange", tracking=True,
default=_get_default_parties, default=_get_default_parties,
help="Parties of the agreement") help="Parties of the agreement",
)
dynamic_parties = fields.Html( dynamic_parties = fields.Html(
compute="_compute_dynamic_parties", compute="_compute_dynamic_parties",
string="Dynamic Parties", string="Dynamic Parties",
help="Compute dynamic parties") help="Compute dynamic parties",
)
agreement_type_id = fields.Many2one( agreement_type_id = fields.Many2one(
track_visibility="onchange", tracking=True,
) )
agreement_subtype_id = fields.Many2one( agreement_subtype_id = fields.Many2one(
"agreement.subtype", "agreement.subtype",
string="Agreement Sub-type", string="Agreement Sub-type",
track_visibility="onchange", tracking=True,
help="Select the sub-type of this agreement. Sub-Types are related to " help="Select the sub-type of this agreement. Sub-Types are related to "
"agreement types.") "agreement types.",
product_ids = fields.Many2many( )
"product.template", string="Products & Services") product_ids = fields.Many2many("product.template", string="Products & Services")
assigned_user_id = fields.Many2one( assigned_user_id = fields.Many2one(
"res.users", "res.users",
string="Assigned To", string="Assigned To",
track_visibility="onchange", tracking=True,
help="Select the user who manages this agreement.") help="Select the user who manages this agreement.",
)
company_signed_user_id = fields.Many2one( company_signed_user_id = fields.Many2one(
"res.users", "res.users",
string="Signed By", string="Signed By",
track_visibility="onchange", tracking=True,
help="The user at our company who authorized/signed the agreement or " help="The user at our company who authorized/signed the agreement or "
"contract.") "contract.",
)
partner_signed_user_id = fields.Many2one( partner_signed_user_id = fields.Many2one(
"res.partner", "res.partner",
string="Signed By (Partner)", string="Signed By (Partner)",
track_visibility="onchange", tracking=True,
help="Contact on the account that signed the agreement/contract.") help="Contact on the account that signed the agreement/contract.",
)
parent_agreement_id = fields.Many2one( parent_agreement_id = fields.Many2one(
"agreement", "agreement",
string="Parent Agreement", string="Parent Agreement",
help="Link this agreement to a parent agreement. For example if this " help="Link this agreement to a parent agreement. For example if this "
"agreement is an amendment to another agreement. This list will " "agreement is an amendment to another agreement. This list will "
"only show other agreements related to the same account.") "only show other agreements related to the same account.",
)
renewal_type_id = fields.Many2one( renewal_type_id = fields.Many2one(
"agreement.renewaltype", "agreement.renewaltype",
string="Renewal Type", string="Renewal Type",
track_visibility="onchange", tracking=True,
help="Describes what happens after the contract expires.") help="Describes what happens after the contract expires.",
)
recital_ids = fields.One2many( recital_ids = fields.One2many(
"agreement.recital", "agreement_id", string="Recitals", copy=True) "agreement.recital", "agreement_id", string="Recitals", copy=True
)
sections_ids = fields.One2many( sections_ids = fields.One2many(
"agreement.section", "agreement_id", string="Sections", copy=True) "agreement.section", "agreement_id", string="Sections", copy=True
clauses_ids = fields.One2many( )
"agreement.clause", "agreement_id", string="Clauses") clauses_ids = fields.One2many("agreement.clause", "agreement_id", string="Clauses")
appendix_ids = fields.One2many( appendix_ids = fields.One2many(
"agreement.appendix", "agreement_id", string="Appendices", copy=True) "agreement.appendix", "agreement_id", string="Appendices", copy=True
)
previous_version_agreements_ids = fields.One2many( previous_version_agreements_ids = fields.One2many(
"agreement", "agreement",
"parent_agreement_id", "parent_agreement_id",
string="Previous Versions", string="Previous Versions",
copy=False, copy=False,
domain=[("active", "=", False)]) domain=[("active", "=", False)],
)
child_agreements_ids = fields.One2many( child_agreements_ids = fields.One2many(
"agreement", "agreement",
"parent_agreement_id", "parent_agreement_id",
string="Child Agreements", string="Child Agreements",
copy=False, copy=False,
domain=[("active", "=", True)]) domain=[("active", "=", True)],
)
line_ids = fields.One2many( line_ids = fields.One2many(
"agreement.line", "agreement.line", "agreement_id", string="Products/Services", copy=False
"agreement_id", )
string="Products/Services",
copy=False)
state = fields.Selection( state = fields.Selection(
[("draft", "Draft"), ("active", "Active"), ("inactive", "Inactive")], [("draft", "Draft"), ("active", "Active"), ("inactive", "Inactive")],
default="draft", default="draft",
track_visibility="always") tracking=True,
)
notification_address_id = fields.Many2one( notification_address_id = fields.Many2one(
"res.partner", "res.partner",
string="Notification Address", string="Notification Address",
help="The address to send notificaitons to, if different from " help="The address to send notificaitons to, if different from "
"customer address.(Address Type = Other)") "customer address.(Address Type = Other)",
)
signed_contract_filename = fields.Char(string="Filename") signed_contract_filename = fields.Char(string="Filename")
signed_contract = fields.Binary( signed_contract = fields.Binary(string="Signed Document", tracking=True)
string="Signed Document", track_visibility="always")
field_id = fields.Many2one( field_id = fields.Many2one(
"ir.model.fields", "ir.model.fields",
string="Field", string="Field",
help="""Select target field from the related document model. If it is a help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the relationship field you will be able to select a target field at the
destination of the relationship.""") destination of the relationship.""",
)
sub_object_id = fields.Many2one( sub_object_id = fields.Many2one(
"ir.model", "ir.model",
string="Sub-model", string="Sub-model",
help="""When a relationship field is selected as first field, this help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""") field shows the document model the relationship goes to.""",
)
sub_model_object_field_id = fields.Many2one( sub_model_object_field_id = fields.Many2one(
"ir.model.fields", "ir.model.fields",
string="Sub-field", string="Sub-field",
help="""When a relationship field is selected as first field, this help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document field lets you select the target field within the destination document
model (sub-model).""") model (sub-model).""",
)
default_value = fields.Char( default_value = fields.Char(
string="Default Value", string="Default Value",
help="Optional value to use if the target field is empty.") help="Optional value to use if the target field is empty.",
)
copyvalue = fields.Char( copyvalue = fields.Char(
string="Placeholder Expression", string="Placeholder Expression",
help="""Final placeholder expression, to be copy-pasted in the desired help="""Final placeholder expression, to be copy-pasted in the desired
template field.""") template field.""",
)
# compute the dynamic content for mako expression # compute the dynamic content for mako expression
@api.multi
def _compute_dynamic_description(self): def _compute_dynamic_description(self):
MailTemplates = self.env["mail.template"] MailTemplates = self.env["mail.template"]
for agreement in self: for agreement in self:
lang = agreement.partner_id.lang or "en_US" lang = agreement.partner_id.lang or "en_US"
description = MailTemplates.with_context( description = MailTemplates.with_context(lang=lang)._render_template(
lang=lang agreement.description, "agreement", [agreement.id]
)._render_template(
agreement.description, "agreement", agreement.id
) )
agreement.dynamic_description = description des = ""
for i in description:
des += description[i]
agreement.dynamic_description = des
@api.multi
def _compute_dynamic_parties(self): def _compute_dynamic_parties(self):
MailTemplates = self.env["mail.template"] MailTemplates = self.env["mail.template"]
for agreement in self: for agreement in self:
lang = agreement.partner_id.lang or "en_US" lang = agreement.partner_id.lang or "en_US"
parties = MailTemplates.with_context( parties = MailTemplates.with_context(lang=lang)._render_template(
lang=lang agreement.parties, "agreement", [agreement.id]
)._render_template(
agreement.parties, "agreement", agreement.id
) )
agreement.dynamic_parties = parties agreement.dynamic_parties = parties
@api.multi
def _compute_dynamic_special_terms(self): def _compute_dynamic_special_terms(self):
MailTemplates = self.env["mail.template"] MailTemplates = self.env["mail.template"]
for agreement in self: for agreement in self:
lang = agreement.partner_id.lang or "en_US" lang = agreement.partner_id.lang or "en_US"
special_terms = MailTemplates.with_context( special_terms = MailTemplates.with_context(lang=lang)._render_template(
lang=lang agreement.special_terms, "agreement", [agreement.id]
)._render_template(
agreement.special_terms, "agreement", agreement.id
) )
agreement.dynamic_special_terms = special_terms agreement.dynamic_special_terms = special_terms
@@ -309,22 +333,26 @@ class Agreement(models.Model):
self.sub_object_id = False self.sub_object_id = False
if self.field_id and not self.field_id.relation: if self.field_id and not self.field_id.relation:
self.copyvalue = "${{object.{} or {}}}".format( self.copyvalue = "${{object.{} or {}}}".format(
self.field_id.name, self.default_value or "''") self.field_id.name, self.default_value or "''"
)
self.sub_model_object_field_id = False self.sub_model_object_field_id = False
if self.field_id and self.field_id.relation: if self.field_id and self.field_id.relation:
self.sub_object_id = self.env["ir.model"].search( self.sub_object_id = self.env["ir.model"].search(
[("model", "=", self.field_id.relation)])[0] [("model", "=", self.field_id.relation)]
)[0]
if self.sub_model_object_field_id: if self.sub_model_object_field_id:
self.copyvalue = "${{object.{}.{} or {}}}".format( self.copyvalue = "${{object.{}.{} or {}}}".format(
self.field_id.name, self.field_id.name,
self.sub_model_object_field_id.name, self.sub_model_object_field_id.name,
self.default_value or "''") self.default_value or "''",
)
# Used for Kanban grouped_by view # Used for Kanban grouped_by view
@api.model @api.model
def _read_group_stage_ids(self, stages, domain, order): def _read_group_stage_ids(self, stages, domain, order):
stage_ids = self.env["agreement.stage"].search( stage_ids = self.env["agreement.stage"].search(
[('stage_type', '=', 'agreement')]) [("stage_type", "=", "agreement")]
)
return stage_ids return stage_ids
stage_id = fields.Many2one( stage_id = fields.Many2one(
@@ -332,12 +360,12 @@ class Agreement(models.Model):
string="Stage", string="Stage",
group_expand="_read_group_stage_ids", group_expand="_read_group_stage_ids",
help="Select the current stage of the agreement.", help="Select the current stage of the agreement.",
track_visibility="onchange", tracking=True,
index=True) index=True,
)
# Create New Version Button # Create New Version Button
@api.multi def create_new_version(self):
def create_new_version(self, vals):
for rec in self: for rec in self:
if not rec.state == "draft": if not rec.state == "draft":
# Make sure status is draft # Make sure status is draft
@@ -346,18 +374,18 @@ class Agreement(models.Model):
"name": "{} - OLD VERSION".format(rec.name), "name": "{} - OLD VERSION".format(rec.name),
"active": False, "active": False,
"parent_agreement_id": rec.id, "parent_agreement_id": rec.id,
"version": rec.version,
"code": rec.code + "-V" + str(rec.version),
} }
# Make a current copy and mark it as old # Make a current copy and mark it as old
rec.copy(default=default_vals) rec.copy(default=default_vals)
# Increment the Version # Increment the Version
rec.version = rec.version + 1 rec.version = rec.version + 1
# Reset revision to 0 since it's a new version
vals["revision"] = 0
return super(Agreement, self).write(vals)
def create_new_agreement(self): def create_new_agreement(self):
self.ensure_one()
default_vals = { default_vals = {
"name": "NEW", "name": "New",
"active": True, "active": True,
"version": 1, "version": 1,
"revision": 0, "revision": 0,
@@ -365,7 +393,7 @@ class Agreement(models.Model):
"stage_id": self.env.ref("agreement_legal.agreement_stage_new").id, "stage_id": self.env.ref("agreement_legal.agreement_stage_new").id,
} }
res = self.copy(default=default_vals) res = self.copy(default=default_vals)
res.sections_ids.mapped('clauses_ids').write({'agreement_id': res.id}) res.sections_ids.mapped("clauses_ids").write({"agreement_id": res.id})
return { return {
"res_model": "agreement", "res_model": "agreement",
"type": "ir.actions.act_window", "type": "ir.actions.act_window",
@@ -377,19 +405,12 @@ class Agreement(models.Model):
@api.model @api.model
def create(self, vals): def create(self, vals):
if vals.get("code", _("New")) == _("New"): if vals.get("code", _("New")) == _("New"):
vals["code"] = self.env["ir.sequence"].next_by_code( vals["code"] = self.env["ir.sequence"].next_by_code("agreement") or _("New")
"agreement" if not vals.get("stage_id"):
) or _("New") vals["stage_id"] = self.env.ref("agreement_legal.agreement_stage_new").id
if not vals.get('stage_id'): return super().create(vals)
vals["stage_id"] = \
self.env.ref("agreement_legal.agreement_stage_new").id
return super(Agreement, self).create(vals)
# Increments the revision on each save action # Increments the revision on each save action
@api.multi
def write(self, vals): def write(self, vals):
res = True vals["revision"] = self.revision + 1
for rec in self: return super().write(vals)
vals["revision"] = rec.revision + 1
res = super(Agreement, rec).write(vals)
return res

View File

@@ -13,21 +13,16 @@ class AgreementAppendix(models.Model):
title = fields.Char( title = fields.Char(
string="Title", string="Title",
required=True, required=True,
help="The title is displayed on the PDF." "The name is not.", help="The title is displayed on the PDF. The name is not.",
) )
sequence = fields.Integer( sequence = fields.Integer(string="Sequence", default=10)
string="Sequence",
default=10)
content = fields.Html(string="Content") content = fields.Html(string="Content")
dynamic_content = fields.Html( dynamic_content = fields.Html(
compute="_compute_dynamic_content", compute="_compute_dynamic_content",
string="Dynamic Content", string="Dynamic Content",
help="compute dynamic Content", help="compute dynamic Content",
) )
agreement_id = fields.Many2one( agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
"agreement",
string="Agreement",
ondelete="cascade")
active = fields.Boolean( active = fields.Boolean(
string="Active", string="Active",
default=True, default=True,
@@ -66,27 +61,29 @@ class AgreementAppendix(models.Model):
template field.""", template field.""",
) )
@api.onchange('field_id', 'sub_model_object_field_id', 'default_value') @api.onchange("field_id", "sub_model_object_field_id", "default_value")
def onchange_copyvalue(self): def onchange_copyvalue(self):
self.sub_object_id = False self.sub_object_id = False
self.copyvalue = False self.copyvalue = False
self.sub_object_id = False self.sub_object_id = False
if self.field_id and not self.field_id.relation: if self.field_id and not self.field_id.relation:
self.copyvalue = "${object.%s or %s}" % \ self.copyvalue = "${{object.{} or {}}}".format(
(self.field_id.name, self.field_id.name,
self.default_value or '\'\'') self.default_value or "''",
)
self.sub_model_object_field_id = False self.sub_model_object_field_id = False
if self.field_id and self.field_id.relation: if self.field_id and self.field_id.relation:
self.sub_object_id = self.env['ir.model'].search( self.sub_object_id = self.env["ir.model"].search(
[('model', '=', self.field_id.relation)])[0] [("model", "=", self.field_id.relation)]
)[0]
if self.sub_model_object_field_id: if self.sub_model_object_field_id:
self.copyvalue = "${object.%s.%s or %s}" %\ self.copyvalue = "${{object.{}.{} or {}}}".format(
(self.field_id.name, self.field_id.name,
self.sub_model_object_field_id.name, self.sub_model_object_field_id.name,
self.default_value or '\'\'') self.default_value or "''",
)
# compute the dynamic content for mako expression # compute the dynamic content for mako expression
@api.multi
def _compute_dynamic_content(self): def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"] MailTemplates = self.env["mail.template"]
for appendix in self: for appendix in self:
@@ -96,6 +93,6 @@ class AgreementAppendix(models.Model):
or "en_US" or "en_US"
) )
content = MailTemplates.with_context(lang=lang)._render_template( content = MailTemplates.with_context(lang=lang)._render_template(
appendix.content, "agreement.appendix", appendix.id appendix.content, "agreement.appendix", [appendix.id]
) )
appendix.dynamic_content = content appendix.dynamic_content = content

View File

@@ -11,27 +11,25 @@ class AgreementClause(models.Model):
name = fields.Char(string="Name", required=True) name = fields.Char(string="Name", required=True)
title = fields.Char( title = fields.Char(
string="Title", string="Title", help="The title is displayed on the PDF. The name is not."
help="The title is displayed on the PDF." "The name is not.") )
sequence = fields.Integer(string="Sequence") sequence = fields.Integer(string="Sequence")
agreement_id = fields.Many2one( agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
"agreement",
string="Agreement",
ondelete="cascade")
section_id = fields.Many2one( section_id = fields.Many2one(
"agreement.section", "agreement.section", string="Section", ondelete="cascade"
string="Section", )
ondelete="cascade")
content = fields.Html(string="Clause Content") content = fields.Html(string="Clause Content")
dynamic_content = fields.Html( dynamic_content = fields.Html(
compute="_compute_dynamic_content", compute="_compute_dynamic_content",
string="Dynamic Content", string="Dynamic Content",
help="compute dynamic Content") help="compute dynamic Content",
)
active = fields.Boolean( active = fields.Boolean(
string="Active", string="Active",
default=True, default=True,
help="If unchecked, it will allow you to hide the agreement without " help="If unchecked, it will allow you to hide the agreement without "
"removing it.") "removing it.",
)
# Dynamic field editor # Dynamic field editor
field_id = fields.Many2one( field_id = fields.Many2one(
@@ -39,56 +37,61 @@ class AgreementClause(models.Model):
string="Field", string="Field",
help="""Select target field from the related document model. If it is a help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the relationship field you will be able to select a target field at the
destination of the relationship.""") destination of the relationship.""",
)
sub_object_id = fields.Many2one( sub_object_id = fields.Many2one(
"ir.model", "ir.model",
string="Sub-model", string="Sub-model",
help="""When a relationship field is selected as first field, this help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""") field shows the document model the relationship goes to.""",
)
sub_model_object_field_id = fields.Many2one( sub_model_object_field_id = fields.Many2one(
"ir.model.fields", "ir.model.fields",
string="Sub-field", string="Sub-field",
help="""When a relationship field is selected as first field, this help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document field lets you select the target field within the destination document
model (sub-model).""") model (sub-model).""",
)
default_value = fields.Char( default_value = fields.Char(
string="Default Value", string="Default Value",
help="Optional value to use if the target field is empty.") help="Optional value to use if the target field is empty.",
)
copyvalue = fields.Char( copyvalue = fields.Char(
string="Placeholder Expression", string="Placeholder Expression",
help="""Final placeholder expression, to be copy-pasted in the desired help="""Final placeholder expression, to be copy-pasted in the desired
template field.""") template field.""",
)
@api.onchange('field_id', 'sub_model_object_field_id', 'default_value') @api.onchange("field_id", "sub_model_object_field_id", "default_value")
def onchange_copyvalue(self): def onchange_copyvalue(self):
self.sub_object_id = False self.sub_object_id = False
self.copyvalue = False self.copyvalue = False
self.sub_object_id = False self.sub_object_id = False
if self.field_id and not self.field_id.relation: if self.field_id and not self.field_id.relation:
self.copyvalue = "${object.%s or %s}" % \ self.copyvalue = "${{object.{} or {}}}".format(
(self.field_id.name, self.field_id.name,
self.default_value or '\'\'') self.default_value or "''",
)
self.sub_model_object_field_id = False self.sub_model_object_field_id = False
if self.field_id and self.field_id.relation: if self.field_id and self.field_id.relation:
self.sub_object_id = self.env['ir.model'].search( self.sub_object_id = self.env["ir.model"].search(
[('model', '=', self.field_id.relation)])[0] [("model", "=", self.field_id.relation)]
)[0]
if self.sub_model_object_field_id: if self.sub_model_object_field_id:
self.copyvalue = "${object.%s.%s or %s}" %\ self.copyvalue = "${{object.{}.{} or {}}}".format(
(self.field_id.name, self.field_id.name,
self.sub_model_object_field_id.name, self.sub_model_object_field_id.name,
self.default_value or '\'\'') self.default_value or "''",
)
# compute the dynamic content for mako expression # compute the dynamic content for mako expression
@api.multi
def _compute_dynamic_content(self): def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"] MailTemplates = self.env["mail.template"]
for clause in self: for clause in self:
lang = ( lang = (
clause.agreement_id clause.agreement_id and clause.agreement_id.partner_id.lang or "en_US"
and clause.agreement_id.partner_id.lang
or "en_US"
) )
content = MailTemplates.with_context(lang=lang)._render_template( content = MailTemplates.with_context(lang=lang)._render_template(
clause.content, "agreement.clause", clause.id clause.content, "agreement.clause", [clause.id]
) )
clause.dynamic_content = content clause.dynamic_content = content

View File

@@ -17,11 +17,8 @@ class AgreementIncreaseType(models.Model):
"the contract.", "the contract.",
) )
description = fields.Text( description = fields.Text(
string="Description", string="Description", required=True, help="Description of the renewal type."
required=True,
help="Description of the renewal type."
) )
increase_percent = fields.Integer( increase_percent = fields.Integer(
string="Increase Percentage", string="Increase Percentage", help="Percentage that the amount will increase."
help="Percentage that the amount will increase."
) )

View File

@@ -8,21 +8,11 @@ class AgreementLine(models.Model):
_name = "agreement.line" _name = "agreement.line"
_description = "Agreement Lines" _description = "Agreement Lines"
product_id = fields.Many2one( product_id = fields.Many2one("product.product", string="Product")
"product.product", name = fields.Char(string="Description", required=True)
string="Product") agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
name = fields.Char(
string="Description",
required=True)
agreement_id = fields.Many2one(
"agreement",
string="Agreement",
ondelete="cascade")
qty = fields.Float(string="Quantity") qty = fields.Float(string="Quantity")
uom_id = fields.Many2one( uom_id = fields.Many2one("uom.uom", string="Unit of Measure", required=True)
"uom.uom",
string="Unit of Measure",
required=True)
@api.onchange("product_id") @api.onchange("product_id")
def _onchange_product_id(self): def _onchange_product_id(self):

View File

@@ -21,9 +21,7 @@ class AgreementRecital(models.Model):
string="Dynamic Content", string="Dynamic Content",
help="compute dynamic Content", help="compute dynamic Content",
) )
agreement_id = fields.Many2one( agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
"agreement", string="Agreement", ondelete="cascade"
)
active = fields.Boolean( active = fields.Boolean(
string="Active", string="Active",
default=True, default=True,
@@ -84,16 +82,13 @@ class AgreementRecital(models.Model):
) )
# compute the dynamic content for mako expression # compute the dynamic content for mako expression
@api.multi
def _compute_dynamic_content(self): def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"] MailTemplates = self.env["mail.template"]
for recital in self: for recital in self:
lang = ( lang = (
recital.agreement_id recital.agreement_id and recital.agreement_id.partner_id.lang or "en_US"
and recital.agreement_id.partner_id.lang
or "en_US"
) )
content = MailTemplates.with_context(lang=lang)._render_template( content = MailTemplates.with_context(lang=lang)._render_template(
recital.content, "agreement.recital", recital.id recital.content, "agreement.recital", [recital.id]
) )
recital.dynamic_content = content recital.dynamic_content = content

View File

@@ -17,7 +17,5 @@ class AgreementRenewalType(models.Model):
"agreement/contract expires.", "agreement/contract expires.",
) )
description = fields.Text( description = fields.Text(
string="Description", string="Description", required=True, help="Description of the renewal type."
required=True,
help="Description of the renewal type."
) )

View File

@@ -11,23 +11,25 @@ class AgreementSection(models.Model):
name = fields.Char(string="Name", required=True) name = fields.Char(string="Name", required=True)
title = fields.Char( title = fields.Char(
string="Title", string="Title", help="The title is displayed on the PDF. The name is not."
help="The title is displayed on the PDF. The name is not.") )
sequence = fields.Integer(string="Sequence") sequence = fields.Integer(string="Sequence")
agreement_id = fields.Many2one( agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
"agreement", string="Agreement", ondelete="cascade")
clauses_ids = fields.One2many( clauses_ids = fields.One2many(
"agreement.clause", "section_id", string="Clauses", copy=True) "agreement.clause", "section_id", string="Clauses", copy=True
)
content = fields.Html(string="Section Content") content = fields.Html(string="Section Content")
dynamic_content = fields.Html( dynamic_content = fields.Html(
compute="_compute_dynamic_content", compute="_compute_dynamic_content",
string="Dynamic Content", string="Dynamic Content",
help="compute dynamic Content") help="compute dynamic Content",
)
active = fields.Boolean( active = fields.Boolean(
string="Active", string="Active",
default=True, default=True,
help="If unchecked, it will allow you to hide the agreement without " help="If unchecked, it will allow you to hide the agreement without "
"removing it.") "removing it.",
)
# Dynamic field editor # Dynamic field editor
field_id = fields.Many2one( field_id = fields.Many2one(
@@ -35,25 +37,30 @@ class AgreementSection(models.Model):
string="Field", string="Field",
help="""Select target field from the related document model. If it is a help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the relationship field you will be able to select a target field at the
destination of the relationship.""") destination of the relationship.""",
)
sub_object_id = fields.Many2one( sub_object_id = fields.Many2one(
"ir.model", "ir.model",
string="Sub-model", string="Sub-model",
help="""When a relationship field is selected as first field, this help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""") field shows the document model the relationship goes to.""",
)
sub_model_object_field_id = fields.Many2one( sub_model_object_field_id = fields.Many2one(
"ir.model.fields", "ir.model.fields",
string="Sub-field", string="Sub-field",
help="""When a relationship field is selected as first field, this help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document field lets you select the target field within the destination document
model (sub-model).""") model (sub-model).""",
)
default_value = fields.Char( default_value = fields.Char(
string="Default Value", string="Default Value",
help="Optional value to use if the target field is empty.") help="Optional value to use if the target field is empty.",
)
copyvalue = fields.Char( copyvalue = fields.Char(
string="Placeholder Expression", string="Placeholder Expression",
help="""Final placeholder expression, to be copy-pasted in the desired help="""Final placeholder expression, to be copy-pasted in the desired
template field.""") template field.""",
)
@api.onchange("field_id", "sub_model_object_field_id", "default_value") @api.onchange("field_id", "sub_model_object_field_id", "default_value")
def onchange_copyvalue(self): def onchange_copyvalue(self):
@@ -62,7 +69,8 @@ class AgreementSection(models.Model):
self.sub_object_id = False self.sub_object_id = False
if self.field_id and not self.field_id.relation: if self.field_id and not self.field_id.relation:
self.copyvalue = "${{object.{} or {}}}".format( self.copyvalue = "${{object.{} or {}}}".format(
self.field_id.name, self.default_value or "''") self.field_id.name, self.default_value or "''"
)
self.sub_model_object_field_id = False self.sub_model_object_field_id = False
if self.field_id and self.field_id.relation: if self.field_id and self.field_id.relation:
self.sub_object_id = self.env["ir.model"].search( self.sub_object_id = self.env["ir.model"].search(
@@ -76,12 +84,13 @@ class AgreementSection(models.Model):
) )
# compute the dynamic content for mako expression # compute the dynamic content for mako expression
@api.multi
def _compute_dynamic_content(self): def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"] MailTemplates = self.env["mail.template"]
for section in self: for section in self:
lang = (section.agreement_id and lang = (
section.agreement_id.partner_id.lang or "en_US") section.agreement_id and section.agreement_id.partner_id.lang or "en_US"
)
content = MailTemplates.with_context(lang=lang)._render_template( content = MailTemplates.with_context(lang=lang)._render_template(
section.content, "agreement.section", section.id) section.content, "agreement.section", [section.id]
)
section.dynamic_content = content section.dynamic_content = content

View File

@@ -11,21 +11,14 @@ class AgreementStage(models.Model):
_order = "sequence" _order = "sequence"
# General # General
name = fields.Char( name = fields.Char(string="Stage Name", required=True)
string="Stage Name", description = fields.Text(string="Description", required=False)
required=True) sequence = fields.Integer(string="Sequence", default="1", required=False)
description = fields.Text(
string="Description",
required=False)
sequence = fields.Integer(
string="Sequence",
default="1",
required=False)
fold = fields.Boolean( fold = fields.Boolean(
string="Is Folded", string="Is Folded",
required=False, required=False,
help="This stage is folded in the kanban view by default.", help="This stage is folded in the kanban view by default.",
) )
stage_type = fields.Selection( stage_type = fields.Selection(
[('agreement', 'Agreement')], [("agreement", "Agreement")], string="Type", required=True
string='Type', required=True) )

View File

@@ -9,6 +9,4 @@ class AgreementSubtype(models.Model):
_description = "Agreement Subtypes" _description = "Agreement Subtypes"
name = fields.Char(string="Name", required=True) name = fields.Char(string="Name", required=True)
agreement_type_id = fields.Many2one( agreement_type_id = fields.Many2one("agreement.type", string="Agreement Type")
"agreement.type",
string="Agreement Type")

View File

@@ -9,7 +9,5 @@ class AgreementType(models.Model):
_description = "Agreement Types" _description = "Agreement Types"
agreement_subtypes_ids = fields.One2many( agreement_subtypes_ids = fields.One2many(
"agreement.subtype", "agreement.subtype", "agreement_type_id", string="Subtypes"
"agreement_type_id",
string="Subtypes"
) )

View File

@@ -7,6 +7,4 @@ from odoo import fields, models
class Product(models.Model): class Product(models.Model):
_inherit = "product.template" _inherit = "product.template"
agreements_ids = fields.Many2many( agreements_ids = fields.Many2many("agreement", string="Agreements")
"agreement",
string="Agreements")

View File

@@ -19,8 +19,7 @@ class ResConfigSettings(models.TransientModel):
module_agreement_repair = fields.Boolean( module_agreement_repair = fields.Boolean(
string="Link your repair orders to an agreement." string="Link your repair orders to an agreement."
) )
module_agreement_rma = fields.Boolean( module_agreement_rma = fields.Boolean(string="Link your RMAs to an agreement.")
string="Link your RMAs to an agreement.")
module_agreement_sale = fields.Boolean( module_agreement_sale = fields.Boolean(
string="Create an agreement when the sale order is confirmed." string="Create an agreement when the sale order is confirmed."
) )

View File

@@ -7,7 +7,4 @@ from odoo import fields, models
class Partner(models.Model): class Partner(models.Model):
_inherit = "res.partner" _inherit = "res.partner"
agreement_ids = fields.One2many( agreement_ids = fields.One2many("agreement", "partner_id", string="Agreements")
"agreement",
"partner_id",
string="Agreements")

View File

@@ -1,21 +1,20 @@
<?xml version="1.0"?>
<odoo> <odoo>
<report <record id="partner_agreement_contract_document" model="ir.actions.report">
id="partner_agreement_contract_document" <field name="name">Agreement</field>
model="agreement" <field name="model">agreement</field>
string="Contract Document" <field name="report_type">qweb-pdf</field>
name="agreement_legal.report_agreement_document" <field name="report_name">agreement_legal.report_agreement_document</field>
file="agreement_legal.report_agreement_document" <field name="report_file">agreement_legal.report_agreement_document</field>
report_type="qweb-pdf"/> </record>
<report <record id="partner_agreement_contract_document_preview" model="ir.actions.report">
id="partner_agreement_contract_document_preview" <field name="name">Agreement Preview</field>
model="agreement" <field name="model">agreement</field>
string="Contract Document Preview" <field name="report_type">qweb-html</field>
name="agreement_legal.report_agreement_document" <field name="report_name">agreement_legal.report_agreement_document</field>
file="agreement_legal.report_agreement_document" <field name="report_file">agreement_legal.report_agreement_document</field>
report_type="qweb-html"/> </record>
<template id="report_agreement_document"> <template id="report_agreement_document">
<t t-name="agreement.report_agreement_document"> <t t-name="agreement.report_agreement_document">
@@ -23,32 +22,40 @@
<t t-foreach="docs" t-as="doc"> <t t-foreach="docs" t-as="doc">
<t t-call="web.external_layout"> <t t-call="web.external_layout">
<div class="page"> <div class="page">
<h1 t-field="doc.name"/> <h1 t-field="doc.name" />
<div name="description"> <div name="description">
<span t-field="doc.dynamic_description"/> <span t-field="doc.dynamic_description" />
</div> </div>
<h2>Parties</h2> <h2>Parties</h2>
<div name="parties"> <div name="parties">
<t t-if="doc.use_parties_content"> <t t-if="doc.use_parties_content">
<p t-field="doc.dynamic_parties"/> <p t-field="doc.dynamic_parties" />
</t> </t>
</div> </div>
<t t-if="not doc.use_parties_content"> <t t-if="not doc.use_parties_content">
<h3>Company Information</h3> <h3>Company Information</h3>
<div name="company_address"> <div name="company_address">
<address t-field="doc.company_id.partner_id" <address
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' /> t-field="doc.company_id.partner_id"
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'
/>
</div> </div>
<div name="company_contact"> <div name="company_contact">
Represented by <span t-field="doc.company_contact_id.name"/>. Represented by <span
t-field="doc.company_contact_id.name"
/>.
</div> </div>
<h3>Partner Information</h3> <h3>Partner Information</h3>
<div name="partner_address"> <div name="partner_address">
<address t-field="doc.partner_id" <address
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' /> t-field="doc.partner_id"
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'
/>
</div> </div>
<div name="partner_contact"> <div name="partner_contact">
Represented by <span t-field="doc.partner_contact_id.name"/>. Represented by <span
t-field="doc.partner_contact_id.name"
/>.
</div> </div>
</t> </t>
<h2>Agreement</h2> <h2>Agreement</h2>
@@ -58,11 +65,14 @@
<tr> <tr>
<td> <td>
<ol> <ol>
<li t-foreach="doc.recital_ids" t-as="r"> <li
t-foreach="doc.recital_ids"
t-as="r"
>
<t t-if="r.title"> <t t-if="r.title">
<h3 t-field="r.title"/> <h3 t-field="r.title" />
</t> </t>
<p t-field="r.dynamic_content"/> <p t-field="r.dynamic_content" />
</li> </li>
</ol> </ol>
</td> </td>
@@ -74,17 +84,25 @@
<tr> <tr>
<td> <td>
<ol> <ol>
<li t-foreach="doc.sections_ids" t-as="s"> <li
t-foreach="doc.sections_ids"
t-as="s"
>
<t t-if="s.title"> <t t-if="s.title">
<h3 t-field="s.title"/> <h3 t-field="s.title" />
</t> </t>
<p t-field="s.dynamic_content"/> <p t-field="s.dynamic_content" />
<ol> <ol>
<li t-foreach="s.clauses_ids" t-as="c"> <li
t-foreach="s.clauses_ids"
t-as="c"
>
<t t-if="c.title"> <t t-if="c.title">
<h4 t-field="c.title"/> <h4 t-field="c.title" />
</t> </t>
<p t-field="c.dynamic_content"/> <p
t-field="c.dynamic_content"
/>
</li> </li>
</ol> </ol>
</li> </li>
@@ -96,7 +114,7 @@
<t t-if="special_term"> <t t-if="special_term">
<h2>Special Terms</h2> <h2>Special Terms</h2>
<div name="special_term"> <div name="special_term">
<p t-field="doc.dynamic_special_terms"/> <p t-field="doc.dynamic_special_terms" />
</div> </div>
</t> </t>
<h2>Signatures</h2> <h2>Signatures</h2>
@@ -110,24 +128,32 @@
<tbody class="section_tbody"> <tbody class="section_tbody">
<tr> <tr>
<td> <td>
<p t-field="doc.partner_id"/> <p t-field="doc.partner_id" />
<p>By: </p> <p>By: </p>
<p> <p>
Name: <span t-field="doc.partner_contact_id.name"/> Name: <span
t-field="doc.partner_contact_id.name"
/>
</p> </p>
<p> <p>
Title: <span t-field="doc.partner_contact_id.function"/> Title: <span
t-field="doc.partner_contact_id.function"
/>
</p> </p>
<p>Date: </p> <p>Date: </p>
</td> </td>
<td> <td>
<p t-field="doc.company_id.partner_id"/> <p t-field="doc.company_id.partner_id" />
<p>By: </p> <p>By: </p>
<p> <p>
Name: <span t-field="doc.company_contact_id.name"/> Name: <span
t-field="doc.company_contact_id.name"
/>
</p> </p>
<p> <p>
Title: <span t-field="doc.company_contact_id.function"/> Title: <span
t-field="doc.company_contact_id.function"
/>
</p> </p>
<p>Date: </p> <p>Date: </p>
</td> </td>
@@ -137,9 +163,11 @@
</div> </div>
<div t-foreach="doc.appendix_ids" t-as="a"> <div t-foreach="doc.appendix_ids" t-as="a">
<div class="page"> <div class="page">
<h1 t-field="a.title" <h1
style="page-break-before: always;"/> t-field="a.title"
<p t-field="a.dynamic_content"/> style="page-break-before: always;"
/>
<p t-field="a.dynamic_content" />
</div> </div>
</div> </div>
</t> </t>

View File

@@ -1,30 +1,36 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="module_agreement_legal_category" model="ir.module.category"> <record id="module_agreement_legal_category" model="ir.module.category">
<field name ="name">Agreement</field> <field name="name">Agreement</field>
<field name ="sequence">17</field> <field name="sequence">17</field>
</record> </record>
<!-- Readonly group --> <!-- Readonly group -->
<record id="group_agreement_readonly" model="res.groups"> <record id="group_agreement_readonly" model="res.groups">
<field name="name">Read-Only Users</field> <field name="name">Read-Only Users</field>
<field name="category_id" ref="module_agreement_legal_category"/> <field name="category_id" ref="module_agreement_legal_category" />
<field name="implied_ids" eval="[(4, ref('base.group_user')), (4, ref('agreement.group_use_agreement_type')), (4, ref('agreement.group_use_agreement_template'))]"/> <field
name="implied_ids"
eval="[(4, ref('base.group_user')), (4, ref('agreement.group_use_agreement_type')), (4, ref('agreement.group_use_agreement_template'))]"
/>
</record> </record>
<!-- User group --> <!-- User group -->
<record id="group_agreement_user" model="res.groups"> <record id="group_agreement_user" model="res.groups">
<field name="name">User</field> <field name="name">User</field>
<field name="category_id" ref="module_agreement_legal_category"/> <field name="category_id" ref="module_agreement_legal_category" />
<field name="implied_ids" eval="[(4, ref('group_agreement_readonly'))]"/> <field name="implied_ids" eval="[(4, ref('group_agreement_readonly'))]" />
</record> </record>
<!-- Manager group --> <!-- Manager group -->
<record id="group_agreement_manager" model="res.groups"> <record id="group_agreement_manager" model="res.groups">
<field name="name">Manager</field> <field name="name">Manager</field>
<field name="category_id" ref="module_agreement_legal_category"/> <field name="category_id" ref="module_agreement_legal_category" />
<field name="implied_ids" eval="[(4, ref('group_agreement_user'))]"/> <field name="implied_ids" eval="[(4, ref('group_agreement_user'))]" />
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/> <field
name="users"
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
/>
</record> </record>
</odoo> </odoo>

View File

@@ -0,0 +1,85 @@
odoo.define("agreement_legal.domain_widget_ext", function (require) {
"use strict";
var basic_fields = require("web.basic_fields");
var DomainSelector = require("web.DomainSelector");
var session = require("web.session");
var core = require("web.core");
var qweb = core.qweb;
basic_fields.FieldDomain.include({
/**
* Init
*/
init: function () {
this._super.apply(this, arguments);
// Add Additional options
this.partialUse = this.nodeOptions.partial_use || false;
},
// ----------------------------------------------------------------------
// Private
// ----------------------------------------------------------------------
/**
* @private
* @override _render from AbstractField
* @returns {Deferred}
*/
_render: function () {
// If there is no model, only change the non-domain-selector content
if (!this._domainModel) {
this._replaceContent();
return $.when();
}
// Convert char value to array value
var value = this.value || "[]";
// Create the domain selector or change the value of the current
// one...
var def = null;
if (this.domainSelector) {
def = this.domainSelector.setDomain(value);
} else {
this.domainSelector = new DomainSelector(
this,
this._domainModel,
value,
{
readonly: this.mode === "readonly" || this.inDialog,
filters: this.fsFilters,
debugMode: session.debug,
partialUse: this.partialUse || false,
}
);
def = this.domainSelector.prependTo(this.$el);
}
// ... then replace the other content (matched records, etc)
return def.then(this._replaceContent.bind(this));
},
/**
* Render the field DOM except for the domain selector part. The full
* field DOM is composed of a DIV which contains the domain selector
* widget, followed by other content. This other content is handled by
* this method.
*
* @private
*/
_replaceContent: function () {
if (this._$content) {
this._$content.remove();
}
this._$content = $(
qweb.render("FieldDomain.content", {
hasModel: Boolean(this._domainModel),
isValid: Boolean(this._isValidForModel),
nbRecords: this.record.specialData[this.name].nbRecords || 0,
inDialogEdit: this.inDialog && this.mode === "edit",
partialUse: this.partialUse || false,
})
);
this._$content.appendTo(this.$el);
},
});
});

View File

@@ -0,0 +1,298 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t t-name="FieldDomain.content">
<t t-if="partialUse">
<div t-if="hasModel" class="o_field_domain_panel">
</div>
</t>
<t t-if="!partialUse">
<div t-if="hasModel" class="o_field_domain_panel">
<i
class="fa fa-arrow-right"
role="img"
aria-label="Domain"
title="Domain"
/>
<button
t-if="isValid"
class="btn btn-sm btn-secondary o_domain_show_selection_button"
type="button"
>
<t t-esc="nbRecords" /> record(s)
</button>
<span t-else="" class="text-warning" role="alert"><i
class="fa fa-exclamation-triangle"
role="img"
aria-label="Warning"
title="Warning"
/> Invalid domain</span>
<button
t-if="inDialogEdit"
class="btn btn-sm btn-primary o_field_domain_dialog_button"
>Edit Domain</button>
</div>
<div t-else="">Select a model to add a filter.</div>
</t>
</t>
<div
aria-atomic="true"
t-name="DomainSelector"
t-attf-class="o_domain_node o_domain_tree o_domain_selector #{widget.readonly ? 'o_read_mode' : 'o_edit_mode'}"
>
<t t-if="widget.options.partialUse">
<t t-if="widget.children.length === 0">
<span>SMatch <strong>all records</strong></span>
<button
t-if="!widget.readonly"
class="btn btn-sm btn-primary o_domain_add_first_node_button"
><i class="fa fa-plus" /> Add filter</button>
</t>
<t t-else="">
<div class="o_domain_tree_header">
<t
t-if="widget.children.length === 1"
>Please navigate below and select field:</t>
<t t-else="">
<span>SSMatch records with</span>
<t t-call="DomainTree.OperatorSelector" />
<span>of the following rules:</span>
</t>
</div>
<div class="o_domain_node_children_container" />
</t>
</t>
<t t-if="!widget.options.partialUse">
<t t-if="widget.children.length === 0">
<span>Match <strong>all records</strong></span>
<button
t-if="!widget.readonly"
class="btn btn-sm btn-primary o_domain_add_first_node_button"
><i class="fa fa-plus" /> Add filter</button>
</t>
<t t-else="">
<div class="o_domain_tree_header">
<t
t-if="widget.children.length === 1"
>Match records with the following rule:</t>
<t t-else="">
<span>Match records with</span>
<t t-call="DomainTree.OperatorSelector" />
<span>of the following rules:</span>
</t>
</div>
<div class="o_domain_node_children_container" />
</t>
<label
t-if="widget.debug &amp;&amp; !widget.readonly"
class="o_domain_debug_container"
>
<span class="small"># Code editor</span>
<input type="text" class="o_domain_debug_input" />
</label>
</t>
</div>
<t t-name="DomainNode.ControlPanel">
<t t-if="widget.options.partialUse">
<div
t-if="!widget.readonly &amp;&amp; !widget.noControlPanel"
class="o_domain_node_control_panel"
role="toolbar"
aria-label="Domain node"
>
</div>
</t>
<t t-if="!widget.options.partialUse">
<div
t-if="!widget.readonly &amp;&amp; !widget.noControlPanel"
class="o_domain_node_control_panel"
role="toolbar"
aria-label="Domain node"
>
<button
class="btn o_domain_delete_node_button"
title="Delete node"
aria-label="Delete node"
><i class="fa fa-times" /></button>
<button
class="btn o_domain_add_node_button"
title="Add node"
aria-label="Add node"
><i class="fa fa-plus-circle" /></button>
<button
class="btn o_domain_add_node_button"
title="Add branch"
aria-label="Add branch"
data-branch="1"
><i class="fa fa-ellipsis-h" /></button>
</div>
</t>
</t>
<div
t-name="DomainLeaf"
t-attf-class="o_domain_node o_domain_leaf o_domain_selector_row #{widget.readonly ? 'o_read_mode' : 'o_edit_mode'}"
>
<t t-call="DomainNode.ControlPanel" />
<div t-if="!widget.readonly" class="o_domain_leaf_edition">
<!-- field selector will be instantiated here -->
<t t-if="!widget.options.partialUse">
<div> <!-- used for flex stretching -->
<select class="o_domain_leaf_operator_select o_input">
<option
t-foreach="widget.operators"
t-as="key"
t-att-value="key"
t-att-selected="widget.displayOperator === key ? 'selected' : None"
>
<t t-esc="key_value" />
</option>
</select>
</div>
<div
t-attf-class="o_ds_value_cell#{_.contains(['set', 'not set'], widget.displayOperator) ? ' d-none' : ''}"
>
<t t-if="widget.selectionChoices !== null">
<select class="o_domain_leaf_value_input o_input">
<option
t-foreach="widget.selectionChoices"
t-as="val"
t-att-value="val[0]"
t-att-selected="_.contains(val, widget.displayValue) ? 'selected' : None"
>
<t t-esc="val[1]" />
</option>
</select>
</t>
<t t-else="">
<t t-if="_.contains(['in', 'not in'], widget.operator)">
<div class="o_domain_leaf_value_input">
<span
class="badge badge-pill"
t-foreach="widget.displayValue"
t-as="val"
>
<t t-esc="val" /> <i
class="o_domain_leaf_value_remove_tag_button fa fa-times"
t-att-data-value="val"
role="img"
aria-label="Remove tag"
title="Remove tag"
/>
</span>
</div>
<div class="o_domain_leaf_value_tags">
<input
placeholder="Add new value"
type="text"
class="o_input"
/>
<button
class="btn btn-sm btn-primary fa fa-plus o_domain_leaf_value_add_tag_button"
aria-label="Add tag"
title="Add tag"
/>
</div>
</t>
<t t-else="">
<input
class="o_domain_leaf_value_input o_input"
type="text"
t-att-value="widget.displayValue"
/>
</t>
</t>
</div>
</t>
</div>
<div t-else="" class="o_domain_leaf_info">
<!-- field selector will be instantiated here -->
<t t-if="_.isString(widget.value)">
<span class="o_domain_leaf_operator"><t
t-esc="widget.operator_mapping[widget.operator]"
/></span>
<span class="o_domain_leaf_value text-primary">"<t
t-esc="widget.value"
/>"</span>
</t>
<t t-if="_.isArray(widget.value)">
<span class="o_domain_leaf_operator"><t
t-esc="widget.operator_mapping[widget.operator]"
/></span>
<t t-foreach="widget.value" t-as="v">
<span class="o_domain_leaf_value text-primary">"<t
t-esc="v"
/>"</span>
<t t-if="!v_last"> or </t>
</t>
</t>
<t t-if="_.isNumber(widget.value)">
<span class="o_domain_leaf_operator"><t
t-esc="widget.operator_mapping[widget.operator]"
/></span>
<span class="o_domain_leaf_value text-primary"><t
t-esc="widget.value"
/></span>
</t>
<t t-if="_.isBoolean(widget.value)">
is
<t
t-if="widget.operator === '=' &amp;&amp; widget.value === false || widget.operator === '!=' &amp;&amp; widget.value === true"
>not</t>
set
</t>
</div>
</div>
<div
aria-atomic="true"
t-name="ModelFieldSelector"
t-attf-class="o_field_selector#{!widget.options.readonly ? ' o_edit_mode o_input' : ''}"
>
<div class="o_field_selector_value" tabindex="0" />
<t t-if="!widget.options.partialUse">
<div class="o_field_selector_controls" tabindex="0">
<i
role="alert"
class="fa fa-exclamation-triangle o_field_selector_warning d-none"
title="Invalid field chain"
aria-label="Invalid field chain"
/>
</div>
</t>
<div
t-if="!widget.options.readonly"
class="o_field_selector_popover d-none"
tabindex="0"
>
<div class="o_field_selector_popover_header text-center">
<i
class="fa fa-arrow-left o_field_selector_popover_option o_field_selector_prev_page"
title="Previous"
role="img"
aria-label="Previous"
/>
<div class="o_field_selector_title" />
<i
class="fa fa-times o_field_selector_popover_option o_field_selector_close"
title="Close"
role="img"
aria-label="Close"
/>
</div>
<div class="o_field_selector_popover_body">
<ul class="o_field_selector_page" />
</div>
<div
t-if="widget.options.debugMode"
class="o_field_selector_popover_footer"
>
<input type="text" class="o_input" />
</div>
</div>
</div>
</templates>

View File

@@ -0,0 +1,8 @@
# License LGPLv3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html).
from . import test_agreement
from . import test_agreement_appendix
from . import test_agreement_clause
from . import test_agreement_line
from . import test_agreement_recital
from . import test_agreement_section

View File

@@ -0,0 +1,131 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from datetime import timedelta
from odoo import fields
from odoo.tests.common import TransactionCase
class TestAgreement(TransactionCase):
def setUp(self):
super().setUp()
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
self.agreement_type = self.env["agreement.type"].create(
{
"name": "Test Agreement Type",
"domain": "sale",
}
)
self.test_agreement = self.env["agreement"].create(
{
"name": "TestAgreement",
"description": "Test",
"special_terms": "Test",
"partner_id": self.test_customer.id,
"start_date": fields.Date.today(),
"end_date": fields.Date.today() + timedelta(days=365),
"state": "active",
}
)
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
def test_onchange_copyvalue(self):
agreement_01 = self.test_agreement
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement"),
("name", "=", "active"),
]
)
agreement_01.field_id = field_01.id
agreement_01.onchange_copyvalue()
self.assertEqual(agreement_01.copyvalue, "${object.active or ''}")
# TEST 02: Set related 'Field' for dynamic placeholder to
# test onchange method
def test_onchange_copyvalue2(self):
agreement_01 = self.test_agreement
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement"),
("name", "=", "agreement_type_id"),
]
)
sub_field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.type"),
("name", "=", "active"),
]
)
agreement_01.field_id = field_01.id
agreement_01.onchange_copyvalue()
self.assertEqual(agreement_01.sub_object_id.model, "agreement.type")
agreement_01.sub_model_object_field_id = sub_field_01.id
agreement_01.onchange_copyvalue()
self.assertEqual(
agreement_01.copyvalue, "${object.agreement_type_id.active or ''}"
)
# TEST 03: Create New Version
def test_create_new_version(self):
agreement_01 = self.test_agreement
agreement_01.create_new_version()
old_agreement = self.env["agreement"].search(
[
("code", "=", agreement_01.code + "-V1"),
("active", "=", False),
]
)
self.assertEqual(len(old_agreement), 1)
new_agreement = self.env["agreement"].search(
[
("name", "=", "TestAgreement"),
("version", "=", 2),
]
)
self.assertEqual(len(new_agreement), 1)
# TEST 04: Create New Agreement
def test_create_new_agreement(self):
agreement_01 = self.test_agreement
agreement_01.create_new_agreement()
new_agreement = self.env["agreement"].search([("name", "=", "New")])
self.assertEqual(len(new_agreement), 1)
# TEST 05: Test Description Dynamic Field
def test_compute_dynamic_description(self):
agreement_01 = self.test_agreement
agreement_01.description = "${object.name}"
self.assertEqual(
agreement_01.dynamic_description,
"TestAgreement",
)
# TEST 06: Test Parties Dynamic Field
def test_compute_dynamic_parties(self):
agreement_01 = self.test_agreement
agreement_01.parties = "${object.name}"
self.assertEqual(
agreement_01.dynamic_parties,
"<p>{" + str(agreement_01.id) + ": '</p><p>TestAgreement</p>'}",
)
# TEST 07: Test Special Terms Dynamic Field
def test_compute_dynamic_special_terms(self):
agreement_01 = self.test_agreement
agreement_01.special_terms = "${object.name}"
self.assertEqual(
agreement_01.dynamic_special_terms,
"{" + str(agreement_01.id) + ": 'TestAgreement'}",
)
# TEST 02: Check Read Stages
def test_read_group_stage_ids(self):
agreement_01 = self.test_agreement
self.assertEqual(
agreement_01._read_group_stage_ids(self.env["agreement.stage"], [], "id"),
self.env["agreement.stage"].search(
[("stage_type", "=", "agreement")],
order="id",
),
)

View File

@@ -0,0 +1,81 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from datetime import timedelta
from odoo import fields
from odoo.tests.common import TransactionCase
class TestAgreementAppendices(TransactionCase):
def setUp(self):
super().setUp()
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
self.agreement_type = self.env["agreement.type"].create(
{
"name": "Test Agreement Type",
"domain": "sale",
}
)
self.test_agreement = self.env["agreement"].create(
{
"name": "TestAgreement",
"description": "Test",
"special_terms": "Test",
"partner_id": self.test_customer.id,
"start_date": fields.Date.today(),
"end_date": fields.Date.today() + timedelta(days=365),
}
)
self.test_appendices = self.env["agreement.appendix"].create(
{
"name": "TestAppendices",
"title": "Test",
"content": "Test",
"agreement_id": self.test_agreement.id,
}
)
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
def test_onchange_copyvalue(self):
appendix_01 = self.test_appendices
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.appendix"),
("name", "=", "active"),
]
)
appendix_01.field_id = field_01.id
appendix_01.onchange_copyvalue()
self.assertEqual(appendix_01.copyvalue, "${object.active or ''}")
# TEST 02: Set related 'Field' for dynamic placeholder to
# test onchange method
def test_onchange_copyvalue2(self):
appendix_01 = self.test_appendices
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.appendix"),
("name", "=", "agreement_id"),
]
)
sub_field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement"),
("name", "=", "active"),
]
)
appendix_01.field_id = field_01.id
appendix_01.onchange_copyvalue()
self.assertEqual(appendix_01.sub_object_id.model, "agreement")
appendix_01.sub_model_object_field_id = sub_field_01.id
appendix_01.onchange_copyvalue()
self.assertEqual(appendix_01.copyvalue, "${object.agreement_id.active or ''}")
# TEST 03: Test Dynamic Field
def test_compute_dynamic_content(self):
appendix_01 = self.test_appendices
appendix_01.content = "${object.name}"
self.assertEqual(
appendix_01.dynamic_content,
"<p>{" + str(appendix_01.id) + ": '</p><p>TestAppendices</p>'}",
)

View File

@@ -0,0 +1,81 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from datetime import timedelta
from odoo import fields
from odoo.tests.common import TransactionCase
class TestAgreementClauses(TransactionCase):
def setUp(self):
super().setUp()
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
self.agreement_type = self.env["agreement.type"].create(
{
"name": "Test Agreement Type",
"domain": "sale",
}
)
self.test_agreement = self.env["agreement"].create(
{
"name": "TestAgreement",
"description": "Test",
"special_terms": "Test",
"partner_id": self.test_customer.id,
"start_date": fields.Date.today(),
"end_date": fields.Date.today() + timedelta(days=365),
}
)
self.test_clause = self.env["agreement.clause"].create(
{
"name": "TestClause",
"title": "Test",
"content": "Test",
"agreement_id": self.test_agreement.id,
}
)
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
def test_onchange_copyvalue(self):
clause_01 = self.test_clause
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.clause"),
("name", "=", "active"),
]
)
clause_01.field_id = field_01.id
clause_01.onchange_copyvalue()
self.assertEqual(clause_01.copyvalue, "${object.active or ''}")
# TEST 02: Set related 'Field' for dynamic placeholder to
# test onchange method
def test_onchange_copyvalue2(self):
clause_01 = self.test_clause
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.clause"),
("name", "=", "agreement_id"),
]
)
sub_field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement"),
("name", "=", "active"),
]
)
clause_01.field_id = field_01.id
clause_01.onchange_copyvalue()
self.assertEqual(clause_01.sub_object_id.model, "agreement")
clause_01.sub_model_object_field_id = sub_field_01.id
clause_01.onchange_copyvalue()
self.assertEqual(clause_01.copyvalue, "${object.agreement_id.active or ''}")
# TEST 03: Test Dynamic Field
def test_compute_dynamic_content(self):
clause_01 = self.test_clause
clause_01.content = "${object.name}"
self.assertEqual(
clause_01.dynamic_content,
"<p>{" + str(clause_01.id) + ": '</p><p>TestClause</p>'}",
)

View File

@@ -0,0 +1,45 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from datetime import timedelta
from odoo import fields
from odoo.tests.common import TransactionCase
class TestAgreementLine(TransactionCase):
def setUp(self):
super().setUp()
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
self.agreement_type = self.env["agreement.type"].create(
{
"name": "Test Agreement Type",
"domain": "sale",
}
)
self.test_agreement = self.env["agreement"].create(
{
"name": "TestAgreement",
"description": "Test",
"special_terms": "Test",
"partner_id": self.test_customer.id,
"start_date": fields.Date.today(),
"end_date": fields.Date.today() + timedelta(days=365),
}
)
self.test_product1 = self.env["product.product"].create({"name": "TEST1"})
self.test_product2 = self.env["product.product"].create({"name": "TEST2"})
self.test_line = self.env["agreement.line"].create(
{
"product_id": self.test_product1.id,
"name": "Test",
"uom_id": 1,
"agreement_id": self.test_agreement.id,
}
)
# TEST 01: Set line product onchange method
def test_onchange_product_id(self):
line_01 = self.test_line
line_01.product_id = self.test_product2.id
line_01._onchange_product_id()
self.assertEqual(line_01.name, "TEST2")

View File

@@ -0,0 +1,81 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from datetime import timedelta
from odoo import fields
from odoo.tests.common import TransactionCase
class TestAgreementRectical(TransactionCase):
def setUp(self):
super().setUp()
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
self.agreement_type = self.env["agreement.type"].create(
{
"name": "Test Agreement Type",
"domain": "sale",
}
)
self.test_agreement = self.env["agreement"].create(
{
"name": "TestAgreement",
"description": "Test",
"special_terms": "Test",
"partner_id": self.test_customer.id,
"start_date": fields.Date.today(),
"end_date": fields.Date.today() + timedelta(days=365),
}
)
self.test_recital = self.env["agreement.recital"].create(
{
"name": "TestRecital",
"title": "Test",
"content": "Test",
"agreement_id": self.test_agreement.id,
}
)
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
def test_onchange_copyvalue(self):
recital_01 = self.test_recital
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.recital"),
("name", "=", "active"),
]
)
recital_01.field_id = field_01.id
recital_01.onchange_copyvalue()
self.assertEqual(recital_01.copyvalue, "${object.active or ''}")
# TEST 02: Set related 'Field' for dynamic placeholder to
# test onchange method
def test_onchange_copyvalue2(self):
recital_01 = self.test_recital
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.recital"),
("name", "=", "agreement_id"),
]
)
sub_field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement"),
("name", "=", "active"),
]
)
recital_01.field_id = field_01.id
recital_01.onchange_copyvalue()
self.assertEqual(recital_01.sub_object_id.model, "agreement")
recital_01.sub_model_object_field_id = sub_field_01.id
recital_01.onchange_copyvalue()
self.assertEqual(recital_01.copyvalue, "${object.agreement_id.active or ''}")
# TEST 03: Test Dynamic Field
def test_compute_dynamic_content(self):
recital_01 = self.test_recital
recital_01.content = "${object.name}"
self.assertEqual(
recital_01.dynamic_content,
"<p>{" + str(recital_01.id) + ": '</p><p>TestRecital</p>'}",
)

View File

@@ -0,0 +1,81 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from datetime import timedelta
from odoo import fields
from odoo.tests.common import TransactionCase
class TestAgreementSection(TransactionCase):
def setUp(self):
super().setUp()
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
self.agreement_type = self.env["agreement.type"].create(
{
"name": "Test Agreement Type",
"domain": "sale",
}
)
self.test_agreement = self.env["agreement"].create(
{
"name": "TestAgreement",
"description": "Test",
"special_terms": "Test",
"partner_id": self.test_customer.id,
"start_date": fields.Date.today(),
"end_date": fields.Date.today() + timedelta(days=365),
}
)
self.test_section = self.env["agreement.section"].create(
{
"name": "TestSection",
"title": "Test",
"content": "Test",
"agreement_id": self.test_agreement.id,
}
)
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
def test_onchange_copyvalue(self):
section_01 = self.test_section
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.section"),
("name", "=", "active"),
]
)
section_01.field_id = field_01.id
section_01.onchange_copyvalue()
self.assertEqual(section_01.copyvalue, "${object.active or ''}")
# TEST 02: Set related 'Field' for dynamic placeholder to
# test onchange method
def test_onchange_copyvalue2(self):
section_01 = self.test_section
field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement.section"),
("name", "=", "agreement_id"),
]
)
sub_field_01 = self.env["ir.model.fields"].search(
[
("model", "=", "agreement"),
("name", "=", "active"),
]
)
section_01.field_id = field_01.id
section_01.onchange_copyvalue()
self.assertEqual(section_01.sub_object_id.model, "agreement")
section_01.sub_model_object_field_id = sub_field_01.id
section_01.onchange_copyvalue()
self.assertEqual(section_01.copyvalue, "${object.agreement_id.active or ''}")
# TEST 03: Test Dynamic Field
def test_compute_dynamic_content(self):
section_01 = self.test_section
section_01.content = "${object.name}"
self.assertEqual(
section_01.dynamic_content,
"<p>{" + str(section_01.id) + ": '</p><p>TestSection</p>'}",
)

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement List View--> <!-- Agreement List View-->
@@ -7,13 +6,13 @@
<field name="model">agreement</field> <field name="model">agreement</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Agreements" default_order='name'> <tree string="Agreements" default_order='name'>
<field name="name"/> <field name="name" />
<field name="partner_id"/> <field name="partner_id" />
<field name="company_id"/> <field name="company_id" />
<field name="parent_agreement_id"/> <field name="parent_agreement_id" />
<field name="agreement_type_id"/> <field name="agreement_type_id" />
<field name="agreement_subtype_id"/> <field name="agreement_subtype_id" />
<field name="active" invisible="1"/> <field name="active" invisible="1" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -22,63 +21,94 @@
<record model="ir.ui.view" id="partner_agreement_form_view"> <record model="ir.ui.view" id="partner_agreement_form_view">
<field name="name">Agreement Form</field> <field name="name">Agreement Form</field>
<field name="model">agreement</field> <field name="model">agreement</field>
<field name="priority" eval="1"/> <field name="priority" eval="1" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Agreement"> <form string="Agreement">
<header> <header>
<button string="New Version" type="object" name="create_new_version" class="oe_highlight" attrs="{'invisible': [('state', '=', 'active')]}"/> <button
<button string="New Agreement" type="object" name="create_new_agreement" class="oe_highlight" attrs="{'invisible': [('is_template', '=', False)]}"/> string="New Version"
<field name="stage_id" widget="statusbar" clickable="True" options="{'fold_field': 'fold'}" domain="[('stage_type', '=', 'agreement')]"/> type="object"
name="create_new_version"
class="oe_highlight"
attrs="{'invisible': [('state', '=', 'active')]}"
/>
<button
string="New Agreement"
type="object"
name="create_new_agreement"
class="oe_highlight"
attrs="{'invisible': [('is_template', '=', False)]}"
/>
<field
name="stage_id"
widget="statusbar"
clickable="True"
options="{'fold_field': 'fold'}"
domain="[('stage_type', '=', 'agreement')]"
/>
</header> </header>
<sheet> <sheet>
<div class="oe_button_box" name="button_box"> <div class="oe_button_box" name="button_box" />
</div>
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only" string="Agreement Name"/> <label
for="name"
class="oe_edit_only"
string="Agreement Name"
/>
<h1> <h1>
<field name="name"/> <field name="name" />
</h1> </h1>
</div> </div>
<group string="General"> <group string="General">
<group> <group>
<field name="code" readonly="1"/> <field name="code" readonly="1" />
<field name="parent_agreement_id" <field
domain="[('partner_id', '=', partner_id)]"/> name="parent_agreement_id"
<field name="is_template"/> domain="[('partner_id', '=', partner_id)]"
/>
<field name="is_template" />
</group> </group>
<group> <group>
<field name="agreement_type_id" <field
widget="selection" name="agreement_type_id"
required="True"/> widget="selection"
<field name="agreement_subtype_id" required="True"
widget="selection" />
domain="[('agreement_type_id', '=', agreement_type_id)]"/> <field
<field name="assigned_user_id" name="agreement_subtype_id"
attrs="{'invisible': [('is_template', '=', True)], 'readonly':[('is_template', '=', True)]}"/> widget="selection"
<field name="active" invisible="1"/> domain="[('agreement_type_id', '=', agreement_type_id)]"
<field name="state" invisible="1"/> />
<field
name="assigned_user_id"
attrs="{'invisible': [('is_template', '=', True)], 'readonly':[('is_template', '=', True)]}"
/>
<field name="active" invisible="1" />
<field name="state" invisible="1" />
</group> </group>
</group> </group>
<group string="Description"> <group string="Description">
<field name="description" <field name="description" required="True" nolabel="1" />
required="True"
nolabel="1"/>
</group> </group>
<group class="oe_edit_only"> <group class="oe_edit_only">
<group> <group>
<field name="field_id" <field
domain="[('model_id', '=', active_model), name="field_id"
('ttype', '!=', 'one2many'), domain="[('model_id', '=', active_model),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'), ('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]" ('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)], />
'required':[('sub_object_id', '!=', False)]}"/> <field name="sub_object_id" readonly="1" />
<field name="default_value"/> <field
<field name="copyvalue"/> name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"
/>
<field name="default_value" />
<field name="copyvalue" />
</group> </group>
<p> <p>
This section (on the left) allows you to add dynamic fields inside the description and special terms. This section (on the left) allows you to add dynamic fields inside the description and special terms.
@@ -86,157 +116,248 @@
<li>Select the agreement field</li> <li>Select the agreement field</li>
<li>Select the sub-field</li> <li>Select the sub-field</li>
<li>Enter the default value if the field is empty</li> <li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the description or the special terms</li> <li
>Copy and paste the placeholder expression in the description or the special terms</li>
</ol> </ol>
</p> </p>
</group> </group>
<group name="parties" string="Parties"> <group name="parties" string="Parties">
<group name="cust_parties"> <group name="cust_parties">
<field name="use_parties_content" string="Use custom content" /> <field
name="use_parties_content"
string="Use custom content"
/>
</group> </group>
<group name="cust_parties"> <group name="cust_parties">
<p> <p>
This section (on the left) allows you to replace the default listing of the parties with custom dynamic content. This section (on the left) allows you to replace the default listing of the parties with custom dynamic content.
</p> </p>
</group> </group>
<group name="partner" <group name="partner" string="Partner">
string="Partner">
<div class="o_address_format"> <div class="o_address_format">
<field name="partner_id" <field
domain="['|',('customer', '=', True),('supplier', '=', True)]" name="partner_id"
context="{'show_address': 1}" context="{'show_address': 1}"
options="{&quot;always_reload&quot;: True}"/> options="{&quot;always_reload&quot;: True}"
/>
</div> </div>
</group> </group>
<group name="company" <group name="company" string="Company">
string="Company">
<div class="o_address_format"> <div class="o_address_format">
<field name="company_id" <field
readonly="1" name="company_id"
context="{'show_address': 1}" readonly="1"
options="{&quot;always_reload&quot;: True}"/> context="{'show_address': 1}"
options="{&quot;always_reload&quot;: True}"
/>
</div> </div>
<field name="company_partner_id" invisible="1" /> <field name="company_partner_id" invisible="1" />
</group> </group>
<group name="partner_left" string="Primary Contact"> <group name="partner_left" string="Primary Contact">
<field name="partner_contact_id" domain="[('parent_id', '=', partner_id)]" nolabel="1"/> <field
<field name="partner_contact_phone" widget="phone" readonly="1" nolabel="1"/> name="partner_contact_id"
<field name="partner_contact_email" widget="email" readonly="1" nolabel="1"/> domain="[('parent_id', '=', partner_id)]"
nolabel="1"
/>
<field
name="partner_contact_phone"
widget="phone"
readonly="1"
nolabel="1"
/>
<field
name="partner_contact_email"
widget="email"
readonly="1"
nolabel="1"
/>
</group> </group>
<group name="contact_right" string="Primary Contact"> <group name="contact_right" string="Primary Contact">
<field name="company_contact_id" domain="[('parent_id', '=', company_partner_id)]" nolabel="1"/> <field
<field name="company_contact_phone" widget="phone" readonly="1" nolabel="1"/> name="company_contact_id"
<field name="company_contact_email" widget="email" readonly="1" nolabel="1"/> domain="[('parent_id', '=', company_partner_id)]"
nolabel="1"
/>
<field
name="company_contact_phone"
widget="phone"
readonly="1"
nolabel="1"
/>
<field
name="company_contact_email"
widget="email"
readonly="1"
nolabel="1"
/>
</group> </group>
</group> </group>
<group name="parties_content" string="Parties Content" attrs="{'invisible':[('use_parties_content', '=', False)]}"> <group
<field name="parties" nolabel="1"/> name="parties_content"
string="Parties Content"
attrs="{'invisible':[('use_parties_content', '=', False)]}"
>
<field name="parties" nolabel="1" />
</group> </group>
<group name="term_information"> <group name="term_information">
<group name="termdates_left" string="Term Dates"> <group name="termdates_left" string="Term Dates">
<field name="start_date" attrs="{'required': [('is_template', '=', False)], 'invisible': [('is_template', '=', True)]}"/> <field
<field name="end_date" attrs="{'required': [('is_template', '=', False)], 'invisible': [('is_template', '=', True)]}"/> name="start_date"
<field name="expiration_notice"/> attrs="{'required': [('is_template', '=', False)], 'invisible': [('is_template', '=', True)]}"
<field name="change_notice"/> />
<field name="notification_address_id" domain="['|', ('parent_id', '=', partner_id), ('parent_id', '=', company_partner_id)]"/> <field
<field name="termination_requested"/> name="end_date"
<field name="termination_date"/> attrs="{'required': [('is_template', '=', False)], 'invisible': [('is_template', '=', True)]}"
/>
<field name="expiration_notice" />
<field name="change_notice" />
<field
name="notification_address_id"
domain="['|', ('parent_id', '=', partner_id), ('parent_id', '=', company_partner_id)]"
/>
<field name="termination_requested" />
<field name="termination_date" />
</group> </group>
</group> </group>
<group string="Special Terms"> <group string="Special Terms">
<field name="special_terms" <field name="special_terms" nolabel="1" />
nolabel="1"/>
</group> </group>
<notebook> <notebook>
<page name="structure" string="Structure"> <page name="structure" string="Structure">
<div> <div>
<button name="%(partner_agreement_contract_document_preview)d" string="Preview" type="action" class="oe_highlight"/> <button
<button name="%(partner_agreement_contract_document)d" string="Print" type="action" class="oe_highlight"/> name="%(partner_agreement_contract_document_preview)d"
string="Preview"
type="action"
class="oe_highlight"
/>
<button
name="%(partner_agreement_contract_document)d"
string="Print"
type="action"
class="oe_highlight"
/>
</div> </div>
<separator string="Recitals"/> <separator string="Recitals" />
<field name="recital_ids" <field
default_order="sequence" name="recital_ids"
nolabel="1" default_order="sequence"
context="{'default_agreement': active_id}"/> nolabel="1"
<separator string="Sections"/> context="{'default_agreement': active_id}"
<field name="sections_ids" />
default_order='sequence' <separator string="Sections" />
nolabel="1" <field
context="{'default_agreement': active_id}"/> name="sections_ids"
<separator string="Clauses"/> default_order='sequence'
<field name="clauses_ids" nolabel="1"
default_order='clause_id, sequence' context="{'default_agreement': active_id}"
nolabel="1" />
context="{'default_agreement': active_id}"/> <separator string="Clauses" />
<separator string="Appendices"/> <field
<field name="appendix_ids" name="clauses_ids"
default_order='sequence' default_order='clause_id, sequence'
nolabel="1" nolabel="1"
context="{'default_agreement': active_id}"/> context="{'default_agreement': active_id}"
/>
<separator string="Appendices" />
<field
name="appendix_ids"
default_order='sequence'
nolabel="1"
context="{'default_agreement': active_id}"
/>
</page> </page>
<page name="signature" string="Signatures"> <page name="signature" string="Signatures">
<group> <group>
<group string="Partner"> <group string="Partner">
<field name="partner_signed_date"/> <field name="partner_signed_date" />
<field name="partner_signed_user_id" domain="[('parent_id', '=', partner_id)]"/> <field
name="partner_signed_user_id"
domain="[('parent_id', '=', partner_id)]"
/>
</group> </group>
<group string="Company"> <group string="Company">
<field name="company_signed_date"/> <field name="company_signed_date" />
<field name="company_signed_user_id"/> <field name="company_signed_user_id" />
<field name="signed_contract" filename="signed_contract_filename"/> <field
<field name="signed_contract_filename" invisible="1"/> name="signed_contract"
filename="signed_contract_filename"
/>
<field
name="signed_contract_filename"
invisible="1"
/>
</group> </group>
</group> </group>
</page> </page>
<page name="products" string="Products/Services"> <page name="products" string="Products/Services">
<field name="line_ids" nolabel="1"> <field name="line_ids" nolabel="1">
<tree editable="top"> <tree editable="top">
<field name="product_id"/> <field name="product_id" />
<field name="name"/> <field name="name" />
<field name="qty"/> <field name="qty" />
<field name="uom_id" groups="uom.group_uom"/> <field name="uom_id" groups="uom.group_uom" />
</tree> </tree>
</field> </field>
</page> </page>
<page name="child_agreements" string="Child Agreements"> <page name="child_agreements" string="Child Agreements">
<field name="child_agreements_ids"> <field name="child_agreements_ids">
<tree default_order='version desc'> <tree default_order='version desc'>
<field name="name"/> <field name="name" />
<field name="version"/> <field name="version" />
<field name="revision"/> <field name="revision" />
</tree> </tree>
</field> </field>
</page> </page>
<page name="old_versions" string="Revisions"> <page name="old_versions" string="Revisions">
<field name="previous_version_agreements_ids" string="Previouse Versions"> <field
name="previous_version_agreements_ids"
string="Previouse Versions"
>
<tree default_order='version desc'> <tree default_order='version desc'>
<field name="name"/> <field name="name" />
<field name="version"/> <field name="version" />
<field name="revision"/> <field name="revision" />
</tree> </tree>
</field> </field>
</page> </page>
<page name="performance" string="Performance"> <page name="performance" string="Performance">
<p>This section is a place where financial records will show the current performance of this agreement.</p> <p
>This section is a place where financial records will show the current performance of this agreement.</p>
<p>Perhaps include invoices with total vs costs? </p> <p>Perhaps include invoices with total vs costs? </p>
</page> </page>
</notebook> </notebook>
<group string="Administration"> <group string="Administration">
<div> <div>
<p>Reviewed by <field name="reviewed_user_id" class="oe_inline"/> on <field name="reviewed_date" class="oe_inline"/>.</p> <p>Reviewed by <field
<p>Approved by <field name="approved_user_id" class="oe_inline"/> on <field name="approved_date" class="oe_inline"/>.</p> name="reviewed_user_id"
class="oe_inline"
/> on <field
name="reviewed_date"
class="oe_inline"
/>.</p>
<p>Approved by <field
name="approved_user_id"
class="oe_inline"
/> on <field
name="approved_date"
class="oe_inline"
/>.</p>
</div> </div>
</group> </group>
<footer> <footer>
Version: <field name="version" readonly="True"/>.<field name="revision" readonly="True"/> Version: <field name="version" readonly="True" />.<field
| Created By: <field name="create_uid" readonly="True"/> name="revision"
| Created On: <field name="create_date" readonly="True"/> readonly="True"
/>
| Created By: <field name="create_uid" readonly="True" />
| Created On: <field name="create_date" readonly="True" />
</footer> </footer>
</sheet> </sheet>
<div class="oe_chatter"> <div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/> <field name="message_follower_ids" widget="mail_followers" />
<field name="activity_ids" widget="mail_activity"/> <field name="activity_ids" widget="mail_activity" />
<field name="message_ids" widget="mail_thread"/> <field name="message_ids" widget="mail_thread" />
</div> </div>
</form> </form>
</field> </field>
@@ -248,52 +369,91 @@
<field name="model">agreement</field> <field name="model">agreement</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<kanban default_group_by="stage_id"> <kanban default_group_by="stage_id">
<field name="color"/> <field name="color" />
<field name="assigned_user_id"/> <field name="assigned_user_id" />
<templates> <templates>
<t t-name="kanban-box"> <t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"> <div
t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"
>
<div class="oe_kanban_content"> <div class="oe_kanban_content">
<div class="o_kanban_record_top"> <div class="o_kanban_record_top">
<div class="o_kanban_record_headings"> <div class="o_kanban_record_headings">
<strong class="o_kanban_record_title"> <strong class="o_kanban_record_title">
<field name="name"/> <field name="name" />
</strong><br/> </strong><br />
<div class="o_kanban_record_subtitle text-muted"> <div
<field name="partner_id" invisible="context.get('default_partner_id', False)"/> class="o_kanban_record_subtitle text-muted"
<t t-if="record.end_date.raw_value and record.end_date.raw_value lt (new Date())" t-set="red">oe_kanban_text_red</t> >
<field name="partner_id" />
<t
t-if="record.end_date.raw_value and record.end_date.raw_value lt (new Date())"
t-set="red"
>oe_kanban_text_red</t>
<div t-attf-class="#{red || ''}"> <div t-attf-class="#{red || ''}">
<i><field name="end_date"/></i> <i><field name="end_date" /></i>
</div> </div>
</div> </div>
</div> </div>
<div class="o_dropdown_kanban dropdown" groups="base.group_user"> <div
<a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#"> class="o_dropdown_kanban dropdown"
<span class="fa fa-ellipsis-v" aria-hidden="true"/> groups="base.group_user"
>
<a
role="button"
class="dropdown-toggle btn"
data-toggle="dropdown"
href="#"
>
<span
class="fa fa-ellipsis-v"
aria-hidden="true"
title="Icon"
/>
</a> </a>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"> <ul
<li t-if="widget.editable"><a type="edit">Edit</a></li> class="dropdown-menu"
<li class="divider"/> role="menu"
<li class="dropdown-header">Record's Colour</li> aria-labelledby="dLabel"
>
<li t-if="widget.editable"><a
type="edit"
>Edit</a></li>
<li class="divider" />
<li
class="dropdown-header"
>Record's Colour</li>
<li> <li>
<ul class="oe_kanban_colorpicker" data-field="color"/> <ul
class="oe_kanban_colorpicker"
data-field="color"
/>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div class="o_kanban_record_body"> <div class="o_kanban_record_body">
<field name="agreement_type_id"/> - <field name="agreement_subtype_id"/> <field name="agreement_type_id" /> - <field
name="agreement_subtype_id"
/>
</div> </div>
<div class="o_kanban_record_bottom"> <div class="o_kanban_record_bottom">
<div class="oe_kanban_bottom_left"> <div class="oe_kanban_bottom_left">
V: <field name="version"/> V: <field name="version" />
</div> </div>
<div class="oe_kanban_bottom_right"> <div class="oe_kanban_bottom_right">
<img t-att-src="kanban_image('res.users', 'image_small', record.assigned_user_id.raw_value)" t-att-title="record.assigned_user_id.value" width="36" height="36" class="oe_kanban_avatar" alt="user &amp; picture"/> <img
t-att-src="kanban_image('res.users', 'image_small', record.assigned_user_id.raw_value)"
t-att-title="record.assigned_user_id.value"
width="36"
height="36"
class="oe_kanban_avatar"
alt="user &amp; picture"
/>
</div> </div>
</div> </div>
</div> </div>
<div class="oe_clear"/> <div class="oe_clear" />
</div> </div>
</t> </t>
</templates> </templates>
@@ -307,15 +467,37 @@
<field name="model">agreement</field> <field name="model">agreement</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Agreement Search"> <search string="Agreement Search">
<field name="name"/> <field name="name" />
<field name="partner_id"/> <field name="partner_id" />
<field name="agreement_type_id"/> <field name="agreement_type_id" />
<field name="agreement_subtype_id"/> <field name="agreement_subtype_id" />
<filter name="filter_non_template" string="Non-Templates" domain="[('active','=',True),('is_template', '=', False)]"/> <filter
<filter name="filter_inactive" string="Archived" domain="[('active','=',False)]"/> name="filter_non_template"
<filter name="filter_templates" string="Templates" domain="[('active','=',True),('is_template', '=', True)]"/> string="Non-Templates"
<filter name="group_partner_id" string="Partners" icon="terp-partner" context="{'group_by':'partner_id'}"/> domain="[('active','=',True),('is_template', '=', False)]"
<filter name="group_status" string="Status" icon="terp-partner" context="{'group_by':'state'}"/> />
<filter
name="filter_inactive"
string="Archived"
domain="[('active','=',False)]"
/>
<filter
name="filter_templates"
string="Templates"
domain="[('active','=',True),('is_template', '=', True)]"
/>
<filter
name="group_partner_id"
string="Partners"
icon="terp-partner"
context="{'group_by':'partner_id'}"
/>
<filter
name="group_status"
string="Status"
icon="terp-partner"
context="{'group_by':'state'}"
/>
</search> </search>
</field> </field>
</record> </record>
@@ -326,7 +508,7 @@
<field name="model">agreement</field> <field name="model">agreement</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<graph string="Agreements" type="bar"> <graph string="Agreements" type="bar">
<field name="stage_id" type="row"/> <field name="stage_id" type="row" />
</graph> </graph>
</field> </field>
</record> </record>
@@ -336,7 +518,7 @@
<field name="model">agreement</field> <field name="model">agreement</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<pivot string="Agreements" display_quantity="true"> <pivot string="Agreements" display_quantity="true">
<field name="stage_id" type="row"/> <field name="stage_id" type="row" />
</pivot> </pivot>
</field> </field>
</record> </record>
@@ -344,7 +526,6 @@
<record id="action_agreement_report_order" model="ir.actions.act_window"> <record id="action_agreement_report_order" model="ir.actions.act_window">
<field name="name">Agreements</field> <field name="name">Agreements</field>
<field name="res_model">agreement</field> <field name="res_model">agreement</field>
<field name="view_type">form</field>
<field name="view_mode">graph,pivot</field> <field name="view_mode">graph,pivot</field>
</record> </record>

View File

@@ -1,5 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Appendix List View--> <!-- Agreement Appendix List View-->
@@ -8,11 +6,11 @@
<field name="model">agreement.appendix</field> <field name="model">agreement.appendix</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Appendices" default_order='agreement_id, sequence'> <tree string="Appendices" default_order='agreement_id, sequence'>
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle" />
<field name="name"/> <field name="name" />
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
<field name="active" invisible="1"/> <field name="active" invisible="1" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -24,40 +22,47 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Appendix"> <form string="Appendix">
<sheet> <sheet>
<div class="oe_button_box" name="button_box"> <div class="oe_button_box" name="button_box" />
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> <widget
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/> name="web_ribbon"
</button> title="Archived"
</div> bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<field name="active" invisible="1" />
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only"/> <label for="name" class="oe_edit_only" />
<h1><field name="name"/></h1> <h1><field name="name" /></h1>
</div> </div>
<group> <group>
<group> <group>
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
</group> </group>
<group> <group>
<field name="sequence"/> <field name="sequence" />
</group> </group>
</group> </group>
<field name="content" widget="html"/> <field name="content" widget="html" />
<group class="oe_edit_only"> <group class="oe_edit_only">
<group> <group>
<field name="field_id" <field
domain="[('model_id', '=', active_model), name="field_id"
('ttype', '!=', 'one2many'), domain="[('model_id', '=', active_model),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'), ('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]" ('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)], />
'required':[('sub_object_id', '!=', False)]}"/> <field name="sub_object_id" readonly="1" />
<field name="default_value"/> <field
<field name="copyvalue"/> name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"
/>
<field name="default_value" />
<field name="copyvalue" />
</group> </group>
<p> <p>
This section (on the left) allows you to add dynamic fields inside the content. This section (on the left) allows you to add dynamic fields inside the content.
@@ -65,7 +70,8 @@
<li>Select the appendix field</li> <li>Select the appendix field</li>
<li>Select the sub-field</li> <li>Select the sub-field</li>
<li>Enter the default value if the field is empty</li> <li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the content</li> <li
>Copy and paste the placeholder expression in the content</li>
</ol> </ol>
</p> </p>
</group> </group>
@@ -79,8 +85,13 @@
<field name="name">Agreement Appendix Search</field> <field name="name">Agreement Appendix Search</field>
<field name="model">agreement.appendix</field> <field name="model">agreement.appendix</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search> <search string="Appendix">
<filter name="group_agreement" icon="terp-partner" context="{'group_by':'agreement_id'}"/> <field name="name" />
<filter
name="group_agreement"
icon="terp-partner"
context="{'group_by':'agreement_id'}"
/>
</search> </search>
</field> </field>
</record> </record>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Clause List View--> <!-- Agreement Clause List View-->
@@ -7,12 +6,12 @@
<field name="model">agreement.clause</field> <field name="model">agreement.clause</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Clauses" default_order='agreement_id, sequence'> <tree string="Clauses" default_order='agreement_id, sequence'>
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle" />
<field name="name"/> <field name="name" />
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
<field name="section_id"/> <field name="section_id" />
<field name="active" invisible="1"/> <field name="active" invisible="1" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -24,41 +23,51 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Clause"> <form string="Clause">
<sheet> <sheet>
<div class="oe_button_box" name="button_box"> <div class="oe_button_box" name="button_box" />
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> <widget
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/> name="web_ribbon"
</button> title="Archived"
</div> bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<field name="active" invisible="1" />
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only"/> <label for="name" class="oe_edit_only" />
<h1><field name="name"/></h1> <h1><field name="name" /></h1>
</div> </div>
<group> <group>
<group> <group>
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
<field name="section_id" domain="[('agreement_id', '=', agreement_id)]"/> <field
name="section_id"
domain="[('agreement_id', '=', agreement_id)]"
/>
</group> </group>
<group> <group>
<field name="sequence"/> <field name="sequence" />
</group> </group>
</group> </group>
<field name="content" widget="html"/> <field name="content" widget="html" />
<group class="oe_edit_only"> <group class="oe_edit_only">
<group> <group>
<field name="field_id" <field
domain="[('model_id', '=', active_model), name="field_id"
('ttype', '!=', 'one2many'), domain="[('model_id', '=', active_model),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'), ('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]" ('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)], />
'required':[('sub_object_id', '!=', False)]}"/> <field name="sub_object_id" readonly="1" />
<field name="default_value"/> <field
<field name="copyvalue"/> name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"
/>
<field name="default_value" />
<field name="copyvalue" />
</group> </group>
<p> <p>
This section (on the left) allows you to add dynamic fields inside the content. This section (on the left) allows you to add dynamic fields inside the content.
@@ -66,7 +75,8 @@
<li>Select the clause field</li> <li>Select the clause field</li>
<li>Select the sub-field</li> <li>Select the sub-field</li>
<li>Enter the default value if the field is empty</li> <li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the content</li> <li
>Copy and paste the placeholder expression in the content</li>
</ol> </ol>
</p> </p>
</group> </group>
@@ -80,9 +90,18 @@
<field name="name">Agreement Clause Search</field> <field name="name">Agreement Clause Search</field>
<field name="model">agreement.clause</field> <field name="model">agreement.clause</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Agreement Clause Search"> <search string="Clause">
<filter name="group_agreement" icon="terp-partner" context="{'group_by':'agreement_id'}"/> <field name="name" />
<filter name="group_section" icon="terp-partner" context="{'group_by':'section_id'}"/> <filter
name="group_agreement"
icon="terp-partner"
context="{'group_by':'agreement_id'}"
/>
<filter
name="group_section"
icon="terp-partner"
context="{'group_by':'section_id'}"
/>
</search> </search>
</field> </field>
</record> </record>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Increase Type List View--> <!-- Agreement Increase Type List View-->
@@ -7,9 +6,9 @@
<field name="model">agreement.increasetype</field> <field name="model">agreement.increasetype</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree default_order='name'> <tree default_order='name'>
<field name="name"/> <field name="name" />
<field name="description"/> <field name="description" />
<field name="increase_percent"/> <field name="increase_percent" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -22,13 +21,13 @@
<form string="Agreements Type Form"> <form string="Agreements Type Form">
<sheet> <sheet>
<group> <group>
<field name="name"/> <field name="name" />
</group> </group>
<group> <group>
<field name="increase_percent"/> <field name="increase_percent" />
</group> </group>
<group string="Description"> <group string="Description">
<field name="description" nolabel="1"/> <field name="description" nolabel="1" />
</group> </group>
</sheet> </sheet>
</form> </form>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Recital List View--> <!-- Agreement Recital List View-->
@@ -7,11 +6,11 @@
<field name="model">agreement.recital</field> <field name="model">agreement.recital</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Recitals" default_order='agreement_id, sequence'> <tree string="Recitals" default_order='agreement_id, sequence'>
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle" />
<field name="name"/> <field name="name" />
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
<field name="active" invisible="1"/> <field name="active" invisible="1" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -23,40 +22,47 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Recital"> <form string="Recital">
<sheet> <sheet>
<div class="oe_button_box" name="button_box"> <div class="oe_button_box" name="button_box" />
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> <widget
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/> name="web_ribbon"
</button> title="Archived"
</div> bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<field name="active" invisible="1" />
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only"/> <label for="name" class="oe_edit_only" />
<h1><field name="name"/></h1> <h1><field name="name" /></h1>
</div> </div>
<group> <group>
<group> <group>
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
</group> </group>
<group> <group>
<field name="sequence"/> <field name="sequence" />
</group> </group>
</group> </group>
<field name="content" widget="html"/> <field name="content" widget="html" />
<group class="oe_edit_only"> <group class="oe_edit_only">
<group> <group>
<field name="field_id" <field
domain="[('model_id', '=', active_model), name="field_id"
('ttype', '!=', 'one2many'), domain="[('model_id', '=', active_model),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'), ('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]" ('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)], />
'required':[('sub_object_id', '!=', False)]}"/> <field name="sub_object_id" readonly="1" />
<field name="default_value"/> <field
<field name="copyvalue"/> name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"
/>
<field name="default_value" />
<field name="copyvalue" />
</group> </group>
<p> <p>
This section (on the left) allows you to add dynamic fields inside the content. This section (on the left) allows you to add dynamic fields inside the content.
@@ -64,7 +70,8 @@
<li>Select the recital field</li> <li>Select the recital field</li>
<li>Select the sub-field</li> <li>Select the sub-field</li>
<li>Enter the default value if the field is empty</li> <li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the content</li> <li
>Copy and paste the placeholder expression in the content</li>
</ol> </ol>
</p> </p>
</group> </group>
@@ -78,8 +85,13 @@
<field name="name">Agreement Recital Search</field> <field name="name">Agreement Recital Search</field>
<field name="model">agreement.recital</field> <field name="model">agreement.recital</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search> <search string="Recitals">
<filter name="group_agreement" icon="terp-partner" context="{'group_by':'agreement_id'}"/> <field name="name" />
<filter
name="group_agreement"
icon="terp-partner"
context="{'group_by':'agreement_id'}"
/>
</search> </search>
</field> </field>
</record> </record>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Renewal Type List View--> <!-- Agreement Renewal Type List View-->
@@ -7,8 +6,8 @@
<field name="model">agreement.renewaltype</field> <field name="model">agreement.renewaltype</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree default_order='name'> <tree default_order='name'>
<field name="name"/> <field name="name" />
<field name="description"/> <field name="description" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -21,10 +20,10 @@
<form string="Agreements Type Form"> <form string="Agreements Type Form">
<sheet> <sheet>
<group> <group>
<field name="name"/> <field name="name" />
</group> </group>
<group string="Description"> <group string="Description">
<field name="description" nolabel="1"/> <field name="description" nolabel="1" />
</group> </group>
</sheet> </sheet>
</form> </form>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Sections List View--> <!-- Agreement Sections List View-->
@@ -7,11 +6,11 @@
<field name="model">agreement.section</field> <field name="model">agreement.section</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Sections" default_order='agreement_id, sequence'> <tree string="Sections" default_order='agreement_id, sequence'>
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle" />
<field name="name"/> <field name="name" />
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
<field name="active" invisible="1"/> <field name="active" invisible="1" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -23,62 +22,73 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Section"> <form string="Section">
<sheet> <sheet>
<div class="oe_button_box" name="button_box"> <div class="oe_button_box" name="button_box" />
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> <widget
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/> name="web_ribbon"
</button> title="Archived"
</div> bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<field name="active" invisible="1" />
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only"/> <label for="name" class="oe_edit_only" />
<h1><field name="name"/></h1> <h1><field name="name" /></h1>
</div> </div>
<group> <group>
<group> <group>
<field name="title"/> <field name="title" />
<field name="agreement_id"/> <field name="agreement_id" />
</group> </group>
<group> <group>
<field name="sequence"/> <field name="sequence" />
</group> </group>
</group> </group>
<notebook> <notebook>
<page string="Content"> <page string="Content">
<field name='content' nolabel="1"/> <field name='content' nolabel="1" />
<group class="oe_edit_only"> <group class="oe_edit_only">
<group> <group>
<field name="field_id" <field
domain="[('model_id', '=', active_model), name="field_id"
('ttype', '!=', 'one2many'), domain="[('model_id', '=', active_model),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'), ('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]" ('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)], />
'required':[('sub_object_id', '!=', False)]}"/> <field name="sub_object_id" readonly="1" />
<field name="default_value"/> <field
<field name="copyvalue"/> name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"
/>
<field name="default_value" />
<field name="copyvalue" />
</group> </group>
<p> <p>
This section (on the left) allows you to add dynamic fields inside the content. This section (on the left) allows you to add dynamic fields inside the content.
<ol> <ol>
<li>Select the section field</li> <li>Select the section field</li>
<li>Select the sub-field</li> <li>Select the sub-field</li>
<li>Enter the default value if the field is empty</li> <li
<li>Copy and paste the placeholder expression in the content</li> >Enter the default value if the field is empty</li>
<li
>Copy and paste the placeholder expression in the content</li>
</ol> </ol>
</p> </p>
</group> </group>
</page> </page>
<page string="Clauses"> <page string="Clauses">
<field name="clauses_ids" <field
nolabel="1" name="clauses_ids"
context="{'default_section_id': active_id, 'default_agreement_id': agreement_id}"> nolabel="1"
context="{'default_section_id': active_id, 'default_agreement_id': agreement_id}"
>
<tree> <tree>
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle" />
<field name="name"/> <field name="name" />
<field name="title"/> <field name="title" />
</tree> </tree>
</field> </field>
</page> </page>
@@ -93,8 +103,14 @@
<field name="name">Agreement Section Search</field> <field name="name">Agreement Section Search</field>
<field name="model">agreement.section</field> <field name="model">agreement.section</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Agreement Section Search"> <search string="Section">
<filter name="group_agreement" string="Agreements" icon="terp-partner" context="{'group_by':'agreement_id'}"/> <field name="name" />
<filter
name="group_agreement"
string="Agreements"
icon="terp-partner"
context="{'group_by':'agreement_id'}"
/>
</search> </search>
</field> </field>
</record> </record>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Stage List View--> <!-- Agreement Stage List View-->
@@ -7,9 +6,9 @@
<field name="model">agreement.stage</field> <field name="model">agreement.stage</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree default_order='sequence, name'> <tree default_order='sequence, name'>
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle" />
<field name="name" string="Stage Name"/> <field name="name" string="Stage Name" />
<field name="stage_type"/> <field name="stage_type" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -22,13 +21,13 @@
<form string="Agreements Stage Form"> <form string="Agreements Stage Form">
<sheet> <sheet>
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only" string="Stage Name"/> <label for="name" class="oe_edit_only" string="Stage Name" />
<h1><field name="name" string="Stage Name"/></h1> <h1><field name="name" string="Stage Name" /></h1>
</div> </div>
<group> <group>
<field name="sequence"/> <field name="sequence" />
<field name="stage_type"/> <field name="stage_type" />
<field name="fold"/> <field name="fold" />
</group> </group>
</sheet> </sheet>
</form> </form>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Sub Type List View--> <!-- Agreement Sub Type List View-->
@@ -7,8 +6,8 @@
<field name="model">agreement.subtype</field> <field name="model">agreement.subtype</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree default_order='name'> <tree default_order='name'>
<field name="name" string="Sub-Type Name"/> <field name="name" string="Sub-Type Name" />
<field name="agreement_type_id" string="Agreement Type"/> <field name="agreement_type_id" string="Agreement Type" />
</tree> </tree>
</field> </field>
</record> </record>
@@ -21,14 +20,14 @@
<form string="Agreement Sub-Types"> <form string="Agreement Sub-Types">
<sheet> <sheet>
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only"/> <label for="name" class="oe_edit_only" />
<h1><field name="name"/></h1> <h1><field name="name" /></h1>
</div> </div>
<group> <group>
<group> <group>
<field name="agreement_type_id"/> <field name="agreement_type_id" />
</group> </group>
<group></group> <group />
</group> </group>
</sheet> </sheet>
</form> </form>

View File

@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Agreement Type List View--> <!-- Agreement Type List View-->
<record model="ir.ui.view" id="partner_agreement_type_list_view"> <record model="ir.ui.view" id="partner_agreement_type_list_view">
<field name="name">Agreement Type List</field> <field name="name">Agreement Type List</field>
<field name="model">agreement.type</field> <field name="model">agreement.type</field>
<field name="inherit_id" ref="agreement.agreement_type_list_view"/> <field name="inherit_id" ref="agreement.agreement_type_list_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="name" position="after"> <field name="name" position="after">
<field name="agreement_subtypes_ids" string="Sub-Types"/> <field name="agreement_subtypes_ids" string="Sub-Types" />
</field> </field>
</field> </field>
</record> </record>
@@ -17,13 +16,12 @@
<record model="ir.ui.view" id="partner_agreement_type_form_view"> <record model="ir.ui.view" id="partner_agreement_type_form_view">
<field name="name">Agreement Type Form</field> <field name="name">Agreement Type Form</field>
<field name="model">agreement.type</field> <field name="model">agreement.type</field>
<field name="inherit_id" ref="agreement.agreement_type_form_view"/> <field name="inherit_id" ref="agreement.agreement_type_form_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//sheet" position="inside"> <xpath expr="//sheet" position="inside">
<field name="agreement_subtypes_ids" <field name="agreement_subtypes_ids" nolabel="1">
nolabel="1">
<tree editable="bottom"> <tree editable="bottom">
<field name="name"/> <field name="name" />
</tree> </tree>
</field> </field>
</xpath> </xpath>

View File

@@ -1,147 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Remove top menu from agreement module --> <!-- Remove top menu from agreement module -->
<!-- <delete model="ir.ui.menu" id="agreement.agreement_menu" /> --> <!-- <delete model="ir.ui.menu" id="agreement.agreement_menu" /> -->
<!-- Top menu item --> <!-- Top menu item -->
<menuitem <menuitem
name="Agreements" name="Agreements"
id="agreement.agreement_menu" id="agreement.agreement_menu"
web_icon="agreement_legal,static/description/icon.png" web_icon="agreement_legal,static/description/icon.png"
sequence="80" sequence="80"
action="agreement_dashboard_agreement" action="agreement_dashboard_agreement"
groups="agreement_legal.group_agreement_readonly"/> groups="agreement_legal.group_agreement_readonly"
/>
<!-- Dashboard --> <!-- Dashboard -->
<menuitem <menuitem
name="Dashboard" name="Dashboard"
id="agreement_dashboard" id="agreement_dashboard"
parent="agreement.agreement_menu" parent="agreement.agreement_menu"
sequence="10"/> sequence="10"
/>
<menuitem <menuitem
name="Agreements" name="Agreements"
id="dashboard_agreements" id="dashboard_agreements"
parent="agreement_dashboard" parent="agreement_dashboard"
sequence="10" sequence="10"
action="agreement_dashboard_agreement"/> action="agreement_dashboard_agreement"
/>
<!-- Operations --> <!-- Operations -->
<menuitem <menuitem
name="Operations" name="Operations"
id="agreement_operations" id="agreement_operations"
parent="agreement.agreement_menu" parent="agreement.agreement_menu"
sequence="20"/> sequence="20"
/>
<menuitem <menuitem
name="Agreements" name="Agreements"
id="operations_agreements" id="operations_agreements"
parent="agreement_operations" parent="agreement_operations"
sequence="10" sequence="10"
action="agreement_operations_agreement"/> action="agreement_operations_agreement"
/>
<!-- Master Data --> <!-- Master Data -->
<menuitem <menuitem
name="Master Data" name="Master Data"
id="agreement_masterdata" id="agreement_masterdata"
parent="agreement.agreement_menu" parent="agreement.agreement_menu"
sequence="30"/> sequence="30"
/>
<menuitem <menuitem
name="Contents" name="Contents"
id="agreement_data_contents" id="agreement_data_contents"
parent="agreement_masterdata" parent="agreement_masterdata"
sequence="10"/> sequence="10"
/>
<menuitem <menuitem
name="Recitals" name="Recitals"
id="agreement_recitals" id="agreement_recitals"
parent="agreement_data_contents" parent="agreement_data_contents"
sequence="10" sequence="10"
action="agreement_recital_action"/> action="agreement_recital_action"
/>
<menuitem <menuitem
name="Clauses" name="Clauses"
id="agreement_clauses" id="agreement_clauses"
parent="agreement_data_contents" parent="agreement_data_contents"
sequence="20" sequence="20"
action="partner_agreement_action_clause"/> action="partner_agreement_action_clause"
/>
<menuitem <menuitem
name="Sections" name="Sections"
id="agreement_sections" id="agreement_sections"
parent="agreement_data_contents" parent="agreement_data_contents"
sequence="30" sequence="30"
action="partner_agreement_action_section"/> action="partner_agreement_action_section"
/>
<menuitem <menuitem
name="Appendices" name="Appendices"
id="agreement_appendices" id="agreement_appendices"
parent="agreement_data_contents" parent="agreement_data_contents"
sequence="40" sequence="40"
action="agreement_appendix_action"/> action="agreement_appendix_action"
/>
<menuitem <menuitem
name="Products" name="Products"
id="agreement_products" id="agreement_products"
sequence="100" sequence="100"
parent="agreement_masterdata" parent="agreement_masterdata"
action="product.product_template_action"/> action="product.product_template_action"
/>
<!-- Reporting --> <!-- Reporting -->
<menuitem <menuitem
name="Reporting" name="Reporting"
id="agreement_reporting" id="agreement_reporting"
sequence="40" sequence="40"
parent="agreement.agreement_menu" parent="agreement.agreement_menu"
groups="agreement_legal.group_agreement_manager"/> groups="agreement_legal.group_agreement_manager"
/>
<menuitem <menuitem
name="Agreements" name="Agreements"
id="agreement_agreement_reporting" id="agreement_agreement_reporting"
sequence="10" sequence="10"
parent="agreement_reporting" parent="agreement_reporting"
action="action_agreement_report_order"/> action="action_agreement_report_order"
/>
<!-- Configuration --> <!-- Configuration -->
<menuitem <menuitem
name="Configuration" name="Configuration"
id="agreement_configuration" id="agreement_configuration"
sequence="50" sequence="50"
parent="agreement.agreement_menu" parent="agreement.agreement_menu"
groups="agreement_legal.group_agreement_manager"/> groups="agreement_legal.group_agreement_manager"
/>
<menuitem <menuitem
name="Settings" name="Settings"
id="agreement_settings" id="agreement_settings"
sequence="10" sequence="10"
parent="agreement_configuration" parent="agreement_configuration"
action="agreement_legal.action_agreement_config"/> action="agreement_legal.action_agreement_config"
/>
<menuitem <menuitem
name="Templates" name="Templates"
id="template" id="template"
parent="agreement_configuration" parent="agreement_configuration"
sequence="20" sequence="20"
action="partner_agreement_agreement_templates"/> action="partner_agreement_agreement_templates"
/>
<menuitem <menuitem
name="Renewal Types" name="Renewal Types"
id="agreement_renewaltype" id="agreement_renewaltype"
parent="agreement_configuration" parent="agreement_configuration"
sequence="30" sequence="30"
action="partner_agreement_action_renewaltype"/> action="partner_agreement_action_renewaltype"
/>
<menuitem <menuitem
name="Increase Types" name="Increase Types"
id="agreement_increamenttypes" id="agreement_increamenttypes"
parent="agreement_configuration" parent="agreement_configuration"
sequence="31" sequence="31"
action="partner_agreement_action_increasetype"/> action="partner_agreement_action_increasetype"
/>
<menuitem <menuitem
name="Stages" name="Stages"
id="agreement_stages" id="agreement_stages"
parent="agreement_configuration" parent="agreement_configuration"
sequence="40" sequence="40"
action="partner_agreement_action_stage"/> action="partner_agreement_action_stage"
/>
<menuitem <menuitem
name="Types" name="Types"
id="agreement_types" id="agreement_types"
parent="agreement_configuration" parent="agreement_configuration"
sequence="50" sequence="50"
action="partner_agreement_action_type"/> action="partner_agreement_action_type"
/>
<menuitem <menuitem
name="Sub-Types" name="Sub-Types"
id="agreement_subtypes" id="agreement_subtypes"
parent="agreement_configuration" parent="agreement_configuration"
sequence="60" sequence="60"
action="partner_agreement_action_subtype"/> action="partner_agreement_action_subtype"
/>
</odoo> </odoo>

View File

@@ -1,32 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<record id="res_config_settings_view_form" model="ir.ui.view"> <record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.agreement</field> <field name="name">res.config.settings.view.form.agreement</field>
<field name="model">res.config.settings</field> <field name="model">res.config.settings</field>
<field name="priority" eval="40"/> <field name="priority" eval="40" />
<field name="inherit_id" ref="base.res_config_settings_view_form"/> <field name="inherit_id" ref="base.res_config_settings_view_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside"> <xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" <div
data-string="Agreements" class="app_settings_block"
string="Agreements" data-string="Agreements"
data-key="agreement_legal" string="Agreements"
groups="agreement_legal.group_agreement_manager"> data-key="agreement_legal"
groups="agreement_legal.group_agreement_manager"
>
<h2>Operations</h2> <h2>Operations</h2>
<div class="row mt16 o_settings_container"> <div class="row mt16 o_settings_container">
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="group_uom"/> <field name="group_uom" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="group_uom"/> <label for="group_uom" />
<div class="text-muted"> <div class="text-muted">
Sell and purchase products in different units of measure Sell and purchase products in different units of measure
</div> </div>
<div class="content-group"> <div class="content-group">
<div class="mt16" attrs="{'invisible': [('group_uom', '=', False)]}"> <div
<button name="%(uom.product_uom_form_action)d" icon="fa-arrow-right" type="action" string="Units Of Measure" class="btn-link"/> class="mt16"
attrs="{'invisible': [('group_uom', '=', False)]}"
>
<button
name="%(uom.product_uom_form_action)d"
icon="fa-arrow-right"
type="action"
string="Units Of Measure"
class="btn-link"
/>
</div> </div>
</div> </div>
</div> </div>
@@ -36,22 +46,27 @@
<div class="row mt16 o_settings_container"> <div class="row mt16 o_settings_container">
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_sale"/> <field name="module_agreement_sale" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Sales"/> <label for="module_agreement_sale" string="Sales" />
<div class="text-muted"> <div class="text-muted">
Create an agreement when the sales order is confirmed Create an agreement when the sales order is confirmed
</div> </div>
</div> </div>
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box" <div
attrs="{'invisible': [('module_agreement_sale', '!=', True)]}"> class="col-xs-12 col-md-6 o_setting_box"
attrs="{'invisible': [('module_agreement_sale', '!=', True)]}"
>
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_sale_subscription"/> <field name="module_agreement_sale_subscription" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Sale Subscriptions"/> <label
for="module_agreement_sale_subscription"
string="Sale Subscriptions"
/>
<div class="text-muted"> <div class="text-muted">
Link your subscriptions to an agreement Link your subscriptions to an agreement
</div> </div>
@@ -59,10 +74,13 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_fieldservice_agreement"/> <field name="module_fieldservice_agreement" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Field Service"/> <label
for="module_fieldservice_agreement"
string="Field Service"
/>
<div class="text-muted"> <div class="text-muted">
Link your Field Service orders and equipments to an agreement Link your Field Service orders and equipments to an agreement
</div> </div>
@@ -70,10 +88,13 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_stock"/> <field name="module_agreement_stock" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Inventory"/> <label
for="module_agreement_stock"
string="Inventory"
/>
<div class="text-muted"> <div class="text-muted">
Link your transfers to an agreement Link your transfers to an agreement
</div> </div>
@@ -81,10 +102,10 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_rma"/> <field name="module_agreement_rma" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Returns"/> <label for="module_agreement_rma" string="Returns" />
<div class="text-muted"> <div class="text-muted">
Link your returns to an agreement Link your returns to an agreement
</div> </div>
@@ -92,10 +113,13 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_maintenance"/> <field name="module_agreement_maintenance" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Maintenance"/> <label
for="module_agreement_maintenance"
string="Maintenance"
/>
<div class="text-muted"> <div class="text-muted">
Manage maintenance agreements and contracts Manage maintenance agreements and contracts
</div> </div>
@@ -103,10 +127,13 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_mrp"/> <field name="module_agreement_mrp" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Manufacturing"/> <label
for="module_agreement_mrp"
string="Manufacturing"
/>
<div class="text-muted"> <div class="text-muted">
Link your manufacturing orders to an agreement Link your manufacturing orders to an agreement
</div> </div>
@@ -114,10 +141,10 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_repair"/> <field name="module_agreement_repair" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Repair"/> <label for="module_agreement_repair" string="Repair" />
<div class="text-muted"> <div class="text-muted">
Link your repair orders to an agreement Link your repair orders to an agreement
</div> </div>
@@ -125,10 +152,13 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_project"/> <field name="module_agreement_project" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Project"/> <label
for="module_agreement_project"
string="Project"
/>
<div class="text-muted"> <div class="text-muted">
Link your projects and tasks to an agreement Link your projects and tasks to an agreement
</div> </div>
@@ -136,10 +166,13 @@
</div> </div>
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_agreement_helpdesk"/> <field name="module_agreement_helpdesk" />
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="" string="Helpdesk"/> <label
for="module_agreement_helpdesk"
string="Helpdesk"
/>
<div class="text-muted"> <div class="text-muted">
Link your Helpdesk tickets to an agreement Link your Helpdesk tickets to an agreement
</div> </div>
@@ -151,11 +184,12 @@
</field> </field>
</record> </record>
<act_window id="action_agreement_config" <record id="action_agreement_config" model="ir.actions.act_window">
name="Settings" <field name="name">Settings</field>
res_model="res.config.settings" <field name="res_model">res.config.settings</field>
view_mode="form" <field name="view_mode">form</field>
target="inline" <field name="target">inline</field>
context="{'module': 'agreement'}"/> <field name="context">{'module': 'agreement'}</field>
</record>
</odoo> </odoo>

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<record model="ir.ui.view" id="partner_form"> <record model="ir.ui.view" id="partner_form">
<field name="model">res.partner</field> <field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/> <field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//page[@name='internal_notes']" position="after"> <xpath expr="//page[@name='internal_notes']" position="after">
<page name="agreement" string="Agreements"> <page name="agreement" string="Agreements">
<group> <group>
<field name="agreement_ids" nolabel="1"/> <field name="agreement_ids" nolabel="1" />
</group> </group>
</page> </page>
</xpath> </xpath>
</field> </field>
</record> </record>
</odoo> </odoo>