1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2014-Today OpenERP SA (<http://www.openerp.com>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
22 from openerp.osv import osv, fields
23 from itertools import groupby
26 def grouplines(self, ordered_lines, sortkey):
27 """Return lines from a specified invoice or sale order grouped by category"""
29 for key, valuesiter in groupby(ordered_lines, sortkey):
31 group['category'] = key
32 group['lines'] = list(v for v in valuesiter)
34 if 'subtotal' in key and key.subtotal is True:
35 group['subtotal'] = sum(line.price_subtotal for line in group['lines'])
36 grouped_lines.append(group)
41 class SaleLayoutCategory(osv.Model):
42 _name = 'sale_layout.category'
45 'name': fields.char('Name', required=True),
46 'sequence': fields.integer('Sequence', required=True),
47 'subtotal': fields.boolean('Add subtotal'),
48 'separator': fields.boolean('Add separator'),
49 'pagebreak': fields.boolean('Add pagebreak')
60 class AccountInvoice(osv.Model):
61 _inherit = 'account.invoice'
63 def sale_layout_lines(self, cr, uid, ids, invoice_id=None, context=None):
65 Returns invoice lines from a specified invoice ordered by
66 sale_layout_category sequence. Used in sale_layout module.
69 -'invoice_id' (int): specify the concerned invoice.
71 ordered_lines = self.browse(cr, uid, invoice_id, context=context).invoice_line
72 # We chose to group first by category model and, if not present, by invoice name
73 sortkey = lambda x: x.sale_layout_cat_id if x.sale_layout_cat_id else ''
75 return grouplines(self, ordered_lines, sortkey)
80 class AccountInvoiceLine(osv.Model):
81 _inherit = 'account.invoice.line'
82 _order = 'invoice_id, categ_sequence, sequence, id'
84 sale_layout_cat_id = openerp.fields.Many2one('sale_layout.category', string='Section')
85 categ_sequence = openerp.fields.Integer(related='sale_layout_cat_id.sequence',
86 string='Layout Sequence', store=True)
92 class SaleOrder(osv.Model):
93 _inherit = 'sale.order'
95 def sale_layout_lines(self, cr, uid, ids, order_id=None, context=None):
97 Returns order lines from a specified sale ordered by
98 sale_layout_category sequence. Used in sale_layout module.
101 -'order_id' (int): specify the concerned sale order.
103 ordered_lines = self.browse(cr, uid, order_id, context=context).order_line
104 sortkey = lambda x: x.sale_layout_cat_id if x.sale_layout_cat_id else ''
106 return grouplines(self, ordered_lines, sortkey)
109 class SaleOrderLine(osv.Model):
110 _inherit = 'sale.order.line'
112 'sale_layout_cat_id': fields.many2one('sale_layout.category',
114 'categ_sequence': fields.related('sale_layout_cat_id',
115 'sequence', type='integer',
116 string='Layout Sequence', store=True)
117 # Store is intentionally set in order to keep the "historic" order.
124 _order = 'order_id, categ_sequence, sequence, id'
126 def _prepare_order_line_invoice_line(self, cr, uid, line, account_id=False, context=None):
127 """Save the layout when converting to an invoice line."""
128 invoice_vals = super(SaleOrderLine, self)._prepare_order_line_invoice_line(cr, uid, line, account_id=account_id, context=context)
129 if line.sale_layout_cat_id:
130 invoice_vals['sale_layout_cat_id'] = line.sale_layout_cat_id.id
131 if line.categ_sequence:
132 invoice_vals['categ_sequence'] = line.categ_sequence