[MERGE]
[odoo/odoo.git] / addons / account_asset / account_asset.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
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 osv import osv, fields
23 import time
24 from datetime import datetime
25
26 class account_asset_category(osv.osv):
27     _name = 'account.asset.category'
28     _description = 'Asset category'
29
30     _columns = {
31         'name': fields.char('Name', size=64, required=True, select=1),
32         'note': fields.text('Note'),
33         'journal_analytic_id': fields.many2one('account.analytic.journal', 'Analytic journal'),
34         'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
35         'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True),
36         'account_depreciation_id': fields.many2one('account.account', 'Depreciation Account', required=True),
37         'account_expense_depreciation_id': fields.many2one('account.account', 'Depr. Expense Account', required=True),
38         'journal_id': fields.many2one('account.journal', 'Journal', required=True),
39         'company_id': fields.many2one('res.company', 'Company', required=True),
40         'method': fields.selection([('linear','Linear'),('progressif','Progressive')], 'Computation method', required=True),
41         'method_delay': fields.integer('During (interval)'),
42         'method_period': fields.integer('Depre. all (period)'),
43         'method_progress_factor': fields.float('Progressif Factor'),
44         'method_time': fields.selection([('delay','Delay'),('end','Ending Period')], 'Time Method', required=True),
45         'prorata':fields.boolean('Prorata Temporis', help='Indicates that the accounting entries for this asset have to be done from the purchase date instead of the first January'),
46     }
47
48     _defaults = {
49         'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'account.asset.category', context=context),
50         'method': 'linear',
51         'method_delay': 5,
52         'method_time': 'delay',
53         'method_period': 12,
54         'method_progress_factor': 0.3,
55     }
56
57 account_asset_category()
58
59 #class one2many_mod_asset(fields.one2many):
60 #
61 #    def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
62 #        prinasset_property_id        if context is None:
63 #            context = {}
64 #        if not values:
65 #            values = {}
66 #        res = {}
67 #        for id in ids:
68 #            res[id] = []
69 #        #compute depreciation board
70 #        depreciation_line_ids = obj.pool.get('account.asset.asset').compute_depreciation_board(cr, user, ids, context=context)
71 #        for key, value in depreciation_line_ids.items():
72 #            #write values on asset
73 #            obj.pool.get(self._obj).write(cr, user, key, {'depreciation_line_ids': [6,0,value]})
74 #        return depreciation_line_ids
75
76 class account_asset_asset(osv.osv):
77     _name = 'account.asset.asset'
78     _description = 'Asset'
79
80     def _get_period(self, cr, uid, context={}):
81         periods = self.pool.get('account.period').find(cr, uid)
82         if periods:
83             return periods[0]
84         else:
85             return False
86
87     def _get_last_depreciation_date(self, cr, uid, ids, context=None):
88         """
89         @param id: ids of a account.asset.asset objects
90         @return: Returns a dictionary of the effective dates of the last depreciation entry made for given asset ids. If there isn't any, return the purchase date of this asset
91         """
92         cr.execute("""
93             SELECT a.id as id, COALESCE(MAX(l.date),a.purchase_date) AS date
94             FROM account_asset_asset a
95             LEFT JOIN account_move_line l ON (l.asset_id = a.id)
96             WHERE a.id IN %s
97             GROUP BY a.id, a.purchase_date """, (tuple(ids),))
98         return dict(cr.fetchall())
99
100     def compute_depreciation_board(self, cr, uid,ids, context=None):
101         depreciation_lin_obj = self.pool.get('account.asset.depreciation.line')
102         for asset in self.browse(cr, uid, ids, context=context):
103             old_depreciation_line_ids = depreciation_lin_obj.search(cr, uid, [('asset_id', '=', asset.id), ('move_id', '=', False)])
104             if old_depreciation_line_ids:
105                 depreciation_lin_obj.unlink(cr, uid, old_depreciation_line_ids, context=context)
106
107             undone_dotation_number = asset.method_delay - len(asset.account_move_line_ids)
108             residual_amount = asset.value_residual
109             depreciation_date = datetime.strptime(self._get_last_depreciation_date(cr, uid, [asset.id], context)[asset.id], '%Y-%m-%d')
110             day = depreciation_date.day
111             month = depreciation_date.month
112             year = depreciation_date.year
113             for i in range(1,undone_dotation_number+1):
114                 if i == undone_dotation_number + 1:
115                     amount = residual_amount
116                 else:
117                     if asset.method == 'linear':
118                         amount = asset.purchase_value / undone_dotation_number
119                     else:
120                         amount = residual_amount * asset.method_progress_factor
121                 residual_amount -= amount
122                 vals = {
123                      'amount': amount,
124                      'asset_id': asset.id,
125                      'sequence':i,
126                      'name': str(asset.id) +'/'+ str(i),
127                      'remaining_value': residual_amount,
128                      'depreciated_value': asset.purchase_value - residual_amount,
129                      'depreciation_date': depreciation_date.strftime('%Y-%m-%d'),
130                 }
131                 self.pool.get('account.asset.depreciation.line').create(cr, uid, vals)
132                 month += asset.method_period
133                 depreciation_date = datetime(year + (month / 12), month % 12, day)
134         return True
135
136     def validate(self, cr, uid, ids, context={}):
137         return self.write(cr, uid, ids, {
138             'state':'open'
139         }, context)
140
141     def _amount_total(self, cr, uid, ids, name, args, context={}):
142         #FIXME: function not working²
143         id_set=",".join(map(str,ids))
144         cr.execute("""SELECT l.asset_id,abs(SUM(l.debit-l.credit)) AS amount FROM
145                 account_move_line l
146             WHERE l.asset_id IN ("""+id_set+") GROUP BY l.asset_id ")
147         res=dict(cr.fetchall())
148         for id in ids:
149             res.setdefault(id, 0.0)
150         return res
151
152     def _amount_residual(self, cr, uid, ids, name, args, context={}):
153         cr.execute("""SELECT
154                 l.asset_id as id, SUM(abs(l.debit-l.credit)) AS amount
155             FROM
156                 account_move_line l
157             WHERE
158                 l.asset_id IN %s GROUP BY l.asset_id """, (tuple(ids),))
159         res=dict(cr.fetchall())
160         for asset in self.browse(cr, uid, ids, context):
161             res[asset.id] = asset.purchase_value - res.get(asset.id, 0.0)
162         for id in ids:
163             res.setdefault(id, 0.0)
164         return res
165
166     _columns = {
167         'period_id': fields.many2one('account.period', 'First Period', required=True, readonly=True, states={'draft':[('readonly',False)]}),
168         'account_move_line_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
169
170         'name': fields.char('Asset', size=64, required=True, select=1),
171         'code': fields.char('Reference ', size=16, select=1),
172         'purchase_value': fields.float('Gross value ', required=True, size=16, select=1),
173         'currency_id': fields.many2one('res.currency','Currency',required=True,size=5,select=1),
174         'company_id': fields.many2one('res.company', 'Company', required=True),
175         'note': fields.text('Note'),
176         'category_id': fields.many2one('account.asset.category', 'Asset category',required=True, change_default=True),
177         'localisation': fields.char('Localisation', size=32, select=2),
178         'parent_id': fields.many2one('account.asset.asset', 'Parent Asset'),
179         'child_ids': fields.one2many('account.asset.asset', 'parent_id', 'Children Assets'),
180         'purchase_date': fields.date('Purchase Date', required=True),
181         'state': fields.selection([('draft','Draft'),('open','Running'),('close','Close')], 'state', required=True),
182         'active': fields.boolean('Active', select=2),
183         'partner_id': fields.many2one('res.partner', 'Partner'),
184
185         'method': fields.selection([('linear','Linear'),('progressif','Progressive')], 'Computation method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
186         'method_delay': fields.integer('During (interval)', readonly=True, states={'draft':[('readonly',False)]}),
187         'method_period': fields.integer('Depre. all (period)', readonly=True, states={'draft':[('readonly',False)]}),
188         'method_end': fields.date('Ending date'),
189         'value_total': fields.function(_amount_total, method=True, digits=(16,2),string='Gross Value'),
190         'method_progress_factor': fields.float('Progressif Factor', readonly=True, states={'draft':[('readonly',False)]}),
191         'value_residual': fields.function(_amount_residual, method=True, digits=(16,2), string='Residual Value'),
192         'method_time': fields.selection([('delay','Delay'),('end','Ending Period')], 'Time Method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
193         'prorata':fields.boolean('Prorata Temporis', Readonly="True", help='Indicates that the accounting entries for this asset have to be done from the purchase date instead of the first January'),
194         'history_ids': fields.one2many('account.asset.history', 'asset_id', 'History', readonly=True),
195         'depreciation_line_ids': fields.one2many('account.asset.depreciation.line', 'asset_id', 'Depreciation Lines', readonly=True,),
196     }
197     _defaults = {
198         'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'account.asset.code'),
199         'purchase_date': lambda obj, cr, uid, context: time.strftime('%Y-%m-%d'),
200         'active': lambda obj, cr, uid, context: True,
201         'state': lambda obj, cr, uid, context: 'draft',
202         'period_id': _get_period,
203         'method': lambda obj, cr, uid, context: 'linear',
204         'method_delay': lambda obj, cr, uid, context: 5,
205         'method_time': lambda obj, cr, uid, context: 'delay',
206         'method_period': lambda obj, cr, uid, context: 12,
207         'method_progress_factor': lambda obj, cr, uid, context: 0.3,
208         'currency_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id,
209         'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'account.asset.asset',context=context),
210     }
211
212     def onchange_category_id(self, cr, uid, ids, category_id, context=None):
213         res = {'value':{}}
214         asset_categ_obj = self.pool.get('account.asset.category')
215         if category_id:
216             category_obj = asset_categ_obj.browse(cr, uid, category_id, context=context)
217             res['value'] = {
218                             'method': category_obj.method, 
219                             'method_delay': category_obj.method_delay,
220                             'method_time': category_obj.method_time,
221                             'method_period': category_obj.method_period,
222                             'method_progress_factor': category_obj.method_progress_factor,
223                             'prorata': category_obj.prorata,
224             }
225         return res
226     
227     def _compute_period(self, cr, uid, property, context={}):
228         if (len(property.entry_asset_ids or [])/2)>=property.method_delay:
229             return False
230         if len(property.entry_asset_ids):
231             cp = property.entry_asset_ids[-1].period_id
232             cpid = self.pool.get('account.period').next(cr, uid, cp, property.method_period, context)
233             current_period = self.pool.get('account.period').browse(cr, uid, cpid, context)
234         else:
235             current_period = property.asset_id.period_id
236         return current_period
237
238     def _compute_move(self, cr, uid, property, period, context={}):
239         #FIXME: fucntion not working OK
240         result = []
241         total = 0.0
242         for move in property.asset_id.entry_ids:
243             total += move.debit-move.credit
244         for move in property.entry_asset_ids:
245             if move.account_id == property.account_asset_ids:
246                 total += move.debit
247                 total += -move.credit
248         periods = (len(property.entry_asset_ids)/2) - property.method_delay
249
250         if periods==1:
251             amount = total
252         else:
253             if property.method == 'linear':
254                 amount = total / periods
255             else:
256                 amount = total * property.method_progress_factor
257
258         move_id = self.pool.get('account.move').create(cr, uid, {
259             'journal_id': property.journal_id.id,
260             'period_id': period.id,
261             'name': property.name or property.asset_id.name,
262             'ref': property.asset_id.code
263         })
264         result = [move_id]
265         id = self.pool.get('account.move.line').create(cr, uid, {
266             'name': property.name or property.asset_id.name,
267             'move_id': move_id,
268             'account_id': property.account_asset_id.id,
269             'debit': amount>0 and amount or 0.0,
270             'credit': amount<0 and -amount or 0.0,
271             'ref': property.asset_id.code,
272             'period_id': period.id,
273             'journal_id': property.journal_id.id,
274             'partner_id': property.asset_id.partner_id.id,
275             'date': time.strftime('%Y-%m-%d'),
276         })
277         id2 = self.pool.get('account.move.line').create(cr, uid, {
278             'name': property.name or property.asset_id.name,
279             'move_id': move_id,
280             'account_id': property.account_actif_id.id,
281             'credit': amount>0 and amount or 0.0,
282             'debit': amount<0 and -amount or 0.0,
283             'ref': property.asset_id.code,
284             'period_id': period.id,
285             'journal_id': property.journal_id.id,
286             'partner_id': property.asset_id.partner_id.id,
287             'date': time.strftime('%Y-%m-%d'),
288         })
289     #
290         self.pool.get('account.asset.asset').write(cr, uid, [property.id], {
291             'entry_asset_ids': [(4, id2, False),(4,id,False)]
292         })
293         if property.method_delay - (len(property.entry_asset_ids)/2)<=1:
294             #self.pool.get('account.asset.property')._close(cr, uid, property, context)
295             return result
296         return result
297
298     def _compute_entries(self, cr, uid, asset, period_id, context={}):
299         #FIXME: function not working CHECK all res
300         result = []
301         date_start = self.pool.get('account.period').browse(cr, uid, period_id, context).date_start
302         for property in asset.property_ids:
303             if property.state=='open':
304                 period = self._compute_period(cr, uid, property, context)
305                 if period and (period.date_start<=date_start):
306                     result += self._compute_move(cr, uid, property, period, context)
307         return result
308 account_asset_asset()
309
310 class account_asset_depreciation_line(osv.osv):
311     _name = 'account.asset.depreciation.line'
312     _description = 'Asset depreciation line'
313
314     def _get_move_check(self, cr, uid, ids, name, args, context=None):
315         res = {}
316         for line in self.browse(cr, uid, ids, context=context):
317             res[line.id] = bool(line.move_id)
318         return res
319
320     _columns = {
321         'name': fields.char('Depreciation Name', size=64, required=True, select=1),
322         'sequence': fields.integer('Sequence of the depreciation', required=True),
323         'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True),
324         'amount': fields.float('Depreciation Amount', required=True),
325         'remaining_value': fields.float('Amount to Depreciate', required=True),
326         'depreciated_value': fields.float('Amount Already Depreciated', required=True),
327         'depreciation_date': fields.char('Depreciation Date', size=64, select=1),
328         'move_id': fields.many2one('account.move', 'Depreciation Entry'),
329         'move_check': fields.function(_get_move_check, method=True, type='boolean', string='Posted', store=True)
330     }
331
332     def create_move(self, cr, uid,ids, context=None):
333         if context is None:
334             context = {}
335         asset_obj = self.pool.get('account.asset.asset')
336         period_obj = self.pool.get('account.period')
337         move_obj = self.pool.get('account.move')
338         move_line_obj = self.pool.get('account.move.line')
339         currency_obj = self.pool.get('res.currency')
340         for line in self.browse(cr, uid, ids, context=context):
341             depreciation_date = time.strftime('%Y-%m-%d')
342             period_ids = period_obj.find(cr, uid, depreciation_date, context=context)
343             company_currency = line.asset_id.company_id.currency_id.id
344             current_currency = line.asset_id.currency_id.id
345             context.update({'date': depreciation_date})
346             amount = currency_obj.compute(cr, uid, current_currency, company_currency, line.amount, context=context)
347             sign = line.asset_id.category_id.journal_id.type = 'purchase' and 1 or -1
348             move_vals = {
349                 'name': line.name,
350                 'date': depreciation_date,
351                 'ref': line.name,
352                 'period_id': period_ids and period_ids[0] or False,
353                 'journal_id': line.asset_id.category_id.journal_id.id,
354                 }
355             move_id = move_obj.create(cr, uid, move_vals, context=context)
356             move_line_obj.create(cr, uid, {
357                 'name': line.name,
358                 'ref': line.name,
359                 'move_id': move_id,
360                 'account_id': line.asset_id.category_id.account_depreciation_id.id,
361                 'debit': 0.0,
362                 'credit': amount,
363                 'period_id': period_ids and period_ids[0] or False,
364                 'journal_id': line.asset_id.category_id.journal_id.id,
365                 'partner_id': line.asset_id.partner_id.id,
366                 'currency_id': company_currency <> current_currency and  current_currency or False,
367                 'amount_currency': company_currency <> current_currency and - sign * line.amount or 0.0,
368                 'analytic_account_id': line.asset_id.category_id.account_analytic_id.id,
369                 'date': depreciation_date,
370             })
371             move_line_obj.create(cr, uid, {
372                 'name': line.name,
373                 'ref': line.name,
374                 'move_id': move_id,
375                 'account_id': line.asset_id.category_id.account_expense_depreciation_id.id,
376                 'credit': 0.0,
377                 'debit': amount,
378                 'period_id': period_ids and period_ids[0] or False,
379                 'journal_id': line.asset_id.category_id.journal_id.id,
380                 'partner_id': line.asset_id.partner_id.id,
381                 'currency_id': company_currency <> current_currency and  current_currency or False,
382                 'amount_currency': company_currency <> current_currency and sign * line.amount or 0.0,
383                 'analytic_account_id': line.asset_id.category_id.account_analytic_id.id,
384                 'date': depreciation_date,
385             })
386             self.write(cr, uid, line.id, {'move_id': move_id}, context=context)
387         return True
388
389 account_asset_depreciation_line()
390
391 #class account_asset_property(osv.osv):
392 #    def _amount_total(self, cr, uid, ids, name, args, context={}):
393 #        id_set=",".join(map(str,ids))
394 #        cr.execute("""SELECT l.asset_id,abs(SUM(l.debit-l.credit)) AS amount FROM
395 #                account_asset_property p
396 #            left join
397 #                account_move_line l on (p.asset_id=l.asset_id)
398 #            WHERE p.id IN ("""+id_set+") GROUP BY l.asset_id ")
399 #        res=dict(cr.fetchall())
400 #        for id in ids:
401 #            res.setdefault(id, 0.0)
402 #        return res
403 #
404 #    def _close(self, cr, uid, property, context={}):
405 #        if property.state<>'close':
406 #            self.pool.get('account.asset.property').write(cr, uid, [property.id], {
407 #                'state': 'close'
408 #            })
409 #            property.state='close'
410 #        ok = property.asset_id.state=='open'
411 #        for prop in property.asset_id.property_ids:
412 #            ok = ok and prop.state=='close'
413 #        self.pool.get('account.asset.asset').write(cr, uid, [property.asset_id.id], {
414 #            'state': 'close'
415 #        }, context)
416 #        return True
417 #
418 #    _name = 'account.asset.property'
419 #    _description = 'Asset property'
420 #    _columns = {
421 #        'name': fields.char('Method name', size=64, select=1),
422 #        'type': fields.selection([('direct','Direct'),('indirect','Indirect')], 'Depr. method type', select=2, required=True),
423 #        'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True),
424 #        'account_asset_id': fields.many2one('account.account', 'Asset account', required=True),
425 #        'account_actif_id': fields.many2one('account.account', 'Depreciation account', required=True),
426 #        'journal_id': fields.many2one('account.journal', 'Journal', required=True),
427 #        'journal_analytic_id': fields.many2one('account.analytic.journal', 'Analytic journal'),
428 #        'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
429 #
430 #        'method': fields.selection([('linear','Linear'),('progressif','Progressive')], 'Computation method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
431 #        'method_delay': fields.integer('During', readonly=True, states={'draft':[('readonly',False)]}),
432 #        'method_period': fields.integer('Depre. all', readonly=True, states={'draft':[('readonly',False)]}),
433 #        'method_end': fields.date('Ending date'),
434 #
435 #        'date': fields.date('Date created'),
436 #    #'test': fields.one2many('account.pre', 'asset_id',  readonly=True, states={'draft':[('readonly',False)]}),
437 #        'entry_asset_ids': fields.many2many('account.move.line', 'account_move_asset_entry_rel', 'asset_property_id', 'move_id', 'Asset Entries'),
438 #        'board_ids': fields.one2many('account.asset.board', 'asset_id', 'Asset board'),
439 #
440 #        'value_total': fields.function(_amount_total, method=True, digits=(16,2),string='Gross value'),
441 #        'state': fields.selection([('draft','Draft'), ('open','Open'), ('close','Close')], 'State', required=True),
442 #        'history_ids': fields.one2many('account.asset.property.history', 'asset_property_id', 'History', readonly=True)
443 ##    'parent_id': fields.many2one('account.asset.asset', 'Parent asset'),
444 ##    'partner_id': fields.many2one('res.partner', 'Partner'),
445 ##    'note': fields.text('Note'),
446 #
447 #    }
448 #    _defaults = {
449 #        'type': lambda obj, cr, uid, context: 'direct',
450 #        'state': lambda obj, cr, uid, context: 'draft',
451 #        'method': lambda obj, cr, uid, context: 'linear',
452 #        'method_time': lambda obj, cr, uid, context: 'delay',
453 #        'method_progress_factor': lambda obj, cr, uid, context: 0.3,
454 #        'method_delay': lambda obj, cr, uid, context: 5,
455 #        'method_period': lambda obj, cr, uid, context: 12,
456 #        'date': lambda obj, cr, uid, context: time.strftime('%Y-%m-%d')
457 #    }
458 #account_asset_property()
459
460 class account_move_line(osv.osv):
461     _inherit = 'account.move.line'
462     _columns = {
463         'asset_id': fields.many2one('account.asset.asset', 'Asset'),
464         'entry_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
465
466     }
467 account_move_line()
468
469 class account_asset_history(osv.osv):
470     _name = 'account.asset.history'
471     _description = 'Asset history'
472     _columns = {
473         'name': fields.char('History name', size=64, select=1),
474         'user_id': fields.many2one('res.users', 'User', required=True),
475         'date': fields.date('Date', required=True),
476         'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True),
477         'method_delay': fields.integer('Number of interval'),
478         'method_period': fields.integer('Period per interval'),
479         'method_end': fields.date('Ending date'),
480         'note': fields.text('Note'),
481     }
482     _defaults = {
483         'date': lambda *args: time.strftime('%Y-%m-%d'),
484         'user_id': lambda self,cr, uid,ctx: uid
485     }
486 account_asset_history()
487
488 class account_asset_board(osv.osv):
489     _name = 'account.asset.board'
490     _description = 'Asset board'
491     _columns = {
492         'name': fields.char('Asset name', size=64, required=True, select=1),
493         'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True, select=1),
494         'value_gross': fields.float('Gross value', required=True, select=1),
495         'value_asset': fields.float('Asset Value', required=True, select=1),
496         'value_asset_cumul': fields.float('Cumul. value', required=True, select=1),
497         'value_net': fields.float('Net value', required=True, select=1),
498
499     }
500     _auto = False
501     def init(self, cr):
502         cr.execute("""
503             create or replace view account_asset_board as (
504                 select
505                     min(l.id) as id,
506                     min(l.id) as asset_id,
507                     0.0 as value_gross,
508                     0.0 as value_asset,
509                     0.0 as value_asset_cumul,
510                     0.0 as value_net
511                 from
512                     account_move_line l
513                 where
514                     l.state <> 'draft' and
515                     l.asset_id=3
516             )""")
517 account_asset_board()
518
519 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: