~camptocamp/account-financial-report/7.0-asgard-ledger-export

« back to all changes in this revision

Viewing changes to asgard_ledger_export/asgard_ledger_export.py

  • Committer: Alexandre Fayolle
  • Date: 2013-03-21 09:58:27 UTC
  • Revision ID: alexandre.fayolle@camptocamp.com-20130321095827-3mz8s556oe4i3axa
import Heonium module in private repo

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
###############################################################################
 
3
#
 
4
# Asgard Ledger Export (ALE) module,
 
5
# Copyright (C) 2005 - 2013
 
6
# Héonium (http://www.heonium.com). All Right Reserved
 
7
#
 
8
# Asgard Ledger Export (ALE) module
 
9
# is free software: you can redistribute it and/or modify it under the terms
 
10
# of the Affero GNU General Public License as published by the Free Software
 
11
# Foundation, either version 3 of the License, or (at your option) any later
 
12
# version.
 
13
#
 
14
# Asgard Ledger Export (ALE) module
 
15
# is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 
16
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 
17
# PARTICULAR PURPOSE. See the Affero GNU General Public License for more
 
18
# details.
 
19
#
 
20
# You should have received a copy of the Affero GNU General Public License
 
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
22
#
 
23
###############################################################################
 
24
 
 
25
 
 
26
import os
 
27
import base64
 
28
import copy
 
29
import time
 
30
import pooler
 
31
from osv import fields, osv
 
32
from tools.translate import _
 
33
from heo_common.hnm_lib import *
 
34
from heo_common.files_tools import *
 
35
 
 
36
 
 
37
END_LINE = [
 
38
    ('unix', 'Unix', '\n'),
 
39
    ('windows', 'Windows', '\r\n'),
 
40
    ('nothing', 'Nothing', '')
 
41
]
 
42
 
 
43
 
 
44
class asgard_ledger_export(osv.osv):
 
45
    """
 
46
    Configuration of export
 
47
    """
 
48
 
 
49
    _name = "asgard.ledger.export"
 
50
    _description = "Define export"
 
51
 
 
52
    _columns = {
 
53
        'name': fields.char('Name', size=64, translate=True, required=True),
 
54
        'separator': fields.char('Separator', size=8, help="Separator field, leave blank if you dont have"),
 
55
        'end_line': fields.selection([('unix', 'Unix'), ('windows','Windows'),('nothing','Nothing')],'End of line'),
 
56
        'file_header': fields.text('File header', help="Text used to begin file."),
 
57
        'extension': fields.char('Extension', size=5, help="String add on end of name file (without the dot).", required=True),
 
58
        'alej_line': fields.one2many('asgard.ledger.export.journal', 'asgard_ledger_id', 'Asgard Ledger Journal Lines'),
 
59
        'alef_line': fields.one2many('asgard.ledger.export.fields', 'asgard_ledger_id', 'Asgard Ledger Field Lines'),
 
60
        'encoding': fields.selection([('utf-8', 'UTF-8'), ('iso-8859-15','ISO-8859-15')], 'Encoding', help="Encoding of exported file"),
 
61
        'active': fields.boolean('Active'),
 
62
        'company_id': fields.many2one('res.company', 'Company', required=True),
 
63
    }
 
64
 
 
65
    _defaults = {
 
66
        'active': lambda *a: True,
 
67
        'end_line': lambda *a: 'unix',
 
68
        'extension': lambda *a: 'csv',
 
69
        'file_header': lambda *a: '',
 
70
        'separator': lambda *a: ';',
 
71
        'encoding': lambda *a: 'utf-8',
 
72
        'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
 
73
    }
 
74
 
 
75
 
 
76
    def get_end_line(self, cr, uid, name, context={}):
 
77
        result = '\n'
 
78
 
 
79
        for endline in END_LINE:
 
80
            if endline[0] == name:
 
81
                return endline[2]
 
82
 
 
83
        return result
 
84
 
 
85
 
 
86
    def get_building_line(self, cr, uid, ids, context={}):
 
87
        """
 
88
        Get the table for building line
 
89
        """
 
90
 
 
91
        pool = pooler.get_pool(cr.dbname)
 
92
        alef_obj = pool.get('asgard.ledger.export.fields')
 
93
        result = []
 
94
 
 
95
        for config in self.browse(cr, uid, ids, context):
 
96
            result = alef_obj.get_building_field(cr, uid, map(lambda x:x.id,config.alef_line))
 
