Browse Source

[FIX] Bug Fixed 'base_accounting_kit'

pull/134/merge
Ajmalcybrosys 6 years ago
parent
commit
c0511fded9
  1. 2
      base_accounting_kit/README.rst
  2. 8
      base_accounting_kit/__manifest__.py
  3. 2
      base_accounting_kit/data/account_asset_data.xml
  4. 11
      base_accounting_kit/doc/RELEASE_NOTES.md
  5. 667
      base_accounting_kit/models/account_asset.py
  6. 59
      base_accounting_kit/models/account_move.py
  7. 12
      base_accounting_kit/models/product_template.py
  8. 51
      base_accounting_kit/report/account_asset_report.py
  9. 15
      base_accounting_kit/report/account_asset_report_views.xml
  10. 65
      base_accounting_kit/report/cash_flow_report.xml
  11. 7
      base_accounting_kit/security/account_asset_security.xml
  12. 177
      base_accounting_kit/static/description/index.html
  13. 4
      base_accounting_kit/static/src/js/account_asset.js
  14. 9
      base_accounting_kit/static/src/less/account_asset.less
  15. 9
      base_accounting_kit/static/src/scss/account_asset.scss
  16. 2
      base_accounting_kit/views/account_asset_templates.xml
  17. 173
      base_accounting_kit/views/account_asset_views.xml
  18. 7
      base_accounting_kit/views/account_move_views.xml
  19. 17
      base_accounting_kit/views/product_views.xml
  20. 19
      base_accounting_kit/wizard/asset_depreciation_confirmation_wizard.py
  21. 11
      base_accounting_kit/wizard/asset_depreciation_confirmation_wizard_views.xml
  22. 48
      base_accounting_kit/wizard/asset_modify.py
  23. 2
      base_accounting_kit/wizard/asset_modify_views.xml
  24. 12
      base_accounting_kit/wizard/cash_flow_report.xml
  25. 16
      base_accounting_kit/wizard/recurring_payments_wizard.xml

2
base_accounting_kit/README.rst

@ -1,5 +1,5 @@
Accounting Kit Accounting Kit
============================= ==============
* Full accounting kit for Odoo 13 community editions * Full accounting kit for Odoo 13 community editions
Installation Installation

8
base_accounting_kit/__manifest__.py

