[ADD] Add Fiscal year concept and Asset report and misc

This commit is contained in:
Haresh Chavda 2018-07-24 16:45:11 +05:30
parent 488bb3d8e6
commit 1b2971d5b8
24 changed files with 972 additions and 36 deletions

View File

@ -22,14 +22,20 @@ Keeps track of depreciations, and creates corresponding journal entries.
'security/account_asset_security.xml',
'security/ir.model.access.csv',
'wizard/asset_depreciation_confirmation_wizard_views.xml',
'data/account_asset_data.xml',
'wizard/asset_modify_views.xml',
'wizard/sale_asset_wizard_view.xml',
'wizard/scrap_asset_wizard_view.xml',
'wizard/asset_depreciation_summary_wizard_view.xml',
'views/account_asset_views.xml',
'views/account_invoice_views.xml',
'views/account_asset_templates.xml',
'views/product_views.xml',
'views/res_config_settings_views.xml',
'report/account_asset_report_views.xml',
'data/account_asset_data.xml',
'report/report_paperformat.xml',
'report/asset_reports.xml',
'report/asset_depreciation_report_template.xml',
'report/account_asset_report_views.xml'
],
'qweb': [
"static/src/xml/account_asset_template.xml",

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding='UTF-8'?>
<flectra>
<record id="account_asset_cron" model="ir.cron">
<record id="account_asset_cron" model="ir.cron">
<field name="name">Account Asset: Generate asset entries</field>
<field name="model_id" ref="model_account_asset_asset"/>
<field name="state">code</field>

View File

@ -49,7 +49,7 @@
}
self._update('account.asset.asset', 'account_asset', vals, 'account_asset_asset_cab0')
vals = {
'prorata': 1,
'prorata': 'purchase_date',
'salvage_value': 100000.0,
'state': 'open',
'method_period': 12,
@ -60,3 +60,26 @@
'category_id': ref('account_asset_category_fixedassets0'),
}
self._update('account.asset.asset', 'account_asset', vals, 'account_asset_asset_office0')
product_id = ref('product.consu_delivery_03')
vals = {
'journal_id': journal_id,
'name': 'Electronics',
'method_number': 6,
'account_asset_id': xfa_account_id,
'account_depreciation_id': xfa_account_id,
'account_depreciation_expense_id': expense_account_id,
}
self._update('account.asset.category', 'account_asset', vals, 'account_asset_category_electronics')
vals = {
'prorata': 'fiscal_year',
'product_id': product_id,
'salvage_value': 1000.0,
'state': 'open',
'method_period': 12,
'method_number': 6,
'date': time.strftime('%Y-01-01'),
'name': 'Basic Computer',
'value': 23500.0,
'category_id': ref('account_asset_category_electronics'),
}
self._update('account.asset.asset', 'account_asset', vals, 'account_asset_asset_electronics')

View File

@ -8,6 +8,7 @@ class AccountMove(models.Model):
_inherit = 'account.move'
asset_depreciation_ids = fields.One2many('account.asset.depreciation.line', 'move_id', string='Assets Depreciation Lines', ondelete="restrict")
asset_id = fields.Many2one('account.asset.asset', string="Asset")
@api.multi
def button_cancel(self):
@ -22,3 +23,9 @@ class AccountMove(models.Model):
for depreciation_line in move.asset_depreciation_ids:
depreciation_line.post_lines_and_close_asset()
return super(AccountMove, self).post()
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
asset_id = fields.Many2one(related='move_id.asset_id', string="Asset")

View File

