[IMP]16335: 12.0 improve dynamic content generation

[UPD] README.rst

[UPD] Update agreement_legal.pot
This commit is contained in:
Sandip Mangukiya
2019-05-29 10:54:12 -07:00
committed by Víctor Martínez
parent b5979055cf
commit 86911287c3
18 changed files with 583 additions and 339 deletions

View File

@@ -61,6 +61,12 @@ To use this module:
* Follow the process to get the required approval
* Send the invitation to the customer to review and sign the agreement
* Define Field using widget domain but having partial_use option true:
* For Ex:
* <field name="field_domain" widget="domain" nolabel="1"
* options="{'model': 'agreement.recital',
* 'partial_use': True}"/>
Known issues / Roadmap
======================

View File

@@ -37,6 +37,8 @@
],
"demo": [
"demo/demo.xml"
'qweb': [
"static/src/xml/domain_widget_view.xml",
],
"post_init_hook": "post_init_agreement_legal",
"application": True,

View File

@@ -13,6 +13,13 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:72
#, python-format
msgid "# Code editor"
msgstr ""
#. module: agreement_legal
#: selection:agreement,state:0
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__active
@@ -23,6 +30,42 @@ msgstr ""
msgid "Active"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:86
#, python-format
msgid "Add branch"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:38
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:56
#, python-format
msgid "Add filter"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:123
#, python-format
msgid "Add new value"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:85
#, python-format
msgid "Add node"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:124
#, python-format
msgid "Add tag"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view
msgid "Administration"
@@ -258,6 +301,13 @@ msgstr ""
msgid "Clauses"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:169
#, python-format
msgid "Close"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__color
msgid "Color"
@@ -431,6 +481,13 @@ msgstr ""
msgid "Default Value"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:84
#, python-format
msgid "Delete node"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__renewal_type_id
msgid "Describes what happens after the contract expires."
@@ -473,6 +530,13 @@ msgstr ""
msgid "Display Name"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:21
#, python-format
msgid "Domain"
msgstr ""
#. module: agreement_legal
#: selection:agreement,state:0
msgid "Draft"
@@ -506,6 +570,13 @@ msgstr ""
msgid "Edit"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:28
#, python-format
msgid "Edit Domain"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_contact_email
msgid "Email"
@@ -531,12 +602,12 @@ msgid "Exp. Notice (Days)"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_appendix__field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_clause__field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_recital__field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_section__field_id
msgid "Field"
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__field_domain
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_appendix__field_domain
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_clause__field_domain
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_recital__field_domain
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_section__field_domain
msgid "Field Expression"
msgstr ""
#. module: agreement_legal
@@ -630,6 +701,20 @@ msgstr ""
msgid "Increase types describe any increases that may happen during the contract."
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:26
#, python-format
msgid "Invalid domain"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:162
#, python-format
msgid "Invalid field chain"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form
msgid "Inventory"
@@ -807,6 +892,27 @@ msgstr ""
msgid "Master Data"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:55
#, python-format
msgid "Match"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:62
#, python-format
msgid "Match records with"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:60
#, python-format
msgid "Match records with the following rule:"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_appendix__name
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_clause__name
@@ -824,8 +930,8 @@ msgstr ""
#. module: agreement_legal
#: code:addons/agreement_legal/models/agreement.py:84
#: code:addons/agreement_legal/models/agreement.py:384
#: code:addons/agreement_legal/models/agreement.py:387
#: code:addons/agreement_legal/models/agreement.py:364
#: code:addons/agreement_legal/models/agreement.py:367
#, python-format
msgid "New"
msgstr ""
@@ -963,11 +1069,25 @@ msgstr ""
msgid "Placeholder Expression"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:42
#, python-format
msgid "Please navigate below and select field:"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view
msgid "Preview"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:167
#, python-format
msgid "Previous"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__previous_version_agreements_ids
msgid "Previous Versions"
@@ -1054,6 +1174,13 @@ msgstr ""
msgid "Reference"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:119
#, python-format
msgid "Remove tag"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__renewal_type_id
msgid "Renewal Type"
@@ -1114,6 +1241,20 @@ msgstr ""
msgid "Revisions"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:37
#, python-format
msgid "SMatch"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:44
#, python-format
msgid "SSMatch records with"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form
msgid "Sale Subscriptions"
@@ -1144,29 +1285,15 @@ msgid "Sections"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_appendix__field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_clause__field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_recital__field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_section__field_id
msgid "Select target field from the related document model. If it is a\n"
" relationship field you will be able to select a target field at the\n"
" destination of the relationship."
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:30
#, python-format
msgid "Select a model to add a filter."
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view
msgid "Select the agreement field"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.agreement_appendix_form
msgid "Select the appendix field"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_clause_form_view
msgid "Select the clause field"
msgid "Select the agreement field using the popup"
msgstr ""
#. module: agreement_legal
@@ -1174,23 +1301,12 @@ msgstr ""
msgid "Select the current stage of the agreement."
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.agreement_recital_form
msgid "Select the recital field"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_section_form_view
msgid "Select the section field"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.agreement_appendix_form
#: model_terms:ir.ui.view,arch_db:agreement_legal.agreement_recital_form
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_clause_form_view
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_section_form_view
msgid "Select the sub-field"
msgid "Select the field using the popup"
msgstr ""
#. module: agreement_legal
@@ -1314,24 +1430,6 @@ msgstr ""
msgid "Sub-Types"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__sub_model_object_field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_appendix__sub_model_object_field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_clause__sub_model_object_field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_recital__sub_model_object_field_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_section__sub_model_object_field_id
msgid "Sub-field"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement__sub_object_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_appendix__sub_object_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_clause__sub_object_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_recital__sub_object_id
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_section__sub_object_id
msgid "Sub-model"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,field_description:agreement_legal.field_agreement_type__agreement_subtypes_ids
msgid "Subtypes"
@@ -1511,24 +1609,10 @@ msgid "Version:"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__sub_model_object_field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_appendix__sub_model_object_field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_clause__sub_model_object_field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_recital__sub_model_object_field_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_section__sub_model_object_field_id
msgid "When a relationship field is selected as first field, this\n"
" field lets you select the target field within the destination document\n"
" model (sub-model)."
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement__sub_object_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_appendix__sub_object_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_clause__sub_object_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_recital__sub_object_id
#: model:ir.model.fields,help:agreement_legal.field_agreement_section__sub_object_id
msgid "When a relationship field is selected as first field, this\n"
" field shows the document model the relationship goes to."
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:26
#, python-format
msgid "Warning"
msgstr ""
#. module: agreement_legal
@@ -1541,6 +1625,14 @@ msgstr ""
msgid "When the agreement starts."
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:37
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:55
#, python-format
msgid "all records"
msgstr ""
#. module: agreement_legal
#: model:ir.model.fields,help:agreement_legal.field_agreement_appendix__dynamic_content
#: model:ir.model.fields,help:agreement_legal.field_agreement_clause__dynamic_content
@@ -1549,16 +1641,59 @@ msgstr ""
msgid "compute dynamic Content"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:151
#, python-format
msgid "is"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:153
#, python-format
msgid "not"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.view_project_agreement_kanban
msgid "oe_kanban_text_red"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:46
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:64
#, python-format
msgid "of the following rules:"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view
msgid "on"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:144
#, python-format
msgid "or"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:24
#, python-format
msgid "record(s)"
msgstr ""
#. module: agreement_legal
#. openerp-web
#: code:addons/agreement_legal/static/src/xml/domain_widget_view.xml:153
#, python-format
msgid "set"
msgstr ""
#. module: agreement_legal
#: model_terms:ir.ui.view,arch_db:agreement_legal.view_project_agreement_kanban
msgid "user & picture"

View File

@@ -246,23 +246,10 @@ class Agreement(models.Model):
signed_contract_filename = fields.Char(string="Filename")
signed_contract = fields.Binary(
string="Signed Document", track_visibility="always")
field_id = fields.Many2one(
"ir.model.fields",
string="Field",
help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the
destination of the relationship.""")
sub_object_id = fields.Many2one(
"ir.model",
string="Sub-model",
help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""")
sub_model_object_field_id = fields.Many2one(
"ir.model.fields",
string="Sub-field",
help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document
model (sub-model).""")
# Dynamic field editor
field_domain = fields.Char(string='Field Expression',
default='[["active", "=", True]]')
default_value = fields.Char(
string="Default Value",
help="Optional value to use if the target field is empty.")
@@ -271,6 +258,17 @@ class Agreement(models.Model):
help="""Final placeholder expression, to be copy-pasted in the desired
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
@api.multi
def _compute_dynamic_description(self):
@@ -308,24 +306,6 @@ class Agreement(models.Model):
)
agreement.dynamic_special_terms = special_terms
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
def onchange_copyvalue(self):
self.sub_object_id = False
self.copyvalue = False
self.sub_object_id = False
if self.field_id and not self.field_id.relation:
self.copyvalue = "${{object.{} or {}}}".format(
self.field_id.name, self.default_value or "''")
self.sub_model_object_field_id = False
if self.field_id and self.field_id.relation:
self.sub_object_id = self.env["ir.model"].search(
[("model", "=", self.field_id.relation)])[0]
if self.sub_model_object_field_id:
self.copyvalue = "${{object.{}.{} or {}}}".format(
self.field_id.name,
self.sub_model_object_field_id.name,
self.default_value or "''")
# Used for Kanban grouped_by view
@api.model
def _read_group_stage_ids(self, stages, domain, order):

View File

@@ -36,54 +36,26 @@ class AgreementAppendix(models.Model):
)
# Dynamic field editor
field_id = fields.Many2one(
"ir.model.fields",
string="Field",
help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the
destination of the relationship.""",
)
sub_object_id = fields.Many2one(
"ir.model",
string="Sub-model",
help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""",
)
sub_model_object_field_id = fields.Many2one(
"ir.model.fields",
string="Sub-field",
help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document
model (sub-model).""",
)
field_domain = fields.Char(string='Field Expression',
default='[["active", "=", True]]')
default_value = fields.Char(
string="Default Value",
help="Optional value to use if the target field is empty.",
)
help="Optional value to use if the target field is empty.")
copyvalue = fields.Char(
string="Placeholder Expression",
help="""Final placeholder expression, to be copy-pasted in the desired
template field.""",
)
template field.""")
@api.onchange('field_id', 'sub_model_object_field_id', 'default_value')
@api.onchange("field_domain", "default_value")
def onchange_copyvalue(self):
self.sub_object_id = False
self.copyvalue = False
self.sub_object_id = False
if self.field_id and not self.field_id.relation:
self.copyvalue = "${object.%s or %s}" % \
(self.field_id.name,
self.default_value or '\'\'')
self.sub_model_object_field_id = False
if self.field_id and self.field_id.relation:
self.sub_object_id = self.env['ir.model'].search(
[('model', '=', self.field_id.relation)])[0]
if self.sub_model_object_field_id:
self.copyvalue = "${object.%s.%s or %s}" %\
(self.field_id.name,
self.sub_model_object_field_id.name,
self.default_value or '\'\'')
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
@api.multi