@ -21,8 +21,8 @@
############################################################################# #############################################################################
{ {
'name': 'Odoo 13 Full Accounting Kit', 'name': 'Odoo 13 Accounting',
'version': '13.0.1.0.0', 'version': '13.0.1.1.1',
'category': 'Accounting', 'category': 'Accounting',
'summary': """ This Module will bring back the accounting features such Asset Management, Accounting Reports, PDC Management, 'summary': """ This Module will bring back the accounting features such Asset Management, Accounting Reports, PDC Management,
Account Lock dates, Customer Credit Limit and Follow Ups, Day book, Account Lock dates, Customer Credit Limit and Follow Ups, Day book,
@ -31,7 +31,7 @@
Odoo 13 Accounting,Accounting Reports,Odoo13 Accounting PDF Reports, Asset Management, Odoo 13 Accounting,Accounting Reports,Odoo13 Accounting PDF Reports, Asset Management,
Customer Credit Limit, Recurring Payment, Customer Credit Limit, Recurring Payment,
PDC Management, Customer Follow-up, PDC Management, Customer Follow-up,
Lock Dates into Odoo 13 Community Edition, Odoo Accounting,Odoo 13 Accounting Reports,Odoo 13, Full Accounting, Complete Accounting, Odoo Community Accounting, Accounting for odoo 13, Full Accounting Package, Financial Reports, Financial Report for Odoo 13""", Lock Dates into Odoo 13 Community Edition, Odoo Accounting,Odoo 13 Accounting Reports,Odoo 13""",
'author': ' Odoo SA,Cybrosys Techno Solutions', 'author': ' Odoo SA,Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com", 'website': "https://www.cybrosys.com",
'company': 'Cybrosys Techno Solutions', 'company': 'Cybrosys Techno Solutions',
@ -57,7 +57,7 @@
'wizard/asset_depreciation_confirmation_wizard_views.xml', 'wizard/asset_depreciation_confirmation_wizard_views.xml',
'wizard/asset_modify_views.xml', 'wizard/asset_modify_views.xml',
'views/account_asset_views.xml', 'views/account_asset_views.xml',
'views/account_invoice_views.xml', 'views/account_move_views.xml',
'views/account_asset_templates.xml', 'views/account_asset_templates.xml',
'views/product_template_views.xml', 'views/product_template_views.xml',
'wizard/financial_report.xml', 'wizard/financial_report.xml',

2
base_accounting_kit/data/account_asset_data.xml

@ -1,6 +1,5 @@
<?xml version="1.0" encoding='UTF-8'?> <?xml version="1.0" encoding='UTF-8'?>
<odoo> <odoo>
<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="name">Account Asset: Generate asset entries</field>
<field name="model_id" ref="model_account_asset_asset"/> <field name="model_id" ref="model_account_asset_asset"/>
@ -11,5 +10,4 @@
<field name="numbercall">-1</field> <field name="numbercall">-1</field>
<field name="doall" eval="False"/> <field name="doall" eval="False"/>
</record> </record>
</odoo> </odoo>

11
base_accounting_kit/doc/RELEASE_NOTES.md

@ -0,0 +1,11 @@
## Module <base_accounting_kit>
#### 23.10.2019
#### Version 13.0.1.0.0
#### ADD
- Initial commit for Dynamic Cash Book Report
#### 28.10.2019
#### Version 13.0.1.1.1
#### FIX
- Function Asset Changed.

667
base_accounting_kit/models/account_asset.py

@ -22,10 +22,12 @@
import calendar import calendar
from datetime import date, datetime from datetime import date, datetime
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _ from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError from odoo.exceptions import UserError, ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from odoo.tools import float_compare, float_is_zero from odoo.tools import float_compare, float_is_zero
@ -35,36 +37,57 @@ class AccountAssetCategory(models.Model):
active = fields.Boolean(default=True) active = fields.Boolean(default=True)
name = fields.Char(required=True, index=True, string="Asset Type") name = fields.Char(required=True, index=True, string="Asset Type")
account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account') account_analytic_id = fields.Many2one('account.analytic.account',
analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tag') string='Analytic Account')
account_asset_id = fields.Many2one('account.account', string='Asset Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)], help="Account used to record the purchase of the asset at its original price.") account_asset_id = fields.Many2one('account.account',
account_depreciation_id = fields.Many2one('account.account', string='Depreciation Entries: Asset Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)], help="Account used in the depreciation entries, to decrease the asset value.") string='Asset Account', required=True,
account_depreciation_expense_id = fields.Many2one('account.account', string='Depreciation Entries: Expense Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)], oldname='account_income_recognition_id', help="Account used in the periodical entries, to record a part of the asset as expense.") domain=[('internal_type', '=', 'other'),
journal_id = fields.Many2one('account.journal', string='Journal', required=True) ('deprecated', '=', False)],
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env['res.company']._company_default_get('account.asset.category')) help="Account used to record the purchase of the asset at its original price.")
method = fields.Selection([('linear', 'Linear'), ('degressive', 'Degressive')], string='Computation Method', required=True, default='linear', account_depreciation_id = fields.Many2one('account.account',
string='Depreciation Entries: Asset Account',
required=True, domain=[
('internal_type', '=', 'other'), ('deprecated', '=', False)],
help="Account used in the depreciation entries, to decrease the asset value.")
account_depreciation_expense_id = fields.Many2one('account.account',
string='Depreciation Entries: Expense Account',
required=True, domain=[
('internal_type', '=', 'other'), ('deprecated', '=', False)],
oldname='account_income_recognition_id',
help="Account used in the periodical entries, to record a part of the asset as expense.")
journal_id = fields.Many2one('account.journal', string='Journal',
required=True)
company_id = fields.Many2one('res.company', string='Company',
required=True, default=lambda self: self.env[
'res.company']._company_default_get('account.asset.category'))
method = fields.Selection(
[('linear', 'Linear'), ('degressive', 'Degressive')],
string='Computation Method', required=True, default='linear',
help="Choose the method to use to compute the amount of depreciation lines.\n" 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" " * Linear: Calculated on basis of: Gross Value / Number of Depreciations\n"
" * Degressive: Calculated on basis of: Residual Value * Degressive Factor") " * Degressive: Calculated on basis of: Residual Value * Degressive Factor")
method_number = fields.Integer(string='Number of Depreciations', default=5, help="The number of depreciations needed to depreciate your asset") method_number = fields.Integer(string='Number of Depreciations', default=5,
method_period = fields.Integer(string='Period Length', default=1, help="State here the time between 2 depreciations, in months", required=True) 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_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 Entries'), ('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" 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" " * 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.") " * Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond.")
method_end = fields.Date('Ending date') 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.Boolean(string='Prorata Temporis',
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.") help='Indicates that the first depreciation entry for this asset have to be done from the purchase date instead of the first of January')
group_entries = fields.Boolean(string='Group Journal Entries', help="Check this if you want to group the generated entries by categories.") open_asset = fields.Boolean(string='Auto-confirm Assets',
type = fields.Selection([('sale', 'Sale: Revenue Recognition'), ('purchase', 'Purchase: Asset')], required=True, index=True, default='purchase') help="Check this if you want to automatically confirm the assets of this category when created by invoices.")
date_first_depreciation = fields.Selection([ group_entries = fields.Boolean(string='Group Journal Entries',
('last_day_period', 'Based on Last Day of Purchase Period'), help="Check this if you want to group the generated entries by categories.")
('manual', 'Manual (Defaulted on Purchase Date)')], type = fields.Selection([('sale', 'Sale: Revenue Recognition'),
string='Depreciation Dates', default='manual', required=True, ('purchase', 'Purchase: Asset')], required=True,
help='The way to compute the date of the first depreciation.\n' index=True, default='purchase')
' * Based on last day of purchase period: The depreciation dates will be based on the last day of the purchase month or the purchase year (depending on the periodicity of the depreciations).\n'
' * Based on purchase date: The depreciation dates will be based on the purchase date.')
@api.onchange('account_asset_id') @api.onchange('account_asset_id')
def onchange_account_asset(self): def onchange_account_asset(self):
@ -92,68 +115,119 @@ class AccountAssetAsset(models.Model):
_description = 'Asset/Revenue Recognition' _description = 'Asset/Revenue Recognition'
_inherit = ['mail.thread'] _inherit = ['mail.thread']
entry_count = fields.Integer(compute='_entry_count', string='# Asset Entries') entry_count = fields.Integer(compute='_entry_count',
name = fields.Char(string='Asset Name', required=True, readonly=True, states={'draft': [('readonly', False)]}) string='# Asset Entries')
code = fields.Char(string='Reference', size=32, readonly=True, states={'draft': [('readonly', False)]}) name = fields.Char(string='Asset Name', required=True, readonly=True,
value = fields.Float(string='Gross Value', required=True, readonly=True, digits=0, states={'draft': [('readonly', False)]}, oldname='purchase_value') states={'draft': [('readonly', False)]})
currency_id = fields.Many2one('res.currency', string='Currency', required=True, readonly=True, states={'draft': [('readonly', False)]}, code = fields.Char(string='Reference', size=32, readonly=True,
default=lambda self: self.env.user.company_id.currency_id.id) states={'draft': [('readonly', False)]})
company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, states={'draft': [('readonly', False)]}, value = fields.Float(string='Gross Value', required=True, readonly=True,
default=lambda self: self.env['res.company']._company_default_get('account.asset.asset')) digits=0, states={'draft': [('readonly', False)]},
oldname='purchase_value')
currency_id = fields.Many2one('res.currency', string='Currency',
required=True, readonly=True,
states={'draft': [('readonly', False)]},
default=lambda
self: self.env.user.company_id.currency_id.id)
company_id = fields.Many2one('res.company', string='Company',
required=True, readonly=True,
states={'draft': [('readonly', False)]},
default=lambda self: self.env[
'res.company']._company_default_get(
'account.asset.asset'))
note = fields.Text() note = fields.Text()
category_id = fields.Many2one('account.asset.category', string='Category', required=True, change_default=True, readonly=True, states={'draft': [('readonly', False)]}) category_id = fields.Many2one('account.asset.category', string='Category',
date = fields.Date(string='Date', required=True, readonly=True, states={'draft': [('readonly', False)]}, default=fields.Date.context_today, oldname="purchase_date") required=True, change_default=True,
state = fields.Selection([('draft', 'Draft'), ('open', 'Running'), ('close', 'Close')], 'Status', required=True, copy=False, default='draft', readonly=True,
states={'draft': [('readonly', False)]})
date = fields.Date(string='Date', required=True, readonly=True,
states={'draft': [('readonly', False)]},
default=fields.Date.context_today,
oldname="purchase_date")
state = fields.Selection(
[('draft', 'Draft'), ('open', 'Running'), ('close', 'Close')],
'Status', required=True, copy=False, default='draft',
help="When an asset is created, the status is 'Draft'.\n" help="When an asset is created, the status is 'Draft'.\n"
"If the asset is confirmed, the status goes in 'Running' and the depreciation lines can be posted in the accounting.\n" "If the asset is confirmed, the status goes in 'Running' and the depreciation lines can be posted in the accounting.\n"
"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.") "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) active = fields.Boolean(default=True)
partner_id = fields.Many2one('res.partner', string='Partner', readonly=True, states={'draft': [('readonly', False)]}) partner_id = fields.Many2one('res.partner', string='Partner',
method = fields.Selection([('linear', 'Linear'), ('degressive', 'Degressive')], string='Computation Method', required=True, readonly=True, states={'draft': [('readonly', False)]}, default='linear', readonly=True,
states={'draft': [('readonly', False)]})
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" 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") " * Degressive: Calculated on basis of: Residual Value * Degressive Factor")
method_number = fields.Integer(string='Number of Depreciations', readonly=True, states={'draft': [('readonly', False)]}, default=5, help="The number of depreciations needed to depreciate your asset") method_number = fields.Integer(string='Number of Depreciations',
method_period = fields.Integer(string='Number of Months in a Period', required=True, readonly=True, default=12, states={'draft': [('readonly', False)]}, readonly=True,
states={'draft': [('readonly', False)]},
default=5,
help="The number of depreciations needed to depreciate your asset")
method_period = fields.Integer(string='Number of Months in a Period',
required=True, readonly=True, default=12,
states={'draft': [('readonly', False)]},
help="The amount of time between two depreciations, in months") help="The amount of time between two depreciations, in months")
method_end = fields.Date(string='Ending Date', readonly=True, states={'draft': [('readonly', False)]}) method_end = fields.Date(string='Ending Date', readonly=True,
method_progress_factor = fields.Float(string='Degressive Factor', readonly=True, default=0.3, states={'draft': [('readonly', False)]}) states={'draft': [('readonly', False)]})
value_residual = fields.Float(compute='_amount_residual', method=True, digits=0, string='Residual Value') method_progress_factor = fields.Float(string='Degressive Factor',
method_time = fields.Selection([('number', 'Number of Entries'), ('end', 'Ending Date')], string='Time Method', required=True, readonly=True, default='number', states={'draft': [('readonly', False)]}, 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" 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" " * 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.") " * 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)]}, prorata = fields.Boolean(string='Prorata Temporis', readonly=True,
help='Indicates that the first depreciation entry for this asset have to be done from the asset date (purchase date) instead of the first January / Start date of fiscal year') states={'draft': [('readonly', False)]},
depreciation_line_ids = fields.One2many('account.asset.depreciation.line', 'asset_id', string='Depreciation Lines', readonly=True, states={'draft': [('readonly', False)], 'open': [('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')
salvage_value = fields.Float(string='Salvage Value', digits=0, readonly=True, states={'draft': [('readonly', False)]}, 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.") help="It is the amount you plan to have that you cannot depreciate.")
invoice_id = fields.Many2one('account.move', string='Invoice', states={'draft': [('readonly', False)]}, copy=False) invoice_id = fields.Many2one('account.move', string='Invoice',
type = fields.Selection(related="category_id.type", string='Type', required=True) states={'draft': [('readonly', False)]},
account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account') copy=False)
analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tag') type = fields.Selection(related="category_id.type", string='Type',
date_first_depreciation = fields.Selection([ required=True)
('last_day_period', 'Based on Last Day of Purchase Period'),
('manual', 'Manual')],
string='Depreciation Dates', default='manual',
readonly=True, states={'draft': [('readonly', False)]}, required=True,
help='The way to compute the date of the first depreciation.\n'
' * Based on last day of purchase period: The depreciation dates will be based on the last day of the purchase month or the purchase year (depending on the periodicity of the depreciations).\n'
' * Based on purchase date: The depreciation dates will be based on the purchase date.\n')
first_depreciation_manual_date = fields.Date(
string='First Depreciation Date',
readonly=True, states={'draft': [('readonly', False)]},
help='Note that this date does not alter the computation of the first journal entry in case of prorata temporis assets. It simply changes its accounting date'
)
def unlink(self): def unlink(self):
for asset in self: for asset in self:
if asset.state in ['open', 'close']: if asset.state in ['open', 'close']:
raise UserError(_('You cannot delete a document that is in %s state.') % (asset.state,)) raise UserError(
_('You cannot delete a document is in %s state.') % (
asset.state,))
for depreciation_line in asset.depreciation_line_ids: for depreciation_line in asset.depreciation_line_ids:
if depreciation_line.move_id: if depreciation_line.move_id:
raise UserError(_('You cannot delete a document that contains posted entries.')) raise UserError(_(
'You cannot delete a document that contains posted entries.'))
return super(AccountAssetAsset, self).unlink() return super(AccountAssetAsset, self).unlink()
def _get_last_depreciation_date(self):
"""
@param id: ids of a account.asset.asset objects
@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
"""
self.env.cr.execute("""
SELECT a.id as id, COALESCE(MAX(m.date),a.date) AS date
FROM account_asset_asset a
LEFT JOIN account_asset_depreciation_line rel ON (rel.asset_id = a.id)
LEFT JOIN account_move m ON (rel.move_id = m.id)
WHERE a.id IN %s
GROUP BY a.id, m.date """, (tuple(self.ids),))
result = dict(self.env.cr.fetchall())
return result
@api.model @api.model
def _cron_generate_entries(self): def _cron_generate_entries(self):
self.compute_generated_entries(datetime.today()) self.compute_generated_entries(datetime.today())
@ -166,126 +240,182 @@ class AccountAssetAsset(models.Model):
if asset_type: if asset_type:
type_domain = [('type', '=', asset_type)] type_domain = [('type', '=', asset_type)]
ungrouped_assets = self.env['account.asset.asset'].search(type_domain + [('state', '=', 'open'), ('category_id.group_entries', '=', False)]) ungrouped_assets = self.env['account.asset.asset'].search(
created_move_ids += ungrouped_assets._compute_entries(date, group_entries=False) type_domain + [('state', '=', 'open'),
('category_id.group_entries', '=', False)])
for grouped_category in self.env['account.asset.category'].search(type_domain + [('group_entries', '=', True)]): created_move_ids += ungrouped_assets._compute_entries(date,
assets = self.env['account.asset.asset'].search([('state', '=', 'open'), ('category_id', '=', grouped_category.id)]) group_entries=False)
created_move_ids += assets._compute_entries(date, group_entries=True)
for grouped_category in self.env['account.asset.category'].search(
type_domain + [('group_entries', '=', True)]):
assets = self.env['account.asset.asset'].search(
[('state', '=', 'open'),
('category_id', '=', grouped_category.id)])
created_move_ids += assets._compute_entries(date,
group_entries=True)
return created_move_ids return created_move_ids
def _compute_board_amount(self, sequence, residual_amount, amount_to_depr, undone_dotation_number, posted_depreciation_line_ids, total_days, depreciation_date): def _compute_board_amount(self, sequence, residual_amount, amount_to_depr,
for record in self: undone_dotation_number,
posted_depreciation_line_ids, total_days,
depreciation_date):
amount = 0 amount = 0
if sequence == undone_dotation_number: if sequence == undone_dotation_number:
amount = residual_amount amount = residual_amount
else: else:
if record.method == 'linear': if self.method == 'linear':
amount = amount_to_depr / (undone_dotation_number - len(posted_depreciation_line_ids)) amount = amount_to_depr / (undone_dotation_number - len(
if record.prorata: posted_depreciation_line_ids))
amount = amount_to_depr / record.method_number if self.prorata:
amount = amount_to_depr / self.method_number
if sequence == 1: if sequence == 1:
date = record.date if self.method_period % 12 != 0:
if record.method_period % 12 != 0: date = datetime.strptime(self.date, '%Y-%m-%d')
month_days = calendar.monthrange(date.year, date.month)[1] month_days = \
calendar.monthrange(date.year, date.month)[1]
days = month_days - date.day + 1 days = month_days - date.day + 1
amount = (amount_to_depr / record.method_number) / month_days * days amount = (
amount_to_depr / self.method_number) / month_days * days
else: else:
days = (record.company_id.compute_fiscalyear_dates(date)['date_to'] - date).days + 1 days = (self.company_id.compute_fiscalyear_dates(
amount = (amount_to_depr / record.method_number) / total_days * days depreciation_date)[
elif record.method == 'degressive': 'date_to'] - depreciation_date).days + 1
amount = residual_amount * record.method_progress_factor amount = (
if record.prorata: amount_to_depr / self.method_number) / total_days * days
elif self.method == 'degressive':
amount = residual_amount * self.method_progress_factor
if self.prorata:
if sequence == 1: if sequence == 1:
date = record.date if self.method_period % 12 != 0:
if record.method_period % 12 != 0: date = datetime.strptime(self.date, '%Y-%m-%d')
month_days = calendar.monthrange(date.year, date.month)[1] month_days = \
calendar.monthrange(date.year, date.month)[1]
days = month_days - date.day + 1 days = month_days - date.day + 1
amount = (residual_amount * record.method_progress_factor) / month_days * days amount = (
residual_amount * self.method_progress_factor) / month_days * days
else: else:
days = (record.company_id.compute_fiscalyear_dates(date)['date_to'] - date).days + 1 days = (self.company_id.compute_fiscalyear_dates(
amount = (residual_amount * record.method_progress_factor) / total_days * days depreciation_date)[
'date_to'] - depreciation_date).days + 1
amount = (
residual_amount * self.method_progress_factor) / total_days * days
return amount return amount
def _compute_board_undone_dotation_nb(self, depreciation_date, total_days): def _compute_board_undone_dotation_nb(self, depreciation_date, total_days):
for record in self: undone_dotation_number = self.method_number
undone_dotation_number = record.method_number if self.method_time == 'end':
if record.method_time == 'end': end_date = datetime.strptime(str(self.method_end), DF).date()
end_date = record.method_end
undone_dotation_number = 0 undone_dotation_number = 0
while depreciation_date <= end_date: while depreciation_date <= end_date:
depreciation_date = date(depreciation_date.year, depreciation_date.month, depreciation_date.day) + relativedelta(months=+record.method_period) depreciation_date = date(depreciation_date.year,
depreciation_date.month,
depreciation_date.day) + relativedelta(
months=+self.method_period)
undone_dotation_number += 1 undone_dotation_number += 1
if record.prorata: if self.prorata:
undone_dotation_number += 1 undone_dotation_number += 1
return undone_dotation_number return undone_dotation_number
def compute_depreciation_board(self): def compute_depreciation_board(self):
self.ensure_one() self.ensure_one()
for record in self:
posted_depreciation_line_ids = record.depreciation_line_ids.filtered(lambda x: x.move_check).sorted(key=lambda l: l.depreciation_date) posted_depreciation_line_ids = self.depreciation_line_ids.filtered(
unposted_depreciation_line_ids = record.depreciation_line_ids.filtered(lambda x: not x.move_check) lambda x: x.move_check).sorted(key=lambda l: l.depreciation_date)
unposted_depreciation_line_ids = self.depreciation_line_ids.filtered(
lambda x: not x.move_check)
# Remove old unposted depreciation lines. We cannot use unlink() with One2many field # Remove old unposted depreciation lines. We cannot use unlink() with One2many field
commands = [(2, line_id.id, False) for line_id in unposted_depreciation_line_ids] commands = [(2, line_id.id, False) for line_id in
unposted_depreciation_line_ids]
if self.value_residual != 0.0:
amount_to_depr = residual_amount = self.value_residual
if self.prorata:
# 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(
str(self._get_last_depreciation_date()[self.id]),
DF).date()
else:
# depreciation_date = 1st of January of purchase year if annual valuation, 1st of
# purchase month in other cases
if self.method_period >= 12:
if self.company_id.fiscalyear_last_month:
print(self.company_id.fiscalyear_last_month)
print(self.company_id.fiscalyear_last_day)
print(self.date)
asset_date = date(year=int(self.date.year),
month=int(
self.company_id.fiscalyear_last_month),
day=int(
self.company_id.fiscalyear_last_day)) + relativedelta(
days=1) + \
relativedelta(year=int(
self.date.year)) # e.g. 2018-12-31 +1 -> 2019
else:
asset_date = datetime.strptime(
self.date[:4] + '-01-01', DF).date()
else:
asset_date = datetime.strptime(self.date[:7] + '-01',
DF).date()
# if we already have some previous validated entries, starting date isn't 1st January but last entry + method period
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 = asset_date
day = depreciation_date.day
month = depreciation_date.month
year = depreciation_date.year
total_days = (year % 4) and 365 or 366
if record.value_residual != 0.0: undone_dotation_number = self._compute_board_undone_dotation_nb(
amount_to_depr = residual_amount = record.value_residual depreciation_date, total_days)
# if we already have some previous validated entries, starting date is last entry + method period for x in range(len(posted_depreciation_line_ids),
if posted_depreciation_line_ids and posted_depreciation_line_ids[-1].depreciation_date: undone_dotation_number):
last_depreciation_date = fields.Date.from_string(posted_depreciation_line_ids[-1].depreciation_date)
depreciation_date = last_depreciation_date + relativedelta(months=+record.method_period)
else:
# depreciation_date computed from the purchase date
depreciation_date = record.date
if record.date_first_depreciation == 'last_day_period':
# depreciation_date = the last day of the month
depreciation_date = depreciation_date + relativedelta(day=31)
# ... or fiscalyear depending the number of period
if record.method_period == 12:
depreciation_date = depreciation_date + relativedelta(month=record.company_id.fiscalyear_last_month)
depreciation_date = depreciation_date + relativedelta(day=record.company_id.fiscalyear_last_day)
if depreciation_date < record.date:
depreciation_date = depreciation_date + relativedelta(years=1)
elif record.first_depreciation_manual_date and record.first_depreciation_manual_date != record.date:
# depreciation_date set manually from the 'first_depreciation_manual_date' field
depreciation_date = record.first_depreciation_manual_date
total_days = (depreciation_date.year % 4) and 365 or 366
month_day = depreciation_date.day
undone_dotation_number = record._compute_board_undone_dotation_nb(depreciation_date, total_days)
for x in range(len(posted_depreciation_line_ids), undone_dotation_number):
sequence = x + 1 sequence = x + 1
amount = record._compute_board_amount(sequence, residual_amount, amount_to_depr, undone_dotation_number, posted_depreciation_line_ids, total_days, depreciation_date) amount = self._compute_board_amount(sequence, residual_amount,
amount = record.currency_id.round(amount) amount_to_depr,
if float_is_zero(amount, precision_rounding=record.currency_id.rounding): undone_dotation_number,
posted_depreciation_line_ids,
total_days,
depreciation_date)
amount = self.currency_id.round(amount)
if float_is_zero(amount,
precision_rounding=self.currency_id.rounding):
continue continue
residual_amount -= amount residual_amount -= amount
vals = { vals = {
'amount': amount, 'amount': amount,
'asset_id': record.id, 'asset_id': self.id,
'sequence': sequence, 'sequence': sequence,
'name': (record.code or '') + '/' + str(sequence), 'name': (self.code or '') + '/' + str(sequence),
'remaining_value': residual_amount, 'remaining_value': residual_amount,
'depreciated_value': record.value - (record.salvage_value + residual_amount), 'depreciated_value': self.value - (
'depreciation_date': depreciation_date, self.salvage_value + residual_amount),
'depreciation_date': depreciation_date.strftime(DF),
} }
commands.append((0, False, vals)) commands.append((0, False, vals))
# Considering Depr. Period as months
depreciation_date = date(year, month, day) + relativedelta(
months=+self.method_period)
day = depreciation_date.day
month = depreciation_date.month
year = depreciation_date.year
depreciation_date = depreciation_date + relativedelta(months=+record.method_period) self.write({'depreciation_line_ids': commands})
if month_day > 28 and record.date_first_depreciation == 'manual':
max_day_in_month = calendar.monthrange(depreciation_date.year, depreciation_date.month)[1]
depreciation_date = depreciation_date.replace(day=min(max_day_in_month, month_day))
# datetime doesn't take into account that the number of days is not the same for each month
if not record.prorata and record.method_period % 12 != 0 and record.date_first_depreciation == 'last_day_period':
max_day_in_month = calendar.monthrange(depreciation_date.year, depreciation_date.month)[1]
depreciation_date = depreciation_date.replace(day=max_day_in_month)
record.write({'depreciation_line_ids': commands})
return True return True
@ -310,29 +440,17 @@ class AccountAssetAsset(models.Model):
del (tracked_fields['method_end']) del (tracked_fields['method_end'])
else: else:
del (tracked_fields['method_number']) del (tracked_fields['method_number'])
dummy, tracking_value_ids = asset._message_track(tracked_fields, dict.fromkeys(fields)) dummy, tracking_value_ids = asset._message_track(tracked_fields,
asset.message_post(subject=_('Asset created'), tracking_value_ids=tracking_value_ids) dict.fromkeys(
fields))
def _return_disposal_view(self, move_ids): asset.message_post(subject=_('Asset created'),
name = _('Disposal Move') tracking_value_ids=tracking_value_ids)
view_mode = 'form'
if len(move_ids) > 1:
name = _('Disposal Moves')
view_mode = 'tree,form'
return {
'name': name,
'view_type': 'form',
'view_mode': view_mode,
'res_model': 'account.move',
'type': 'ir.actions.act_window',
'target': 'current',
'res_id': move_ids[0],
}
def _get_disposal_moves(self): def _get_disposal_moves(self):
move_ids = [] move_ids = []
for asset in self: for asset in self:
unposted_depreciation_line_ids = asset.depreciation_line_ids.filtered(lambda x: not x.move_check) unposted_depreciation_line_ids = asset.depreciation_line_ids.filtered(
lambda x: not x.move_check)
if unposted_depreciation_line_ids: if unposted_depreciation_line_ids:
old_values = { old_values = {
'method_end': asset.method_end, 'method_end': asset.method_end,
@ -340,41 +458,65 @@ class AccountAssetAsset(models.Model):
} }
# Remove all unposted depr. lines # Remove all unposted depr. lines
commands = [(2, line_id.id, False) for line_id in unposted_depreciation_line_ids] commands = [(2, line_id.id, False) for line_id in
unposted_depreciation_line_ids]
# Create a new depr. line with the residual amount and post it # Create a new depr. line with the residual amount and post it
sequence = len(asset.depreciation_line_ids) - len(unposted_depreciation_line_ids) + 1 sequence = len(asset.depreciation_line_ids) - len(
today = fields.Datetime.today() unposted_depreciation_line_ids) + 1
today = datetime.today().strftime(DF)
vals = { vals = {
'amount': asset.value_residual, 'amount': asset.value_residual,
'asset_id': asset.id, 'asset_id': asset.id,
'sequence': sequence, 'sequence': sequence,
'name': (asset.code or '') + '/' + str(sequence), 'name': (asset.code or '') + '/' + str(sequence),
'remaining_value': 0, 'remaining_value': 0,
'depreciated_value': asset.value - asset.salvage_value, # the asset is completely depreciated 'depreciated_value': asset.value - asset.salvage_value,
# the asset is completely depreciated
'depreciation_date': today, 'depreciation_date': today,
} }
commands.append((0, False, vals)) commands.append((0, False, vals))
asset.write({'depreciation_line_ids': commands, 'method_end': today, 'method_number': sequence}) asset.write(
tracked_fields = self.env['account.asset.asset'].fields_get(['method_number', 'method_end']) {'depreciation_line_ids': commands, 'method_end': today,
changes, tracking_value_ids = asset._message_track(tracked_fields, old_values) 'method_number': sequence})
tracked_fields = self.env['account.asset.asset'].fields_get(
['method_number', 'method_end'])
changes, tracking_value_ids = asset._message_track(
tracked_fields, old_values)
if changes: if changes:
asset.message_post(subject=_('Asset sold or disposed. Accounting entry awaiting for validation.'), tracking_value_ids=tracking_value_ids) asset.message_post(subject=_(
move_ids += asset.depreciation_line_ids[-1].create_move(post_move=False) 'Asset sold or disposed. Accounting entry awaiting for validation.'),
tracking_value_ids=tracking_value_ids)
move_ids += asset.depreciation_line_ids[-1].create_move(
post_move=False)
return move_ids return move_ids
def set_to_close(self): def set_to_close(self):
move_ids = self._get_disposal_moves() move_ids = self._get_disposal_moves()
if move_ids: if move_ids:
return self._return_disposal_view(move_ids) name = _('Disposal Move')
view_mode = 'form'
if len(move_ids) > 1:
name = _('Disposal Moves')
view_mode = 'tree,form'
return {
'name': name,
'view_type': 'form',
'view_mode': view_mode,
'res_model': 'account.move',
'type': 'ir.actions.act_window',
'target': 'current',
'res_id': move_ids[0],
}
# Fallback, as if we just clicked on the smartbutton # Fallback, as if we just clicked on the smartbutton
return self.open_entries() return self.open_entries()
def set_to_draft(self): def set_to_draft(self):
self.write({'state': 'draft'}) self.write({'state': 'draft'})
@api.depends('value', 'salvage_value', 'depreciation_line_ids.move_check', 'depreciation_line_ids.amount') @api.depends('value', 'salvage_value', 'depreciation_line_ids.move_check',
'depreciation_line_ids.amount')
def _amount_residual(self): def _amount_residual(self):
for record in self: for record in self:
total_amount = 0.0 total_amount = 0.0
@ -387,21 +529,18 @@ class AccountAssetAsset(models.Model):
def onchange_company_id(self): def onchange_company_id(self):
self.currency_id = self.company_id.currency_id.id self.currency_id = self.company_id.currency_id.id
@api.onchange('date_first_depreciation')
def onchange_date_first_depreciation(self):
if self.date_first_depreciation == 'manual':
self.first_depreciation_manual_date = self.date
@api.depends('depreciation_line_ids.move_id') @api.depends('depreciation_line_ids.move_id')
def _entry_count(self): def _entry_count(self):
for asset in self: for asset in self:
res = self.env['account.asset.depreciation.line'].search_count([('asset_id', '=', asset.id), ('move_id', '!=', False)]) res = self.env['account.asset.depreciation.line'].search_count(
[('asset_id', '=', asset.id), ('move_id', '!=', False)])
asset.entry_count = res or 0 asset.entry_count = res or 0
@api.constrains('prorata', 'method_time') @api.constrains('prorata', 'method_time')
def _check_prorata(self): def _check_prorata(self):
if self.prorata and self.method_time != 'number': if self.prorata and self.method_time != 'number':
raise ValidationError(_('Prorata temporis can be applied only for the "number of depreciations" time method.')) raise ValidationError(_(
'Prorata temporis can be applied only for time method "number of depreciations".'))
@api.onchange('category_id') @api.onchange('category_id')
def onchange_category_id(self): def onchange_category_id(self):
@ -423,9 +562,6 @@ class AccountAssetAsset(models.Model):
'method_progress_factor': category.method_progress_factor, 'method_progress_factor': category.method_progress_factor,
'method_end': category.method_end, 'method_end': category.method_end,
'prorata': category.prorata, 'prorata': category.prorata,
'date_first_depreciation': category.date_first_depreciation,
'account_analytic_id': category.account_analytic_id.id,
'analytic_tag_ids': [(6, 0, category.analytic_tag_ids.ids)],
} }
} }
@ -450,15 +586,15 @@ class AccountAssetAsset(models.Model):
@api.model @api.model
def create(self, vals): def create(self, vals):
asset = super(AccountAssetAsset, self.with_context(mail_create_nolog=True)).create(vals) asset = super(AccountAssetAsset,
self.with_context(mail_create_nolog=True)).create(vals)
asset.sudo().compute_depreciation_board() asset.sudo().compute_depreciation_board()
return asset return asset
def write(self, vals): def write(self, vals):
for record in self: res = super(AccountAssetAsset, self).write(vals)
res = super(AccountAssetAsset, record).write(vals)
if 'depreciation_line_ids' not in vals and 'state' not in vals: if 'depreciation_line_ids' not in vals and 'state' not in vals:
for rec in record: for rec in self:
rec.compute_depreciation_board() rec.compute_depreciation_board()
return res return res
@ -485,15 +621,23 @@ class AccountAssetDepreciationLine(models.Model):
name = fields.Char(string='Depreciation Name', required=True, index=True) name = fields.Char(string='Depreciation Name', required=True, index=True)
sequence = fields.Integer(required=True) sequence = fields.Integer(required=True)
asset_id = fields.Many2one('account.asset.asset', string='Asset', required=True, ondelete='cascade') asset_id = fields.Many2one('account.asset.asset', string='Asset',
parent_state = fields.Selection(related='asset_id.state', string='State of Asset') required=True, ondelete='cascade')
amount = fields.Float(string='Current Depreciation', digits=0, required=True) parent_state = fields.Selection(related='asset_id.state',
remaining_value = fields.Float(string='Next Period Depreciation', digits=0, required=True) string='State of Asset')
depreciated_value = fields.Float(string='Cumulative Depreciation', required=True) amount = fields.Float(string='Current Depreciation', digits=0,
required=True)
remaining_value = fields.Float(string='Next Period Depreciation', digits=0,
required=True)
depreciated_value = fields.Float(string='Cumulative Depreciation',
required=True)
depreciation_date = fields.Date('Depreciation Date', index=True) depreciation_date = fields.Date('Depreciation Date', index=True)
move_id = fields.Many2one('account.move', string='Depreciation Entry') 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_check = fields.Boolean(compute='_get_move_check', string='Linked',
move_posted_check = fields.Boolean(compute='_get_move_posted_check', string='Posted', track_visibility='always', store=True) track_visibility='always', store=True)
move_posted_check = fields.Boolean(compute='_get_move_posted_check',
string='Posted',
track_visibility='always', store=True)
@api.depends('move_id') @api.depends('move_id')
def _get_move_check(self): def _get_move_check(self):
@ -507,48 +651,46 @@ class AccountAssetDepreciationLine(models.Model):
def create_move(self, post_move=True): def create_move(self, post_move=True):
created_moves = self.env['account.move'] created_moves = self.env['account.move']
prec = self.env['decimal.precision'].precision_get('Account')
if self.mapped('move_id'):
raise UserError(_(
'This depreciation is already linked to a journal entry! Please post or delete it.'))
for line in self: for line in self:
if line.move_id:
raise UserError(_('This depreciation is already linked to a journal entry. Please post or delete it.'))
move_vals = self._prepare_move(line)
move = self.env['account.move'].create(move_vals)
line.write({'move_id': move.id, 'move_check': True})
created_moves |= move
if post_move and created_moves:
created_moves.filtered(lambda m: any(m.asset_depreciation_ids.mapped('asset_id.category_id.open_asset'))).post()
return [x.id for x in created_moves]
def _prepare_move(self, line):
category_id = line.asset_id.category_id category_id = line.asset_id.category_id
account_analytic_id = line.asset_id.account_analytic_id depreciation_date = self.env.context.get(
analytic_tag_ids = line.asset_id.analytic_tag_ids 'depreciation_date') or line.depreciation_date or fields.Date.context_today(
depreciation_date = self.env.context.get('depreciation_date') or line.depreciation_date or fields.Date.context_today(self) self)
company_currency = line.asset_id.company_id.currency_id company_currency = line.asset_id.company_id.currency_id
current_currency = line.asset_id.currency_id current_currency = line.asset_id.currency_id
prec = company_currency.decimal_places amount = current_currency.with_context(
amount = current_currency._convert( date=depreciation_date).compute(line.amount, company_currency)
line.amount, company_currency, line.asset_id.company_id, depreciation_date) asset_name = line.asset_id.name + ' (%s/%s)' % (
asset_name = line.asset_id.name + ' (%s/%s)' % (line.sequence, len(line.asset_id.depreciation_line_ids)) line.sequence, len(line.asset_id.depreciation_line_ids))
partner = self.env['res.partner']._find_accounting_partner(
line.asset_id.partner_id)
move_line_1 = { move_line_1 = {
'name': asset_name, 'name': asset_name,
'account_id': category_id.account_depreciation_id.id, 'account_id': category_id.account_depreciation_id.id,
'debit': 0.0 if float_compare(amount, 0.0, precision_digits=prec) > 0 else -amount, 'debit': 0.0 if float_compare(amount, 0.0,
'credit': amount if float_compare(amount, 0.0, precision_digits=prec) > 0 else 0.0, precision_digits=prec) > 0 else -amount,
'partner_id': line.asset_id.partner_id.id, 'credit': amount if float_compare(amount, 0.0,
'analytic_account_id': account_analytic_id.id if category_id.type == 'sale' else False, precision_digits=prec) > 0 else 0.0,
'analytic_tag_ids': [(6, 0, analytic_tag_ids.ids)] if category_id.type == 'sale' else False, 'journal_id': category_id.journal_id.id,
'partner_id': partner.id,
'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'sale' else False,
'currency_id': company_currency != current_currency and current_currency.id or False, 'currency_id': company_currency != current_currency and current_currency.id or False,
'amount_currency': company_currency != current_currency and - 1.0 * line.amount or 0.0, 'amount_currency': company_currency != current_currency and - 1.0 * line.amount or 0.0,
} }
move_line_2 = { move_line_2 = {
'name': asset_name, 'name': asset_name,
'account_id': category_id.account_depreciation_expense_id.id, 'account_id': category_id.account_depreciation_expense_id.id,
'credit': 0.0 if float_compare(amount, 0.0, precision_digits=prec) > 0 else -amount, 'credit': 0.0 if float_compare(amount, 0.0,
'debit': amount if float_compare(amount, 0.0, precision_digits=prec) > 0 else 0.0, precision_digits=prec) > 0 else -amount,
'partner_id': line.asset_id.partner_id.id, 'debit': amount if float_compare(amount, 0.0,
'analytic_account_id': account_analytic_id.id if category_id.type == 'purchase' else False, precision_digits=prec) > 0 else 0.0,
'analytic_tag_ids': [(6, 0, analytic_tag_ids.ids)] if category_id.type == 'purchase' else False, 'journal_id': category_id.journal_id.id,
'partner_id': partner.id,
'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'purchase' else False,
'currency_id': company_currency != current_currency and current_currency.id or False, 'currency_id': company_currency != current_currency and current_currency.id or False,
'amount_currency': company_currency != current_currency and line.amount or 0.0, 'amount_currency': company_currency != current_currency and line.amount or 0.0,
} }
@ -558,21 +700,31 @@ class AccountAssetDepreciationLine(models.Model):
'journal_id': category_id.journal_id.id, 'journal_id': category_id.journal_id.id,
'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)], 'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)],
} }
return move_vals move = self.env['account.move'].create(move_vals)
line.write({'move_id': move.id, 'move_check': True})
def _prepare_move_grouped(self): created_moves |= move
asset_id = self[0].asset_id
category_id = asset_id.category_id # we can suppose that all lines have the same category if post_move and created_moves:
account_analytic_id = asset_id.account_analytic_id created_moves.filtered(lambda m: any(
analytic_tag_ids = asset_id.analytic_tag_ids m.asset_depreciation_ids.mapped(
depreciation_date = self.env.context.get('depreciation_date') or fields.Date.context_today(self) 'asset_id.category_id.open_asset'))).post()
return [x.id for x in created_moves]
def create_grouped_move(self, post_move=True):
if not self.exists():
return []
created_moves = self.env['account.move']
category_id = self[
0].asset_id.category_id # we can suppose that all lines have the same category
depreciation_date = self.env.context.get(
'depreciation_date') or fields.Date.context_today(self)
amount = 0.0 amount = 0.0
for line in self: for line in self:
# Sum amount of all depreciation lines # Sum amount of all depreciation lines
company_currency = line.asset_id.company_id.currency_id company_currency = line.asset_id.company_id.currency_id
current_currency = line.asset_id.currency_id current_currency = line.asset_id.currency_id
company = line.asset_id.company_id amount += current_currency.compute(line.amount, company_currency)
amount += current_currency._convert(line.amount, company_currency, company, fields.Date.today())
name = category_id.name + _(' (grouped)') name = category_id.name + _(' (grouped)')
move_line_1 = { move_line_1 = {
@ -581,8 +733,7 @@ class AccountAssetDepreciationLine(models.Model):
'debit': 0.0, 'debit': 0.0,
'credit': amount, 'credit': amount,
'journal_id': category_id.journal_id.id, 'journal_id': category_id.journal_id.id,
'analytic_account_id': account_analytic_id.id if category_id.type == 'sale' else False, 'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'sale' else False,
'analytic_tag_ids': [(6, 0, analytic_tag_ids.ids)] if category_id.type == 'sale' else False,
} }
move_line_2 = { move_line_2 = {
'name': name, 'name': name,
@ -590,8 +741,7 @@ class AccountAssetDepreciationLine(models.Model):
'credit': 0.0, 'credit': 0.0,
'debit': amount, 'debit': amount,
'journal_id': category_id.journal_id.id, 'journal_id': category_id.journal_id.id,
'analytic_account_id': account_analytic_id.id if category_id.type == 'purchase' else False, 'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'purchase' else False,
'analytic_tag_ids': [(6, 0, analytic_tag_ids.ids)] if category_id.type == 'purchase' else False,
} }
move_vals = { move_vals = {
'ref': category_id.name, 'ref': category_id.name,
@ -599,15 +749,7 @@ class AccountAssetDepreciationLine(models.Model):
'journal_id': category_id.journal_id.id, 'journal_id': category_id.journal_id.id,
'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)], 'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)],
} }
move = self.env['account.move'].create(move_vals)
return move_vals
def create_grouped_move(self, post_move=True):
if not self.exists():
return []
created_moves = self.env['account.move']
move = self.env['account.move'].create(self._prepare_move_grouped())
self.write({'move_id': move.id, 'move_check': True}) self.write({'move_id': move.id, 'move_check': True})
created_moves |= move created_moves |= move
@ -618,12 +760,18 @@ class AccountAssetDepreciationLine(models.Model):
def post_lines_and_close_asset(self): def post_lines_and_close_asset(self):
# we re-evaluate the assets to determine whether we can close them # we re-evaluate the assets to determine whether we can close them
# `message_post` invalidates the (whole) cache
# preprocess the assets and lines in which a message should be posted,
# and then post in batch will prevent the re-fetch of the same data over and over.
assets_to_close = self.env['account.asset.asset']
for line in self: for line in self:
line.log_message_when_posted()
asset = line.asset_id asset = line.asset_id
if asset.currency_id.is_zero(asset.value_residual): if asset.currency_id.is_zero(asset.value_residual):
assets_to_close |= asset
self.log_message_when_posted()
assets_to_close.write({'state': 'close'})
for asset in assets_to_close:
asset.message_post(body=_("Document closed.")) asset.message_post(body=_("Document closed."))
asset.write({'state': 'close'})
def log_message_when_posted(self): def log_message_when_posted(self):
def _format_message(message_description, tracked_values): def _format_message(message_description, tracked_values):
@ -635,15 +783,24 @@ class AccountAssetDepreciationLine(models.Model):
message += '%s</div>' % values message += '%s</div>' % values
return message return message
# `message_post` invalidates the (whole) cache
# preprocess the assets in which messages should be posted,
# and then post in batch will prevent the re-fetch of the same data over and over.
assets_to_post = {}
for line in self: for line in self:
if line.move_id and line.move_id.state == 'draft': if line.move_id and line.move_id.state == 'draft':
partner_name = line.asset_id.partner_id.name partner_name = line.asset_id.partner_id.name
currency_name = line.asset_id.currency_id.name currency_name = line.asset_id.currency_id.name
msg_values = {_('Currency'): currency_name, _('Amount'): line.amount} msg_values = {_('Currency'): currency_name,
_('Amount'): line.amount}
if partner_name: if partner_name:
msg_values[_('Partner')] = partner_name msg_values[_('Partner')] = partner_name
msg = _format_message(_('Depreciation line posted.'), msg_values) msg = _format_message(_('Depreciation line posted.'),
line.asset_id.message_post(body=msg) msg_values)
assets_to_post.setdefault(line.asset_id, []).append(msg)
for asset, messages in assets_to_post.items():
for msg in messages:
asset.message_post(body=msg)
def unlink(self): def unlink(self):
for record in self: for record in self:

