From dd8bae81bedf78c185651d3fdbe61ed884046f78 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Wed, 11 Apr 2018 15:33:34 +0200 Subject: [PATCH] Add method to group by order in invoice report Move invoice class in dedicated file --- sale_usability/__init__.py | 1 + sale_usability/account_invoice.py | 90 +++++++++++++++++++++++++++++++ sale_usability/sale.py | 86 +++++++---------------------- 3 files changed, 109 insertions(+), 68 deletions(-) create mode 100644 sale_usability/account_invoice.py diff --git a/sale_usability/__init__.py b/sale_usability/__init__.py index fa8603d..f31096d 100644 --- a/sale_usability/__init__.py +++ b/sale_usability/__init__.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from . import sale +from . import account_invoice from . import product from . import partner diff --git a/sale_usability/account_invoice.py b/sale_usability/account_invoice.py new file mode 100644 index 0000000..0bf27b8 --- /dev/null +++ b/sale_usability/account_invoice.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2015-2018 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + # for report (located in sale_usability and not account_usability + # because it uses layout categ defined in sale + # Method used in the sample invoice report available here: + # https://github.com/akretion/odoo-py3o-report-templates/tree/10.0/account_invoice_report_py3o + def py3o_lines_layout(self): + self.ensure_one() + res1 = {} + # {'categ(6)': {'lines': [l1, l2], 'subtotal': 23.32}} + for line in self.invoice_line_ids: + categ = line.layout_category_id + if categ in res1: + res1[categ]['lines'].append(line) + res1[categ]['subtotal'] += line.price_subtotal + else: + res1[categ] = { + 'lines': [line], + 'subtotal': line.price_subtotal} + res2 = [] + if len(res1) == 1 and not res1.keys()[0]: + # No category at all + for line in res1.values()[0]['lines']: + res2.append({'line': line}) + else: + for categ, ldict in res1.iteritems(): + res2.append({'categ': categ}) + for line in ldict['lines']: + res2.append({'line': line}) + if categ.subtotal: + res2.append({'subtotal': ldict['subtotal']}) + # res2: + # [ + # {'categ': categ(1)}, + # {'line': invoice_line(2)}, + # {'line': invoice_line(3)}, + # {'subtotal': 8932.23}, + # ] + return res2 + + def py3o_lines_layout_groupby_order(self, subtotal=True): + # This method is an alternative to the method py3o_lines_layout() + # defined above: you just have to change the call in the invoice + # ODT template + self.ensure_one() + res1 = {} + # {categ(1): {'lines': [l1, l2], 'subtotal': 23.32}} + soo = self.env['sale.order'] + for line in self.invoice_line_ids: + order = line.sale_line_ids and line.sale_line_ids[0].order_id\ + or soo + if order in res1: + res1[order]['lines'].append(line) + res1[order]['subtotal'] += line.price_subtotal + else: + res1[order] = { + 'lines': [line], + 'subtotal': line.price_subtotal} + # from pprint import pprint + # pprint(res1) + res2 = [] + if len(res1) == 1 and not res1.keys()[0]: + # No order at all + for line in res1.values()[0]['lines']: + res2.append({'line': line}) + else: + for order, ldict in res1.iteritems(): + res2.append({'categ': order}) + for line in ldict['lines']: + res2.append({'line': line}) + if subtotal: + res2.append({'subtotal': ldict['subtotal']}) + # res2: + # [ + # {'categ': categ(1)}, + # {'line': invoice_line(2)}, + # {'line': invoice_line(3)}, + # {'subtotal': 8932.23}, + # ] + # pprint(res2) + return res2 diff --git a/sale_usability/sale.py b/sale_usability/sale.py index 67bac59..cde4629 100644 --- a/sale_usability/sale.py +++ b/sale_usability/sale.py @@ -4,7 +4,6 @@ from odoo import models, fields, api from odoo.tools import float_is_zero -from itertools import groupby class SaleOrder(models.Model): @@ -56,33 +55,29 @@ class SaleOrder(models.Model): @api.multi def py3o_lines_layout(self): self.ensure_one() - res1 = [] - # [ - # {'categ': categ(6), 'lines': [l1, l2], 'subtotal': 23.32}, - # {'categ': categ(1), 'lines': [l3, l4, l5], 'subtotal': 12.42}, - # ] - for categ, lines in\ - groupby(self.order_line, lambda l: l.layout_category_id): - entry = {'lines': [], 'categ': categ} - if categ.subtotal: - entry['subtotal'] = 0.0 - for line in lines: - entry['lines'].append(line) - if 'subtotal' in entry: - entry['subtotal'] += line.price_subtotal - res1.append(entry) + res1 = {} + # {categ(6): {'lines': [l1, l2], 'subtotal': 23.32}} + for line in self.order_line: + categ = line.layout_category_id + if categ in res1: + res1[categ]['lines'].append(line) + res1[categ]['subtotal'] += line.price_subtotal + else: + res1[categ] = { + 'lines': [line], + 'subtotal': line.price_subtotal} + res2 = [] - if len(res1) == 1 and not res1[0]['categ']: + if len(res1) == 1 and not res1.keys()[0]: # No category at all - for l in res1[0]['lines']: - res2.append({'line': l}) + for line in res1.values()[0]['lines']: + res2.append({'line': line}) else: - # TODO : gérer qd il n'y a pas de categ - for ldict in res1: - res2.append({'categ': ldict['categ']}) + for categ, ldict in res1.iteritems(): + res2.append({'categ': categ}) for line in ldict['lines']: res2.append({'line': line}) - if 'subtotal' in ldict: + if categ.subtotal: res2.append({'subtotal': ldict['subtotal']}) # res2: # [ @@ -100,48 +95,3 @@ class ProcurementGroup(models.Model): sale_ids = fields.One2many( 'sale.order', 'procurement_group_id', string='Sale Orders', readonly=True) - - -class AccountInvoice(models.Model): - _inherit = 'account.invoice' - - # for report (located in sale_usability and not account_usability - # because it uses layout categ defined in sale - @api.multi - def py3o_lines_layout(self): - self.ensure_one() - res1 = [] - # [ - # {'categ': categ(6), 'lines': [l1, l2], 'subtotal': 23.32}, - # {'categ': categ(1), 'lines': [l3, l4, l5], 'subtotal': 12.42}, - # ] - for categ, lines in\ - groupby(self.invoice_line_ids, lambda l: l.layout_category_id): - entry = {'lines': [], 'categ': categ} - if categ.subtotal: - entry['subtotal'] = 0.0 - for line in lines: - entry['lines'].append(line) - if 'subtotal' in entry: - entry['subtotal'] += line.price_subtotal - res1.append(entry) - res2 = [] - if len(res1) == 1 and not res1[0]['categ']: - # No category at all - for l in res1[0]['lines']: - res2.append({'line': l}) - else: - for ldict in res1: - res2.append({'categ': ldict['categ']}) - for line in ldict['lines']: - res2.append({'line': line}) - if 'subtotal' in ldict: - res2.append({'subtotal': ldict['subtotal']}) - # res2: - # [ - # {'categ': categ(1)}, - # {'line': invoice_line(2)}, - # {'line': invoice_line(3)}, - # {'subtotal': 8932.23}, - # ] - return res2