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