View File

@@ -34,23 +34,8 @@ class AgreementClause(models.Model):
"removing it.")
# Dynamic field editor
field_id = fields.Many2one(
"ir.model.fields",
string="Field",
help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the
destination of the relationship.""")
sub_object_id = fields.Many2one(
"ir.model",
string="Sub-model",
help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""")
sub_model_object_field_id = fields.Many2one(
"ir.model.fields",
string="Sub-field",
help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document
model (sub-model).""")
field_domain = fields.Char(string='Field Expression',
default='[["active", "=", True]]')
default_value = fields.Char(
string="Default Value",
help="Optional value to use if the target field is empty.")
@@ -59,24 +44,16 @@ class AgreementClause(models.Model):
help="""Final placeholder expression, to be copy-pasted in the desired
template field.""")
@api.onchange('field_id', 'sub_model_object_field_id', 'default_value')
@api.onchange("field_domain", "default_value")
def onchange_copyvalue(self):
self.sub_object_id = False
self.copyvalue = False
self.sub_object_id = False
if self.field_id and not self.field_id.relation:
self.copyvalue = "${object.%s or %s}" % \
(self.field_id.name,
self.default_value or '\'\'')
self.sub_model_object_field_id = False
if self.field_id and self.field_id.relation:
self.sub_object_id = self.env['ir.model'].search(
[('model', '=', self.field_id.relation)])[0]
if self.sub_model_object_field_id:
self.copyvalue = "${object.%s.%s or %s}" %\
(self.field_id.name,
self.sub_model_object_field_id.name,
self.default_value or '\'\'')
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
@api.multi

View File

@@ -12,76 +12,42 @@ class AgreementRecital(models.Model):
name = fields.Char(string="Name", required=True)
title = fields.Char(
string="Title",
help="The title is displayed on the PDF." "The name is not.",
)
help="The title is displayed on the PDF." "The name is not.")
sequence = fields.Integer(string="Sequence", default=10)
content = fields.Html(string="Content")
dynamic_content = fields.Html(
compute="_compute_dynamic_content",
string="Dynamic Content",
help="compute dynamic Content",
)
help="compute dynamic Content")
agreement_id = fields.Many2one(
"agreement", string="Agreement", ondelete="cascade"
)
"agreement", string="Agreement", ondelete="cascade")
active = fields.Boolean(
string="Active",
default=True,
help="If unchecked, it will allow you to hide this recital without "
"removing it.",
)
"removing it.")
# Dynamic field editor
field_id = fields.Many2one(
"ir.model.fields",
string="Field",
help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the
destination of the relationship.""",
)
sub_object_id = fields.Many2one(
"ir.model",
string="Sub-model",
help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""",
)
sub_model_object_field_id = fields.Many2one(
"ir.model.fields",
string="Sub-field",
help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document
model (sub-model).""",
)
field_domain = fields.Char(string='Field Expression',
default='[["active", "=", True]]')
default_value = fields.Char(
string="Default Value",
help="Optional value to use if the target field is empty.",
)
help="Optional value to use if the target field is empty.")
copyvalue = fields.Char(
string="Placeholder Expression",
help="""Final placeholder expression, to be copy-pasted in the desired
template field.""",
)
template field.""")
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
@api.onchange("field_domain", "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 "''",
)
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
@api.multi
@@ -91,9 +57,7 @@ class AgreementRecital(models.Model):
lang = (
recital.agreement_id
and recital.agreement_id.partner_id.lang
or "en_US"
)
or "en_US")
content = MailTemplates.with_context(lang=lang)._render_template(
recital.content, "agreement.recital", recital.id
)
recital.content, "agreement.recital", recital.id)
recital.dynamic_content = content

View File

@@ -30,23 +30,8 @@ class AgreementSection(models.Model):
"removing it.")
# Dynamic field editor
field_id = fields.Many2one(
"ir.model.fields",
string="Field",
help="""Select target field from the related document model. If it is a
relationship field you will be able to select a target field at the
destination of the relationship.""")
sub_object_id = fields.Many2one(
"ir.model",
string="Sub-model",
help="""When a relationship field is selected as first field, this
field shows the document model the relationship goes to.""")
sub_model_object_field_id = fields.Many2one(
"ir.model.fields",
string="Sub-field",
help="""When a relationship field is selected as first field, this
field lets you select the target field within the destination document
model (sub-model).""")
field_domain = fields.Char(string='Field Expression',
default='[["active", "=", True]]')
default_value = fields.Char(
string="Default Value",
help="Optional value to use if the target field is empty.")
@@ -55,25 +40,16 @@ class AgreementSection(models.Model):
help="""Final placeholder expression, to be copy-pasted in the desired
template field.""")
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
@api.onchange("field_domain", "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 "''",
)
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
@api.multi

View File

@@ -5,3 +5,9 @@ To use this module:
* Select a template
* Follow the process to get the required approval
* Send the invitation to the customer to review and sign the agreement
* Define Field using widget domain but having partial_use option true:
* For Ex:
* <field name="field_domain" widget="domain" nolabel="1"
* options="{'model': 'agreement.recital',
* 'partial_use': True}"/>

View File

@@ -93,7 +93,7 @@
</tr>
</tbody>
</table>
<t t-if="special_term">
<t t-if="doc.special_terms">
<h2>Special Terms</h2>
<div name="special_term">
<p t-field="doc.dynamic_special_terms"/>

View File

@@ -410,6 +410,11 @@ customer signature.</p>
<li>Select a template</li>
<li>Follow the process to get the required approval</li>
<li>Send the invitation to the customer to review and sign the agreement</li>
<li>Define Field using widget domain but having partial_use option true:</li>
<li>For Ex:</li>
<li>&lt;field name=”field_domain” widget=”domain” nolabel=”1”</li>
<li>options=”{model: agreement.recital,</li>
<li>partial_use: True}”/&gt;</li>
</ul>
</div>
<div class="section" id="known-issues-roadmap">

View File

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

View File

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

View File

@@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<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-->
<record model="ir.ui.view" id="partner_agreement_list_view">
<field name="name">Agreement List</field>
@@ -65,26 +73,17 @@
nolabel="1"/>
</group>
<group class="oe_edit_only">
<field name="field_domain" widget="domain" nolabel="1"
options="{'model': 'agreement',
'partial_use': True}" />
<group>
<field name="field_id"
domain="[('model_id', '=', active_model),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"/>
<field name="default_value"/>
<field name="copyvalue"/>
</group>
<p>
This section (on the left) allows you to add dynamic fields inside the description and special terms.
<ol>
<li>Select the agreement field</li>
<li>Select the sub-field</li>
<li>Select the agreement field using the popup</li>
<li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the description or the special terms</li>
</ol>

View File

@@ -44,26 +44,17 @@
</group>
<field name="content" widget="html"/>
<group class="oe_edit_only">
<field name="field_domain" widget="domain" nolabel="1"
options="{'model': 'agreement.appendix',
'partial_use': True}" />
<group>
<field name="field_id"
domain="[('model_id', '=', active_model),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"/>
<field name="default_value"/>
<field name="copyvalue"/>
</group>
<p>
This section (on the left) allows you to add dynamic fields inside the content.
<ol>
<li>Select the appendix field</li>
<li>Select the sub-field</li>
<li>Select the field using the popup</li>
<li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the content</li>
</ol>

View File

@@ -45,26 +45,17 @@
</group>
<field name="content" widget="html"/>
<group class="oe_edit_only">
<field name="field_domain" widget="domain" nolabel="1"
options="{'model': 'agreement.clause',
'partial_use': True}" />
<group>
<field name="field_id"
domain="[('model_id', '=', active_model),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"/>
<field name="default_value"/>
<field name="copyvalue"/>
</group>
<p>
This section (on the left) allows you to add dynamic fields inside the content.
<ol>
<li>Select the clause field</li>
<li>Select the sub-field</li>
<li>Select the field using the popup</li>
<li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the content</li>
</ol>

View File

@@ -24,8 +24,10 @@
<form string="Recital">
<sheet>
<div class="oe_button_box" name="button_box">
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/>
<button name="toggle_active" type="object"
class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button"
options="{&quot;terminology&quot;: &quot;archive&quot;}"/>
</button>
</div>
<div class="oe_title">
@@ -43,26 +45,17 @@
</group>
<field name="content" widget="html"/>
<group class="oe_edit_only">
<field name="field_domain" widget="domain" nolabel="1"
options="{'model': 'agreement.recital',
'partial_use': True}" />
<group>
<field name="field_id"
domain="[('model_id', '=', active_model),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"/>
<field name="default_value"/>
<field name="copyvalue"/>
</group>
<p>
This section (on the left) allows you to add dynamic fields inside the content.
<ol>
<li>Select the recital field</li>
<li>Select the sub-field</li>
<li>Select the field using the popup</li>
<li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the content</li>
</ol>

View File

@@ -45,26 +45,17 @@
<page string="Content">
<field name='content' nolabel="1"/>
<group class="oe_edit_only">
<field name="field_domain" widget="domain" nolabel="1"
options="{'model': 'agreement.section',
'partial_use': True}" />
<group>
<field name="field_id"
domain="[('model_id', '=', active_model),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"/>
<field name="sub_object_id" readonly="1"/>
<field name="sub_model_object_field_id"
domain="[('model_id', '=', sub_object_id),
('ttype', '!=', 'one2many'),
('ttype', '!=', 'many2many')]"
attrs="{'readonly':[('sub_object_id', '=', False)],
'required':[('sub_object_id', '!=', False)]}"/>
<field name="default_value"/>
<field name="copyvalue"/>
</group>
<p>
This section (on the left) allows you to add dynamic fields inside the content.
<ol>
<li>Select the section field</li>
<li>Select the sub-field</li>
<li>Select the field using the popup</li>
<li>Enter the default value if the field is empty</li>
<li>Copy and paste the placeholder expression in the content</li>
</ol>