From c0182f6e1bd1918a480eedd6cc163cdb091bbcfd Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 7 May 2019 12:40:10 -0500 Subject: [PATCH 1/6] [FIX] Issue #323 + Cleanup --- agreement_legal/models/agreement_section.py | 45 +++++++-------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/agreement_legal/models/agreement_section.py b/agreement_legal/models/agreement_section.py index 2fe67ea9..4ef260aa 100644 --- a/agreement_legal/models/agreement_section.py +++ b/agreement_legal/models/agreement_section.py @@ -12,27 +12,22 @@ class AgreementSection(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") agreement_id = fields.Many2one( - "agreement", string="Agreement", ondelete="cascade" - ) + "agreement", string="Agreement", ondelete="cascade") clauses_ids = fields.One2many( - "agreement.clause", "section_id", string="Clauses" - ) + "agreement.clause", "section_id", string="Clauses",copy=True) content = fields.Html(string="Section Content") dynamic_content = fields.Html( compute="_compute_dynamic_content", string="Dynamic Content", - help="compute dynamic Content", - ) + help="compute dynamic Content") active = fields.Boolean( string="Active", default=True, - help="""If unchecked, it will allow you to hide the - agreement without removing it.""", - ) + help="If unchecked, it will allow you to hide the agreement without " + "removing it.") # Dynamic field editor field_id = fields.Many2one( @@ -40,30 +35,25 @@ class AgreementSection(models.Model): 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.""", - ) + 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.""", - ) + 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).""", - ) + model (sub-model).""") 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") def onchange_copyvalue(self): @@ -72,8 +62,7 @@ class AgreementSection(models.Model): 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.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( @@ -91,12 +80,8 @@ class AgreementSection(models.Model): def _compute_dynamic_content(self): MailTemplates = self.env["mail.template"] for section in self: - lang = ( - section.agreement_id - and section.agreement_id.partner_id.lang - or "en_US" - ) + lang = (section.agreement_id and + section.agreement_id.partner_id.lang or "en_US") content = MailTemplates.with_context(lang=lang)._render_template( - section.content, "agreement.section", section.id - ) + section.content, "agreement.section", section.id) section.dynamic_content = content From 77c5233467906f3ce9abe76b3e6320bf9f768d23 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 7 May 2019 12:43:08 -0500 Subject: [PATCH 2/6] Update agreement_section.py --- agreement_legal/models/agreement_section.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agreement_legal/models/agreement_section.py b/agreement_legal/models/agreement_section.py index 4ef260aa..2d9220df 100644 --- a/agreement_legal/models/agreement_section.py +++ b/agreement_legal/models/agreement_section.py @@ -17,7 +17,7 @@ class AgreementSection(models.Model): agreement_id = fields.Many2one( "agreement", string="Agreement", ondelete="cascade") clauses_ids = fields.One2many( - "agreement.clause", "section_id", string="Clauses",copy=True) + "agreement.clause", "section_id", string="Clauses", copy=True) content = fields.Html(string="Section Content") dynamic_content = fields.Html( compute="_compute_dynamic_content", From 00a3da61ab877dd332fd78b483ed3fd0c7647486 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 7 May 2019 12:47:12 -0500 Subject: [PATCH 3/6] [FIX] Missing newline --- agreement/security/ir.model.access.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agreement/security/ir.model.access.csv b/agreement/security/ir.model.access.csv index 54dd4f50..3184640e 100644 --- a/agreement/security/ir.model.access.csv +++ b/agreement/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_agreement_read,Read access on agreement to Employees,model_agreement,base.group_user,1,0,0,0 -access_agreement_full,Full access on agreement grp,model_agreement,base.group_no_one,1,1,1,1 \ No newline at end of file +access_agreement_full,Full access on agreement grp,model_agreement,base.group_no_one,1,1,1,1 From 0ea12fcb6b4324ff0d2805d8e582c2d211b618c5 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Wed, 8 May 2019 08:28:48 -0500 Subject: [PATCH 4/6] [FIX] Duplicate label --- agreement_legal/models/agreement.py | 28 +++++++++++----------------- agreement_legal/report/agreement.xml | 4 ++-- agreement_legal/views/agreement.xml | 8 ++++---- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/agreement_legal/models/agreement.py b/agreement_legal/models/agreement.py index 8a87cf96..c98f4e94 100644 --- a/agreement_legal/models/agreement.py +++ b/agreement_legal/models/agreement.py @@ -65,7 +65,7 @@ class Agreement(models.Model): help="Date the contract was signed by Company.", ) partner_signed_date = fields.Date( - string="Signed on", + string="Signed on (Partner)", track_visibility="onchange", help="Date the contract was signed by the Partner.", ) @@ -140,12 +140,6 @@ class Agreement(models.Model): copy=True, help="The customer or vendor this agreement is related to.", ) - company_partner_id = fields.Many2one( - "res.partner", - string="Company", - copy=True, - default=lambda self: self.env.user.company_id.partner_id, - ) partner_contact_id = fields.Many2one( "res.partner", string="Partner Contact", @@ -153,10 +147,10 @@ class Agreement(models.Model): help="The primary partner contact (If Applicable).", ) partner_contact_phone = fields.Char( - related="partner_contact_id.phone", string="Phone" + related="partner_contact_id.phone", string="Partner Phone" ) partner_contact_email = fields.Char( - related="partner_contact_id.email", string="Email" + related="partner_contact_id.email", string="Partner Email" ) company_contact_id = fields.Many2one( "res.partner", @@ -178,12 +172,12 @@ class Agreement(models.Model): deftext = """