59
base_accounting_kit/models/account_move.py

@ -20,11 +20,14 @@
# #
############################################################################# #############################################################################
from datetime import datetime
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _ from odoo import api, fields, models, _
from odoo.addons.base.models import decimal_precision as dp from odoo.addons.base.models import decimal_precision as dp
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF
class AccountMove(models.Model): class AccountMove(models.Model):
@ -35,6 +38,16 @@ class AccountMove(models.Model):
string='Assets Depreciation Lines', string='Assets Depreciation Lines',
ondelete="restrict") ondelete="restrict")
def button_cancel(self):
for move in self:
for line in move.asset_depreciation_ids:
line.move_posted_check = False
return super(AccountMove, self).button_cancel()
def post(self):
self.mapped('asset_depreciation_ids').post_lines_and_close_asset()
return super(AccountMove, self).post()
@api.model @api.model
def _refund_cleanup_lines(self, lines): def _refund_cleanup_lines(self, lines):
result = super(AccountMove, self)._refund_cleanup_lines(lines) result = super(AccountMove, self)._refund_cleanup_lines(lines)
@ -63,26 +76,12 @@ class AccountMove(models.Model):
inv.invoice_line_ids.with_context(context).asset_create() inv.invoice_line_ids.with_context(context).asset_create()
return result return result
def button_cancel(self):
for move in self:
for line in move.asset_depreciation_ids:
line.move_posted_check = False
return super(AccountMove, self).button_cancel()
def post(self):
for move in self:
for depreciation_line in move.asset_depreciation_ids:
depreciation_line.post_lines_and_close_asset()
return super(AccountMove, self).post()
class AccountMoveLine(models.Model): class AccountInvoiceLine(models.Model):
_inherit = 'account.move.line' _inherit = 'account.move.line'
asset_category_id = fields.Many2one('account.asset.category', asset_category_id = fields.Many2one('account.asset.category',
string='Asset Category') string='Asset Category')
type_rel = fields.Selection(related='move_id.type')
move_asset_category_id = fields.Many2one('account.move')
asset_start_date = fields.Date(string='Asset Start Date', asset_start_date = fields.Date(string='Asset Start Date',
compute='_get_asset_date', readonly=True, compute='_get_asset_date', readonly=True,
store=True) store=True)
@ -90,8 +89,9 @@ class AccountMoveLine(models.Model):
compute='_get_asset_date', readonly=True, compute='_get_asset_date', readonly=True,
store=True) store=True)
asset_mrr = fields.Float(string='Monthly Recurring Revenue', asset_mrr = fields.Float(string='Monthly Recurring Revenue',
compute='_get_asset_date', readonly=True, compute='_get_asset_date',
digits=dp.get_precision('Account'), store=True) readonly=True, digits=dp.get_precision('Account'),
store=True)
@api.depends('asset_category_id', 'move_id.invoice_date') @api.depends('asset_category_id', 'move_id.invoice_date')
def _get_asset_date(self): def _get_asset_date(self):
@ -102,17 +102,18 @@ class AccountMoveLine(models.Model):
cat = record.asset_category_id cat = record.asset_category_id
if cat: if cat:
if cat.method_number == 0 or cat.method_period == 0: if cat.method_number == 0 or cat.method_period == 0:
raise UserError(_('The number of depreciations or ' raise UserError(_(
'the period length of your asset category cannot be 0.')) 'The number of depreciations or the period length of your asset category cannot be null.'))
months = cat.method_number * cat.method_period months = cat.method_number * cat.method_period
if record.move_id.type in ['out_invoice', 'out_refund']: if record.move_id.type in ['out_invoice', 'out_refund']:
record.asset_mrr = record.price_subtotal / months record.asset_mrr = record.price_subtotal_signed / months
if record.move_id.invoice_date: if record.move_id.invoice_date:
start_date = record.move_id.invoice_date.replace(day=1) start_date = datetime.strptime(
str(record.move_id.invoice_date), DF).replace(day=1)
end_date = (start_date + relativedelta(months=months, end_date = (start_date + relativedelta(months=months,
days=-1)) days=-1))
record.asset_start_date = start_date record.asset_start_date = start_date.strftime(DF)
record.asset_end_date = end_date record.asset_end_date = end_date.strftime(DF)
def asset_create(self): def asset_create(self):
for record in self: for record in self:
@ -146,13 +147,13 @@ class AccountMoveLine(models.Model):
@api.onchange('uom_id') @api.onchange('uom_id')
def _onchange_uom_id(self): def _onchange_uom_id(self):
result = super(AccountMoveLine, self)._onchange_uom_id() result = super(AccountInvoiceLine, self)._onchange_uom_id()
self.onchange_asset_category_id() self.onchange_asset_category_id()
return result return result
@api.onchange('product_id') @api.onchange('product_id')
def _onchange_product_id(self): def _onchange_product_id(self):
vals = super(AccountMoveLine, self)._onchange_product_id() vals = super(AccountInvoiceLine, self)._onchange_product_id()
if self.product_id: if self.product_id:
if self.move_id.type == 'out_invoice': if self.move_id.type == 'out_invoice':
self.asset_category_id = self.product_id.product_tmpl_id.deferred_revenue_category_id self.asset_category_id = self.product_id.product_tmpl_id.deferred_revenue_category_id
@ -167,11 +168,9 @@ class AccountMoveLine(models.Model):
elif invoice.type == 'in_invoice': elif invoice.type == 'in_invoice':
self.asset_category_id = self.product_id.product_tmpl_id.asset_category_id.id self.asset_category_id = self.product_id.product_tmpl_id.asset_category_id.id
self.onchange_asset_category_id() self.onchange_asset_category_id()
super(AccountMoveLine, self)._set_additional_fields(invoice) super(AccountInvoiceLine, self)._set_additional_fields(invoice)
def get_invoice_line_account(self, type, product, fpos, company): def get_invoice_line_account(self, type, product, fpos, company):
return product.asset_category_id.account_asset_id or super( return product.asset_category_id.account_asset_id or super(
AccountMoveLine, self).get_invoice_line_account(type, AccountInvoiceLine, self).get_invoice_line_account(type, product,
product, fpos, company)
fpos,
company)

