From ae89bb4536a6305239a7f02110db93fa4bee9cb0 Mon Sep 17 00:00:00 2001 From: mackilem Date: Wed, 17 Oct 2018 20:54:38 -0300 Subject: [PATCH 1/3] =?UTF-8?q?novo=20m=C3=B3dulo=20para=20agrupar=20as=20?= =?UTF-8?q?faturas,=20principalmente=20de=20servi=C3=A7os?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- br_invoice_group/__init__.py | 4 + br_invoice_group/__manifest__.py | 25 ++++ br_invoice_group/data/ir_cron.xml | 21 ++++ br_invoice_group/models/__init__.py | 4 + br_invoice_group/models/account_invoice.py | 127 +++++++++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 br_invoice_group/__init__.py create mode 100644 br_invoice_group/__manifest__.py create mode 100644 br_invoice_group/data/ir_cron.xml create mode 100644 br_invoice_group/models/__init__.py create mode 100644 br_invoice_group/models/account_invoice.py diff --git a/br_invoice_group/__init__.py b/br_invoice_group/__init__.py new file mode 100644 index 000000000..dc5e6b693 --- /dev/null +++ b/br_invoice_group/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/br_invoice_group/__manifest__.py b/br_invoice_group/__manifest__.py new file mode 100644 index 000000000..4d9097fba --- /dev/null +++ b/br_invoice_group/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# © 2017 Mackilem Van der Laan, Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ # pylint: disable=C8101,C8103 + 'name': "BR Invoice Group", + + 'summary': """ + """, + + 'description': """""", + 'author': "Trustcode", + 'website': "http://www.trustcode.com.br", + 'category': 'Uncategorized', + 'version': '11.0.1.0.0', + 'license': 'AGPL-3', + 'contributors': [ + 'Mackilem Van der Laan ', + ], + 'depends': ['br_account'], + 'data': ['data/ir_cron.xml'], + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/br_invoice_group/data/ir_cron.xml b/br_invoice_group/data/ir_cron.xml new file mode 100644 index 000000000..8a82d27c4 --- /dev/null +++ b/br_invoice_group/data/ir_cron.xml @@ -0,0 +1,21 @@ + + + + Invoice Group + + code + + model.group_invoices(group_dict=[{"rule_name": 'SERVIÇOS-01.06', "fpos": 1, "domain": [('service_type_id', '=', 7)]}, + {"rule_name": 'SERVIÇOS-01.02', "fpos": 1, "domain": [('service_type_id', '=', 3)]}, + {"rule_name": 'OUTROS SERVIÇOS', "fpos": 1, "domain": [('product_type', '=', 'service')]}, + {"rule_name": 'TODOS PRODUTOS', "fpos": 1, "domain": [('product_type', '=', 'product')]}, + ]) + + 1 + months + -1 + + + + + diff --git a/br_invoice_group/models/__init__.py b/br_invoice_group/models/__init__.py new file mode 100644 index 000000000..0967df7c7 --- /dev/null +++ b/br_invoice_group/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import account_invoice diff --git a/br_invoice_group/models/account_invoice.py b/br_invoice_group/models/account_invoice.py new file mode 100644 index 000000000..cb2d0655d --- /dev/null +++ b/br_invoice_group/models/account_invoice.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# © 2017 Mackilem Van der Laan, Trustcode +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models +from itertools import product + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + @api.multi + def group_invoices(self, group_dict): + """ + group_dict = [{"rule_name": 'serv_01.05', "fpos": 1, + "domain": [('service_type_id', '=', 7)]}, + ] + """ + vals = self._prepare_invoice_dict(group_dict) + if vals: + for inv in vals: + self._create_invoices_grouped(inv) + + @api.multi + def _prepare_invoice_dict(self, group_dict): + vals = [] + if self.ids: + inv = self.filtered(lambda l: l.state == "draft") + else: + inv = self.search([('state', '=', 'draft')]) + lines = inv.mapped('invoice_line_ids') + + for group in group_dict: + if 'domain' not in group and not group['domain']: + continue + group['domain'].append(('id', 'in', lines.ids)) + f_lines = lines.search(group['domain']) + for v in self._prepare_vals(f_lines): + v['rule'] = group['rule_name'] + v['fpos'] = group['fpos'] or False + vals.append(v) + lines -= f_lines + + return vals + + def _prepare_vals(self, lines): + inv_vals = [] + comp_ids = lines.mapped('company_id') + part_ids = lines.mapped('partner_id') + for (c, p) in product(comp_ids, part_ids): + ln = lines.filtered(lambda l: l.company_id == c + and l.partner_id == p) + if ln: + inv_vals.append({'company': c, 'partner': p, 'lines': ln}) + lines -= ln + if not lines: + break + return inv_vals + + def _create_invoices_grouped(self, inv): + fpos_id, journal_id = self._get_fpos_journal(inv) + partner_id = inv['partner'] + company = inv['company'] + inv_ids = inv['lines'].mapped('invoice_id') + origin = [org for org in inv_ids.mapped('origin') if org] + pgto_ids = inv_ids.mapped('payment_term_id') + user_ids = inv_ids.mapped('user_id') + team_ids = inv_ids.mapped('team_id') + + gr_invoice_id = self.create({ + 'origin': origin or '', + 'type': 'out_invoice', + 'account_id': partner_id.with_context( + force_company=company.id).property_account_receivable_id.id, + 'partner_id': partner_id.id, + 'partner_shipping_id': partner_id.id, + 'journal_id': journal_id.id, + 'currency_id': company.currency_id.id, + 'payment_term_id': pgto_ids[0].id if pgto_ids else False, + 'fiscal_position_id': fpos_id.id, + 'company_id': company.id, + 'user_id': user_ids[0].id if user_ids else False, + 'team_id': team_ids[0].id if team_ids else False + }) + for line in inv['lines']: + line.copy({'invoice_id': gr_invoice_id.id}) + + cancel_msg = (""" +

