~luc-demeyer/openobject-addons/7.0-account_financial_report_webkit-fixes

« back to all changes in this revision

Viewing changes to account_export_csv/wizard/account_export_csv.py

  • Committer: Alexandre Fayolle
  • Author(s): vincent.renaville at camptocamp
  • Date: 2013-04-17 09:30:01 UTC
  • mfrom: (27.1.7 account-financial-report)
  • Revision ID: alexandre.fayolle@camptocamp.com-20130417093001-sjvlv7wiinnn5815
[MRG] Add account_export_csv, that allow to export Trial Balance and Analytic Balance with accounts in CSV

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    Author Joel Grand-Guillaume and Vincent Renaville Copyright 2013 Camptocamp SA
 
5
#    CSV data formating inspired from http://docs.python.org/2.7/library/csv.html?highlight=csv#examples
 
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
import time
 
23
import StringIO
 
24
import cStringIO
 
25
import base64
 
26
 
 
27
import csv
 
28
import codecs
 
29
 
 
30
from openerp.osv import orm, fields
 
31
from openerp.tools.translate import _
 
32
 
 
33
 
 
34
class AccountUnicodeWriter(object):
 
35
    """
 
36
    A CSV writer which will write rows to CSV file "f",
 
37
    which is encoded in the given encoding.
 
38
    """
 
39
 
 
40
    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
 
41
        # Redirect output to a queue
 
42
        self.queue = cStringIO.StringIO()
 
43
        # created a writer with Excel formating settings
 
44
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
 
45
        self.stream = f
 
46
        self.encoder = codecs.getincrementalencoder(encoding)()
 
47
 
 
48
    def writerow(self, row):
 
49
        #we ensure that we do not try to encode none or bool
 
50
        row = [x or u'' for x in row]
 
51
        
 
52
        encoded_row = []
 
53
        for c in row:
 
54
            if type(c) == unicode:
 
55
                encoded_row.append(c.encode("utf-8"))
 
56
            else:
 
57
                encoded_row.append(c)
 
58
        
 
59
        self.writer.writerow(encoded_row)
 
60
        # Fetch UTF-8 output from the queue ...
 
61
        data = self.queue.getvalue()
 
62
        data = data.decode("utf-8")
 
63
        # ... and reencode it into the target encoding
 
64
        data = self.encoder.encode(data)
 
65
        # write to the target stream
 
66
        self.stream.write(data)
 
67
        # empty queue
 
68
        self.queue.truncate(0)
 
69
 
 
70
    def writerows(self, rows):
 
71
        for row in rows:
 
72
            self.writerow(row)
 
73
 
 
74
class AccountCSVExport(orm.TransientModel):
 
75
    _name = 'account.csv.export'
 
76
    _description = 'Export Accounting'
 
77
 
 
78
    _columns = {
 
79
        'data': fields.binary('CSV',readonly=True),
 
80
        'company_id': fields.many2one('res.company', 'Company', invisible=True),
 
81
        'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscalyear', required=True),
 
82
        'periods': fields.many2many('account.period','rel_wizard_period','wizard_id','period_id','Periods',help='All periods in the fiscal year if empty'),
 
83
        'export_filename': fields.char('Export CSV Filename', size=128),
 
84
    }
 
85
 
 
86
    def _get_company_default(self, cr, uid, context=None):
 
87
        comp_obj = self.pool['res.company']
 
88
        return comp_obj._company_default_get(cr, uid, 'account.fiscalyear', context=context)
 
89
 
 
90
    def _get_fiscalyear_default(self, cr, uid, context=None):
 
91
        fiscalyear_obj = self.pool['account.fiscalyear']
 
92
        context['company_id'] = self._get_company_default(cr, uid, context)
 
93
        return fiscalyear_obj.find(cr,uid,dt=None,exception=True, context=context)
 
94
 
 
95
    _defaults = {'company_id': _get_company_default,
 
96
                 'fiscalyear_id' : _get_fiscalyear_default,
 
97
                 'export_filename' : 'account_export.csv'}
 
98
 
 
99
    def action_manual_export_account(self, cr, uid, ids, context=None):
 
100
        this = self.browse(cr, uid, ids)[0]
 
101
        rows = self.get_data(cr, uid, ids,"account", context)
 
102
        file_data = StringIO.StringIO()
 
103
        try:
 
104
            writer = AccountUnicodeWriter(file_data)
 
105
            writer.writerows(rows)
 
106
            file_value = file_data.getvalue()
 
107
            self.write(cr, uid, ids,
 
108
                       {'data': base64.encodestring(file_value)},
 
109
                       context=context)
 
110
        finally:
 
111
            file_data.close()
 
112
        return {
 
113
            'type': 'ir.actions.act_window',
 
114
            'res_model': 'account.csv.export',
 
115
            'view_mode': 'form',
 
116
            'view_type': 'form',
 
117
            'res_id': this.id,
 
118
            'views': [(False, 'form')],
 
119
            'target': 'new',
 
120
        }
 
121
 
 
122
 
 
123
    def _get_header_account(self, cr, uid, ids, context=None):
 