12
base_accounting_kit/models/product_template.py

@ -20,20 +20,14 @@
# #
############################################################################# #############################################################################
from odoo import fields, models from odoo import api, fields, models
class ProductTemplate(models.Model): class ProductTemplate(models.Model):
_inherit = 'product.template' _inherit = 'product.template'
asset_category_id = fields.Many2one('account.asset.category', asset_category_id = fields.Many2one('account.asset.category', string='Asset Type', company_dependent=True, ondelete="restrict")
string='Asset Type', deferred_revenue_category_id = fields.Many2one('account.asset.category', string='Deferred Revenue Type', company_dependent=True, ondelete="restrict")
company_dependent=True,
ondelete="restrict")
deferred_revenue_category_id = fields.Many2one('account.asset.category',
string='Deferred Revenue Type',
company_dependent=True,
ondelete="restrict")
def _get_asset_accounts(self): def _get_asset_accounts(self):
res = super(ProductTemplate, self)._get_asset_accounts() res = super(ProductTemplate, self)._get_asset_accounts()

51
base_accounting_kit/report/account_asset_report.py

@ -1,27 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################# # Part of Odoo. See LICENSE file for full copyright and licensing details.
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2019-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models, tools
from odoo import api, fields, models, tools
class AssetAssetReport(models.Model): class AssetAssetReport(models.Model):
_name = "asset.asset.report" _name = "asset.asset.report"
@ -31,28 +11,19 @@ class AssetAssetReport(models.Model):
name = fields.Char(string='Year', required=False, readonly=True) name = fields.Char(string='Year', required=False, readonly=True)
date = fields.Date(readonly=True) date = fields.Date(readonly=True)
depreciation_date = fields.Date(string='Depreciation Date', readonly=True) depreciation_date = fields.Date(string='Depreciation Date', readonly=True)
asset_id = fields.Many2one('account.asset.asset', string='Asset', asset_id = fields.Many2one('account.asset.asset', string='Asset', readonly=True)
readonly=True) asset_category_id = fields.Many2one('account.asset.category', string='Asset category', readonly=True)
asset_category_id = fields.Many2one('account.asset.category', partner_id = fields.Many2one('res.partner', string='Partner', readonly=True)
string='Asset category', readonly=True) state = fields.Selection([('draft', 'Draft'), ('open', 'Running'), ('close', 'Close')], string='Status', readonly=True)
partner_id = fields.Many2one('res.partner', string='Partner', depreciation_value = fields.Float(string='Amount of Depreciation Lines', readonly=True)
readonly=True) installment_value = fields.Float(string='Amount of Installment Lines', readonly=True)
state = fields.Selection(
[('draft', 'Draft'), ('open', 'Running'), ('close', 'Close')],
string='Status', readonly=True)
depreciation_value = fields.Float(string='Amount of Depreciation Lines',
readonly=True)
installment_value = fields.Float(string='Amount of Installment Lines',
readonly=True)
move_check = fields.Boolean(string='Posted', readonly=True) move_check = fields.Boolean(string='Posted', readonly=True)
installment_nbr = fields.Integer(string='Installment Count', readonly=True) installment_nbr = fields.Integer(string='# of Installment Lines', readonly=True)
depreciation_nbr = fields.Integer(string='Depreciation Count', depreciation_nbr = fields.Integer(string='# of Depreciation Lines', readonly=True)
readonly=True)
gross_value = fields.Float(string='Gross Amount', readonly=True) gross_value = fields.Float(string='Gross Amount', readonly=True)
posted_value = fields.Float(string='Posted Amount', readonly=True) posted_value = fields.Float(string='Posted Amount', readonly=True)
unposted_value = fields.Float(string='Unposted Amount', readonly=True) unposted_value = fields.Float(string='Unposted Amount', readonly=True)
company_id = fields.Many2one('res.company', string='Company', company_id = fields.Many2one('res.company', string='Company', readonly=True)
readonly=True)
def init(self): def init(self):
tools.drop_view_if_exists(self._cr, 'asset_asset_report') tools.drop_view_if_exists(self._cr, 'asset_asset_report')

