diff --git a/contract_invoice_merge_by_partner/README.rst b/contract_invoice_merge_by_partner/README.rst new file mode 100644 index 00000000..62a31b8d --- /dev/null +++ b/contract_invoice_merge_by_partner/README.rst @@ -0,0 +1,61 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +================================= +Contract Invoice Merge By Partner +================================= + +This module merges same partner invoices generated by contracts. + +Installation +============ + +To install this module you need *account_invoice_merge*, available in: + +* Install repository `OCA/account-invoicing `_. + +Usage +===== + +#. Go to *Sales > Contracts* and create some contracts with same partner +#. Go to *Settings > Automation > Scheduled Actions* +#. Select *Generate Recurring Invoices from Contracts* +#. Set previous time that now in *Next Execution Date* +#. Go to *Invoicing > Customer Invoices* and show merged invoice + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/95/8.0 + + +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 +======= + +Contributors +------------ +* Carlos Dauden +* Pedro M. Baeza + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +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. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/contract_invoice_merge_by_partner/__init__.py b/contract_invoice_merge_by_partner/__init__.py new file mode 100644 index 00000000..cfa84f54 --- /dev/null +++ b/contract_invoice_merge_by_partner/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models diff --git a/contract_invoice_merge_by_partner/__openerp__.py b/contract_invoice_merge_by_partner/__openerp__.py new file mode 100644 index 00000000..7ac7a2cd --- /dev/null +++ b/contract_invoice_merge_by_partner/__openerp__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Contract Invoice Merge By Partner', + 'summary': 'This module merges same partner invoices generated by ' + 'contracts', + 'version': '8.0.1.0.0', + 'category': 'Account', + 'license': 'AGPL-3', + 'author': "Tecnativa, " + "Odoo Community Association (OCA)", + 'website': 'http://www.tecnativa.com', + 'depends': ['account_analytic_analysis', 'account_invoice_merge'], + 'data': [ + 'views/res_partner_view.xml', + ], + 'installable': True, +} diff --git a/contract_invoice_merge_by_partner/i18n/es.po b/contract_invoice_merge_by_partner/i18n/es.po new file mode 100644 index 00000000..b8c2a890 --- /dev/null +++ b/contract_invoice_merge_by_partner/i18n/es.po @@ -0,0 +1,33 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * contract_invoice_merge_by_partner +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-06-14 13:16+0000\n" +"PO-Revision-Date: 2016-06-14 15:19+0100\n" +"Last-Translator: Carlos Dauden \n" +"Language-Team: Tecnativa \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" +"Language: es_ES\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#. module: contract_invoice_merge_by_partner +#: model:ir.model,name:contract_invoice_merge_by_partner.model_account_analytic_account +msgid "Analytic Account" +msgstr "Cuenta analítica" + +#. module: contract_invoice_merge_by_partner +#: field:res.partner,contract_invoice_merge:0 +msgid "Contract invoice merge" +msgstr "Fusionar facturas de contratos" + +#. module: contract_invoice_merge_by_partner +#: model:ir.model,name:contract_invoice_merge_by_partner.model_res_partner +msgid "Partner" +msgstr "Empresa" diff --git a/contract_invoice_merge_by_partner/models/__init__.py b/contract_invoice_merge_by_partner/models/__init__.py new file mode 100644 index 00000000..17b40b5b --- /dev/null +++ b/contract_invoice_merge_by_partner/models/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import account_analytic_analysis +from . import res_partner diff --git a/contract_invoice_merge_by_partner/models/account_analytic_analysis.py b/contract_invoice_merge_by_partner/models/account_analytic_analysis.py new file mode 100644 index 00000000..eb366831 --- /dev/null +++ b/contract_invoice_merge_by_partner/models/account_analytic_analysis.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, models + + +class PurchaseOrderLine(models.Model): + _inherit = 'account.analytic.account' + + @api.multi + def _recurring_create_invoice(self, automatic=False): + invoice_obj = self.env['account.invoice'] + invoices = invoice_obj.browse( + super(PurchaseOrderLine, self)._recurring_create_invoice(automatic) + ) + res = [] + unlink_list = [] + for partner in invoices.mapped('partner_id'): + inv_to_merge = invoices.filtered(lambda x: x.partner_id == partner) + if partner.contract_invoice_merge and (len(inv_to_merge) > 1): + invoices_info = inv_to_merge.do_merge() + res.extend(invoices_info.keys()) + for inv_ids_list in invoices_info.values(): + unlink_list.extend(inv_ids_list) + else: + res.extend(inv_to_merge.ids) + if unlink_list: + invoice_obj.browse(unlink_list).unlink() + return res diff --git a/contract_invoice_merge_by_partner/models/res_partner.py b/contract_invoice_merge_by_partner/models/res_partner.py new file mode 100644 index 00000000..34cc712e --- /dev/null +++ b/contract_invoice_merge_by_partner/models/res_partner.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + contract_invoice_merge = fields.Boolean() diff --git a/contract_invoice_merge_by_partner/static/description/icon.png b/contract_invoice_merge_by_partner/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/contract_invoice_merge_by_partner/static/description/icon.png differ diff --git a/contract_invoice_merge_by_partner/tests/__init__.py b/contract_invoice_merge_by_partner/tests/__init__.py new file mode 100644 index 00000000..181cf9bd --- /dev/null +++ b/contract_invoice_merge_by_partner/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_contract_invoice_merge_by_partner diff --git a/contract_invoice_merge_by_partner/tests/test_contract_invoice_merge_by_partner.py b/contract_invoice_merge_by_partner/tests/test_contract_invoice_merge_by_partner.py new file mode 100644 index 00000000..225a8041 --- /dev/null +++ b/contract_invoice_merge_by_partner/tests/test_contract_invoice_merge_by_partner.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp.tests.common import TransactionCase + + +class TestContractInvoiceMergeByPartner(TransactionCase): + """ Use case : Prepare some data for current test case """ + def setUp(self): + super(TestContractInvoiceMergeByPartner, self).setUp() + self.partner = self.env['res.partner'].create( + {'customer': True, + 'name': "Test Customer", + 'contract_invoice_merge': True, + }) + self.product = self.env.ref('product.product_product_consultant') + self.uom = self.env.ref('product.product_uom_hour') + self.contract1 = self.env['account.analytic.account'].create({ + 'name': 'Test contract', + 'partner_id': self.partner.id, + 'type': 'contract', + 'recurring_invoices': True, + 'recurring_rule_type': 'monthly', + 'recurring_interval': 1, + 'recurring_invoice_line_ids': [ + (0, 0, {'quantity': 2.0, + 'price_unit': 100.0, + 'name': self.product.name, + 'product_id': self.product.id, + 'uom_id': self.uom.id})], + }) + self.contract2 = self.contract1.copy() + self.contract3 = self.contract1.copy() + self.contract4 = self.contract1.copy() + + def test_invoices_merged(self): + self.env['account.analytic.account']._recurring_create_invoice() + invoices = self.env['account.invoice'].search( + [('partner_id', '=', self.partner.id)]) + inv_draft = invoices.filtered(lambda x: x.state == 'draft') + self.assertEqual(len(inv_draft), 1) + inv_cancel = invoices.filtered(lambda x: x.state == 'cancel') + self.assertFalse(inv_cancel) diff --git a/contract_invoice_merge_by_partner/views/res_partner_view.xml b/contract_invoice_merge_by_partner/views/res_partner_view.xml new file mode 100644 index 00000000..bc0540db --- /dev/null +++ b/contract_invoice_merge_by_partner/views/res_partner_view.xml @@ -0,0 +1,19 @@ + + + + + + + Partner Form Contract Invoice Merge + res.partner + + + + + + + + + +