@ -30,15 +30,20 @@ class AccountAssetCategory(models.Model):
method_number = fields.Integer(string='Number of Depreciations', default=5, help="The number of depreciations needed to depreciate your asset")
method_period = fields.Integer(string='Period Length', default=1, help="State here the time between 2 depreciations, in months", required=True)
method_progress_factor = fields.Float('Degressive Factor', default=0.3)
method_time = fields.Selection([('number', 'Number of Entries'), ('end', 'Ending Date')], string='Time Method', required=True, default='number',
method_time = fields.Selection([('number', 'Number of Depreciations'), ('end', 'Ending Date')], string='Time Method', required=True, default='number',
help="Choose the method to use to compute the dates and number of entries.\n"
" * Number of Entries: Fix the number of entries and the time between 2 depreciations.\n"
" * Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond.")
method_end = fields.Date('Ending date')
prorata = fields.Boolean(string='Prorata Temporis', help='Indicates that the first depreciation entry for this asset have to be done from the purchase date instead of the first of January')
prorata = fields.Selection([('first_january', 'First of January'),
('purchase_date', 'From the Purchase Date'),
('fiscal_year', 'Fiscal Year')],
help='Indicates that the first depreciation entry for this asset have to be done from the purchase date or first of January or fiscal year')
open_asset = fields.Boolean(string='Auto-confirm Assets', help="Check this if you want to automatically confirm the assets of this category when created by invoices.")
group_entries = fields.Boolean(string='Group Journal Entries', help="Check this if you want to group the generated entries by categories.")
type = fields.Selection([('sale', 'Sale: Revenue Recognition'), ('purchase', 'Purchase: Asset')], required=True, index=True, default='purchase')
asset_ids = fields.One2many('account.asset.asset', 'category_id',
string='Asset Line')
@api.onchange('account_asset_id')
def onchange_account_asset(self):
@ -50,7 +55,7 @@ class AccountAssetCategory(models.Model):
@api.onchange('type')
def onchange_type(self):
if self.type == 'sale':
self.prorata = True
self.prorata = 'purchase_date'
self.method_period = 1
else:
self.method_period = 12
@ -58,7 +63,12 @@ class AccountAssetCategory(models.Model):
@api.onchange('method_time')
def _onchange_method_time(self):
if self.method_time != 'number':
self.prorata = False
self.prorata = 'first_january'
@api.onchange('prorata')
def onchange_prorata(self):
if self.prorata == 'fiscal_year':
self.method_period = 12
class AccountAssetAsset(models.Model):
@ -83,6 +93,12 @@ class AccountAssetAsset(models.Model):
"You can manually close an asset when the depreciation is over. If the last line of depreciation is posted, the asset automatically goes in that status.")
active = fields.Boolean(default=True)
partner_id = fields.Many2one('res.partner', string='Partner', readonly=True, states={'draft': [('readonly', False)]})
product_id = fields.Many2one('product.product', string='Product',
track_visibility='onchange')
invoice_count = fields.Integer(string="Invoice",
compute="count_invoice")
remaining_asset_value = fields.Float(string="Remaining Asset Value",
compute="get_remaining_value")
method = fields.Selection([('linear', 'Linear'), ('degressive', 'Degressive')], string='Computation Method', required=True, readonly=True, states={'draft': [('readonly', False)]}, default='linear',
help="Choose the method to use to compute the amount of depreciation lines.\n * Linear: Calculated on basis of: Gross Value / Number of Depreciations\n"
" * Degressive: Calculated on basis of: Residual Value * Degressive Factor")
@ -92,18 +108,73 @@ class AccountAssetAsset(models.Model):
method_end = fields.Date(string='Ending Date', readonly=True, states={'draft': [('readonly', False)]})
method_progress_factor = fields.Float(string='Degressive Factor', readonly=True, default=0.3, states={'draft': [('readonly', False)]})
value_residual = fields.Float(compute='_amount_residual', method=True, digits=0, string='Residual Value')
method_time = fields.Selection([('number', 'Number of Entries'), ('end', 'Ending Date')], string='Time Method', required=True, readonly=True, default='number', states={'draft': [('readonly', False)]},
help="Choose the method to use to compute the dates and number of entries.\n"
" * Number of Entries: Fix the number of entries and the time between 2 depreciations.\n"
method_time = fields.Selection([('number', 'Number of Entries'), ('end', 'Ending Date')], string='Time Method', required=True, readonly=True, default='number', states={'draft': [('readonly', False)]}, track_visibility='onchange',
help="Choose the method to use to compute the dates and number of depreciation lines.\n"
" * Number of Depreciation lines: Fix the number of depreciation lines and the time between 2 depreciations.\n"
" * Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond.")
prorata = fields.Boolean(string='Prorata Temporis', readonly=True, states={'draft': [('readonly', False)]},
help='Indicates that the first depreciation entry for this asset have to be done from the purchase date instead of the first January / Start date of fiscal year')
sale_date = fields.Date(string='Sale Date')
prorata = fields.Selection([('first_january', 'First of January'),
('purchase_date', 'From the Purchase Date'),
('fiscal_year', 'Fiscal Year')],
readonly=True, states={'draft': [('readonly', False)]},
help='Indicates that the first depreciation entry for this asset have to be done from the purchase date or first of January or fiscal year')
depreciation_line_ids = fields.One2many('account.asset.depreciation.line', 'asset_id', string='Depreciation Lines', readonly=True, states={'draft': [('readonly', False)], 'open': [('readonly', False)]})
salvage_value = fields.Float(string='Salvage Value', digits=0, readonly=True, states={'draft': [('readonly', False)]},
help="It is the amount you plan to have that you cannot depreciate.")
invoice_id = fields.Many2one('account.invoice', string='Invoice', states={'draft': [('readonly', False)]}, copy=False)
type = fields.Selection(related="category_id.type", string='Type', required=True)
@api.onchange('prorata')
def onchange_prorata(self):
if self.prorata == 'fiscal_year':
self.method_period = 12
@api.multi
def get_remaining_value(self):
for record in self:
posted_line_id = record.depreciation_line_ids.search(
[('move_check', '=', True), ('asset_id', '=', record.id)],
limit=1, order='id desc')
record.remaining_asset_value = posted_line_id.remaining_value
@api.onchange('product_id')
def on_product_id_change(self):
self.category_id = self.product_id.asset_category_id
self.value = self.product_id.list_price
@api.depends('prorata')
def get_fiscal_date(self, date):
if self.prorata == 'fiscal_year':
last_day = self.company_id.fiscalyear_last_day
last_month = self.company_id.fiscalyear_last_month
if date:
date = datetime.strptime(date, DF).date()
else:
date = datetime.now()
if date.month <= 3 and date.day < 31:
year = date.year
else:
year = date.year + 1
date = date.replace(month=last_month, day=last_day, year=year)
return datetime.strftime(date, '%Y-%m-%d')
@api.multi
def count_invoice(self):
for self_obj in self:
count = self.env['account.invoice'].search_count(
[('asset_id', '=', self_obj.id)])
self_obj.invoice_count = count
def redirect_to_invoice(self):
return {
'name': (_('Invoices')),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'domain': [('asset_id', '=', self.id)]
}
@api.multi
def unlink(self):
for asset in self:
@ -156,8 +227,11 @@ class AccountAssetAsset(models.Model):
amount = residual_amount
else:
if self.method == 'linear':
# Manage last line with remaining amount
if self.prorata == 'fiscal_year':
undone_dotation_number = undone_dotation_number - 1
amount = amount_to_depr / (undone_dotation_number - len(posted_depreciation_line_ids))
if self.prorata:
if self.prorata == 'purchase_date':
amount = amount_to_depr / self.method_number
if sequence == 1:
if self.method_period % 12 != 0:
@ -168,9 +242,14 @@ class AccountAssetAsset(models.Model):
else:
days = (self.company_id.compute_fiscalyear_dates(depreciation_date)['date_to'] - depreciation_date).days + 1
amount = (amount_to_depr / self.method_number) / total_days * days
elif self.prorata == 'fiscal_year' and sequence == 1:
fiscal_date = datetime.strptime(self.date or fields.Datetime.today(), '%Y-%m-%d')
days = (self.company_id.compute_fiscalyear_dates(depreciation_date)['date_to'] - fiscal_date.date()).days
amount = (amount_to_depr / self.method_number) / total_days * days
elif self.method == 'degressive':
amount = residual_amount * self.method_progress_factor
if self.prorata:
if self.prorata == 'purchase_date':
if sequence == 1:
if self.method_period % 12 != 0:
date = datetime.strptime(self.date, '%Y-%m-%d')
@ -180,6 +259,10 @@ class AccountAssetAsset(models.Model):
else:
days = (self.company_id.compute_fiscalyear_dates(depreciation_date)['date_to'] - depreciation_date).days + 1
amount = (residual_amount * self.method_progress_factor) / total_days * days
elif self.prorata == 'fiscal_year' and sequence == 1:
fiscal_date = datetime.strptime(self.date or fields.Datetime.today(), '%Y-%m-%d')
days = (self.company_id.compute_fiscalyear_dates(depreciation_date)['date_to'] - fiscal_date.date()).days
amount = (residual_amount * self.method_progress_factor) / total_days * days
return amount
def _compute_board_undone_dotation_nb(self, depreciation_date, total_days):
@ -190,7 +273,7 @@ class AccountAssetAsset(models.Model):
while depreciation_date <= end_date:
depreciation_date = date(depreciation_date.year, depreciation_date.month, depreciation_date.day) + relativedelta(months=+self.method_period)
undone_dotation_number += 1
if self.prorata:
if self.prorata in ['purchase_date', 'fiscal_year']:
undone_dotation_number += 1
return undone_dotation_number
@ -206,13 +289,20 @@ class AccountAssetAsset(models.Model):
if self.value_residual != 0.0:
amount_to_depr = residual_amount = self.value_residual
if self.prorata:
if self.prorata == 'purchase_date':
# if we already have some previous validated entries, starting date is last entry + method perio
if posted_depreciation_line_ids and posted_depreciation_line_ids[-1].depreciation_date:
last_depreciation_date = datetime.strptime(posted_depreciation_line_ids[-1].depreciation_date, DF).date()
depreciation_date = last_depreciation_date + relativedelta(months=+self.method_period)
else:
depreciation_date = datetime.strptime(self._get_last_depreciation_date()[self.id], DF).date()
elif self.prorata == 'fiscal_year':
if posted_depreciation_line_ids and posted_depreciation_line_ids[-1].depreciation_date:
last_depreciation_date = datetime.strptime(posted_depreciation_line_ids[-1].depreciation_date, DF).date()
depreciation_date = last_depreciation_date + relativedelta(months=+self.method_period)
else:
fiscal_date = self.get_fiscal_date(self.date)
depreciation_date = datetime.strptime(fiscal_date, DF).date()
else:
# depreciation_date = 1st of January of purchase year if annual valuation, 1st of
# purchase month in other cases
@ -366,7 +456,7 @@ class AccountAssetAsset(models.Model):
@api.one
@api.constrains('prorata', 'method_time')
def _check_prorata(self):
if self.prorata and self.method_time != 'number':
if self.prorata == 'purchase_date' and self.method_time != 'number':
raise ValidationError(_('Prorata temporis can be applied only for time method "number of depreciations".'))
@api.onchange('category_id')
@ -395,7 +485,7 @@ class AccountAssetAsset(models.Model):
@api.onchange('method_time')
def onchange_method_time(self):
if self.method_time != 'number':
self.prorata = False
self.prorata = 'first_january'
@api.multi
def copy_data(self, default=None):
@ -416,7 +506,7 @@ class AccountAssetAsset(models.Model):
@api.model
def create(self, vals):
asset = super(AccountAssetAsset, self.with_context(mail_create_nolog=True)).create(vals)
asset.compute_depreciation_board()
asset.sudo().compute_depreciation_board()
return asset
@api.multi
@ -460,6 +550,14 @@ class AccountAssetDepreciationLine(models.Model):
move_id = fields.Many2one('account.move', string='Depreciation Entry')
move_check = fields.Boolean(compute='_get_move_check', string='Linked', track_visibility='always', store=True)
move_posted_check = fields.Boolean(compute='_get_move_posted_check', string='Posted', track_visibility='always', store=True)
product_id = fields.Many2one(related='asset_id.product_id', relation="product.product", string="SID")
begin_value = fields.Float(compute='_get_begin_value', string="Beginning Value", store=True)
@api.multi
@api.depends('asset_id.value', 'asset_id.salvage_value')
def _get_begin_value(self):
for line in self:
line.begin_value = line.asset_id.value - line.asset_id.salvage_value
@api.multi
@api.depends('move_id')
@ -473,13 +571,23 @@ class AccountAssetDepreciationLine(models.Model):
for line in self:
line.move_posted_check = True if line.move_id and line.move_id.state == 'posted' else False
@api.multi
def action_move_cancel(self):
for line in self.asset_id.depreciation_line_ids:
if line.id >= self.id and line.move_check:
line.move_check = False
line.move_id.button_cancel()
@api.multi
def create_move(self, post_move=True):
created_moves = self.env['account.move']
prec = self.env['decimal.precision'].precision_get('Account')
for line in self:
if line.move_id:
raise UserError(_('This depreciation is already linked to a journal entry! Please post or delete it.'))
# raise UserError(_('This depreciation is already linked to a journal entry! Please post or delete it.'))
line.move_id.post()
line.write({'move_check': True})
return [x.id for x in line.move_id]
category_id = line.asset_id.category_id
depreciation_date = self.env.context.get('depreciation_date') or line.depreciation_date or fields.Date.context_today(self)
company_currency = line.asset_id.company_id.currency_id
@ -512,6 +620,7 @@ class AccountAssetDepreciationLine(models.Model):
'ref': line.asset_id.code,
'date': depreciation_date or False,
'journal_id': category_id.journal_id.id,
'asset_id': line.asset_id.id,
'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)],
}
move = self.env['account.move'].create(move_vals)