97
 
 
98
        return result
 
99
 
 
100
 
 
101
asgard_ledger_export()
 
102
 
 
103
 
 
104
class asgard_ledger_export_journal(osv.osv):
 
105
    """
 
106
    Table d'association entre les journaux comptable d'OpenERP et les noms des
 
107
    journaux.
 
108
    """
 
109
 
 
110
    _name = "asgard.ledger.export.journal"
 
111
    _description = "Link beetween OpenERP's journal and Sage journal"
 
112
 
 
113
    _columns = {
 
114
        'name': fields.char('Name', size=64, translate=True, required=True),
 
115
        'asgard_ledger_id': fields.many2one('asgard.ledger.export', 'Asgard Ledger Ref', required=True, ondelete="cascade", select=True,
 
116
            help="Associated configuration"),
 
117
        'active': fields.boolean('Active'),
 
118
        # Association journaux
 
119
        'journal_name': fields.char('Journal name', size=10, required=True,
 
120
            help="Journal name in target software. Warning, you must put exact name"),
 
121
        'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade",
 
122
            help="Select the associated OpenERP's journal"),
 
123
        'company_id': fields.many2one('res.company', 'Company', required=True),
 
124
    }
 
125
 
 
126
    _defaults = {
 
127
        'active': lambda *a: True,
 
128
        'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
 
129
    }
 
130
 
 
131
    _sql_constraints = [
 
132
        ('oerp_journal_uniq', 'unique (asgard_ledger_id,journal_id)', _('There is already an association with this journal !')),
 
133
    ]
 
134
 
 
135
 
 
136
 
 
137
asgard_ledger_export_journal()
 
138
 
 
139
 
 
140
class asgard_ledger_export_fields(osv.osv):
 
141
    _name = "asgard.ledger.export.fields"
 
142
    _description = "Definition of fields"
 
143
    _order = "sequence"
 
