From c9acdbc4d52da2f7baf9d1faf464458bab6b17e3 Mon Sep 17 00:00:00 2001
From: newtratip
Date: Fri, 16 Jul 2021 18:26:02 +0700
Subject: [PATCH] [14.0][ENH] agreement_legal
---
agreement_legal/__init__.py | 1 +
agreement_legal/__manifest__.py | 6 +-
agreement_legal/data/agreement_stage.xml | 7 +
agreement_legal/data/module_category.xml | 8 -
agreement_legal/models/__init__.py | 3 -
agreement_legal/models/agreement.py | 186 ++++++++---
agreement_legal/models/agreement_appendix.py | 5 +-
agreement_legal/models/agreement_clause.py | 8 +-
.../models/agreement_increasetype.py | 24 --
agreement_legal/models/agreement_recital.py | 7 +-
.../models/agreement_renewaltype.py | 21 --
agreement_legal/models/agreement_section.py | 5 +-
agreement_legal/models/agreement_stage.py | 9 +-
agreement_legal/models/agreement_status.py | 12 -
agreement_legal/models/agreement_subtype.py | 3 +-
agreement_legal/models/agreement_type.py | 2 +-
agreement_legal/models/product_template.py | 10 -
agreement_legal/readme/CONTRIBUTORS.rst | 1 +
agreement_legal/report/agreement.xml | 4 +
agreement_legal/security/ir.model.access.csv | 15 +-
agreement_legal/security/res_groups.xml | 2 -
agreement_legal/static/src/js/agreement.js | 40 +++
.../static/src/js/domain_widget_ext.js | 85 -----
agreement_legal/static/src/xml/agreement.xml | 22 ++
.../static/src/xml/domain_widget_view.xml | 298 ------------------
agreement_legal/tests/__init__.py | 1 +
agreement_legal/tests/test_agreement.py | 18 +-
.../tests/test_agreement_appendix.py | 2 +-
.../tests/test_agreement_clause.py | 2 +-
.../tests/test_agreement_recital.py | 2 +-
.../tests/test_agreement_section.py | 2 +-
.../tests/test_create_agreement_wizard.py | 80 +++++
agreement_legal/views/agreement.xml | 71 +++--
agreement_legal/views/agreement_appendix.xml | 33 +-
agreement_legal/views/agreement_clause.xml | 41 ++-
.../views/agreement_increasetype.xml | 44 ---
agreement_legal/views/agreement_recital.xml | 33 +-
.../views/agreement_renewaltype.xml | 40 ---
agreement_legal/views/agreement_section.xml | 33 +-
agreement_legal/views/agreement_stages.xml | 41 ++-
agreement_legal/views/agreement_subtype.xml | 43 ++-
agreement_legal/views/agreement_type.xml | 2 +-
agreement_legal/views/assets.xml | 14 +
agreement_legal/views/menu.xml | 20 +-
agreement_legal/wizards/__init__.py | 3 +
.../wizards/create_agreement_wizard.py | 31 ++
.../wizards/create_agreement_wizard.xml | 34 ++
47 files changed, 694 insertions(+), 680 deletions(-)
delete mode 100644 agreement_legal/data/module_category.xml
delete mode 100644 agreement_legal/models/agreement_increasetype.py
delete mode 100644 agreement_legal/models/agreement_renewaltype.py
delete mode 100644 agreement_legal/models/agreement_status.py
delete mode 100644 agreement_legal/models/product_template.py
create mode 100644 agreement_legal/static/src/js/agreement.js
delete mode 100644 agreement_legal/static/src/js/domain_widget_ext.js
create mode 100644 agreement_legal/static/src/xml/agreement.xml
delete mode 100644 agreement_legal/static/src/xml/domain_widget_view.xml
create mode 100644 agreement_legal/tests/test_create_agreement_wizard.py
delete mode 100644 agreement_legal/views/agreement_increasetype.xml
delete mode 100644 agreement_legal/views/agreement_renewaltype.xml
create mode 100644 agreement_legal/views/assets.xml
create mode 100644 agreement_legal/wizards/__init__.py
create mode 100644 agreement_legal/wizards/create_agreement_wizard.py
create mode 100644 agreement_legal/wizards/create_agreement_wizard.xml
diff --git a/agreement_legal/__init__.py b/agreement_legal/__init__.py
index 073035d16..c1cfe3914 100644
--- a/agreement_legal/__init__.py
+++ b/agreement_legal/__init__.py
@@ -2,3 +2,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models
+from . import wizards
diff --git a/agreement_legal/__manifest__.py b/agreement_legal/__manifest__.py
index 808328fff..63667b4a9 100644
--- a/agreement_legal/__manifest__.py
+++ b/agreement_legal/__manifest__.py
@@ -15,7 +15,6 @@
"depends": ["contacts", "agreement", "product"],
"data": [
"data/ir_sequence.xml",
- "data/module_category.xml",
"data/agreement_stage.xml",
"data/agreement_type.xml",
"security/res_groups.xml",
@@ -29,13 +28,14 @@
"views/agreement_stages.xml",
"views/agreement_type.xml",
"views/agreement_subtype.xml",
- "views/agreement_renewaltype.xml",
- "views/agreement_increasetype.xml",
"views/res_partner.xml",
"views/agreement.xml",
"views/menu.xml",
+ "views/assets.xml",
+ "wizards/create_agreement_wizard.xml",
],
"demo": ["demo/demo.xml"],
+ "qweb": ["static/src/xml/agreement.xml"],
"application": True,
"development_status": "Beta",
"maintainers": ["max3903", "ygol"],
diff --git a/agreement_legal/data/agreement_stage.xml b/agreement_legal/data/agreement_stage.xml
index 0f930eab7..f3d9ca0de 100644
--- a/agreement_legal/data/agreement_stage.xml
+++ b/agreement_legal/data/agreement_stage.xml
@@ -48,6 +48,13 @@
agreement
+
+ Terminated
+ 90
+ True
+ agreement
+
+
Cancelled
100
diff --git a/agreement_legal/data/module_category.xml b/agreement_legal/data/module_category.xml
deleted file mode 100644
index da4af85af..000000000
--- a/agreement_legal/data/module_category.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Agreement
- 80
-
-
-
diff --git a/agreement_legal/models/__init__.py b/agreement_legal/models/__init__.py
index c24e38c08..238f84cbe 100644
--- a/agreement_legal/models/__init__.py
+++ b/agreement_legal/models/__init__.py
@@ -12,7 +12,4 @@ from . import (
agreement_type,
agreement_subtype,
res_partner,
- product_template,
- agreement_renewaltype,
- agreement_increasetype,
)
diff --git a/agreement_legal/models/agreement.py b/agreement_legal/models/agreement.py
index d0450bcd9..b2c99129a 100644
--- a/agreement_legal/models/agreement.py
+++ b/agreement_legal/models/agreement.py
@@ -1,6 +1,11 @@
# Copyright (C) 2018 - TODAY, Pavlov Media
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+import ast
+import json as simplejson
+
+from lxml import etree
+
from odoo import _, api, fields, models
@@ -52,12 +57,6 @@ class Agreement(models.Model):
tracking=True,
help="Date the contract was signed by the Partner.",
)
- term = fields.Integer(
- string="Term (Months)",
- tracking=True,
- help="Number of months this agreement/contract is in effect with the "
- "partner.",
- )
expiration_notice = fields.Integer(
string="Exp. Notice (Days)",
tracking=True,
@@ -87,12 +86,6 @@ class Agreement(models.Model):
copy=False,
help="ID used for internal contract tracking.",
)
- increase_type_id = fields.Many2one(
- "agreement.increasetype",
- string="Increase Type",
- tracking=True,
- help="The amount that certain rates may increase.",
- )
termination_requested = fields.Date(
string="Termination Requested Date",
tracking=True,
@@ -107,7 +100,6 @@ class Agreement(models.Model):
reviewed_user_id = fields.Many2one("res.users", string="Reviewed By", tracking=True)
approved_date = fields.Date(string="Approved Date", tracking=True)
approved_user_id = fields.Many2one("res.users", string="Approved By", tracking=True)
- currency_id = fields.Many2one("res.currency", string="Currency")
partner_id = fields.Many2one(
"res.partner",
string="Partner",
@@ -192,7 +184,6 @@ class Agreement(models.Model):
help="Select the sub-type of this agreement. Sub-Types are related to "
"agreement types.",
)
- product_ids = fields.Many2many("product.template", string="Products & Services")
assigned_user_id = fields.Many2one(
"res.users",
string="Assigned To",
@@ -219,12 +210,6 @@ class Agreement(models.Model):
"agreement is an amendment to another agreement. This list will "
"only show other agreements related to the same account.",
)
- renewal_type_id = fields.Many2one(
- "agreement.renewaltype",
- string="Renewal Type",
- tracking=True,
- help="Describes what happens after the contract expires.",
- )
recital_ids = fields.One2many(
"agreement.recital", "agreement_id", string="Recitals", copy=True
)
@@ -241,6 +226,7 @@ class Agreement(models.Model):
string="Previous Versions",
copy=False,
domain=[("active", "=", False)],
+ context={"active_test": False},
)
child_agreements_ids = fields.One2many(
"agreement",
@@ -294,19 +280,37 @@ class Agreement(models.Model):
help="""Final placeholder expression, to be copy-pasted in the desired
template field.""",
)
+ created_by = fields.Many2one(
+ "res.users",
+ string="Created By",
+ copy=False,
+ default=lambda self: self.env.user,
+ help="User which create the agreement.",
+ )
+ date_created = fields.Datetime(
+ string="Created On",
+ copy=False,
+ default=lambda self: fields.Datetime.now(),
+ help="Date which create the agreement.",
+ )
+ template_id = fields.Many2one(
+ "agreement",
+ string="Template",
+ domain=[("is_template", "=", True)],
+ )
+ readonly = fields.Boolean(
+ related="stage_id.readonly",
+ )
- # compute the dynamic content for mako expression
+ # compute the dynamic content for jinja expression
def _compute_dynamic_description(self):
MailTemplates = self.env["mail.template"]
for agreement in self:
lang = agreement.partner_id.lang or "en_US"
description = MailTemplates.with_context(lang=lang)._render_template(
agreement.description, "agreement", [agreement.id]
- )
- des = ""
- for i in description:
- des += description[i]
- agreement.dynamic_description = des
+ )[agreement.id]
+ agreement.dynamic_description = description
def _compute_dynamic_parties(self):
MailTemplates = self.env["mail.template"]
@@ -314,7 +318,7 @@ class Agreement(models.Model):
lang = agreement.partner_id.lang or "en_US"
parties = MailTemplates.with_context(lang=lang)._render_template(
agreement.parties, "agreement", [agreement.id]
- )
+ )[agreement.id]
agreement.dynamic_parties = parties
def _compute_dynamic_special_terms(self):
@@ -323,14 +327,13 @@ class Agreement(models.Model):
lang = agreement.partner_id.lang or "en_US"
special_terms = MailTemplates.with_context(lang=lang)._render_template(
agreement.special_terms, "agreement", [agreement.id]
- )
+ )[agreement.id]
agreement.dynamic_special_terms = special_terms
@api.onchange("field_id", "sub_model_object_field_id", "default_value")
def onchange_copyvalue(self):
self.sub_object_id = False
self.copyvalue = False
- self.sub_object_id = False
if self.field_id and not self.field_id.relation:
self.copyvalue = "${{object.{} or {}}}".format(
self.field_id.name, self.default_value or "''"
@@ -360,29 +363,55 @@ class Agreement(models.Model):
string="Stage",
group_expand="_read_group_stage_ids",
help="Select the current stage of the agreement.",
+ default=lambda self: self._get_default_stage_id(),
tracking=True,
index=True,
+ copy=False,
)
+ @api.model
+ def _get_default_stage_id(self):
+ try:
+ stage_id = self.env.ref("agreement_legal.agreement_stage_new").id
+ except ValueError:
+ stage_id = False
+ return stage_id
+
+ def _get_old_version_default_vals(self):
+ self.ensure_one()
+ default_vals = {
+ "name": "{} - OLD VERSION".format(self.name),
+ "active": False,
+ "parent_agreement_id": self.id,
+ "version": self.version,
+ "revision": self.revision,
+ "created_by": self.created_by.id,
+ "date_created": self.date_created,
+ "code": "{}-V{}".format(self.code, str(self.version)),
+ "stage_id": self.stage_id.id,
+ }
+ return default_vals
+
# Create New Version Button
def create_new_version(self):
for rec in self:
if not rec.state == "draft":
# Make sure status is draft
rec.state = "draft"
- default_vals = {
- "name": "{} - OLD VERSION".format(rec.name),
- "active": False,
- "parent_agreement_id": rec.id,
- "version": rec.version,
- "code": rec.code + "-V" + str(rec.version),
- }
# Make a current copy and mark it as old
- rec.copy(default=default_vals)
- # Increment the Version
- rec.version = rec.version + 1
+ rec.copy(default=rec._get_old_version_default_vals())
+ # Update version, created by and created on
+ rec.update(
+ {
+ "version": rec.version + 1,
+ "created_by": self.env.user.id,
+ "date_created": fields.Datetime.now(),
+ }
+ )
+ # Reset revision to 0 since it's a new version
+ rec.revision = 0
- def create_new_agreement(self):
+ def _get_new_agreement_default_vals(self):
self.ensure_one()
default_vals = {
"name": "New",
@@ -390,10 +419,13 @@ class Agreement(models.Model):
"version": 1,
"revision": 0,
"state": "draft",
- "stage_id": self.env.ref("agreement_legal.agreement_stage_new").id,
+ "is_template": False,
}
- res = self.copy(default=default_vals)
- res.sections_ids.mapped("clauses_ids").write({"agreement_id": res.id})
+ return default_vals
+
+ def create_new_agreement(self):
+ self.ensure_one()
+ res = self.copy(default=self._get_new_agreement_default_vals())
return {
"res_model": "agreement",
"type": "ir.actions.act_window",
@@ -407,10 +439,72 @@ class Agreement(models.Model):
if vals.get("code", _("New")) == _("New"):
vals["code"] = self.env["ir.sequence"].next_by_code("agreement") or _("New")
if not vals.get("stage_id"):
- vals["stage_id"] = self.env.ref("agreement_legal.agreement_stage_new").id
+ vals["stage_id"] = self._get_default_stage_id()
return super().create(vals)
# Increments the revision on each save action
def write(self, vals):
- vals["revision"] = self.revision + 1
- return super().write(vals)
+ res = True
+ for rec in self:
+ has_revision = False
+ if "revision" not in vals:
+ vals["revision"] = rec.revision + 1
+ has_revision = True
+ res = super(Agreement, rec).write(vals)
+ if has_revision:
+ vals.pop("revision")
+ return res
+
+ def copy(self, default=None):
+ """Assign a value for code is New"""
+ default = dict(default or {})
+ if not default.get("code", False):
+ default.setdefault("code", _("New"))
+ res = super().copy(default)
+ res.sections_ids.mapped("clauses_ids").write({"agreement_id": res.id})
+ return res
+
+ def _exclude_readonly_field(self):
+ return ["stage_id"]
+
+ @api.model
+ def fields_view_get(
+ self, view_id=None, view_type=False, toolbar=False, submenu=False
+ ):
+ res = super().fields_view_get(
+ view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
+ )
+ # Readonly fields
+ doc = etree.XML(res["arch"])
+ if view_type == "form":
+ for node in doc.xpath("//field"):
+ if node.attrib.get("name") in self._exclude_readonly_field():
+ continue
+ attrs = ast.literal_eval(node.attrib.get("attrs", "{}"))
+ if attrs:
+ if attrs.get("readonly"):
+ attrs["readonly"] = ["|", ("readonly", "=", True)] + attrs[
+ "readonly"
+ ]
+ else:
+ attrs["readonly"] = [("readonly", "=", True)]
+ else:
+ attrs["readonly"] = [("readonly", "=", True)]
+ node.set("attrs", simplejson.dumps(attrs))
+ modifiers = ast.literal_eval(
+ node.attrib.get("modifiers", "{}")
+ .replace("true", "True")
+ .replace("false", "False")
+ )
+ readonly = modifiers.get("readonly")
+ invisible = modifiers.get("invisible")
+ required = modifiers.get("required")
+ if isinstance(readonly, bool) and readonly:
+ attrs["readonly"] = readonly
+ if isinstance(invisible, bool) and invisible:
+ attrs["invisible"] = invisible
+ if isinstance(required, bool) and required:
+ attrs["required"] = required
+ node.set("modifiers", simplejson.dumps(attrs))
+ res["arch"] = etree.tostring(doc)
+ return res
diff --git a/agreement_legal/models/agreement_appendix.py b/agreement_legal/models/agreement_appendix.py
index 1376cbaf4..77b651569 100644
--- a/agreement_legal/models/agreement_appendix.py
+++ b/agreement_legal/models/agreement_appendix.py
@@ -65,7 +65,6 @@ class AgreementAppendix(models.Model):
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,
@@ -83,7 +82,7 @@ class AgreementAppendix(models.Model):
self.default_value or "''",
)
- # compute the dynamic content for mako expression
+ # compute the dynamic content for jinja expression
def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"]
for appendix in self:
@@ -94,5 +93,5 @@ class AgreementAppendix(models.Model):
)
content = MailTemplates.with_context(lang=lang)._render_template(
appendix.content, "agreement.appendix", [appendix.id]
- )
+ )[appendix.id]
appendix.dynamic_content = content
diff --git a/agreement_legal/models/agreement_clause.py b/agreement_legal/models/agreement_clause.py
index ecae7af24..c399cb404 100644
--- a/agreement_legal/models/agreement_clause.py
+++ b/agreement_legal/models/agreement_clause.py
@@ -15,6 +15,9 @@ class AgreementClause(models.Model):
)
sequence = fields.Integer(string="Sequence")
agreement_id = fields.Many2one("agreement", string="Agreement", ondelete="cascade")
+ temp_agreement_id = fields.Many2one(
+ "agreement", string="Temp Agreement", help="This field help to filter section."
+ )
section_id = fields.Many2one(
"agreement.section", string="Section", ondelete="cascade"
)
@@ -66,7 +69,6 @@ class AgreementClause(models.Model):
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,
@@ -84,7 +86,7 @@ class AgreementClause(models.Model):
self.default_value or "''",
)
- # compute the dynamic content for mako expression
+ # compute the dynamic content for jinja expression
def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"]
for clause in self:
@@ -93,5 +95,5 @@ class AgreementClause(models.Model):
)
content = MailTemplates.with_context(lang=lang)._render_template(
clause.content, "agreement.clause", [clause.id]
- )
+ )[clause.id]
clause.dynamic_content = content
diff --git a/agreement_legal/models/agreement_increasetype.py b/agreement_legal/models/agreement_increasetype.py
deleted file mode 100644
index e3fc62f3f..000000000
--- a/agreement_legal/models/agreement_increasetype.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018 - TODAY, Pavlov Media
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
-from odoo import fields, models
-
-
-# Main Agreement Increase Type Records Model
-class AgreementIncreaseType(models.Model):
- _name = "agreement.increasetype"
- _description = "Agreement Increase Type"
-
- # General
- name = fields.Char(
- string="Title",
- required=True,
- help="Increase types describe any increases that may happen during "
- "the contract.",
- )
- description = fields.Text(
- string="Description", required=True, help="Description of the renewal type."
- )
- increase_percent = fields.Integer(
- string="Increase Percentage", help="Percentage that the amount will increase."
- )
diff --git a/agreement_legal/models/agreement_recital.py b/agreement_legal/models/agreement_recital.py
index 7fec94a4d..f86b6fd75 100644
--- a/agreement_legal/models/agreement_recital.py
+++ b/agreement_legal/models/agreement_recital.py
@@ -12,7 +12,7 @@ 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")
@@ -64,7 +64,6 @@ class AgreementRecital(models.Model):
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 "''"
@@ -81,7 +80,7 @@ class AgreementRecital(models.Model):
self.default_value or "''",
)
- # compute the dynamic content for mako expression
+ # compute the dynamic content for jinja expression
def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"]
for recital in self:
@@ -90,5 +89,5 @@ class AgreementRecital(models.Model):
)
content = MailTemplates.with_context(lang=lang)._render_template(
recital.content, "agreement.recital", [recital.id]
- )
+ )[recital.id]
recital.dynamic_content = content
diff --git a/agreement_legal/models/agreement_renewaltype.py b/agreement_legal/models/agreement_renewaltype.py
deleted file mode 100644
index fd8694e3c..000000000
--- a/agreement_legal/models/agreement_renewaltype.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018 - TODAY, Pavlov Media
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
-from odoo import fields, models
-
-
-# Main Agreement Section Records Model
-class AgreementRenewalType(models.Model):
- _name = "agreement.renewaltype"
- _description = "Agreement Renewal Type"
-
- # General
- name = fields.Char(
- string="Title",
- required=True,
- help="Renewal types describe what happens after the "
- "agreement/contract expires.",
- )
- description = fields.Text(
- string="Description", required=True, help="Description of the renewal type."
- )
diff --git a/agreement_legal/models/agreement_section.py b/agreement_legal/models/agreement_section.py
index b4c275111..a192e3519 100644
--- a/agreement_legal/models/agreement_section.py
+++ b/agreement_legal/models/agreement_section.py
@@ -66,7 +66,6 @@ class AgreementSection(models.Model):
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 "''"
@@ -83,7 +82,7 @@ class AgreementSection(models.Model):
self.default_value or "''",
)
- # compute the dynamic content for mako expression
+ # compute the dynamic content for jinja expression
def _compute_dynamic_content(self):
MailTemplates = self.env["mail.template"]
for section in self:
@@ -92,5 +91,5 @@ class AgreementSection(models.Model):
)
content = MailTemplates.with_context(lang=lang)._render_template(
section.content, "agreement.section", [section.id]
- )
+ )[section.id]
section.dynamic_content = content
diff --git a/agreement_legal/models/agreement_stage.py b/agreement_legal/models/agreement_stage.py
index 874c2d0b4..b13d62652 100644
--- a/agreement_legal/models/agreement_stage.py
+++ b/agreement_legal/models/agreement_stage.py
@@ -4,7 +4,7 @@
from odoo import fields, models
-# Main Agreement Section Records Model
+# Main Stage on the Agreement
class AgreementStage(models.Model):
_name = "agreement.stage"
_description = "Agreement Stages"
@@ -12,7 +12,6 @@ class AgreementStage(models.Model):
# General
name = fields.Char(string="Stage Name", required=True)
- description = fields.Text(string="Description", required=False)
sequence = fields.Integer(string="Sequence", default="1", required=False)
fold = fields.Boolean(
string="Is Folded",
@@ -22,3 +21,9 @@ class AgreementStage(models.Model):
stage_type = fields.Selection(
[("agreement", "Agreement")], string="Type", required=True
)
+ active = fields.Boolean(string="Active", default=True)
+ readonly = fields.Boolean(
+ string="Readonly",
+ default=False,
+ help="The agreement can not edit if set Readonly = True.",
+ )
diff --git a/agreement_legal/models/agreement_status.py b/agreement_legal/models/agreement_status.py
deleted file mode 100644
index 8d9ef3a2d..000000000
--- a/agreement_legal/models/agreement_status.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (C) 2018 - TODAY, Pavlov Media
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
-from odoo import fields, models
-
-
-# Main Agreement Status Records Model
-class AgreementStatus(models.Model):
- _name = "agreement.type"
-
- # General
- name = fields.Char(string="Title", required=True)
diff --git a/agreement_legal/models/agreement_subtype.py b/agreement_legal/models/agreement_subtype.py
index 056c061f1..0187c5f0c 100644
--- a/agreement_legal/models/agreement_subtype.py
+++ b/agreement_legal/models/agreement_subtype.py
@@ -8,5 +8,6 @@ class AgreementSubtype(models.Model):
_name = "agreement.subtype"
_description = "Agreement Subtypes"
- name = fields.Char(string="Name", required=True)
+ name = fields.Char(string="Sub-Type Name", required=True)
agreement_type_id = fields.Many2one("agreement.type", string="Agreement Type")
+ active = fields.Boolean(string="Active", default=True)
diff --git a/agreement_legal/models/agreement_type.py b/agreement_legal/models/agreement_type.py
index 20df56b73..b1add48e5 100644
--- a/agreement_legal/models/agreement_type.py
+++ b/agreement_legal/models/agreement_type.py
@@ -9,5 +9,5 @@ class AgreementType(models.Model):
_description = "Agreement Types"
agreement_subtypes_ids = fields.One2many(
- "agreement.subtype", "agreement_type_id", string="Subtypes"
+ "agreement.subtype", "agreement_type_id", string="Sub-Types"
)
diff --git a/agreement_legal/models/product_template.py b/agreement_legal/models/product_template.py
deleted file mode 100644
index 9cf9e2e34..000000000
--- a/agreement_legal/models/product_template.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018 - TODAY, Pavlov Media
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
-from odoo import fields, models
-
-
-class Product(models.Model):
- _inherit = "product.template"
-
- agreements_ids = fields.Many2many("agreement", string="Agreements")
diff --git a/agreement_legal/readme/CONTRIBUTORS.rst b/agreement_legal/readme/CONTRIBUTORS.rst
index a0afb1231..1e7ffdd32 100644
--- a/agreement_legal/readme/CONTRIBUTORS.rst
+++ b/agreement_legal/readme/CONTRIBUTORS.rst
@@ -4,3 +4,4 @@
* Maxime Chambreuil
* Sandip Mangukiya
* Yves Goldberg
+* Tharathip Chaweewongphan
diff --git a/agreement_legal/report/agreement.xml b/agreement_legal/report/agreement.xml
index a2b9b5337..965b8d82c 100644
--- a/agreement_legal/report/agreement.xml
+++ b/agreement_legal/report/agreement.xml
@@ -3,17 +3,21 @@
Agreement
agreement
+
qweb-pdf
agreement_legal.report_agreement_document
agreement_legal.report_agreement_document
+ list,form
Agreement Preview
agreement
+
qweb-html
agreement_legal.report_agreement_document
agreement_legal.report_agreement_document
+ list,form
diff --git a/agreement_legal/security/ir.model.access.csv b/agreement_legal/security/ir.model.access.csv
index d5df825a7..9b7507f2e 100644
--- a/agreement_legal/security/ir.model.access.csv
+++ b/agreement_legal/security/ir.model.access.csv
@@ -3,19 +3,19 @@ access_agreement_readonly,agreement readonly,model_agreement,group_agreement_rea
access_agreement_allusers,agreement all users,model_agreement,group_agreement_user,1,1,1,0
access_agreement_manager,agreement manager,model_agreement,group_agreement_manager,1,1,1,1
access_agreement_recital_readonly,recital readonly,model_agreement_recital,group_agreement_readonly,1,0,0,0
-access_agreement_recital_allusers,recital all users,model_agreement_recital,group_agreement_user,1,1,1,0
+access_agreement_recital_allusers,recital all users,model_agreement_recital,group_agreement_user,1,1,1,1
access_agreement_recital_manager,recital manager,model_agreement_recital,group_agreement_manager,1,1,1,1
access_agreement_section_readonly,section readonly,model_agreement_section,group_agreement_readonly,1,0,0,0
-access_agreement_section_allusers,section all users,model_agreement_section,group_agreement_user,1,1,1,0
+access_agreement_section_allusers,section all users,model_agreement_section,group_agreement_user,1,1,1,1
access_agreement_section_manager,section manager,model_agreement_section,group_agreement_manager,1,1,1,1
access_agreement_clause_readonly,clause readonly,model_agreement_clause,group_agreement_readonly,1,0,0,0
-access_agreement_clause_allusers,clause all users,model_agreement_clause,group_agreement_user,1,1,1,0
+access_agreement_clause_allusers,clause all users,model_agreement_clause,group_agreement_user,1,1,1,1
access_agreement_clause_manager,clause manager,model_agreement_clause,group_agreement_manager,1,1,1,1
access_agreement_appendix_readonly,appendix readonly,model_agreement_appendix,group_agreement_readonly,1,0,0,0
-access_agreement_appendix_allusers,appendix all users,model_agreement_appendix,group_agreement_user,1,1,1,0
+access_agreement_appendix_allusers,appendix all users,model_agreement_appendix,group_agreement_user,1,1,1,1
access_agreement_appendix_manager,appendix manager,model_agreement_appendix,group_agreement_manager,1,1,1,1
access_agreement_line_readonly,agreement line readonly,model_agreement_line,group_agreement_readonly,1,0,0,0
-access_agreement_line_allusers,agreement line all users,model_agreement_line,group_agreement_user,1,1,1,0
+access_agreement_line_allusers,agreement line all users,model_agreement_line,group_agreement_user,1,1,1,1
access_agreement_line_manager,agreement line manager,model_agreement_line,group_agreement_manager,1,1,1,1
access_agreement_stage_readonly,stage readonly,model_agreement_stage,group_agreement_readonly,1,0,0,0
access_agreement_stage_manager,stage manager,model_agreement_stage,group_agreement_manager,1,1,1,1
@@ -23,7 +23,4 @@ access_agreement_type_readonly,type readonly,model_agreement_type,group_agreemen
access_agreement_type_manager,type manager,model_agreement_type,group_agreement_manager,1,1,1,1
access_agreement_subtype_readonly,subtype readonly,model_agreement_subtype,group_agreement_readonly,1,0,0,0
access_agreement_subtype_manager,subtype manager,model_agreement_subtype,group_agreement_manager,1,1,1,1
-access_agreement_renewaltype_readonly,renewaltype readonly,model_agreement_renewaltype,group_agreement_readonly,1,0,0,0
-access_agreement_renewaltype_manager,renewaltype manager,model_agreement_renewaltype,group_agreement_manager,1,1,1,1
-access_agreement_increasetype_readonly,increasetype readonly,model_agreement_increasetype,group_agreement_readonly,1,0,0,0
-access_agreement_increasetype_manager,increasetype manager,model_agreement_increasetype,group_agreement_manager,1,1,1,1
+access_create_agreement_wizard_allusers,create agreement wizard users,model_create_agreement_wizard,group_agreement_user,1,1,1,1
diff --git a/agreement_legal/security/res_groups.xml b/agreement_legal/security/res_groups.xml
index 83b954207..532fcbe67 100644
--- a/agreement_legal/security/res_groups.xml
+++ b/agreement_legal/security/res_groups.xml
@@ -1,4 +1,3 @@
-
Agreement
@@ -32,5 +31,4 @@
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
/>
-
diff --git a/agreement_legal/static/src/js/agreement.js b/agreement_legal/static/src/js/agreement.js
new file mode 100644
index 000000000..7a3ff31e9
--- /dev/null
+++ b/agreement_legal/static/src/js/agreement.js
@@ -0,0 +1,40 @@
+odoo.define("agreement_legal.agreement", function (require) {
+ "use strict";
+
+ var KanbanController = require("web.KanbanController");
+ var ListController = require("web.ListController");
+ var FormController = require("web.FormController");
+
+ var includeDict = {
+ renderButtons: function () {
+ this._super.apply(this, arguments);
+ if (this.modelName === "agreement" && this.$buttons) {
+ var self = this;
+ var data = this.model.get(this.handle);
+ if (data.context.default_is_template === true) {
+ // Hide create from template
+ this.$buttons.find(".create_agreement_from_template").hide();
+ } else {
+ // Hide create button
+ this.$buttons.find(".o-kanban-button-new").hide();
+ this.$buttons.find(".o_list_button_add").hide();
+ this.$buttons.find(".o_form_button_create").hide();
+ }
+ this.$buttons
+ .find(".create_agreement_from_template")
+ .on("click", function () {
+ self.do_action(
+ "agreement_legal.create_agreement_from_template_action",
+ {
+ additional_context: {},
+ }
+ );
+ });
+ }
+ },
+ };
+
+ KanbanController.include(includeDict);
+ ListController.include(includeDict);
+ FormController.include(includeDict);
+});
diff --git a/agreement_legal/static/src/js/domain_widget_ext.js b/agreement_legal/static/src/js/domain_widget_ext.js
deleted file mode 100644
index cf959d39e..000000000
--- a/agreement_legal/static/src/js/domain_widget_ext.js
+++ /dev/null
@@ -1,85 +0,0 @@
-odoo.define("agreement_legal.domain_widget_ext", function (require) {
- "use strict";
-
- var basic_fields = require("web.basic_fields");
- var DomainSelector = require("web.DomainSelector");
- var session = require("web.session");
- var core = require("web.core");
- var qweb = core.qweb;
-
- basic_fields.FieldDomain.include({
- /**
- * Init
- */
- init: function () {
- this._super.apply(this, arguments);
- // Add Additional options
- this.partialUse = this.nodeOptions.partial_use || false;
- },
-
- // ----------------------------------------------------------------------
- // Private
- // ----------------------------------------------------------------------
-
- /**
- * @private
- * @override _render from AbstractField
- * @returns {Deferred}
- */
- _render: function () {
- // If there is no model, only change the non-domain-selector content
- if (!this._domainModel) {
- this._replaceContent();
- return $.when();
- }
-
- // Convert char value to array value
- var value = this.value || "[]";
-
- // Create the domain selector or change the value of the current
- // one...
- var def = null;
- if (this.domainSelector) {
- def = this.domainSelector.setDomain(value);
- } else {
- this.domainSelector = new DomainSelector(
- this,
- this._domainModel,
- value,
- {
- readonly: this.mode === "readonly" || this.inDialog,
- filters: this.fsFilters,
- debugMode: session.debug,
- partialUse: this.partialUse || false,
- }
- );
- def = this.domainSelector.prependTo(this.$el);
- }
- // ... then replace the other content (matched records, etc)
- return def.then(this._replaceContent.bind(this));
- },
- /**
- * Render the field DOM except for the domain selector part. The full
- * field DOM is composed of a DIV which contains the domain selector
- * widget, followed by other content. This other content is handled by
- * this method.
- *
- * @private
- */
- _replaceContent: function () {
- if (this._$content) {
- this._$content.remove();
- }
- this._$content = $(
- qweb.render("FieldDomain.content", {
- hasModel: Boolean(this._domainModel),
- isValid: Boolean(this._isValidForModel),
- nbRecords: this.record.specialData[this.name].nbRecords || 0,
- inDialogEdit: this.inDialog && this.mode === "edit",
- partialUse: this.partialUse || false,
- })
- );
- this._$content.appendTo(this.$el);
- },
- });
-});
diff --git a/agreement_legal/static/src/xml/agreement.xml b/agreement_legal/static/src/xml/agreement.xml
new file mode 100644
index 000000000..5defe02d5
--- /dev/null
+++ b/agreement_legal/static/src/xml/agreement.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/agreement_legal/static/src/xml/domain_widget_view.xml b/agreement_legal/static/src/xml/domain_widget_view.xml
deleted file mode 100644
index 7b08b951b..000000000
--- a/agreement_legal/static/src/xml/domain_widget_view.xml
+++ /dev/null
@@ -1,298 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Invalid domain
-
-
-
- Select a model to add a filter.
-
-
-
-
-
-
- SMatch all records
-
-
-
-
- Please navigate below and select field:
-
- SSMatch records with
-
- of the following rules:
-
-
-
-
-
-
-
-
- Match all records
-
-
-
-
- Match records with the following rule:
-
- Match records with
-
- of the following rules:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ""
-
-
-
-
- ""
- or
-
-
-
-
-
-
-
- is
- not
- set
-
-
-
-
-
diff --git a/agreement_legal/tests/__init__.py b/agreement_legal/tests/__init__.py
index b1ea60b55..07cd93b88 100644
--- a/agreement_legal/tests/__init__.py
+++ b/agreement_legal/tests/__init__.py
@@ -6,3 +6,4 @@ from . import test_agreement_clause
from . import test_agreement_line
from . import test_agreement_recital
from . import test_agreement_section
+from . import test_create_agreement_wizard
diff --git a/agreement_legal/tests/test_agreement.py b/agreement_legal/tests/test_agreement.py
index 62498e150..4b6cb6cd0 100644
--- a/agreement_legal/tests/test_agreement.py
+++ b/agreement_legal/tests/test_agreement.py
@@ -2,6 +2,8 @@
from datetime import timedelta
+from lxml import etree
+
from odoo import fields
from odoo.tests.common import TransactionCase
@@ -107,7 +109,7 @@ class TestAgreement(TransactionCase):
agreement_01.parties = "${object.name}"
self.assertEqual(
agreement_01.dynamic_parties,
- "{" + str(agreement_01.id) + ": '
TestAgreement
'}",
+ "TestAgreement
",
)
# TEST 07: Test Special Terms Dynamic Field
@@ -116,7 +118,7 @@ class TestAgreement(TransactionCase):
agreement_01.special_terms = "${object.name}"
self.assertEqual(
agreement_01.dynamic_special_terms,
- "{" + str(agreement_01.id) + ": 'TestAgreement'}",
+ "TestAgreement",
)
# TEST 02: Check Read Stages
@@ -129,3 +131,15 @@ class TestAgreement(TransactionCase):
order="id",
),
)
+
+ # Test fields_view_get
+ def test_agreement_fields_view_get(self):
+ res = self.env["agreement"].fields_view_get(
+ view_id=self.ref("agreement_legal.partner_agreement_form_view"),
+ view_type="form",
+ )
+ doc = etree.XML(res["arch"])
+ field = doc.xpath("//field[@name='partner_contact_id']")
+ self.assertEqual(
+ field[0].get("modifiers", ""), '{"readonly": [["readonly", "=", true]]}'
+ )
diff --git a/agreement_legal/tests/test_agreement_appendix.py b/agreement_legal/tests/test_agreement_appendix.py
index 90cb1e3e9..81a440755 100644
--- a/agreement_legal/tests/test_agreement_appendix.py
+++ b/agreement_legal/tests/test_agreement_appendix.py
@@ -77,5 +77,5 @@ class TestAgreementAppendices(TransactionCase):
appendix_01.content = "${object.name}"
self.assertEqual(
appendix_01.dynamic_content,
- "{" + str(appendix_01.id) + ": '
TestAppendices
'}",
+ "TestAppendices
",
)
diff --git a/agreement_legal/tests/test_agreement_clause.py b/agreement_legal/tests/test_agreement_clause.py
index d4fd59ba4..3a81e7999 100644
--- a/agreement_legal/tests/test_agreement_clause.py
+++ b/agreement_legal/tests/test_agreement_clause.py
@@ -77,5 +77,5 @@ class TestAgreementClauses(TransactionCase):
clause_01.content = "${object.name}"
self.assertEqual(
clause_01.dynamic_content,
- "{" + str(clause_01.id) + ": '
TestClause
'}",
+ "TestClause
",
)
diff --git a/agreement_legal/tests/test_agreement_recital.py b/agreement_legal/tests/test_agreement_recital.py
index fcb4ae57d..62abd6a35 100644
--- a/agreement_legal/tests/test_agreement_recital.py
+++ b/agreement_legal/tests/test_agreement_recital.py
@@ -77,5 +77,5 @@ class TestAgreementRectical(TransactionCase):
recital_01.content = "${object.name}"
self.assertEqual(
recital_01.dynamic_content,
- "{" + str(recital_01.id) + ": '
TestRecital
'}",
+ "TestRecital
",
)
diff --git a/agreement_legal/tests/test_agreement_section.py b/agreement_legal/tests/test_agreement_section.py
index 75298d2a0..ea29ea977 100644
--- a/agreement_legal/tests/test_agreement_section.py
+++ b/agreement_legal/tests/test_agreement_section.py
@@ -77,5 +77,5 @@ class TestAgreementSection(TransactionCase):
section_01.content = "${object.name}"
self.assertEqual(
section_01.dynamic_content,
- "{" + str(section_01.id) + ": '
TestSection
'}",
+ "TestSection
",
)
diff --git a/agreement_legal/tests/test_create_agreement_wizard.py b/agreement_legal/tests/test_create_agreement_wizard.py
new file mode 100644
index 000000000..b0c523913
--- /dev/null
+++ b/agreement_legal/tests/test_create_agreement_wizard.py
@@ -0,0 +1,80 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+from odoo.tests.common import TransactionCase
+
+
+class TestCreateAgreementWizard(TransactionCase):
+ def setUp(self):
+ super().setUp()
+ self.agreement_type = self.env["agreement.type"].create(
+ {
+ "name": "Test Agreement Type",
+ "domain": "sale",
+ }
+ )
+ # Create Agreement Template
+ self.agreement_template = self.env["agreement"].create(
+ {
+ "name": "Test Agreement Template",
+ "description": "Test",
+ "state": "active",
+ "agreement_type_id": self.agreement_type.id,
+ "is_template": True,
+ }
+ )
+ # Create Recital
+ self.env["agreement.recital"].create(
+ {
+ "name": "Test Recital",
+ "title": "Test",
+ "content": "Test",
+ "agreement_id": self.agreement_template.id,
+ }
+ )
+ # Create Section
+ self.section = self.env["agreement.section"].create(
+ {
+ "name": "Test Section",
+ "title": "Test",
+ "content": "Test",
+ "agreement_id": self.agreement_template.id,
+ }
+ )
+ # Create Clause
+ self.env["agreement.clause"].create(
+ {
+ "name": "Test Clause",
+ "title": "Test",
+ "content": "Test",
+ "agreement_id": self.agreement_template.id,
+ "section_id": self.section.id,
+ }
+ )
+ # Create Appendix
+ self.env["agreement.appendix"].create(
+ {
+ "name": "Test Appendices",
+ "title": "Test",
+ "content": "Test",
+ "agreement_id": self.agreement_template.id,
+ }
+ )
+
+ # Test create agreement from template
+ def test_create_agreement(self):
+ template = self.agreement_template
+ wizard = self.env["create.agreement.wizard"].create(
+ {
+ "template_id": self.agreement_template.id,
+ "name": "Test Agreement",
+ }
+ )
+ res = wizard.create_agreement()
+ agreement = self.env[res["res_model"]].browse(res["res_id"])
+ self.assertEqual(agreement.template_id, template)
+ self.assertEqual(agreement.is_template, False)
+ self.assertEqual(agreement.recital_ids.name, template.recital_ids.name)
+ self.assertEqual(agreement.sections_ids.name, template.sections_ids.name)
+ self.assertEqual(agreement.clauses_ids.name, template.clauses_ids.name)
+ self.assertEqual(agreement.clauses_ids.section_id, agreement.sections_ids)
+ self.assertEqual(agreement.appendix_ids.name, template.appendix_ids.name)
diff --git a/agreement_legal/views/agreement.xml b/agreement_legal/views/agreement.xml
index 2ad12b020..53840a260 100644
--- a/agreement_legal/views/agreement.xml
+++ b/agreement_legal/views/agreement.xml
@@ -5,13 +5,15 @@
Agreement List
agreement
-
+
+
+
@@ -43,12 +45,18 @@
name="stage_id"
widget="statusbar"
clickable="True"
- options="{'fold_field': 'fold'}"
+ options="{'clickable': 1, 'fold_field': 'fold'}"
domain="[('stage_type', '=', 'agreement')]"
/>
+
-
+
+
+
@@ -138,7 +151,7 @@
@@ -148,7 +161,7 @@
name="company_id"
readonly="1"
context="{'show_address': 1}"
- options="{"always_reload": True}"
+ options="{'always_reload': True}"
/>
@@ -201,6 +214,10 @@
+
@@ -302,7 +315,7 @@
-
+
@@ -313,8 +326,9 @@
-
+
@@ -345,14 +359,14 @@
/>.
-
+ | Created By:
+ | Created On:
+
@@ -467,6 +481,7 @@
agreement
+
@@ -492,11 +507,23 @@
icon="terp-partner"
context="{'group_by':'partner_id'}"
/>
+
+
@@ -535,6 +562,7 @@
Agreements
agreement
[('is_template', '=', False)]
+
{'default_is_template': False}
kanban,tree,form
@@ -542,6 +570,7 @@
Agreements
agreement
[('is_template', '=', False)]
+
{'default_is_template': False}
tree,form
@@ -549,7 +578,7 @@
Templates
agreement
[('is_template', '=', True)]
-
+
{'default_is_template': True}
tree,kanban,form
diff --git a/agreement_legal/views/agreement_appendix.xml b/agreement_legal/views/agreement_appendix.xml
index 258de95a8..27fce2c00 100644
--- a/agreement_legal/views/agreement_appendix.xml
+++ b/agreement_legal/views/agreement_appendix.xml
@@ -5,7 +5,7 @@
Agreement Appendix Tree
agreement.appendix
-
+
@@ -103,4 +103,35 @@
tree,form
+
+
+ Agreement Appendix Tree2
+ agreement.appendix
+
+ primary
+ 999
+
+
+ sequence
+
+
+ 1
+
+
+
+
+
+
+ Agreement Appendix Form2
+ agreement.appendix
+
+ primary
+ 999
+
+
+ 1
+
+
+
+
diff --git a/agreement_legal/views/agreement_clause.xml b/agreement_legal/views/agreement_clause.xml
index fbcaaf7c0..6e712ad9d 100644
--- a/agreement_legal/views/agreement_clause.xml
+++ b/agreement_legal/views/agreement_clause.xml
@@ -5,7 +5,7 @@
Agreement Clause List
agreement.clause
-
+
@@ -113,4 +113,43 @@
tree,form
+
+
+ Agreement Clause List2
+ agreement.clause
+
+ primary
+ 999
+
+
+ sequence
+
+
+ 1
+
+
+
+
+
+
+ Agreement Clause Form2
+ agreement.clause
+
+ primary
+ 999
+
+
+
+
+
+ 1
+
+
+ [('agreement_id', '=', temp_agreement_id)]
+
+
+
+
diff --git a/agreement_legal/views/agreement_increasetype.xml b/agreement_legal/views/agreement_increasetype.xml
deleted file mode 100644
index 94993e1e9..000000000
--- a/agreement_legal/views/agreement_increasetype.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
- Agreement Increase Type List
- agreement.increasetype
-
-
-
-
-
-
-
-
-
-
-
- Agreement Increase Type Form
- agreement.increasetype
-
-
-
-
-
-
-
- Agreement Increase Type
- agreement.increasetype
- tree,form
-
-
-
diff --git a/agreement_legal/views/agreement_recital.xml b/agreement_legal/views/agreement_recital.xml
index 20fb26494..3cabd4878 100644
--- a/agreement_legal/views/agreement_recital.xml
+++ b/agreement_legal/views/agreement_recital.xml
@@ -5,7 +5,7 @@
Agreement Recital Tree
agreement.recital
-
+
@@ -103,4 +103,35 @@
tree,form
+
+
+ Agreement Recital Tree2
+ agreement.recital
+
+ primary
+ 999
+
+
+ sequence
+
+
+ 1
+
+
+
+
+
+
+ Agreement Recital Form2
+ agreement.recital
+
+ primary
+ 999
+
+
+ 1
+
+
+
+
diff --git a/agreement_legal/views/agreement_renewaltype.xml b/agreement_legal/views/agreement_renewaltype.xml
deleted file mode 100644
index 218511600..000000000
--- a/agreement_legal/views/agreement_renewaltype.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- Agreement Renewal Type List
- agreement.renewaltype
-
-
-
-
-
-
-
-
-
-
- Agreement Renewal Type Form
- agreement.renewaltype
-
-
-
-
-
-
-
- Agreement Renewal Type
- agreement.renewaltype
- tree,form
-
-
-
diff --git a/agreement_legal/views/agreement_section.xml b/agreement_legal/views/agreement_section.xml
index 4836d627f..d48195aac 100644
--- a/agreement_legal/views/agreement_section.xml
+++ b/agreement_legal/views/agreement_section.xml
@@ -5,7 +5,7 @@
Agreement Section List
agreement.section
-
+
@@ -122,4 +122,35 @@
tree,form
+
+
+ Agreement Section List2
+ agreement.section
+
+ primary
+ 999
+
+
+ sequence
+
+
+ 1
+
+
+
+
+
+
+ Agreement Section Form2
+ agreement.section
+
+ primary
+ 999
+
+
+ 1
+
+
+
+
diff --git a/agreement_legal/views/agreement_stages.xml b/agreement_legal/views/agreement_stages.xml
index 89c3eaa44..99cd400bf 100644
--- a/agreement_legal/views/agreement_stages.xml
+++ b/agreement_legal/views/agreement_stages.xml
@@ -5,10 +5,11 @@
Agreement Stage List
agreement.stage
-
+
-
+
+
@@ -20,20 +21,52 @@
+
+
+ Agreement Stage Search
+ agreement.stage
+
+
+
+
+
+
+
+
+
+
+
+
Agreement Stage
diff --git a/agreement_legal/views/agreement_subtype.xml b/agreement_legal/views/agreement_subtype.xml
index e5e548c9b..5c14b0453 100644
--- a/agreement_legal/views/agreement_subtype.xml
+++ b/agreement_legal/views/agreement_subtype.xml
@@ -5,9 +5,10 @@
Agreement Subtype List
agreement.subtype
-
-
-
+
+
+
+
@@ -19,14 +20,21 @@
+
+
+ Agreement Sub Type Search
+ agreement.subtype
+
+
+
+
+
+
+
+
+
+
+
+
+
Agreement Sub-Types
diff --git a/agreement_legal/views/agreement_type.xml b/agreement_legal/views/agreement_type.xml
index f3cb67491..91e059f71 100644
--- a/agreement_legal/views/agreement_type.xml
+++ b/agreement_legal/views/agreement_type.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/agreement_legal/views/assets.xml b/agreement_legal/views/assets.xml
new file mode 100644
index 000000000..53e95e394
--- /dev/null
+++ b/agreement_legal/views/assets.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/agreement_legal/views/menu.xml b/agreement_legal/views/menu.xml
index ab6b62493..97421752d 100644
--- a/agreement_legal/views/menu.xml
+++ b/agreement_legal/views/menu.xml
@@ -129,39 +129,25 @@
sequence="20"
action="partner_agreement_agreement_templates"
/>
-
-
diff --git a/agreement_legal/wizards/__init__.py b/agreement_legal/wizards/__init__.py
new file mode 100644
index 000000000..8ceffa813
--- /dev/null
+++ b/agreement_legal/wizards/__init__.py
@@ -0,0 +1,3 @@
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from . import create_agreement_wizard
diff --git a/agreement_legal/wizards/create_agreement_wizard.py b/agreement_legal/wizards/create_agreement_wizard.py
new file mode 100644
index 000000000..1f239bb66
--- /dev/null
+++ b/agreement_legal/wizards/create_agreement_wizard.py
@@ -0,0 +1,31 @@
+# Copyright 2021 Ecosoft Co., Ltd (http://ecosoft.co.th)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class CreateAgreementWizard(models.TransientModel):
+ _name = "create.agreement.wizard"
+ _description = "Create Agreement Wizard"
+
+ template_id = fields.Many2one(
+ "agreement",
+ string="Template",
+ required=True,
+ domain=[("is_template", "=", True)],
+ )
+ name = fields.Char(string="Title", required=True)
+
+ def create_agreement(self):
+ self.ensure_one()
+ res = self.template_id.create_new_agreement()
+ agreement = self.env[res["res_model"]].browse(res["res_id"])
+ agreement.write(
+ {
+ "name": self.name,
+ "description": self.name,
+ "template_id": self.template_id.id,
+ "revision": 0,
+ }
+ )
+ return res
diff --git a/agreement_legal/wizards/create_agreement_wizard.xml b/agreement_legal/wizards/create_agreement_wizard.xml
new file mode 100644
index 000000000..4aee8d2b8
--- /dev/null
+++ b/agreement_legal/wizards/create_agreement_wizard.xml
@@ -0,0 +1,34 @@
+
+
+ Create Agreement From Template
+ create.agreement.wizard
+
+
+
+
+
+
+ Create From Template
+ create.agreement.wizard
+ form
+ new
+
+