From ee1016897670e34dd56f1cb59ddaf4059b1e3903 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Fri, 12 Oct 2018 17:31:37 -0500 Subject: [PATCH] [ADD] agreement --- agreement/README.md | 30 ++ agreement/__init__.py | 4 + agreement/__manifest__.py | 31 ++ agreement/controllers/__init__.py | 3 + agreement/controllers/controllers.py | 2 + agreement/demo/demo.xml | 30 ++ agreement/models/__init__.py | 10 + agreement/models/agreement_clause.py | 28 ++ agreement/models/agreement_increasetype.py | 10 + agreement/models/agreement_renewaltype.py | 9 + agreement/models/agreement_section.py | 27 ++ agreement/models/agreement_stage.py | 12 + agreement/models/agreement_status.py | 8 + agreement/models/agreement_subtype.py | 9 + agreement/models/agreement_type.py | 9 + agreement/models/partner_agreement.py | 123 ++++++++ agreement/models/product_template.py | 7 + agreement/models/res_partner.py | 7 + agreement/security/ir.model.access.csv | 9 + agreement/security/security.xml | 4 + agreement/static/description/icon.png | Bin 0 -> 6755 bytes agreement/views/agreement.xml | 331 +++++++++++++++++++++ agreement/views/agreement_clause.xml | 103 +++++++ agreement/views/agreement_increasetype.xml | 53 ++++ agreement/views/agreement_renewaltype.xml | 51 ++++ agreement/views/agreement_section.xml | 97 ++++++ agreement/views/agreement_stages.xml | 52 ++++ agreement/views/agreement_subtype.xml | 51 ++++ agreement/views/agreement_type.xml | 51 ++++ agreement/views/reports.xml | 48 +++ agreement/views/res_partner.xml | 19 ++ 31 files changed, 1228 insertions(+) create mode 100644 agreement/README.md create mode 100644 agreement/__init__.py create mode 100644 agreement/__manifest__.py create mode 100644 agreement/controllers/__init__.py create mode 100644 agreement/controllers/controllers.py create mode 100644 agreement/demo/demo.xml create mode 100644 agreement/models/__init__.py create mode 100644 agreement/models/agreement_clause.py create mode 100644 agreement/models/agreement_increasetype.py create mode 100644 agreement/models/agreement_renewaltype.py create mode 100644 agreement/models/agreement_section.py create mode 100644 agreement/models/agreement_stage.py create mode 100644 agreement/models/agreement_status.py create mode 100644 agreement/models/agreement_subtype.py create mode 100644 agreement/models/agreement_type.py create mode 100644 agreement/models/partner_agreement.py create mode 100644 agreement/models/product_template.py create mode 100644 agreement/models/res_partner.py create mode 100644 agreement/security/ir.model.access.csv create mode 100644 agreement/security/security.xml create mode 100644 agreement/static/description/icon.png create mode 100644 agreement/views/agreement.xml create mode 100644 agreement/views/agreement_clause.xml create mode 100644 agreement/views/agreement_increasetype.xml create mode 100644 agreement/views/agreement_renewaltype.xml create mode 100644 agreement/views/agreement_section.xml create mode 100644 agreement/views/agreement_stages.xml create mode 100644 agreement/views/agreement_subtype.xml create mode 100644 agreement/views/agreement_type.xml create mode 100644 agreement/views/reports.xml create mode 100644 agreement/views/res_partner.xml diff --git a/agreement/README.md b/agreement/README.md new file mode 100644 index 00000000..fe016e1a --- /dev/null +++ b/agreement/README.md @@ -0,0 +1,30 @@ +Agreements + +This module adds Agreements to the partner module. + +Usage + +To use this module, you need to: +1. . + +Known issues / Roadmap + +* . + +Bug Tracker + +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. + +Credits + +Images + +* Agreement: Icon. + +Contributors + +* Patrick Wilson + +Do not contact contributors directly about support or help with technical issues. + +Maintainer diff --git a/agreement/__init__.py b/agreement/__init__.py new file mode 100644 index 00000000..aa4d0fd6 --- /dev/null +++ b/agreement/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import controllers +from . import models diff --git a/agreement/__manifest__.py b/agreement/__manifest__.py new file mode 100644 index 00000000..899c540f --- /dev/null +++ b/agreement/__manifest__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Agreements", + 'summary': "Manage Agreements, LOI and Contracts", + 'author': "Pavlov Media", + 'website': "https://github.com/OCA/contract", + 'category': 'Partner', + 'version': '11.0.0.0.1', + 'depends': [ + 'mail', + 'sale_management' + ], + 'data': [ + 'views/reports.xml', + 'views/agreement.xml', + 'views/agreement_clause.xml', + 'views/agreement_section.xml', + 'views/agreement_stages.xml', + 'views/agreement_type.xml', + 'views/agreement_subtype.xml', + 'views/agreement_renewaltype.xml', + 'views/agreement_increasetype.xml', + 'views/res_partner.xml', + 'security/security.xml', + 'security/ir.model.access.csv', + ], + 'demo': [ + 'demo/demo.xml', + ], + 'application': True, +} diff --git a/agreement/controllers/__init__.py b/agreement/controllers/__init__.py new file mode 100644 index 00000000..b0f26a9a --- /dev/null +++ b/agreement/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers diff --git a/agreement/controllers/controllers.py b/agreement/controllers/controllers.py new file mode 100644 index 00000000..b97fd18c --- /dev/null +++ b/agreement/controllers/controllers.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from odoo import http diff --git a/agreement/demo/demo.xml b/agreement/demo/demo.xml new file mode 100644 index 00000000..b2d1b70c --- /dev/null +++ b/agreement/demo/demo.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/agreement/models/__init__.py b/agreement/models/__init__.py new file mode 100644 index 00000000..25f33f61 --- /dev/null +++ b/agreement/models/__init__.py @@ -0,0 +1,10 @@ +from . import partner_agreement +from . import agreement_clause +from . import agreement_section +from . import agreement_stage +from . import agreement_type +from . import agreement_subtype +from . import res_partner +from . import product_template +from . import agreement_renewaltype +from . import agreement_increasetype diff --git a/agreement/models/agreement_clause.py b/agreement/models/agreement_clause.py new file mode 100644 index 00000000..553faa75 --- /dev/null +++ b/agreement/models/agreement_clause.py @@ -0,0 +1,28 @@ +from odoo import models, fields, api + +#Main Agreement clause Records Model +class AgreementClause(models.Model): + _name = 'partner_agreement.clause' + _order = 'clause_sequence' + +#General + name = fields.Char(string="Title", required=True) + clause_sequence = fields.Integer(string="Sequence") + agreement = fields.Many2one('partner_agreement.agreement', string="Agreement", ondelete="cascade") + section = fields.Many2one('partner_agreement.section', string="Section", ondelete="cascade") + content = fields.Html(string="Clause Content") + active = fields.Boolean(string="Active", default=True, help="If unchecked, it will allow you to hide the agreement without removing it.") + +#Placeholder fields + model_id = fields.Many2one('ir.model', string="Applies to", help="The type of document this template can be used with.") + model_object_field = 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 = 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 = 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).") + null_value = fields.Char(string="Default Value", help="Optional value to use if the target field is empty.") + copyvalue = fields.Char(string="Placeholder Expression", help="Final placeholder expression, to be copy-pasted in the desired template field.") + + @api.model + def create(self, vals): + seq = self.env['ir.sequence'].next_by_code('agreement.clause') or '/' + vals['clause_sequence'] = seq + return super(AgreementClause, self).create(vals) diff --git a/agreement/models/agreement_increasetype.py b/agreement/models/agreement_increasetype.py new file mode 100644 index 00000000..b83a85a7 --- /dev/null +++ b/agreement/models/agreement_increasetype.py @@ -0,0 +1,10 @@ +from odoo import models, fields + +#Main Agreement Increase Type Records Model +class AgreementIncreaseType(models.Model): + _name = 'partner_agreement.increasetype' + +#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/models/agreement_renewaltype.py b/agreement/models/agreement_renewaltype.py new file mode 100644 index 00000000..b46d89e7 --- /dev/null +++ b/agreement/models/agreement_renewaltype.py @@ -0,0 +1,9 @@ +from odoo import models, fields + +#Main Agreement Section Records Model +class AgreementRenewalType(models.Model): + _name = 'partner_agreement.renewaltype' + +#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/models/agreement_section.py b/agreement/models/agreement_section.py new file mode 100644 index 00000000..87af1308 --- /dev/null +++ b/agreement/models/agreement_section.py @@ -0,0 +1,27 @@ +from odoo import models, fields, api + +#Main Agreement Section Records Model +class AgreementSection(models.Model): + _name = 'partner_agreement.section' + _order = 'section_sequence' + +#General + name = fields.Char(string="Title", required=True) + section_sequence = fields.Integer(string="Sequence") + agreement = fields.Many2one('partner_agreement.agreement', string="Agreement", ondelete="cascade") + clauses = fields.One2many('partner_agreement.clause', 'section', string="Clauses") + content = fields.Html(string="Section Content") + active = fields.Boolean(string="Active", default=True, help="If unchecked, it will allow you to hide the agreement without removing it.") +#Placeholder fields + model_id = fields.Many2one('ir.model', string="Applies to", help="The type of document this template can be used with.") + model_object_field = 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 = 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 = 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).") + null_value = fields.Char(string="Default Value", help="Optional value to use if the target field is empty.") + copyvalue = fields.Char(string="Placeholder Expression", help="Final placeholder expression, to be copy-pasted in the desired template field.") + + @api.model + def create(self, vals): + seq = self.env['ir.sequence'].next_by_code('agreement.section') or '/' + vals['section_sequence'] = seq + return super(AgreementSection, self).create(vals) diff --git a/agreement/models/agreement_stage.py b/agreement/models/agreement_stage.py new file mode 100644 index 00000000..1d967448 --- /dev/null +++ b/agreement/models/agreement_stage.py @@ -0,0 +1,12 @@ +from odoo import models, fields + +#Main Agreement Section Records Model +class AgreementStage(models.Model): + _name = 'partner_agreement.stage' + _order = 'sequence' + +#General + name = fields.Char(string="Stage Name", required=True) + description = fields.Text(string="Description", required=False) + sequence = fields.Integer(string="Sequence", default="1", required=False) + fold = fields.Boolean(string="Is Folded", required=False, help="This stage is folded in the kanban view by deafault.") diff --git a/agreement/models/agreement_status.py b/agreement/models/agreement_status.py new file mode 100644 index 00000000..e5d95cda --- /dev/null +++ b/agreement/models/agreement_status.py @@ -0,0 +1,8 @@ +from odoo import models, fields + +#Main Agreement Status Records Model +class AgreementStatus(models.Model): + _name = 'partner_agreement.type' + +#General + name = fields.Char(string="Title", required=True) diff --git a/agreement/models/agreement_subtype.py b/agreement/models/agreement_subtype.py new file mode 100644 index 00000000..fe95cfe3 --- /dev/null +++ b/agreement/models/agreement_subtype.py @@ -0,0 +1,9 @@ +from odoo import models, fields + +#Main Agreement Section Records Model +class AgreementSubtype(models.Model): + _name = 'partner_agreement.subtype' + +#General + name = fields.Char(string="Title", required=True) + agreement_type = fields.Many2one('partner_agreement.type', string="Agreement Type") diff --git a/agreement/models/agreement_type.py b/agreement/models/agreement_type.py new file mode 100644 index 00000000..c492a3a7 --- /dev/null +++ b/agreement/models/agreement_type.py @@ -0,0 +1,9 @@ +from odoo import models, fields + +#Main Agreement Section Records Model +class AgreementType(models.Model): + _name = 'partner_agreement.type' + +#General + name = fields.Char(string="Title", required=True) + agreement_subtypes = fields.One2many('partner_agreement.subtype', 'agreement_type', string="Agreement") diff --git a/agreement/models/partner_agreement.py b/agreement/models/partner_agreement.py new file mode 100644 index 00000000..5a62aed0 --- /dev/null +++ b/agreement/models/partner_agreement.py @@ -0,0 +1,123 @@ +from odoo import models, fields, api + +#Main Agreement Records Model +class Agreement(models.Model): + _name = 'partner_agreement.agreement' + _inherit = ['mail.thread'] + +#General + name = fields.Char(string="Title", required=True) + is_template = fields.Boolean(string="Is a Template?", default=False, copy=False, help="Make this agreement a template.") + version = fields.Integer(string="Version", default=1, help="The versions are used to keep track of document history and previous versions can be referenced.", copy=False) + revision = fields.Integer(string="Revision", default=0, help="The revision will increase with every save event.", copy=False) + description = fields.Text(string="Description", help="Description of the agreement", track_visibility='onchange') + start_date = fields.Date(string="Start Date", help="When the agreement starts.", track_visibility='onchange') + end_date = fields.Date(string="End Date", help="When the agreement ends.", track_visibility='onchange') + color = fields.Integer() + active = fields.Boolean(string="Active", default=True, help="If unchecked, it will allow you to hide the agreement without removing it.") + company_signed_date = fields.Date(string="Company Signed Date", help="Date the contract was signed by Company.", track_visibility='onchange') + customer_signed_date = fields.Date(string="Customer Signed Date", help="Date the contract was signed by Customer.", track_visibility='onchange') + customer_term = fields.Integer(string="Customer Term (Months)", help="Number of months this agreement/contract is in effect with customer.", track_visibility='onchange') + vendor_term = fields.Integer(string="Vendor Term (Months)", help="Number of months this agreement/contract is in effect with vendor.", track_visibility='onchange') + expiration_notice = fields.Integer(string="Exp. Notice (Days)", help="Number of Days before expiration to be notified.", track_visibility='onchange') + change_notice = fields.Integer(string="Change Notice (Days)", help="Number of Days to be notified before changes.", track_visibility='onchange') + special_terms = fields.Text(string="Special Terms", help="Any terms that you have agreed to and want to track on the agreement/contract.", track_visibility='onchange') + contract_value = fields.Monetary(compute='_compute_contract_value', string="Contract Value", help="Total value of the contract over ther entire term.", store=True) + contract_id = fields.Char(string="ID", help="ID used for internal contract tracking.", track_visibility='onchange') + total_company_mrc = fields.Monetary('Company MRC', currency_field='currency_id', help="Total company monthly recurring costs.")#, compute='_compute_company_mrc') + total_customer_mrc = fields.Monetary('Customer MRC', currency_field='currency_id', help="Total custemer monthly recurring costs.") + total_company_nrc = fields.Monetary('Company NRC', currency_field='currency_id', help="Total company non-recurring costs.") + total_customer_nrc = fields.Monetary('Customer NRC', currency_field='currency_id', help="Total custemer non-monthly recurring costs.") + increase_type = fields.Many2one('partner_agreement.increasetype', string="Increase Type", help="The amount that certain rates may increase.", track_visibility='onchange') + termination_requested = fields.Date(string="Termination Requested Date", help="Date that a request for termination was received.", track_visibility='onchange') + termination_date = fields.Date(string="Termination Date", help="Date that the contract was terminated.", track_visibility='onchange') + customer_address = fields.Char(related='customer.contact_address', string="Address") + customer_street = fields.Char(related='customer.street', string="Street") + customer_street2 = fields.Char(related='customer.street2', string="Street 2") + customer_city = fields.Char(related='customer.city', string="City") + customer_state = fields.Many2one(related='customer.state_id', string="State") + customer_zip = fields.Char(related='customer.zip', string="Zip") + vendor_address = fields.Char(related='vendor.contact_address', string="Address") + vendor_street = fields.Char(related='vendor.street', string="Street") + vendor_street2 = fields.Char(related='vendor.street2', string="Street 2") + vendor_city = fields.Char(related='vendor.city', string="City") + vendor_state = fields.Many2one(related='vendor.state_id', string="State") + vendor_zip = fields.Char(related='vendor.zip', string="Zip") + reviewed_date = fields.Date(string="Reviewed Date", track_visibility='onchange') + reviewed_by = fields.Many2one('res.users', string="Reviewed By", track_visibility='onchange') + approved_date = fields.Date(string="Approved Date", track_visibility='onchange') + approved_by = fields.Many2one('res.users', string="Approved By", track_visibility='onchange') + + currency_id = fields.Many2one('res.currency', string='Currency') + customer = fields.Many2one('res.partner', string="Customer", copy=True, help="The customer this agreement is related to (If Applicable).") + vendor = fields.Many2one('res.partner', string="Vendor", copy=True, help="The vendor this agreement is related to (If Applicable).") + customer_contact = fields.Many2one('res.partner', string="Customer Contact", copy=True, help="The primary customer contact (If Applicable).") + customer_contact_phone = fields.Char(related='customer_contact.phone', string="Phone") + customer_contact_email = fields.Char(related='customer_contact.email', string="Email") + + vendor_contact = fields.Many2one('res.partner', string="Vendor Contact", copy=True, help="The primary vendor contact (If Applicable).") + vendor_contact_phone = fields.Char(related='vendor_contact.phone', string="Phone") + vendor_contact_email = fields.Char(related='vendor_contact.email', string="Email") + type = fields.Many2one('partner_agreement.type', string="Agreement Type", help="Select the type of agreement.", track_visibility='onchange') + subtype = fields.Many2one('partner_agreement.subtype', string="Agreement Sub-type", help="Select the sub-type of this agreement. Sub-Types are related to agreement types.", track_visibility='onchange') + sale_order = fields.Many2one('sale.order', string="Sales Order", help="Select the Sales Order that this agreement is related to.", copy=False, track_visibility='onchange') + payment_term = fields.Many2one('account.payment.term', string="Payment Term", help="Terms of payments.", track_visibility='onchange') + assigned_to = fields.Many2one('res.users', string="Assigned To", help="Select the user who manages this agreement.", track_visibility='onchange') + company_signed_by = fields.Many2one('res.users', string="Company Signed By", help="The user at our company who authorized/signed the agreement or contract.", track_visibility='onchange') + customer_signed_by = fields.Many2one('res.partner', string="Customer Signed By", help="Contact on the account that signed the agreement/contract.", track_visibility='onchange') + parent_agreement = fields.Many2one('partner_agreement.agreement', string="Parent Agreement", help="Link this agreement to a parent agreement. For example if this agreement is an amendment to another agreement. This list will only show other agreements related to the same account.") + renewal_type = fields.Many2one('partner_agreement.renewaltype', string="Renewal Type", help="Describes what happens after the contract expires.", track_visibility='onchange') + + order_lines_services = fields.One2many(related='sale_order.order_line', string="Service Order Lines", copy=False) +# order_lines_nonservices = fields.One2many(related='sale_order.order_line', string="Non Service Order Lines", copy=False, store=False) + sections = fields.One2many('partner_agreement.section', 'agreement', string="Sections", copy=True) + clauses = fields.One2many('partner_agreement.clause', 'agreement', string="Clauses", copy=True) + previous_version_agreements = fields.One2many('partner_agreement.agreement', 'parent_agreement', string="Child Agreements", copy=False, domain=[('active', '=', False)]) + child_agreements = fields.One2many('partner_agreement.agreement', 'parent_agreement', string="Child Agreements", copy=False, domain=[('active', '=', True)]) + products = fields.Many2many('product.template', string="Products", copy=False) + state = fields.Selection([('draft', 'Draft'),('active', 'Active'),('inactive', 'Inactive')], default='draft', track_visibility='always') + notification_address = fields.Many2one('res.partner', string="Notification Address", help="The address to send notificaitons to, if different from customer address.(Address Type = Other)") + signed_contract_filename = fields.Char(string="Filename") + signed_contract = fields.Binary(string="Signed Document", track_visibility='always') + + #compute contract_value field + @api.depends('total_customer_mrc','total_customer_nrc','customer_term') + def _compute_contract_value (self): + for record in self: + record.contract_value = (record.total_customer_mrc * record.customer_term) + record.total_customer_nrc + + #compute total_company_mrc field + #@api.multi + @api.depends('order_lines_services','sale_order') + def _compute_company_mrc(self): + order_lines = self.env['sale.order.line'].search([('is_service', '=', True)]) + amount_total = sum(order_lines.mapped('purchase_price')) + for record in self: + record.total_company_mrc = amount_total + + #Used for Kanban grouped_by view + @api.model + def _read_group_stage_ids(self,stages,domain,order): + stage_ids = self.env['partner_agreement.stage'].search([]) + return stage_ids + + stage = fields.Many2one('partner_agreement.stage', string="Stage", group_expand='_read_group_stage_ids', help="Select the current stage of the agreement.") + + #Create New Version Button + @api.multi + def create_new_version(self, vals): + self.write({'state': 'draft'}) #Make sure status is draft + self.copy(default={'name': self.name + ' - OLD VERSION', 'active': False, 'parent_agreement': self.id}) #Make a current copy and mark it as old + self.write({'version': self.version + 1}) #Increment the Version + #Reset revision to 0 since it's a new version + vals['revision'] = 0 + return super(Agreement, self).write(vals) + + def create_new_agreement(self): + res = self.copy(default={'name': 'NEW', 'active': True, 'version': 1, 'revision': 0, 'state': 'draft', 'start_date': "", 'end_date':""}) + return {'res_model': 'partner_agreement.agreement', 'type': 'ir.actions.act_window', 'view_mode': 'form', 'view_type': 'form', 'res_id': res.id} + + #Increments the revision on each save action + def write(self, vals): + vals['revision'] = self.revision + 1 + return super(Agreement, self).write(vals) diff --git a/agreement/models/product_template.py b/agreement/models/product_template.py new file mode 100644 index 00000000..1b93eb49 --- /dev/null +++ b/agreement/models/product_template.py @@ -0,0 +1,7 @@ +from odoo import models, fields, api + +class Product(models.Model): + + _inherit = 'product.template' + + agreements = fields.Many2many('partner_agreement.agreement', string="Agreements") diff --git a/agreement/models/res_partner.py b/agreement/models/res_partner.py new file mode 100644 index 00000000..a451e455 --- /dev/null +++ b/agreement/models/res_partner.py @@ -0,0 +1,7 @@ +from odoo import models, fields, api + +class Partner(models.Model): + + _inherit = 'res.partner' + + agreements = fields.One2many('partner_agreement.agreement', 'name', string="Agreements") diff --git a/agreement/security/ir.model.access.csv b/agreement/security/ir.model.access.csv new file mode 100644 index 00000000..670e99a4 --- /dev/null +++ b/agreement/security/ir.model.access.csv @@ -0,0 +1,9 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_agreement_allusers,agreement all users,model_partner_agreement_agreement,,1,1,1,1 +access_agreement_section_allusers,section all users,model_partner_agreement_section,,1,1,1,1 +access_agreement_clause_allusers,clause all users,model_partner_agreement_clause,,1,1,1,1 +access_agreement_stage_allusers,stage all users,model_partner_agreement_stage,,1,1,1,1 +access_agreement_type_allusers,type all users,model_partner_agreement_type,,1,1,1,1 +access_agreement_subtype_allusers,subtype all users,model_partner_agreement_subtype,,1,1,1,1 +access_agreement_renewaltype_allusers,renewaltype all users,model_partner_agreement_renewaltype,,1,1,1,1 +access_agreement_increasetype_allusers,increasetype all users,model_partner_agreement_increasetype,,1,1,1,1 diff --git a/agreement/security/security.xml b/agreement/security/security.xml new file mode 100644 index 00000000..c9817ed2 --- /dev/null +++ b/agreement/security/security.xml @@ -0,0 +1,4 @@ + + + + diff --git a/agreement/static/description/icon.png b/agreement/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..23ce93135053c48a74469807879f2805b12382ad GIT binary patch literal 6755 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 + + + + + + Agreement List + partner_agreement.agreement + + + + + + + + + + + + + + + + Agreement Form + partner_agreement.agreement + +
+
+
+ +
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+
+ +
+ + + + + + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