15
base_accounting_kit/report/account_asset_report_views.xml

@ -12,7 +12,6 @@
</pivot> </pivot>
</field> </field>
</record> </record>
<record model="ir.ui.view" id="action_account_asset_report_graph"> <record model="ir.ui.view" id="action_account_asset_report_graph">
<field name="name">asset.asset.report.graph</field> <field name="name">asset.asset.report.graph</field>
<field name="model">asset.asset.report</field> <field name="model">asset.asset.report</field>
@ -34,6 +33,7 @@
<field name="depreciation_date"/> <field name="depreciation_date"/>
<filter string="Draft" name="draft" domain="[('state','=','draft')]" help="Assets in draft state"/> <filter string="Draft" name="draft" domain="[('state','=','draft')]" help="Assets in draft state"/>
<filter string="Running" name="running" domain="[('state','=','open')]" help="Assets in running state"/> <filter string="Running" name="running" domain="[('state','=','open')]" help="Assets in running state"/>
<filter string="Not archived" name="only_active" domain="[('asset_id.active','=', True)]"/>
<separator/> <separator/>
<filter string="Posted" name="posted" domain="[('move_check','=',True)]" help="Posted depreciation lines" context="{'unposted_value_visible': 0}"/> <filter string="Posted" name="posted" domain="[('move_check','=',True)]" help="Posted depreciation lines" context="{'unposted_value_visible': 0}"/>
<field name="asset_id"/> <field name="asset_id"/>
@ -60,21 +60,18 @@
<field name="name">Assets Analysis</field> <field name="name">Assets Analysis</field>
<field name="res_model">asset.asset.report</field> <field name="res_model">asset.asset.report</field>
<field name="view_mode">graph,pivot</field> <field name="view_mode">graph,pivot</field>
<field name="search_view_id" ref="view_asset_asset_report_search"/>
<field name="domain">[('asset_category_id.type', '=', 'purchase')]</field> <field name="domain">[('asset_category_id.type', '=', 'purchase')]</field>
<field name="context">{}</field> <!-- force empty --> <field name="context">{'search_default_only_active': 1}</field>
<field name="help" type="html"> <field name="help" type="html">
<p class="o_view_nocontent_empty_folder"> <p>
No content
</p><p>
From this report, you can have an overview on all depreciations. The From this report, you can have an overview on all depreciations. The
search bar can also be used to personalize your assets depreciation reporting. search bar can also be used to personalize your assets depreciation reporting.
</p> </p>
</field> </field>
</record> </record>
<menuitem name="Assets" <menuitem name="Assets" action="action_asset_asset_report"
action="action_asset_asset_report"
id="menu_action_asset_asset_report" id="menu_action_asset_asset_report"
parent="account.account_reports_management_menu" parent="account.account_reports_management_menu" sequence="21"/>
sequence="21"/>
</odoo> </odoo>

65
base_accounting_kit/report/cash_flow_report.xml

@ -22,14 +22,14 @@
</p> </p>
</div> </div>
</div> </div>
<table class="table table-sm table-reports">
<table class="table table-sm table-reports" t-if="data['debit_credit'] == 1">
<thead> <thead>
<tr> <tr>
<th><strong>Name</strong></th> <th><strong>Name</strong></th>
<th class="text-right"><strong>Debit</strong></th> <th class="text-right" t-if="data['debit_credit']"><strong>Debit</strong></th>
<th class="text-right"><strong>Credit</strong></th> <th class="text-right" t-if="data['debit_credit']"><strong>Credit</strong></th>
<th class="text-right"><strong>Balance</strong></th> <th class="text-right"><strong>Balance</strong></th>
<th class="text-right" t-if="data['enable_filter']"><strong t-esc="data['label_filter']"/></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -42,60 +42,21 @@
<span t-att-style="style" t-esc="a.get('name')"/> <span t-att-style="style" t-esc="a.get('name')"/>
</td> </td>
<td class="text-right" style="white-space: text-nowrap;"> <td class="text-right" style="white-space: text-nowrap;">
<span t-att-style="style" t-esc="a.get('debit')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/> <span t-att-style="style" t-esc="a.get('debit')" t-if="data['debit_credit']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</td> </td>
<td class="text-right" style="white-space: text-nowrap;"> <td class="text-right" style="white-space: text-nowrap;">
<span t-att-style="style" t-esc="a.get('credit')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/> <span t-att-style="style" t-esc="a.get('credit')" t-if="data['debit_credit']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</td> </td>
<td class="text-right" style="white-space: text-nowrap;"> <td class="text-right" style="white-space: text-nowrap;">
<span t-att-style="style" t-esc="a.get('balance')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/> <span t-att-style="style" t-esc="a.get('balance')"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</td> </td>
</t> <td class="text-right">
</tr> <span t-att-style="style" t-esc="a.get('balance_cmp')" t-if="data['enable_filter']"
</tbody> t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</table>
<table class="table table-sm table-reports" t-if="not data['enable_filter'] and not data['debit_credit']">
<thead>
<tr>
<th><strong>Name</strong></th>
<th class="text-right"><strong>Balance</strong></th>
</tr>
</thead>
<tbody>
<tr t-foreach="get_account_lines" t-as="a">
<t t-if="a['level'] != 0">
<t t-if="a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: normal;'"/></t>
<t t-if="not a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: bold;'"/></t>
<td>
<span style="color: white;" t-esc="'..' * a.get('level', 0)"/>
<span t-att-style="style" t-esc="a.get('name')"/>
</td>
<td class="text-right"><span t-att-style="style" t-esc="a.get('balance')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></td>
</t>
</tr>
</tbody>
</table>
<table class="table table-sm table-reports" t-if="data['enable_filter'] == 1 and not data['debit_credit']">
<thead>
<tr>
<th><strong>Name</strong></th>
<th class="text-right"><strong>Balance</strong></th>
<th class="text-right"><span t-esc="data['label_filter']"/></th>
</tr>
</thead>
<tbody>
<tr t-foreach="get_account_lines" t-as="a">
<t t-if="a['level'] != 0">
<t t-if="a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: normal;'"/></t>
<t t-if="not a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: bold;'"/></t>
<td>
<span style="color: white;" t-esc="'..'"/>
<span t-att-style="style" t-esc="a.get('name')"/>
</td> </td>
<td class="text-right"><span t-att-style="style" t-esc="a.get('balance')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></td>
<td class="text-right"><span t-att-style="style" t-esc="a.get('balance_cmp')"/></td>
</t> </t>
</tr> </tr>
</tbody> </tbody>

7
base_accounting_kit/security/account_asset_security.xml

@ -15,12 +15,5 @@
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field> <field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record> </record>
<record id="account.group_account_user" model="res.groups">
<field name="name">Accountant</field>
<field name="implied_ids" eval="[(4, ref('account.group_account_invoice'))]"/>
<!-- <field name="category_id" ref="base.module_category_accounting_invoicing"/>-->
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data> </data>
</odoo> </odoo>

177
base_accounting_kit/static/description/index.html

@ -55,12 +55,6 @@
style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;">
<a id="pills-home-tab1" data-toggle="pill" href="#pills-home" role="tab" <a id="pills-home-tab1" data-toggle="pill" href="#pills-home" role="tab"
aria-controls="pills-home" aria-selected="true" class="nav-link active show" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400;text-align: center; aria-controls="pills-home" aria-selected="true" class="nav-link active show" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400;text-align: center;
color: #fff;">Screenshots</a></li>
<li class="nav-item mr-1 mb-3"
style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;">
<a class="nav-link" id="pills-profile-tab2" data-toggle="pill" href="#pills-profile" role="tab"
aria-controls="pills-profile" aria-selected="false" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400; text-align: center;
color: #fff;">Overview </a></li> color: #fff;">Overview </a></li>
<li class="nav-item mr-1 mb-3" <li class="nav-item mr-1 mb-3"
style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;">
@ -68,7 +62,11 @@
aria-controls="pills-home" aria-selected="true" class="nav-link " style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400; text-align: center; aria-controls="pills-home" aria-selected="true" class="nav-link " style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400; text-align: center;
color: #fff;">Features </a></li> color: #fff;">Features </a></li>
<li class="nav-item mr-1 mb-3"
style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;">
<a class="nav-link" id="pills-profile-tab2" data-toggle="pill" href="#pills-profile" role="tab"
aria-controls="pills-profile" aria-selected="false" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400; text-align: center;
color: #fff;">Screenshots </a></li>
<!-- <li class="nav-item mr-1 mb-3"--> <!-- <li class="nav-item mr-1 mb-3"-->
<!-- style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;">--> <!-- style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;">-->
@ -83,10 +81,88 @@
style="padding-top: 30px; padding-bottom: 30px; padding: 30px;"> style="padding-top: 30px; padding-bottom: 30px; padding: 30px;">
<div class="px-3 pt-1 tab-pane fade active show" id="pills-home" role="tabpanel" aria-labelledby=" <div class="px-3 pt-1 tab-pane fade active show" id="pills-home" role="tabpanel" aria-labelledby="
pills-home-tab"> pills-home-tab">
<div class="tab-pane"> <!-- Overview-->
<h2 style="font-weight: 600;text-align: center;width: 100%;">Overview</h2>
<hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
<h3 class="oe_slogan"
style="text-align: center;font-size: 19px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 31px;font-weight: 400;letter-spacing: .5px;margin-bottom: 21px;">
This module will bring back the accounting features such as Account Reports, Asset Management
and Customer Follow Up into Odoo 13 Community Edition. Also new features are added to the
accounting module such as Customer Credit Limit, Recurring Payment, PDC Management and Lock Dates.
</h3>
</div>
<div class="px-3 pt-1 tab-pane fade " id="pills-home1" role="tabpanel" aria-labelledby="
pills-home-tab">
<!-- feature tab-->
<h2 style="font-weight: 600;text-align: center;width: 100%;">Odoo 13 Accounting</h2>
<hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
<ul>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Asset management system for Odoo 13 community edition.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
PDC management is now in.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Accounting lock dates for Odoo 13 community edition.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Customer credit limit.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Handle Recurring payments in Odoo.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Manage Customer follow-ups.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Day book, Bank book and Cash book reports.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Financial reports.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Trial balance report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Journal audit report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
General ledger report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Partner ledger report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Aged partner balance.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Tax reports.
</li>
</ul>
</div>
<!-- Screenshot tab-->
<div class="px-3 tab-pane fade" id="pills-profile" role="tabpanel"
aria-labelledby="pills-profile-tab">
<div class="tab-pane">
<h2 style="font-weight: 600;text-align: center;width: 100%;">Screenshots</h2> <h2 style="font-weight: 600;text-align: center;width: 100%;">Screenshots</h2>
<hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;"> <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
<div> <div>
@ -485,91 +561,6 @@
</section> </section>
</div> </div>
</div> </div>
</div>
<div class="px-3 pt-1 tab-pane fade " id="pills-home1" role="tabpanel" aria-labelledby="
pills-home-tab">
<!-- feature tab-->
<h2 style="font-weight: 600;text-align: center;width: 100%;">Odoo 13 Accounting</h2>
<hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
<ul>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Asset management system for Odoo 13 community edition.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
PDC management is now in.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Accounting lock dates for Odoo 13 community edition.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Customer credit limit.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Handle Recurring payments in Odoo.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Manage Customer follow-ups.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Day book, Bank book and Cash book reports.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Financial reports.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Trial balance report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Journal audit report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
General ledger report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Partner ledger report.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Aged partner balance.
</li>
<li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
<img src="images/checked.png" style=" width: 22px; margin-right: 6px; " alt="check">
Tax reports.
</li>
</ul>
</div>
<!-- Screenshot tab-->
<div class="px-3 tab-pane fade" id="pills-profile" role="tabpanel"
aria-labelledby="pills-profile-tab">
<!-- Overview-->
<h2 style="font-weight: 600;text-align: center;width: 100%;">Overview</h2>
<hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
<h3 class="oe_slogan"
style="text-align: center;font-size: 19px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 31px;font-weight: 400;letter-spacing: .5px;margin-bottom: 21px;">
This module will bring back the accounting features such as Account Reports, Asset Management
and Customer Follow Up into Odoo 13 Community Edition. Also new features are added to the
accounting module such as Customer Credit Limit, Recurring Payment, PDC Management and Lock Dates.
</h3>
</div> </div>

4
base_accounting_kit/static/src/js/account_asset.js

