Browse Source
Merge pull request #301 from ygol/12.0-mig-ag_legal
Merge pull request #301 from ygol/12.0-mig-ag_legal
[MIG] agreement --> agreement_legalpull/303/head
Maxime Chambreuil
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 6887 additions and 0 deletions
-
130agreement_legal/README.rst
-
4agreement_legal/__init__.py
-
41agreement_legal/__manifest__.py
-
49agreement_legal/data/agreement_stage.xml
-
16agreement_legal/data/agreement_type.xml
-
13agreement_legal/data/ir_sequence.xml
-
9agreement_legal/data/module_category.xml
-
1782agreement_legal/i18n/agreement_legal.pot
-
1800agreement_legal/i18n/fr.po
-
18agreement_legal/models/__init__.py
-
408agreement_legal/models/agreement.py
-
101agreement_legal/models/agreement_appendix.py
-
103agreement_legal/models/agreement_clause.py
-
27agreement_legal/models/agreement_increasetype.py
-
30agreement_legal/models/agreement_line.py
-
99agreement_legal/models/agreement_recital.py
-
23agreement_legal/models/agreement_renewaltype.py
-
102agreement_legal/models/agreement_section.py
-
28agreement_legal/models/agreement_stage.py
-
12agreement_legal/models/agreement_status.py
-
14agreement_legal/models/agreement_subtype.py
-
16agreement_legal/models/agreement_type.py
-
12agreement_legal/models/product_template.py
-
38agreement_legal/models/res_config_settings.py
-
13agreement_legal/models/res_partner.py
-
6agreement_legal/readme/CONFIGURE.rst
-
6agreement_legal/readme/CONTRIBUTORS.rst
-
5agreement_legal/readme/CREDITS.rst
-
9agreement_legal/readme/DESCRIPTION.rst
-
3agreement_legal/readme/ROADMAP.rst
-
7agreement_legal/readme/USAGE.rst
-
144agreement_legal/report/agreement.xml
-
23agreement_legal/security/ir.model.access.csv
-
22agreement_legal/security/res_groups.xml
-
BINagreement_legal/static/description/icon.png
-
473agreement_legal/static/description/index.html
-
362agreement_legal/views/agreement.xml
-
95agreement_legal/views/agreement_appendix.xml
-
97agreement_legal/views/agreement_clause.xml
-
45agreement_legal/views/agreement_increasetype.xml
-
94agreement_legal/views/agreement_recital.xml
-
41agreement_legal/views/agreement_renewaltype.xml
-
109agreement_legal/views/agreement_section.xml
-
43agreement_legal/views/agreement_stages.xml
-
45agreement_legal/views/agreement_subtype.xml
-
45agreement_legal/views/agreement_type.xml
-
147agreement_legal/views/menu.xml
-
161agreement_legal/views/res_config_settings.xml
-
17agreement_legal/views/res_partner.xml
@ -0,0 +1,130 @@ |
|||||
|
========== |
||||
|
Agreements |
||||
|
========== |
||||
|
|
||||
|
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||||
|
!! This file is generated by oca-gen-addon-readme !! |
||||
|
!! changes will be overwritten. !! |
||||
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||||
|
|
||||
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png |
||||
|
:target: https://odoo-community.org/page/development-status |
||||
|
:alt: Beta |
||||
|
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fcontract-lightgray.png?logo=github |
||||
|
:target: https://github.com/OCA/contract/tree/11.0/agreement |
||||
|
:alt: OCA/contract |
||||
|
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png |
||||
|
:target: https://translation.odoo-community.org/projects/contract-11-0/contract-11-0-agreement |
||||
|
:alt: Translate me on Weblate |
||||
|
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png |
||||
|
:target: https://runbot.odoo-community.org/runbot/110/11.0 |
||||
|
:alt: Try me on Runbot |
||||
|
|
||||
|
|badge1| |badge2| |badge3| |badge4| |badge5| |
||||
|
|
||||
|
This module allows you to manage agreements, letter of intent and contract content. |
||||
|
The module is meant to be used by the legal team of a company and to allow them |
||||
|
to define sections, clauses and templates with their respective content that can |
||||
|
be dynamic. |
||||
|
|
||||
|
Based on the template, an agreement can be created and the pdf document generated. |
||||
|
|
||||
|
The agreement would go through a workflow to finally become a contract with the |
||||
|
customer signature. |
||||
|
|
||||
|
**Table of contents** |
||||
|
|
||||
|
.. contents:: |
||||
|
:local: |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
To configure this module: |
||||
|
|
||||
|
* Go to Agreement > Configuration > Templates |
||||
|
* Create a new template with sections and clauses and their respective content |
||||
|
* Go to Agreement > Configuration > Stages |
||||
|
* Create and reorder stages to match your process |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
To use this module: |
||||
|
|
||||
|
* Go to Agreement > Agrements |
||||
|
* Create a new agreement |
||||
|
* Select a template |
||||
|
* Follow the process to get the required approval |
||||
|
* Send the invitation to the customer to review and sign the agreement |
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
* Split the module to remove the dependencies on sale and account and provide |
||||
|
the same feature in extra modules (agreement_sale, agreement_account, |
||||
|
agreement_purchase) |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/contract/issues>`_. |
||||
|
In case of trouble, please check there if your issue has already been reported. |
||||
|
If you spotted it first, help us smashing it by providing a detailed and welcomed |
||||
|
`feedback <https://github.com/OCA/contract/issues/new?body=module:%20agreement%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
||||
|
|
||||
|
Do not contact contributors directly about support or help with technical issues. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Authors |
||||
|
~~~~~~~ |
||||
|
|
||||
|
* Pavlov Media |
||||
|
* Open Source Integrators |
||||
|
|
||||
|
Contributors |
||||
|
~~~~~~~~~~~~ |
||||
|
|
||||
|
* Patrick Wilson <pwilson@pavlovmedia.com> |
||||
|
* Bhavesh Odedra <bodedra@opensourceintegrators.com> |
||||
|
* Wolfgang Hall <whall@opensourceintegrators.com> |
||||
|
* Maxime Chambreuil <mchambreuil@opensourceintegrators.com> |
||||
|
* Sandip Mangukiya <smangukiya@opensourceintegrators.com> |
||||
|
|
||||
|
Other credits |
||||
|
~~~~~~~~~~~~~ |
||||
|
|
||||
|
The development of this module has been financially supported by: |
||||
|
|
||||
|
* Pavlov Media |
||||
|
* Open Source Integrators |
||||
|
|
||||
|
Maintainers |
||||
|
~~~~~~~~~~~ |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
.. |maintainer-max3903| image:: https://github.com/max3903.png?size=40px |
||||
|
:target: https://github.com/max3903 |
||||
|
:alt: max3903 |
||||
|
|
||||
|
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__: |
||||
|
|
||||
|
|maintainer-max3903| |
||||
|
|
||||
|
This module is part of the `OCA/contract <https://github.com/OCA/contract/tree/11.0/agreement>`_ project on GitHub. |
||||
|
|
||||
|
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
@ -0,0 +1,4 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from . import models |
@ -0,0 +1,41 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
{ |
||||
|
"name": "Agreements Legal", |
||||
|
"summary": "Manage Agreements, LOI and Contracts", |
||||
|
"author": "Pavlov Media, " |
||||
|
"Open Source Integrators, " |
||||
|
"Yves Goldberg (Ygol Internetwork), " |
||||
|
"Odoo Community Association (OCA)", |
||||
|
"website": "https://github.com/OCA/contract", |
||||
|
"category": "Partner", |
||||
|
"license": "AGPL-3", |
||||
|
"version": "12.0.1.0.0", |
||||
|
"depends": ["contacts", "agreement", "product"], |
||||
|
"data": [ |
||||
|
"data/ir_sequence.xml", |
||||
|
"data/module_category.xml", |
||||
|
"data/agreement_stage.xml", |
||||
|
"data/agreement_type.xml", |
||||
|
"security/res_groups.xml", |
||||
|
"security/ir.model.access.csv", |
||||
|
"report/agreement.xml", |
||||
|
"views/res_config_settings.xml", |
||||
|
"views/agreement_appendix.xml", |
||||
|
"views/agreement_clause.xml", |
||||
|
"views/agreement_recital.xml", |
||||
|
"views/agreement_section.xml", |
||||
|
"views/agreement_stages.xml", |
||||
|
"views/agreement_type.xml", |
||||
|
"views/agreement_subtype.xml", |
||||
|
"views/agreement_renewaltype.xml", |
||||
|
"views/agreement_increasetype.xml", |
||||
|
"views/res_partner.xml", |
||||
|
"views/agreement.xml", |
||||
|
"views/menu.xml", |
||||
|
], |
||||
|
"application": True, |
||||
|
"development_status": "Beta", |
||||
|
"maintainers": ["max3903", "ygol"], |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="agreement_stage_new" model="agreement.stage"> |
||||
|
<field name="name">New</field> |
||||
|
<field name="sequence">10</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_draft" model="agreement.stage"> |
||||
|
<field name="name">Draft</field> |
||||
|
<field name="sequence">20</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_reviewed" model="agreement.stage"> |
||||
|
<field name="name">Reviewed</field> |
||||
|
<field name="sequence">30</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_negotiation" model="agreement.stage"> |
||||
|
<field name="name">Negotiation</field> |
||||
|
<field name="sequence">40</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_out" model="agreement.stage"> |
||||
|
<field name="name">Out for Customer Signature</field> |
||||
|
<field name="sequence">50</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_internal" model="agreement.stage"> |
||||
|
<field name="name">Waiting Internal Signature</field> |
||||
|
<field name="sequence">60</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_active" model="agreement.stage"> |
||||
|
<field name="name">Active</field> |
||||
|
<field name="sequence">70</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_expired" model="agreement.stage"> |
||||
|
<field name="name">Expired</field> |
||||
|
<field name="sequence">80</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_stage_cancelled" model="agreement.stage"> |
||||
|
<field name="name">Cancelled</field> |
||||
|
<field name="sequence">100</field> |
||||
|
<field name="fold">True</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="agreement_type_agreement" model="agreement.type"> |
||||
|
<field name="name">Agreement</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_type_contract" model="agreement.type"> |
||||
|
<field name="name">Contract</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_type_loi" model="agreement.type"> |
||||
|
<field name="name">Letter of Intent</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,13 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo noupdate="1"> |
||||
|
|
||||
|
<!-- Sequence for agreement --> |
||||
|
<record id="seq_agreement" model="ir.sequence"> |
||||
|
<field name="name">Agreements</field> |
||||
|
<field name="code">agreement</field> |
||||
|
<field name="prefix">AG</field> |
||||
|
<field name="padding">3</field> |
||||
|
<field name="company_id" eval="False"/> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,9 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="agreement" model="ir.module.category"> |
||||
|
<field name="name">Agreement</field> |
||||
|
<field name="sequence">80</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
1782
agreement_legal/i18n/agreement_legal.pot
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1800
agreement_legal/i18n/fr.po
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,18 @@ |
|||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from . import ( |
||||
|
res_config_settings, |
||||
|
agreement_stage, |
||||
|
agreement, |
||||
|
agreement_appendix, |
||||
|
agreement_clause, |
||||
|
agreement_line, |
||||
|
agreement_recital, |
||||
|
agreement_section, |
||||
|
agreement_type, |
||||
|
agreement_subtype, |
||||
|
res_partner, |
||||
|
product_template, |
||||
|
agreement_renewaltype, |
||||
|
agreement_increasetype, |
||||
|
) |
@ -0,0 +1,408 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import _, api, fields, models |
||||
|
|
||||
|
|
||||
|
class Agreement(models.Model): |
||||
|
_name = "agreement" |
||||
|
_inherit = ["agreement", "mail.thread"] |
||||
|
|
||||
|
def _default_stage_id(self): |
||||
|
return self.env.ref("agreement_legal.agreement_stage_new") |
||||
|
|
||||
|
# General |
||||
|
name = fields.Char(string="Title", required=True) |
||||
|
is_template = fields.Boolean( |
||||
|
string="Is a Template?", |
||||
|
default=False, |
||||
|
copy=False, |
||||
|
help="Make this agreement a template.", |
||||
|
) |
||||
|
version = fields.Integer( |
||||
|
string="Version", |
||||
|
default=1, |
||||
|
copy=False, |
||||
|
help="The versions are used to keep track of document history and " |
||||
|
"previous versions can be referenced.", |
||||
|
) |
||||
|
revision = fields.Integer( |
||||
|
string="Revision", |
||||
|
default=0, |
||||
|
copy=False, |
||||
|
help="The revision will increase with every save event.", |
||||
|
) |
||||
|
description = fields.Text( |
||||
|
string="Description", |
||||
|
track_visibility="onchange", |
||||
|
help="Description of the agreement", |
||||
|
) |
||||
|
dynamic_description = fields.Text( |
||||
|
compute="_compute_dynamic_description", |
||||
|
string="Dynamic Description", |
||||
|
help="Compute dynamic description", |
||||
|
) |
||||
|
start_date = fields.Date( |
||||
|
string="Start Date", |
||||
|
track_visibility="onchange", |
||||
|
help="When the agreement starts.", |
||||
|
) |
||||
|
end_date = fields.Date( |
||||
|
string="End Date", |
||||
|
track_visibility="onchange", |
||||
|
help="When the agreement ends.", |
||||
|
) |
||||
|
color = fields.Integer() |
||||
|
active = fields.Boolean( |
||||
|
string="Active", |
||||
|
default=True, |
||||
|
help="If unchecked, it will allow you to hide the agreement without " |
||||
|
"removing it.", |
||||
|
) |
||||
|
company_signed_date = fields.Date( |
||||
|
string="Signed on", |
||||
|
track_visibility="onchange", |
||||
|
help="Date the contract was signed by Company.", |
||||
|
) |
||||
|
partner_signed_date = fields.Date( |
||||
|
string="Signed on", |
||||
|
track_visibility="onchange", |
||||
|
help="Date the contract was signed by the Partner.", |
||||
|
) |
||||
|
term = fields.Integer( |
||||
|
string="Term (Months)", |
||||
|
track_visibility="onchange", |
||||
|
help="Number of months this agreement/contract is in effect with the " |
||||
|
"partner.", |
||||
|
) |
||||
|
expiration_notice = fields.Integer( |
||||
|
string="Exp. Notice (Days)", |
||||
|
track_visibility="onchange", |
||||
|
help="Number of Days before expiration to be notified.", |
||||
|
) |
||||
|
change_notice = fields.Integer( |
||||
|
string="Change Notice (Days)", |
||||
|
track_visibility="onchange", |
||||
|
help="Number of Days to be notified before changes.", |
||||
|
) |
||||
|
special_terms = fields.Text( |
||||
|
string="Special Terms", |
||||
|
track_visibility="onchange", |
||||
|
help="Any terms that you have agreed to and want to track on the " |
||||
|
"agreement/contract.", |
||||
|
) |
||||
|
dynamic_special_terms = fields.Text( |
||||
|
compute="_compute_dynamic_special_terms", |
||||
|
string="Dynamic Special Terms", |
||||
|
help="Compute dynamic special terms", |
||||
|
) |
||||
|
reference = fields.Char( |
||||
|
string="Reference", |
||||
|
copy=False, |
||||
|
required=True, |
||||
|
default=lambda self: _("New"), |
||||
|
track_visibility="onchange", |
||||
|
help="ID used for internal contract tracking.", |
||||
|
) |
||||
|
increase_type_id = fields.Many2one( |
||||
|
"agreement.increasetype", |
||||
|
string="Increase Type", |
||||
|
track_visibility="onchange", |
||||
|
help="The amount that certain rates may increase.", |
||||
|
) |
||||
|
termination_requested = fields.Date( |
||||
|
string="Termination Requested Date", |
||||
|
track_visibility="onchange", |
||||
|
help="Date that a request for termination was received.", |
||||
|
) |
||||
|
termination_date = fields.Date( |
||||
|
string="Termination Date", |
||||
|
track_visibility="onchange", |
||||
|
help="Date that the contract was terminated.", |
||||
|
) |
||||
|
reviewed_date = fields.Date( |
||||
|
string="Reviewed Date", track_visibility="onchange" |
||||
|
) |
||||
|
reviewed_user_id = fields.Many2one( |
||||
|
"res.users", string="Reviewed By", track_visibility="onchange" |
||||
|
) |
||||
|
approved_date = fields.Date( |
||||
|
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") |
||||
|
partner_id = fields.Many2one( |
||||
|
"res.partner", |
||||
|
string="Partner", |
||||
|
copy=True, |
||||
|
help="The customer or vendor this agreement is related to.", |
||||
|
) |
||||
|
company_partner_id = fields.Many2one( |
||||
|
"res.partner", |
||||
|
string="Company", |
||||
|
copy=True, |
||||
|
default=lambda self: self.env.user.company_id.partner_id, |
||||
|
) |
||||
|
partner_contact_id = fields.Many2one( |
||||
|
"res.partner", |
||||
|
string="Partner Contact", |
||||
|
copy=True, |
||||
|
help="The primary partner contact (If Applicable).", |
||||
|
) |
||||
|
partner_contact_phone = fields.Char( |
||||
|
related="partner_contact_id.phone", string="Phone" |
||||
|
) |
||||
|
partner_contact_email = fields.Char( |
||||
|
related="partner_contact_id.email", string="Email" |
||||
|
) |
||||
|
company_contact_id = fields.Many2one( |
||||
|
"res.partner", |
||||
|
string="Company Contact", |
||||
|
copy=True, |
||||
|
help="The primary contact in the company.", |
||||
|
) |
||||
|
company_contact_phone = fields.Char( |
||||
|
related="company_contact_id.phone", string="Phone" |
||||
|
) |
||||
|
company_contact_email = fields.Char( |
||||
|
related="company_contact_id.email", string="Email" |
||||
|
) |
||||
|
agreement_type_id = fields.Many2one( |
||||
|
"agreement.type", |
||||
|
string="Agreement Type", |
||||
|
track_visibility="onchange", |
||||
|
help="Select the type of agreement.", |
||||
|
) |
||||
|
agreement_subtype_id = fields.Many2one( |
||||
|
"agreement.subtype", |
||||
|
string="Agreement Sub-type", |
||||
|
track_visibility="onchange", |
||||
|
help="Select the sub-type of this agreement. Sub-Types are related to " |
||||
|
"agreement types.", |
||||
|
) |
||||
|
product_ids = fields.Many2many( |
||||
|
"product.template", string="Products & Services" |
||||
|
) |
||||
|
assigned_user_id = fields.Many2one( |
||||
|
"res.users", |
||||
|
string="Assigned To", |
||||
|
track_visibility="onchange", |
||||
|
help="Select the user who manages this agreement.", |
||||
|
) |
||||
|
company_signed_user_id = fields.Many2one( |
||||
|
"res.users", |
||||
|
string="Signed By", |
||||
|
track_visibility="onchange", |
||||
|
help="The user at our company who authorized/signed the agreement or " |
||||
|
"contract.", |
||||
|
) |
||||
|
partner_signed_user_id = fields.Many2one( |
||||
|
"res.partner", |
||||
|
string="Signed By", |
||||
|
track_visibility="onchange", |
||||
|
help="Contact on the account that signed the agreement/contract.", |
||||
|
) |
||||
|
parent_agreement_id = fields.Many2one( |
||||
|
"agreement", |
||||
|
string="Parent Agreement", |
||||
|
help="Link this agreement to a parent agreement. For example if this " |
||||
|
"agreement is an amendment to another agreement. This list will " |
||||
|
"only show other agreements related to the same account.", |
||||
|
) |
||||
|
renewal_type_id = fields.Many2one( |
||||
|
"agreement.renewaltype", |
||||
|
string="Renewal Type", |
||||
|
track_visibility="onchange", |
||||
|
help="Describes what happens after the contract expires.", |
||||
|
) |
||||
|
recital_ids = fields.One2many( |
||||
|
"agreement.recital", "agreement_id", string="Recitals", copy=True |
||||
|
) |
||||
|
sections_ids = fields.One2many( |
||||
|
"agreement.section", "agreement_id", string="Sections", copy=True |
||||
|
) |
||||
|
clauses_ids = fields.One2many( |
||||
|
"agreement.clause", "agreement_id", string="Clauses", copy=True |
||||
|
) |
||||
|
appendix_ids = fields.One2many( |
||||
|
"agreement.appendix", "agreement_id", string="Appendices", copy=True |
||||
|
) |
||||
|
previous_version_agreements_ids = fields.One2many( |
||||
|
"agreement", |
||||
|
"parent_agreement_id", |
||||
|
string="Child Agreements", |
||||
|
copy=False, |
||||
|
domain=[("active", "=", False)], |
||||
|
) |
||||
|
child_agreements_ids = fields.One2many( |
||||
|
"agreement", |
||||
|
"parent_agreement_id", |
||||
|
string="Child Agreements", |
||||
|
copy=False, |
||||
|
domain=[("active", "=", True)], |
||||
|
) |
||||
|
line_ids = fields.One2many( |
||||
|
"agreement.line", |
||||
|
"agreement_id", |
||||
|
string="Products/Services", |
||||
|
copy=False, |
||||
|
) |
||||
|
state = fields.Selection( |
||||
|
[("draft", "Draft"), ("active", "Active"), ("inactive", "Inactive")], |
||||
|
default="draft", |
||||
|
track_visibility="always", |
||||
|
) |
||||
|
notification_address_id = fields.Many2one( |
||||
|
"res.partner", |
||||
|
string="Notification Address", |
||||
|
help="The address to send notificaitons to, if different from " |
||||
|
"customer address.(Address Type = Other)", |
||||
|
) |
||||
|
signed_contract_filename = fields.Char(string="Filename") |
||||
|
signed_contract = fields.Binary( |
||||
|
string="Signed Document", track_visibility="always" |
||||
|
) |
||||
|
field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Field", |
||||
|
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 |
||||
|
destination of the relationship.""", |
||||
|
) |
||||
|
sub_object_id = fields.Many2one( |
||||
|
"ir.model", |
||||
|
string="Sub-model", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field shows the document model the relationship goes to.""", |
||||
|
) |
||||
|
sub_model_object_field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Sub-field", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field lets you select the target field within the destination document |
||||
|
model (sub-model).""", |
||||
|
) |
||||
|
default_value = fields.Char( |
||||
|
string="Default Value", |
||||
|
help="Optional value to use if the target field is empty.", |
||||
|
) |
||||
|
copyvalue = fields.Char( |
||||
|
string="Placeholder Expression", |
||||
|
help="""Final placeholder expression, to be copy-pasted in the desired |
||||
|
template field.""", |
||||
|
) |
||||
|
|
||||
|
# compute the dynamic content for mako expression |
||||
|
@api.multi |
||||
|
def _compute_dynamic_description(self): |
||||
|
MailTemplates = self.env["mail.template"] |
||||
|
for agreement in self: |
||||
|
lang = agreement.partner_id.lang or "en_US" |
||||
|
description = MailTemplates.with_context( |
||||
|
lang=lang |
||||
|
)._render_template( |
||||
|
agreement.description, "agreement", agreement.id |
||||
|
) |
||||
|
agreement.dynamic_description = description |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_dynamic_special_terms(self): |
||||
|
MailTemplates = self.env["mail.template"] |
||||
|
for agreement in self: |
||||
|
lang = agreement.partner_id.lang or "en_US" |
||||
|
special_terms = MailTemplates.with_context( |
||||
|
lang=lang |
||||
|
)._render_template( |
||||
|
agreement.special_terms, "agreement", agreement.id |
||||
|
) |
||||
|
agreement.dynamic_special_terms = special_terms |
||||
|
|
||||
|
@api.onchange("field_id", "sub_model_object_field_id", "default_value") |
||||
|
def onchange_copyvalue(self): |
||||
|
self.sub_object_id = False |
||||
|
self.copyvalue = False |
||||
|
self.sub_object_id = False |
||||
|
if self.field_id and not self.field_id.relation: |
||||
|
self.copyvalue = "${{object.{} or {}}}".format( |
||||
|
self.field_id.name, self.default_value or "''" |
||||
|
) |
||||
|
self.sub_model_object_field_id = False |
||||
|
if self.field_id and self.field_id.relation: |
||||
|
self.sub_object_id = self.env["ir.model"].search( |
||||
|
[("model", "=", self.field_id.relation)] |
||||
|
)[0] |
||||
|
if self.sub_model_object_field_id: |
||||
|
self.copyvalue = "${{object.{}.{} or {}}}".format( |
||||
|
self.field_id.name, |
||||
|
self.sub_model_object_field_id.name, |
||||
|
self.default_value or "''", |
||||
|
) |
||||
|
|
||||
|
# Used for Kanban grouped_by view |
||||
|
@api.model |
||||
|
def _read_group_stage_ids(self, stages, domain, order): |
||||
|
stage_ids = self.env["agreement.stage"].search([]) |
||||
|
return stage_ids |
||||
|
|
||||
|
stage_id = fields.Many2one( |
||||
|
"agreement.stage", |
||||
|
string="Stage", |
||||
|
group_expand="_read_group_stage_ids", |
||||
|
help="Select the current stage of the agreement.", |
||||
|
track_visibility="onchange", |
||||
|
index=True, |
||||
|
# default=lambda self: self._default_stage_id(), |
||||
|
) |
||||
|
|
||||
|
# Create New Version Button |
||||
|
@api.multi |
||||
|
def create_new_version(self, vals): |
||||
|
for rec in self: |
||||
|
if not rec.state == "draft": |
||||
|
# Make sure status is draft |
||||
|
rec.state = "draft" |
||||
|
default_vals = { |
||||
|
"name": "{} - OLD VERSION".format(rec.name), |
||||
|
"active": False, |
||||
|
"parent_agreement_id": rec.id, |
||||
|
} |
||||
|
# Make a current copy and mark it as old |
||||
|
rec.copy(default=default_vals) |
||||
|
# Increment the Version |
||||
|
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): |
||||
|
default_vals = { |
||||
|
"name": "NEW", |
||||
|
"active": True, |
||||
|
"version": 1, |
||||
|
"revision": 0, |
||||
|
"state": "draft", |
||||
|
} |
||||
|
res = self.copy(default=default_vals) |
||||
|
return { |
||||
|
"res_model": "agreement", |
||||
|
"type": "ir.actions.act_window", |
||||
|
"view_mode": "form", |
||||
|
"view_type": "form", |
||||
|
"res_id": res.id, |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, vals): |
||||
|
if vals.get("reference", _("New")) == _("New"): |
||||
|
vals["reference"] = self.env["ir.sequence"].next_by_code( |
||||
|
"agreement" |
||||
|
) or _("New") |
||||
|
return super(Agreement, self).create(vals) |
||||
|
|
||||
|
# Increments the revision on each save action |
||||
|
@api.multi |
||||
|
def write(self, vals): |
||||
|
vals["revision"] = self.revision + 1 |
||||
|
return super(Agreement, self).write(vals) |
@ -0,0 +1,101 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AgreementAppendix(models.Model): |
||||
|
_name = "agreement.appendix" |
||||
|
_description = "Agreement Appendices" |
||||
|
_order = "sequence" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
title = fields.Char( |
||||
|
string="Title", |
||||
|
required=True, |
||||
|
help="The title is displayed on the PDF." "The name is not.", |
||||
|
) |
||||
|
sequence = fields.Integer( |
||||
|
string="Sequence", |
||||
|
default=10) |
||||
|
content = fields.Html(string="Content") |
||||
|
dynamic_content = fields.Html( |
||||
|
compute="_compute_dynamic_content", |
||||
|
string="Dynamic Content", |
||||
|
help="compute dynamic Content", |
||||
|
) |
||||
|
agreement_id = fields.Many2one( |
||||
|
"agreement", |
||||
|
string="Agreement", |
||||
|
ondelete="cascade") |
||||
|
active = fields.Boolean( |
||||
|
string="Active", |
||||
|
default=True, |
||||
|
help="If unchecked, it will allow you to hide this appendix without " |
||||
|
"removing it.", |
||||
|
) |
||||
|
|
||||
|
# Dynamic field editor |
||||
|
field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Field", |
||||
|
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 |
||||
|
destination of the relationship.""", |
||||
|
) |
||||
|
sub_object_id = fields.Many2one( |
||||
|
"ir.model", |
||||
|
string="Sub-model", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field shows the document model the relationship goes to.""", |
||||
|
) |
||||
|
sub_model_object_field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Sub-field", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field lets you select the target field within the destination document |
||||
|
model (sub-model).""", |
||||
|
) |
||||
|
default_value = fields.Char( |
||||
|
string="Default Value", |
||||
|
help="Optional value to use if the target field is empty.", |
||||
|
) |
||||
|
copyvalue = fields.Char( |
||||
|
string="Placeholder Expression", |
||||
|
help="""Final placeholder expression, to be copy-pasted in the desired |
||||
|
template field.""", |
||||
|
) |
||||
|
|
||||
|
@api.onchange('field_id', 'sub_model_object_field_id', 'default_value') |
||||
|
def onchange_copyvalue(self): |
||||
|
self.sub_object_id = False |
||||
|
self.copyvalue = False |
||||
|
self.sub_object_id = False |
||||
|
if self.field_id and not self.field_id.relation: |
||||
|
self.copyvalue = "${object.%s or %s}" % \ |
||||
|
(self.field_id.name, |
||||
|
self.default_value or '\'\'') |
||||
|
self.sub_model_object_field_id = False |
||||
|
if self.field_id and self.field_id.relation: |
||||
|
self.sub_object_id = self.env['ir.model'].search( |
||||
|
[('model', '=', self.field_id.relation)])[0] |
||||
|
if self.sub_model_object_field_id: |
||||
|
self.copyvalue = "${object.%s.%s or %s}" %\ |
||||
|
(self.field_id.name, |
||||
|
self.sub_model_object_field_id.name, |
||||
|
self.default_value or '\'\'') |
||||
|
|
||||
|
# compute the dynamic content for mako expression |
||||
|
@api.multi |
||||
|
def _compute_dynamic_content(self): |
||||
|
MailTemplates = self.env["mail.template"] |
||||
|
for appendix in self: |
||||
|
lang = ( |
||||
|
appendix.agreement_id |
||||
|
and appendix.agreement_id.partner_id.lang |
||||
|
or "en_US" |
||||
|
) |
||||
|
content = MailTemplates.with_context(lang=lang)._render_template( |
||||
|
appendix.content, "agreement.appendix", appendix.id |
||||
|
) |
||||
|
appendix.dynamic_content = content |
@ -0,0 +1,103 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AgreementClause(models.Model): |
||||
|
_name = "agreement.clause" |
||||
|
_description = "Agreement Clauses" |
||||
|
_order = "sequence" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
title = fields.Char( |
||||
|
string="Title", |
||||
|
help="The title is displayed on the PDF." "The name is not." |
||||
|
) |
||||
|
sequence = fields.Integer(string="Sequence") |
||||
|
agreement_id = fields.Many2one( |
||||
|
"agreement", |
||||
|
string="Agreement", |
||||
|
ondelete="cascade") |
||||
|
section_id = fields.Many2one( |
||||
|
"agreement.section", |
||||
|
string="Section", |
||||
|
ondelete="cascade" |
||||
|
) |
||||
|
content = fields.Html(string="Clause Content") |
||||
|
dynamic_content = fields.Html( |
||||
|
compute="_compute_dynamic_content", |
||||
|
string="Dynamic Content", |
||||
|
help="compute dynamic Content", |
||||
|
) |
||||
|
active = fields.Boolean( |
||||
|
string="Active", |
||||
|
default=True, |
||||
|
help="If unchecked, it will allow you to hide the agreement without " |
||||
|
"removing it.", |
||||
|
) |
||||
|
|
||||
|
# Dynamic field editor |
||||
|
field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Field", |
||||
|
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 |
||||
|
destination of the relationship.""", |
||||
|
) |
||||
|
sub_object_id = fields.Many2one( |
||||
|
"ir.model", |
||||
|
string="Sub-model", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field shows the document model the relationship goes to.""", |
||||
|
) |
||||
|
sub_model_object_field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Sub-field", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field lets you select the target field within the destination document |
||||
|
model (sub-model).""", |
||||
|
) |
||||
|
default_value = fields.Char( |
||||
|
string="Default Value", |
||||
|
help="Optional value to use if the target field is empty.", |
||||
|
) |
||||
|
copyvalue = fields.Char( |
||||
|
string="Placeholder Expression", |
||||
|
help="""Final placeholder expression, to be copy-pasted in the desired |
||||
|
template field.""", |
||||
|
) |
||||
|
|
||||
|
@api.onchange('field_id', 'sub_model_object_field_id', 'default_value') |
||||
|
def onchange_copyvalue(self): |
||||
|
self.sub_object_id = False |
||||
|
self.copyvalue = False |
||||
|
self.sub_object_id = False |
||||
|
if self.field_id and not self.field_id.relation: |
||||
|
self.copyvalue = "${object.%s or %s}" % \ |
||||
|
(self.field_id.name, |
||||
|
self.default_value or '\'\'') |
||||
|
self.sub_model_object_field_id = False |
||||
|
if self.field_id and self.field_id.relation: |
||||
|
self.sub_object_id = self.env['ir.model'].search( |
||||
|
[('model', '=', self.field_id.relation)])[0] |
||||
|
if self.sub_model_object_field_id: |
||||
|
self.copyvalue = "${object.%s.%s or %s}" %\ |
||||
|
(self.field_id.name, |
||||
|
self.sub_model_object_field_id.name, |
||||
|
self.default_value or '\'\'') |
||||
|
|
||||
|
# compute the dynamic content for mako expression |
||||
|
@api.multi |
||||
|
def _compute_dynamic_content(self): |
||||
|
MailTemplates = self.env["mail.template"] |
||||
|
for clause in self: |
||||
|
lang = ( |
||||
|
clause.agreement_id |
||||
|
and clause.agreement_id.partner_id.lang |
||||
|
or "en_US" |
||||
|
) |
||||
|
content = MailTemplates.with_context(lang=lang)._render_template( |
||||
|
clause.content, "agreement.clause", clause.id |
||||
|
) |
||||
|
clause.dynamic_content = content |
@ -0,0 +1,27 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
# Main Agreement Increase Type Records Model |
||||
|
class AgreementIncreaseType(models.Model): |
||||
|
_name = "agreement.increasetype" |
||||
|
_description = "Agreement Increase Type" |
||||
|
|
||||
|
# General |
||||
|
name = fields.Char( |
||||
|
string="Title", |
||||
|
required=True, |
||||
|
help="Increase types describe any increases that may happen during " |
||||
|
"the contract.", |
||||
|
) |
||||
|
description = fields.Text( |
||||
|
string="Description", |
||||
|
required=True, |
||||
|
help="Description of the renewal type." |
||||
|
) |
||||
|
increase_percent = fields.Integer( |
||||
|
string="Increase Percentage", |
||||
|
help="Percentage that the amount will increase." |
||||
|
) |
@ -0,0 +1,30 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AgreementLine(models.Model): |
||||
|
_name = "agreement.line" |
||||
|
_description = "Agreement Lines" |
||||
|
|
||||
|
product_id = fields.Many2one( |
||||
|
"product.product", |
||||
|
string="Product") |
||||
|
name = fields.Char( |
||||
|
string="Description", |
||||
|
required=True) |
||||
|
agreement_id = fields.Many2one( |
||||
|
"agreement", |
||||
|
string="Agreement", |
||||
|
ondelete="cascade") |
||||
|
qty = fields.Float(string="Quantity") |
||||
|
uom_id = fields.Many2one( |
||||
|
"uom.uom", |
||||
|
string="Unit of Measure", |
||||
|
required=True) |
||||
|
|
||||
|
@api.onchange("product_id") |
||||
|
def _onchange_product_id(self): |
||||
|
self.name = self.product_id.name |
||||
|
self.uom_id = self.product_id.uom_id.id |
@ -0,0 +1,99 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AgreementRecital(models.Model): |
||||
|
_name = "agreement.recital" |
||||
|
_description = "Agreement Recitals" |
||||
|
_order = "sequence" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
title = fields.Char( |
||||
|
string="Title", |
||||
|
help="The title is displayed on the PDF." "The name is not.", |
||||
|
) |
||||
|
sequence = fields.Integer(string="Sequence", default=10) |
||||
|
content = fields.Html(string="Content") |
||||
|
dynamic_content = fields.Html( |
||||
|
compute="_compute_dynamic_content", |
||||
|
string="Dynamic Content", |
||||
|
help="compute dynamic Content", |
||||
|
) |
||||
|
agreement_id = fields.Many2one( |
||||
|
"agreement", string="Agreement", ondelete="cascade" |
||||
|
) |
||||
|
active = fields.Boolean( |
||||
|
string="Active", |
||||
|
default=True, |
||||
|
help="If unchecked, it will allow you to hide this recital without " |
||||
|
"removing it.", |
||||
|
) |
||||
|
|
||||
|
# Dynamic field editor |
||||
|
field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Field", |
||||
|
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 |
||||
|
destination of the relationship.""", |
||||
|
) |
||||
|
sub_object_id = fields.Many2one( |
||||
|
"ir.model", |
||||
|
string="Sub-model", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field shows the document model the relationship goes to.""", |
||||
|
) |
||||
|
sub_model_object_field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Sub-field", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field lets you select the target field within the destination document |
||||
|
model (sub-model).""", |
||||
|
) |
||||
|
default_value = fields.Char( |
||||
|
string="Default Value", |
||||
|
help="Optional value to use if the target field is empty.", |
||||
|
) |
||||
|
copyvalue = fields.Char( |
||||
|
string="Placeholder Expression", |
||||
|
help="""Final placeholder expression, to be copy-pasted in the desired |
||||
|
template field.""", |
||||
|
) |
||||
|
|
||||
|
@api.onchange("field_id", "sub_model_object_field_id", "default_value") |
||||
|
def onchange_copyvalue(self): |
||||
|
self.sub_object_id = False |
||||
|
self.copyvalue = False |
||||
|
self.sub_object_id = False |
||||
|
if self.field_id and not self.field_id.relation: |
||||
|
self.copyvalue = "${{object.{} or {}}}".format( |
||||
|
self.field_id.name, self.default_value or "''" |
||||
|
) |
||||
|
self.sub_model_object_field_id = False |
||||
|
if self.field_id and self.field_id.relation: |
||||
|
self.sub_object_id = self.env["ir.model"].search( |
||||
|
[("model", "=", self.field_id.relation)] |
||||
|
)[0] |
||||
|
if self.sub_model_object_field_id: |
||||
|
self.copyvalue = "${{object.{}.{} or {}}}".format( |
||||
|
self.field_id.name, |
||||
|
self.sub_model_object_field_id.name, |
||||
|
self.default_value or "''", |
||||
|
) |
||||
|
|
||||
|
# compute the dynamic content for mako expression |
||||
|
@api.multi |
||||
|
def _compute_dynamic_content(self): |
||||
|
MailTemplates = self.env["mail.template"] |
||||
|
for recital in self: |
||||
|
lang = ( |
||||
|
recital.agreement_id |
||||
|
and recital.agreement_id.partner_id.lang |
||||
|
or "en_US" |
||||
|
) |
||||
|
content = MailTemplates.with_context(lang=lang)._render_template( |
||||
|
recital.content, "agreement.recital", recital.id |
||||
|
) |
||||
|
recital.dynamic_content = content |
@ -0,0 +1,23 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
# Main Agreement Section Records Model |
||||
|
class AgreementRenewalType(models.Model): |
||||
|
_name = "agreement.renewaltype" |
||||
|
_description = "Agreement Renewal Type" |
||||
|
|
||||
|
# General |
||||
|
name = fields.Char( |
||||
|
string="Title", |
||||
|
required=True, |
||||
|
help="Renewal types describe what happens after the " |
||||
|
"agreement/contract expires.", |
||||
|
) |
||||
|
description = fields.Text( |
||||
|
string="Description", |
||||
|
required=True, |
||||
|
help="Description of the renewal type." |
||||
|
) |
@ -0,0 +1,102 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AgreementSection(models.Model): |
||||
|
_name = "agreement.section" |
||||
|
_description = "Agreement Sections" |
||||
|
_order = "sequence" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
title = fields.Char( |
||||
|
string="Title", |
||||
|
help="The title is displayed on the PDF." "The name is not.", |
||||
|
) |
||||
|
sequence = fields.Integer(string="Sequence") |
||||
|
agreement_id = fields.Many2one( |
||||
|
"agreement", string="Agreement", ondelete="cascade" |
||||
|
) |
||||
|
clauses_ids = fields.One2many( |
||||
|
"agreement.clause", "section_id", string="Clauses" |
||||
|
) |
||||
|
content = fields.Html(string="Section Content") |
||||
|
dynamic_content = fields.Html( |
||||
|
compute="_compute_dynamic_content", |
||||
|
string="Dynamic Content", |
||||
|
help="compute dynamic Content", |
||||
|
) |
||||
|
active = fields.Boolean( |
||||
|
string="Active", |
||||
|
default=True, |
||||
|
help="""If unchecked, it will allow you to hide the |
||||
|
agreement without removing it.""", |
||||
|
) |
||||
|
|
||||
|
# Dynamic field editor |
||||
|
field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Field", |
||||
|
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 |
||||
|
destination of the relationship.""", |
||||
|
) |
||||
|
sub_object_id = fields.Many2one( |
||||
|
"ir.model", |
||||
|
string="Sub-model", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field shows the document model the relationship goes to.""", |
||||
|
) |
||||
|
sub_model_object_field_id = fields.Many2one( |
||||
|
"ir.model.fields", |
||||
|
string="Sub-field", |
||||
|
help="""When a relationship field is selected as first field, this |
||||
|
field lets you select the target field within the destination document |
||||
|
model (sub-model).""", |
||||
|
) |
||||
|
default_value = fields.Char( |
||||
|
string="Default Value", |
||||
|
help="Optional value to use if the target field is empty.", |
||||
|
) |
||||
|
copyvalue = fields.Char( |
||||
|
string="Placeholder Expression", |
||||
|
help="""Final placeholder expression, to be copy-pasted in the desired |
||||
|
template field.""", |
||||
|
) |
||||
|
|
||||
|
@api.onchange("field_id", "sub_model_object_field_id", "default_value") |
||||
|
def onchange_copyvalue(self): |
||||
|
self.sub_object_id = False |
||||
|
self.copyvalue = False |
||||
|
self.sub_object_id = False |
||||
|
if self.field_id and not self.field_id.relation: |
||||
|
self.copyvalue = "${{object.{} or {}}}".format( |
||||
|
self.field_id.name, self.default_value or "''" |
||||
|
) |
||||
|
self.sub_model_object_field_id = False |
||||
|
if self.field_id and self.field_id.relation: |
||||
|
self.sub_object_id = self.env["ir.model"].search( |
||||
|
[("model", "=", self.field_id.relation)] |
||||
|
)[0] |
||||
|
if self.sub_model_object_field_id: |
||||
|
self.copyvalue = "${{object.{}.{} or {}}}".format( |
||||
|
self.field_id.name, |
||||
|
self.sub_model_object_field_id.name, |
||||
|
self.default_value or "''", |
||||
|
) |
||||
|
|
||||
|
# compute the dynamic content for mako expression |
||||
|
@api.multi |
||||
|
def _compute_dynamic_content(self): |
||||
|
MailTemplates = self.env["mail.template"] |
||||
|
for section in self: |
||||
|
lang = ( |
||||
|
section.agreement_id |
||||
|
and section.agreement_id.partner_id.lang |
||||
|
or "en_US" |
||||
|
) |
||||
|
content = MailTemplates.with_context(lang=lang)._render_template( |
||||
|
section.content, "agreement.section", section.id |
||||
|
) |
||||
|
section.dynamic_content = content |
@ -0,0 +1,28 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
# Main Agreement Section Records Model |
||||
|
class AgreementStage(models.Model): |
||||
|
_name = "agreement.stage" |
||||
|
_description = "Agreement Stages" |
||||
|
_order = "sequence" |
||||
|
|
||||
|
# General |
||||
|
name = fields.Char( |
||||
|
string="Stage Name", |
||||
|
required=True) |
||||
|
description = fields.Text( |
||||
|
string="Description", |
||||
|
required=False) |
||||
|
sequence = fields.Integer( |
||||
|
string="Sequence", |
||||
|
default="1", |
||||
|
required=False) |
||||
|
fold = fields.Boolean( |
||||
|
string="Is Folded", |
||||
|
required=False, |
||||
|
help="This stage is folded in the kanban view by deafault.", |
||||
|
) |
@ -0,0 +1,12 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
# Main Agreement Status Records Model |
||||
|
class AgreementStatus(models.Model): |
||||
|
_name = "agreement.type" |
||||
|
|
||||
|
# General |
||||
|
name = fields.Char(string="Title", required=True) |
@ -0,0 +1,14 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AgreementSubtype(models.Model): |
||||
|
_name = "agreement.subtype" |
||||
|
_description = "Agreement Subtypes" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
agreement_type_id = fields.Many2one( |
||||
|
"agreement.type", |
||||
|
string="Agreement Type") |
@ -0,0 +1,16 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AgreementType(models.Model): |
||||
|
_name = "agreement.type" |
||||
|
_description = "Agreement Types" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
agreement_subtypes_ids = fields.One2many( |
||||
|
"agreement.subtype", |
||||
|
"agreement_type_id", |
||||
|
string="Subtypes" |
||||
|
) |
@ -0,0 +1,12 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class Product(models.Model): |
||||
|
_inherit = "product.template" |
||||
|
|
||||
|
agreements_ids = fields.Many2many( |
||||
|
"agreement", |
||||
|
string="Agreements") |
@ -0,0 +1,38 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Open Source Integrators |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResConfigSettings(models.TransientModel): |
||||
|
_inherit = "res.config.settings" |
||||
|
|
||||
|
module_agreement_maintenance = fields.Boolean( |
||||
|
string="Manage maintenance agreements and contracts." |
||||
|
) |
||||
|
module_agreement_mrp = fields.Boolean( |
||||
|
string="Link your manufacturing orders to an agreement." |
||||
|
) |
||||
|
module_agreement_project = fields.Boolean( |
||||
|
string="Link your projects and tasks to an agreement." |
||||
|
) |
||||
|
module_agreement_repair = fields.Boolean( |
||||
|
string="Link your repair orders to an agreement." |
||||
|
) |
||||
|
module_agreement_rma = fields.Boolean( |
||||
|
string="Link your RMAs to an agreement.") |
||||
|
module_agreement_sale = fields.Boolean( |
||||
|
string="Create an agreement when the sale order is confirmed." |
||||
|
) |
||||
|
module_agreement_sale_subscription = fields.Boolean( |
||||
|
string="Link your subscriptions to an agreement." |
||||
|
) |
||||
|
module_agreement_stock = fields.Boolean( |
||||
|
string="Link your pickings to an agreement." |
||||
|
) |
||||
|
module_fieldservice_agreement = fields.Boolean( |
||||
|
string="Link your Field Service orders and equipments to an agreement." |
||||
|
) |
||||
|
module_helpdesk_agreement = fields.Boolean( |
||||
|
string="Link your Helpdesk tickets to an agreement." |
||||
|
) |
@ -0,0 +1,13 @@ |
|||||
|
# Copyright (C) 2018 - TODAY, Pavlov Media |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class Partner(models.Model): |
||||
|
_inherit = "res.partner" |
||||
|
|
||||
|
agreement_ids = fields.One2many( |
||||
|
"agreement", |
||||
|
"partner_id", |
||||
|
string="Agreements") |
@ -0,0 +1,6 @@ |
|||||
|
To configure this module: |
||||
|
|
||||
|
* Go to Agreement > Configuration > Templates |
||||
|
* Create a new template with sections and clauses and their respective content |
||||
|
* Go to Agreement > Configuration > Stages |
||||
|
* Create and reorder stages to match your process |
@ -0,0 +1,6 @@ |
|||||
|
* Patrick Wilson <pwilson@pavlovmedia.com> |
||||
|
* Bhavesh Odedra <bodedra@opensourceintegrators.com> |
||||
|
* Wolfgang Hall <whall@opensourceintegrators.com> |
||||
|
* Maxime Chambreuil <mchambreuil@opensourceintegrators.com> |
||||
|
* Sandip Mangukiya <smangukiya@opensourceintegrators.com> |
||||
|
* Yves Goldberg <yves@ygol.com> |
@ -0,0 +1,5 @@ |
|||||
|
The development of this module has been financially supported by: |
||||
|
|
||||
|
* Pavlov Media |
||||
|
* Open Source Integrators |
||||
|
* Yves Goldberg |
@ -0,0 +1,9 @@ |
|||||
|
This module allows you to manage agreements, letter of intent and contract content. |
||||
|
The module is meant to be used by the legal team of a company and to allow them |
||||
|
to define sections, clauses and templates with their respective content that can |
||||
|
be dynamic. |
||||
|
|
||||
|
Based on the template, an agreement can be created and the pdf document generated. |
||||
|
|
||||
|
The agreement would go through a workflow to finally become a contract with the |
||||
|
customer signature. |
@ -0,0 +1,3 @@ |
|||||
|
* Split the module to remove the dependencies on sale and account and provide |
||||
|
the same feature in extra modules (agreement_sale, agreement_account, |
||||
|
agreement_purchase) |
@ -0,0 +1,7 @@ |
|||||
|
To use this module: |
||||
|
|
||||
|
* Go to Agreement > Agreements |
||||
|
* Create a new agreement |
||||
|
* Select a template |
||||
|
* Follow the process to get the required approval |
||||
|
* Send the invitation to the customer to review and sign the agreement |
@ -0,0 +1,144 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<report |
||||
|
id="partner_agreement_contract_document" |
||||
|
model="agreement" |
||||
|
string="Contract Document" |
||||
|
name="agreement_legal.report_agreement_document" |
||||
|
file="agreement_legal.report_agreement_document" |
||||
|
report_type="qweb-pdf"/> |
||||
|
|
||||
|
<report |
||||
|
id="partner_agreement_contract_document_preview" |
||||
|
model="agreement" |
||||
|
string="Contract Document Preview" |
||||
|
name="agreement_legal.report_agreement_document" |
||||
|
file="agreement_legal.report_agreement_document" |
||||
|
report_type="qweb-html"/> |
||||
|
|
||||
|
<template id="report_agreement_document"> |
||||
|
<t t-name="agreement.report_agreement_document"> |
||||
|
<t t-call="web.html_container"> |
||||
|
<t t-foreach="docs" t-as="doc"> |
||||
|
<t t-call="web.external_layout"> |
||||
|
<div class="page"> |
||||
|
<h1 t-field="doc.name"/> |
||||
|
<div name="description"> |
||||
|
<p t-field="doc.dynamic_description"/> |
||||
|
</div> |
||||
|
<h2>Parties</h2> |
||||
|
<h3>Company Information</h3> |
||||
|
<div name="company_address"> |
||||
|
<address t-field="doc.company_partner_id" |
||||
|
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' /> |
||||
|
</div> |
||||
|
<div name="company_contact"> |
||||
|
Represented by <span t-field="doc.company_contact_id.name"/>. |
||||
|
</div> |
||||
|
<h3>Partner Information</h3> |
||||
|
<div name="partner_address"> |
||||
|
<address t-field="doc.partner_id" |
||||
|
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' /> |
||||
|
</div> |
||||
|
<div name="partner_contact"> |
||||
|
Represented by <span t-field="doc.partner_contact_id.name"/>. |
||||
|
</div> |
||||
|
<h2>Agreement</h2> |
||||
|
<h3>Recitals</h3> |
||||
|
<table class="table table-condensed"> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<ol> |
||||
|
<li t-foreach="doc.recital_ids" t-as="r"> |
||||
|
<t t-if="r.title"> |
||||
|
<h3 t-field="r.title"/> |
||||
|
</t> |
||||
|
<p t-field="r.dynamic_content"/> |
||||
|
</li> |
||||
|
</ol> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<table class="table table-condensed"> |
||||
|
<tbody class="section_tbody"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<ol> |
||||
|
<li t-foreach="doc.sections_ids" t-as="s"> |
||||
|
<t t-if="s.title"> |
||||
|
<h3 t-field="s.title"/> |
||||
|
</t> |
||||
|
<p t-field="s.dynamic_content"/> |
||||
|
<ol> |
||||
|
<li t-foreach="s.clauses_ids" t-as="c"> |
||||
|
<t t-if="c.title"> |
||||
|
<h4 t-field="c.title"/> |
||||
|
</t> |
||||
|
<p t-field="c.dynamic_content"/> |
||||
|
</li> |
||||
|
</ol> |
||||
|
</li> |
||||
|
</ol> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<t t-if="special_term"> |
||||
|
<h2>Special Terms</h2> |
||||
|
<div name="special_term"> |
||||
|
<p t-field="doc.dynamic_special_terms"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
<h2>Signatures</h2> |
||||
|
<table class="table table-condensed"> |
||||
|
<theader> |
||||
|
<tr> |
||||
|
<th>Partner</th> |
||||
|
<th>Company</th> |
||||
|
</tr> |
||||
|
</theader> |
||||
|
<tbody class="section_tbody"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<p t-field="doc.partner_id"/> |
||||
|
<p>By: </p> |
||||
|
<p> |
||||
|
Name: <span t-field="doc.partner_contact_id.name"/> |
||||
|
</p> |
||||
|
<p> |
||||
|
Title: <span t-field="doc.partner_contact_id.function"/> |
||||
|
</p> |
||||
|
<p>Date: </p> |
||||
|
</td> |
||||
|
<td> |
||||
|
<p t-field="doc.company_partner_id"/> |
||||
|
<p>By: </p> |
||||
|
<p> |
||||
|
Name: <span t-field="doc.company_contact_id.name"/> |
||||
|
</p> |
||||
|
<p> |
||||
|
Title: <span t-field="doc.company_contact_id.function"/> |
||||
|
</p> |
||||
|
<p>Date: </p> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
<div t-foreach="doc.appendix_ids" t-as="a"> |
||||
|
<div class="page"> |
||||
|
<h1 t-field="a.title" |
||||
|
style="page-break-before: always;"/> |
||||
|
<p t-field="a.dynamic_content"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
</template> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,23 @@ |
|||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
||||
|
access_agreement_allusers,agreement all users,model_agreement,group_agreement_user,1,1,1,0 |
||||
|
access_agreement_manager,agreement manager,model_agreement,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_recital_allusers,recital all users,model_agreement_recital,group_agreement_user,1,1,1,0 |
||||
|
access_agreement_recital_manager,recital manager,model_agreement_recital,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_section_allusers,section all users,model_agreement_section,group_agreement_user,1,1,1,0 |
||||
|
access_agreement_section_manager,section manager,model_agreement_section,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_clause_allusers,clause all users,model_agreement_clause,group_agreement_user,1,1,1,0 |
||||
|
access_agreement_clause_manager,clause manager,model_agreement_clause,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_appendix_allusers,appendix all users,model_agreement_appendix,group_agreement_user,1,1,1,0 |
||||
|
access_agreement_appendix_manager,appendix manager,model_agreement_appendix,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_line_allusers,agreement line all users,model_agreement_line,group_agreement_user,1,1,1,0 |
||||
|
access_agreement_line_manager,agreement line manager,model_agreement_line,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_stage_allusers,stage all users,model_agreement_stage,group_agreement_user,1,0,0,0 |
||||
|
access_agreement_stage_manager,stage manager,model_agreement_stage,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_type_allusers,type all users,model_agreement_type,group_agreement_user,1,0,0,0 |
||||
|
access_agreement_type_manager,type manager,model_agreement_type,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_subtype_allusers,subtype all users,model_agreement_subtype,group_agreement_user,1,0,0,0 |
||||
|
access_agreement_subtype_manager,subtype manager,model_agreement_subtype,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_renewaltype_allusers,renewaltype all users,model_agreement_renewaltype,group_agreement_user,1,0,0,0 |
||||
|
access_agreement_renewaltype_manager,renewaltype manager,model_agreement_renewaltype,group_agreement_manager,1,1,1,1 |
||||
|
access_agreement_increasetype_allusers,increasetype all users,model_agreement_increasetype,group_agreement_user,1,0,0,0 |
||||
|
access_agreement_increasetype_manager,increasetype manager,model_agreement_increasetype,group_agreement_manager,1,1,1,1 |
@ -0,0 +1,22 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<record id="module_agreement_legal_category" model="ir.module.category"> |
||||
|
<field name ="name">Agreement</field> |
||||
|
<field name ="sequence">17</field> |
||||
|
</record> |
||||
|
<!-- User group --> |
||||
|
<record id="group_agreement_user" model="res.groups"> |
||||
|
<field name="name">User</field> |
||||
|
<field name="category_id" ref="module_agreement_legal_category"/> |
||||
|
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Manager group --> |
||||
|
<record id="group_agreement_manager" model="res.groups"> |
||||
|
<field name="name">Manager</field> |
||||
|
<field name="category_id" ref="module_agreement_legal_category"/> |
||||
|
<field name="implied_ids" eval="[(4, ref('group_agreement_user'))]"/> |
||||
|
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
After Width: 64 | Height: 64 | Size: 6.6 KiB |
@ -0,0 +1,473 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
||||
|
<head> |
||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
||||
|
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" /> |
||||
|
<title>Agreements</title> |
||||
|
<style type="text/css"> |
||||
|
|
||||
|
/* |
||||
|
:Author: David Goodger (goodger@python.org) |
||||
|
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ |
||||
|
:Copyright: This stylesheet has been placed in the public domain. |
||||
|
|
||||
|
Default cascading style sheet for the HTML output of Docutils. |
||||
|
|
||||
|
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to |
||||
|
customize this style sheet. |
||||
|
*/ |
||||
|
|
||||
|
/* used to remove borders from tables and images */ |
||||
|
.borderless, table.borderless td, table.borderless th { |
||||
|
border: 0 } |
||||
|
|
||||
|
table.borderless td, table.borderless th { |
||||
|
/* Override padding for "table.docutils td" with "! important". |
||||
|
The right padding separates the table cells. */ |
||||
|
padding: 0 0.5em 0 0 ! important } |
||||
|
|
||||
|
.first { |
||||
|
/* Override more specific margin styles with "! important". */ |
||||
|
margin-top: 0 ! important } |
||||
|
|
||||
|
.last, .with-subtitle { |
||||
|
margin-bottom: 0 ! important } |
||||
|
|
||||
|
.hidden { |
||||
|
display: none } |
||||
|
|
||||
|
.subscript { |
||||
|
vertical-align: sub; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
.superscript { |
||||
|
vertical-align: super; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
a.toc-backref { |
||||
|
text-decoration: none ; |
||||
|
color: black } |
||||
|
|
||||
|
blockquote.epigraph { |
||||
|
margin: 2em 5em ; } |
||||
|
|
||||
|
dl.docutils dd { |
||||
|
margin-bottom: 0.5em } |
||||
|
|
||||
|
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
/* Uncomment (and remove this text!) to get bold-faced definition list terms |
||||
|
dl.docutils dt { |
||||
|
font-weight: bold } |
||||
|
*/ |
||||
|
|
||||
|
div.abstract { |
||||
|
margin: 2em 5em } |
||||
|
|
||||
|
div.abstract p.topic-title { |
||||
|
font-weight: bold ; |
||||
|
text-align: center } |
||||
|
|
||||
|
div.admonition, div.attention, div.caution, div.danger, div.error, |
||||
|
div.hint, div.important, div.note, div.tip, div.warning { |
||||
|
margin: 2em ; |
||||
|
border: medium outset ; |
||||
|
padding: 1em } |
||||
|
|
||||
|
div.admonition p.admonition-title, div.hint p.admonition-title, |
||||
|
div.important p.admonition-title, div.note p.admonition-title, |
||||
|
div.tip p.admonition-title { |
||||
|
font-weight: bold ; |
||||
|
font-family: sans-serif } |
||||
|
|
||||
|
div.attention p.admonition-title, div.caution p.admonition-title, |
||||
|
div.danger p.admonition-title, div.error p.admonition-title, |
||||
|
div.warning p.admonition-title, .code .error { |
||||
|
color: red ; |
||||
|
font-weight: bold ; |
||||
|
font-family: sans-serif } |
||||
|
|
||||
|
/* Uncomment (and remove this text!) to get reduced vertical space in |
||||
|
compound paragraphs. |
||||
|
div.compound .compound-first, div.compound .compound-middle { |
||||
|
margin-bottom: 0.5em } |
||||
|
|
||||
|
div.compound .compound-last, div.compound .compound-middle { |
||||
|
margin-top: 0.5em } |
||||
|
*/ |
||||
|
|
||||
|
div.dedication { |
||||
|
margin: 2em 5em ; |
||||
|
text-align: center ; |
||||
|
font-style: italic } |
||||
|
|
||||
|
div.dedication p.topic-title { |
||||
|
font-weight: bold ; |
||||
|
font-style: normal } |
||||
|
|
||||
|
div.figure { |
||||
|
margin-left: 2em ; |
||||
|
margin-right: 2em } |
||||
|
|
||||
|
div.footer, div.header { |
||||
|
clear: both; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
div.line-block { |
||||
|
display: block ; |
||||
|
margin-top: 1em ; |
||||
|
margin-bottom: 1em } |
||||
|
|
||||
|
div.line-block div.line-block { |
||||
|
margin-top: 0 ; |
||||
|
margin-bottom: 0 ; |
||||
|
margin-left: 1.5em } |
||||
|
|
||||
|
div.sidebar { |
||||
|
margin: 0 0 0.5em 1em ; |
||||
|
border: medium outset ; |
||||
|
padding: 1em ; |
||||
|
background-color: #ffffee ; |
||||
|
width: 40% ; |
||||
|
float: right ; |
||||
|
clear: right } |
||||
|
|
||||
|
div.sidebar p.rubric { |
||||
|
font-family: sans-serif ; |
||||
|
font-size: medium } |
||||
|
|
||||
|
div.system-messages { |
||||
|
margin: 5em } |
||||
|
|
||||
|
div.system-messages h1 { |
||||
|
color: red } |
||||
|
|
||||
|
div.system-message { |
||||
|
border: medium outset ; |
||||
|
padding: 1em } |
||||
|
|
||||
|
div.system-message p.system-message-title { |
||||
|
color: red ; |
||||
|
font-weight: bold } |
||||
|
|
||||
|
div.topic { |
||||
|
margin: 2em } |
||||
|
|
||||
|
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, |
||||
|
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { |
||||
|
margin-top: 0.4em } |
||||
|
|
||||
|
h1.title { |
||||
|
text-align: center } |
||||
|
|
||||
|
h2.subtitle { |
||||
|
text-align: center } |
||||
|
|
||||
|
hr.docutils { |
||||
|
width: 75% } |
||||
|
|
||||
|
img.align-left, .figure.align-left, object.align-left, table.align-left { |
||||
|
clear: left ; |
||||
|
float: left ; |
||||
|
margin-right: 1em } |
||||
|
|
||||
|
img.align-right, .figure.align-right, object.align-right, table.align-right { |
||||
|
clear: right ; |
||||
|
float: right ; |
||||
|
margin-left: 1em } |
||||
|
|
||||
|
img.align-center, .figure.align-center, object.align-center { |
||||
|
display: block; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
} |
||||
|
|
||||
|
table.align-center { |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
} |
||||
|
|
||||
|
.align-left { |
||||
|
text-align: left } |
||||
|
|
||||
|
.align-center { |
||||
|
clear: both ; |
||||
|
text-align: center } |
||||
|
|
||||
|
.align-right { |
||||
|
text-align: right } |
||||
|
|
||||
|
/* reset inner alignment in figures */ |
||||
|
div.align-right { |
||||
|
text-align: inherit } |
||||
|
|
||||
|
/* div.align-center * { */ |
||||
|
/* text-align: left } */ |
||||
|
|
||||
|
.align-top { |
||||
|
vertical-align: top } |
||||
|
|
||||
|
.align-middle { |
||||
|
vertical-align: middle } |
||||
|
|
||||
|
.align-bottom { |
||||
|
vertical-align: bottom } |
||||
|
|
||||
|
ol.simple, ul.simple { |
||||
|
margin-bottom: 1em } |
||||
|
|
||||
|
ol.arabic { |
||||
|
list-style: decimal } |
||||
|
|
||||
|
ol.loweralpha { |
||||
|
list-style: lower-alpha } |
||||
|
|
||||
|
ol.upperalpha { |
||||
|
list-style: upper-alpha } |
||||
|
|
||||
|
ol.lowerroman { |
||||
|
list-style: lower-roman } |
||||
|
|
||||
|
ol.upperroman { |
||||
|
list-style: upper-roman } |
||||
|
|
||||
|
p.attribution { |
||||
|
text-align: right ; |
||||
|
margin-left: 50% } |
||||
|
|
||||
|
p.caption { |
||||
|
font-style: italic } |
||||
|
|
||||
|
p.credits { |
||||
|
font-style: italic ; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
p.label { |
||||
|
white-space: nowrap } |
||||
|
|
||||
|
p.rubric { |
||||
|
font-weight: bold ; |
||||
|
font-size: larger ; |
||||
|
color: maroon ; |
||||
|
text-align: center } |
||||
|
|
||||
|
p.sidebar-title { |
||||
|
font-family: sans-serif ; |
||||
|
font-weight: bold ; |
||||
|
font-size: larger } |
||||
|
|
||||
|
p.sidebar-subtitle { |
||||
|
font-family: sans-serif ; |
||||
|
font-weight: bold } |
||||
|
|
||||
|
p.topic-title { |
||||
|
font-weight: bold } |
||||
|
|
||||
|
pre.address { |
||||
|
margin-bottom: 0 ; |
||||
|
margin-top: 0 ; |
||||
|
font: inherit } |
||||
|
|
||||
|
pre.literal-block, pre.doctest-block, pre.math, pre.code { |
||||
|
margin-left: 2em ; |
||||
|
margin-right: 2em } |
||||
|
|
||||
|
pre.code .ln { color: grey; } /* line numbers */ |
||||
|
pre.code, code { background-color: #eeeeee } |
||||
|
pre.code .comment, code .comment { color: #5C6576 } |
||||
|
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } |
||||
|
pre.code .literal.string, code .literal.string { color: #0C5404 } |
||||
|
pre.code .name.builtin, code .name.builtin { color: #352B84 } |
||||
|
pre.code .deleted, code .deleted { background-color: #DEB0A1} |
||||
|
pre.code .inserted, code .inserted { background-color: #A3D289} |
||||
|
|
||||
|
span.classifier { |
||||
|
font-family: sans-serif ; |
||||
|
font-style: oblique } |
||||
|
|
||||
|
span.classifier-delimiter { |
||||
|
font-family: sans-serif ; |
||||
|
font-weight: bold } |
||||
|
|
||||
|
span.interpreted { |
||||
|
font-family: sans-serif } |
||||
|
|
||||
|
span.option { |
||||
|
white-space: nowrap } |
||||
|
|
||||
|
span.pre { |
||||
|
white-space: pre } |
||||
|
|
||||
|
span.problematic { |
||||
|
color: red } |
||||
|
|
||||
|
span.section-subtitle { |
||||
|
/* font-size relative to parent (h1..h6 element) */ |
||||
|
font-size: 80% } |
||||
|
|
||||
|
table.citation { |
||||
|
border-left: solid 1px gray; |
||||
|
margin-left: 1px } |
||||
|
|
||||
|
table.docinfo { |
||||
|
margin: 2em 4em } |
||||
|
|
||||
|
table.docutils { |
||||
|
margin-top: 0.5em ; |
||||
|
margin-bottom: 0.5em } |
||||
|
|
||||
|
table.footnote { |
||||
|
border-left: solid 1px black; |
||||
|
margin-left: 1px } |
||||
|
|
||||
|
table.docutils td, table.docutils th, |
||||
|
table.docinfo td, table.docinfo th { |
||||
|
padding-left: 0.5em ; |
||||
|
padding-right: 0.5em ; |
||||
|
vertical-align: top } |
||||
|
|
||||
|
table.docutils th.field-name, table.docinfo th.docinfo-name { |
||||
|
font-weight: bold ; |
||||
|
text-align: left ; |
||||
|
white-space: nowrap ; |
||||
|
padding-left: 0 } |
||||
|
|
||||
|
/* "booktabs" style (no vertical lines) */ |
||||
|
table.docutils.booktabs { |
||||
|
border: 0px; |
||||
|
border-top: 2px solid; |
||||
|
border-bottom: 2px solid; |
||||
|
border-collapse: collapse; |
||||
|
} |
||||
|
table.docutils.booktabs * { |
||||
|
border: 0px; |
||||
|
} |
||||
|
table.docutils.booktabs th { |
||||
|
border-bottom: thin solid; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, |
||||
|
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { |
||||
|
font-size: 100% } |
||||
|
|
||||
|
ul.auto-toc { |
||||
|
list-style-type: none } |
||||
|
|
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div class="document" id="agreements"> |
||||
|
<h1 class="title">Agreements</h1> |
||||
|
|
||||
|
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||||
|
!! This file is generated by oca-gen-addon-readme !! |
||||
|
!! changes will be overwritten. !! |
||||
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> |
||||
|
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/contract/tree/11.0/agreement"><img alt="OCA/contract" src="https://img.shields.io/badge/github-OCA%2Fcontract-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/contract-11-0/contract-11-0-agreement"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/110/11.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> |
||||
|
<p>This module allows you to manage agreements, letter of intent and contract content. |
||||
|
The module is meant to be used by the legal team of a company and to allow them |
||||
|
to define sections, clauses and templates with their respective content that can |
||||
|
be dynamic.</p> |
||||
|
<p>Based on the template, an agreement can be created and the pdf document generated.</p> |
||||
|
<p>The agreement would go through a workflow to finally become a contract with the |
||||
|
customer signature.</p> |
||||
|
<p><strong>Table of contents</strong></p> |
||||
|
<div class="contents local topic" id="contents"> |
||||
|
<ul class="simple"> |
||||
|
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li> |
||||
|
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li> |
||||
|
<li><a class="reference internal" href="#known-issues-roadmap" id="id3">Known issues / Roadmap</a></li> |
||||
|
<li><a class="reference internal" href="#bug-tracker" id="id4">Bug Tracker</a></li> |
||||
|
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul> |
||||
|
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li> |
||||
|
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li> |
||||
|
<li><a class="reference internal" href="#other-credits" id="id8">Other credits</a></li> |
||||
|
<li><a class="reference internal" href="#maintainers" id="id9">Maintainers</a></li> |
||||
|
</ul> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="configuration"> |
||||
|
<h1><a class="toc-backref" href="#id1">Configuration</a></h1> |
||||
|
<p>To configure this module:</p> |
||||
|
<ul class="simple"> |
||||
|
<li>Go to Agreement > Configuration > Templates</li> |
||||
|
<li>Create a new template with sections and clauses and their respective content</li> |
||||
|
<li>Go to Agreement > Configuration > Stages</li> |
||||
|
<li>Create and reorder stages to match your process</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="usage"> |
||||
|
<h1><a class="toc-backref" href="#id2">Usage</a></h1> |
||||
|
<p>To use this module:</p> |
||||
|
<ul class="simple"> |
||||
|
<li>Go to Agreement > Agrements</li> |
||||
|
<li>Create a new agreement</li> |
||||
|
<li>Select a template</li> |
||||
|
<li>Follow the process to get the required approval</li> |
||||
|
<li>Send the invitation to the customer to review and sign the agreement</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="known-issues-roadmap"> |
||||
|
<h1><a class="toc-backref" href="#id3">Known issues / Roadmap</a></h1> |
||||
|
<ul class="simple"> |
||||
|
<li>Split the module to remove the dependencies on sale and account and provide |
||||
|
the same feature in extra modules (agreement_sale, agreement_account, |
||||
|
agreement_purchase)</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="bug-tracker"> |
||||
|
<h1><a class="toc-backref" href="#id4">Bug Tracker</a></h1> |
||||
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/contract/issues">GitHub Issues</a>. |
||||
|
In case of trouble, please check there if your issue has already been reported. |
||||
|
If you spotted it first, help us smashing it by providing a detailed and welcomed |
||||
|
<a class="reference external" href="https://github.com/OCA/contract/issues/new?body=module:%20agreement%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> |
||||
|
<p>Do not contact contributors directly about support or help with technical issues.</p> |
||||
|
</div> |
||||
|
<div class="section" id="credits"> |
||||
|
<h1><a class="toc-backref" href="#id5">Credits</a></h1> |
||||
|
<div class="section" id="authors"> |
||||
|
<h2><a class="toc-backref" href="#id6">Authors</a></h2> |
||||
|
<ul class="simple"> |
||||
|
<li>Pavlov Media</li> |
||||
|
<li>Open Source Integrators</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="contributors"> |
||||
|
<h2><a class="toc-backref" href="#id7">Contributors</a></h2> |
||||
|
<ul class="simple"> |
||||
|
<li>Patrick Wilson <<a class="reference external" href="mailto:pwilson@pavlovmedia.com">pwilson@pavlovmedia.com</a>></li> |
||||
|
<li>Bhavesh Odedra <<a class="reference external" href="mailto:bodedra@opensourceintegrators.com">bodedra@opensourceintegrators.com</a>></li> |
||||
|
<li>Wolfgang Hall <<a class="reference external" href="mailto:whall@opensourceintegrators.com">whall@opensourceintegrators.com</a>></li> |
||||
|
<li>Maxime Chambreuil <<a class="reference external" href="mailto:mchambreuil@opensourceintegrators.com">mchambreuil@opensourceintegrators.com</a>></li> |
||||
|
<li>Sandip Mangukiya <<a class="reference external" href="mailto:smangukiya@opensourceintegrators.com">smangukiya@opensourceintegrators.com</a>></li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="other-credits"> |
||||
|
<h2><a class="toc-backref" href="#id8">Other credits</a></h2> |
||||
|
<p>The development of this module has been financially supported by:</p> |
||||
|
<ul class="simple"> |
||||
|
<li>Pavlov Media</li> |
||||
|
<li>Open Source Integrators</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="maintainers"> |
||||
|
<h2><a class="toc-backref" href="#id9">Maintainers</a></h2> |
||||
|
<p>This module is maintained by the OCA.</p> |
||||
|
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> |
||||
|
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use.</p> |
||||
|
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p> |
||||
|
<p><a class="reference external" href="https://github.com/max3903"><img alt="max3903" src="https://github.com/max3903.png?size=40px" /></a></p> |
||||
|
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/contract/tree/11.0/agreement">OCA/contract</a> project on GitHub.</p> |
||||
|
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,362 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_list_view"> |
||||
|
<field name="name">Agreement List</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Agreements" default_order='name'> |
||||
|
<field name="name"/> |
||||
|
<field name="partner_id"/> |
||||
|
<field name="company_partner_id"/> |
||||
|
<field name="parent_agreement_id"/> |
||||
|
<field name="agreement_type_id"/> |
||||
|
<field name="agreement_subtype_id"/> |
||||
|
<field name="active" invisible="1"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_form_view"> |
||||
|
<field name="name">Agreement Form</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Agreements Form"> |
||||
|
<header> |
||||
|
<button string="New Version" 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'}"/> |
||||
|
</header> |
||||
|
<sheet> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
</div> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only" string="Agreement Name"/> |
||||
|
<h1> |
||||
|
<field name="name"/> |
||||
|
</h1> |
||||
|
</div> |
||||
|
<group string="General"> |
||||
|
<group> |
||||
|
<field name="code"/> |
||||
|
<field name="reference" readonly="1"/> |
||||
|
<field name="parent_agreement_id" |
||||
|
domain="[('partner_id', '=', partner_id)]"/> |
||||
|
<field name="is_template"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="agreement_type_id" |
||||
|
widget="selection" |
||||
|
required="True"/> |
||||
|
<field name="agreement_subtype_id" |
||||
|
widget="selection" |
||||
|
domain="[('agreement_type_id', '=', agreement_type_id)]"/> |
||||
|
<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 string="Description"> |
||||
|
<field name="description" |
||||
|
required="True" |
||||
|
nolabel="1"/> |
||||
|
</group> |
||||
|
<group class="oe_edit_only"> |
||||
|
<group> |
||||
|
<field name="field_id" |
||||
|
domain="[('model_id', '=', active_model), |
||||
|
('ttype', '!=', 'one2many'), |
||||
|
('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', '!=', 'many2many')]" |
||||
|
attrs="{'readonly':[('sub_object_id', '=', False)], |
||||
|
'required':[('sub_object_id', '!=', False)]}"/> |
||||
|
<field name="default_value"/> |
||||
|
<field name="copyvalue"/> |
||||
|
</group> |
||||
|
<p> |
||||
|
This section (on the left) allows you to add dynamic fields inside the description and special terms. |
||||
|
<ol> |
||||
|
<li>Select the agreement field</li> |
||||
|
<li>Select the sub-field</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> |
||||
|
</ol> |
||||
|
</p> |
||||
|
</group> |
||||
|
<group name="parties" string="Parties"> |
||||
|
<group name="partner" |
||||
|
string="Partner"> |
||||
|
<div class="o_address_format"> |
||||
|
<field name="partner_id" |
||||
|
domain="[('customer', '=', True)]" |
||||
|
context="{'show_address': 1}" |
||||
|
options="{"always_reload": True}"/> |
||||
|
</div> |
||||
|
</group> |
||||
|
<group name="company" |
||||
|
string="Company"> |
||||
|
<div class="o_address_format"> |
||||
|
<field name="company_partner_id" |
||||
|
readonly="1" |
||||
|
context="{'show_address': 1}" |
||||
|
options="{"always_reload": True}"/> |
||||
|
</div> |
||||
|
</group> |
||||
|
<group name="partner_left" string="Primary Contact"> |
||||
|
<field name="partner_contact_id" 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 name="contact_right" string="Primary Contact"> |
||||
|
<field name="company_contact_id" 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 name="term_information"> |
||||
|
<group name="termdates_left" string="Term Dates"> |
||||
|
<field name="start_date" attrs="{'required': [('is_template', '=', False)], 'invisible': [('is_template', '=', True)]}"/> |
||||
|
<field name="end_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 string="Special Terms"> |
||||
|
<field name="special_terms" |
||||
|
nolabel="1"/> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page name="structure" string="Structure"> |
||||
|
<div> |
||||
|
<button 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> |
||||
|
<separator string="Recitals"/> |
||||
|
<field name="recital_ids" |
||||
|
default_order="sequence" |
||||
|
nolabel="1" |
||||
|
context="{'default_agreement': active_id}"/> |
||||
|
<separator string="Sections"/> |
||||
|
<field name="sections_ids" |
||||
|
default_order='sequence' |
||||
|
nolabel="1" |
||||
|
context="{'default_agreement': active_id}"/> |
||||
|
<separator string="Clauses"/> |
||||
|
<field name="clauses_ids" |
||||
|
default_order='clause_id, sequence' |
||||
|
nolabel="1" |
||||
|
context="{'default_agreement': active_id}"/> |
||||
|
<separator string="Appendices"/> |
||||
|
<field name="appendix_ids" |
||||
|
default_order='sequence' |
||||
|
nolabel="1" |
||||
|
context="{'default_agreement': active_id}"/> |
||||
|
</page> |
||||
|
<page name="signature" string="Signatures"> |
||||
|
<group> |
||||
|
<group string="Partner"> |
||||
|
<field name="partner_signed_date"/> |
||||
|
<field name="partner_signed_user_id" domain="[('parent_id', '=', partner_id)]"/> |
||||
|
</group> |
||||
|
<group string="Company"> |
||||
|
<field name="company_signed_date"/> |
||||
|
<field name="company_signed_user_id"/> |
||||
|
<field name="signed_contract" filename="signed_contract_filename"/> |
||||
|
<field name="signed_contract_filename" invisible="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</page> |
||||
|
<page name="products" string="Products/Services"> |
||||
|
<field name="line_ids" nolabel="1"> |
||||
|
<tree editable="top"> |
||||
|
<field name="product_id"/> |
||||
|
<field name="name"/> |
||||
|
<field name="qty"/> |
||||
|
<field name="uom_id" groups="uom.group_uom"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</page> |
||||
|
<page name="child_agreements" string="Child Agreements"> |
||||
|
<field name="child_agreements_ids"> |
||||
|
<tree default_order='version desc'> |
||||
|
<field name="name"/> |
||||
|
<field name="version"/> |
||||
|
<field name="revision"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</page> |
||||
|
<page name="old_versions" string="Revisions"> |
||||
|
<field name="previous_version_agreements_ids" string="Previouse Versions"> |
||||
|
<tree default_order='version desc'> |
||||
|
<field name="name"/> |
||||
|
<field name="version"/> |
||||
|
<field name="revision"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</page> |
||||
|
<page name="performance" string="Performance"> |
||||
|
<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> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
<group string="Administration"> |
||||
|
<div> |
||||
|
<p>Reviewed by <field 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> |
||||
|
</group> |
||||
|
<footer> |
||||
|
Version: <field name="version" readonly="True"/>.<field name="revision" readonly="True"/> |
||||
|
| Created By: <field name="create_uid" readonly="True"/> |
||||
|
| Created On: <field name="create_date" readonly="True"/> |
||||
|
</footer> |
||||
|
</sheet> |
||||
|
<div class="oe_chatter"> |
||||
|
<field name="message_follower_ids" widget="mail_followers"/> |
||||
|
<field name="message_ids" widget="mail_thread"/> |
||||
|
</div> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Kanban View --> |
||||
|
<record id="view_project_agreement_kanban" model="ir.ui.view"> |
||||
|
<field name="name">Agreement Kanban</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<kanban default_group_by="stage_id"> |
||||
|
<field name="color"/> |
||||
|
<field name="assigned_user_id"/> |
||||
|
<templates> |
||||
|
<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 class="oe_kanban_content"> |
||||
|
<div class="o_kanban_record_top"> |
||||
|
<div class="o_kanban_record_headings"> |
||||
|
<strong class="o_kanban_record_title"> |
||||
|
<field name="name"/> |
||||
|
</strong><br/> |
||||
|
<div class="o_kanban_record_subtitle text-muted"> |
||||
|
<field name="partner_id" invisible="context.get('default_partner_id', False)"/> |
||||
|
<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 || ''}"> |
||||
|
<i><field name="end_date"/></i> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="o_dropdown_kanban dropdown" groups="base.group_user"> |
||||
|
<a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#"> |
||||
|
<span class="fa fa-ellipsis-v" aria-hidden="true"/> |
||||
|
</a> |
||||
|
<ul class="dropdown-menu" role="menu" 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> |
||||
|
<ul class="oe_kanban_colorpicker" data-field="color"/> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="o_kanban_record_body"> |
||||
|
<field name="agreement_type_id"/> - <field name="agreement_subtype_id"/> |
||||
|
</div> |
||||
|
<div class="o_kanban_record_bottom"> |
||||
|
<div class="oe_kanban_bottom_left"> |
||||
|
V: <field name="version"/> |
||||
|
</div> |
||||
|
<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 & picture"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_clear"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
||||
|
</kanban> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Search View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_search_view"> |
||||
|
<field name="name">Agreement Search</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Agreement Search"> |
||||
|
<field name="name"/> |
||||
|
<field name="partner_id"/> |
||||
|
<field name="agreement_type_id"/> |
||||
|
<field name="agreement_subtype_id"/> |
||||
|
<filter name="filter_non_template" string="Non-Templates" domain="[('active','=',True),('is_template', '=', False)]"/> |
||||
|
<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> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Reporting --> |
||||
|
<record id="agreement_graph_view" model="ir.ui.view"> |
||||
|
<field name="name">agreement.graph</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<graph string="Agreements" type="bar"> |
||||
|
<field name="stage_id" type="row"/> |
||||
|
</graph> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_pivot_view" model="ir.ui.view"> |
||||
|
<field name="name">agreement.pivot</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<pivot string="Agreements" display_quantity="true"> |
||||
|
<field name="stage_id" type="row"/> |
||||
|
</pivot> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="action_agreement_report_order" model="ir.actions.act_window"> |
||||
|
<field name="name">Agreements</field> |
||||
|
<field name="res_model">agreement</field> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">graph,pivot</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- actions opening views on models --> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="agreement_dashboard_agreement"> |
||||
|
<field name="name">Agreements</field> |
||||
|
<field name="res_model">agreement</field> |
||||
|
<field name="domain">[('is_template', '=', False)]</field> |
||||
|
<field name="view_mode">kanban,tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="agreement_operations_agreement"> |
||||
|
<field name="name">Agreements</field> |
||||
|
<field name="res_model">agreement</field> |
||||
|
<field name="domain">[('is_template', '=', False)]</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="partner_agreement_agreement_templates"> |
||||
|
<field name="name">Templates</field> |
||||
|
<field name="res_model">agreement</field> |
||||
|
<field name="domain">[('is_template', '=', True)]</field> |
||||
|
<!-- <field name="context">[('is_template', '=', True)]</field> --> |
||||
|
<field name="view_mode">tree,kanban,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,95 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Appendix List View--> |
||||
|
<record model="ir.ui.view" id="agreement_appendix_tree"> |
||||
|
<field name="name">Agreement Appendix Tree</field> |
||||
|
<field name="model">agreement.appendix</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Appendices" default_order='agreement_id, sequence'> |
||||
|
<field name="sequence" widget="handle"/> |
||||
|
<field name="name"/> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
<field name="active" invisible="1"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Appendix Form View --> |
||||
|
<record model="ir.ui.view" id="agreement_appendix_form"> |
||||
|
<field name="name">Agreement Appendix Form</field> |
||||
|
<field name="model">agreement.appendix</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Appendix"> |
||||
|
<sheet> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> |
||||
|
<field name="active" widget="boolean_button" options="{"terminology": "archive"}"/> |
||||
|
</button> |
||||
|
</div> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only"/> |
||||
|
<h1><field name="name"/></h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="sequence"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<field name="content" widget="html"/> |
||||
|
<group class="oe_edit_only"> |
||||
|
<group> |
||||
|
<field name="field_id" |
||||
|
domain="[('model_id', '=', active_model), |
||||
|
('ttype', '!=', 'one2many'), |
||||
|
('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', '!=', 'many2many')]" |
||||
|
attrs="{'readonly':[('sub_object_id', '=', False)], |
||||
|
'required':[('sub_object_id', '!=', False)]}"/> |
||||
|
<field name="default_value"/> |
||||
|
<field name="copyvalue"/> |
||||
|
</group> |
||||
|
<p> |
||||
|
This section (on the left) allows you to add dynamic fields inside the content. |
||||
|
<ol> |
||||
|
<li>Select the appendix field</li> |
||||
|
<li>Select the sub-field</li> |
||||
|
<li>Enter the default value if the field is empty</li> |
||||
|
<li>Copy and paste the placeholder expression in the content</li> |
||||
|
</ol> |
||||
|
</p> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Appendix Search View --> |
||||
|
<record model="ir.ui.view" id="agreement_appendix_search"> |
||||
|
<field name="name">Agreement Appendix Search</field> |
||||
|
<field name="model">agreement.appendix</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search> |
||||
|
<filter name="group_agreement" icon="terp-partner" context="{'group_by':'agreement_id'}"/> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="agreement_appendix_action"> |
||||
|
<field name="name">Appendices</field> |
||||
|
<field name="res_model">agreement.appendix</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,97 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Clause List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_clause_list_view"> |
||||
|
<field name="name">Agreement Clause List</field> |
||||
|
<field name="model">agreement.clause</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Clauses" default_order='agreement_id, sequence'> |
||||
|
<field name="sequence" widget="handle"/> |
||||
|
<field name="name"/> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
<field name="section_id"/> |
||||
|
<field name="active" invisible="1"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Clause Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_clause_form_view"> |
||||
|
<field name="name">Agreement clause Form</field> |
||||
|
<field name="model">agreement.clause</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Clause"> |
||||
|
<sheet> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> |
||||
|
<field name="active" widget="boolean_button" options="{"terminology": "archive"}"/> |
||||
|
</button> |
||||
|
</div> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only"/> |
||||
|
<h1><field name="name"/></h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
<field name="section_id" domain="[('agreement_id', '=', agreement_id)]"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="sequence"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<field name="content" widget="html"/> |
||||
|
<group class="oe_edit_only"> |
||||
|
<group> |
||||
|
<field name="field_id" |
||||
|
domain="[('model_id', '=', active_model), |
||||
|
('ttype', '!=', 'one2many'), |
||||
|
('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', '!=', 'many2many')]" |
||||
|
attrs="{'readonly':[('sub_object_id', '=', False)], |
||||
|
'required':[('sub_object_id', '!=', False)]}"/> |
||||
|
<field name="default_value"/> |
||||
|
<field name="copyvalue"/> |
||||
|
</group> |
||||
|
<p> |
||||
|
This section (on the left) allows you to add dynamic fields inside the content. |
||||
|
<ol> |
||||
|
<li>Select the clause field</li> |
||||
|
<li>Select the sub-field</li> |
||||
|
<li>Enter the default value if the field is empty</li> |
||||
|
<li>Copy and paste the placeholder expression in the content</li> |
||||
|
</ol> |
||||
|
</p> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Clause Search View --> |
||||
|
<record model="ir.ui.view" id="agreement_clause_search_view"> |
||||
|
<field name="name">Agreement Clause Search</field> |
||||
|
<field name="model">agreement.clause</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Agreement Clause Search"> |
||||
|
<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> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="partner_agreement_action_clause"> |
||||
|
<field name="name">Clauses</field> |
||||
|
<field name="res_model">agreement.clause</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,45 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Increase Type List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_increasetype_list_view"> |
||||
|
<field name="name">Agreement Increase Type List</field> |
||||
|
<field name="model">agreement.increasetype</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree default_order='name'> |
||||
|
<field name="name"/> |
||||
|
<field name="description"/> |
||||
|
<field name="increase_percent"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Increase Type Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_increasetype_form_view"> |
||||
|
<field name="name">Agreement Increase Type Form</field> |
||||
|
<field name="model">agreement.increasetype</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Agreements Type Form"> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<field name="name"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="increase_percent"/> |
||||
|
</group> |
||||
|
<group string="Description"> |
||||
|
<field name="description" nolabel="1"/> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="partner_agreement_action_increasetype"> |
||||
|
<field name="name">Agreement Increase Type</field> |
||||
|
<field name="res_model">agreement.increasetype</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,94 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Recital List View--> |
||||
|
<record model="ir.ui.view" id="agreement_recital_tree"> |
||||
|
<field name="name">Agreement Recital Tree</field> |
||||
|
<field name="model">agreement.recital</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Recitals" default_order='agreement_id, sequence'> |
||||
|
<field name="sequence" widget="handle"/> |
||||
|
<field name="name"/> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
<field name="active" invisible="1"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Recital Form View --> |
||||
|
<record model="ir.ui.view" id="agreement_recital_form"> |
||||
|
<field name="name">Agreement Recital Form</field> |
||||
|
<field name="model">agreement.recital</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Recital"> |
||||
|
<sheet> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> |
||||
|
<field name="active" widget="boolean_button" options="{"terminology": "archive"}"/> |
||||
|
</button> |
||||
|
</div> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only"/> |
||||
|
<h1><field name="name"/></h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="sequence"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<field name="content" widget="html"/> |
||||
|
<group class="oe_edit_only"> |
||||
|
<group> |
||||
|
<field name="field_id" |
||||
|
domain="[('model_id', '=', active_model), |
||||
|
('ttype', '!=', 'one2many'), |
||||
|
('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', '!=', 'many2many')]" |
||||
|
attrs="{'readonly':[('sub_object_id', '=', False)], |
||||
|
'required':[('sub_object_id', '!=', False)]}"/> |
||||
|
<field name="default_value"/> |
||||
|
<field name="copyvalue"/> |
||||
|
</group> |
||||
|
<p> |
||||
|
This section (on the left) allows you to add dynamic fields inside the content. |
||||
|
<ol> |
||||
|
<li>Select the recital field</li> |
||||
|
<li>Select the sub-field</li> |
||||
|
<li>Enter the default value if the field is empty</li> |
||||
|
<li>Copy and paste the placeholder expression in the content</li> |
||||
|
</ol> |
||||
|
</p> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Recital Search View --> |
||||
|
<record model="ir.ui.view" id="agreement_recital_search"> |
||||
|
<field name="name">Agreement Recital Search</field> |
||||
|
<field name="model">agreement.recital</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search> |
||||
|
<filter name="group_agreement" icon="terp-partner" context="{'group_by':'agreement_id'}"/> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="agreement_recital_action"> |
||||
|
<field name="name">Recitals</field> |
||||
|
<field name="res_model">agreement.recital</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,41 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Renewal Type List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_renewaltype_list_view"> |
||||
|
<field name="name">Agreement Renewal Type List</field> |
||||
|
<field name="model">agreement.renewaltype</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree default_order='name'> |
||||
|
<field name="name"/> |
||||
|
<field name="description"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Renewal Type Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_renewaltype_form_view"> |
||||
|
<field name="name">Agreement Renewal Type Form</field> |
||||
|
<field name="model">agreement.renewaltype</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Agreements Type Form"> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<field name="name"/> |
||||
|
</group> |
||||
|
<group string="Description"> |
||||
|
<field name="description" nolabel="1"/> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="partner_agreement_action_renewaltype"> |
||||
|
<field name="name">Agreement Renewal Type</field> |
||||
|
<field name="res_model">agreement.renewaltype</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,109 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Sections List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_section_list_view"> |
||||
|
<field name="name">Agreement Section List</field> |
||||
|
<field name="model">agreement.section</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Sections" default_order='agreement_id, sequence'> |
||||
|
<field name="sequence" widget="handle"/> |
||||
|
<field name="name"/> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
<field name="active" invisible="1"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Sections Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_section_form_view"> |
||||
|
<field name="name">Agreement Section Form</field> |
||||
|
<field name="model">agreement.section</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Section"> |
||||
|
<sheet> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"> |
||||
|
<field name="active" widget="boolean_button" options="{"terminology": "archive"}"/> |
||||
|
</button> |
||||
|
</div> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only"/> |
||||
|
<h1><field name="name"/></h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="title"/> |
||||
|
<field name="agreement_id"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="sequence"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page string="Content"> |
||||
|
<field name='content' nolabel="1"/> |
||||
|
<group class="oe_edit_only"> |
||||
|
<group> |
||||
|
<field name="field_id" |
||||
|
domain="[('model_id', '=', active_model), |
||||
|
('ttype', '!=', 'one2many'), |
||||
|
('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', '!=', 'many2many')]" |
||||
|
attrs="{'readonly':[('sub_object_id', '=', False)], |
||||
|
'required':[('sub_object_id', '!=', False)]}"/> |
||||
|
<field name="default_value"/> |
||||
|
<field name="copyvalue"/> |
||||
|
</group> |
||||
|
<p> |
||||
|
This section (on the left) allows you to add dynamic fields inside the content. |
||||
|
<ol> |
||||
|
<li>Select the section field</li> |
||||
|
<li>Select the sub-field</li> |
||||
|
<li>Enter the default value if the field is empty</li> |
||||
|
<li>Copy and paste the placeholder expression in the content</li> |
||||
|
</ol> |
||||
|
</p> |
||||
|
</group> |
||||
|
</page> |
||||
|
<page string="Clauses"> |
||||
|
<field name="clauses_ids" |
||||
|
nolabel="1" |
||||
|
context="{'default_section_id': active_id, 'default_agreement_id': agreement_id}"> |
||||
|
<tree> |
||||
|
<field name="sequence" widget="handle"/> |
||||
|
<field name="name"/> |
||||
|
<field name="title"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Section Search View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_section_search_view"> |
||||
|
<field name="name">Agreement Section Search</field> |
||||
|
<field name="model">agreement.section</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Agreement Section Search"> |
||||
|
<filter name="group_agreement" string="Agreements" icon="terp-partner" context="{'group_by':'agreement_id'}"/> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="partner_agreement_action_section"> |
||||
|
<field name="name">Agreement Sections</field> |
||||
|
<field name="res_model">agreement.section</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,43 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Stage List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_stage_list_view"> |
||||
|
<field name="name">Agreement Stage List</field> |
||||
|
<field name="model">agreement.stage</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree default_order='sequence, name'> |
||||
|
<field name="sequence" widget="handle"/> |
||||
|
<field name="name" string="Stage Name"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Stage Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_stage_form_view"> |
||||
|
<field name="name">Agreement Stage Form</field> |
||||
|
<field name="model">agreement.stage</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Agreements Stage Form"> |
||||
|
<sheet> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only" string="Stage Name"/> |
||||
|
<h1><field name="name" string="Stage Name"/></h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<field name="sequence"/> |
||||
|
<field name="fold"/> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="partner_agreement_action_stage"> |
||||
|
<field name="name">Agreement Stage</field> |
||||
|
<field name="res_model">agreement.stage</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,45 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Sub Type List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_subtype_list_view"> |
||||
|
<field name="name">Agreement Subtype List</field> |
||||
|
<field name="model">agreement.subtype</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree default_order='name'> |
||||
|
<field name="name" string="Sub-Type Name"/> |
||||
|
<field name="agreement_type_id" string="Agreement Type"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Sub Type Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_subtype_form_view"> |
||||
|
<field name="name">Agreement Sub Type Form</field> |
||||
|
<field name="model">agreement.subtype</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Agreement Sub-Types"> |
||||
|
<sheet> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only"/> |
||||
|
<h1><field name="name"/></h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="agreement_type_id"/> |
||||
|
</group> |
||||
|
<group></group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="partner_agreement_action_subtype"> |
||||
|
<field name="name">Agreement Sub-Types</field> |
||||
|
<field name="res_model">agreement.subtype</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,45 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Agreement Type List View--> |
||||
|
<record model="ir.ui.view" id="partner_agreement_type_list_view"> |
||||
|
<field name="name">Agreement Type List</field> |
||||
|
<field name="model">agreement.type</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Agreement Types" default_order='name'> |
||||
|
<field name="name" string="Type Name"/> |
||||
|
<field name="agreement_subtypes_ids" string="Sub-Types"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Agreement Type Form View --> |
||||
|
<record model="ir.ui.view" id="partner_agreement_type_form_view"> |
||||
|
<field name="name">Agreement Type Form</field> |
||||
|
<field name="model">agreement.type</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Agreement Type"> |
||||
|
<sheet> |
||||
|
<div class="oe_title"> |
||||
|
<label for="name" class="oe_edit_only"/> |
||||
|
<h1><field name="name"/></h1> |
||||
|
</div> |
||||
|
<field name="agreement_subtypes_ids" |
||||
|
nolabel="1"> |
||||
|
<tree editable="bottom"> |
||||
|
<field name="name"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Actions opening views on models --> |
||||
|
<record model="ir.actions.act_window" id="partner_agreement_action_type"> |
||||
|
<field name="name">Agreement Types</field> |
||||
|
<field name="res_model">agreement.type</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,147 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<!-- Remove top menu from agreement module --> |
||||
|
<!-- <delete model="ir.ui.menu" id="agreement.agreement_menu" /> --> |
||||
|
|
||||
|
<!-- Top menu item --> |
||||
|
<menuitem |
||||
|
name="Agreements" |
||||
|
id="agreement.agreement_menu" |
||||
|
web_icon="agreement,static/description/icon.png" |
||||
|
sequence="80" |
||||
|
action="agreement_dashboard_agreement" |
||||
|
groups="agreement_legal.group_agreement_user"/> |
||||
|
<!-- Dashboard --> |
||||
|
<menuitem |
||||
|
name="Dashboard" |
||||
|
id="agreement_dashboard" |
||||
|
parent="agreement.agreement_menu" |
||||
|
sequence="10"/> |
||||
|
<menuitem |
||||
|
name="Agreements" |
||||
|
id="dashboard_agreements" |
||||
|
parent="agreement_dashboard" |
||||
|
sequence="10" |
||||
|
action="agreement_dashboard_agreement"/> |
||||
|
|
||||
|
<!-- Operations --> |
||||
|
<menuitem |
||||
|
name="Operations" |
||||
|
id="agreement_operations" |
||||
|
parent="agreement.agreement_menu" |
||||
|
sequence="20"/> |
||||
|
<menuitem |
||||
|
name="Agreements" |
||||
|
id="operations_agreements" |
||||
|
parent="agreement_operations" |
||||
|
sequence="10" |
||||
|
action="agreement_operations_agreement"/> |
||||
|
|
||||
|
<!-- Master Data --> |
||||
|
<menuitem |
||||
|
name="Master Data" |
||||
|
id="agreement_masterdata" |
||||
|
parent="agreement.agreement_menu" |
||||
|
sequence="30"/> |
||||
|
<menuitem |
||||
|
name="Contents" |
||||
|
id="agreement_data_contents" |
||||
|
parent="agreement_masterdata" |
||||
|
sequence="10"/> |
||||
|
<menuitem |
||||
|
name="Recitals" |
||||
|
id="agreement_recitals" |
||||
|
parent="agreement_data_contents" |
||||
|
sequence="10" |
||||
|
action="agreement_recital_action"/> |
||||
|
<menuitem |
||||
|
name="Clauses" |
||||
|
id="agreement_clauses" |
||||
|
parent="agreement_data_contents" |
||||
|
sequence="20" |
||||
|
action="partner_agreement_action_clause"/> |
||||
|
<menuitem |
||||
|
name="Sections" |
||||
|
id="agreement_sections" |
||||
|
parent="agreement_data_contents" |
||||
|
sequence="30" |
||||
|
action="partner_agreement_action_section"/> |
||||
|
<menuitem |
||||
|
name="Appendices" |
||||
|
id="agreement_appendices" |
||||
|
parent="agreement_data_contents" |
||||
|
sequence="40" |
||||
|
action="agreement_appendix_action"/> |
||||
|
<menuitem |
||||
|
name="Products" |
||||
|
id="agreement_products" |
||||
|
sequence="100" |
||||
|
parent="agreement_masterdata" |
||||
|
action="product.product_template_action"/> |
||||
|
|
||||
|
<!-- Reporting --> |
||||
|
<menuitem |
||||
|
name="Reporting" |
||||
|
id="agreement_reporting" |
||||
|
sequence="40" |
||||
|
parent="agreement.agreement_menu" |
||||
|
groups="agreement_legal.group_agreement_manager"/> |
||||
|
|
||||
|
<menuitem |
||||
|
name="Agreements" |
||||
|
id="agreement_agreement_reporting" |
||||
|
sequence="10" |
||||
|
parent="agreement_reporting" |
||||
|
action="action_agreement_report_order"/> |
||||
|
|
||||
|
<!-- Configuration --> |
||||
|
<menuitem |
||||
|
name="Configuration" |
||||
|
id="agreement_configuration" |
||||
|
sequence="50" |
||||
|
parent="agreement.agreement_menu" |
||||
|
groups="agreement_legal.group_agreement_manager"/> |
||||
|
<menuitem |
||||
|
name="Settings" |
||||
|
id="agreement_settings" |
||||
|
sequence="10" |
||||
|
parent="agreement_configuration" |
||||
|
action="agreement_legal.action_agreement_config"/> |
||||
|
<menuitem |
||||
|
name="Templates" |
||||
|
id="template" |
||||
|
parent="agreement_configuration" |
||||
|
sequence="20" |
||||
|
action="partner_agreement_agreement_templates"/> |
||||
|
<menuitem |
||||
|
name="Renewal Types" |
||||
|
id="agreement_renewaltype" |
||||
|
parent="agreement_configuration" |
||||
|
sequence="30" |
||||
|
action="partner_agreement_action_renewaltype"/> |
||||
|
<menuitem |
||||
|
name="Increase Types" |
||||
|
id="agreement_increamenttypes" |
||||
|
parent="agreement_configuration" |
||||
|
sequence="31" |
||||
|
action="partner_agreement_action_increasetype"/> |
||||
|
<menuitem |
||||
|
name="Stages" |
||||
|
id="agreement_stages" |
||||
|
parent="agreement_configuration" |
||||
|
sequence="40" |
||||
|
action="partner_agreement_action_stage"/> |
||||
|
<menuitem |
||||
|
name="Types" |
||||
|
id="agreement_types" |
||||
|
parent="agreement_configuration" |
||||
|
sequence="50" |
||||
|
action="partner_agreement_action_type"/> |
||||
|
<menuitem |
||||
|
name="Sub-Types" |
||||
|
id="agreement_subtypes" |
||||
|
parent="agreement_configuration" |
||||
|
sequence="60" |
||||
|
action="partner_agreement_action_subtype"/> |
||||
|
</odoo> |
@ -0,0 +1,161 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="res_config_settings_view_form" model="ir.ui.view"> |
||||
|
<field name="name">res.config.settings.view.form.agreement</field> |
||||
|
<field name="model">res.config.settings</field> |
||||
|
<field name="priority" eval="40"/> |
||||
|
<field name="inherit_id" ref="base.res_config_settings_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//div[hasclass('settings')]" position="inside"> |
||||
|
<div class="app_settings_block" |
||||
|
data-string="Agreements" |
||||
|
string="Agreements" |
||||
|
data-key="agreement" |
||||
|
groups="agreement_legal.group_agreement_manager"> |
||||
|
<h2>Operations</h2> |
||||
|
<div class="row mt16 o_settings_container"> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="group_uom"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="group_uom"/> |
||||
|
<div class="text-muted"> |
||||
|
Sell and purchase products in different units of measure |
||||
|
</div> |
||||
|
<div class="content-group"> |
||||
|
<div 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> |
||||
|
<h2>Advanced Features</h2> |
||||
|
<div class="row mt16 o_settings_container"> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_sale"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Sales"/> |
||||
|
<div class="text-muted"> |
||||
|
Create an agreement when the sales order is confirmed |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box" |
||||
|
attrs="{'invisible': [('module_agreement_sale', '!=', True)]}"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_sale_subscription"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Sale Subscriptions"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your subscriptions to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_fieldservice_agreement"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Field Service"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your Field Service orders and equipments to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_stock"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Inventory"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your transfers to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_rma"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Returns"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your returns to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_maintenance"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Maintenance"/> |
||||
|
<div class="text-muted"> |
||||
|
Manage maintenance agreements and contracts |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_mrp"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Manufacturing"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your manufacturing orders to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_repair"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Repair"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your repair orders to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_agreement_project"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Project"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your projects and tasks to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="module_helpdesk_agreement"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="" string="Helpdesk"/> |
||||
|
<div class="text-muted"> |
||||
|
Link your Helpdesk tickets to an agreement |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<act_window id="action_agreement_config" |
||||
|
name="Settings" |
||||
|
res_model="res.config.settings" |
||||
|
view_mode="form" |
||||
|
target="inline" |
||||
|
context="{'module': 'agreement'}"/> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record model="ir.ui.view" id="partner_form"> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//page[@name='internal_notes']" position="after"> |
||||
|
<page name="agreement" string="Agreements"> |
||||
|
<group> |
||||
|
<field name="agreement_ids" nolabel="1"/> |
||||
|
</group> |
||||
|
</page> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue