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