From ee1016897670e34dd56f1cb59ddaf4059b1e3903 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Fri, 12 Oct 2018 17:31:37 -0500 Subject: [PATCH 1/8] [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 000000000..fe016e1a2 --- /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 000000000..aa4d0fd63 --- /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 000000000..899c540f9 --- /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 000000000..b0f26a9a6 --- /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 000000000..b97fd18c9 --- /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 000000000..b2d1b70c7 --- /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 000000000..25f33f611 --- /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 000000000..553faa758 --- /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 000000000..b83a85a76 --- /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 000000000..b46d89e7b --- /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 000000000..87af13083 --- /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 000000000..1d9674480 --- /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 000000000..e5d95cda5 --- /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 000000000..fe95cfe31 --- /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 000000000..c492a3a70 --- /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 000000000..5a62aed0b --- /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 000000000..1b93eb49f --- /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 000000000..a451e455e --- /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 000000000..670e99a4c --- /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 000000000..c9817ed22 --- /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 zcmV-p8l2^cP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vG&=l}pD=mCOb1snhX8Td&=K~#8N-CKFQ zBvp0(s=Io9`)n{X!YCjrLL4@uLLx?^7>Nlg;0OWKpNe}Tf-$lvB8s2}{h8qK3&9P6 zA)<*}0!9po;{xiS0)rw5Gt55ky?(Ek>Z-1M-??>PSHF1!0kiLh2wasDW7Mv0M0u zAiRJ^rHqA4zG5Ljk*y(xm+2{|26%Krt8`xQhXRsC)@DI(@bcpppYg!>v;++1pP(b zB62H-0kN3ksaS zR}aWD)l0;!XGCohU_SQS-CoR|NhIdH`PiGAGavhN=hn!rHy`_k8N??N6qOqcfEdVw zYK|$D#GZf7Gu%fHdYr?({Mo+@_XY!NOCXPXgWMR+(PN&k`H&?-_G#d?mP(6sE#^fQ20q0-8j1dCw}k zkNIsfAY={-+|HERRq|lXT!gdv#KlNdZY2*$l4K6eI%=noM#Knb7R#__Ub83iBR9sa zFLdiVCFRHD>9SKnDWkpcn%?@EO&5gVpby@rj9@?sHi^Q-qQSKUjyWwxW|ca#UuB0u zRG>iA2Tk&I&2eY0T1Cbf)pL%s{Ilq|(Hd)o!Q4DO^FtI$#ekTn?LZ?-MFvJyxORb_ z>t+tZ9t!Y8RHmF5#}bqqAx+Q;hf(QH(*?Vjj4BulV;sJs&UBLV$q{GRIwmk5wUTaI zPKj<^&w^?pE1F~K3_{l~y0WhELE1URYE6NS;p8;#;^$jB*xl)2=}?K=p}@_W(I;w+ zfU*gTRDkHrhv0w@`Rni?$knwyx?Sx)Em}l5YM@yh!_LMGKJX_)IODm?c{&tPQ6zQr zD6zX}$Tg)BJEH7KpxapPc;Ycd^QPUjg>B6Q*PSqoV-Gz9 zjme!Tb7~TnjA5-|1*P(0n=&M21_gw)Mu3UYAr4M3Iol=;hCz*!Vr-O@t~$4!d|frI z&7;^9M~JDYv`|9Cp--uI@a>He&iwjTEE$pkoH$|Vyh=GikyreM6yRWS#xeV$ zIm0+WCgh%Fx|Uun*b5a-DN&_m)=R|->ctR4oL8j_4pRZkN2*x9bPQ*H;;SguM^UYW zc+KVCz`o0hSUy(Aa5=zGjSA-))e^T>DYW&=^!<|Pu-(&2RWH#jRJ34friC;9DG<-;`cUSOSg-~W5bx3 z7_oKb!X=@U!7{&ok^Q#S$P@L9I4F@fa@~u`J3S!jn&6KI?i9!!BPrd-1ZQrq-QUxh z97iZJ^6!{#Vf%&0;?Y)@`a*73!Z$u2mEtHKnQo#?#*~UTvJH=Ho5n+1rtt9gY5accZalbUlJ!a4_q$1~zjqV9@zYnCnW2IbQCleq zY8Yjr@SKD8$K9KzG0LQBtjLQng(@+67s+gik$>NjGS=PtORRm%OEAkZ&0Yy%Qs5W` zTmQ;lG(7nG?k||}1Hd5P794-t6f7%U#KMEOelo4{JfER-xQCO5R zobUp(f=4x}6j_!rx6IQfD%dvN#`dk7@PX^^!g)9S0w2He`?!?&k+0v0OTKgmF8|tX zxc1!F;KMhq$Mx?%9^F*&eXn3!*U-`QV9#0A1SZdt-%IVr_Q%f$_dZ~tpABl8 z135bdR&cZc=@zzcR1BPJx~J@!U5dJCSfL<1!ir2$t0Nd2ZD27^hOyC6j172o?`ml*;~!Y!`u$0Z`i@ut?0d90Se^8Td4qZSoo^N5QMyV;A)2&-CMd*04maX|1vsm~nuBmutIOCtbNg`ZFX*R)9@;RCkPR}v| z>yBgFf^+g_WWBNW1}+nP94%=9%LsGobPV-TxkUfj5!Ge0}|0_~u1#Ws>B)$z_vHxhaEeo5$bg zZ5^!Ke;I!KlMQ&+NiQWsEvDYQ_@vAh&C#hA-ca?PBBJ8D^q82rN)kmF9SU*qyKlhQ zqGf2;hmi83rc~NIlG{dniI(#U2YY=b)(4W*BrA9l(3(nu$e9VL{qCka%{l`1Xzgm1 zn{~)!kAd);>wk@}uKyKo`q8g(`uYF)&vkW3EUrS>wgm}aMv>+`;i+8&YJKdBia>R?#4(ziJ^8*Td{p}mE>Wyphstc~d z5ANS$?-2Y}Fq&EE);CfHyd79wA<;a`D!Bn{&qKCboe&x zsewwzl>@sY*=hn#khRpU7+~IEH6a&ury#+*xhw55m4PWH2O8Gn^;to1tXjrt7hi*u zFZnl|{88d1H?q7Dr(ALaUUA7S_{H5Dam{;9z$I%|BdsmQ&Injk>S58y2)=*kJ#ImQ zx4b~gH!Ef>y00(=bBCb#H<{$S&PaZo2j>CCGe1<}CbHMj0+Z5XADktmbuMbpj}3Nz zpaQ0vE!_JrXXD<_y&W6ZzJvHq!~5303lCp)Ca!$%8vOM|*WpLp3OAp9EDk$pKXkZN zbiDSMOzjC`+?i+&$iH5Q=)Hi=8W(GKpLk`nTMA2h$^-OP+2sb@|MuQO*Wt`)99JODd1!_n1}{TmoC8e&P0&Q5wX@V- zR(wcEAQn;H*!*iLYiC``5Mw)fS!#GaY>Xt_QJo zQ-W7rycQ>Z`Zly14cD5yZUQ@Ng9w~d~ZL7G|Jod!AuSn4q|pvgcW zr~Gs>3NxQ~bo8a8b*M>hEbWl@9<`}I2@vrdk2AtjLZ?GyTf|_cy3X~O&k;Rjyi&%7 ztKN%8cTDm+J%cTsDmv{+Y-j&yt&104cnxm&_D@l&GovfiFH#PLpg!@kA~C{=`j0d$bBoL z7oZ|z->zyg?xRvPi?F#HK{So29Sz*|sWp}g>)h5`+X{vBDX@~2BHILdho?X}S`YET z>wk#djSgz%0%{CsNyM7=1yfqkzUW}9;!KMN_p>G{Soiad*!*Y{Eed??*)PX` z{P-cf;bn(m`N%L@+!AvCh$*m?okShds^ExozJ$f&`=DDLMz=fylq=}*!sXL*9of2} z%E%T2>9rLsQtF zUW#+CxgBf2dpBNr!8K?ybEL!>Z3=JOk+jLHoK`Mxu1)r72lEE!+5D4d=fGWts2$63 zI7r{^>p1L@0P|Lq;}$(&8ifw;@H?mQgO8t#MyrdEH#5Dma_BA`4&5Ae8bJScYA}L9AWchiVI$I z6ej8=3ePyh^+i`Fl4wLUnEn2Uo*>UPi%TB1N4x-DNBnl3{uK)c43Tru&6BWzlC&A+`nVd{-k;f2JjUC=akURrN^^ zVDyd5!gOz8n@1Kc*=n_{%%iL>%qzyXt1aTTh$D{aMEK42-8lWv4#w|4a~c*6RdDt9 zHewND!mc>LA0N0F7oGAvY@%}7JaXHl>DP41blXwKxbgs##d~iiiiykzpEi5Qwt$NP zHYg9K1YIta0jf7J!pa17^hlUir%mCT6vCBKL>?uq%4V~PX4bDZ)mtn(j1?^^0_|CB z-LezE-QGlxYo!dVvz-`+OoaIKsYm0Xt=rIPHs;oK^Rdsd8 zuFfgZE=X*bx2P}R+S0n6{Q9Rx5w>w8Ws21eG$hhuMIO0~-0SXq5F2^wocH4AprdV+ zbZG>gPA<5~TkX!l`B4`5>eUKPzw#E0O)N!Ft|Mh05LX#c^}7Rop(C2gS;&ZckH9B= zIm(*WvBh0lOD*zjFD4W|Y9MIOpwOarCwJn~Q;tS6o<>5I>g#cBAqngi;E^9DxClyk zy+%`EpT*4X&G_g^hoiydgl6J`q)Z0%^;sZ|iV-_s*_EoF!pj51@H_>W_t-^5!jq)l zIH@KcI7hjCi4DD2w^V@>))c@oDxEUKHx*2ttMxiATz4l%#ulSg8$qkS3_)cGagjMe zMY#Y~PCk|2%V6?c^8ia<$&j{yk|4eM2^e5{;9WfKAfzG`MI)Z!FMQfCPXz`XqCgI% z?*h&3C7j79+p?bR~!Gtq|H&EY!0ST(6H8_VwOLkeSnlgioS-oQA}qt+B;g@JzL@;O!O!#kbt5Cu@>3 zS<+fqT3;rZR!J31OzTb&Zea)6D2~r0BDg2lL)Q8e{9r+D5n0lMoig^MPqjNE^@p$~ zA*EpQsO-|sm$$h-H_Mt#5ek~-3H)dAM(BPGo=xN;4yg!flKaQ@u9aDx3+q{^aUN|P z(adDlAp^=S6kt`xZoZ+OJ^D6V+pS@*p;B*!1Qrt*G`%M}58wz5vH-@4Tto(AicN#)*iZ~mu;Cdk z)Xj^Q)v@V!mIvEw^UyT!=aR5T`%b|WCdK#B+?GNKxxj+x`wdk$;^Nm1$4qMH8M-N^ zl0gBIt{&SlPM&0JodR0G5#~Ha{~TDLQlFVosJi|Qj(aSywHJT^&zJ||$;!Qu+1uQK z@iH8ZotBskyO+;?2zG`Ek5i zvg+&nlgn#KZ+$6E?+eZC%}qsz9U5e4ooq9$s&r_58NvK`17FFZmdPtYgbn#DvgT#> z=cX7@Ln)9&hOY2*`>1yDC3zL)J=%Qst5nT^)&7 + + + + + + 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 000000000..fb1a72031 --- /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 000000000..ede75d6d0 --- /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 000000000..5950d0b34 --- /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 000000000..b747ef478 --- /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 000000000..e2d83fd39 --- /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 000000000..59bbbbe33 --- /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 000000000..886089247 --- /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 000000000..98ba467aa --- /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 000000000..39d034e4c --- /dev/null +++ b/agreement/views/res_partner.xml @@ -0,0 +1,19 @@ + + + + res.partner + + + + + + + + + + + + + + + From 7d40232093406d228a1c386791ef117cd434a030 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Tue, 16 Oct 2018 17:20:33 +0530 Subject: [PATCH 2/8] [ENH] OCA Standards --- agreement/README.md | 1 + agreement/__init__.py | 4 +- agreement/__manifest__.py | 53 +- agreement/controllers/__init__.py | 3 - agreement/controllers/controllers.py | 2 - agreement/demo/demo.xml | 30 -- agreement/models/__init__.py | 2 + agreement/models/agreement_clause.py | 90 +++- agreement/models/agreement_increasetype.py | 30 +- agreement/models/agreement_renewaltype.py | 25 +- agreement/models/agreement_section.py | 91 +++- agreement/models/agreement_stage.py | 36 +- agreement/models/agreement_status.py | 17 +- agreement/models/agreement_subtype.py | 22 +- agreement/models/agreement_type.py | 23 +- agreement/models/partner_agreement.py | 528 ++++++++++++++---- agreement/models/product_template.py | 12 +- agreement/models/res_partner.py | 13 +- agreement/security/ir.model.access.csv | 16 +- agreement/security/security.xml | 4 - agreement/views/agreement.xml | 587 ++++++++++----------- agreement/views/agreement_clause.xml | 141 +++-- agreement/views/agreement_increasetype.xml | 74 ++- agreement/views/agreement_renewaltype.xml | 68 ++- agreement/views/agreement_section.xml | 147 +++--- agreement/views/agreement_stages.xml | 70 ++- agreement/views/agreement_subtype.xml | 68 ++- agreement/views/agreement_type.xml | 68 ++- agreement/views/reports.xml | 69 +-- agreement/views/res_partner.xml | 30 +- 30 files changed, 1388 insertions(+), 936 deletions(-) delete mode 100644 agreement/controllers/__init__.py delete mode 100644 agreement/controllers/controllers.py delete mode 100644 agreement/demo/demo.xml delete mode 100644 agreement/security/security.xml diff --git a/agreement/README.md b/agreement/README.md index fe016e1a2..b467cfb2d 100644 --- a/agreement/README.md +++ b/agreement/README.md @@ -24,6 +24,7 @@ Images Contributors * Patrick Wilson +* Bhavesh Odedra Do not contact contributors directly about support or help with technical issues. diff --git a/agreement/__init__.py b/agreement/__init__.py index aa4d0fd63..073035d16 100644 --- a/agreement/__init__.py +++ b/agreement/__init__.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from . import controllers from . import models diff --git a/agreement/__manifest__.py b/agreement/__manifest__.py index 899c540f9..89a4cb906 100644 --- a/agreement/__manifest__.py +++ b/agreement/__manifest__.py @@ -1,31 +1,30 @@ -# -*- coding: utf-8 -*- +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + { - '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' + "name": "Agreements", + "summary": "Manage Agreements, LOI and Contracts", + "author": "Pavlov Media, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/contract", + "category": "Partner", + "license": "AGPL-3", + "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', + "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/ir.model.access.csv", ], - 'demo': [ - 'demo/demo.xml', - ], - 'application': True, + "application": True, } diff --git a/agreement/controllers/__init__.py b/agreement/controllers/__init__.py deleted file mode 100644 index b0f26a9a6..000000000 --- a/agreement/controllers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import controllers diff --git a/agreement/controllers/controllers.py b/agreement/controllers/controllers.py deleted file mode 100644 index b97fd18c9..000000000 --- a/agreement/controllers/controllers.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -from odoo import http diff --git a/agreement/demo/demo.xml b/agreement/demo/demo.xml deleted file mode 100644 index b2d1b70c7..000000000 --- a/agreement/demo/demo.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/agreement/models/__init__.py b/agreement/models/__init__.py index 25f33f611..253dd9d65 100644 --- a/agreement/models/__init__.py +++ b/agreement/models/__init__.py @@ -1,3 +1,5 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from . import partner_agreement from . import agreement_clause from . import agreement_section diff --git a/agreement/models/agreement_clause.py b/agreement/models/agreement_clause.py index 553faa758..765d951fa 100644 --- a/agreement/models/agreement_clause.py +++ b/agreement/models/agreement_clause.py @@ -1,28 +1,80 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from odoo import models, fields, api -#Main Agreement clause Records Model + +# Main Agreement clause Records Model class AgreementClause(models.Model): - _name = 'partner_agreement.clause' - _order = 'clause_sequence' + _name = '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.") + # General + name = fields.Char( + string="Title", + required=True + ) + clause_sequence = fields.Integer( + string="Sequence" + ) + agreement_id = fields.Many2one( + 'agreement', + string="Agreement", + ondelete="cascade" + ) + section_id = fields.Many2one( + '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.") + # 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_id = fields.Many2one( + 'ir.model.fields', + string="Field", + help="Select target field from the related document model. If it is a " + "relationship field you will be able to select a target field at " + "the destination of the relationship." + ) + sub_object_id = fields.Many2one( + 'ir.model', + string="Sub-model", + help="When a relationship field is selected as first field, this " + "field shows the document model the relationship goes to." + ) + sub_model_object_field_id = fields.Many2one( + 'ir.model.fields', + string="Sub-field", + help="When a relationship field is selected as first field, this " + "field lets you select the target field within the destination " + "document model (sub-model)." + ) + 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): + @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 index b83a85a76..1988112bf 100644 --- a/agreement/models/agreement_increasetype.py +++ b/agreement/models/agreement_increasetype.py @@ -1,10 +1,26 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + 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.") +# Main Agreement Increase Type Records Model +class AgreementIncreaseType(models.Model): + _name = '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 index b46d89e7b..f8dfc00a2 100644 --- a/agreement/models/agreement_renewaltype.py +++ b/agreement/models/agreement_renewaltype.py @@ -1,9 +1,22 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + 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.") +# Main Agreement Section Records Model +class AgreementRenewalType(models.Model): + _name = '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 index 87af13083..09c9acdd1 100644 --- a/agreement/models/agreement_section.py +++ b/agreement/models/agreement_section.py @@ -1,27 +1,80 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from odoo import models, fields, api -#Main Agreement Section Records Model + +# Main Agreement Section Records Model class AgreementSection(models.Model): - _name = 'partner_agreement.section' - _order = 'section_sequence' + _name = '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.") + # General + name = fields.Char( + string="Title", + required=True + ) + section_sequence = fields.Integer( + string="Sequence" + ) + agreement_id = fields.Many2one( + 'agreement', + string="Agreement", + ondelete="cascade" + ) + clauses_ids = fields.One2many( + 'agreement.clause', + 'section_id', + 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." + ) - @api.model - def create(self, vals): + # 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_id = fields.Many2one( + 'ir.model.fields', + string="Field", + help="Select target field from the related document model. If it is a " + "relationship field you will be able to select a target field at " + "the destination of the relationship." + ) + sub_object_id = fields.Many2one( + 'ir.model', + string="Sub-model", + help="When a relationship field is selected as first field, this " + "field shows the document model the relationship goes to." + ) + sub_model_object_field_id = fields.Many2one( + 'ir.model.fields', + string="Sub-field", + help="When a relationship field is selected as first field, this " + "field lets you select the target field within the destination " + "document model (sub-model)." + ) + 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 index 1d9674480..beb8dd438 100644 --- a/agreement/models/agreement_stage.py +++ b/agreement/models/agreement_stage.py @@ -1,12 +1,30 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + 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.") +# Main Agreement Section Records Model +class AgreementStage(models.Model): + _name = '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 index e5d95cda5..6d6a190ca 100644 --- a/agreement/models/agreement_status.py +++ b/agreement/models/agreement_status.py @@ -1,8 +1,15 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + 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) +# Main Agreement Status Records Model +class AgreementStatus(models.Model): + _name = 'agreement.type' + + # General + name = fields.Char( + string="Title", + required=True + ) diff --git a/agreement/models/agreement_subtype.py b/agreement/models/agreement_subtype.py index fe95cfe31..1959e02a9 100644 --- a/agreement/models/agreement_subtype.py +++ b/agreement/models/agreement_subtype.py @@ -1,9 +1,19 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + 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") +# Main Agreement Section Records Model +class AgreementSubtype(models.Model): + _name = 'agreement.subtype' + + # General + name = fields.Char( + string="Title", + required=True + ) + agreement_type_id = fields.Many2one( + 'agreement.type', + string="Agreement Type" + ) diff --git a/agreement/models/agreement_type.py b/agreement/models/agreement_type.py index c492a3a70..b87cc4899 100644 --- a/agreement/models/agreement_type.py +++ b/agreement/models/agreement_type.py @@ -1,9 +1,20 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + 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") +# Main Agreement Section Records Model +class AgreementType(models.Model): + _name = 'agreement.type' + + # General + name = fields.Char( + string="Title", + required=True + ) + agreement_subtypes_ids = fields.One2many( + 'agreement.subtype', + 'agreement_type_id', + string="Agreement" + ) diff --git a/agreement/models/partner_agreement.py b/agreement/models/partner_agreement.py index 5a62aed0b..a9b3eb24c 100644 --- a/agreement/models/partner_agreement.py +++ b/agreement/models/partner_agreement.py @@ -1,123 +1,435 @@ +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from odoo import models, fields, api -#Main Agreement Records Model + +# Main Agreement Records Model class Agreement(models.Model): - _name = 'partner_agreement.agreement' - _inherit = ['mail.thread'] + _name = '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') + # 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, + copy=False, + help="The versions are used to keep track of document history and " + "previous versions can be referenced." + ) + revision = fields.Integer( + string="Revision", + default=0, + copy=False, + help="The revision will increase with every save event." + ) + description = fields.Text( + string="Description", + track_visibility='onchange', + help="Description of the agreement" + ) + start_date = fields.Date( + string="Start Date", + track_visibility='onchange', + help="When the agreement starts." + ) + end_date = fields.Date( + string="End Date", + track_visibility='onchange', + help="When the agreement ends." + ) + 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", + track_visibility='onchange', + help="Date the contract was signed by Company." + ) + customer_signed_date = fields.Date( + string="Customer Signed Date", + track_visibility='onchange', + help="Date the contract was signed by Customer." + ) + customer_term = fields.Integer( + string="Customer Term (Months)", + track_visibility='onchange', + help="Number of months this agreement/contract is in effect with " + "customer." + ) + vendor_term = fields.Integer( + string="Vendor Term (Months)", + track_visibility='onchange', + help="Number of months this agreement/contract is in effect with " + "vendor." + ) + expiration_notice = fields.Integer( + string="Exp. Notice (Days)", + track_visibility='onchange', + 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." + ) + 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." + ) + 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", + track_visibility='onchange', + help="ID used for internal contract tracking.") + total_company_mrc = fields.Monetary( + 'Company MRC', + currency_field='currency_id', + help="Total company monthly recurring costs." + ) + 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_id = fields.Many2one( + 'agreement.increasetype', + string="Increase Type", + track_visibility='onchange', + 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." + ) + termination_date = fields.Date( + string="Termination Date", + track_visibility='onchange', + help="Date that the contract was terminated." + ) + customer_address = fields.Char( + related='customer_id.contact_address', + string="Address" + ) + customer_street = fields.Char( + related='customer_id.street', + string="Street" + ) + customer_street2 = fields.Char( + related='customer_id.street2', + string="Street 2" + ) + customer_city = fields.Char( + related='customer_id.city', + string="City" + ) + customer_state_id = fields.Many2one( + related='customer_id.state_id', + string="State" + ) + customer_zip = fields.Char( + related='customer_id.zip', + string="Zip" + ) + vendor_address = fields.Char( + related='vendor_id.contact_address', + string="Address" + ) + vendor_street = fields.Char( + related='vendor_id.street', + string="Street" + ) + vendor_street2 = fields.Char( + related='vendor_id.street2', + string="Street 2" + ) + vendor_city = fields.Char( + related='vendor_id.city', + string="City" + ) + vendor_state_id = fields.Many2one( + related='vendor_id.state_id', + string="State" + ) + vendor_zip = fields.Char( + related='vendor_id.zip', + string="Zip" + ) + reviewed_date = fields.Date( + string="Reviewed Date", + track_visibility='onchange' + ) + reviewed_user_id = fields.Many2one( + 'res.users', + string="Reviewed By", + track_visibility='onchange' + ) + approved_date = fields.Date( + string="Approved Date", + track_visibility='onchange' + ) + approved_user_id = 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") + currency_id = fields.Many2one( + 'res.currency', + string='Currency' + ) + customer_id = fields.Many2one( + 'res.partner', + string="Customer", + copy=True, + help="The customer this agreement is related to (If Applicable)." + ) + vendor_id = fields.Many2one( + 'res.partner', + string="Vendor", + copy=True, + help="The vendor this agreement is related to (If Applicable)." + ) + customer_contact_id = fields.Many2one( + 'res.partner', + string="Customer Contact", + copy=True, + help="The primary customer contact (If Applicable)." + ) + customer_contact_phone = fields.Char( + related='customer_contact_id.phone', + string="Phone" + ) + customer_contact_email = fields.Char( + related='customer_contact_id.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') + vendor_contact_id = fields.Many2one( + 'res.partner', + string="Vendor Contact", + copy=True, + help="The primary vendor contact (If Applicable)." + ) + vendor_contact_phone = fields.Char( + related='vendor_contact_id.phone', + string="Phone" + ) + vendor_contact_email = fields.Char( + related='vendor_contact_id.email', + string="Email" + ) + agreement_type_id = fields.Many2one( + 'agreement.type', + string="Agreement Type", + track_visibility='onchange', + 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." + ) + sale_order_id = fields.Many2one( + 'sale.order', + string="Sales Order", + track_visibility='onchange', + copy=False, + help="Select the Sales Order that this agreement is related to." + ) + payment_term_id = fields.Many2one( + 'account.payment.term', + string="Payment Term", + track_visibility='onchange', + help="Terms of payments." + ) + assigned_user_id = fields.Many2one( + 'res.users', + string="Assigned To", + track_visibility='onchange', + help="Select the user who manages this agreement." + ) + company_signed_user_id = fields.Many2one( + 'res.users', + string="Company Signed By", + track_visibility='onchange', + help="The user at our company who authorized/signed the agreement or " + "contract." + ) + customer_signed_user_id = fields.Many2one( + 'res.partner', + string="Customer Signed By", + track_visibility='onchange', + 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." + ) + renewal_type_id = fields.Many2one( + 'agreement.renewaltype', + string="Renewal Type", + track_visibility='onchange', + help="Describes what happens after the contract expires." + ) - 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') + order_lines_services_ids = fields.One2many( + related='sale_order_id.order_line', + string="Service Order Lines", + copy=False + ) + sections_ids = fields.One2many( + 'agreement.section', + 'agreement_id', + string="Sections", + copy=True + ) + clauses_ids = fields.One2many( + 'agreement.clause', + 'agreement_id', + string="Clauses", + copy=True + ) + previous_version_agreements_ids = fields.One2many( + 'agreement', + 'parent_agreement_id', + string="Child Agreements", + copy=False, + domain=[('active', '=', False)] + ) + child_agreements_ids = fields.One2many( + 'agreement', + 'parent_agreement_id', + string="Child Agreements", + copy=False, + domain=[('active', '=', True)] + ) + products_ids = fields.Many2many( + 'product.template', + string="Products", + copy=False + ) + state = fields.Selection([ + ('draft', 'Draft'), + ('active', 'Active'), + ('inactive', 'Inactive')], + default='draft', + 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)" + ) + 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 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: + # compute total_company_mrc field + @api.depends('order_lines_services_ids', 'sale_order_id') + 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 + # Used for Kanban grouped_by view + @api.model + def _read_group_stage_ids(self, stages, domain, order): + stage_ids = self.env['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.") + stage_id = fields.Many2one( + '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) + # Create New Version Button + @api.multi + def create_new_version(self, vals): + for rec in self: + if not rec.state == 'draft': + # Make sure status is draft + rec.state = 'draft' + default_vals = {'name': '{0} - OLD VERSION'.format(rec.name), + 'active': False, + 'parent_agreement_id': rec.id} + # Make a current copy and mark it as old + rec.copy(default=default_vals) + # Increment the Version + rec.version = rec.version + 1 + # 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} + def create_new_agreement(self): + default_vals = {'name': 'NEW', + 'active': True, + 'version': 1, + 'revision': 0, + 'state': 'draft'} + res = self.copy(default=default_vals) + return {'res_model': '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) + # Increments the revision on each save action + @api.multi + 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 index 1b93eb49f..cfd3516b2 100644 --- a/agreement/models/product_template.py +++ b/agreement/models/product_template.py @@ -1,7 +1,13 @@ -from odoo import models, fields, api +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models, fields + class Product(models.Model): - _inherit = 'product.template' - agreements = fields.Many2many('partner_agreement.agreement', string="Agreements") + agreements_ids = fields.Many2many( + 'agreement', + string="Agreements" + ) diff --git a/agreement/models/res_partner.py b/agreement/models/res_partner.py index a451e455e..61c30d0cb 100644 --- a/agreement/models/res_partner.py +++ b/agreement/models/res_partner.py @@ -1,7 +1,14 @@ -from odoo import models, fields, api +# Copyright (C) 2018 - TODAY, Pavlov Media +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models, fields + class Partner(models.Model): - _inherit = 'res.partner' - agreements = fields.One2many('partner_agreement.agreement', 'name', string="Agreements") + agreements_ids = fields.One2many( + 'agreement', + 'name', + string="Agreements" + ) diff --git a/agreement/security/ir.model.access.csv b/agreement/security/ir.model.access.csv index 670e99a4c..996aeba72 100644 --- a/agreement/security/ir.model.access.csv +++ b/agreement/security/ir.model.access.csv @@ -1,9 +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 +access_agreement_allusers,agreement all users,model_agreement,,1,1,1,1 +access_agreement_section_allusers,section all users,model_agreement_section,,1,1,1,1 +access_agreement_clause_allusers,clause all users,model_agreement_clause,,1,1,1,1 +access_agreement_stage_allusers,stage all users,model_agreement_stage,,1,1,1,1 +access_agreement_type_allusers,type all users,model_agreement_type,,1,1,1,1 +access_agreement_subtype_allusers,subtype all users,model_agreement_subtype,,1,1,1,1 +access_agreement_renewaltype_allusers,renewaltype all users,model_agreement_renewaltype,,1,1,1,1 +access_agreement_increasetype_allusers,increasetype all users,model_agreement_increasetype,,1,1,1,1 diff --git a/agreement/security/security.xml b/agreement/security/security.xml deleted file mode 100644 index c9817ed22..000000000 --- a/agreement/security/security.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/agreement/views/agreement.xml b/agreement/views/agreement.xml index b86878d1b..f05b3b5a0 100644 --- a/agreement/views/agreement.xml +++ b/agreement/views/agreement.xml @@ -1,331 +1,328 @@ + - - - Agreement List - partner_agreement.agreement - - - - - - - - - - - + Agreement List + agreement + + + + + + + + + + + - Agreement Form - partner_agreement.agreement - -
-
-
- -
-
- - - - - - - - - - - - - - - -
- - - - - - + Agreement Form + 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: +
+
+
+ +
- - -
- - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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 Kanban + agreement + + + + + + +
+
+
+
+ + +
+
+ + oe_kanban_text_red +
+ +
+
+
+ +
+
+ - +
+
+
+ V: +
+
+ +
+
+
+
+
+ + + + - Agreement Search - partner_agreement.agreement - - - - - - - - - + Agreement Search + agreement + + + + + + + + + - Order Lines Search - sale.order.line - search - - - - - - + Order Lines Search + sale.order.line + search + + + + + + - Agreements - partner_agreement.agreement - {"search_default_filter_non_template":1} - kanban,tree,form + Agreements + agreement + {"search_default_filter_non_template":1} + kanban,tree,form - Agreements - partner_agreement.agreement - {"search_default_filter_templates":1} - tree,kanban,form + Agreements + agreement + {"search_default_filter_templates":1} + tree,kanban,form - + - + - + - - - - + + + \ No newline at end of file diff --git a/agreement/views/agreement_clause.xml b/agreement/views/agreement_clause.xml index fb1a72031..90082b433 100644 --- a/agreement/views/agreement_clause.xml +++ b/agreement/views/agreement_clause.xml @@ -1,103 +1,102 @@ + - + - agreement_clause_sequencer - agreement.clause - 0 - 1 + agreement_clause_sequencer + agreement.clause + 0 + 1 - Agreement Clause List - partner_agreement.clause - - - - - - - - - - + Agreement Clause List + 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 Form + 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 Search + agreement.clause + + + + + + - Agreement Clause Pivot - partner_agreement.clause - - - - - - - + Agreement Clause Pivot + agreement.clause + + + + + + + Agreement Clauses - partner_agreement.clause + agreement.clause tree,pivot,form - + -
-
+ \ No newline at end of file diff --git a/agreement/views/agreement_increasetype.xml b/agreement/views/agreement_increasetype.xml index ede75d6d0..7620ae196 100644 --- a/agreement/views/agreement_increasetype.xml +++ b/agreement/views/agreement_increasetype.xml @@ -1,53 +1,51 @@ + - - - Agreement Increase Type List - partner_agreement.increasetype - - - - - - - + Agreement Increase Type List + agreement.increasetype + + + + + + + - - Agreement Increase Type Form - partner_agreement.increasetype - -
- -
-
- - - - -
-
-
+ + Agreement Increase Type Form + agreement.increasetype + +
+ +
+
+ + + + +
+
+
- Agreement Increase Type - partner_agreement.increasetype - tree,form + Agreement Increase Type + agreement.increasetype + tree,form -
-
+ name="Increase Types" + id="partner_agreement_increasetype_menu_1" + parent="agreement.partner_agreement_menu_3" + sequence="45" + action="partner_agreement_action_increasetype"/> + \ No newline at end of file diff --git a/agreement/views/agreement_renewaltype.xml b/agreement/views/agreement_renewaltype.xml index 5950d0b34..df762c9a2 100644 --- a/agreement/views/agreement_renewaltype.xml +++ b/agreement/views/agreement_renewaltype.xml @@ -1,51 +1,49 @@ + - - - Agreement Renewal Type List - partner_agreement.renewaltype - - - - - - + Agreement Renewal Type List + agreement.renewaltype + + + + + + - Agreement Renewal Type Form - partner_agreement.renewaltype - -
- -
-
- - - -
-
-
+ Agreement Renewal Type Form + agreement.renewaltype + +
+ +
+
+ + + +
+
+
- Agreement Renewal Type - partner_agreement.renewaltype - tree,form + Agreement Renewal Type + agreement.renewaltype + tree,form -
-
+ name="Renewal Types" + id="partner_agreement_renewaltype_menu_1" + parent="agreement.partner_agreement_menu_3" + sequence="44" + action="partner_agreement_action_renewaltype"/> + \ No newline at end of file diff --git a/agreement/views/agreement_section.xml b/agreement/views/agreement_section.xml index b747ef478..7d7cb290e 100644 --- a/agreement/views/agreement_section.xml +++ b/agreement/views/agreement_section.xml @@ -1,97 +1,96 @@ + - + - agreement_section_sequencer - agreement.section - 0 - 1 + agreement_section_sequencer + agreement.section + 0 + 1 - Agreement Section List - partner_agreement.section - - - - - - - - + Agreement Section List + 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 Form + 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 Section Search + agreement.section + + + + + - Agreement Sections - partner_agreement.section - tree,form + Agreement Sections + agreement.section + tree,form - -
-
+ name="Sections" + id="partner_agreement_sections_menu_1" + parent="agreement.partner_agreement_menu_2" + sequence="31" + action="partner_agreement_action_section"/> + \ No newline at end of file diff --git a/agreement/views/agreement_stages.xml b/agreement/views/agreement_stages.xml index e2d83fd39..11e15b8d9 100644 --- a/agreement/views/agreement_stages.xml +++ b/agreement/views/agreement_stages.xml @@ -1,52 +1,50 @@ + - - - Agreement Stage List - partner_agreement.stage - - - - - - + Agreement Stage List + agreement.stage + + + + + + - Agreement Stage Form - partner_agreement.stage - -
- -
-
- - - - -
-
-
+ Agreement Stage Form + agreement.stage + +
+ +
+
+ + + + +
+
+
- Agreement Stage - partner_agreement.stage - tree,form + Agreement Stage + agreement.stage + tree,form -
-
+ name="Stages" + id="partner_agreement_stage_menu_1" + parent="agreement.partner_agreement_menu_3" + sequence="41" + action="partner_agreement_action_stage"/> + \ No newline at end of file diff --git a/agreement/views/agreement_subtype.xml b/agreement/views/agreement_subtype.xml index 59bbbbe33..0024b91a0 100644 --- a/agreement/views/agreement_subtype.xml +++ b/agreement/views/agreement_subtype.xml @@ -1,51 +1,49 @@ + - - - Agreement Subtype List - partner_agreement.subtype - - - - - - + Agreement Subtype List + agreement.subtype + + + + + + - Agreement Sub Type Form - partner_agreement.subtype - -
- -
-
- - - -
-
-
+ Agreement Sub Type Form + agreement.subtype + +
+ +
+
+ + + +
+
+
- Agreement Sub Type - partner_agreement.subtype - tree,form + Agreement Sub Type + agreement.subtype + tree,form -
-
+ name="Sub-Types" + id="partner_agreement_subtype_menu_1" + parent="agreement.partner_agreement_menu_3" + sequence="43" + action="partner_agreement_action_subtype"/> + \ No newline at end of file diff --git a/agreement/views/agreement_type.xml b/agreement/views/agreement_type.xml index 886089247..21aeb5a45 100644 --- a/agreement/views/agreement_type.xml +++ b/agreement/views/agreement_type.xml @@ -1,51 +1,49 @@ + - - - Agreement Type List - partner_agreement.type - - - - - - + Agreement Type List + agreement.type + + + + + + - Agreement Type Form - partner_agreement.type - -
- -
-
- - - -
-
-
+ Agreement Type Form + agreement.type + +
+ +
+
+ + + +
+
+
- Agreement Type - partner_agreement.type - tree,form + Agreement Type + agreement.type + tree,form -
-
+ name="Types" + id="partner_agreement_type_menu_1" + parent="agreement.partner_agreement_menu_3" + sequence="42" + action="partner_agreement_action_type"/> + \ No newline at end of file diff --git a/agreement/views/reports.xml b/agreement/views/reports.xml index 98ba467aa..46de46b05 100644 --- a/agreement/views/reports.xml +++ b/agreement/views/reports.xml @@ -1,48 +1,49 @@ + + - + \ No newline at end of file diff --git a/agreement/views/res_partner.xml b/agreement/views/res_partner.xml index 39d034e4c..9c3d08ecd 100644 --- a/agreement/views/res_partner.xml +++ b/agreement/views/res_partner.xml @@ -1,19 +1,17 @@ + - - res.partner - - - - - - - - - - - - - - + + res.partner + + + + + + + + + + + From 98af456370e3b1800167171811784ca92c75f310 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 16 Oct 2018 10:43:44 -0500 Subject: [PATCH 3/8] [IMP] Documentation --- agreement/README.md | 31 ------------------------------- agreement/README.rst | 21 +++++++++++++++++++++ agreement/__manifest__.py | 6 +++++- agreement/readme/CONFIGURE.rst | 6 ++++++ agreement/readme/CONTRIBUTORS.rst | 4 ++++ agreement/readme/CREDITS.rst | 4 ++++ agreement/readme/DESCRIPTION.rst | 9 +++++++++ agreement/readme/USAGE.rst | 7 +++++++ 8 files changed, 56 insertions(+), 32 deletions(-) delete mode 100644 agreement/README.md create mode 100644 agreement/README.rst create mode 100644 agreement/readme/CONFIGURE.rst create mode 100644 agreement/readme/CONTRIBUTORS.rst create mode 100644 agreement/readme/CREDITS.rst create mode 100644 agreement/readme/DESCRIPTION.rst create mode 100644 agreement/readme/USAGE.rst diff --git a/agreement/README.md b/agreement/README.md deleted file mode 100644 index b467cfb2d..000000000 --- a/agreement/README.md +++ /dev/null @@ -1,31 +0,0 @@ -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 -* Bhavesh Odedra - -Do not contact contributors directly about support or help with technical issues. - -Maintainer diff --git a/agreement/README.rst b/agreement/README.rst new file mode 100644 index 000000000..21cd7854d --- /dev/null +++ b/agreement/README.rst @@ -0,0 +1,21 @@ +**This file is going to be generated by oca-gen-addon-readme.** + +*Manual changes will be overwritten.* + +Please provide content in the ``readme`` directory: + +* **DESCRIPTION.rst** (required) +* INSTALL.rst (optional) +* CONFIGURE.rst (optional) +* **USAGE.rst** (optional, highly recommended) +* DEVELOP.rst (optional) +* ROADMAP.rst (optional) +* HISTORY.rst (optional, recommended) +* **CONTRIBUTORS.rst** (optional, highly recommended) +* CREDITS.rst (optional) + +Content of this README will also be drawn from the addon manifest, +from keys such as name, authors, maintainers, development_status, +and license. + +A good, one sentence summary in the manifest is also highly recommended. diff --git a/agreement/__manifest__.py b/agreement/__manifest__.py index 89a4cb906..11fd01662 100644 --- a/agreement/__manifest__.py +++ b/agreement/__manifest__.py @@ -4,7 +4,9 @@ { "name": "Agreements", "summary": "Manage Agreements, LOI and Contracts", - "author": "Pavlov Media, Odoo Community Association (OCA)", + "author": "Pavlov Media, " + "Open Source Integrators, " + "Odoo Community Association (OCA)", "website": "https://github.com/OCA/contract", "category": "Partner", "license": "AGPL-3", @@ -27,4 +29,6 @@ "security/ir.model.access.csv", ], "application": True, + "development_status": "Beta", + "maintainers": "max3903", } diff --git a/agreement/readme/CONFIGURE.rst b/agreement/readme/CONFIGURE.rst new file mode 100644 index 000000000..3871fc34e --- /dev/null +++ b/agreement/readme/CONFIGURE.rst @@ -0,0 +1,6 @@ +To configure this module: + +* Go to Agreement > Configuration > Templates +* Create a new template with sections and clauses and their respective content +* Go to Agreement > Configuration > Stages +* Create and reorder stages to match your process diff --git a/agreement/readme/CONTRIBUTORS.rst b/agreement/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..94d667e1c --- /dev/null +++ b/agreement/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Patrick Wilson +* Bhavesh Odedra +* Wolfgang Hall +* Maxime Chambreuil \ No newline at end of file diff --git a/agreement/readme/CREDITS.rst b/agreement/readme/CREDITS.rst new file mode 100644 index 000000000..b4198038d --- /dev/null +++ b/agreement/readme/CREDITS.rst @@ -0,0 +1,4 @@ +The development of this module has been financially supported by: + +* Pavlov Media +* Open Source Integrators \ No newline at end of file diff --git a/agreement/readme/DESCRIPTION.rst b/agreement/readme/DESCRIPTION.rst new file mode 100644 index 000000000..0680b36cf --- /dev/null +++ b/agreement/readme/DESCRIPTION.rst @@ -0,0 +1,9 @@ +This module allows you to manage agreements, letter of intent and contract content. +The module is meant to be used by the legal team of a company and to allow them +to define sections, clauses and templates with their respective content that can +be dynamic. + +Based on the template, an agreement can be created and the pdf document generated. + +The agreement would go through a workflow to finally become a contract with the +customer signature. diff --git a/agreement/readme/USAGE.rst b/agreement/readme/USAGE.rst new file mode 100644 index 000000000..cae6e70e9 --- /dev/null +++ b/agreement/readme/USAGE.rst @@ -0,0 +1,7 @@ +To use this module: + +* Go to Agreement > Agrements +* Create a new agreement +* Select a template +* Follow the process to get the required approval +* Send the invitation to the customer to review and sign the agreement \ No newline at end of file From 91bb5c8eaaa62fb358f7ef8c32f33cf1389aec6f Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 16 Oct 2018 11:12:34 -0500 Subject: [PATCH 4/8] [ADD] Roadmap --- agreement/__manifest__.py | 5 ++++- agreement/readme/ROADMAP.rst | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 agreement/readme/ROADMAP.rst diff --git a/agreement/__manifest__.py b/agreement/__manifest__.py index 11fd01662..2e524d5dc 100644 --- a/agreement/__manifest__.py +++ b/agreement/__manifest__.py @@ -12,8 +12,11 @@ "license": "AGPL-3", "version": "11.0.0.0.1", "depends": [ + "account", + "contacts", "mail", - "sale_management" + "product", + "sale_management", ], "data": [ "views/reports.xml", diff --git a/agreement/readme/ROADMAP.rst b/agreement/readme/ROADMAP.rst new file mode 100644 index 000000000..58ac79c67 --- /dev/null +++ b/agreement/readme/ROADMAP.rst @@ -0,0 +1,3 @@ +* Split the module to remove the dependencies on sale and account and provide + the same feature in extra modules (agreement_sale, agreement_account, + agreement_purchase) From 6a50096a99d99e8d2b02f270366ea41e9880caac Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 16 Oct 2018 12:22:47 -0500 Subject: [PATCH 5/8] [IMP] Menu and groups --- agreement/__manifest__.py | 5 +- agreement/data/module_category.xml | 9 ++ .../{partner_agreement.py => agreement.py} | 0 agreement/security/ir.model.access.csv | 24 +++-- agreement/security/res_groups.xml | 19 ++++ agreement/views/agreement.xml | 32 +----- agreement/views/agreement_clause.xml | 9 +- agreement/views/agreement_increasetype.xml | 9 +- agreement/views/agreement_renewaltype.xml | 9 +- agreement/views/agreement_section.xml | 9 +- agreement/views/agreement_stages.xml | 9 +- agreement/views/agreement_subtype.xml | 9 +- agreement/views/agreement_type.xml | 9 +- agreement/views/menu.xml | 101 ++++++++++++++++++ 14 files changed, 157 insertions(+), 96 deletions(-) create mode 100644 agreement/data/module_category.xml rename agreement/models/{partner_agreement.py => agreement.py} (100%) create mode 100644 agreement/security/res_groups.xml create mode 100644 agreement/views/menu.xml diff --git a/agreement/__manifest__.py b/agreement/__manifest__.py index 2e524d5dc..cc43e2fcd 100644 --- a/agreement/__manifest__.py +++ b/agreement/__manifest__.py @@ -19,6 +19,9 @@ "sale_management", ], "data": [ + "data/module_category.xml", + "security/res_groups.xml", + "security/ir.model.access.csv", "views/reports.xml", "views/agreement.xml", "views/agreement_clause.xml", @@ -29,7 +32,7 @@ "views/agreement_renewaltype.xml", "views/agreement_increasetype.xml", "views/res_partner.xml", - "security/ir.model.access.csv", + "views/menu.xml", ], "application": True, "development_status": "Beta", diff --git a/agreement/data/module_category.xml b/agreement/data/module_category.xml new file mode 100644 index 000000000..d3c2ee7a7 --- /dev/null +++ b/agreement/data/module_category.xml @@ -0,0 +1,9 @@ + + + + + Agreement + 80 + + + diff --git a/agreement/models/partner_agreement.py b/agreement/models/agreement.py similarity index 100% rename from agreement/models/partner_agreement.py rename to agreement/models/agreement.py diff --git a/agreement/security/ir.model.access.csv b/agreement/security/ir.model.access.csv index 996aeba72..13b3a0ed6 100644 --- a/agreement/security/ir.model.access.csv +++ b/agreement/security/ir.model.access.csv @@ -1,9 +1,17 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_agreement_allusers,agreement all users,model_agreement,,1,1,1,1 -access_agreement_section_allusers,section all users,model_agreement_section,,1,1,1,1 -access_agreement_clause_allusers,clause all users,model_agreement_clause,,1,1,1,1 -access_agreement_stage_allusers,stage all users,model_agreement_stage,,1,1,1,1 -access_agreement_type_allusers,type all users,model_agreement_type,,1,1,1,1 -access_agreement_subtype_allusers,subtype all users,model_agreement_subtype,,1,1,1,1 -access_agreement_renewaltype_allusers,renewaltype all users,model_agreement_renewaltype,,1,1,1,1 -access_agreement_increasetype_allusers,increasetype all users,model_agreement_increasetype,,1,1,1,1 +access_agreement_allusers,agreement all users,model_agreement,agreement.group_agreement_user,1,1,1,0 +access_agreement_allusers,agreement all users,model_agreement,agreement.group_agreement_manager,1,1,1,1 +access_agreement_section_allusers,section all users,model_agreement_section,agreement.group_agreement_user,1,1,1,0 +access_agreement_section_allusers,section all users,model_agreement_section,agreement.group_agreement_manager,1,1,1,1 +access_agreement_clause_allusers,clause all users,model_agreement_clause,agreement.group_agreement_user,1,1,1,0 +access_agreement_clause_allusers,clause all users,model_agreement_clause,agreement.group_agreement_manager,1,1,1,1 +access_agreement_stage_allusers,stage all users,model_agreement_stage,agreement.group_agreement_user,1,0,0,0 +access_agreement_stage_allusers,stage all users,model_agreement_stage,agreement.group_agreement_manager,1,1,1,1 +access_agreement_type_allusers,type all users,model_agreement_type,agreement.group_agreement_user,1,0,0,0 +access_agreement_type_allusers,type all users,model_agreement_type,agreement.group_agreement_manager,1,1,1,1 +access_agreement_subtype_allusers,subtype all users,model_agreement_subtype,agreement.group_agreement_user,1,0,0,0 +access_agreement_subtype_allusers,subtype all users,model_agreement_subtype,agreement.group_agreement_manager,1,1,1,1 +access_agreement_renewaltype_allusers,renewaltype all users,model_agreement_renewaltype,agreement.group_agreement_user,1,0,0,0 +access_agreement_renewaltype_allusers,renewaltype all users,model_agreement_renewaltype,agreement.group_agreement_manager,1,1,1,1 +access_agreement_increasetype_allusers,increasetype all users,model_agreement_increasetype,agreement.group_agreement_user,1,0,0,0 +access_agreement_increasetype_allusers,increasetype all users,model_agreement_increasetype,agreement.group_agreement_manager,1,1,1,1 diff --git a/agreement/security/res_groups.xml b/agreement/security/res_groups.xml new file mode 100644 index 000000000..a0917b7bc --- /dev/null +++ b/agreement/security/res_groups.xml @@ -0,0 +1,19 @@ + + + + + + User + + + + + + + Manager + + + + + + diff --git a/agreement/views/agreement.xml b/agreement/views/agreement.xml index f05b3b5a0..2b42591fc 100644 --- a/agreement/views/agreement.xml +++ b/agreement/views/agreement.xml @@ -295,34 +295,4 @@ tree,kanban,form - - - - - - - - - \ No newline at end of file + diff --git a/agreement/views/agreement_clause.xml b/agreement/views/agreement_clause.xml index 90082b433..c25cc404d 100644 --- a/agreement/views/agreement_clause.xml +++ b/agreement/views/agreement_clause.xml @@ -92,11 +92,4 @@ tree,pivot,form - - - \ No newline at end of file + diff --git a/agreement/views/agreement_increasetype.xml b/agreement/views/agreement_increasetype.xml index 7620ae196..d28cfd8d1 100644 --- a/agreement/views/agreement_increasetype.xml +++ b/agreement/views/agreement_increasetype.xml @@ -41,11 +41,4 @@ tree,form - - - \ No newline at end of file + diff --git a/agreement/views/agreement_renewaltype.xml b/agreement/views/agreement_renewaltype.xml index df762c9a2..31fa13238 100644 --- a/agreement/views/agreement_renewaltype.xml +++ b/agreement/views/agreement_renewaltype.xml @@ -39,11 +39,4 @@ tree,form - - - \ No newline at end of file + diff --git a/agreement/views/agreement_section.xml b/agreement/views/agreement_section.xml index 7d7cb290e..3e3e5f51a 100644 --- a/agreement/views/agreement_section.xml +++ b/agreement/views/agreement_section.xml @@ -86,11 +86,4 @@ tree,form - - - \ No newline at end of file + diff --git a/agreement/views/agreement_stages.xml b/agreement/views/agreement_stages.xml index 11e15b8d9..66f7b094f 100644 --- a/agreement/views/agreement_stages.xml +++ b/agreement/views/agreement_stages.xml @@ -40,11 +40,4 @@ tree,form - - - \ No newline at end of file + diff --git a/agreement/views/agreement_subtype.xml b/agreement/views/agreement_subtype.xml index 0024b91a0..e6b8ba656 100644 --- a/agreement/views/agreement_subtype.xml +++ b/agreement/views/agreement_subtype.xml @@ -39,11 +39,4 @@ tree,form - - - \ No newline at end of file + diff --git a/agreement/views/agreement_type.xml b/agreement/views/agreement_type.xml index 21aeb5a45..2e4d8b729 100644 --- a/agreement/views/agreement_type.xml +++ b/agreement/views/agreement_type.xml @@ -39,11 +39,4 @@ tree,form - - - \ No newline at end of file + diff --git a/agreement/views/menu.xml b/agreement/views/menu.xml new file mode 100644 index 000000000..6e69cbeb8 --- /dev/null +++ b/agreement/views/menu.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b89e68712c1490309be23ccf9667977003853995 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 16 Oct 2018 14:14:59 -0500 Subject: [PATCH 6/8] [IMP] Menu and report --- agreement/__manifest__.py | 1 + agreement/models/__init__.py | 23 +++-- agreement/models/res_config_settings.py | 8 ++ agreement/views/agreement.xml | 122 ++++++++++++++---------- agreement/views/menu.xml | 16 +++- agreement/views/reports.xml | 37 +++---- agreement/views/res_config_settings.xml | 28 ++++++ 7 files changed, 153 insertions(+), 82 deletions(-) create mode 100644 agreement/models/res_config_settings.py create mode 100644 agreement/views/res_config_settings.xml diff --git a/agreement/__manifest__.py b/agreement/__manifest__.py index cc43e2fcd..0d2c31a5f 100644 --- a/agreement/__manifest__.py +++ b/agreement/__manifest__.py @@ -22,6 +22,7 @@ "data/module_category.xml", "security/res_groups.xml", "security/ir.model.access.csv", + 'views/res_config_settings.xml', "views/reports.xml", "views/agreement.xml", "views/agreement_clause.xml", diff --git a/agreement/models/__init__.py b/agreement/models/__init__.py index 253dd9d65..faf7817b0 100644 --- a/agreement/models/__init__.py +++ b/agreement/models/__init__.py @@ -1,12 +1,15 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -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 +from . import ( + res_config_settings, + agreement, + agreement_clause, + agreement_section, + agreement_stage, + agreement_type, + agreement_subtype, + res_partner, + product_template, + agreement_renewaltype, + agreement_increasetype, +) diff --git a/agreement/models/res_config_settings.py b/agreement/models/res_config_settings.py new file mode 100644 index 000000000..2c78a5f1b --- /dev/null +++ b/agreement/models/res_config_settings.py @@ -0,0 +1,8 @@ +# Copyright (C) 2018 - TODAY, Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' diff --git a/agreement/views/agreement.xml b/agreement/views/agreement.xml index 2b42591fc..dc7537712 100644 --- a/agreement/views/agreement.xml +++ b/agreement/views/agreement.xml @@ -27,7 +27,7 @@
@@ -37,36 +37,43 @@
- - - - - - - + + + + + + + - + - +
- - - - - - +
- +
- - - - - - +
@@ -82,8 +89,8 @@ - - + + @@ -99,22 +106,14 @@ - + - +
- - - - - - - - @@ -133,6 +132,16 @@
+ + + + + + + + + + @@ -143,10 +152,10 @@ - + - + @@ -168,16 +177,16 @@ -

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

+

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

Perhaps include invoices with total vs costs?

- - - - - + + + + +
Version: . @@ -237,14 +246,14 @@
- V: -
-
- + V: +
+
+ +
-
-
+
@@ -281,17 +290,24 @@ - + Agreements agreement - {"search_default_filter_non_template":1} + [('is_template', '=', False)] kanban,tree,form - + Agreements agreement - {"search_default_filter_templates":1} + [('is_template', '=', False)] + tree,form + + + + Templates + agreement + [('is_template', '=', True)] tree,kanban,form diff --git a/agreement/views/menu.xml b/agreement/views/menu.xml index 6e69cbeb8..59ac12b88 100644 --- a/agreement/views/menu.xml +++ b/agreement/views/menu.xml @@ -15,6 +15,12 @@ id="agreement_dashboard" parent="agreement_root" sequence="10"/> + + action="agreement_operations_agreement"/> + - + + id="partner_agreement_contract_document_preview" + model="agreement" + string="Contract Document Preview" + name="agreement.report_agreement_document" + file="agreement.report_agreement_document" + report_type="qweb-html"/>