This invoice was canceled by group rule named %s and + created the invoice: + %s + +

""" % (inv['rule'], gr_invoice_id.id, partner_id.name)) + + [i.message_post(cancel_msg) for i in inv_ids] + [i.action_invoice_cancel_paid() for i in inv_ids if i.state == "draft"] + msg_ids = '' + for id in inv_ids.ids: + msg_ids += """ inv_%s - + """ % (id, id) + + new_msg = (""" +

This invoice was created by group rule named %s and + grouped this invoices: %s +

""" % (inv['rule'], msg_ids)) + gr_invoice_id.message_post(new_msg) + + def _get_fpos_journal(self, inv): + aj = self.env['account.journal'] + afp = self.env['account.fiscal.position'] + company = inv['company'] + fpos_id = journal_id = False + + if 'fpos' in inv: + fpos_id = afp.browse(inv['fpos']) + else: + fpos_id = inv['partner'].with_context( + force_company=company.id).property_account_position_id + if fpos_id: + journal_id = fpos_id.journal_id or False + if not journal_id: + domain = [('company_id', '=', company.id), ('type', '=', 'sale')] + journal_id = aj.search(domain, limit=1) + + return fpos_id, journal_id From 9a054d22c89df7c96c73c084c1527281dd74e315 Mon Sep 17 00:00:00 2001 From: mackilem Date: Wed, 17 Oct 2018 21:24:19 -0300 Subject: [PATCH 2/3] manifest --- br_invoice_group/__manifest__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/br_invoice_group/__manifest__.py b/br_invoice_group/__manifest__.py index 4d9097fba..1815923bb 100644 --- a/br_invoice_group/__manifest__.py +++ b/br_invoice_group/__manifest__.py @@ -3,15 +3,18 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { # pylint: disable=C8101,C8103 - 'name': "BR Invoice Group", + 'name': "BR Group Invoices", 'summary': """ + Adiciona o recurso de agrupar faturas para o mesmo cliente, respeitando + as regras conforme configurado. Roda automáticamente conforme + parametrização do Cron """, - 'description': """""", + 'description': """Group Invoices""", 'author': "Trustcode", 'website': "http://www.trustcode.com.br", - 'category': 'Uncategorized', + 'category': 'Account', 'version': '11.0.1.0.0', 'license': 'AGPL-3', 'contributors': [ From 09e2296b23c6975e01ad00a73b7c3d6f546f87ad Mon Sep 17 00:00:00 2001 From: mackilem Date: Fri, 19 Oct 2018 15:56:39 -0300 Subject: [PATCH 3/3] =?UTF-8?q?nome=20do=20m=C3=B3dulo=20alterado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {br_invoice_group => br_group_invoice}/__init__.py | 0 {br_invoice_group => br_group_invoice}/__manifest__.py | 0 {br_invoice_group => br_group_invoice}/data/ir_cron.xml | 0 {br_invoice_group => br_group_invoice}/models/__init__.py | 0 {br_invoice_group => br_group_invoice}/models/account_invoice.py | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {br_invoice_group => br_group_invoice}/__init__.py (100%) rename {br_invoice_group => br_group_invoice}/__manifest__.py (100%) rename {br_invoice_group => br_group_invoice}/data/ir_cron.xml (100%) rename {br_invoice_group => br_group_invoice}/models/__init__.py (100%) rename {br_invoice_group => br_group_invoice}/models/account_invoice.py (100%) diff --git a/br_invoice_group/__init__.py b/br_group_invoice/__init__.py similarity index 100% rename from br_invoice_group/__init__.py rename to br_group_invoice/__init__.py diff --git a/br_invoice_group/__manifest__.py b/br_group_invoice/__manifest__.py similarity index 100% rename from br_invoice_group/__manifest__.py rename to br_group_invoice/__manifest__.py diff --git a/br_invoice_group/data/ir_cron.xml b/br_group_invoice/data/ir_cron.xml similarity index 100% rename from br_invoice_group/data/ir_cron.xml rename to br_group_invoice/data/ir_cron.xml diff --git a/br_invoice_group/models/__init__.py b/br_group_invoice/models/__init__.py similarity index 100% rename from br_invoice_group/models/__init__.py rename to br_group_invoice/models/__init__.py diff --git a/br_invoice_group/models/account_invoice.py b/br_group_invoice/models/account_invoice.py similarity index 100% rename from br_invoice_group/models/account_invoice.py rename to br_group_invoice/models/account_invoice.py