Company Information

- ${object.company_partner_id.name or ''}.
- ${object.company_partner_id.street or ''}
- ${object.company_partner_id.state_id.code or ''} - ${object.company_partner_id.zip or ''} - ${object.company_partner_id.city or ''}
- ${object.company_partner_id.country_id.name or ''}.

+ ${object.company_id.partner_id.name or ''}.
+ ${object.company_id.partner_id.street or ''}
+ ${object.company_id.partner_id.state_id.code or ''} + ${object.company_id.partner_id.zip or ''} + ${object.company_id.partner_id.city or ''}
+ ${object.company_id.partner_id.country_id.name or ''}.

Represented by ${object.company_contact_id.name or ''}.

@@ -241,7 +235,7 @@ class Agreement(models.Model): ) partner_signed_user_id = fields.Many2one( "res.partner", - string="Signed By", + string="Signed By (Partner)", track_visibility="onchange", help="Contact on the account that signed the agreement/contract.", ) @@ -273,7 +267,7 @@ class Agreement(models.Model): previous_version_agreements_ids = fields.One2many( "agreement", "parent_agreement_id", - string="Child Agreements", + string="Previous Versions", copy=False, domain=[("active", "=", False)], ) diff --git a/agreement_legal/report/agreement.xml b/agreement_legal/report/agreement.xml index 546fa212..6a621d0f 100644 --- a/agreement_legal/report/agreement.xml +++ b/agreement_legal/report/agreement.xml @@ -36,7 +36,7 @@

Company Information

-
@@ -121,7 +121,7 @@

Date:

-

+

By:

Name: diff --git a/agreement_legal/views/agreement.xml b/agreement_legal/views/agreement.xml index b400b10b..df023206 100644 --- a/agreement_legal/views/agreement.xml +++ b/agreement_legal/views/agreement.xml @@ -9,7 +9,7 @@ - + @@ -110,7 +110,7 @@

