b5c996aad23aa017a37286c665be1bd65ccd0d01
[odoo/odoo.git] / addons / sale_layout / models / sale_layout.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2014-Today OpenERP SA (<http://www.openerp.com>).
6 #
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.
11 #
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.
16 #
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/>.
19 #
20 ##############################################################################
21
22 from openerp.osv import osv, fields
23 from itertools import groupby
24
25
26 def grouplines(self, ordered_lines, sortkey):
27     """Return lines from a specified invoice or sale order grouped by category"""
28     grouped_lines = []
29     for key, valuesiter in groupby(ordered_lines, sortkey):
30         group = {}
31         group['category'] = key
32         group['lines'] = list(v for v in valuesiter)
33
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)
37
38     return grouped_lines
39
40
41 class SaleLayoutCategory(osv.Model):
42     _name = 'sale_layout.category'
43     _order = 'sequence'
44     _columns = {
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')
50     }
51
52     _defaults = {
53         'subtotal': True,
54         'separator': True,
55         'pagebreak': False,
56         'sequence': 10
57     }
58
59
60 class AccountInvoice(osv.Model):
61     _inherit = 'account.invoice'
62
63     def sale_layout_lines(self, cr, uid, ids, invoice_id=None, context=None):
64         """
65         Returns invoice lines from a specified invoice ordered by
66         sale_layout_category sequence. Used in sale_layout module.
67
68         :Parameters:
69             -'invoice_id' (int): specify the concerned invoice.
70         """
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 ''
74
75         return grouplines(self, ordered_lines, sortkey)
76
77
78 import openerp
79
80 class AccountInvoiceLine(osv.Model):
81     _inherit = 'account.invoice.line'
82     _order = 'invoice_id, categ_sequence, sequence, id'
83
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)
87
88
89 class SaleOrder(osv.Model):
90     _inherit = 'sale.order'
91
92     def sale_layout_lines(self, cr, uid, ids, order_id=None, context=None):
93         """
94         Returns order lines from a specified sale ordered by
95         sale_layout_category sequence. Used in sale_layout module.
96
97         :Parameters:
98             -'order_id' (int): specify the concerned sale order.
99         """
100         ordered_lines = self.browse(cr, uid, order_id, context=context).order_line
101         sortkey = lambda x: x.sale_layout_cat_id if x.sale_layout_cat_id else ''
102
103         return grouplines(self, ordered_lines, sortkey)
104
105
106 class SaleOrderLine(osv.Model):
107     _inherit = 'sale.order.line'
108     _columns = {
109         'sale_layout_cat_id': fields.many2one('sale_layout.category',
110                                               string='Section'),
111         'categ_sequence': fields.related('sale_layout_cat_id',
112                                          'sequence', type='integer',
113                                          string='Layout Sequence', store=True)
114         #  Store is intentionally set in order to keep the "historic" order.
115     }
116     _order = 'order_id, categ_sequence, sequence, id'
117
118     def _prepare_order_line_invoice_line(self, cr, uid, line, account_id=False, context=None):
119         """Save the layout when converting to an invoice line."""
120         invoice_vals = super(SaleOrderLine, self)._prepare_order_line_invoice_line(cr, uid, line, account_id=account_id, context=context)
121         if line.sale_layout_cat_id:
122             invoice_vals['sale_layout_cat_id'] = line.sale_layout_cat_id.id
123         if line.categ_sequence:
124             invoice_vals['categ_sequence'] = line.categ_sequence
125         return invoice_vals