124
        return [_(u'CODE'),
 
125
                _(u'NAME'),
 
126
                _(u'DEBIT'),
 
127
                _(u'CREDIT'),
 
128
                _(u'BALANCE'),
 
129
                ]
 
130
 
 
131
    def _get_rows_account(self, cr, uid, ids, fiscalyear_id,period_range_ids,company_id,context=None):
 
132
        """
 
133
        Return list to generate rows of the CSV file
 
134
        """
 
135
        cr.execute("""
 
136
                        select ac.code,ac.name,
 
137
                        sum(debit) as sum_debit,sum(credit) as sum_credit,sum(debit) - sum(credit) as balance
 
138
                        from account_move_line as aml,account_account as ac
 
139
                        where aml.account_id = ac.id
 
140
                        and period_id in %(period_ids)s
 
141
                        group by ac.id,ac.code,ac.name
 
142
                        order by ac.code
 
143
                   """,
 
144
                    {'fiscalyear_id': fiscalyear_id,'company_id':company_id,'period_ids':tuple(period_range_ids)}
 
145
                )
 
146
        res = cr.fetchall()
 
147
        
 
148
        rows = []
 
149
        for line in res:
 
150
            rows.append(list(line))
 
151
        return rows
 
152
    
 
153
    def action_manual_export_analytic(self, cr, uid, ids, context=None):
 
154
        this = self.browse(cr, uid, ids)[0]
 
155
        rows = self.get_data(cr, uid, ids,"analytic", context)
 
156
        file_data = StringIO.StringIO()
 
157
        try:
 
158
            writer = AccountUnicodeWriter(file_data)
 
159
            writer.writerows(rows)
 
160
            file_value = file_data.getvalue()
 
161
            self.write(cr, uid, ids,
 
162
                       {'data': base64.encodestring(file_value)},
 
163
                       context=context)
 
164
        finally:
 
165
            file_data.close()
 
166
        return {
 
167
            'type': 'ir.actions.act_window',
 
168
            'res_model': 'account.csv.export',
 
169
            'view_mode': 'form',
 
170
            'view_type': 'form',
 
171
            'res_id': this.id,
 
172
            'views': [(False, 'form')],
 
173
            'target': 'new',
 
174
        }
 
175
    
 
176
    def _get_header_analytic(self, cr, uid, ids, context=None):
 
177
        return [_(u'ANALYTIC CODE'),
 
178
                _(u'ANALYTIC NAME'),
 
179
                _(u'CODE'),
 
180
                _(u'ACCOUNT NAME'),
 
181
                _(u'DEBIT'),
 
182
                _(u'CREDIT'),
 
183
                _(u'BALANCE'),
 
184
                ]
 
185
 
 
186
    def _get_rows_analytic(self, cr, uid, ids, fiscalyear_id,period_range_ids,company_id,context=None):
 
187
        """
 
188
        Return list to generate rows of the CSV file
 
189
        """
 
190
        cr.execute("""  select aac.code as analytic_code,aac.name as analytic_name,ac.code,ac.name,
 
191
                        sum(debit) as sum_debit,sum(credit) as sum_credit,sum(debit) - sum(credit) as balance
 
192
                        from account_move_line 
 
193
                        left outer join account_analytic_account as aac
 
194
                        on (account_move_line.analytic_account_id = aac.id)
 
195
                        inner join account_account as ac
 
196
                        on account_move_line.account_id = ac.id
 
197
                        and account_move_line.period_id in %(period_ids)s
 
198
                        group by aac.id,aac.code,aac.name,ac.id,ac.code,ac.name
 
199
                        order by aac.code
 
200
                   """,
 
201
                    {'fiscalyear_id': fiscalyear_id,'company_id':company_id,'period_ids':tuple(period_range_ids)}
 
202
                )
 
203
        res = cr.fetchall()
 
204
        
 
205
        rows = []
 
206
        for line in res:
 
207
            rows.append(list(line))
 
208
        return rows
 
209
 
 
210
    def get_data(self, cr, uid, ids,result_type,context=None):
 
211
        get_header_func = getattr(self,("_get_header_%s"%(result_type)), None)
 
212
        get_rows_func = getattr(self,("_get_rows_%s"%(result_type)), None)
 
213
        form = self.browse(cr, uid, ids[0], context=context)
 
214
        fiscalyear_id = form.fiscalyear_id.id
 
215
        user_obj = self.pool.get('res.users')
 
216
        company_id = user_obj.browse(cr, uid, uid).company_id.id
 
217
        if form.periods:
 
218
            period_range_ids = [x.id for x in form.periods]
 
219
        else:
 
220
            # If not period selected , we take all periods
 
221
            p_obj = self.pool.get("account.period")
 
222
            period_range_ids = p_obj.search(cr,uid,[('fiscalyear_id','=',fiscalyear_id)],context=context)
 
223
        rows = []
 
224
        rows.append(get_header_func(cr, uid, ids, context=context))
 
225
        rows.extend(get_rows_func(cr, uid, ids, fiscalyear_id,period_range_ids,company_id, context=context))
 
226
        return rows