View File

@ -3,7 +3,8 @@
from datetime import datetime
from dateutil.relativedelta import relativedelta
from flectra import api, fields, models
from flectra.exceptions import UserError
from flectra import api, fields, models, _
from flectra.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from flectra.addons import decimal_precision as dp
@ -12,6 +13,9 @@ from flectra.addons import decimal_precision as dp
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
asset_id = fields.Many2one('account.asset.asset')
asset_bool = fields.Boolean(string="Asset")
@api.model
def _refund_cleanup_lines(self, lines):
result = super(AccountInvoice, self)._refund_cleanup_lines(lines)
@ -45,6 +49,8 @@ class AccountInvoice(models.Model):
class AccountInvoiceLine(models.Model):
_inherit = 'account.invoice.line'
asset_id = fields.Many2one('account.asset.asset')
asset_bool = fields.Boolean(string="Asset")
asset_category_id = fields.Many2one('account.asset.category', string='Asset Category')
asset_start_date = fields.Date(string='Asset Start Date', compute='_get_asset_date', readonly=True, store=True)
asset_end_date = fields.Date(string='Asset End Date', compute='_get_asset_date', readonly=True, store=True)
@ -71,9 +77,13 @@ class AccountInvoiceLine(models.Model):
@api.one
def asset_create(self):
if self.asset_category_id:
if not self.asset_category_id:
self.write(
{'asset_category_id': self.product_id.asset_category_id.id})
if self.asset_category_id and not self.asset_bool:
vals = {
'name': self.name,
'product_id': self.product_id.id,
'code': self.invoice_id.number or False,
'category_id': self.asset_category_id.id,
'value': self.price_subtotal_signed,
@ -86,6 +96,7 @@ class AccountInvoiceLine(models.Model):
changed_vals = self.env['account.asset.asset'].onchange_category_id_values(vals['category_id'])
vals.update(changed_vals['value'])
asset = self.env['account.asset.asset'].create(vals)
self.invoice_id.update({'asset_id': asset.id})
if self.asset_category_id.open_asset:
asset.validate()
return True

View File

@ -2,3 +2,5 @@
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
from . import account_asset_report
from . import asset_depreciation_report

View File

@ -3,6 +3,7 @@
from flectra import api, fields, models, tools
class AssetAssetReport(models.Model):
_name = "asset.asset.report"
_description = "Assets Analysis"

View File

@ -0,0 +1,104 @@
# Part of Flectra. See LICENSE file for full copyright and licensing
# details.
from flectra import api, models, _
from datetime import datetime
from flectra.exceptions import UserError
class AssetDepreciation(models.AbstractModel):
_name = "report.account_asset.asset_depreciation_template"
def get_date(self, data):
date_lst = [{
'start_date': data['start_date'],
'end_date': data['end_date']
}]
return date_lst
def get_data(self, data):
asset_dep_line_id_list = list()
asset_dep_line_id_list = \
self.env['account.asset.depreciation.line'].search([
('depreciation_date', '>=', data['start_date']),
('depreciation_date', '<=', data['end_date']),
('move_check', '=', True),
('move_id', '!=', False),
('move_id.state', '=', 'posted')
])
if not asset_dep_line_id_list:
raise UserError(_("No Depreciation Lines in this fiscal year.."))
data_dict = {}
for line_id in asset_dep_line_id_list:
product_id = line_id.asset_id.product_id.id
depre_date = datetime.strptime(
line_id.depreciation_date, "%Y-%m-%d")
purchase_date = datetime.strptime(
line_id.asset_id.date, "%Y-%m-%d")
if product_id not in data_dict:
if depre_date.year == purchase_date.year \
or line_id.sequence == 1:
open_asset = 0.0
open_dep = 0.0
add_asset = line_id.asset_id.value_residual
else:
open_asset = line_id.asset_id.value_residual
add_asset = 0.00
open_dep = line_id.depreciated_value - line_id.amount
add_dep = line_id.amount
total_dep = open_dep + add_dep
total_asset = open_asset + add_asset
data_dict[product_id] = {
'name': line_id.asset_id.name,
'product_name': line_id.asset_id.product_id.name,
'category': line_id.asset_id.category_id.name,
'open_asset': open_asset,
'add_asset': add_asset,
'total_asset': total_asset,
'open_dep': open_dep,
'add_dep': add_dep,
'total_dep': total_dep,
'open_net': open_asset - open_dep,
'add_net': add_asset - add_dep,
'total_net': total_asset - total_dep
}
else:
add_dep = line_id.amount
if depre_date.year == purchase_date.year \
or line_id.sequence == 1:
open_asset = 0.0
add_asset = line_id.asset_id.value_residual
open_dep = 0.0
else:
open_asset = line_id.asset_id.value_residual
add_asset = 0.00
open_dep = line_id.depreciated_value - line_id.amount
if line_id.asset_id.sale_date \
and line_id.asset_id.sale_date >= data['start_date'] \
and line_id.asset_id.sale_date <= data['end_date']:
add_asset -= line_id.begin_value
add_dep -= line_id.depreciated_value
total_dep = open_dep + add_dep
total_asset = open_asset + add_asset
data_dict[product_id]['open_asset'] += open_asset
data_dict[product_id]['add_asset'] += add_asset
data_dict[product_id]['total_asset'] += total_asset
data_dict[product_id]['open_dep'] += open_dep
data_dict[product_id]['add_dep'] += add_dep
data_dict[product_id]['total_dep'] += total_dep
data_dict[product_id]['open_net'] += open_asset - open_dep
data_dict[product_id]['add_net'] += add_asset - add_dep
data_dict[product_id]['total_net'] += total_asset - total_dep
final_data = []
for key in data_dict:
final_data.append(data_dict[key])
return final_data
@api.model
def get_report_values(self, docids, data=None):
report_lines = self.get_data(data.get('form'))
model = self.env.context.get('active_model')
docs = self.env[model].browse(self.env.context.get('active_id'))
return {'doc_ids': docids, 'doc_model': model, 'data': data,
'docs': docs, 'get_data': report_lines}

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<flectra>
<template id="asset_depreciation_template">
<t t-call="web.html_container">
<t t-call="web.internal_layout">
<div class="page">
<h2>Asset Depreciation</h2>
<div class="row mt32">
<div class="col-xs-3">
<strong>Start Date:</strong>
<p t-esc="data['form']['start_date']"/>
</div>
<div class="col-xs-3">
<strong>End Date:</strong>
<p t-esc="data['form']['end_date']"/>
</div>
</div>
<br/>
<br/>
<table class="table table-bordered">
<tr>
<th colspan="2"></th>
<th colspan="3" class="text-center">Assets</th>
<th colspan="3" class="text-center">Depreciation</th>
<th colspan="3" class="text-center">Closing Balance</th>
</tr>
<tr>
<th class="text-center">Asset Name</th>
<th class="text-center">Category</th>
<th class="text-center">Opening</th>
<th class="text-center">Additional</th>
<th class="text-center">Total</th>
<th class="text-center">Opening</th>
<th class="text-center">Additional</th>
<th class="text-center">Total</th>
<th class="text-center">Opening</th>
<th class="text-center">Additional</th>
<th class="text-center">Total</th>
</tr>
<tr t-foreach="get_data" t-as="object">
<td>
<t t-esc="object['name']"/>
</td>
<td>
<t t-esc="object['category']"/>
</td>
<td align="right">
<t t-esc="object['open_asset']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['add_asset']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['total_asset']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['open_dep']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['add_dep']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['total_dep']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['open_net']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['add_net']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
<td align="right">
<t t-esc="object['total_net']"
t-options='{"widget": "monetary", "display_currency": res_company.currency_id}'/>
</td>
</tr>
</table>
</div>
</t>
</t>
</template>
</flectra>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<flectra>
<report
id="asset_depreciation_report"
model="account.asset.asset"
string="Asset Depreciation Report"
report_type="qweb-pdf"
name="account_asset.asset_depreciation_template"
file="account_asset.asset_depreciation_template"
menu="False"
/>
</flectra>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<flectra>
<record id="asset_depreciation_report_format" model="report.paperformat">
<field name="name">Asset Depreciation Report Format</field>
<field name="default" eval="True"/>
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Landscape</field>
<field name="margin_top">40</field>
<field name="margin_bottom">20</field>
<field name="margin_left">7</field>
<field name="margin_right">7</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">43</field>
<field name="dpi">90</field>
</record>
</flectra>

View File

@ -26,6 +26,32 @@
<field name="method_period">12</field>
</record>
<record id="account_asset_category_1" model="account.asset.category">
<field name="name">Furniture</field>
<field name="account_depreciation_id" ref="xfa"/>
<field name="account_depreciation_expense_id" ref="a_expense"/>
<field name="account_asset_id" ref="xfa"/>
<field name="journal_id" ref="expenses_journal"/>
<field name="method_time">number</field>
<field name="method_number">5</field>
<field name="method_period">12</field>
<field name="method">linear</field>
<field name="open_asset" eval="True"/>
</record>
<record id="account_asset_category_2" model="account.asset.category">
<field name="name">Electronics</field>
<field name="account_depreciation_id" ref="xfa"/>
<field name="account_depreciation_expense_id" ref="a_expense"/>
<field name="account_asset_id" ref="xfa"/>
<field name="journal_id" ref="expenses_journal"/>
<field name="method_time">number</field>
<field name="method_number">6</field>
<field name="method_period">12</field>
<field name="method">linear</field>
<field name="open_asset" eval="True"/>
</record>
<!--
Assets Demo
-->
@ -50,7 +76,7 @@
</record>
<record id="account_asset_asset_office_test0" model="account.asset.asset">
<field eval="1" name="prorata"/>
<field name="prorata">purchase_date</field>
<field eval="100000.0" name="salvage_value"/>
<field name="state">open</field>
<field eval="12" name="method_period"/>
@ -61,6 +87,45 @@
<field name="category_id" ref="account_asset_category_fixedassets_test0"/>
</record>
<record id="product_product_id_1" model="product.product">
<field name="name">Asset Product</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="standard_price">100</field>
<field name="list_price">150</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
<field name="description">Asset Product</field>
<field name="default_code">AP</field>
</record>
<record id="account_asset_1" model="account.asset.asset">
<field name="name">Asset 1</field>
<field name="product_id" ref="product_product_id_1"/>
<field name="category_id" ref="account_asset_category_1"/>
<field name="partner_id" ref="base.res_partner_1"/>
<field name="date" eval="time.strftime('%Y-%m-%d')"/>
<field name="value">50000</field>
<field name="salvage_value">10000</field>
<field name="method">linear</field>
<field name="method_number">5</field>
<field name="method_period">12</field>
<field name="prorata">first_january</field>
</record>
<record id="account_asset_2" model="account.asset.asset">
<field name="name">Asset 2</field>
<field name="product_id" ref="product_product_id_1"/>
<field name="category_id" ref="account_asset_category_2"/>
<field name="partner_id" ref="base.res_partner_1"/>
<field name="date" eval="time.strftime('%Y-%m-%d')"/>
<field name="value">40000</field>
<field name="salvage_value">10000</field>
<field name="method">linear</field>
<field name="method_number">5</field>
<field name="method_period">12</field>
<field name="prorata">fiscal_year</field>
</record>
</data>
</flectra>

View File

@ -4,6 +4,9 @@
from flectra import tools
from flectra.tests import common
from flectra.modules.module import get_resource_path
from datetime import date, datetime
from flectra.tools import DEFAULT_SERVER_DATE_FORMAT as DF
import logging
class TestAccountAsset(common.TransactionCase):
@ -17,6 +20,10 @@ class TestAccountAsset(common.TransactionCase):
self._load('account', 'test', 'account_minimal_test.xml')
self._load('account_asset', 'test', 'account_asset_demo_test.xml')
self.asset_id_1 = self.env.ref("account_asset.account_asset_1")
self.asset_id_2 = self.env.ref("account_asset.account_asset_2")
self.partner_id = self.env.ref("base.res_partner_2")
# In order to test the process of Account Asset, I perform a action to confirm Account Asset.
self.browse_ref("account_asset.account_asset_asset_vehicles_test0").validate()
@ -64,3 +71,82 @@ class TestAccountAsset(common.TransactionCase):
}
asset_compute_period_0 = self.env['asset.depreciation.confirmation.wizard'].create({})
asset_compute_period_0.with_context(context).asset_compute()
assert self.asset_id_1.product_id, "Product is not there in %s" % \
self.asset_id_1
assert self.asset_id_1.category_id, "Asset Category is not there " \
"in %s" % self.asset_id_1
assert self.asset_id_1.partner_id, "Vendor is not defined in %s" % \
self.asset_id_1
assert self.asset_id_1.date, "Asset Purchase date is not defined."
assert self.asset_id_1.value, "Definig an asset value is necessary"
if self.asset_id_1.method is 'degressive':
assert self.asset_id_1.method_progress_factor, \
"Degressive Factor is required for further calculation"
if self.asset_id_1.method_time is 'number':
assert self.asset_id_1.method_number, "Method number is required"
if self.asset_id_1.method_time is 'end':
assert self.asset_id_1.method_end, "Ending Date is required"
assert self.asset_id_1.method_period, "Field 'Number of months in " \
"a period is blank'"
self.asset_id_1.validate()
if self.asset_id_1.state != 'open':
raise AssertionError("Asset state must be in open state!")
sale_asset_id = self.env['sale.asset.wizard'].create({
'asset_id': self.asset_id_1.id,
'product_id': self.asset_id_1.product_id.id,
'asset_category_id': self.asset_id_1.category_id.id,
'sale_date': date.today(),
'partner_id': self.partner_id.id,
})
sale_asset_id.onchange_sale_date()
sale_asset_id.with_context(
{'active_id': self.asset_id_1.id}).sale_asset()
if self.asset_id_1.state != 'close':
raise AssertionError("Asset is not sold")
else:
logging.info("Asset Sale Function successfully executed")
scrap_asset_id = self.env['scrap.asset.wizard'].create({
'partner_id': self.asset_id_1.partner_id.id,
'asset_id': self.asset_id_1.id,
'product_id': self.asset_id_1.product_id.id,
'asset_category_id': self.asset_id_1.category_id.id,
'depreciated_amount': self.asset_id_1.remaining_asset_value,
'sale_date': date.today(),
})
scrap_asset_id.with_context(
{'active_id': self.asset_id_1.id}).do_scrap()
if self.asset_id_1.state != 'close':
raise AssertionError("Asset is not moved to scrap location")
else:
logging.info("Asset scrap function successfully executed")
# Check Fiscal Year
account_config = self.env['res.config.settings'].create({
'fiscalyear_last_month': 3,
})
account_config.execute()
self.assertEqual(self.asset_id_2.prorata, 'fiscal_year')
self.assertEqual(self.asset_id_2.method_period, 12)
self.asset_id_2.compute_depreciation_board()
self.asset_id_2.validate()
fl_depreciation_date = self.asset_id_2.depreciation_line_ids[0].depreciation_date
first_line_date = datetime.strptime(fl_depreciation_date, DF).date()
self.assertEqual(first_line_date.month, 3)
sl_depreciation_date = self.asset_id_2.depreciation_line_ids[1].depreciation_date
second_line_date = datetime.strptime(sl_depreciation_date, DF).date()
self.assertEqual(second_line_date.month, 3)

View File

@ -43,9 +43,9 @@
</group>
<group string="Periodicity">
<field name="method_time" string="Time Method Based On" widget="radio" attrs="{'invisible': [('type','!=','purchase')]}"/>
<field name="method_number" string="Number of Entries" attrs="{'invisible':['|',('method_time','!=','number'),'&amp;',('type','=', False)], 'required':[('method_time','=','number')]}"/>
<label for="method_period" string="One Entry Every"/>
<div>
<field name="method_number" attrs="{'invisible':['|',('method_time','!=','number'),'&amp;',('type','=', False)], 'required':[('method_time','=','number')]}"/>
<label for="method_period" string="One Entry Every" attrs="{'invisible': [('prorata','=','fiscal_year')]}"/>
<div attrs="{'invisible': [('prorata','=','fiscal_year')]}">
<field name="method_period" nolabel="1" attrs="{'invisible': [('type','=', False)]}" class="oe_inline"/>
months
</div>
@ -128,16 +128,44 @@
<form string="Asset">
<header>
<button name="validate" states="draft" string="Confirm" type="object" class="oe_highlight"/>
<button name="%(asset_sale_action)d" states="open" type="action" string="Customer Invoice"
class="oe_highlight"
context="{
'default_product_id': product_id,
'default_asset_category_id': category_id,
'default_asset_id': active_id,
'default_depreciated_amount': remaining_asset_value,
'default_sale_value': remaining_asset_value,
}"/>
<button name="%(asset_scrap_action)d" type="action" string="Scrap" class="oe_highlight"
context="{
'default_product_id': product_id,
'default_asset_category_id': category_id,
'default_asset_id': active_id,
'default_depreciated_amount': remaining_asset_value,
'default_sale_value': remaining_asset_value,
'default_partner_id': partner_id,
}"
attrs="{'invisible': [('state', '!=', 'open')]}"
/>
<button type="object" name="compute_depreciation_board" string="Compute Depreciation" states="draft"/>
<button name="set_to_close" states="open" string="Sell or Dispose" type="object" class="oe_highlight"/>
<button name="set_to_close" states="open" string="Sell or Dispose" type="object" class="oe_highlight" invisible="1"/>
<button name="set_to_draft" string="Set to Draft" type="object" attrs="{'invisible': ['|', ('entry_count', '!=', 0), ('state', '!=', 'open')]}"/>
<button name="%(action_asset_modify)d" states="open" string="Modify Depreciation" type="action"/>
<button name="%(action_asset_modify)d" states="open" string="Modify Depreciation" type="action" context="{'prorata': prorata}"/>
<field name="state" widget="statusbar" statusbar_visible="draft,open"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="toggle_active" type="object"
class="oe_stat_button" icon="fa-archive" attrs="{'invisible': [('state', '=', 'close')]}">
<field name="active" widget="boolean_button"
options='{"terminology": "archive"}'/>
</button>
<button class="oe_stat_button" name="open_entries" type="object" icon="fa-pencil">
<field string="Items" name="entry_count" widget="statinfo" />
<field string="Dep. Entries" name="entry_count" widget="statinfo" />
</button>
<button class="oe_inline oe_stat_button" name="redirect_to_invoice" type="object" icon="fa-pencil" attrs="{'invisible': [('invoice_count', '=', 0)]}">
<field name="invoice_count" widget="statinfo"/>
</button>
</div>
<div class="oe_title">
@ -150,7 +178,12 @@
<group>
<field name="category_id" domain="[('type', '=', 'purchase')]" context="{'default_type': 'purchase'}" help="Category of asset"/>
<field name="code"/>
<field name="product_id"
attrs="{'required': [('state','=','draft')],'readonly': [('state','!=','draft')]}"
string="Asset"/>
<field name="remaining_asset_value" invisible="1"/>
<field name="date" help="Date of asset"/>
<field name="sale_date" attrs="{'invisible': [('sale_date', '=', False)], 'readonly': [('sale_date', '!=', False)]}"/>
<field name="type" invisible="1"/>
</group>
<group>
@ -168,10 +201,12 @@
<field name="depreciation_line_ids" mode="tree" options="{'reload_whole_on_button': true}">
<tree string="Depreciation Lines" decoration-info="(move_check == False)" create="false">
<field name="depreciation_date"/>
<field name="depreciated_value" readonly="1"/>
<field name="begin_value"/>
<field name="amount" widget="monetary" string="Depreciation"/>
<field name="depreciated_value" readonly="1"/>
<field name="remaining_value" readonly="1" widget="monetary" string="Residual"/>
<field name="move_check" widget="deprec_lines_toggler" attrs="{'invisible': [('parent_state', '!=', 'open')]}"/>
<button name="action_move_cancel" string="Cancel Entry" type="object" attrs="{'invisible': ['|', ('move_check', '=', False), ('parent_state', '=', 'close')]}"/>
<field name="move_posted_check" invisible="1"/>
<field name="parent_state" invisible="1"/>
</tree>
@ -204,7 +239,7 @@
</group>
<group>
<field name="method_number" attrs="{'invisible':[('method_time','=','end')], 'required':[('method_time','=','number')]}"/>
<field name="method_period"/>
<field name="method_period" attrs="{'invisible': [('prorata','=','fiscal_year')]}"/>
<field name="method_end" attrs="{'required': [('method_time','=','end')], 'invisible':[('method_time','=','number')]}"/>
</group>
</page>
@ -284,9 +319,16 @@
<filter string="Closed" domain="[('state','=', 'close')]" help="Assets in closed state"/>
<field name="category_id"/>
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<filter string="Inactive" domain="[('active','=', False)]"/>
<field name="product_id"/>
<group expand="0" string="Group By...">
<filter string="Month" domain="[]" context="{'group_by':'date'}"/>
<filter string="Category" domain="[]" context="{'group_by':'category_id'}"/>
<filter string="Month" domain="[]" context="{'group_by':'date'}"/>
<filter string="State" icon="terp-folder-orange" domain="[]" context="{'group_by':'state'}"/>
<filter string="Asset Category" icon="terp-folder-orange" domain="[]"
context="{'group_by':'category_id'}"/>
<filter string="Product" icon="terp-folder-orange" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="Partner" icon="terp-folder-orange" domain="[]"
context="{'group_by':'partner_id'}"/>
</group>
</search>
</field>