@ -1,4 +1,4 @@
odoo.define('om_account_asset.widget', function(require) { odoo.define('base_accounting_kit.account_asset', function(require) {
"use strict"; "use strict";
/** /**
@ -58,7 +58,7 @@ var AccountAssetWidget = AbstractField.extend({
type: 'button', type: 'button',
title: title, title: title,
disabled: disabled, disabled: disabled,
}).addClass('btn btn-link fa fa-circle o_deprec_lines_toggler ' + className); }).addClass('btn btn-sm btn-link fa fa-circle o_deprec_lines_toggler ' + className);
this.$el.html($button); this.$el.html($button);
}, },

9
base_accounting_kit/static/src/less/account_asset.less

@ -0,0 +1,9 @@
.o_web_client .o_deprec_lines_toggler {
color: #b52121;
&.o_is_posted {
color: #6f7370;
}
&.o_unposted {
color: #178230;
}
}

9
base_accounting_kit/static/src/scss/account_asset.scss

@ -1,9 +0,0 @@
.o_web_client .o_deprec_lines_toggler {
color: theme-color('danger');
&.o_is_posted {
color: theme-color('success');
}
&.o_unposted {
color: theme-color('warning');
}
}

2
base_accounting_kit/views/account_asset_templates.xml

@ -2,7 +2,7 @@
<odoo> <odoo>
<template id="assets_backend" name="account assets" inherit_id="web.assets_backend"> <template id="assets_backend" name="account assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside"> <xpath expr="." position="inside">
<link rel="stylesheet" type="text/scss" href="/base_accounting_kit/static/src/scss/account_asset.scss"/> <link rel="stylesheet" href="/base_accounting_kit/static/src/less/account_asset.less"/>
<script type="text/javascript" src="/base_accounting_kit/static/src/js/account_asset.js"/> <script type="text/javascript" src="/base_accounting_kit/static/src/js/account_asset.js"/>
</xpath> </xpath>
</template> </template>

173
base_accounting_kit/views/account_asset_views.xml

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!--
Asset Category
-->
<record model="ir.ui.view" id="view_account_asset_category_form"> <record model="ir.ui.view" id="view_account_asset_category_form">
<field name="name">account.asset.category.form</field> <field name="name">account.asset.category.form</field>
<field name="model">account.asset.category</field> <field name="model">account.asset.category</field>
@ -16,40 +20,27 @@
</h1> </h1>
</div> </div>
<group> <group>
<field name="type" attrs="{'invisible': 1}"/> <field name="type" invisible="1"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/> <field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
</group> </group>
<group string="Journal Entries"> <group string="Journal Entries">
<field name="journal_id"/> <field name="journal_id"/>
<div> <div>
<label for="account_asset_id" <label for="account_asset_id" attrs="{'invisible': [('type','!=','purchase')]}"/>
attrs="{'invisible': [('type','!=','purchase')]}" <label for="account_asset_id" string="Deferred Revenue Account" attrs="{'invisible': [('type','!=','sale')]}"/>
style="font-weight: bold" class="o_light_label"/>
<label for="account_asset_id" string="Deferred Revenue Account"
attrs="{'invisible': [('type','!=','sale')]}"
style="font-weight: bold" class="o_light_label"/>
</div> </div>
<field name="account_asset_id" nolabel="1" attrs="{'invisible': [('type','=', False)]}"/> <field name="account_asset_id" nolabel="1" attrs="{'invisible': [('type','=', False)]}" domain="[('company_id', '=', company_id)]"/>
<div> <div>
<label for="account_depreciation_id" <label for="account_depreciation_id" attrs="{'invisible': [('type','!=','purchase')]}"/>
attrs="{'invisible': [('type','!=','purchase')]}" <label for="account_depreciation_id" string="Recognition Income Account" attrs="{'invisible': [('type','!=','sale')]}"/>
style="font-weight: bold" class="o_light_label"/>
<label for="account_depreciation_id" string="Recognition Income Account"
attrs="{'invisible': [('type','!=','sale')]}"
style="font-weight: bold" class="o_light_label"/>
</div> </div>
<field name="account_depreciation_id" nolabel="1"/> <field name="account_depreciation_id" nolabel="1" domain="[('company_id', '=', company_id)]"/>
<div> <div>
<label for="account_depreciation_expense_id" <label for="account_depreciation_expense_id" attrs="{'invisible': [('type','!=','purchase')]}"/>
attrs="{'invisible': [('type','!=','purchase')]}" <label for="account_depreciation_expense_id" string="Recognition Account" attrs="{'invisible': [('type','!=','sale')]}"/>
style="font-weight: bold" class="o_light_label"/>
<label for="account_depreciation_expense_id" string="Recognition Account"
attrs="{'invisible': [('type','!=','sale')]}"
style="font-weight: bold" class="o_light_label"/>
</div> </div>
<field name="account_depreciation_expense_id" nolabel="1"/> <field name="account_depreciation_expense_id" nolabel="1" domain="[('company_id', '=', company_id)]"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/> <field name="account_analytic_id" domain="[('company_id', '=', company_id)]" groups="analytic.group_analytic_accounting"/>
<field name="analytic_tag_ids" groups="analytic.group_analytic_accounting" widget="many2many_tags"/>
</group> </group>
<group string="Periodicity"> <group string="Periodicity">
<field name="method_time" string="Time Method Based On" widget="radio" attrs="{'invisible': [('type','!=','purchase')]}"/> <field name="method_time" string="Time Method Based On" widget="radio" attrs="{'invisible': [('type','!=','purchase')]}"/>
@ -64,7 +55,6 @@
<group string="Additional Options"> <group string="Additional Options">
<field name="open_asset"/> <field name="open_asset"/>
<field name="group_entries"/> <field name="group_entries"/>
<field name="date_first_depreciation"/>
</group> </group>
<group attrs="{'invisible': [('type','=','sale')]}" string="Depreciation Method"> <group attrs="{'invisible': [('type','=','sale')]}" string="Depreciation Method">
<field name="method" widget="radio"/> <field name="method" widget="radio"/>
@ -89,11 +79,11 @@
<t t-name="kanban-box"> <t t-name="kanban-box">
<div t-attf-class="oe_kanban_card oe_kanban_global_click"> <div t-attf-class="oe_kanban_card oe_kanban_global_click">
<div class="row mb4"> <div class="row mb4">
<div class="col-6"> <div class="col-xs-6">
<strong><span><t t-esc="record.name.value"/></span></strong> <strong><span><t t-esc="record.name.value"/></span></strong>
</div> </div>
<div class="col-6 text-right"> <div class="col-xs-6 text-right">
<span class="badge badge-pill"><strong><t t-esc="record.method.value"/></strong></span> <span class="badge"><strong><t t-esc="record.method.value"/></strong></span>
</div> </div>
</div> </div>
<div> <t t-esc="record.journal_id.value"/></div> <div> <t t-esc="record.journal_id.value"/></div>
@ -117,24 +107,24 @@
</field> </field>
</record> </record>
<record model="ir.ui.view" id="view_account_asset_category_search"> <!-- <record model="ir.ui.view" id="view_account_asset_category_search">-->
<field name="name">account.asset.category.search</field> <!-- <field name="name">account.asset.category.search</field>-->
<field name="model">account.asset.category</field> <!-- <field name="model">account.asset.category</field>-->
<field name="arch" type="xml"> <!-- <field name="arch" type="xml">-->
<search string="Search Asset Category"> <!-- <search string="Search Asset Category">-->
<filter string="Sales" name="sales" domain="[('type','=', 'sale')]" help="Deferred Revenues"/> <!-- <filter string="Sales" domain="[('type','=', 'sale')]" help="Deferred Revenues"/>-->
<filter string="Purchase" name="purchase" domain="[('type','=', 'purchase')]" help="Assets"/> <!-- <filter string="Purchase" domain="[('type','=', 'purchase')]" help="Assets"/>-->
<field name="name" string="Category"/> <!-- <field name="name" string="Category"/>-->
<field name="journal_id"/> <!-- <field name="journal_id"/>-->
<group expand="0" string="Group By..."> <!-- <group expand="0" string="Group By...">-->
<filter string="Type" name="type" domain="[]" context="{'group_by':'type'}"/> <!-- <filter string="Type" domain="[]" context="{'group_by':'type'}"/>-->
</group> <!-- </group>-->
</search> <!-- </search>-->
</field> <!-- </field>-->
</record> <!-- </record>-->
<record id="view_account_asset_asset_form" model="ir.ui.view"> <record model="ir.ui.view" id="view_account_asset_asset_form">
<field name="name">account_asset_asset_form</field> <field name="name">account.asset.asset.form</field>
<field name="model">account.asset.asset</field> <field name="model">account.asset.asset</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Asset"> <form string="Asset">
@ -160,14 +150,10 @@
</div> </div>
<group> <group>
<group> <group>
<field name="category_id" string="Asset Category" domain="[('type', '=', 'purchase')]" context="{'default_type': 'purchase'}" help="Category of asset"/> <field name="category_id" domain="[('type', '=', 'purchase')]" context="{'default_type': 'purchase'}" help="Category of asset"/>
<field name="code"/> <field name="code"/>
<field name="date" help="Date of asset"/> <field name="date" help="Date of asset"/>
<field name="date_first_depreciation"/>
<field name="first_depreciation_manual_date"
attrs="{'invisible': [('date_first_depreciation', '!=', 'manual')], 'required': [('date_first_depreciation', '=', 'manual')]}"/>
<field name="type" invisible="1"/> <field name="type" invisible="1"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting" />
</group> </group>
<group> <group>
<field name="currency_id" groups="base.group_multi_currency"/> <field name="currency_id" groups="base.group_multi_currency"/>
@ -176,8 +162,7 @@
<field name="salvage_value" widget="monetary" options="{'currency_field': 'currency_id'}" attrs="{'invisible': [('type','=','sale')]}"/> <field name="salvage_value" widget="monetary" options="{'currency_field': 'currency_id'}" attrs="{'invisible': [('type','=','sale')]}"/>
<field name="value_residual" widget="monetary" options="{'currency_field': 'currency_id'}"/> <field name="value_residual" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="partner_id" string="Vendor" domain="[('supplier', '=', True)]"/> <field name="partner_id" string="Vendor" domain="[('supplier', '=', True)]"/>
<field name="invoice_id" string="Invoice" options="{'no_create': True}"/> <field name="invoice_id" string="Invoice" attrs="{'readonly': [('state', '!=', 'draft')]}" options="{'no_create': True}"/>
<field name="analytic_tag_ids" groups="analytic.group_analytic_accounting" widget="many2many_tags"/>
</group> </group>
</group> </group>
<notebook colspan="4"> <notebook colspan="4">
@ -185,14 +170,14 @@
<field name="depreciation_line_ids" mode="tree" options="{'reload_whole_on_button': true}"> <field name="depreciation_line_ids" mode="tree" options="{'reload_whole_on_button': true}">
<tree string="Depreciation Lines" decoration-info="(move_check == False)" create="false"> <tree string="Depreciation Lines" decoration-info="(move_check == False)" create="false">
<field name="depreciation_date"/> <field name="depreciation_date"/>
<field name="amount" widget="monetary" string="Depreciation"/>
<field name="depreciated_value" readonly="1"/> <field name="depreciated_value" readonly="1"/>
<field name="amount" widget="monetary" string="Depreciation"/>
<field name="remaining_value" readonly="1" widget="monetary" string="Residual"/> <field name="remaining_value" readonly="1" widget="monetary" string="Residual"/>
<field name="move_check" widget="deprec_lines_toggler" attrs="{'invisible': [('parent_state', '!=', 'open')]}"/> <field name="move_check" widget="deprec_lines_toggler" attrs="{'invisible': [('parent_state', '!=', 'open')]}"/>
<field name="move_posted_check" invisible="1"/> <field name="move_posted_check" invisible="1"/>
<field name="parent_state" invisible="1"/> <field name="parent_state" invisible="1"/>
</tree> </tree>
<form string="Depreciation Lines" create="false"> <form string="Depreciation Lines">
<group> <group>
<group> <group>
<field name="parent_state" invisible="1"/> <field name="parent_state" invisible="1"/>
@ -248,20 +233,20 @@
<t t-name="kanban-box"> <t t-name="kanban-box">
<div t-attf-class="oe_kanban_global_click"> <div t-attf-class="oe_kanban_global_click">
<div class="row mb4"> <div class="row mb4">
<div class="col-6"> <div class="col-xs-6">
<strong><span><t t-esc="record.name.value"/></span></strong> <strong><span><t t-esc="record.name.value"/></span></strong>
</div> </div>
<div class="col-6 text-right"> <div class="col-xs-6 pull-right text-right">
<strong><t t-esc="record.date.value"/></strong> <strong><t t-esc="record.date.value"/></strong>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-6 text-muted"> <div class="col-xs-6 text-muted">
<span><t t-esc="record.category_id.value"/></span> <span><t t-esc="record.category_id.value"/></span>
</div> </div>
<div class="col-6"> <div class="col-xs-6">
<span class="float-right text-right"> <span class="pull-right text-right">
<field name="state" widget="kanban_label_selection" options="{'classes': {'draft': 'primary', 'open': 'success', 'close': 'default'}}"/> <field name="state" widget="label_selection" options="{'classes': {'draft': 'primary', 'open': 'success', 'close': 'default'}}"/>
</span> </span>
</div> </div>
</div> </div>
@ -278,7 +263,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Assets" decoration-info="(state == 'draft')" decoration-muted="(state == 'close')"> <tree string="Assets" decoration-info="(state == 'draft')" decoration-muted="(state == 'close')">
<field name="name"/> <field name="name"/>
<field name="category_id" string="Asset Category"/> <field name="category_id"/>
<field name="date"/> <field name="date"/>
<field name="partner_id" string="Vendor"/> <field name="partner_id" string="Vendor"/>
<field name="value"/> <field name="value"/>
@ -290,37 +275,36 @@
</field> </field>
</record> </record>
<record id="view_account_asset_search" model="ir.ui.view"> <!-- <record id="view_account_asset_search" model="ir.ui.view">-->
<field name="name">account.asset.asset.search</field> <!-- <field name="name">account.asset.asset.search</field>-->
<field name="model">account.asset.asset</field> <!-- <field name="model">account.asset.asset</field>-->
<field name="arch" type="xml"> <!-- <field name="arch" type="xml">-->
<search string="Asset Account"> <!-- <search string="Asset Account">-->
<field name="name" string="Asset"/> <!-- <field name="name" string="Asset"/>-->
<field name="date"/> <!-- <field name="date"/>-->
<filter string="Current" name="current" domain="[('state','in', ('draft','open'))]" help="Assets in draft and open states"/> <!-- <filter string="Current" domain="[('state','in', ('draft','open'))]" help="Assets in draft and open states"/>-->
<filter string="Closed" name="closed" domain="[('state','=', 'close')]" help="Assets in closed state"/> <!-- <filter string="Closed" domain="[('state','=', 'close')]" help="Assets in closed state"/>-->
<field name="category_id" string="Asset Category"/> <!-- <field name="category_id"/>-->
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/> <!-- <field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>-->
<group expand="0" string="Group By..."> <!-- <group expand="0" string="Group By...">-->
<filter string="Date" name="month" domain="[]" context="{'group_by':'date'}"/> <!-- <filter string="Month" domain="[]" context="{'group_by':'date'}"/>-->
<filter string="Asset Category" name="category" domain="[]" context="{'group_by':'category_id'}"/> <!-- <filter string="Category" domain="[]" context="{'group_by':'category_id'}"/>-->
</group> <!-- </group>-->
</search> <!-- </search>-->
</field> <!-- </field>-->
</record> <!-- </record>-->
<record model="ir.actions.act_window" id="action_account_asset_asset_form"> <record model="ir.actions.act_window" id="action_account_asset_asset_form">
<field name="name">Assets</field> <field name="name">Assets</field>
<field name="res_model">account.asset.asset</field> <field name="res_model">account.asset.asset</field>
<!-- <field name="view_type">form</field>-->
<field name="view_mode">tree,kanban,form</field> <field name="view_mode">tree,kanban,form</field>
<!-- <field name="view_id" ref="view_account_asset_asset_purchase_tree"/>--> <field name="view_id" ref="view_account_asset_asset_purchase_tree"/>
<field name="domain">[('category_id.type', '=', 'purchase')]</field> <field name="domain">[('category_id.type', '=', 'purchase')]</field>
</record> </record>
<menuitem parent="account.menu_finance_entries_management" id="menu_action_account_asset_asset_form" action="action_account_asset_asset_form" sequence="101" groups="account.group_account_manager"/> <menuitem parent="account.menu_finance_entries_management" id="menu_action_account_asset_asset_form" action="action_account_asset_asset_form" sequence="101" groups="account.group_account_user"/>
<!-- Configuration --> <!-- Configuration -->
@ -331,33 +315,10 @@
<field name="name">Asset Types</field> <field name="name">Asset Types</field>
<field name="res_model">account.asset.category</field> <field name="res_model">account.asset.category</field>
<field name="domain">[('type', '=', 'purchase')]</field> <field name="domain">[('type', '=', 'purchase')]</field>
<!-- <field name="view_type">form</field>-->
<field name="view_mode">tree,kanban,form</field> <field name="view_mode">tree,kanban,form</field>
<field name="context">{'default_type': 'purchase'}</field> <field name="context">{'default_type': 'purchase'}</field>
</record> </record>
<menuitem parent="account.account_management_menu" <menuitem parent="account.account_management_menu" id="menu_action_account_asset_asset_list_normal_purchase" action="action_account_asset_asset_list_normal_purchase" sequence="6"/>
id="menu_action_account_asset_asset_list_normal_purchase"
action="action_account_asset_asset_list_normal_purchase"
sequence="6"/>
<!-- <record id="stock_scrap_tree_view" model="ir.ui.view">-->
<!-- <field name="name">stock.scrap.tree</field>-->
<!-- <field name="model">stock.scrap</field>-->
<!-- <field name="arch" type="xml">-->
<!-- <tree decoration-danger="state == 'draft'">-->
<!-- <field name="name"/>-->
<!-- <field name="date_done"/>-->
<!-- <field name="product_id"/>-->
<!-- <field name="scrap_qty"/>-->
<!-- <field name="product_uom_id" groups="uom.group_uom"/>-->
<!-- <field name="location_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>-->
<!-- <field name="scrap_location_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>-->
<!-- <field name="state"/>-->
<!-- <field name="company_id" groups="base.group_multi_company"/>-->
<!-- </tree>-->
<!-- </field>-->
<!-- </record>-->
</odoo> </odoo>

7
base_accounting_kit/views/account_invoice_views.xml → base_accounting_kit/views/account_move_views.xml

@ -1,17 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Add "Asset Category" to supplier invoices -->
<record model="ir.ui.view" id="view_invoice_asset_category"> <record model="ir.ui.view" id="view_invoice_asset_category">
<field name="name">account.move.form</field> <field name="name">account.invoice.supplier.form</field>
<field name="model">account.move</field> <field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/> <field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='account_id']" position="before"> <xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='account_id']" position="before">
<field string="Asset Category" name="asset_category_id" attrs="{'column_invisible': [('parent.type', '!=', 'in_invoice')]}" optional="show"/> <field string="Asset Category" attrs="{'column_invisible': [('parent.type', '!=', 'in_invoice')]}"
name="asset_category_id" domain="[('type','=','purchase')]" context="{'default_type':'purchase'}"/>
</xpath> </xpath>
<xpath expr="//field[@name='line_ids']/tree/field[@name='account_id']" position="after"> <xpath expr="//field[@name='line_ids']/tree/field[@name='account_id']" position="after">
<field string="Asset Category" name="asset_category_id" invisible="1"/> <field string="Asset Category" name="asset_category_id" invisible="1"/>
</xpath> </xpath>
</field> </field>
</record> </record>
</odoo> </odoo>

17
base_accounting_kit/views/product_views.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Product Template -->
<record id="view_product_template_form_inherit" model="ir.ui.view">
<field name="name">Product Template (form)</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="account.product_template_form_view"/>
<field name="arch" type="xml">
<field name="property_account_expense_id" position="after">
<field name="asset_category_id"
domain="[('type', '=', 'purchase')]"
context="{'default_type': 'purchase'}"
groups="account.group_account_user"/>
</field>
</field>
</record>
</odoo>

19
base_accounting_kit/wizard/asset_depreciation_confirmation_wizard.py

@ -20,35 +20,26 @@
# #
############################################################################# #############################################################################
from odoo import fields, models, _ from odoo import api, fields, models, _
class AssetDepreciationConfirmationWizard(models.TransientModel): class AssetDepreciationConfirmationWizard(models.TransientModel):
_name = "asset.depreciation.confirmation.wizard" _name = "asset.depreciation.confirmation.wizard"
_description = "asset.depreciation.confirmation.wizard" _description = "asset.depreciation.confirmation.wizard"
date = fields.Date('Account Date', required=True, date = fields.Date('Account Date', required=True, help="Choose the period for which you want to automatically post the depreciation lines of running assets", default=fields.Date.context_today)
help="Choose the period for which you want to "
"automatically post the depreciation "
"lines of running assets",
default=fields.Date.context_today)
def asset_compute(self): def asset_compute(self):
self.ensure_one() self.ensure_one()
context = self._context context = self._context
created_move_ids = self.env[ created_move_ids = self.env['account.asset.asset'].compute_generated_entries(self.date, asset_type=context.get('asset_type'))
'account.asset.asset'].compute_generated_entries(self.date,
asset_type=context.get(
'asset_type'))
return { return {
'name': _('Created Asset Moves') if context.get( 'name': _('Created Asset Moves') if context.get('asset_type') == 'purchase' else _('Created Revenue Moves'),
'asset_type') == 'purchase' else _('Created Revenue Moves'),
'view_type': 'form', 'view_type': 'form',
'view_mode': 'tree,form', 'view_mode': 'tree,form',
'res_model': 'account.move', 'res_model': 'account.move',
'view_id': False, 'view_id': False,
'domain': "[('id','in',[" + ','.join( 'domain': "[('id','in',[" + ','.join(str(id) for id in created_move_ids) + "])]",
str(id) for id in created_move_ids) + "])]",
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',
} }

11
base_accounting_kit/wizard/asset_depreciation_confirmation_wizard_views.xml

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<record id="view_asset_depreciation_confirmation_wizard" model="ir.ui.view"> <record id="view_asset_depreciation_confirmation_wizard" model="ir.ui.view">
<field name="name">asset.depreciation.confirmation.wizard</field> <field name="name">asset.depreciation.confirmation.wizard</field>
<field name="model">asset.depreciation.confirmation.wizard</field> <field name="model">asset.depreciation.confirmation.wizard</field>
@ -17,7 +16,7 @@
</group> </group>
<footer> <footer>
<button string="Generate Entries" name="asset_compute" type="object" class="btn-primary"/> <button string="Generate Entries" name="asset_compute" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/> <button string="Cancel" class="btn-default" special="cancel"/>
</footer> </footer>
</form> </form>
</field> </field>
@ -26,18 +25,14 @@
<record id="action_asset_depreciation_confirmation_wizard" model="ir.actions.act_window"> <record id="action_asset_depreciation_confirmation_wizard" model="ir.actions.act_window">
<field name="name">Post Depreciation Lines</field> <field name="name">Post Depreciation Lines</field>
<field name="res_model">asset.depreciation.confirmation.wizard</field> <field name="res_model">asset.depreciation.confirmation.wizard</field>
<!-- <field name="view_type">form</field>-->
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="view_id" ref="view_asset_depreciation_confirmation_wizard"/> <field name="view_id" ref="view_asset_depreciation_confirmation_wizard"/>
<field name="target">new</field> <field name="target">new</field>
<field name="context">{'asset_type': 'purchase'}</field> <field name="context">{'asset_type': 'purchase'}</field>
</record> </record>
<menuitem name="Generate Assets Entries" <menuitem name="Generate Assets Entries" action="action_asset_depreciation_confirmation_wizard"
action="action_asset_depreciation_confirmation_wizard"
id="menu_asset_depreciation_confirmation_wizard" id="menu_asset_depreciation_confirmation_wizard"
parent="account.menu_finance_entries_generate_entries" parent="account.menu_finance_entries_generate_entries" sequence="111" groups="base.group_no_one"/>
sequence="111"
groups="account.group_account_manager"/>
</odoo> </odoo>

48
base_accounting_kit/wizard/asset_modify.py

@ -24,31 +24,20 @@ from lxml import etree
from odoo import api, fields, models, _ from odoo import api, fields, models, _
from odoo.addons.base.models.ir_ui_view import ( from odoo.addons.base.models.ir_ui_view import (
transfer_field_to_modifiers, transfer_node_to_modifiers, transfer_field_to_modifiers, transfer_node_to_modifiers, transfer_modifiers_to_node,
transfer_modifiers_to_node,
) )
class AssetModify(models.TransientModel): class AssetModify(models.TransientModel):
_name = 'asset.modify' _name = 'asset.modify'
_description = 'Modify Asset' _description = 'Modify Asset'
name = fields.Text(string='Reason', required=True) name = fields.Text(string='Reason', required=True)
method_number = fields.Integer(string='Number of Depreciations', method_number = fields.Integer(string='Number of Depreciations', required=True)
required=True)
method_period = fields.Integer(string='Period Length') method_period = fields.Integer(string='Period Length')
method_end = fields.Date(string='Ending date') method_end = fields.Date(string='Ending date')
asset_method_time = fields.Char(compute='_get_asset_method_time', asset_method_time = fields.Char(compute='_get_asset_method_time', string='Asset Method Time', readonly=True)
string='Asset Method Time', readonly=True)
def _get_asset_method_time(self):
if self.env.context.get('active_id'):
asset = self.env['account.asset.asset'].browse(
self.env.context.get('active_id'))
self.asset_method_time = asset.method_time
def setup_modifiers(node, field=None, context=None, in_tree_view=False): def setup_modifiers(node, field=None, context=None, in_tree_view=False):
modifiers = {} modifiers = {}
if field is not None: if field is not None:
transfer_field_to_modifiers(field, modifiers) transfer_field_to_modifiers(field, modifiers)
@ -56,24 +45,24 @@ class AssetModify(models.TransientModel):
node, modifiers, context=context, in_tree_view=in_tree_view) node, modifiers, context=context, in_tree_view=in_tree_view)
transfer_modifiers_to_node(modifiers, node) transfer_modifiers_to_node(modifiers, node)
def _get_asset_method_time(self):
if self.env.context.get('active_id'):
asset = self.env['account.asset.asset'].browse(self.env.context.get('active_id'))
self.asset_method_time = asset.method_time
@api.model @api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
submenu=False): result = super(AssetModify, self).fields_view_get(view_id, view_type, toolbar=toolbar, submenu=submenu)
result = super(AssetModify, self).fields_view_get(view_id, view_type,
toolbar=toolbar,
submenu=submenu)
asset_id = self.env.context.get('active_id') asset_id = self.env.context.get('active_id')
active_model = self.env.context.get('active_model') active_model = self.env.context.get('active_model')
if active_model == 'account.asset.asset' and asset_id: if active_model == 'account.asset.asset' and asset_id:
asset = self.env['account.asset.asset'].browse(asset_id) asset = self.env['account.asset.asset'].browse(asset_id)
doc = etree.XML(result['arch']) doc = etree.XML(result['arch'])
if asset.method_time == 'number' and doc.xpath( if asset.method_time == 'number' and doc.xpath("//field[@name='method_end']"):
"//field[@name='method_end']"):
node = doc.xpath("//field[@name='method_end']")[0] node = doc.xpath("//field[@name='method_end']")[0]
node.set('invisible', '1') node.set('invisible', '1')
self.setup_modifiers(node, result['fields']['method_end']) self.setup_modifiers(node, result['fields']['method_end'])
elif asset.method_time == 'end' and doc.xpath( elif asset.method_time == 'end' and doc.xpath("//field[@name='method_number']"):
"//field[@name='method_number']"):
node = doc.xpath("//field[@name='method_number']")[0] node = doc.xpath("//field[@name='method_number']")[0]
node.set('invisible', '1') node.set('invisible', '1')
self.setup_modifiers(node, result['fields']['method_number']) self.setup_modifiers(node, result['fields']['method_number'])
@ -94,8 +83,7 @@ class AssetModify(models.TransientModel):
if 'method_end' in fields and asset.method_time == 'end': if 'method_end' in fields and asset.method_time == 'end':
res.update({'method_end': asset.method_end}) res.update({'method_end': asset.method_end})
if self.env.context.get('active_id'): if self.env.context.get('active_id'):
active_asset = self.env['account.asset.asset'].browse( active_asset = self.env['account.asset.asset'].browse(self.env.context.get('active_id'))
self.env.context.get('active_id'))
res['asset_method_time'] = active_asset.method_time res['asset_method_time'] = active_asset.method_time
return res return res
@ -117,12 +105,8 @@ class AssetModify(models.TransientModel):
} }
asset.write(asset_vals) asset.write(asset_vals)
asset.compute_depreciation_board() asset.compute_depreciation_board()
tracked_fields = self.env['account.asset.asset'].fields_get( tracked_fields = self.env['account.asset.asset'].fields_get(['method_number', 'method_period', 'method_end'])
['method_number', 'method_period', 'method_end']) changes, tracking_value_ids = asset._message_track(tracked_fields, old_values)
changes, tracking_value_ids = asset._message_track(tracked_fields,
old_values)
if changes: if changes:
asset.message_post(subject=_('Depreciation board modified'), asset.message_post(subject=_('Depreciation board modified'), body=self.name, tracking_value_ids=tracking_value_ids)
body=self.name,
tracking_value_ids=tracking_value_ids)
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}

2
base_accounting_kit/wizard/asset_modify_views.xml

@ -22,7 +22,7 @@
</group> </group>
<footer> <footer>
<button name="modify" string="Modify" type="object" class="btn-primary"/> <button name="modify" string="Modify" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/> <button string="Cancel" class="btn-default" special="cancel"/>
</footer> </footer>
</form> </form>
</field> </field>

12
base_accounting_kit/wizard/cash_flow_report.xml

@ -5,16 +5,20 @@
<field name="model">cash.flow.report</field> <field name="model">cash.flow.report</field>
<field name="inherit_id" ref="account.account_common_report_view"/> <field name="inherit_id" ref="account.account_common_report_view"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="company_id" position="replace"/>
<field name="target_move" position="before"> <field name="target_move" position="before">
<field name="account_report_id" domain="[('parent_id','=',False)]" readonly="1"/> <field name="account_report_id" domain="[('parent_id','=',False)]" readonly="1"/>
<field name="enable_filter"/>
</field> </field>
<field name="target_move" position="after"> <field name="target_move" position="after">
<field name="enable_filter" invisible="1"/> <field name="debit_credit"/>
<field name="debit_credit" attrs="{'invisible': [('enable_filter','=',True)]}"/>
</field> </field>
<field name="journal_ids" position="after"> <field name="journal_ids" position="after">
<notebook tabpos="up" colspan="4"> <group>
<page string="Comparison" name="comparison" attrs="{'invisible': [('enable_filter','=',False)]}"> <field name="company_id" position="replace"/>
</group>
<notebook tabpos="up" colspan="4" attrs="{'invisible': [('enable_filter','=',False)]}">
<page string="Comparison" name="comparison">
<group> <group>
<field name="label_filter" attrs="{'required': [('enable_filter', '=', True)]}"/> <field name="label_filter" attrs="{'required': [('enable_filter', '=', True)]}"/>
<field name="filter_cmp"/> <field name="filter_cmp"/>

16
base_accounting_kit/wizard/recurring_payments_wizard.xml

@ -46,11 +46,23 @@
<field name="view_id" ref="account_recurring_payments_wizard_view"/> <field name="view_id" ref="account_recurring_payments_wizard_view"/>
<field name="target">new</field> <field name="target">new</field>
</record> </record>
<!-- Create a parent menu for payments and recurring payment -->
<menuitem id="menu_action_account_payments_receivable_main" name="Payments"
parent="account.menu_finance_receivables" sequence="15"/>
<menuitem id="menu_action_account_payments_payable_main" name="Payments"
parent="account.menu_finance_payables" sequence="20"/>
<!-- Override the existing Payment menu -->
<menuitem action="account.action_account_payments" id="menu_action_account_payments_receivable"
parent="menu_action_account_payments_receivable_main" sequence="1"/>
<menuitem action="account.action_account_payments_payable" id="menu_action_account_payments_payable"
parent="menu_action_account_payments_payable_main" sequence="1"/>
<!-- Menu for recurring payment -->
<menuitem id="account_recurring_payments_child2" name="Recurring Entries" <menuitem id="account_recurring_payments_child2" name="Recurring Entries"
action="action_account_recurring_payments_wizard_view" action="action_account_recurring_payments_wizard_view"
parent="account.menu_action_account_payments_receivable" groups="account.group_account_user"/> parent="menu_action_account_payments_receivable_main" groups="account.group_account_user"/>
<menuitem id="account_recurring_payments_child3" name="Recurring Entries" <menuitem id="account_recurring_payments_child3" name="Recurring Entries"
action="action_account_recurring_payments_wizard_view" action="action_account_recurring_payments_wizard_view"
parent="account.menu_action_account_payments_payable" groups="account.group_account_user"/> parent="menu_action_account_payments_payable_main" groups="account.group_account_user"/>
</data> </data>
</odoo> </odoo>

Loading…
Cancel
Save