diff --git a/agreement/models/agreement.py b/agreement/models/agreement.py index 6df4e1588..0eae3eece 100644 --- a/agreement/models/agreement.py +++ b/agreement/models/agreement.py @@ -10,11 +10,11 @@ class Agreement(models.Model): _description = 'Agreement' _inherit = ["mail.thread", "mail.activity.mixin"] - code = fields.Char(required=True) - name = fields.Char(required=True) + code = fields.Char(required=True, track_visibility='onchange') + name = fields.Char(required=True, track_visibility='onchange') partner_id = fields.Many2one( 'res.partner', string='Partner', ondelete='restrict', - domain=[('parent_id', '=', False)]) + domain=[('parent_id', '=', False)], track_visibility='onchange') company_id = fields.Many2one( 'res.company', string='Company', default=lambda self: self.env['res.company']._company_default_get()) @@ -30,10 +30,25 @@ class Agreement(models.Model): string="Agreement Type", help="Select the type of agreement", ) + domain = fields.Selection( + '_domain_selection', string='Domain', default='sale', + track_visibility='onchange') active = fields.Boolean(default=True) - signature_date = fields.Date() - start_date = fields.Date() - end_date = fields.Date() + signature_date = fields.Date(track_visibility='onchange') + start_date = fields.Date(track_visibility='onchange') + end_date = fields.Date(track_visibility='onchange') + + @api.model + def _domain_selection(self): + return [ + ('sale', _('Sale')), + ('purchase', _('Purchase')), + ] + + @api.onchange('agreement_type_id') + def agreement_type_change(self): + if self.agreement_type_id and self.agreement_type_id.domain: + self.domain = self.agreement_type_id.domain def name_get(self): res = [] diff --git a/agreement/models/agreement_type.py b/agreement/models/agreement_type.py index a35a64826..8074b5262 100644 --- a/agreement/models/agreement_type.py +++ b/agreement/models/agreement_type.py @@ -1,7 +1,7 @@ # Copyright (C) 2018 - TODAY, Pavlov Media # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import api, fields, models class AgreementType(models.Model): @@ -10,3 +10,9 @@ class AgreementType(models.Model): name = fields.Char(string="Name", required=True) active = fields.Boolean(default=True) + domain = fields.Selection( + '_domain_selection', string='Domain', default='sale') + + @api.model + def _domain_selection(self): + return self.env['agreement']._domain_selection() diff --git a/agreement/views/agreement.xml b/agreement/views/agreement.xml index 1c110ee5a..bb6b8925b 100644 --- a/agreement/views/agreement.xml +++ b/agreement/views/agreement.xml @@ -20,20 +20,26 @@ options='{"terminology": "archive"}'/> +
+
- - + - - + + + + - @@ -61,6 +67,7 @@ + @@ -74,12 +81,17 @@ + + + + diff --git a/agreement/views/agreement_type.xml b/agreement/views/agreement_type.xml index 1ca06a478..b801260ee 100644 --- a/agreement/views/agreement_type.xml +++ b/agreement/views/agreement_type.xml @@ -7,6 +7,7 @@ + @@ -29,6 +30,9 @@ @@ -40,7 +44,14 @@ + + + + + + + diff --git a/agreement_account/__init__.py b/agreement_account/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/agreement_account/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/agreement_account/__manifest__.py b/agreement_account/__manifest__.py new file mode 100644 index 000000000..d70831428 --- /dev/null +++ b/agreement_account/__manifest__.py @@ -0,0 +1,28 @@ +# Copyright 2017-2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Agreement Account', + 'summary': "Agreement on invoices", + 'version': '12.0.1.0.0', + 'category': 'Contract', + 'author': 'Akretion, Odoo Community Association (OCA)', + 'website': 'https://github.com/OCA/contract', + 'license': 'AGPL-3', + 'depends': [ + 'agreement', + 'account', + ], + 'data': [ + 'security/ir.model.access.csv', + 'views/agreement.xml', + 'views/account_invoice.xml', + ], + 'development_status': 'Beta', + 'maintainers': [ + 'alexis-via', + 'bealdav', + ], + 'installable': True, +} diff --git a/agreement_account/models/__init__.py b/agreement_account/models/__init__.py new file mode 100644 index 000000000..720f31c8b --- /dev/null +++ b/agreement_account/models/__init__.py @@ -0,0 +1,2 @@ +from . import agreement +from . import account_invoice diff --git a/agreement_account/models/account_invoice.py b/agreement_account/models/account_invoice.py new file mode 100644 index 000000000..a6bdc4122 --- /dev/null +++ b/agreement_account/models/account_invoice.py @@ -0,0 +1,15 @@ +# Copyright 2017-2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + agreement_id = fields.Many2one( + comodel_name='agreement', string='Agreement', ondelete='restrict', + track_visibility='onchange', readonly=True, copy=False, + states={'draft': [('readonly', False)]}) diff --git a/agreement_account/models/agreement.py b/agreement_account/models/agreement.py new file mode 100644 index 000000000..ddbc4ef42 --- /dev/null +++ b/agreement_account/models/agreement.py @@ -0,0 +1,36 @@ +# Copyright 2017-2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class Agreement(models.Model): + _inherit = 'agreement' + + invoice_ids = fields.One2many( + 'account.invoice', 'agreement_id', string='Invoices', readonly=True) + out_invoice_count = fields.Integer( + compute='_compute_invoice_count', string='# of Customer Invoices') + in_invoice_count = fields.Integer( + compute='_compute_invoice_count', string='# of Vendor Bills') + + def _compute_invoice_count(self): + base_domain = [ + ('agreement_id', 'in', self.ids), + ('state', 'not in', ('draft', 'cancel'))] + aio = self.env['account.invoice'] + out_rg_res = aio.read_group( + base_domain + [('type', 'in', ('out_invoice', 'out_refund'))], + ['agreement_id'], ['agreement_id']) + out_data = dict( + [(x['agreement_id'][0], x['agreement_id_count']) for x in out_rg_res]) + in_rg_res = aio.read_group( + base_domain + [('type', 'in', ('in_invoice', 'in_refund'))], + ['agreement_id'], ['agreement_id']) + in_data = dict( + [(x['agreement_id'][0], x['agreement_id_count']) for x in in_rg_res]) + for agreement in self: + agreement.out_invoice_count = out_data.get(agreement.id, 0) + agreement.in_invoice_count = in_data.get(agreement.id, 0) diff --git a/agreement_account/readme/CONTRIBUTORS.rst b/agreement_account/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..ff65d68ce --- /dev/null +++ b/agreement_account/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Alexis de Lattre diff --git a/agreement_account/readme/DESCRIPTION.rst b/agreement_account/readme/DESCRIPTION.rst new file mode 100644 index 000000000..18e63adc3 --- /dev/null +++ b/agreement_account/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module adds *Agreement* field on invoices. diff --git a/agreement_account/security/ir.model.access.csv b/agreement_account/security/ir.model.access.csv new file mode 100644 index 000000000..c1b7f487c --- /dev/null +++ b/agreement_account/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_agreement_full,Full access on agreement to Financial mgr,agreement.model_agreement,account.group_account_manager,1,1,1,1 +access_agreement_type_full,Full access on agreement type to Financial mgr,agreement.model_agreement_type,account.group_account_manager,1,1,1,1 diff --git a/agreement_account/static/description/icon.png b/agreement_account/static/description/icon.png new file mode 100644 index 000000000..a99cce6be Binary files /dev/null and b/agreement_account/static/description/icon.png differ diff --git a/agreement_account/static/description/index.html b/agreement_account/static/description/index.html new file mode 100644 index 000000000..198c00cdc --- /dev/null +++ b/agreement_account/static/description/index.html @@ -0,0 +1,430 @@ + + + + + + +Agreement Sale + + + +
+