View File

@ -10,6 +10,18 @@
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='account_id']" position="before">
<field string="Asset Category" name="asset_category_id" domain="[('type','=','purchase')]" context="{'default_type':'purchase'}"/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="after">
<field name="asset_bool" invisible="1"/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="attributes">
<attribute name="attrs">{'readonly': [('asset_bool', '=', True)]}</attribute>
</xpath>
<xpath expr="//field[@name='invoice_line_ids']" position="inside">
<field name="asset_bool" invisible="1"/>
</xpath>
<xpath expr="//field[@name='invoice_line_ids']" position="attributes">
<attribute name="attrs">{'readonly': [('asset_bool', '=', True)]}</attribute>
</xpath>
</field>
</record>

View File

@ -3,3 +3,6 @@
from . import asset_depreciation_confirmation_wizard
from . import asset_modify
from . import sale_asset_wizard
from . import scrap_asset_wizard
from . import asset_depreciation_summary

View File

@ -0,0 +1,35 @@
# Part of Flectra. See LICENSE file for full copyright and licensing
# details.
from flectra import api, fields, models
from datetime import datetime
from flectra.tools import DEFAULT_SERVER_DATE_FORMAT as DF
class AssetDepreciationWizard(models.TransientModel):
_name = "asset.depreciation.wizard"
@api.depends('start_date')
def _compute_get_end_date(self):
if self.start_date:
last_day = self.env.user.company_id.fiscalyear_last_day
last_month = self.env.user.company_id.fiscalyear_last_month
date = datetime.strptime(self.start_date, DF).date()
if date.month <= 3 and date.day < 31:
year = date.year
else:
year = date.year + 1
date = date.replace(month=last_month, day=last_day, year=year)
self.end_date = datetime.strftime(date, '%Y-%m-%d')
start_date = fields.Date(string="Start Date", required=True)
end_date = fields.Date(compute='_compute_get_end_date', store=True)
@api.multi
def print_depreciation_lines(self):
data = {'form': self.read(['start_date', 'end_date'])[0]}
return self.env.ref(
'account_asset.asset_depreciation_report').report_action(
self,
data=data,
config=False)

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<flectra>
<record id="asset_depreciation_summary_report_form_view" model="ir.ui.view">
<field name="name">asset.depreciation.summary.report.form</field>
<field name="model">asset.depreciation.wizard</field>
<field name="arch" type="xml">
<form>
<group col="4">
<field name="start_date"/>
<field name="end_date"/>
</group>
<footer>
<button name="print_depreciation_lines" type="object" class="oe_highlight" string="Print"/>
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="asset_depreciation_summary_report_action" model="ir.actions.act_window">
<field name="name">Asset Depreciation Summary Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">asset.depreciation.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem
id="asset_depreciation_summary_report_menu"
name="Asset Depreciation Summary"
parent="account.menu_finance_legal_statement"
action="asset_depreciation_summary_report_action"
/>
</flectra>