- @@ -122,7 +122,7 @@ - + @@ -136,7 +136,7 @@ - + From 9429895ffd3412b10d7352118d257b5e9fea982d Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Wed, 8 May 2019 09:07:16 -0500 Subject: [PATCH 5/6] [FIX] Clauses are copied from the sections --- agreement_legal/models/agreement.py | 180 ++++++++++------------------ 1 file changed, 60 insertions(+), 120 deletions(-) diff --git a/agreement_legal/models/agreement.py b/agreement_legal/models/agreement.py index c98f4e94..c354144c 100644 --- a/agreement_legal/models/agreement.py +++ b/agreement_legal/models/agreement.py @@ -17,153 +17,123 @@ class Agreement(models.Model): string="Is a Template?", default=False, copy=False, - help="Make this agreement a template.", - ) + help="Make this agreement a template.") version = fields.Integer( string="Version", default=1, copy=False, help="The versions are used to keep track of document history and " - "previous versions can be referenced.", - ) + "previous versions can be referenced.") revision = fields.Integer( string="Revision", default=0, copy=False, - help="The revision will increase with every save event.", - ) + help="The revision will increase with every save event.") description = fields.Text( string="Description", track_visibility="onchange", - help="Description of the agreement", - ) + help="Description of the agreement") dynamic_description = fields.Text( compute="_compute_dynamic_description", string="Dynamic Description", - help="Compute dynamic description", - ) + help="Compute dynamic description") start_date = fields.Date( string="Start Date", track_visibility="onchange", - help="When the agreement starts.", - ) + help="When the agreement starts.") end_date = fields.Date( string="End Date", track_visibility="onchange", - help="When the agreement ends.", - ) - color = fields.Integer() + help="When the agreement ends.") + color = fields.Integer(string="Color") active = fields.Boolean( string="Active", default=True, help="If unchecked, it will allow you to hide the agreement without " - "removing it.", - ) + "removing it.") company_signed_date = fields.Date( string="Signed on", track_visibility="onchange", - help="Date the contract was signed by Company.", - ) + help="Date the contract was signed by Company.") partner_signed_date = fields.Date( string="Signed on (Partner)", track_visibility="onchange", - help="Date the contract was signed by the Partner.", - ) + help="Date the contract was signed by the Partner.") term = fields.Integer( string="Term (Months)", track_visibility="onchange", help="Number of months this agreement/contract is in effect with the " - "partner.", - ) + "partner.") expiration_notice = fields.Integer( string="Exp. Notice (Days)", track_visibility="onchange", - help="Number of Days before expiration to be notified.", - ) + help="Number of Days before expiration to be notified.") change_notice = fields.Integer( string="Change Notice (Days)", track_visibility="onchange", - help="Number of Days to be notified before changes.", - ) + help="Number of Days to be notified before changes.") special_terms = fields.Text( string="Special Terms", track_visibility="onchange", help="Any terms that you have agreed to and want to track on the " - "agreement/contract.", - ) + "agreement/contract.") dynamic_special_terms = fields.Text( compute="_compute_dynamic_special_terms", string="Dynamic Special Terms", - help="Compute dynamic special terms", - ) + help="Compute dynamic special terms") code = fields.Char( string="Reference", required=True, default=lambda self: _("New"), track_visibility="onchange", copy=False, - help="ID used for internal contract tracking.", - ) + help="ID used for internal contract tracking.") increase_type_id = fields.Many2one( "agreement.increasetype", string="Increase Type", track_visibility="onchange", - help="The amount that certain rates may increase.", - ) + help="The amount that certain rates may increase.") termination_requested = fields.Date( string="Termination Requested Date", track_visibility="onchange", - help="Date that a request for termination was received.", - ) + help="Date that a request for termination was received.") termination_date = fields.Date( string="Termination Date", track_visibility="onchange", - help="Date that the contract was terminated.", - ) + help="Date that the contract was terminated.") reviewed_date = fields.Date( - string="Reviewed Date", track_visibility="onchange" - ) + string="Reviewed Date", track_visibility="onchange") reviewed_user_id = fields.Many2one( - "res.users", string="Reviewed By", track_visibility="onchange" - ) + "res.users", string="Reviewed By", track_visibility="onchange") approved_date = fields.Date( - string="Approved Date", track_visibility="onchange" - ) + string="Approved Date", track_visibility="onchange") approved_user_id = fields.Many2one( - "res.users", string="Approved By", track_visibility="onchange" - ) + "res.users", string="Approved By", track_visibility="onchange") currency_id = fields.Many2one("res.currency", string="Currency") partner_id = fields.Many2one( "res.partner", string="Partner", required=False, 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( "res.partner", string="Partner Contact", copy=True, - help="The primary partner contact (If Applicable).", - ) + help="The primary partner contact (If Applicable).") partner_contact_phone = fields.Char( - related="partner_contact_id.phone", string="Partner Phone" - ) + related="partner_contact_id.phone", string="Partner Phone") partner_contact_email = fields.Char( - related="partner_contact_id.email", string="Partner Email" - ) + related="partner_contact_id.email", string="Partner Email") company_contact_id = fields.Many2one( "res.partner", string="Company Contact", copy=True, - help="The primary contact in the company.", - ) + help="The primary contact in the company.") company_contact_phone = fields.Char( - related="company_contact_id.phone", string="Phone" - ) + related="company_contact_id.phone", string="Phone") company_contact_email = fields.Char( - related="company_contact_id.email", string="Email" - ) + related="company_contact_id.email", string="Email") use_parties_content = fields.Boolean( string="Use parties content", help="Use custom content for parties") @@ -197,137 +167,112 @@ class Agreement(models.Model): string="Parties", track_visibility="onchange", default=_get_default_parties, - help="Parties of the agreement", - ) + help="Parties of the agreement") dynamic_parties = fields.Html( compute="_compute_dynamic_parties", string="Dynamic Parties", - help="Compute dynamic parties", - ) + help="Compute dynamic parties") agreement_type_id = fields.Many2one( "agreement.type", string="Agreement Type", track_visibility="onchange", - help="Select the type of agreement.", - ) + help="Select the type of agreement.") agreement_subtype_id = fields.Many2one( "agreement.subtype", string="Agreement Sub-type", track_visibility="onchange", help="Select the sub-type of this agreement. Sub-Types are related to " - "agreement types.", - ) + "agreement types.") product_ids = fields.Many2many( - "product.template", string="Products & Services" - ) + "product.template", string="Products & Services") assigned_user_id = fields.Many2one( "res.users", string="Assigned To", track_visibility="onchange", - help="Select the user who manages this agreement.", - ) + help="Select the user who manages this agreement.") company_signed_user_id = fields.Many2one( "res.users", string="Signed By", track_visibility="onchange", help="The user at our company who authorized/signed the agreement or " - "contract.", - ) + "contract.") partner_signed_user_id = fields.Many2one( "res.partner", string="Signed By (Partner)", track_visibility="onchange", - 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( "agreement", string="Parent Agreement", help="Link this agreement to a parent agreement. For example if this " "agreement is an amendment to another agreement. This list will " - "only show other agreements related to the same account.", - ) + "only show other agreements related to the same account.") renewal_type_id = fields.Many2one( "agreement.renewaltype", string="Renewal Type", track_visibility="onchange", - help="Describes what happens after the contract expires.", - ) + help="Describes what happens after the contract expires.") recital_ids = fields.One2many( - "agreement.recital", "agreement_id", string="Recitals", copy=True - ) + "agreement.recital", "agreement_id", string="Recitals", copy=True) sections_ids = fields.One2many( - "agreement.section", "agreement_id", string="Sections", copy=True - ) + "agreement.section", "agreement_id", string="Sections", copy=True) clauses_ids = fields.One2many( - "agreement.clause", "agreement_id", string="Clauses", copy=True - ) + "agreement.clause", "agreement_id", string="Clauses") appendix_ids = fields.One2many( - "agreement.appendix", "agreement_id", string="Appendices", copy=True - ) + "agreement.appendix", "agreement_id", string="Appendices", copy=True) previous_version_agreements_ids = fields.One2many( "agreement", "parent_agreement_id", string="Previous Versions", copy=False, - domain=[("active", "=", False)], - ) + domain=[("active", "=", False)]) child_agreements_ids = fields.One2many( "agreement", "parent_agreement_id", string="Child Agreements", copy=False, - domain=[("active", "=", True)], - ) + domain=[("active", "=", True)]) line_ids = fields.One2many( "agreement.line", "agreement_id", string="Products/Services", - copy=False, - ) + copy=False) state = fields.Selection( [("draft", "Draft"), ("active", "Active"), ("inactive", "Inactive")], default="draft", - track_visibility="always", - ) + track_visibility="always") notification_address_id = fields.Many2one( "res.partner", string="Notification Address", help="The address to send notificaitons to, if different from " - "customer address.(Address Type = Other)", - ) + "customer address.(Address Type = Other)") signed_contract_filename = fields.Char(string="Filename") signed_contract = fields.Binary( - string="Signed Document", track_visibility="always" - ) + 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.""", - ) + 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.""", - ) + 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).""", - ) + model (sub-model).""") 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.""") # compute the dynamic content for mako expression @api.multi @@ -373,19 +318,16 @@ class Agreement(models.Model): 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.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] + [("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 "''", - ) + self.default_value or "''") # Used for Kanban grouped_by view @api.model @@ -399,9 +341,7 @@ class Agreement(models.Model): group_expand="_read_group_stage_ids", help="Select the current stage of the agreement.", track_visibility="onchange", - index=True, - # default=lambda self: self._default_stage_id(), - ) + index=True) # Create New Version Button @api.multi From f1f11f42ea89d4dc8fdeb1b567f2a57f64baf40c Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Mon, 13 May 2019 10:59:33 -0500 Subject: [PATCH 6/6] [FIX] agreement_legal: Copy --- agreement_legal/models/agreement.py | 3 +++ agreement_legal/models/agreement_clause.py | 27 ++++++++-------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/agreement_legal/models/agreement.py b/agreement_legal/models/agreement.py index c354144c..0f784976 100644 --- a/agreement_legal/models/agreement.py +++ b/agreement_legal/models/agreement.py @@ -339,6 +339,7 @@ class Agreement(models.Model): "agreement.stage", string="Stage", group_expand="_read_group_stage_ids", + default=lambda self: self._default_stage_id(), help="Select the current stage of the agreement.", track_visibility="onchange", index=True) @@ -370,8 +371,10 @@ class Agreement(models.Model): "version": 1, "revision": 0, "state": "draft", + "stage_id": self.env.ref("agreement_legal.agreement_stage_new").id, } res = self.copy(default=default_vals) + res.sections_ids.clauses_ids.write({'agreement_id': res.id}) return { "res_model": "agreement", "type": "ir.actions.act_window", diff --git a/agreement_legal/models/agreement_clause.py b/agreement_legal/models/agreement_clause.py index 2c2debad..e7ab066f 100644 --- a/agreement_legal/models/agreement_clause.py +++ b/agreement_legal/models/agreement_clause.py @@ -12,8 +12,7 @@ class AgreementClause(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") agreement_id = fields.Many2one( "agreement", @@ -22,20 +21,17 @@ class AgreementClause(models.Model): section_id = fields.Many2one( "agreement.section", string="Section", - ondelete="cascade" - ) + ondelete="cascade") content = fields.Html(string="Clause Content") dynamic_content = fields.Html( compute="_compute_dynamic_content", string="Dynamic Content", - help="compute dynamic Content", - ) + help="compute dynamic Content") active = fields.Boolean( string="Active", default=True, help="If unchecked, it will allow you to hide the agreement without " - "removing it.", - ) + "removing it.") # Dynamic field editor field_id = fields.Many2one( @@ -43,30 +39,25 @@ class AgreementClause(models.Model): 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.""", - ) + 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.""", - ) + 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).""", - ) + model (sub-model).""") 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') def onchange_copyvalue(self):