This section is a place where finincial records will show the current performance of this agreement.

+

Perhaps include invoices with total vs costs?

+
+
+ + + + + + + +
+ Version: . + | Created By: + | Created On: +
+
+
+ + +
+
+
+
+ + + + Agreement Kanban + partner_agreement.agreement + + + + + + +
+
+
+
+
+
+ + oe_kanban_text_red +
+
+
+ + +
+ +
+ - +
+ +
+
+ V: +
+
+ +
+
+
+
+
+ + + + + + + + + Agreement Search + partner_agreement.agreement + + + + + + + + + + + + + + Order Lines Search + sale.order.line + search + + + + + + + + + + + Agreements + partner_agreement.agreement + {"search_default_filter_non_template":1} + kanban,tree,form + + + + Agreements + partner_agreement.agreement + {"search_default_filter_templates":1} + tree,kanban,form + + + + + + + + + + + + diff --git a/agreement/views/agreement_clause.xml b/agreement/views/agreement_clause.xml new file mode 100644 index 00000000..fb1a7203 --- /dev/null +++ b/agreement/views/agreement_clause.xml @@ -0,0 +1,103 @@ + + + + + agreement_clause_sequencer + agreement.clause + 0 + 1 + + + + + Agreement Clause List + partner_agreement.clause + + + + + + + + + + + + + + + Agreement clause Form + partner_agreement.clause + +
+ +
+
+ + + + + + + + + THIS IS UNDER DEVELOPEMENT: The purpose of this section is to be able to create dynamic fields inside your content. + + + + + + + + + + + Sequence # +
+
+
+
+ + + + Agreement Clause Search + partner_agreement.clause + + + + + + + + + + + Agreement Clause Pivot + partner_agreement.clause + + + + + + + + + + + + Agreement Clauses + partner_agreement.clause + tree,pivot,form + + + + +
+
diff --git a/agreement/views/agreement_increasetype.xml b/agreement/views/agreement_increasetype.xml new file mode 100644 index 00000000..ede75d6d --- /dev/null +++ b/agreement/views/agreement_increasetype.xml @@ -0,0 +1,53 @@ + + + + + + + Agreement Increase Type List + partner_agreement.increasetype + + + + + + + + + + + + Agreement Increase Type Form + partner_agreement.increasetype + +
+ +
+
+ + + + +
+
+
+
+ + + + Agreement Increase Type + partner_agreement.increasetype + tree,form + + + + +
+
diff --git a/agreement/views/agreement_renewaltype.xml b/agreement/views/agreement_renewaltype.xml new file mode 100644 index 00000000..5950d0b3 --- /dev/null +++ b/agreement/views/agreement_renewaltype.xml @@ -0,0 +1,51 @@ + + + + + + + Agreement Renewal Type List + partner_agreement.renewaltype + + + + + + + + + + + Agreement Renewal Type Form + partner_agreement.renewaltype + +
+ +
+
+ + + +
+
+
+
+ + + + Agreement Renewal Type + partner_agreement.renewaltype + tree,form + + + + +
+
diff --git a/agreement/views/agreement_section.xml b/agreement/views/agreement_section.xml new file mode 100644 index 00000000..b747ef47 --- /dev/null +++ b/agreement/views/agreement_section.xml @@ -0,0 +1,97 @@ + + + + + agreement_section_sequencer + agreement.section + 0 + 1 + + + + + Agreement Section List + partner_agreement.section + + + + + + + + + + + + + Agreement Section Form + partner_agreement.section + +
+ +
+
+ + + + + + + + + + + + + + + + + + THIS IS UNDER DEVELOPEMENT: The purpose of this section is to be able to create dynamic fields inside your content. + + + + + + + + + + + Sequence # +
+
+
+
+ + + + Agreement Section Search + partner_agreement.section + + + + + + + + + + Agreement Sections + partner_agreement.section + tree,form + + + + + +
+
diff --git a/agreement/views/agreement_stages.xml b/agreement/views/agreement_stages.xml new file mode 100644 index 00000000..e2d83fd3 --- /dev/null +++ b/agreement/views/agreement_stages.xml @@ -0,0 +1,52 @@ + + + + + + + Agreement Stage List + partner_agreement.stage + + + + + + + + + + + Agreement Stage Form + partner_agreement.stage + +
+ +
+
+ + + + +
+
+
+
+ + + + Agreement Stage + partner_agreement.stage + tree,form + + + + +
+
diff --git a/agreement/views/agreement_subtype.xml b/agreement/views/agreement_subtype.xml new file mode 100644 index 00000000..59bbbbe3 --- /dev/null +++ b/agreement/views/agreement_subtype.xml @@ -0,0 +1,51 @@ + + + + + + + Agreement Subtype List + partner_agreement.subtype + + + + + + + + + + + Agreement Sub Type Form + partner_agreement.subtype + +
+ +
+
+ + + +
+
+
+
+ + + + Agreement Sub Type + partner_agreement.subtype + tree,form + + + + +
+
diff --git a/agreement/views/agreement_type.xml b/agreement/views/agreement_type.xml new file mode 100644 index 00000000..88608924 --- /dev/null +++ b/agreement/views/agreement_type.xml @@ -0,0 +1,51 @@ + + + + + + + Agreement Type List + partner_agreement.type + + + + + + + + + + + Agreement Type Form + partner_agreement.type + +
+ +
+
+ + + +
+
+
+
+ + + + Agreement Type + partner_agreement.type + tree,form + + + + +
+
diff --git a/agreement/views/reports.xml b/agreement/views/reports.xml new file mode 100644 index 00000000..98ba467a --- /dev/null +++ b/agreement/views/reports.xml @@ -0,0 +1,48 @@ + + + + + + + + diff --git a/agreement/views/res_partner.xml b/agreement/views/res_partner.xml new file mode 100644 index 00000000..39d034e4 --- /dev/null +++ b/agreement/views/res_partner.xml @@ -0,0 +1,19 @@ + + + + res.partner + + + + + + + + + + + + + + +