mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[14.0][MIG] agreement_legal (Version 12.0 to 14.0)
[MIG] Black & Cleanup [IMP] Reviewer Requested Changes [IMP] Black [IMP] Reviewer Suggestion [FIX] Tests [FIX] Multiple Issues - Added 'is_old_version' field to better display old versions. Before these were marked as inactive therefore not showing in the agreement. - 'is_template' field now copies when making a template revision or copying a template. - New Versions now retain original create date. - Moved version/revision and created on/by fields out of footer to top in order to have the save buttons when creating children. - Moved demo data out of data folder into the demo.xml [FIX] demo data [FIX] Revert back to only migration [FIX] Report dynamic field rendering [FIX] Test
This commit is contained in:
committed by
Enric Tobella
parent
884fcd1b93
commit
9cf3d551b0
@@ -1,14 +1,4 @@
|
|||||||
# Copyright (C) 2018 - TODAY, Pavlov Media
|
# Copyright (C) 2018 - TODAY, Pavlov Media
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import api, SUPERUSER_ID
|
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
|
|
||||||
def post_init_agreement_legal(cr, registry):
|
|
||||||
env = api.Environment(cr, SUPERUSER_ID, dict())
|
|
||||||
cr.execute(
|
|
||||||
"UPDATE agreement SET stage_id = %s WHERE stage_id IS NULL;",
|
|
||||||
(env.ref("agreement_legal.agreement_stage_new").id,),
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
"views/menu.xml",
|
"views/menu.xml",
|
||||||
],
|
],
|
||||||
"demo": ["demo/demo.xml"],
|
"demo": ["demo/demo.xml"],
|
||||||
"qweb": ["static/src/xml/domain_widget_view.xml"],
|
|
||||||
"post_init_hook": "post_init_agreement_legal",
|
|
||||||
"application": True,
|
"application": True,
|
||||||
"development_status": "Beta",
|
"development_status": "Beta",
|
||||||
"maintainers": ["max3903", "ygol"],
|
"maintainers": ["max3903", "ygol"],
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="agreement_stage_new" model="agreement.stage">
|
<record id="agreement_stage_new" model="agreement.stage">
|
||||||
<field name="name">New</field>
|
<field name="name">New</field>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="agreement_type_agreement" model="agreement.type">
|
<record id="agreement_type_agreement" model="agreement.type">
|
||||||
<field name="name">Agreement</field>
|
<field name="name">Agreement</field>
|
||||||
|
|||||||
0
agreement_legal/data/demo.xml
Normal file
0
agreement_legal/data/demo.xml
Normal file
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo noupdate="1">
|
<odoo noupdate="1">
|
||||||
<!-- Sequence for agreement -->
|
<!-- Sequence for agreement -->
|
||||||
<record id="seq_agreement" model="ir.sequence">
|
<record id="seq_agreement" model="ir.sequence">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="agreement" model="ir.module.category">
|
<record id="agreement" model="ir.module.category">
|
||||||
<field name="name">Agreement</field>
|
<field name="name">Agreement</field>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<!--
|
<!--
|
||||||
© 2019 Ygol Internetwork (yves@ygol.com)
|
© 2019 Ygol Internetwork (yves@ygol.com)
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from odoo import _, api, fields, models
|
|||||||
class Agreement(models.Model):
|
class Agreement(models.Model):
|
||||||
_inherit = "agreement"
|
_inherit = "agreement"
|
||||||
|
|
||||||
# General
|
|
||||||
name = fields.Char(string="Title", required=True)
|
name = fields.Char(string="Title", required=True)
|
||||||
version = fields.Integer(
|
version = fields.Integer(
|
||||||
string="Version",
|
string="Version",
|
||||||
@@ -23,7 +22,7 @@ class Agreement(models.Model):
|
|||||||
help="The revision will increase with every save event.",
|
help="The revision will increase with every save event.",
|
||||||
)
|
)
|
||||||
description = fields.Text(
|
description = fields.Text(
|
||||||
string="Description", tracking=True, help="Description of the agreement",
|
string="Description", tracking=True, help="Description of the agreement"
|
||||||
)
|
)
|
||||||
dynamic_description = fields.Text(
|
dynamic_description = fields.Text(
|
||||||
compute="_compute_dynamic_description",
|
compute="_compute_dynamic_description",
|
||||||
@@ -31,7 +30,7 @@ class Agreement(models.Model):
|
|||||||
help="Compute dynamic description",
|
help="Compute dynamic description",
|
||||||
)
|
)
|
||||||
start_date = fields.Date(
|
start_date = fields.Date(
|
||||||
string="Start Date", tracking=True, help="When the agreement starts.",
|
string="Start Date", tracking=True, help="When the agreement starts."
|
||||||
)
|
)
|
||||||
end_date = fields.Date(
|
end_date = fields.Date(
|
||||||
string="End Date", tracking=True, help="When the agreement ends."
|
string="End Date", tracking=True, help="When the agreement ends."
|
||||||
@@ -89,7 +88,7 @@ class Agreement(models.Model):
|
|||||||
help="ID used for internal contract tracking.",
|
help="ID used for internal contract tracking.",
|
||||||
)
|
)
|
||||||
increase_type_id = fields.Many2one(
|
increase_type_id = fields.Many2one(
|
||||||
comodel_name="agreement.increasetype",
|
"agreement.increasetype",
|
||||||
string="Increase Type",
|
string="Increase Type",
|
||||||
tracking=True,
|
tracking=True,
|
||||||
help="The amount that certain rates may increase.",
|
help="The amount that certain rates may increase.",
|
||||||
@@ -105,23 +104,19 @@ class Agreement(models.Model):
|
|||||||
help="Date that the contract was terminated.",
|
help="Date that the contract was terminated.",
|
||||||
)
|
)
|
||||||
reviewed_date = fields.Date(string="Reviewed Date", tracking=True)
|
reviewed_date = fields.Date(string="Reviewed Date", tracking=True)
|
||||||
reviewed_user_id = fields.Many2one(
|
reviewed_user_id = fields.Many2one("res.users", string="Reviewed By", tracking=True)
|
||||||
comodel_name="res.users", string="Reviewed By", tracking=True
|
|
||||||
)
|
|
||||||
approved_date = fields.Date(string="Approved Date", tracking=True)
|
approved_date = fields.Date(string="Approved Date", tracking=True)
|
||||||
approved_user_id = fields.Many2one(
|
approved_user_id = fields.Many2one("res.users", string="Approved By", tracking=True)
|
||||||
comodel_name="res.users", string="Approved By", tracking=True
|
currency_id = fields.Many2one("res.currency", string="Currency")
|
||||||
)
|
|
||||||
currency_id = fields.Many2one(comodel_name="res.currency", string="Currency")
|
|
||||||
partner_id = fields.Many2one(
|
partner_id = fields.Many2one(
|
||||||
comodel_name="res.partner",
|
"res.partner",
|
||||||
string="Partner",
|
string="Partner",
|
||||||
required=False,
|
required=False,
|
||||||
copy=True,
|
copy=True,
|
||||||
help="The customer or vendor this agreement is related to.",
|
help="The customer or vendor this agreement is related to.",
|
||||||
)
|
)
|
||||||
partner_contact_id = fields.Many2one(
|
partner_contact_id = fields.Many2one(
|
||||||
comodel_name="res.partner",
|
"res.partner",
|
||||||
string="Partner Contact",
|
string="Partner Contact",
|
||||||
copy=True,
|
copy=True,
|
||||||
help="The primary partner contact (If Applicable).",
|
help="The primary partner contact (If Applicable).",
|
||||||
@@ -133,7 +128,7 @@ class Agreement(models.Model):
|
|||||||
related="partner_contact_id.email", string="Partner Email"
|
related="partner_contact_id.email", string="Partner Email"
|
||||||
)
|
)
|
||||||
company_contact_id = fields.Many2one(
|
company_contact_id = fields.Many2one(
|
||||||
comodel_name="res.partner",
|
"res.partner",
|
||||||
string="Company Contact",
|
string="Company Contact",
|
||||||
copy=True,
|
copy=True,
|
||||||
help="The primary contact in the company.",
|
help="The primary contact in the company.",
|
||||||
@@ -187,89 +182,73 @@ class Agreement(models.Model):
|
|||||||
string="Dynamic Parties",
|
string="Dynamic Parties",
|
||||||
help="Compute dynamic parties",
|
help="Compute dynamic parties",
|
||||||
)
|
)
|
||||||
agreement_type_id = fields.Many2one(tracking=True)
|
agreement_type_id = fields.Many2one(tracking=True,)
|
||||||
agreement_subtype_id = fields.Many2one(
|
agreement_subtype_id = fields.Many2one(
|
||||||
comodel_name="agreement.subtype",
|
"agreement.subtype",
|
||||||
string="Agreement Sub-type",
|
string="Agreement Sub-type",
|
||||||
tracking=True,
|
tracking=True,
|
||||||
help="Select the sub-type of this agreement. Sub-Types are related to "
|
help="Select the sub-type of this agreement. Sub-Types are related to "
|
||||||
"agreement types.",
|
"agreement types.",
|
||||||
)
|
)
|
||||||
product_ids = fields.Many2many(
|
product_ids = fields.Many2many("product.template", string="Products & Services")
|
||||||
comodel_name="product.template", string="Products & Services"
|
|
||||||
)
|
|
||||||
assigned_user_id = fields.Many2one(
|
assigned_user_id = fields.Many2one(
|
||||||
comodel_name="res.users",
|
"res.users",
|
||||||
string="Assigned To",
|
string="Assigned To",
|
||||||
tracking=True,
|
tracking=True,
|
||||||
help="Select the user who manages this agreement.",
|
help="Select the user who manages this agreement.",
|
||||||
)
|
)
|
||||||
company_signed_user_id = fields.Many2one(
|
company_signed_user_id = fields.Many2one(
|
||||||
comodel_name="res.users",
|
"res.users",
|
||||||
string="Signed By",
|
string="Signed By",
|
||||||
tracking=True,
|
tracking=True,
|
||||||
help="The user at our company who authorized/signed the agreement or "
|
help="The user at our company who authorized/signed the agreement or "
|
||||||
"contract.",
|
"contract.",
|
||||||
)
|
)
|
||||||
partner_signed_user_id = fields.Many2one(
|
partner_signed_user_id = fields.Many2one(
|
||||||
comodel_name="res.partner",
|
"res.partner",
|
||||||
string="Signed By (Partner)",
|
string="Signed By (Partner)",
|
||||||
tracking=True,
|
tracking=True,
|
||||||
help="Contact on the account that signed the agreement/contract.",
|
help="Contact on the account that signed the agreement/contract.",
|
||||||
)
|
)
|
||||||
parent_agreement_id = fields.Many2one(
|
parent_agreement_id = fields.Many2one(
|
||||||
comodel_name="agreement",
|
"agreement",
|
||||||
string="Parent Agreement",
|
string="Parent Agreement",
|
||||||
help="Link this agreement to a parent agreement. For example if this "
|
help="Link this agreement to a parent agreement. For example if this "
|
||||||
"agreement is an amendment to another agreement. This list will "
|
"agreement is an amendment to another agreement. This list will "
|
||||||
"only show other agreements related to the same account.",
|
"only show other agreements related to the same account.",
|
||||||
)
|
)
|
||||||
renewal_type_id = fields.Many2one(
|
renewal_type_id = fields.Many2one(
|
||||||
comodel_name="agreement.renewaltype",
|
"agreement.renewaltype",
|
||||||
string="Renewal Type",
|
string="Renewal Type",
|
||||||
tracking=True,
|
tracking=True,
|
||||||
help="Describes what happens after the contract expires.",
|
help="Describes what happens after the contract expires.",
|
||||||
)
|
)
|
||||||
recital_ids = fields.One2many(
|
recital_ids = fields.One2many(
|
||||||
comodel_name="agreement.recital",
|
"agreement.recital", "agreement_id", string="Recitals", copy=True
|
||||||
inverse_name="agreement_id",
|
|
||||||
string="Recitals",
|
|
||||||
copy=True,
|
|
||||||
)
|
)
|
||||||
sections_ids = fields.One2many(
|
sections_ids = fields.One2many(
|
||||||
comodel_name="agreement.section",
|
"agreement.section", "agreement_id", string="Sections", copy=True
|
||||||
inverse_name="agreement_id",
|
|
||||||
string="Sections",
|
|
||||||
copy=True,
|
|
||||||
)
|
|
||||||
clauses_ids = fields.One2many(
|
|
||||||
comodel_name="agreement.clause", inverse_name="agreement_id", string="Clauses"
|
|
||||||
)
|
)
|
||||||
|
clauses_ids = fields.One2many("agreement.clause", "agreement_id", string="Clauses")
|
||||||
appendix_ids = fields.One2many(
|
appendix_ids = fields.One2many(
|
||||||
comodel_name="agreement.appendix",
|
"agreement.appendix", "agreement_id", string="Appendices", copy=True
|
||||||
inverse_name="agreement_id",
|
|
||||||
string="Appendices",
|
|
||||||
copy=True,
|
|
||||||
)
|
)
|
||||||
previous_version_agreements_ids = fields.One2many(
|
previous_version_agreements_ids = fields.One2many(
|
||||||
comodel_name="agreement",
|
"agreement",
|
||||||
inverse_name="parent_agreement_id",
|
"parent_agreement_id",
|
||||||
string="Previous Versions",
|
string="Previous Versions",
|
||||||
copy=False,
|
copy=False,
|
||||||
context={"active_test": False},
|
context={"active_test": False},
|
||||||
)
|
)
|
||||||
child_agreements_ids = fields.One2many(
|
child_agreements_ids = fields.One2many(
|
||||||
comodel_name="agreement",
|
"agreement",
|
||||||
inverse_name="parent_agreement_id",
|
"parent_agreement_id",
|
||||||
string="Child Agreements",
|
string="Child Agreements",
|
||||||
copy=False,
|
copy=False,
|
||||||
domain=[("active", "=", True)],
|
domain=[("active", "=", True)],
|
||||||
)
|
)
|
||||||
line_ids = fields.One2many(
|
line_ids = fields.One2many(
|
||||||
comodel_name="agreement.line",
|
"agreement.line", "agreement_id", string="Products/Services", copy=False
|
||||||
inverse_name="agreement_id",
|
|
||||||
string="Products/Services",
|
|
||||||
copy=False,
|
|
||||||
)
|
)
|
||||||
state = fields.Selection(
|
state = fields.Selection(
|
||||||
[("draft", "Draft"), ("active", "Active"), ("inactive", "Inactive")],
|
[("draft", "Draft"), ("active", "Active"), ("inactive", "Inactive")],
|
||||||
@@ -277,17 +256,32 @@ class Agreement(models.Model):
|
|||||||
tracking=True,
|
tracking=True,
|
||||||
)
|
)
|
||||||
notification_address_id = fields.Many2one(
|
notification_address_id = fields.Many2one(
|
||||||
comodel_name="res.partner",
|
"res.partner",
|
||||||
string="Notification Address",
|
string="Notification Address",
|
||||||
help="The address to send notificaitons to, if different from "
|
help="The address to send notificaitons to, if different from "
|
||||||
"customer address.(Address Type = Other)",
|
"customer address.(Address Type = Other)",
|
||||||
)
|
)
|
||||||
signed_contract_filename = fields.Char(string="Filename")
|
signed_contract_filename = fields.Char(string="Filename")
|
||||||
signed_contract = fields.Binary(string="Signed Document", tracking=True)
|
signed_contract = fields.Binary(string="Signed Document", tracking=True)
|
||||||
|
field_id = fields.Many2one(
|
||||||
# Dynamic field editor
|
"ir.model.fields",
|
||||||
field_domain = fields.Char(
|
string="Field",
|
||||||
string="Field Expression", default='[["active", "=", True]]'
|
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(
|
default_value = fields.Char(
|
||||||
string="Default Value",
|
string="Default Value",
|
||||||
@@ -299,33 +293,25 @@ class Agreement(models.Model):
|
|||||||
template field.""",
|
template field.""",
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange("field_domain", "default_value")
|
|
||||||
def onchange_copyvalue(self):
|
|
||||||
self.copyvalue = False
|
|
||||||
if self.field_domain:
|
|
||||||
string_list = self.field_domain.split(",")
|
|
||||||
if string_list:
|
|
||||||
field_domain = string_list[0][3:-1]
|
|
||||||
self.copyvalue = "${{object.{} or {}}}".format(
|
|
||||||
field_domain, self.default_value or "''"
|
|
||||||
)
|
|
||||||
|
|
||||||
# compute the dynamic content for mako expression
|
# compute the dynamic content for mako expression
|
||||||
def _compute_dynamic_description(self):
|
def _compute_dynamic_description(self):
|
||||||
MailTemplates = self.env["mail.template"]
|
MailTemplates = self.env["mail.template"]
|
||||||
for agreement in self:
|
for agreement in self:
|
||||||
lang = agreement.partner_id.lang or "en_US"
|
lang = agreement.partner_id.lang or "en_US"
|
||||||
description = MailTemplates.with_context(lang=lang)._render_template(
|
description = MailTemplates.with_context(lang=lang)._render_template(
|
||||||
agreement.description, "agreement", agreement.id
|
agreement.description, "agreement", [agreement.id]
|
||||||
)
|
)
|
||||||
agreement.dynamic_description = description
|
des = ""
|
||||||
|
for i in description:
|
||||||
|
des += description[i]
|
||||||
|
agreement.dynamic_description = des
|
||||||
|
|
||||||
def _compute_dynamic_parties(self):
|
def _compute_dynamic_parties(self):
|
||||||
MailTemplates = self.env["mail.template"]
|
MailTemplates = self.env["mail.template"]
|
||||||
for agreement in self:
|
for agreement in self:
|
||||||
lang = agreement.partner_id.lang or "en_US"
|
lang = agreement.partner_id.lang or "en_US"
|
||||||
parties = MailTemplates.with_context(lang=lang)._render_template(
|
parties = MailTemplates.with_context(lang=lang)._render_template(
|
||||||
agreement.parties, "agreement", agreement.id
|
agreement.parties, "agreement", [agreement.id]
|
||||||
)
|
)
|
||||||
agreement.dynamic_parties = parties
|
agreement.dynamic_parties = parties
|
||||||
|
|
||||||
@@ -334,10 +320,31 @@ class Agreement(models.Model):
|
|||||||
for agreement in self:
|
for agreement in self:
|
||||||
lang = agreement.partner_id.lang or "en_US"
|
lang = agreement.partner_id.lang or "en_US"
|
||||||
special_terms = MailTemplates.with_context(lang=lang)._render_template(
|
special_terms = MailTemplates.with_context(lang=lang)._render_template(
|
||||||
agreement.special_terms, "agreement", agreement.id
|
agreement.special_terms, "agreement", [agreement.id]
|
||||||
)
|
)
|
||||||
agreement.dynamic_special_terms = special_terms
|
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
|
# Used for Kanban grouped_by view
|
||||||
@api.model
|
@api.model
|
||||||
def _read_group_stage_ids(self, stages, domain, order):
|
def _read_group_stage_ids(self, stages, domain, order):
|
||||||
@@ -347,7 +354,7 @@ class Agreement(models.Model):
|
|||||||
return stage_ids
|
return stage_ids
|
||||||
|
|
||||||
stage_id = fields.Many2one(
|
stage_id = fields.Many2one(
|
||||||
comodel_name="agreement.stage",
|
"agreement.stage",
|
||||||
string="Stage",
|
string="Stage",
|
||||||
group_expand="_read_group_stage_ids",
|
group_expand="_read_group_stage_ids",
|
||||||
help="Select the current stage of the agreement.",
|
help="Select the current stage of the agreement.",
|
||||||
@@ -365,14 +372,19 @@ class Agreement(models.Model):
|
|||||||
"name": "{} - OLD VERSION".format(rec.name),
|
"name": "{} - OLD VERSION".format(rec.name),
|
||||||
"active": False,
|
"active": False,
|
||||||
"parent_agreement_id": rec.id,
|
"parent_agreement_id": rec.id,
|
||||||
|
"version": rec.version,
|
||||||
|
"code": rec.code + "-V" + str(rec.version),
|
||||||
}
|
}
|
||||||
# Make a current copy and mark it as old
|
# Make a current copy and mark it as old
|
||||||
rec.copy(default=default_vals)
|
rec.copy(default=default_vals)
|
||||||
|
# Increment the Version
|
||||||
|
rec.version = rec.version + 1
|
||||||
return super().write({"revision": 0})
|
return super().write({"revision": 0})
|
||||||
|
|
||||||
def create_new_agreement(self):
|
def create_new_agreement(self):
|
||||||
|
self.ensure_one()
|
||||||
default_vals = {
|
default_vals = {
|
||||||
"name": "NEW",
|
"name": "New",
|
||||||
"active": True,
|
"active": True,
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"revision": 0,
|
"revision": 0,
|
||||||
@@ -395,12 +407,9 @@ class Agreement(models.Model):
|
|||||||
vals["code"] = self.env["ir.sequence"].next_by_code("agreement") or _("New")
|
vals["code"] = self.env["ir.sequence"].next_by_code("agreement") or _("New")
|
||||||
if not vals.get("stage_id"):
|
if not vals.get("stage_id"):
|
||||||
vals["stage_id"] = self.env.ref("agreement_legal.agreement_stage_new").id
|
vals["stage_id"] = self.env.ref("agreement_legal.agreement_stage_new").id
|
||||||
return super(Agreement, self).create(vals)
|
return super().create(vals)
|
||||||
|
|
||||||
# Increments the revision on each save action
|
# Increments the revision on each save action
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
res = True
|
vals["revision"] = self.revision + 1
|
||||||
for rec in self:
|
return super().write(vals)
|
||||||
vals["revision"] = rec.revision + 1
|
|
||||||
res = super(Agreement, rec).write(vals)
|
|
||||||
return res
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class AgreementAppendix(models.Model):
|
|||||||
title = fields.Char(
|
title = fields.Char(
|
||||||
string="Title",
|
string="Title",
|
||||||
required=True,
|
required=True,
|
||||||
help="The title is displayed on the PDF." "The name is not.",
|
help="The title is displayed on the PDF. The name is not.",
|
||||||
)
|
)
|
||||||
sequence = fields.Integer(string="Sequence", default=10)
|
sequence = fields.Integer(string="Sequence", default=10)
|
||||||
content = fields.Html(string="Content")
|
content = fields.Html(string="Content")
|
||||||
@@ -22,9 +22,7 @@ class AgreementAppendix(models.Model):
|
|||||||
string="Dynamic Content",
|
string="Dynamic Content",
|
||||||
help="compute dynamic Content",
|
help="compute dynamic Content",
|
||||||
)
|
)
|
||||||
agreement_id = fields.Many2one(
|
agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
|
||||||
comodel_name="agreement", string="Agreement", ondelete="cascade"
|
|
||||||
)
|
|
||||||
active = fields.Boolean(
|
active = fields.Boolean(
|
||||||
string="Active",
|
string="Active",
|
||||||
default=True,
|
default=True,
|
||||||
@@ -33,8 +31,25 @@ class AgreementAppendix(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Dynamic field editor
|
# Dynamic field editor
|
||||||
field_domain = fields.Char(
|
field_id = fields.Many2one(
|
||||||
string="Field Expression", default='[["active", "=", True]]'
|
"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(
|
default_value = fields.Char(
|
||||||
string="Default Value",
|
string="Default Value",
|
||||||
@@ -46,16 +61,26 @@ class AgreementAppendix(models.Model):
|
|||||||
template field.""",
|
template field.""",
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange("field_domain", "default_value")
|
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
|
||||||
def onchange_copyvalue(self):
|
def onchange_copyvalue(self):
|
||||||
|
self.sub_object_id = False
|
||||||
self.copyvalue = False
|
self.copyvalue = False
|
||||||
if self.field_domain:
|
self.sub_object_id = False
|
||||||
string_list = self.field_domain.split(",")
|
if self.field_id and not self.field_id.relation:
|
||||||
if string_list:
|
self.copyvalue = "${{object.{} or {}}}".format(
|
||||||
field_domain = string_list[0][3:-1]
|
self.field_id.name, self.default_value or "''",
|
||||||
self.copyvalue = "${{object.{} or {}}}".format(
|
)
|
||||||
field_domain, 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
|
# compute the dynamic content for mako expression
|
||||||
def _compute_dynamic_content(self):
|
def _compute_dynamic_content(self):
|
||||||
@@ -67,6 +92,6 @@ class AgreementAppendix(models.Model):
|
|||||||
or "en_US"
|
or "en_US"
|
||||||
)
|
)
|
||||||
content = MailTemplates.with_context(lang=lang)._render_template(
|
content = MailTemplates.with_context(lang=lang)._render_template(
|
||||||
appendix.content, "agreement.appendix", appendix.id
|
appendix.content, "agreement.appendix", [appendix.id]
|
||||||
)
|
)
|
||||||
appendix.dynamic_content = content
|
appendix.dynamic_content = content
|
||||||
|
|||||||
@@ -11,14 +11,12 @@ class AgreementClause(models.Model):
|
|||||||
|
|
||||||
name = fields.Char(string="Name", required=True)
|
name = fields.Char(string="Name", required=True)
|
||||||
title = fields.Char(
|
title = fields.Char(
|
||||||
string="Title", help="The title is displayed on the PDF." "The name is not."
|
string="Title", help="The title is displayed on the PDF. The name is not."
|
||||||
)
|
)
|
||||||
sequence = fields.Integer(string="Sequence")
|
sequence = fields.Integer(string="Sequence")
|
||||||
agreement_id = fields.Many2one(
|
agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
|
||||||
comodel_name="agreement", string="Agreement", ondelete="cascade"
|
|
||||||
)
|
|
||||||
section_id = fields.Many2one(
|
section_id = fields.Many2one(
|
||||||
comodel_name="agreement.section", string="Section", ondelete="cascade"
|
"agreement.section", string="Section", ondelete="cascade"
|
||||||
)
|
)
|
||||||
content = fields.Html(string="Clause Content")
|
content = fields.Html(string="Clause Content")
|
||||||
dynamic_content = fields.Html(
|
dynamic_content = fields.Html(
|
||||||
@@ -34,8 +32,25 @@ class AgreementClause(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Dynamic field editor
|
# Dynamic field editor
|
||||||
field_domain = fields.Char(
|
field_id = fields.Many2one(
|
||||||
string="Field Expression", default='[["active", "=", True]]'
|
"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(
|
default_value = fields.Char(
|
||||||
string="Default Value",
|
string="Default Value",
|
||||||
@@ -47,16 +62,26 @@ class AgreementClause(models.Model):
|
|||||||
template field.""",
|
template field.""",
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange("field_domain", "default_value")
|
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
|
||||||
def onchange_copyvalue(self):
|
def onchange_copyvalue(self):
|
||||||
|
self.sub_object_id = False
|
||||||
self.copyvalue = False
|
self.copyvalue = False
|
||||||
if self.field_domain:
|
self.sub_object_id = False
|
||||||
string_list = self.field_domain.split(",")
|
if self.field_id and not self.field_id.relation:
|
||||||
if string_list:
|
self.copyvalue = "${{object.{} or {}}}".format(
|
||||||
field_domain = string_list[0][3:-1]
|
self.field_id.name, self.default_value or "''",
|
||||||
self.copyvalue = "${{object.{} or {}}}".format(
|
)
|
||||||
field_domain, 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
|
# compute the dynamic content for mako expression
|
||||||
def _compute_dynamic_content(self):
|
def _compute_dynamic_content(self):
|
||||||
@@ -66,6 +91,6 @@ class AgreementClause(models.Model):
|
|||||||
clause.agreement_id and clause.agreement_id.partner_id.lang or "en_US"
|
clause.agreement_id and clause.agreement_id.partner_id.lang or "en_US"
|
||||||
)
|
)
|
||||||
content = MailTemplates.with_context(lang=lang)._render_template(
|
content = MailTemplates.with_context(lang=lang)._render_template(
|
||||||
clause.content, "agreement.clause", clause.id
|
clause.content, "agreement.clause", [clause.id]
|
||||||
)
|
)
|
||||||
clause.dynamic_content = content
|
clause.dynamic_content = content
|
||||||
|
|||||||
@@ -8,15 +8,11 @@ class AgreementLine(models.Model):
|
|||||||
_name = "agreement.line"
|
_name = "agreement.line"
|
||||||
_description = "Agreement Lines"
|
_description = "Agreement Lines"
|
||||||
|
|
||||||
product_id = fields.Many2one(comodel_name="product.product", string="Product")
|
product_id = fields.Many2one("product.product", string="Product")
|
||||||
name = fields.Char(string="Description", required=True)
|
name = fields.Char(string="Description", required=True)
|
||||||
agreement_id = fields.Many2one(
|
agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
|
||||||
comodel_name="agreement", string="Agreement", ondelete="cascade"
|
|
||||||
)
|
|
||||||
qty = fields.Float(string="Quantity")
|
qty = fields.Float(string="Quantity")
|
||||||
uom_id = fields.Many2one(
|
uom_id = fields.Many2one("uom.uom", string="Unit of Measure", required=True)
|
||||||
comodel_name="uom.uom", string="Unit of Measure", required=True
|
|
||||||
)
|
|
||||||
|
|
||||||
@api.onchange("product_id")
|
@api.onchange("product_id")
|
||||||
def _onchange_product_id(self):
|
def _onchange_product_id(self):
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class AgreementRecital(models.Model):
|
|||||||
|
|
||||||
name = fields.Char(string="Name", required=True)
|
name = fields.Char(string="Name", required=True)
|
||||||
title = fields.Char(
|
title = fields.Char(
|
||||||
string="Title", help="The title is displayed on the PDF." "The name is not."
|
string="Title", help="The title is displayed on the PDF." "The name is not.",
|
||||||
)
|
)
|
||||||
sequence = fields.Integer(string="Sequence", default=10)
|
sequence = fields.Integer(string="Sequence", default=10)
|
||||||
content = fields.Html(string="Content")
|
content = fields.Html(string="Content")
|
||||||
@@ -20,9 +20,7 @@ class AgreementRecital(models.Model):
|
|||||||
string="Dynamic Content",
|
string="Dynamic Content",
|
||||||
help="compute dynamic Content",
|
help="compute dynamic Content",
|
||||||
)
|
)
|
||||||
agreement_id = fields.Many2one(
|
agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
|
||||||
comodel_name="agreement", string="Agreement", ondelete="cascade"
|
|
||||||
)
|
|
||||||
active = fields.Boolean(
|
active = fields.Boolean(
|
||||||
string="Active",
|
string="Active",
|
||||||
default=True,
|
default=True,
|
||||||
@@ -31,8 +29,25 @@ class AgreementRecital(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Dynamic field editor
|
# Dynamic field editor
|
||||||
field_domain = fields.Char(
|
field_id = fields.Many2one(
|
||||||
string="Field Expression", default='[["active", "=", True]]'
|
"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(
|
default_value = fields.Char(
|
||||||
string="Default Value",
|
string="Default Value",
|
||||||
@@ -44,16 +59,26 @@ class AgreementRecital(models.Model):
|
|||||||
template field.""",
|
template field.""",
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange("field_domain", "default_value")
|
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
|
||||||
def onchange_copyvalue(self):
|
def onchange_copyvalue(self):
|
||||||
|
self.sub_object_id = False
|
||||||
self.copyvalue = False
|
self.copyvalue = False
|
||||||
if self.field_domain:
|
self.sub_object_id = False
|
||||||
string_list = self.field_domain.split(",")
|
if self.field_id and not self.field_id.relation:
|
||||||
if string_list:
|
self.copyvalue = "${{object.{} or {}}}".format(
|
||||||
field_domain = string_list[0][3:-1]
|
self.field_id.name, self.default_value or "''"
|
||||||
self.copyvalue = "${{object.{} or {}}}".format(
|
)
|
||||||
field_domain, 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
|
# compute the dynamic content for mako expression
|
||||||
def _compute_dynamic_content(self):
|
def _compute_dynamic_content(self):
|
||||||
@@ -63,6 +88,6 @@ class AgreementRecital(models.Model):
|
|||||||
recital.agreement_id and recital.agreement_id.partner_id.lang or "en_US"
|
recital.agreement_id and recital.agreement_id.partner_id.lang or "en_US"
|
||||||
)
|
)
|
||||||
content = MailTemplates.with_context(lang=lang)._render_template(
|
content = MailTemplates.with_context(lang=lang)._render_template(
|
||||||
recital.content, "agreement.recital", recital.id
|
recital.content, "agreement.recital", [recital.id]
|
||||||
)
|
)
|
||||||
recital.dynamic_content = content
|
recital.dynamic_content = content
|
||||||
|
|||||||
@@ -14,14 +14,9 @@ class AgreementSection(models.Model):
|
|||||||
string="Title", help="The title is displayed on the PDF. The name is not."
|
string="Title", help="The title is displayed on the PDF. The name is not."
|
||||||
)
|
)
|
||||||
sequence = fields.Integer(string="Sequence")
|
sequence = fields.Integer(string="Sequence")
|
||||||
agreement_id = fields.Many2one(
|
agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
|
||||||
comodel_name="agreement", string="Agreement", ondelete="cascade"
|
|
||||||
)
|
|
||||||
clauses_ids = fields.One2many(
|
clauses_ids = fields.One2many(
|
||||||
comodel_name="agreement.clause",
|
"agreement.clause", "section_id", string="Clauses", copy=True
|
||||||
inverse_name="section_id",
|
|
||||||
string="Clauses",
|
|
||||||
copy=True,
|
|
||||||
)
|
)
|
||||||
content = fields.Html(string="Section Content")
|
content = fields.Html(string="Section Content")
|
||||||
dynamic_content = fields.Html(
|
dynamic_content = fields.Html(
|
||||||
@@ -37,8 +32,25 @@ class AgreementSection(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Dynamic field editor
|
# Dynamic field editor
|
||||||
field_domain = fields.Char(
|
field_id = fields.Many2one(
|
||||||
string="Field Expression", default='[["active", "=", True]]'
|
"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(
|
default_value = fields.Char(
|
||||||
string="Default Value",
|
string="Default Value",
|
||||||
@@ -50,16 +62,26 @@ class AgreementSection(models.Model):
|
|||||||
template field.""",
|
template field.""",
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange("field_domain", "default_value")
|
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
|
||||||
def onchange_copyvalue(self):
|
def onchange_copyvalue(self):
|
||||||
|
self.sub_object_id = False
|
||||||
self.copyvalue = False
|
self.copyvalue = False
|
||||||
if self.field_domain:
|
self.sub_object_id = False
|
||||||
string_list = self.field_domain.split(",")
|
if self.field_id and not self.field_id.relation:
|
||||||
if string_list:
|
self.copyvalue = "${{object.{} or {}}}".format(
|
||||||
field_domain = string_list[0][3:-1]
|
self.field_id.name, self.default_value or "''"
|
||||||
self.copyvalue = "${{object.{} or {}}}".format(
|
)
|
||||||
field_domain, 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
|
# compute the dynamic content for mako expression
|
||||||
def _compute_dynamic_content(self):
|
def _compute_dynamic_content(self):
|
||||||
@@ -69,6 +91,6 @@ class AgreementSection(models.Model):
|
|||||||
section.agreement_id and section.agreement_id.partner_id.lang or "en_US"
|
section.agreement_id and section.agreement_id.partner_id.lang or "en_US"
|
||||||
)
|
)
|
||||||
content = MailTemplates.with_context(lang=lang)._render_template(
|
content = MailTemplates.with_context(lang=lang)._render_template(
|
||||||
section.content, "agreement.section", section.id
|
section.content, "agreement.section", [section.id]
|
||||||
)
|
)
|
||||||
section.dynamic_content = content
|
section.dynamic_content = content
|
||||||
|
|||||||
@@ -9,6 +9,4 @@ class AgreementSubtype(models.Model):
|
|||||||
_description = "Agreement Subtypes"
|
_description = "Agreement Subtypes"
|
||||||
|
|
||||||
name = fields.Char(string="Name", required=True)
|
name = fields.Char(string="Name", required=True)
|
||||||
agreement_type_id = fields.Many2one(
|
agreement_type_id = fields.Many2one("agreement.type", string="Agreement Type")
|
||||||
comodel_name="agreement.type", string="Agreement Type"
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -9,7 +9,5 @@ class AgreementType(models.Model):
|
|||||||
_description = "Agreement Types"
|
_description = "Agreement Types"
|
||||||
|
|
||||||
agreement_subtypes_ids = fields.One2many(
|
agreement_subtypes_ids = fields.One2many(
|
||||||
comodel_name="agreement.subtype",
|
"agreement.subtype", "agreement_type_id", string="Subtypes"
|
||||||
inverse_name="agreement_type_id",
|
|
||||||
string="Subtypes",
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ from odoo import fields, models
|
|||||||
class Product(models.Model):
|
class Product(models.Model):
|
||||||
_inherit = "product.template"
|
_inherit = "product.template"
|
||||||
|
|
||||||
agreements_ids = fields.Many2many(comodel_name="agreement", string="Agreements")
|
agreements_ids = fields.Many2many("agreement", string="Agreements")
|
||||||
|
|||||||
@@ -7,6 +7,4 @@ from odoo import fields, models
|
|||||||
class Partner(models.Model):
|
class Partner(models.Model):
|
||||||
_inherit = "res.partner"
|
_inherit = "res.partner"
|
||||||
|
|
||||||
agreement_ids = fields.One2many(
|
agreement_ids = fields.One2many("agreement", "partner_id", string="Agreements")
|
||||||
comodel_name="agreement", inverse_name="partner_id", string="Agreements"
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<report
|
<record id="partner_agreement_contract_document" model="ir.actions.report">
|
||||||
id="partner_agreement_contract_document"
|
<field name="name">Agreement</field>
|
||||||
model="agreement"
|
<field name="model">agreement</field>
|
||||||
string="Contract Document"
|
<field name="report_type">qweb-pdf</field>
|
||||||
name="agreement_legal.report_agreement_document"
|
<field name="report_name">agreement_legal.report_agreement_document</field>
|
||||||
file="agreement_legal.report_agreement_document"
|
<field name="report_file">agreement_legal.report_agreement_document</field>
|
||||||
report_type="qweb-pdf"
|
</record>
|
||||||
/>
|
<record id="partner_agreement_contract_document_preview" model="ir.actions.report">
|
||||||
<report
|
<field name="name">Agreement Preview</field>
|
||||||
id="partner_agreement_contract_document_preview"
|
<field name="model">agreement</field>
|
||||||
model="agreement"
|
<field name="report_type">qweb-html</field>
|
||||||
string="Contract Document Preview"
|
<field name="report_name">agreement_legal.report_agreement_document</field>
|
||||||
name="agreement_legal.report_agreement_document"
|
<field name="report_file">agreement_legal.report_agreement_document</field>
|
||||||
file="agreement_legal.report_agreement_document"
|
</record>
|
||||||
report_type="qweb-html"
|
|
||||||
/>
|
|
||||||
<template id="report_agreement_document">
|
<template id="report_agreement_document">
|
||||||
<t t-name="agreement.report_agreement_document">
|
<t t-name="agreement.report_agreement_document">
|
||||||
<t t-call="web.html_container">
|
<t t-call="web.html_container">
|
||||||
@@ -111,7 +109,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<t t-if="doc.special_terms">
|
<t t-if="special_term">
|
||||||
<h2>Special Terms</h2>
|
<h2>Special Terms</h2>
|
||||||
<div name="special_term">
|
<div name="special_term">
|
||||||
<p t-field="doc.dynamic_special_terms" />
|
<p t-field="doc.dynamic_special_terms" />
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
odoo.define("agreement_legal.domain_widget_ext", function(require) {
|
odoo.define("agreement_legal.domain_widget_ext", function(require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const basic_fields = require("web.basic_fields");
|
var basic_fields = require("web.basic_fields");
|
||||||
const DomainSelector = require("web.DomainSelector");
|
var DomainSelector = require("web.DomainSelector");
|
||||||
const session = require("web.session");
|
var session = require("web.session");
|
||||||
const core = require("web.core");
|
var core = require("web.core");
|
||||||
const qweb = core.qweb;
|
var qweb = core.qweb;
|
||||||
|
|
||||||
basic_fields.FieldDomain.include({
|
basic_fields.FieldDomain.include({
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +26,6 @@ odoo.define("agreement_legal.domain_widget_ext", function(require) {
|
|||||||
* @override _render from AbstractField
|
* @override _render from AbstractField
|
||||||
* @returns {Deferred}
|
* @returns {Deferred}
|
||||||
*/
|
*/
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
_render: function() {
|
_render: function() {
|
||||||
// If there is no model, only change the non-domain-selector content
|
// If there is no model, only change the non-domain-selector content
|
||||||
if (!this._domainModel) {
|
if (!this._domainModel) {
|
||||||
@@ -35,7 +34,7 @@ odoo.define("agreement_legal.domain_widget_ext", function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert char value to array value
|
// Convert char value to array value
|
||||||
const value = this.value || "[]";
|
var value = this.value || "[]";
|
||||||
|
|
||||||
// Create the domain selector or change the value of the current
|
// Create the domain selector or change the value of the current
|
||||||
// one...
|
// one...
|
||||||
|
|||||||
@@ -3,17 +3,6 @@
|
|||||||
<t t-name="FieldDomain.content">
|
<t t-name="FieldDomain.content">
|
||||||
<t t-if="partialUse">
|
<t t-if="partialUse">
|
||||||
<div t-if="hasModel" class="o_field_domain_panel">
|
<div t-if="hasModel" class="o_field_domain_panel">
|
||||||
<!--<div t-if="hasModel" class="o_field_domain_panel">
|
|
||||||
<i class="fa fa-arrow-right" role="img" aria-label="Domain" title="Domain"/>
|
|
||||||
|
|
||||||
<button t-if="isValid" class="btn btn-sm btn-secondary o_domain_show_selection_button" type="button">
|
|
||||||
<t t-esc="nbRecords"/> record(s)
|
|
||||||
</button>
|
|
||||||
<span t-else="" class="text-warning" role="alert"><i class="fa fa-exclamation-triangle" role="img" aria-label="Warning" title="Warning"/> Invalid domain</span>
|
|
||||||
|
|
||||||
<button t-if="inDialogEdit" class="btn btn-sm btn-primary o_field_domain_dialog_button">Edit Domain</button>
|
|
||||||
</div>
|
|
||||||
<div t-else="">Select a model to add a filter.</div>-->
|
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
<t t-if="!partialUse">
|
<t t-if="!partialUse">
|
||||||
|
|||||||
@@ -1 +1,8 @@
|
|||||||
|
# License LGPLv3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html).
|
||||||
|
|
||||||
from . import test_agreement
|
from . import test_agreement
|
||||||
|
from . import test_agreement_appendix
|
||||||
|
from . import test_agreement_clause
|
||||||
|
from . import test_agreement_line
|
||||||
|
from . import test_agreement_recital
|
||||||
|
from . import test_agreement_section
|
||||||
|
|||||||
@@ -1,13 +1,116 @@
|
|||||||
# Copyright 2021 Tecnativa - Víctor Martínez
|
|
||||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
||||||
from odoo.addons.agreement.tests import test_agreement
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from odoo import fields
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
class TestAgreement(test_agreement.TestAgreement):
|
class TestAgreement(TransactionCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
|
||||||
|
self.agreement_type = self.env["agreement.type"].create(
|
||||||
|
{"name": "Test Agreement Type", "domain": "sale"}
|
||||||
|
)
|
||||||
|
self.test_agreement = self.env["agreement"].create(
|
||||||
|
{
|
||||||
|
"name": "TestAgreement",
|
||||||
|
"description": "Test",
|
||||||
|
"special_terms": "Test",
|
||||||
|
"partner_id": self.test_customer.id,
|
||||||
|
"start_date": fields.Date.today(),
|
||||||
|
"end_date": fields.Date.today() + timedelta(days=365),
|
||||||
|
"state": "active",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
|
||||||
|
def test_onchange_copyvalue(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
agreement_01.field_id = field_01.id
|
||||||
|
agreement_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(agreement_01.copyvalue, "${object.active or ''}")
|
||||||
|
|
||||||
|
# TEST 02: Set related 'Field' for dynamic placeholder to
|
||||||
|
# test onchange method
|
||||||
|
def test_onchange_copyvalue2(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement"), ("name", "=", "agreement_type_id")]
|
||||||
|
)
|
||||||
|
sub_field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.type"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
agreement_01.field_id = field_01.id
|
||||||
|
agreement_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(agreement_01.sub_object_id.model, "agreement.type")
|
||||||
|
agreement_01.sub_model_object_field_id = sub_field_01.id
|
||||||
|
agreement_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(
|
||||||
|
agreement_01.copyvalue, "${object.agreement_type_id.active or ''}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 03: Create New Version
|
||||||
|
def test_create_new_version(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
agreement_01.create_new_version()
|
||||||
|
old_agreement = self.env["agreement"].search(
|
||||||
|
[("code", "=", agreement_01.code + "-V1"), ("active", "=", False)]
|
||||||
|
)
|
||||||
|
self.assertEqual(len(old_agreement), 1)
|
||||||
|
new_agreement = self.env["agreement"].search(
|
||||||
|
[("name", "=", "TestAgreement"), ("version", "=", 2)]
|
||||||
|
)
|
||||||
|
self.assertEqual(len(new_agreement), 1)
|
||||||
|
|
||||||
|
# TEST 04: Create New Agreement
|
||||||
|
def test_create_new_agreement(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
agreement_01.create_new_agreement()
|
||||||
|
new_agreement = self.env["agreement"].search([("name", "=", "New")])
|
||||||
|
self.assertEqual(len(new_agreement), 1)
|
||||||
|
|
||||||
|
# TEST 05: Test Description Dynamic Field
|
||||||
|
def test_compute_dynamic_description(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
agreement_01.description = "${object.name}"
|
||||||
|
self.assertEqual(
|
||||||
|
agreement_01.dynamic_description, "TestAgreement",
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 06: Test Parties Dynamic Field
|
||||||
|
def test_compute_dynamic_parties(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
agreement_01.parties = "${object.name}"
|
||||||
|
self.assertEqual(
|
||||||
|
agreement_01.dynamic_parties,
|
||||||
|
"<p>{" + str(agreement_01.id) + ": '</p><p>TestAgreement</p>'}",
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 07: Test Special Terms Dynamic Field
|
||||||
|
def test_compute_dynamic_special_terms(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
agreement_01.special_terms = "${object.name}"
|
||||||
|
self.assertEqual(
|
||||||
|
agreement_01.dynamic_special_terms,
|
||||||
|
"{" + str(agreement_01.id) + ": 'TestAgreement'}",
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 02: Check Read Stages
|
||||||
|
def test_read_group_stage_ids(self):
|
||||||
|
agreement_01 = self.test_agreement
|
||||||
|
self.assertEqual(
|
||||||
|
agreement_01._read_group_stage_ids(self.env["agreement.stage"], [], "id"),
|
||||||
|
self.env["agreement.stage"].search(
|
||||||
|
[("stage_type", "=", "agreement")], order="id",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def test_action_create_new_version(self):
|
def test_action_create_new_version(self):
|
||||||
self.agreement.create_new_version()
|
self.test_agreement.create_new_version()
|
||||||
self.assertEqual(self.agreement.state, "draft")
|
self.assertEqual(self.test_agreement.state, "draft")
|
||||||
self.assertEqual(len(self.agreement.previous_version_agreements_ids), 1)
|
self.assertEqual(len(self.test_agreement.previous_version_agreements_ids), 1)
|
||||||
|
|||||||
69
agreement_legal/tests/test_agreement_appendix.py
Normal file
69
agreement_legal/tests/test_agreement_appendix.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from odoo import fields
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestAgreementAppendices(TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
|
||||||
|
self.agreement_type = self.env["agreement.type"].create(
|
||||||
|
{"name": "Test Agreement Type", "domain": "sale"}
|
||||||
|
)
|
||||||
|
self.test_agreement = self.env["agreement"].create(
|
||||||
|
{
|
||||||
|
"name": "TestAgreement",
|
||||||
|
"description": "Test",
|
||||||
|
"special_terms": "Test",
|
||||||
|
"partner_id": self.test_customer.id,
|
||||||
|
"start_date": fields.Date.today(),
|
||||||
|
"end_date": fields.Date.today() + timedelta(days=365),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.test_appendices = self.env["agreement.appendix"].create(
|
||||||
|
{
|
||||||
|
"name": "TestAppendices",
|
||||||
|
"title": "Test",
|
||||||
|
"content": "Test",
|
||||||
|
"agreement_id": self.test_agreement.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
|
||||||
|
def test_onchange_copyvalue(self):
|
||||||
|
appendix_01 = self.test_appendices
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.appendix"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
appendix_01.field_id = field_01.id
|
||||||
|
appendix_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(appendix_01.copyvalue, "${object.active or ''}")
|
||||||
|
|
||||||
|
# TEST 02: Set related 'Field' for dynamic placeholder to
|
||||||
|
# test onchange method
|
||||||
|
def test_onchange_copyvalue2(self):
|
||||||
|
appendix_01 = self.test_appendices
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.appendix"), ("name", "=", "agreement_id")]
|
||||||
|
)
|
||||||
|
sub_field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
appendix_01.field_id = field_01.id
|
||||||
|
appendix_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(appendix_01.sub_object_id.model, "agreement")
|
||||||
|
appendix_01.sub_model_object_field_id = sub_field_01.id
|
||||||
|
appendix_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(appendix_01.copyvalue, "${object.agreement_id.active or ''}")
|
||||||
|
|
||||||
|
# TEST 03: Test Dynamic Field
|
||||||
|
def test_compute_dynamic_content(self):
|
||||||
|
appendix_01 = self.test_appendices
|
||||||
|
appendix_01.content = "${object.name}"
|
||||||
|
self.assertEqual(
|
||||||
|
appendix_01.dynamic_content,
|
||||||
|
"<p>{" + str(appendix_01.id) + ": '</p><p>TestAppendices</p>'}",
|
||||||
|
)
|
||||||
69
agreement_legal/tests/test_agreement_clause.py
Normal file
69
agreement_legal/tests/test_agreement_clause.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from odoo import fields
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestAgreementClauses(TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
|
||||||
|
self.agreement_type = self.env["agreement.type"].create(
|
||||||
|
{"name": "Test Agreement Type", "domain": "sale"}
|
||||||
|
)
|
||||||
|
self.test_agreement = self.env["agreement"].create(
|
||||||
|
{
|
||||||
|
"name": "TestAgreement",
|
||||||
|
"description": "Test",
|
||||||
|
"special_terms": "Test",
|
||||||
|
"partner_id": self.test_customer.id,
|
||||||
|
"start_date": fields.Date.today(),
|
||||||
|
"end_date": fields.Date.today() + timedelta(days=365),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.test_clause = self.env["agreement.clause"].create(
|
||||||
|
{
|
||||||
|
"name": "TestClause",
|
||||||
|
"title": "Test",
|
||||||
|
"content": "Test",
|
||||||
|
"agreement_id": self.test_agreement.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
|
||||||
|
def test_onchange_copyvalue(self):
|
||||||
|
clause_01 = self.test_clause
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.clause"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
clause_01.field_id = field_01.id
|
||||||
|
clause_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(clause_01.copyvalue, "${object.active or ''}")
|
||||||
|
|
||||||
|
# TEST 02: Set related 'Field' for dynamic placeholder to
|
||||||
|
# test onchange method
|
||||||
|
def test_onchange_copyvalue2(self):
|
||||||
|
clause_01 = self.test_clause
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.clause"), ("name", "=", "agreement_id")]
|
||||||
|
)
|
||||||
|
sub_field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
clause_01.field_id = field_01.id
|
||||||
|
clause_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(clause_01.sub_object_id.model, "agreement")
|
||||||
|
clause_01.sub_model_object_field_id = sub_field_01.id
|
||||||
|
clause_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(clause_01.copyvalue, "${object.agreement_id.active or ''}")
|
||||||
|
|
||||||
|
# TEST 03: Test Dynamic Field
|
||||||
|
def test_compute_dynamic_content(self):
|
||||||
|
clause_01 = self.test_clause
|
||||||
|
clause_01.content = "${object.name}"
|
||||||
|
self.assertEqual(
|
||||||
|
clause_01.dynamic_content,
|
||||||
|
"<p>{" + str(clause_01.id) + ": '</p><p>TestClause</p>'}",
|
||||||
|
)
|
||||||
42
agreement_legal/tests/test_agreement_line.py
Normal file
42
agreement_legal/tests/test_agreement_line.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from odoo import fields
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestAgreementLine(TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
|
||||||
|
self.agreement_type = self.env["agreement.type"].create(
|
||||||
|
{"name": "Test Agreement Type", "domain": "sale"}
|
||||||
|
)
|
||||||
|
self.test_agreement = self.env["agreement"].create(
|
||||||
|
{
|
||||||
|
"name": "TestAgreement",
|
||||||
|
"description": "Test",
|
||||||
|
"special_terms": "Test",
|
||||||
|
"partner_id": self.test_customer.id,
|
||||||
|
"start_date": fields.Date.today(),
|
||||||
|
"end_date": fields.Date.today() + timedelta(days=365),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.test_product1 = self.env["product.product"].create({"name": "TEST1"})
|
||||||
|
self.test_product2 = self.env["product.product"].create({"name": "TEST2"})
|
||||||
|
self.test_line = self.env["agreement.line"].create(
|
||||||
|
{
|
||||||
|
"product_id": self.test_product1.id,
|
||||||
|
"name": "Test",
|
||||||
|
"uom_id": 1,
|
||||||
|
"agreement_id": self.test_agreement.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 01: Set line product onchange method
|
||||||
|
def test_onchange_product_id(self):
|
||||||
|
line_01 = self.test_line
|
||||||
|
line_01.product_id = self.test_product2.id
|
||||||
|
line_01._onchange_product_id()
|
||||||
|
self.assertEqual(line_01.name, "TEST2")
|
||||||
69
agreement_legal/tests/test_agreement_recital.py
Normal file
69
agreement_legal/tests/test_agreement_recital.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from odoo import fields
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestAgreementRectical(TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
|
||||||
|
self.agreement_type = self.env["agreement.type"].create(
|
||||||
|
{"name": "Test Agreement Type", "domain": "sale"}
|
||||||
|
)
|
||||||
|
self.test_agreement = self.env["agreement"].create(
|
||||||
|
{
|
||||||
|
"name": "TestAgreement",
|
||||||
|
"description": "Test",
|
||||||
|
"special_terms": "Test",
|
||||||
|
"partner_id": self.test_customer.id,
|
||||||
|
"start_date": fields.Date.today(),
|
||||||
|
"end_date": fields.Date.today() + timedelta(days=365),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.test_recital = self.env["agreement.recital"].create(
|
||||||
|
{
|
||||||
|
"name": "TestRecital",
|
||||||
|
"title": "Test",
|
||||||
|
"content": "Test",
|
||||||
|
"agreement_id": self.test_agreement.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
|
||||||
|
def test_onchange_copyvalue(self):
|
||||||
|
recital_01 = self.test_recital
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.recital"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
recital_01.field_id = field_01.id
|
||||||
|
recital_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(recital_01.copyvalue, "${object.active or ''}")
|
||||||
|
|
||||||
|
# TEST 02: Set related 'Field' for dynamic placeholder to
|
||||||
|
# test onchange method
|
||||||
|
def test_onchange_copyvalue2(self):
|
||||||
|
recital_01 = self.test_recital
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.recital"), ("name", "=", "agreement_id")]
|
||||||
|
)
|
||||||
|
sub_field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
recital_01.field_id = field_01.id
|
||||||
|
recital_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(recital_01.sub_object_id.model, "agreement")
|
||||||
|
recital_01.sub_model_object_field_id = sub_field_01.id
|
||||||
|
recital_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(recital_01.copyvalue, "${object.agreement_id.active or ''}")
|
||||||
|
|
||||||
|
# TEST 03: Test Dynamic Field
|
||||||
|
def test_compute_dynamic_content(self):
|
||||||
|
recital_01 = self.test_recital
|
||||||
|
recital_01.content = "${object.name}"
|
||||||
|
self.assertEqual(
|
||||||
|
recital_01.dynamic_content,
|
||||||
|
"<p>{" + str(recital_01.id) + ": '</p><p>TestRecital</p>'}",
|
||||||
|
)
|
||||||
69
agreement_legal/tests/test_agreement_section.py
Normal file
69
agreement_legal/tests/test_agreement_section.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from odoo import fields
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestAgreementSection(TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"})
|
||||||
|
self.agreement_type = self.env["agreement.type"].create(
|
||||||
|
{"name": "Test Agreement Type", "domain": "sale"}
|
||||||
|
)
|
||||||
|
self.test_agreement = self.env["agreement"].create(
|
||||||
|
{
|
||||||
|
"name": "TestAgreement",
|
||||||
|
"description": "Test",
|
||||||
|
"special_terms": "Test",
|
||||||
|
"partner_id": self.test_customer.id,
|
||||||
|
"start_date": fields.Date.today(),
|
||||||
|
"end_date": fields.Date.today() + timedelta(days=365),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.test_section = self.env["agreement.section"].create(
|
||||||
|
{
|
||||||
|
"name": "TestSection",
|
||||||
|
"title": "Test",
|
||||||
|
"content": "Test",
|
||||||
|
"agreement_id": self.test_agreement.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# TEST 01: Set 'Field' for dynamic placeholder, test onchange method
|
||||||
|
def test_onchange_copyvalue(self):
|
||||||
|
section_01 = self.test_section
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.section"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
section_01.field_id = field_01.id
|
||||||
|
section_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(section_01.copyvalue, "${object.active or ''}")
|
||||||
|
|
||||||
|
# TEST 02: Set related 'Field' for dynamic placeholder to
|
||||||
|
# test onchange method
|
||||||
|
def test_onchange_copyvalue2(self):
|
||||||
|
section_01 = self.test_section
|
||||||
|
field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement.section"), ("name", "=", "agreement_id")]
|
||||||
|
)
|
||||||
|
sub_field_01 = self.env["ir.model.fields"].search(
|
||||||
|
[("model", "=", "agreement"), ("name", "=", "active")]
|
||||||
|
)
|
||||||
|
section_01.field_id = field_01.id
|
||||||
|
section_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(section_01.sub_object_id.model, "agreement")
|
||||||
|
section_01.sub_model_object_field_id = sub_field_01.id
|
||||||
|
section_01.onchange_copyvalue()
|
||||||
|
self.assertEqual(section_01.copyvalue, "${object.agreement_id.active or ''}")
|
||||||
|
|
||||||
|
# TEST 03: Test Dynamic Field
|
||||||
|
def test_compute_dynamic_content(self):
|
||||||
|
section_01 = self.test_section
|
||||||
|
section_01.content = "${object.name}"
|
||||||
|
self.assertEqual(
|
||||||
|
section_01.dynamic_content,
|
||||||
|
"<p>{" + str(section_01.id) + ": '</p><p>TestSection</p>'}",
|
||||||
|
)
|
||||||
@@ -1,17 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<template
|
|
||||||
id="assets_backend"
|
|
||||||
name="agreement_legal assets"
|
|
||||||
inherit_id="web.assets_backend"
|
|
||||||
>
|
|
||||||
<xpath expr="." position="inside">
|
|
||||||
<script
|
|
||||||
type="text/javascript"
|
|
||||||
src="/agreement_legal/static/src/js/domain_widget_ext.js"
|
|
||||||
/>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
<!-- Agreement List View-->
|
<!-- Agreement List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_list_view">
|
<record model="ir.ui.view" id="partner_agreement_list_view">
|
||||||
<field name="name">Agreement List</field>
|
<field name="name">Agreement List</field>
|
||||||
@@ -59,8 +47,7 @@
|
|||||||
/>
|
/>
|
||||||
</header>
|
</header>
|
||||||
<sheet>
|
<sheet>
|
||||||
<div class="oe_button_box" name="button_box">
|
<div class="oe_button_box" name="button_box" />
|
||||||
</div>
|
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<label
|
<label
|
||||||
for="name"
|
for="name"
|
||||||
@@ -103,21 +90,30 @@
|
|||||||
<field name="description" required="True" nolabel="1" />
|
<field name="description" required="True" nolabel="1" />
|
||||||
</group>
|
</group>
|
||||||
<group class="oe_edit_only">
|
<group class="oe_edit_only">
|
||||||
<field
|
|
||||||
name="field_domain"
|
|
||||||
widget="domain"
|
|
||||||
nolabel="1"
|
|
||||||
options="{'model': 'agreement',
|
|
||||||
'partial_use': True}"
|
|
||||||
/>
|
|
||||||
<group>
|
<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="default_value" />
|
||||||
<field name="copyvalue" />
|
<field name="copyvalue" />
|
||||||
</group>
|
</group>
|
||||||
<p>
|
<p>
|
||||||
This section (on the left) allows you to add dynamic fields inside the description and special terms.
|
This section (on the left) allows you to add dynamic fields inside the description and special terms.
|
||||||
<ol>
|
<ol>
|
||||||
<li>Select the agreement field using the popup</li>
|
<li>Select the agreement field</li>
|
||||||
|
<li>Select the sub-field</li>
|
||||||
<li>Enter the default value if the field is empty</li>
|
<li>Enter the default value if the field is empty</li>
|
||||||
<li
|
<li
|
||||||
>Copy and paste the placeholder expression in the description or the special terms</li>
|
>Copy and paste the placeholder expression in the description or the special terms</li>
|
||||||
@@ -388,10 +384,7 @@
|
|||||||
<div
|
<div
|
||||||
class="o_kanban_record_subtitle text-muted"
|
class="o_kanban_record_subtitle text-muted"
|
||||||
>
|
>
|
||||||
<field
|
<field name="partner_id" />
|
||||||
name="partner_id"
|
|
||||||
invisible="context.get('default_partner_id', False)"
|
|
||||||
/>
|
|
||||||
<t
|
<t
|
||||||
t-if="record.end_date.raw_value and record.end_date.raw_value lt (new Date())"
|
t-if="record.end_date.raw_value and record.end_date.raw_value lt (new Date())"
|
||||||
t-set="red"
|
t-set="red"
|
||||||
@@ -416,6 +409,7 @@
|
|||||||
<span
|
<span
|
||||||
class="fa fa-ellipsis-v"
|
class="fa fa-ellipsis-v"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
title="Icon"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<ul
|
<ul
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Appendix List View-->
|
<!-- Agreement Appendix List View-->
|
||||||
<record model="ir.ui.view" id="agreement_appendix_tree">
|
<record model="ir.ui.view" id="agreement_appendix_tree">
|
||||||
@@ -21,20 +21,14 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Appendix">
|
<form string="Appendix">
|
||||||
<sheet>
|
<sheet>
|
||||||
<div class="oe_button_box" name="button_box">
|
<div class="oe_button_box" name="button_box" />
|
||||||
<button
|
<widget
|
||||||
name="toggle_active"
|
name="web_ribbon"
|
||||||
type="object"
|
title="Archived"
|
||||||
class="oe_stat_button"
|
bg_color="bg-danger"
|
||||||
icon="fa-archive"
|
attrs="{'invisible': [('active', '=', True)]}"
|
||||||
>
|
/>
|
||||||
<field
|
<field name="active" invisible="1" />
|
||||||
name="active"
|
|
||||||
widget="boolean_button"
|
|
||||||
options="{"terminology": "archive"}"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<label for="name" class="oe_edit_only" />
|
<label for="name" class="oe_edit_only" />
|
||||||
<h1>
|
<h1>
|
||||||
@@ -52,21 +46,30 @@
|
|||||||
</group>
|
</group>
|
||||||
<field name="content" widget="html" />
|
<field name="content" widget="html" />
|
||||||
<group class="oe_edit_only">
|
<group class="oe_edit_only">
|
||||||
<field
|
|
||||||
name="field_domain"
|
|
||||||
widget="domain"
|
|
||||||
nolabel="1"
|
|
||||||
options="{'model': 'agreement.appendix',
|
|
||||||
'partial_use': True}"
|
|
||||||
/>
|
|
||||||
<group>
|
<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="default_value" />
|
||||||
<field name="copyvalue" />
|
<field name="copyvalue" />
|
||||||
</group>
|
</group>
|
||||||
<p>
|
<p>
|
||||||
This section (on the left) allows you to add dynamic fields inside the content.
|
This section (on the left) allows you to add dynamic fields inside the content.
|
||||||
<ol>
|
<ol>
|
||||||
<li>Select the field using the popup</li>
|
<li>Select the appendix field</li>
|
||||||
|
<li>Select the sub-field</li>
|
||||||
<li>Enter the default value if the field is empty</li>
|
<li>Enter the default value if the field is empty</li>
|
||||||
<li
|
<li
|
||||||
>Copy and paste the placeholder expression in the content</li>
|
>Copy and paste the placeholder expression in the content</li>
|
||||||
@@ -82,7 +85,8 @@
|
|||||||
<field name="name">Agreement Appendix Search</field>
|
<field name="name">Agreement Appendix Search</field>
|
||||||
<field name="model">agreement.appendix</field>
|
<field name="model">agreement.appendix</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search>
|
<search string="Appendix">
|
||||||
|
<field name="name" />
|
||||||
<filter
|
<filter
|
||||||
name="group_agreement"
|
name="group_agreement"
|
||||||
icon="terp-partner"
|
icon="terp-partner"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Clause List View-->
|
<!-- Agreement Clause List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_clause_list_view">
|
<record model="ir.ui.view" id="partner_agreement_clause_list_view">
|
||||||
@@ -22,20 +22,14 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Clause">
|
<form string="Clause">
|
||||||
<sheet>
|
<sheet>
|
||||||
<div class="oe_button_box" name="button_box">
|
<div class="oe_button_box" name="button_box" />
|
||||||
<button
|
<widget
|
||||||
name="toggle_active"
|
name="web_ribbon"
|
||||||
type="object"
|
title="Archived"
|
||||||
class="oe_stat_button"
|
bg_color="bg-danger"
|
||||||
icon="fa-archive"
|
attrs="{'invisible': [('active', '=', True)]}"
|
||||||
>
|
/>
|
||||||
<field
|
<field name="active" invisible="1" />
|
||||||
name="active"
|
|
||||||
widget="boolean_button"
|
|
||||||
options="{"terminology": "archive"}"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<label for="name" class="oe_edit_only" />
|
<label for="name" class="oe_edit_only" />
|
||||||
<h1>
|
<h1>
|
||||||
@@ -57,21 +51,30 @@
|
|||||||
</group>
|
</group>
|
||||||
<field name="content" widget="html" />
|
<field name="content" widget="html" />
|
||||||
<group class="oe_edit_only">
|
<group class="oe_edit_only">
|
||||||
<field
|
|
||||||
name="field_domain"
|
|
||||||
widget="domain"
|
|
||||||
nolabel="1"
|
|
||||||
options="{'model': 'agreement.clause',
|
|
||||||
'partial_use': True}"
|
|
||||||
/>
|
|
||||||
<group>
|
<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="default_value" />
|
||||||
<field name="copyvalue" />
|
<field name="copyvalue" />
|
||||||
</group>
|
</group>
|
||||||
<p>
|
<p>
|
||||||
This section (on the left) allows you to add dynamic fields inside the content.
|
This section (on the left) allows you to add dynamic fields inside the content.
|
||||||
<ol>
|
<ol>
|
||||||
<li>Select the field using the popup</li>
|
<li>Select the clause field</li>
|
||||||
|
<li>Select the sub-field</li>
|
||||||
<li>Enter the default value if the field is empty</li>
|
<li>Enter the default value if the field is empty</li>
|
||||||
<li
|
<li
|
||||||
>Copy and paste the placeholder expression in the content</li>
|
>Copy and paste the placeholder expression in the content</li>
|
||||||
@@ -87,7 +90,8 @@
|
|||||||
<field name="name">Agreement Clause Search</field>
|
<field name="name">Agreement Clause Search</field>
|
||||||
<field name="model">agreement.clause</field>
|
<field name="model">agreement.clause</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Agreement Clause Search">
|
<search string="Clause">
|
||||||
|
<field name="name" />
|
||||||
<filter
|
<filter
|
||||||
name="group_agreement"
|
name="group_agreement"
|
||||||
icon="terp-partner"
|
icon="terp-partner"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Increase Type List View-->
|
<!-- Agreement Increase Type List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_increasetype_list_view">
|
<record model="ir.ui.view" id="partner_agreement_increasetype_list_view">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Recital List View-->
|
<!-- Agreement Recital List View-->
|
||||||
<record model="ir.ui.view" id="agreement_recital_tree">
|
<record model="ir.ui.view" id="agreement_recital_tree">
|
||||||
@@ -21,20 +21,14 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Recital">
|
<form string="Recital">
|
||||||
<sheet>
|
<sheet>
|
||||||
<div class="oe_button_box" name="button_box">
|
<div class="oe_button_box" name="button_box" />
|
||||||
<button
|
<widget
|
||||||
name="toggle_active"
|
name="web_ribbon"
|
||||||
type="object"
|
title="Archived"
|
||||||
class="oe_stat_button"
|
bg_color="bg-danger"
|
||||||
icon="fa-archive"
|
attrs="{'invisible': [('active', '=', True)]}"
|
||||||
>
|
/>
|
||||||
<field
|
<field name="active" invisible="1" />
|
||||||
name="active"
|
|
||||||
widget="boolean_button"
|
|
||||||
options="{"terminology": "archive"}"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<label for="name" class="oe_edit_only" />
|
<label for="name" class="oe_edit_only" />
|
||||||
<h1>
|
<h1>
|
||||||
@@ -52,21 +46,30 @@
|
|||||||
</group>
|
</group>
|
||||||
<field name="content" widget="html" />
|
<field name="content" widget="html" />
|
||||||
<group class="oe_edit_only">
|
<group class="oe_edit_only">
|
||||||
<field
|
|
||||||
name="field_domain"
|
|
||||||
widget="domain"
|
|
||||||
nolabel="1"
|
|
||||||
options="{'model': 'agreement.recital',
|
|
||||||
'partial_use': True}"
|
|
||||||
/>
|
|
||||||
<group>
|
<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="default_value" />
|
||||||
<field name="copyvalue" />
|
<field name="copyvalue" />
|
||||||
</group>
|
</group>
|
||||||
<p>
|
<p>
|
||||||
This section (on the left) allows you to add dynamic fields inside the content.
|
This section (on the left) allows you to add dynamic fields inside the content.
|
||||||
<ol>
|
<ol>
|
||||||
<li>Select the field using the popup</li>
|
<li>Select the recital field</li>
|
||||||
|
<li>Select the sub-field</li>
|
||||||
<li>Enter the default value if the field is empty</li>
|
<li>Enter the default value if the field is empty</li>
|
||||||
<li
|
<li
|
||||||
>Copy and paste the placeholder expression in the content</li>
|
>Copy and paste the placeholder expression in the content</li>
|
||||||
@@ -82,7 +85,8 @@
|
|||||||
<field name="name">Agreement Recital Search</field>
|
<field name="name">Agreement Recital Search</field>
|
||||||
<field name="model">agreement.recital</field>
|
<field name="model">agreement.recital</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search>
|
<search string="Recitals">
|
||||||
|
<field name="name" />
|
||||||
<filter
|
<filter
|
||||||
name="group_agreement"
|
name="group_agreement"
|
||||||
icon="terp-partner"
|
icon="terp-partner"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Renewal Type List View-->
|
<!-- Agreement Renewal Type List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_renewaltype_list_view">
|
<record model="ir.ui.view" id="partner_agreement_renewaltype_list_view">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Sections List View-->
|
<!-- Agreement Sections List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_section_list_view">
|
<record model="ir.ui.view" id="partner_agreement_section_list_view">
|
||||||
@@ -21,20 +21,14 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Section">
|
<form string="Section">
|
||||||
<sheet>
|
<sheet>
|
||||||
<div class="oe_button_box" name="button_box">
|
<div class="oe_button_box" name="button_box" />
|
||||||
<button
|
<widget
|
||||||
name="toggle_active"
|
name="web_ribbon"
|
||||||
type="object"
|
title="Archived"
|
||||||
class="oe_stat_button"
|
bg_color="bg-danger"
|
||||||
icon="fa-archive"
|
attrs="{'invisible': [('active', '=', True)]}"
|
||||||
>
|
/>
|
||||||
<field
|
<field name="active" invisible="1" />
|
||||||
name="active"
|
|
||||||
widget="boolean_button"
|
|
||||||
options="{"terminology": "archive"}"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<label for="name" class="oe_edit_only" />
|
<label for="name" class="oe_edit_only" />
|
||||||
<h1>
|
<h1>
|
||||||
@@ -54,21 +48,30 @@
|
|||||||
<page string="Content">
|
<page string="Content">
|
||||||
<field name='content' nolabel="1" />
|
<field name='content' nolabel="1" />
|
||||||
<group class="oe_edit_only">
|
<group class="oe_edit_only">
|
||||||
<field
|
|
||||||
name="field_domain"
|
|
||||||
widget="domain"
|
|
||||||
nolabel="1"
|
|
||||||
options="{'model': 'agreement.section',
|
|
||||||
'partial_use': True}"
|
|
||||||
/>
|
|
||||||
<group>
|
<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="default_value" />
|
||||||
<field name="copyvalue" />
|
<field name="copyvalue" />
|
||||||
</group>
|
</group>
|
||||||
<p>
|
<p>
|
||||||
This section (on the left) allows you to add dynamic fields inside the content.
|
This section (on the left) allows you to add dynamic fields inside the content.
|
||||||
<ol>
|
<ol>
|
||||||
<li>Select the field using the popup</li>
|
<li>Select the section field</li>
|
||||||
|
<li>Select the sub-field</li>
|
||||||
<li
|
<li
|
||||||
>Enter the default value if the field is empty</li>
|
>Enter the default value if the field is empty</li>
|
||||||
<li
|
<li
|
||||||
@@ -100,7 +103,8 @@
|
|||||||
<field name="name">Agreement Section Search</field>
|
<field name="name">Agreement Section Search</field>
|
||||||
<field name="model">agreement.section</field>
|
<field name="model">agreement.section</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Agreement Section Search">
|
<search string="Section">
|
||||||
|
<field name="name" />
|
||||||
<filter
|
<filter
|
||||||
name="group_agreement"
|
name="group_agreement"
|
||||||
string="Agreements"
|
string="Agreements"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Stage List View-->
|
<!-- Agreement Stage List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_stage_list_view">
|
<record model="ir.ui.view" id="partner_agreement_stage_list_view">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Sub Type List View-->
|
<!-- Agreement Sub Type List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_subtype_list_view">
|
<record model="ir.ui.view" id="partner_agreement_subtype_list_view">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Agreement Type List View-->
|
<!-- Agreement Type List View-->
|
||||||
<record model="ir.ui.view" id="partner_agreement_type_list_view">
|
<record model="ir.ui.view" id="partner_agreement_type_list_view">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- Remove top menu from agreement module -->
|
<!-- Remove top menu from agreement module -->
|
||||||
<!-- <delete model="ir.ui.menu" id="agreement.agreement_menu" /> -->
|
<!-- <delete model="ir.ui.menu" id="agreement.agreement_menu" /> -->
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||||
<field name="name">res.config.settings.view.form.agreement</field>
|
<field name="name">res.config.settings.view.form.agreement</field>
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<field name="module_agreement_sale" />
|
<field name="module_agreement_sale" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Sales" />
|
<label for="module_agreement_sale" string="Sales" />
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Create an agreement when the sales order is confirmed
|
Create an agreement when the sales order is confirmed
|
||||||
</div>
|
</div>
|
||||||
@@ -63,7 +63,10 @@
|
|||||||
<field name="module_agreement_sale_subscription" />
|
<field name="module_agreement_sale_subscription" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Sale Subscriptions" />
|
<label
|
||||||
|
for="module_agreement_sale_subscription"
|
||||||
|
string="Sale Subscriptions"
|
||||||
|
/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your subscriptions to an agreement
|
Link your subscriptions to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -74,7 +77,10 @@
|
|||||||
<field name="module_fieldservice_agreement" />
|
<field name="module_fieldservice_agreement" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Field Service" />
|
<label
|
||||||
|
for="module_fieldservice_agreement"
|
||||||
|
string="Field Service"
|
||||||
|
/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your Field Service orders and equipments to an agreement
|
Link your Field Service orders and equipments to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -85,7 +91,10 @@
|
|||||||
<field name="module_agreement_stock" />
|
<field name="module_agreement_stock" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Inventory" />
|
<label
|
||||||
|
for="module_agreement_stock"
|
||||||
|
string="Inventory"
|
||||||
|
/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your transfers to an agreement
|
Link your transfers to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -96,7 +105,7 @@
|
|||||||
<field name="module_agreement_rma" />
|
<field name="module_agreement_rma" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Returns" />
|
<label for="module_agreement_rma" string="Returns" />
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your returns to an agreement
|
Link your returns to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -107,7 +116,10 @@
|
|||||||
<field name="module_agreement_maintenance" />
|
<field name="module_agreement_maintenance" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Maintenance" />
|
<label
|
||||||
|
for="module_agreement_maintenance"
|
||||||
|
string="Maintenance"
|
||||||
|
/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Manage maintenance agreements and contracts
|
Manage maintenance agreements and contracts
|
||||||
</div>
|
</div>
|
||||||
@@ -118,7 +130,10 @@
|
|||||||
<field name="module_agreement_mrp" />
|
<field name="module_agreement_mrp" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Manufacturing" />
|
<label
|
||||||
|
for="module_agreement_mrp"
|
||||||
|
string="Manufacturing"
|
||||||
|
/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your manufacturing orders to an agreement
|
Link your manufacturing orders to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -129,7 +144,7 @@
|
|||||||
<field name="module_agreement_repair" />
|
<field name="module_agreement_repair" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Repair" />
|
<label for="module_agreement_repair" string="Repair" />
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your repair orders to an agreement
|
Link your repair orders to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -140,7 +155,10 @@
|
|||||||
<field name="module_agreement_project" />
|
<field name="module_agreement_project" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Project" />
|
<label
|
||||||
|
for="module_agreement_project"
|
||||||
|
string="Project"
|
||||||
|
/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your projects and tasks to an agreement
|
Link your projects and tasks to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -151,7 +169,10 @@
|
|||||||
<field name="module_agreement_helpdesk" />
|
<field name="module_agreement_helpdesk" />
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label for="" string="Helpdesk" />
|
<label
|
||||||
|
for="module_agreement_helpdesk"
|
||||||
|
string="Helpdesk"
|
||||||
|
/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Link your Helpdesk tickets to an agreement
|
Link your Helpdesk tickets to an agreement
|
||||||
</div>
|
</div>
|
||||||
@@ -162,12 +183,11 @@
|
|||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
<act_window
|
<record id="action_agreement_config" model="ir.actions.act_window">
|
||||||
id="action_agreement_config"
|
<field name="name">Settings</field>
|
||||||
name="Settings"
|
<field name="res_model">res.config.settings</field>
|
||||||
res_model="res.config.settings"
|
<field name="view_mode">form</field>
|
||||||
view_mode="form"
|
<field name="target">inline</field>
|
||||||
target="inline"
|
<field name="context">{'module': 'agreement'}</field>
|
||||||
context="{'module': 'agreement'}"
|
</record>
|
||||||
/>
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record model="ir.ui.view" id="partner_form">
|
<record model="ir.ui.view" id="partner_form">
|
||||||
<field name="model">res.partner</field>
|
<field name="model">res.partner</field>
|
||||||
|
|||||||
Reference in New Issue
Block a user