144
 
 
145
 
 
146
    _columns = {
 
147
        'name': fields.char('Name', size=64, translate=True, required=True, help="Name of this definition"),
 
148
        'asgard_ledger_id': fields.many2one('asgard.ledger.export', 'Asgard Ledger Ref', required=True, ondelete="cascade", select=True,
 
149
            help="Asgard associated configuration"),
 
150
        'sequence': fields.integer('Sequence', help="Order of field (in file target)."),
 
151
        'type_field': fields.selection([
 
152
            ('account_field', 'Account field'),
 
153
            ('text_field', 'Text field'),
 
154
            ('internal_field', 'Internal field'),
 
155
            ('build_field', 'Build field')], 'Field type',
 
156
                help="Select the type of field\n \
 
157
                    Account field : Field of object 'Account'.\n \
 
158
                    Internal field : Select field from list.\n \
 
159
                    Text field : Only text.\n \
 
160
                    Build field : Python code for build value. You can use 'object' and 'time'."),
 
161
 
 
162
        'field_account': fields.many2one('ir.model.fields', 'Fields', domain=[
 
163
            ('model', '=', 'account.move.line')
 
164
        ],
 
165
            help="Select which account filed you want export."),
 
166
        'field_indirection': fields.char('Indirection', size=128, help="Indirection line if fields is a key (ex : .name) "),
 
167
        'field_text': fields.char('Value', size=512, help="You can put here text (if 'Field type' on 'Text field') or python expression (if 'Field type' on 'Build field')."),
 
168
        'field_internal': fields.selection([
 
169
            ('journal_code', 'Target Journal code'),
 
170
            ('entry_num', '# Entry (relatif)')], 'Computed field',
 
171
            help="Target Jounal Code: Journal code when you run wizard. '# Entry': Number of entry (relative to export)"),
 
172
 
 
173
        'build_cmd': fields.char('Build command', size=64, required=True,
 
174
            help="Define with folowing sample : \n \
 
175
                ['string','%s'] : For standard string field. \n \
 
176
                ['string','%20s'] : For right justify string on 20 char. \n \
 
177
                ['date','%d/%m/%Y'] : For date formated in french. \n \
 
178
                ['float','%f'], : ... \n \
 
179
                ['int','%d'] : ..."),
 
180
        'position': fields.integer('Position', required=True, help='Position in exported file (not use)'),
 
181
        'lenght': fields.integer('Size (lenght)', required=True, help='Lenght of field in exported file.'),
 
182
        'error_label': fields.char('Error label', size=64, help="Fill this information if the content of the field shouldn't empty. This information ..."),
 
183
 
 
184
        'active': fields.boolean('Active'),
 
185
        'company_id': fields.many2one('res.company', 'Company', required=True),
 
186
    }
 
187
 
 
188
    _defaults = {
 
189
        'build_cmd': lambda *a: "['string','%s']",
 
190
        'type_field': lambda *a: 'internal_field',
 
191
        'field_text': lambda *a: '',
 
192
        'field_indirection': lambda *a: '',
 
193
        'position': lambda *a: 0,
 
194
        'active': lambda *a: True,
 
195
        'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
 
196
    }
 
197
 
 
198
 
 
199
    def get_building_field(self, cr, uid, ids, context={}):
 
200
        """
 
201
        Return a list of informations need to build each field.
 
202
        """
 
203
        result = []
 
204
 
 
205
        for line in self.browse(cr, uid, ids, context):
 
206
            temp = []
 
207
            # Ajout du type de champs ...
 
208
            if line.type_field == 'account_field':
 
209
                temp.append([line.type_field, line.field_account.id, line.field_indirection or ''])
 
210
            elif line.type_field in ['text_field', 'build_field']:
 
211
                temp.append([line.type_field, line.field_text])
 
212
            else:
 
213
                temp.append([line.type_field, line.field_internal])
 
214
            # ... ajout des infos complémentaire, position, longueur, ...
 
215
            temp.extend([line.position, line.lenght, eval(line.build_cmd)])
 
216
            # ... ajout du libelé si besoin ...
 
217
            if line.error_label:
 
218
                temp.extend(line.error_label)
 
219
            result.append(temp)
 
220
 
 
221
        return result
 
222
 
 
223
 
 
224
asgard_ledger_export_fields()
 
225
 
 
226
 
 
227
class asgard_ledger_export_statement(osv.osv):
 
228
    """
 
229
    Liste des exports déja réalisé
 
230
    """
 
231
    def _balance(self, cursor, user, ids, name, attr, context=None):
 
232
        res = {}
 
233
 
 
234
        for statement in self.browse(cursor, user, ids, context=context):
 
235
            res[statement.id] = 0.0
 
236
            for ales_line_id in statement.ales_line_ids:
 
237
                if ales_line_id.debit > 0:
 
238
                    res[statement.id] += ales_line_id.debit
 
239
                else:
 
240
                    res[statement.id] -= ales_line_id.credit
 
241
            for r in res:
 
242
                res[r] = round(res[r], 2)
 
243
        return res
 
244
 
 
245
 
 
246
    def _get_period(self, cr, uid, context={}):
 
247
        periods = self.pool.get('account.period').find(cr, uid)
 
248
        if periods:
 
249
            return periods[0]
 
250
        else:
 
251
            return False
 
252
 
 
253
 
 
254
    _order = "date desc"
 
255
    _name = "asgard.ledger.export.statement"
 
256
    _description = "Asgard Ledger Export Statement"
 
257
 
 
258
    _columns = {
 
259
        'name': fields.char('Name', size=64, translate=True, required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
260
        'date': fields.date('Date', required=True, readonly=True, states={'draft': [('readonly', False)]}),
 
261
        'journal_period_id': fields.many2many('account.journal.period', 'asgard_export_ledger_journal_period_rel',
 
262
            'statement_id', 'journal_period_id', 'Journal/Period', readonly=True, states={'draft':[('readonly',False)]},
 
263
            help="Select which period you want export."),
 
264
        'ale_id': fields.many2one('asgard.ledger.export', 'Asgard Ledger', required=True, readonly=True,
 
265
            states={'draft':[('readonly', False)]}),
 
266
        'ales_line_ids': fields.one2many('asgard.ledger.export.statement.line', 'ales_id', 'ALE Lines',
 
267
            readonly=True, states={'draft':[('readonly',False)]}),
 
268
        'balance': fields.function(_balance, method=True, string='Balance'),
 
269
        'state': fields.selection([
 
270
            ('draft', _('Draft')),
 
271
            ('confirm', _('Confirmed')),
 
272
            ('done', _('Done')),
 
273
            ('cancel', _('Cancelled'))
 
274
        ],
 
275
            'State', required=True,
 
276
            states={'confirm': [('readonly', True)]}, readonly="1"),
 
277
        'company_id': fields.many2one('res.company', 'Company', required=True),
 
278
    }
 
279
 
 
280
    _defaults = {
 
281
        'name': lambda self, cr, uid, context=None: \
 
282
                self.pool.get('ir.sequence').get(cr, uid, 'asgard.ledger.export.statement'),
 
283
        'date': lambda *a: time.strftime('%Y-%m-%d'),
 
284
        'state': lambda *a: 'draft',
 
285
        'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
 
286
    }
 
287
 
 
288
 
 
289
    def onchange_ale_id(self, cr, uid, ids, ale_id):
 
290
        if not ale_id:
 
291
            return {}
 
292
 
 
293
        ale_obj = self.pool.get('asgard.ledger.export')
 
294
        journal_period_obj = self.pool.get('account.journal.period')
 
295
 
 
296
        ale = ale_obj.browse(cr, uid, ale_id)
 
297
        journal_ids = [x.journal_id.id for x in ale.alej_line]
 
298
 
 
299
        journal_period_ids = journal_period_obj.search(cr, uid, [
 
300
            ('journal_id', 'in', journal_ids)
 
301
        ])
 
302
 
 
303
        return {'context': {'journal_id': journal_ids}}
 
304
 
 
305
 
 
306
    def action_confirm(self, cr, uid, ids, *args):
 
307
        result = False
 
308
 
 
309
        # Si la balance est égale a zéro et qu'il y a des lignes à exporter
 
310
        for ale in self.browse(cr, uid, ids, context={}):
 
311
            if len(ale.ales_line_ids) == 0:
 
312
                raise osv.except_osv(
 
313
                    _('No Lines !'),
 
314
                    _("You have to add some line to export.")
 
315
                )
 
316
 
 
317
            if ale.balance == 0.0:
 
318
                result = self.write(cr, uid, ids, {'state':'confirm'})
 
319
            else:
 
320
                raise osv.except_osv(
 
321
                    _('Bad balance !'),
 
322
                    _("Balance need to be equal to zero.")
 
323
                )
 
324
 
 
325
        return result
 
326
 
 
327
 
 
328
    def action_draft(self, cr, uid, ids, *args):
 
329
        return self.write(cr, uid, ids, {'state':'draft'})
 
330
 
 
331
 
 
332
    def action_cancel(self, cr, uid, ids, *args):
 
333
        return self.write(cr, uid, ids, {'state':'cancel'})
 
334
 
 
335
 
 
336
    def action_populate(self, cr, uid, ids, *args):
 
337
        """
 
338
        parameters :
 
339
            journal_period_id
 
340
        """
 
341
 
 
342
        pool = pooler.get_pool(cr.dbname)
 
343
        journal_period_obj = pool.get('account.journal.period')
 
344
        ales_line_obj = pool.get('asgard.ledger.export.statement.line')
 
345
 
 
346
        for ale in self.browse(cr, uid, ids, context={}):
 
347
            if not ale.journal_period_id:
 
348
                raise osv.except_osv(_('No Journal/Period selected !'), _('You have to select Journal/Period before populate line.'))
 
349
            jp_ids = journal_period_obj.read(cr, uid, map(lambda x:x.id,ale.journal_period_id), ['journal_id','period_id'])
 
350
            start = time.time()
 
351
            for jp in jp_ids:
 
352
                offset = 0
 
353
                results = [1]
 
354
                while len(results):
 
355
                    cr.execute('SELECT id \
 
356
                        FROM \
 
357
                            account_move_line \
 
358
                        WHERE \
 
359
                            period_id = %s AND journal_id = %s AND id NOT IN \
 
360
                            (SELECT move_line_id FROM asgard_ledger_export_statement_line) \
 
361
                        LIMIT 500 OFFSET %s',
 
362
                        (jp['period_id'][0],jp['journal_id'][0],str(offset)))
 
363
                    results = map(lambda x:x[0], cr.fetchall())
 
364
                    for result in results:
 
365
                        ales_line_id = ales_line_obj.create(cr, uid, {
 
366
                            'ales_id': ale.id,
 
367
                            'move_line_id': result})
 
368
            stop = time.time()
 
369
 
 
370
        return True
 
371
 
 
372
 
 
373
    def _fjournal_code(self, cr, uid, ids, **kwargs):
 
374
        alej_obj = pooler.get_pool(cr.dbname).get('asgard.ledger.export.journal')
 
375
 
 
376
        alej_line_id = alej_obj.search(cr, uid, [
 
377
            ('asgard_ledger_id', '=', kwargs['data'][1].ales_id.ale_id.id),
 
378
            ('journal_id', '=', kwargs['data'][1].journal_id.id),
 
379
            ('active', '=', True)])
 
380
 
 
381
        if not alej_line_id:
 
382
            raise osv.except_osv(
 
383
                _('No Journal linked !'),
 
384
                _("You have to define OpenERP journal linked with target name in asgard ledger configuration")
 
385
            )
 
386
 
 
387
        return alej_obj.read(cr, uid, alej_line_id, ['journal_name'])[0]['journal_name']
 
388
 
 
389
 
 
390
    def _faccount_field(self, cr, uid, ids, **kwargs):
 
391
        """
 
392
        Cette fonction peut être remplacée par '_fbuild_field', mais elle est
 
393
        gardé pour éviter d'avoir mettre une expression python pour les champs
 
394
        simple de l'écriture et leur indirection de niveau 1
 
395
        parameters : {'data':[<type_field>,<python_expression>], 'line':<browse_line_record>}
 
396
        return : Value of field
 
397
        """
 
398
        imf_obj = pooler.get_pool(cr.dbname).get('ir.model.fields')
 
399
 
 
400
 
 
401
        # Récupération du nom du champs par rapport à l'object 'ir_model_fields' ...
 
402
        imf = imf_obj.read(cr, uid, [kwargs['data'][1]], ['name'])[0]['name']
 
403
 
 
404
        # ... Contruction du champs et affectation à 'bf.
 
405
        t = "kwargs['line'].move_line_id.%s%s" % (str(imf), str(kwargs['data'][2]))
 
406
 
 
407
        if isinstance(eval(t), float):
 
408
            return str(eval(t))
 
409
 
 
410
        return eval(t)
 
411
 
 
412
 
 
413
    def _ftext_field(self, cr, uid, ids, **kwargs):
 
414
        """
 
415
        parameters : {'data':[<type_field>,<python_expression>], 'line':<browse_line_record>}
 
416
        return : Text value of data given in parameters
 
417
        """
 
418
        return kwargs['data'][1]
 
419
 
 
420
 
 
421
    def _fbuild_field(self, cr, uid, ids, **kwargs):
 
422
        """
 
423
        Evalue le champ contenant une expression Python
 
424
        parameters : {'data':[<type_field>,<python_expression>], 'line':<browse_line_record>}
 
425
        return : result of python expression evaluation.
 
426
        """
 
427
        result = False
 
428
 
 
429
        if kwargs['data'][1]:
 
430
            # Récupération de l'objet 'account_move_line'
 
431
            obj = kwargs['line'].move_line_id
 
432
            # Évaluation de l'expression python sur l'objet
 
433
            result = eval(kwargs['data'][1], {'object': obj, 'time': time})
 
434
 
 
435
        return result
 
436
 
 
437
 
 
438
    def _finternal_field(self, cr, uid, ids, **kwargs):
 
439
        return self.get_value(cr, uid, ids, data=[kwargs['data'][1], kwargs['line']])
 
440
 
 
441
 
 
442
    def get_value(self, cr, uid, ids, **kwargs):
 
443
        """
 
444
        Call correct method depend on parameters
 
445
        parameters : {'data':[<type_field>,<python_expression>], 'line':<browse_line_record>}
 
446
        return : result of method called
 
447
        """
 
448
        method_name = '_f' + str(kwargs['data'][0]).lower()
 
449
        try:
 
450
            method = getattr(self, method_name)
 
451
        except AttributeError:
 
452
            print ("The method for verify '%s' type isn't defined (You must define it in class 'asgard_ledger_export_statement' of module '%s')." % (method_name,__name__))
 
453
        else:
 
454
            return method(cr, uid, ids, **kwargs)
 
455
 
 
456
 
 
457
    def action_export(self, cr, uid, ids, *args):
 
458
        """
 
459
        For each entry line build the text value
 
460
        """
 
461
        pool = pooler.get_pool(cr.dbname)
 
462
        mod_obj = self.pool.get('ir.model.data')
 
463
        ale_obj = pool.get('asgard.ledger.export')
 
464
        alej_obj = pool.get('asgard.ledger.export.journal')
 
465
        attach_obj = pool.get('ir.attachment')
 
466
 
 
467
 
 
468
        for ales in self.browse(cr, uid, ids):
 
469
 
 
470
            # We need first to check if we have other attchments
 
471
            # (Attachments are limited to 1 per statement)
 
472
            attach_ids = []
 
473
            attach_ids = attach_obj.search(cr, uid, [
 
474
                ('name', 'like', 'export : %'),
 
475
                ('res_model', '=', 'asgard.ledger.export.statement'),
 
476
                ('res_id', '=', ales.id),
 
477
            ])
 
478
 
 
479
            if len(attach_ids) >= 1:
 
480
                raise osv.except_osv(
 
481
                    _('Error !'),
 
482
                    _("You cannot have more than one attachment !")
 
483
                )
 
484
 
 
485
            # Initalisation de l'encodage du fichier
 
486
            enc = generic_encode(
 
487
                file_header=ales.ale_id.file_header,
 
488
                separator=ales.ale_id.separator,
 
489
                ext=ales.ale_id.extension,
 
490
                ending=ale_obj.get_end_line(cr, uid, ales.ale_id.end_line),
 
491
                encoding=ales.ale_id.encoding)
 
492
 
 
493
            # Recupération du tableau de construction de ligne
 
494
            build_line = ale_obj.get_building_line(cr, uid, [ales.ale_id.id])
 
495
 
 
496
            # pour chaque ligne écritures
 
497
            for ales_line in ales.ales_line_ids:
 
498
                # Pour chaque construction de champs dans le tableau 'build_line'
 
499
                # Duplication du tableau de génération de ligne de texte
 
500
                bl = copy.deepcopy(build_line)
 
501
                for bf in bl:
 
502
                    bf[0] = self.get_value(cr, uid, ids, data=bf[0], line=ales_line)
 
503
                result = enc.write_file_in_flow(bl)
 
504
 
 
505
 
 
506
            ####
 
507
            ## Attachement
 
508
            fp = open(os.path.join(enc.dir_tmp, enc.filetmp), 'r')
 
509
            file_data = fp.read()
 
510
            attach_id = attach_obj.create(cr, uid, {
 
511
                'name': 'export : ' + ales.name,
 
512
                'datas': base64.encodestring(file_data),
 
513
                'datas_fname': enc.filetmp,
 
514
                'res_model': 'asgard.ledger.export.statement',
 
515
                'res_id': ales.id,
 
516
                })
 
517
            ## Attachement
 
518
 
 
519
        self.write(cr, uid, ids, {'state': 'done'})
 
520
 
 
521
        return True
 
522
 
 
523
 
 
524
asgard_ledger_export_statement()
 
525
 
 
526
 
 
527
class asgard_ledger_export_statement_line(osv.osv):
 
528
    _name = "asgard.ledger.export.statement.line"
 
529
    _description = "Export Statement reconcile"
 
530
    _order = 'name'
 
531
 
 
532
    _columns = {
 
533
        'name': fields.char('Date', size=64, translate=True, required=True, readonly=True),
 
534
        'ales_id': fields.many2one('asgard.ledger.export.statement', 'Asgard Statement', required=True, ondelete='cascade', select=True),
 
535
        'move_line_id': fields.many2one('account.move.line', 'Entry',
 
536
            select=True, required=True,
 
537
            help="Entry selected for ..."),
 
538
        'date_created': fields.related('move_line_id', 'date_created', type='date', string='Date Created Entry', store=True),
 
539
        'move_id': fields.related('move_line_id', 'move_id', type='many2one', relation='account.move', string='Entry', store=True),
 
540
        'period_id': fields.related('move_line_id', 'period_id', type='many2one', relation='account.period', string='Period', store=True),
 
541
        'journal_id': fields.related('move_line_id', 'journal_id', type='many2one', relation='account.journal', string='Journal', store=True),
 
542
        'credit': fields.related('move_line_id', 'credit', type='float', string='Credit', store=True),
 
543
        'debit': fields.related('move_line_id', 'debit', type='float', string='Debit', store=True),
 
544
        'account_id': fields.related('move_line_id', 'account_id', type='many2one', relation='account.account', string='Account', store=True),
 
545
        'text_line': fields.text('Line exported', readonly=True,
 
546
            help="Value of the line when it's exported in file (From format field)"),
 
547
        'company_id': fields.many2one('res.company', 'Company', required=True),
 
548
    }
 
549
 
 
550
    _defaults = {
 
551
        'name': lambda *a: time.strftime('%Y/%m/%d-%H:%M:%S'),
 
552
        'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
 
553
    }
 
554
 
 
555
 
 
556
asgard_ledger_export_statement_line()