View File

@ -14,8 +14,8 @@
</group>
<group colspan="2" col="2">
<field name="method_end" attrs="{'invisible': [('asset_method_time', '=', 'number')]}"/>
<label for="method_period"/>
<div>
<label for="method_period" invisible="context.get('prorata') == 'fiscal_year'"/>
<div invisible="context.get('prorata') == 'fiscal_year'">
<field name="method_period" class="oe_inline"/> months
</div>
</group>

View File

@ -0,0 +1,159 @@
# Part of Flectra. See LICENSE file for full copyright and licensing
# details.
from flectra import fields, models, _, api
from datetime import datetime
from flectra.tools import DEFAULT_SERVER_DATE_FORMAT as DF
class SaleAssetWizard(models.TransientModel):
_name = "sale.asset.wizard"
asset_id = fields.Many2one("account.asset.asset", string="Asset")
asset_category_id = fields.Many2one("account.asset.category",
string="Asset Category", required=True)
depreciated_amount = fields.Float(string="Depreciated Amount")
product_id = fields.Many2one("product.product", string="Product",
required=True)
partner_id = fields.Many2one("res.partner", string="Customer",
required=True)
sale_value = fields.Float(string="Sale Value")
sale_date = fields.Date(
string="Date", default=lambda self: datetime.today(),
required=True)
@api.onchange('sale_date')
def onchange_sale_date(self):
if self.sale_date:
amount = 0.0
last_date = False
for line in self.asset_id.depreciation_line_ids:
if self.sale_date >= line.depreciation_date:
amount += line.amount
last_date = line.depreciation_date
else:
if not last_date:
last_date = line.depreciation_date
delta, total_days = \
self.get_days(last_date, self.sale_date)
amount += (line.amount * delta.days) / total_days
break
self.depreciated_amount = amount
self.sale_value = self.asset_id.value_residual - amount
@api.constrains('sale_date')
def _check_sale_date(self):
if self.sale_date:
posted_line_ids = \
self.env['account.asset.depreciation.line'].search([
('asset_id', '=', self.asset_id.id),
('move_check', '=', True)])
if posted_line_ids:
last_depreciation_date = \
datetime.strptime(
posted_line_ids[-1].depreciation_date, DF).date()
if self.sale_date < str(last_depreciation_date):
raise ValueError(_("Sale date must be greater than last "
"Depreciated date!"))
@api.multi
def get_days(self, last_date, sale_date):
last_depreciation_date = datetime.strptime(last_date, DF).date()
sale_date = datetime.strptime(sale_date, DF).date()
delta = sale_date - last_depreciation_date
year = last_depreciation_date.year
total_days = (year % 4) and 365 or 366
return delta, total_days
@api.multi
def last_line_info(self):
last_date = False
last_line = False
sale_date = self.sale_date
for line in self.asset_id.depreciation_line_ids:
if sale_date >= line.depreciation_date:
line.create_move(post_move=True)
last_date = line.depreciation_date
last_line = line
else:
last_line = line
if not last_date:
last_date = line.depreciation_date
break
delta, total_days = self.get_days(last_date, sale_date)
amount = (last_line.amount * delta.days) / total_days
return last_line, amount
def sale_asset(self):
if self.asset_id:
self.asset_id.write({
'state': 'close',
'sale_date': self.sale_date,
})
last_line, amount = self.last_line_info()
if last_line:
depreciated_value = \
(last_line.depreciated_value - last_line.amount) + amount
last_line.update({
'depreciation_date': self.sale_date,
'amount': amount,
'depreciated_value': depreciated_value,
'remaining_value':
last_line.begin_value - depreciated_value,
})
last_line.create_move(post_move=True)
for line in self.asset_id.depreciation_line_ids:
if not line.move_check:
line.unlink()
self.create_sale_invoice()
def create_sale_invoice(self):
invoice_obj = self.env['account.invoice']
invoice_line_obj = self.env['account.invoice.line']
journal_id = self.env['account.journal'].search(
[('code', '=', 'INV')])
account_id = self.env['account.account'].search(
[('internal_type', '=', 'receivable')])
tax_ids = self.product_id.supplier_taxes_id.ids
invoice_id = invoice_obj.create({
'partner_id': self.partner_id.id,
'journal_id':
journal_id and
journal_id[0].id or
self.asset_id.category_id.journal_id.id,
'account_id':
account_id and
account_id[0].id or
self.asset_id.category_id.account_asset_id.id,
'company_id': self.partner_id.company_id.id,
'type': 'out_invoice',
'date_invoice': self.sale_date,
'payment_term_id':
self.partner_id.property_supplier_payment_term_id.id,
'currency_id': self.partner_id.company_id.currency_id.id,
'asset_id': self.asset_id.id,
'asset_bool': True
})
invoice_line_obj.create({
'product_id': self.product_id.id,
'name': self.product_id.name,
'asset_id': self.asset_id.id,
'asset_category_id': self.asset_id.category_id.id,
'account_id': self.asset_id.category_id.account_asset_id.id,
'quantity': 1.0,
'price_unit': self.sale_value,
'partner_id': self.partner_id.id,
'company_id': self.partner_id.company_id.id,
'invoice_line_tax_ids': tax_ids and [[6, 0, tax_ids]] or False,
'asset_bool': True,
'invoice_id': invoice_id.id
})
return {
'name': (_('Invoices')),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'domain': [('asset_id', '=', self.asset_id.id)]
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<flectra>
<record id="asset_sale_form_view" model="ir.ui.view">
<field name="name">sale.asset.wizard</field>
<field name="model">sale.asset.wizard</field>
<field name="arch" type="xml">
<form>
<group col="4">
<field name="asset_id" readonly="1"/>
<field name="product_id" readonly="1"/>
<field name="asset_category_id" readonly="1"/>
<field name="depreciated_amount" readonly="1" invisible="1"/>
<field name="sale_date"/>
<field name="partner_id"/>
<field name="sale_value"/>
</group>
<footer>
<button name="sale_asset" string="Confirm"
type="object"
class="oe_highlight" context="{}"/>
<button string="Cancel" class="oe_highlight"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="asset_sale_action" model="ir.actions.act_window">
<field name="name">Sale</field>
<field name="res_model">sale.asset.wizard</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</flectra>

View File

@ -0,0 +1,44 @@
# Part of Flectra. See LICENSE file for full copyright and licensing
# details.
from flectra import fields, models, api
from datetime import datetime
class ScrapAssetWizard(models.TransientModel):
_name = "scrap.asset.wizard"
partner_id = fields.Many2one('res.partner', 'Partner', required=True)
asset_id = fields.Many2one("account.asset.asset", string="Asset")
asset_category_id = fields.Many2one("account.asset.category",
string="Asset Category", required=True)
product_id = fields.Many2one("product.product", string="Product",
required=True)
depreciated_amount = fields.Float(string="Depreciated Amount",
required=True)
sale_date = fields.Date(
string="Date", default=lambda self: datetime.today(),
required=True)
financial_move = fields.Boolean(string="Create Financial Move")
journal_id = fields.Many2one("account.journal", string="Payment Journal",
domain=[('type', 'in', ('bank', 'cash'))])
amount = fields.Float(string="Payment Amount")
@api.multi
def do_scrap(self):
asset_id = self.env['account.asset.asset'].browse(
self._context['active_id'])
if asset_id:
asset_id.write({
'active': False,
'state': 'close'
})
depreciation_line_ids = self.env[
'account.asset.depreciation.line'].search(
[('asset_id', '=', asset_id.id), ('move_check', '=', False)])
if depreciation_line_ids:
depreciation_line_ids.unlink()
return True

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<flectra>
<record id="asset_scrap_form_view" model="ir.ui.view">
<field name="name">scrap.asset.wizard</field>
<field name="model">scrap.asset.wizard</field>
<field name="arch" type="xml">
<form>
<group col="4">
<field name="partner_id"/>
<field name="asset_id" readonly="1"/>
<field name="product_id"/>
<field name="asset_category_id"/>
<field name="depreciated_amount"/>
<field name="sale_date"/>
</group>
<footer>
<button name="do_scrap" string="Confirm"
type="object"
class="oe_highlight" context="{}"/>
<button string="Cancel" class="oe_highlight"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="asset_scrap_action" model="ir.actions.act_window">
<field name="name">scrap.asset.wizard</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">scrap.asset.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</flectra>