Agreement Sale

+ + +

Beta License: AGPL-3 OCA/contract Translate me on Weblate Try me on Runbot

+

This module adds Agreement field to Sales Orders

+

Table of contents

+ +
+

Known issues / Roadmap

+

Features to evaluate before implementation

+
    +
  • add smart button on agreement to access implied sales
  • +
  • add module agreement_account: agreement_sale’ll depends on it
  • +
+
+
+

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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainers:

+

alexis-via bealdav

+

This module is part of the OCA/contract project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/agreement_account/views/account_invoice.xml b/agreement_account/views/account_invoice.xml new file mode 100644 index 000000000..891ca4f05 --- /dev/null +++ b/agreement_account/views/account_invoice.xml @@ -0,0 +1,54 @@ + + + + + + + + agreement.customer.invoice.form + account.invoice + + + + + + + + + + + agreement.supplier.invoice.form + account.invoice + + + + + + + + + + agreement.account.invoice.search + account.invoice + + + + + + + + + + + + + diff --git a/agreement_account/views/agreement.xml b/agreement_account/views/agreement.xml new file mode 100644 index 000000000..36104570a --- /dev/null +++ b/agreement_account/views/agreement.xml @@ -0,0 +1,61 @@ + + + + + + + 150 + + + + + + Vendor Bills + account.invoice + tree,form + [('type','in', ('in_invoice', 'in_refund')), ('state', 'not in', ('draft', 'cancel'))] + {'default_type': 'in_invoice', 'type': 'in_invoice', 'journal_type': 'purchase'} + + + + + tree + + + + + + + form + + + + + + invoice.button.agreement.form + agreement + + +
+ + + +
+
+
+ +
diff --git a/agreement_sale/__manifest__.py b/agreement_sale/__manifest__.py index 9ee05c394..0392f15f5 100644 --- a/agreement_sale/__manifest__.py +++ b/agreement_sale/__manifest__.py @@ -12,7 +12,8 @@ 'license': 'AGPL-3', 'depends': [ 'sale_management', - 'agreement', + 'agreement_account', + 'sale_commercial_partner', ], 'data': [ 'security/ir.model.access.csv', diff --git a/agreement_sale/models/__init__.py b/agreement_sale/models/__init__.py index 534c392d2..9576a5f73 100644 --- a/agreement_sale/models/__init__.py +++ b/agreement_sale/models/__init__.py @@ -1,2 +1,3 @@ +from . import agreement from . import sale from . import res_config_settings diff --git a/agreement_sale/models/agreement.py b/agreement_sale/models/agreement.py new file mode 100644 index 000000000..1f6d435f5 --- /dev/null +++ b/agreement_sale/models/agreement.py @@ -0,0 +1,27 @@ +# Copyright 2017-2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class Agreement(models.Model): + _inherit = 'agreement' + + sale_ids = fields.One2many( + 'sale.order', 'agreement_id', string='Sale Orders', readonly=True) + sale_count = fields.Integer( + compute='_compute_sale_count', string='# of Sale Orders') + + def _compute_sale_count(self): + rg_res = self.env['sale.order'].read_group( + [ + ('agreement_id', 'in', self.ids), + ('state', 'not in', ('draft', 'sent', 'cancel')), + ], + ['agreement_id'], ['agreement_id']) + mapped_data = dict( + [(x['agreement_id'][0], x['agreement_id_count']) for x in rg_res]) + for agreement in self: + agreement.sale_count = mapped_data.get(agreement.id, 0) diff --git a/agreement_sale/models/sale.py b/agreement_sale/models/sale.py index bf97d9de2..5c2a9a1a5 100644 --- a/agreement_sale/models/sale.py +++ b/agreement_sale/models/sale.py @@ -1,4 +1,5 @@ -# © 2017 Akretion (Alexis de Lattre ) +# Copyright 2017-2020 Akretion France +# @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -18,3 +19,8 @@ class SaleOrder(models.Model): ondelete="restrict", track_visibility='onchange', readonly=True, copy=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}) + + def _prepare_invoice(self): + vals = super()._prepare_invoice() + vals['agreement_id'] = self.agreement_id.id or False + return vals diff --git a/agreement_sale/readme/DESCRIPTION.rst b/agreement_sale/readme/DESCRIPTION.rst index 3f0417552..c78e1a42b 100644 --- a/agreement_sale/readme/DESCRIPTION.rst +++ b/agreement_sale/readme/DESCRIPTION.rst @@ -1 +1 @@ -This module adds *Agreement* field to Sales Orders +This module adds *Agreement* field to Sales Orders. Upon invoice creation, that field is copied to the invoice. diff --git a/agreement_sale/security/ir.model.access.csv b/agreement_sale/security/ir.model.access.csv index f6e188f41..7494f7f2e 100644 --- a/agreement_sale/security/ir.model.access.csv +++ b/agreement_sale/security/ir.model.access.csv @@ -1,4 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink agreement.access_agreement_full,Full access on agreement grp,agreement.model_agreement,sales_team.group_sale_manager,1,1,1,1 agreement_sale.access_agreement_type_full,Full access on agreement type grp,agreement.model_agreement_type,sales_team.group_sale_manager,1,1,1,1 -agreement_sale.access_agreement_type_read,Read access on agreement grp,agreement.model_agreement_type,base.group_user,1,0,0,0 diff --git a/agreement_sale/views/agreement.xml b/agreement_sale/views/agreement.xml index cc30d5ce8..d7a40c22b 100644 --- a/agreement_sale/views/agreement.xml +++ b/agreement_sale/views/agreement.xml @@ -2,9 +2,32 @@ - - + + + 150 + + + + + + + sale.button.agreement.form + agreement + + +
+ +
+
+
diff --git a/agreement_sale/views/sale_order.xml b/agreement_sale/views/sale_order.xml index e7e5b5ea4..fbd2dc4c8 100644 --- a/agreement_sale/views/sale_order.xml +++ b/agreement_sale/views/sale_order.xml @@ -6,7 +6,9 @@ - + + + agreement.sale.order.search + sale.order + + + + + + + + + + + diff --git a/oca_dependencies.txt b/oca_dependencies.txt index ff045117f..915dd1d8b 100644 --- a/oca_dependencies.txt +++ b/oca_dependencies.txt @@ -4,3 +4,4 @@ field-service sale-reporting account-invoicing account-closing +sale-workflow