2 Commits

62 changed files with 13285 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
from . import wizard
from . import models
from . import report

View File

@@ -0,0 +1,32 @@
{
'name': 'Odoo 19 Assets Management',
'version': '19.0.1.0.0', # __odoosky_original_version__: '1.0.0'
'author': 'Odoo Mates, Odoo SA',
'depends': ['account'],
'description': """Manage assets owned by a company or a person.
Keeps track of depreciation's, and creates corresponding journal entries""",
'summary': 'Odoo 19 Assets Management',
'category': 'Accounting',
'sequence': 10,
'website': 'https://www.odoomates.tech',
'license': 'LGPL-3',
'images': ['static/description/assets.gif'],
'data': [
'data/account_asset_data.xml',
'security/account_asset_security.xml',
'security/ir.model.access.csv',
'wizard/asset_depreciation_confirmation_wizard_views.xml',
'wizard/asset_modify_views.xml',
'views/account_asset_views.xml',
'views/account_move_views.xml',
'views/account_asset_templates.xml',
'views/asset_category_views.xml',
'views/product_views.xml',
'report/account_asset_report_views.xml',
],
'assets': {
'web.assets_backend': [
'om_account_asset/static/src/scss/account_asset.scss',
],
},
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding='UTF-8'?>
<odoo>
<data noupdate="1">
<record id="account_asset_cron" model="ir.cron">
<field name="name">Account Asset: Generate asset entries</field>
<field name="model_id" ref="model_account_asset_asset"/>
<field name="state">code</field>
<field name="code">model._cron_generate_entries()</field>
<field name="interval_number">1</field>
<field name="interval_type">months</field>
</record>
</data>
</odoo>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import account
from . import account_asset
from . import account_move
from . import product

View File

@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class AccountMove(models.Model):
_inherit = 'account.move'
asset_depreciation_ids = fields.One2many('account.asset.depreciation.line', 'move_id',
string='Assets Depreciation Lines')
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 action_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).action_post()

View File

@@ -0,0 +1,728 @@
import calendar
from datetime import date, datetime
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools import float_compare, float_is_zero
from markupsafe import Markup
class AccountAssetCategory(models.Model):
_name = 'account.asset.category'
_description = 'Asset category'
_inherit = ['mail.thread', 'mail.activity.mixin', 'analytic.mixin']
exclude_types = ['asset_receivable', 'asset_cash', 'liability_payable',
'liability_credit_card', 'equity', 'equity_unaffected']
active = fields.Boolean(default=True)
name = fields.Char(required=True, index=True, string="Asset Type")
account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account')
account_asset_id = fields.Many2one(
'account.account', string='Asset Account',
required=True,
domain=[('account_type', 'not in', exclude_types)],
help="Account used to record the purchase of the asset at its original price."
)
account_depreciation_id = fields.Many2one(
'account.account', string='Depreciation Entries: Asset Account',
required=True,
domain=[('account_type', 'not in', exclude_types)],
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=[('account_type', 'not in', exclude_types)],
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.company
)
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"
" * Linear: Calculated on basis of: Gross Value / Number of Depreciations\n"
" * 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_period = fields.Integer(
string='Period Length', default=1,
help="State here the time between 2 depreciations, in months", required=True
)
method_progress_factor = fields.Float(
'Degressive Factor', default=0.3
)
method_time = fields.Selection(
[('number', 'Number of Entries'), ('end', 'Ending Date')],
string='Time Method', required=True, default='number',
help="Choose the method to use to compute the dates and number of entries.\n"
" * Number of Entries: Fix the number of entries and the time between 2 depreciations.\n"
" * Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond."
)
method_end = fields.Date('Ending date')
prorata = fields.Boolean(
string='Prorata Temporis',
help='Indicates that the first depreciation entry for this asset have to be done from the '
'purchase date instead of the first of January'
)
open_asset = fields.Boolean(
string='Auto-Confirm Assets',
help="Check this if you want to automatically confirm the assets "
"of this category when created by invoices."
)
group_entries = fields.Boolean(
string='Group Journal Entries',
help="Check this if you want to group the generated entries by categories."
)
type = fields.Selection(
[('sale', 'Sale: Revenue Recognition'), ('purchase', 'Purchase: Asset')],
required=True, index=True, default='purchase'
)
date_first_depreciation = fields.Selection([
('last_day_period', 'Based on Last Day of Purchase Period'),
('manual', 'Manual (Defaulted on Purchase Date)')],
string='Depreciation Dates', default='manual', 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.')
@api.onchange('account_asset_id')
def onchange_account_asset(self):
if self.type == "purchase":
self.account_depreciation_id = self.account_asset_id
elif self.type == "sale":
self.account_depreciation_expense_id = self.account_asset_id
@api.onchange('type')
def onchange_type(self):
if self.type == 'sale':
self.prorata = True
self.method_period = 1
else:
self.method_period = 12
@api.onchange('method_time')
def _onchange_method_time(self):
if self.method_time != 'number':
self.prorata = False
class AccountAssetAsset(models.Model):
_name = 'account.asset.asset'
_description = 'Asset/Revenue Recognition'
_inherit = ['mail.thread', 'mail.activity.mixin', 'analytic.mixin']
entry_count = fields.Integer(compute='_entry_count', string='# Asset Entries')
name = fields.Char(string='Asset Name', required=True)
code = fields.Char(string='Reference', size=32)
value = fields.Monetary(string='Gross Value', required=True)
currency_id = fields.Many2one(
'res.currency', string='Currency', required=True,
default=lambda self: self.env.user.company_id.currency_id.id
)
company_id = fields.Many2one(
'res.company', string='Company', required=True,
default=lambda self: self.env.company)
note = fields.Text()
category_id = fields.Many2one(
'account.asset.category', string='Category',
required=True, change_default=True
)
date = fields.Date(string='Date', required=True, default=fields.Date.context_today)
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"
"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.")
active = fields.Boolean(default=True)
partner_id = fields.Many2one('res.partner', string='Partner')
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 * Linear:"
" Calculated on basis of: Gross Value / Number of Depreciations\n"
" * 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_period = fields.Integer(
string='Number of Months in a Period', required=True, default=12,
help="The amount of time between two depreciations, in months"
)
method_end = fields.Date(string='Ending Date')
method_progress_factor = fields.Float(
string='Degressive Factor', default=0.3
)
value_residual = fields.Monetary(compute='_amount_residual', string='Residual Value')
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"
" * 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."
)
prorata = fields.Boolean(
string='Prorata Temporis',
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'
)
depreciation_line_ids = fields.One2many(
'account.asset.depreciation.line', 'asset_id', string='Depreciation Lines'
)
salvage_value = fields.Monetary(
string='Salvage Value',
help="It is the amount you plan to have that you cannot depreciate."
)
invoice_id = fields.Many2one('account.move', string='Invoice', copy=False)
type = fields.Selection(related="category_id.type", string='Type', required=True)
account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account')
date_first_depreciation = fields.Selection([
('last_day_period', 'Based on Last Day of Purchase Period'),
('manual', 'Manual')],
string='Depreciation Dates', default='manual',
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',
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):
for asset in self:
if asset.state in ['open', 'close']:
raise UserError(_('You cannot delete a document that is in %s state.') % (asset.state,))
for depreciation_line in asset.depreciation_line_ids:
if depreciation_line.move_id:
raise UserError(_('You cannot delete a document that contains posted entries.'))
return super(AccountAssetAsset, self).unlink()
@api.model
def _cron_generate_entries(self):
self.compute_generated_entries(datetime.today())
@api.model
def compute_generated_entries(self, date, asset_type=None):
# Entries generated : one by grouped category and one by asset from ungrouped category
created_move_ids = []
type_domain = []
if asset_type:
type_domain = [('type', '=', asset_type)]
ungrouped_assets = self.env['account.asset.asset'].search(type_domain + [('state', '=', 'open'), ('category_id.group_entries', '=', False)])
created_move_ids += ungrouped_assets._compute_entries(date, group_entries=False)
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
def _compute_board_amount(self, sequence, residual_amount, amount_to_depr,
undone_dotation_number, posted_depreciation_line_ids,
total_days, depreciation_date):
amount = 0
if sequence == undone_dotation_number:
amount = residual_amount
else:
if self.method == 'linear':
amount = amount_to_depr / (undone_dotation_number - len(posted_depreciation_line_ids))
if self.prorata:
amount = amount_to_depr / self.method_number
if sequence == 1:
date = self.date
if self.method_period % 12 != 0:
month_days = calendar.monthrange(date.year, date.month)[1]
days = month_days - date.day + 1
amount = (amount_to_depr / self.method_number) / month_days * days
else:
days = (self.company_id.compute_fiscalyear_dates(date)['date_to'] - date).days + 1
amount = (amount_to_depr / self.method_number) / total_days * days
elif self.method == 'degressive':
amount = residual_amount * self.method_progress_factor
if self.prorata:
if sequence == 1:
date = self.date
if self.method_period % 12 != 0:
month_days = calendar.monthrange(date.year, date.month)[1]
days = month_days - date.day + 1
amount = (residual_amount * self.method_progress_factor) / month_days * days
else:
days = (self.company_id.compute_fiscalyear_dates(date)['date_to'] - date).days + 1
amount = (residual_amount * self.method_progress_factor) / total_days * days
return amount
def _compute_board_undone_dotation_nb(self, depreciation_date, total_days):
undone_dotation_number = self.method_number
if self.method_time == 'end':
end_date = self.method_end
undone_dotation_number = 0
while depreciation_date <= end_date:
depreciation_date = date(depreciation_date.year, depreciation_date.month,
depreciation_date.day) + relativedelta(months=+self.method_period)
undone_dotation_number += 1
if self.prorata:
undone_dotation_number += 1
return undone_dotation_number
def compute_depreciation_board(self):
self.ensure_one()
posted_depreciation_line_ids = self.depreciation_line_ids.filtered(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
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 we already have some previous validated entries, starting date is last entry + method period
if posted_depreciation_line_ids and posted_depreciation_line_ids[-1].depreciation_date:
last_depreciation_date = fields.Date.from_string(posted_depreciation_line_ids[-1].depreciation_date)
depreciation_date = last_depreciation_date + relativedelta(months=+self.method_period)
else:
# depreciation_date computed from the purchase date
depreciation_date = self.date
if self.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 self.method_period == 12:
depreciation_date = depreciation_date + relativedelta(month=int(self.company_id.fiscalyear_last_month))
depreciation_date = depreciation_date + relativedelta(day=int(self.company_id.fiscalyear_last_day))
if depreciation_date < self.date:
depreciation_date = depreciation_date + relativedelta(years=1)
elif self.first_depreciation_manual_date and self.first_depreciation_manual_date != self.date:
# depreciation_date set manually from the 'first_depreciation_manual_date' field
depreciation_date = self.first_depreciation_manual_date
total_days = (depreciation_date.year % 4) and 365 or 366
month_day = depreciation_date.day
undone_dotation_number = self._compute_board_undone_dotation_nb(depreciation_date, total_days)
for x in range(len(posted_depreciation_line_ids), undone_dotation_number):
sequence = x + 1
amount = self._compute_board_amount(sequence, residual_amount, amount_to_depr,
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
residual_amount -= amount
vals = {
'amount': amount,
'asset_id': self.id,
'sequence': sequence,
'name': (self.code or '') + '/' + str(sequence),
'remaining_value': residual_amount,
'depreciated_value': self.value - (self.salvage_value + residual_amount),
'depreciation_date': depreciation_date,
}
commands.append((0, False, vals))
depreciation_date = depreciation_date + relativedelta(months=+self.method_period)
if month_day > 28 and self.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 self.prorata and self.method_period % 12 != 0 and self.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)
self.write({'depreciation_line_ids': commands})
return True
def validate(self):
self.write({'state': 'open'})
fields = [
'method',
'method_number',
'method_period',
'method_end',
'method_progress_factor',
'method_time',
'salvage_value',
'invoice_id',
]
ref_tracked_fields = self.env['account.asset.asset'].fields_get(fields)
for asset in self:
tracked_fields = ref_tracked_fields.copy()
if asset.method == 'linear':
del(tracked_fields['method_progress_factor'])
if asset.method_time != 'end':
del(tracked_fields['method_end'])
else:
del(tracked_fields['method_number'])
dummy, tracking_value_ids = asset._mail_track(tracked_fields, dict.fromkeys(fields))
asset.message_post(subject=_('Asset created'), tracking_value_ids=tracking_value_ids)
def _return_disposal_view(self, 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],
}
def _get_disposal_moves(self):
move_ids = []
for asset in self:
unposted_depreciation_line_ids = asset.depreciation_line_ids.filtered(lambda x: not x.move_check)
if unposted_depreciation_line_ids:
old_values = {
'method_end': asset.method_end,
'method_number': asset.method_number,
}
# Remove all unposted depr. lines
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
sequence = len(asset.depreciation_line_ids) - len(unposted_depreciation_line_ids) + 1
today = fields.Datetime.today()
vals = {
'amount': asset.value_residual,
'asset_id': asset.id,
'sequence': sequence,
'name': (asset.code or '') + '/' + str(sequence),
'remaining_value': 0,
'depreciated_value': asset.value - asset.salvage_value, # the asset is completely depreciated
'depreciation_date': today,
}
commands.append((0, False, vals))
asset.write({'depreciation_line_ids': commands, 'method_end': today, 'method_number': sequence})
tracked_fields = self.env['account.asset.asset'].fields_get(['method_number', 'method_end'])
changes, tracking_value_ids = asset._mail_track(tracked_fields, old_values)
if changes:
asset.message_post(subject=_('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
def set_to_close(self):
move_ids = self._get_disposal_moves()
if move_ids:
return self._return_disposal_view(move_ids)
# Fallback, as if we just clicked on the smartbutton
return self.open_entries()
def set_to_draft(self):
self.write({'state': 'draft'})
@api.depends('value', 'salvage_value', 'depreciation_line_ids.move_check', 'depreciation_line_ids.amount')
def _amount_residual(self):
for rec in self:
total_amount = 0.0
for line in rec.depreciation_line_ids:
if line.move_check:
total_amount += line.amount
rec.value_residual = rec.value - total_amount - rec.salvage_value
@api.onchange('company_id')
def onchange_company_id(self):
self.currency_id = self.company_id.currency_id.id
@api.onchange('date_first_depreciation')
def onchange_date_first_depreciation(self):
for record in self:
if record.date_first_depreciation == 'manual':
record.first_depreciation_manual_date = record.date
@api.depends('depreciation_line_ids.move_id')
def _entry_count(self):
for asset in self:
res = self.env['account.asset.depreciation.line'].search_count([('asset_id', '=', asset.id), ('move_id', '!=', False)])
asset.entry_count = res or 0
@api.constrains('prorata', 'method_time')
def _check_prorata(self):
if self.prorata and self.method_time != 'number':
raise ValidationError(_('Prorata temporis can be applied only for the "number of depreciations" time method.'))
@api.onchange('category_id')
def onchange_category_id(self):
vals = self.onchange_category_id_values(self.category_id.id)
# We cannot use 'write' on an object that doesn't exist yet
if vals:
for k, v in vals['value'].items():
setattr(self, k, v)
def onchange_category_id_values(self, category_id):
if category_id:
category = self.env['account.asset.category'].browse(category_id)
return {
'value': {
'method': category.method,
'method_number': category.method_number,
'method_time': category.method_time,
'method_period': category.method_period,
'method_progress_factor': category.method_progress_factor,
'method_end': category.method_end,
'prorata': category.prorata,
'date_first_depreciation': category.date_first_depreciation,
'account_analytic_id': category.account_analytic_id.id,
'analytic_distribution': category.analytic_distribution,
}
}
@api.onchange('method_time')
def onchange_method_time(self):
if self.method_time != 'number':
self.prorata = False
def copy_data(self, default=None):
if default is None:
default = {}
default['name'] = self.name + _(' (copy)')
return super(AccountAssetAsset, self).copy_data(default)
def _compute_entries(self, date, group_entries=False):
depreciation_ids = self.env['account.asset.depreciation.line'].search([
('asset_id', 'in', self.ids), ('depreciation_date', '<=', date),
('move_check', '=', False)])
if group_entries:
return depreciation_ids.create_grouped_move()
return depreciation_ids.create_move()
@api.model_create_multi
def create(self, vals_list):
assets = super(AccountAssetAsset, self.with_context(mail_create_nolog=True)).create(vals_list)
for asset in assets:
asset.sudo().compute_depreciation_board()
return assets
def write(self, vals):
res = super(AccountAssetAsset, self).write(vals)
if 'depreciation_line_ids' not in vals and 'state' not in vals:
for rec in self:
rec.compute_depreciation_board()
return res
def open_entries(self):
move_ids = []
for asset in self:
for depreciation_line in asset.depreciation_line_ids:
if depreciation_line.move_id:
move_ids.append(depreciation_line.move_id.id)
return {
'name': _('Journal Entries'),
'view_type': 'form',
'view_mode': 'list,form',
'res_model': 'account.move',
'view_id': False,
'type': 'ir.actions.act_window',
'domain': [('id', 'in', move_ids)],
}
class AccountAssetDepreciationLine(models.Model):
_name = 'account.asset.depreciation.line'
_description = 'Asset depreciation line'
name = fields.Char(string='Depreciation Name', required=True, index=True)
sequence = fields.Integer(required=True)
asset_id = fields.Many2one('account.asset.asset', string='Asset',
required=True, ondelete='cascade')
parent_state = fields.Selection(related='asset_id.state',
string='State of Asset')
amount = fields.Monetary(string='Current Depreciation',
required=True)
remaining_value = fields.Monetary(string='Next Period Depreciation',
required=True)
depreciated_value = fields.Monetary(string='Cumulative Depreciation',
required=True)
depreciation_date = fields.Date('Depreciation Date', index=True)
move_id = fields.Many2one('account.move', string='Depreciation Entry')
move_check = fields.Boolean(compute='_get_move_check', string='Linked',
store=True)
move_posted_check = fields.Boolean(compute='_get_move_posted_check',
string='Posted', store=True)
currency_id = fields.Many2one('res.currency', string='Currency',
related='asset_id.currency_id',
readonly=True)
@api.depends('move_id')
def _get_move_check(self):
for line in self:
line.move_check = bool(line.move_id)
@api.depends('move_id.state')
def _get_move_posted_check(self):
for line in self:
line.move_posted_check = True if line.move_id and line.move_id.state == 'posted' else False
def create_move(self, post_move=True):
created_moves = self.env['account.move']
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'))).action_post()
return [x.id for x in created_moves]
def _prepare_move(self, line):
category_id = line.asset_id.category_id
analytic_distribution = line.asset_id.analytic_distribution
depreciation_date = self.env.context.get('depreciation_date') or line.depreciation_date or fields.Date.context_today(self)
company_currency = line.asset_id.company_id.currency_id
current_currency = line.asset_id.currency_id
prec = company_currency.decimal_places
amount = current_currency._convert(
line.amount, company_currency, line.asset_id.company_id, depreciation_date)
asset_name = line.asset_id.name + ' (%s/%s)' % (line.sequence, len(line.asset_id.depreciation_line_ids))
move_line_1 = {
'name': asset_name,
'account_id': category_id.account_depreciation_id.id,
'debit': 0.0 if float_compare(amount, 0.0, precision_digits=prec) > 0 else -amount,
'credit': amount if float_compare(amount, 0.0, precision_digits=prec) > 0 else 0.0,
'partner_id': line.asset_id.partner_id.id,
'analytic_distribution': analytic_distribution,
'currency_id': company_currency != current_currency and current_currency.id or company_currency.id,
'amount_currency': - 1.0 * line.amount
}
move_line_2 = {
'name': asset_name,
'account_id': category_id.account_depreciation_expense_id.id,
'credit': 0.0 if float_compare(amount, 0.0, precision_digits=prec) > 0 else -amount,
'debit': amount if float_compare(amount, 0.0, precision_digits=prec) > 0 else 0.0,
'partner_id': line.asset_id.partner_id.id,
'analytic_distribution': analytic_distribution,
'currency_id': company_currency != current_currency and current_currency.id or company_currency.id,
'amount_currency': line.amount,
}
move_vals = {
'ref': line.asset_id.code,
'date': depreciation_date or False,
'journal_id': category_id.journal_id.id,
'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)],
}
return move_vals
def _prepare_move_grouped(self):
asset_id = self[0].asset_id
category_id = asset_id.category_id # we can suppose that all lines have the same category
account_analytic_id = asset_id.account_analytic_id
# analytic_tag_ids = asset_id.analytic_tag_ids
analytic_distribution = asset_id.analytic_distribution
depreciation_date = self.env.context.get('depreciation_date') or fields.Date.context_today(self)
amount = 0.0
for line in self:
# Sum amount of all depreciation lines
company_currency = line.asset_id.company_id.currency_id
current_currency = line.asset_id.currency_id
company = line.asset_id.company_id
amount += current_currency._convert(line.amount, company_currency, company, fields.Date.today())
name = category_id.name + _(' (grouped)')
move_line_1 = {
'name': name,
'account_id': category_id.account_depreciation_id.id,
'debit': 0.0,
'credit': amount,
'journal_id': category_id.journal_id.id,
'analytic_distribution': analytic_distribution,
}
move_line_2 = {
'name': name,
'account_id': category_id.account_depreciation_expense_id.id,
'credit': 0.0,
'debit': amount,
'journal_id': category_id.journal_id.id,
'analytic_distribution': analytic_distribution,
}
move_vals = {
'ref': category_id.name,
'date': depreciation_date or False,
'journal_id': category_id.journal_id.id,
'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)],
}
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})
created_moves |= move
if post_move and created_moves:
created_moves.action_post()
return [x.id for x in created_moves]
def post_lines_and_close_asset(self):
# we re-evaluate the assets to determine whether we can close them
for line in self:
line.log_message_when_posted()
asset = line.asset_id
if asset.currency_id.is_zero(asset.value_residual):
asset.message_post(body=_("Document closed."))
asset.write({'state': 'close'})
def log_message_when_posted(self):
def _format_message(message_description, tracked_values):
message = ''
if message_description:
message = '<span>%s</span>' % message_description
for name, values in tracked_values.items():
message += '<div> &nbsp; &nbsp; &bull; <b>%s</b>: ' % name
message += '%s</div>' % values
return Markup(message)
for line in self:
if line.move_id and line.move_id.state == 'draft':
partner_name = line.asset_id.partner_id.name
currency_name = line.asset_id.currency_id.name
msg_values = {_('Currency'): currency_name, _('Amount'): line.amount}
if partner_name:
msg_values[_('Partner')] = partner_name
msg = _format_message(_('Depreciation line posted.'), msg_values)
line.asset_id.message_post(body=msg)
def unlink(self):
for record in self:
if record.move_check:
if record.asset_id.category_id.type == 'purchase':
msg = _("You cannot delete posted depreciation lines.")
else:
msg = _("You cannot delete posted installment lines.")
raise UserError(msg)
return super(AccountAssetDepreciationLine, self).unlink()

View File

@@ -0,0 +1,160 @@
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError
class AccountMove(models.Model):
_inherit = 'account.move'
asset_ids = fields.One2many(
'account.asset.asset', 'invoice_id', string="Assets"
)
def button_draft(self):
res = super(AccountMove, self).button_draft()
for move in self:
if any(asset_id.state != 'draft' for asset_id in move.asset_ids):
raise ValidationError(_(
'You cannot reset to draft for an entry having a posted asset'))
if move.asset_ids:
move.asset_ids.sudo().write({'active': False})
for asset in move.asset_ids:
asset.sudo().message_post(body=_("Vendor bill cancelled."))
return res
@api.model
def _refund_cleanup_lines(self, lines):
result = super(AccountMove, self)._refund_cleanup_lines(lines)
for i, line in enumerate(lines):
for name, field in line._fields.items():
if name == 'asset_category_id':
result[i][2][name] = False
break
return result
def action_cancel(self):
res = super(AccountMove, self).action_cancel()
assets = self.env['account.asset.asset'].sudo().search(
[('invoice_id', 'in', self.ids)])
if assets:
assets.sudo().write({'active': False})
for asset in assets:
asset.sudo().message_post(body=_("Vendor bill cancelled."))
return res
def action_post(self):
result = super(AccountMove, self).action_post()
for inv in self:
context = dict(self.env.context)
context.pop('default_type', None)
for mv_line in inv.invoice_line_ids:
mv_line.with_context(context).asset_create()
return result
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
asset_category_id = fields.Many2one(
'account.asset.category', string='Asset Category'
)
asset_start_date = fields.Date(
string='Asset Start Date', compute='_get_asset_date',
readonly=True, store=True
)
asset_end_date = fields.Date(
string='Asset End Date', compute='_get_asset_date',
readonly=True, store=True
)
asset_mrr = fields.Float(
string='Monthly Recurring Revenue', compute='_get_asset_date',
readonly=True, store=True
)
@api.model
def default_get(self, fields):
res = super(AccountMoveLine, self).default_get(fields)
if self.env.context.get('create_bill') and not self.asset_category_id:
if self.product_id and self.move_id.move_type == 'out_invoice' and \
self.product_id.product_tmpl_id.deferred_revenue_category_id:
self.asset_category_id = self.product_id.product_tmpl_id.deferred_revenue_category_id.id
elif self.product_id and self.product_id.product_tmpl_id.asset_category_id and \
self.move_id.move_type == 'in_invoice':
self.asset_category_id = self.product_id.product_tmpl_id.asset_category_id.id
self.onchange_asset_category_id()
return res
@api.depends('asset_category_id', 'move_id.invoice_date')
def _get_asset_date(self):
for rec in self:
rec.asset_mrr = 0
rec.asset_start_date = False
rec.asset_end_date = False
cat = rec.asset_category_id
if cat:
if cat.method_number == 0 or cat.method_period == 0:
raise UserError(_('The number of depreciations or the period length of '
'your asset category cannot be 0.'))
months = cat.method_number * cat.method_period
if rec.move_id.move_type in ['out_invoice', 'out_refund']:
price_subtotal = self.currency_id._convert(
self.price_subtotal,
self.company_currency_id,
self.company_id,
self.move_id.invoice_date or fields.Date.context_today(
self))
rec.asset_mrr = price_subtotal / months
if rec.move_id.invoice_date:
start_date = rec.move_id.invoice_date.replace(day=1)
end_date = (start_date + relativedelta(months=months, days=-1))
rec.asset_start_date = start_date
rec.asset_end_date = end_date
def asset_create(self):
if self.asset_category_id:
price_subtotal = self.currency_id._convert(
self.price_subtotal,
self.company_currency_id,
self.company_id,
self.move_id.invoice_date or fields.Date.context_today(
self))
vals = {
'name': self.name,
'code': self.name or False,
'category_id': self.asset_category_id.id,
'value': price_subtotal,
'partner_id': self.move_id.partner_id.id,
'company_id': self.move_id.company_id.id,
'currency_id': self.move_id.company_currency_id.id,
'date': self.move_id.invoice_date or self.move_id.date,
'invoice_id': self.move_id.id,
}
changed_vals = self.env['account.asset.asset'].onchange_category_id_values(vals['category_id'])
vals.update(changed_vals['value'])
asset = self.env['account.asset.asset'].create(vals)
if self.asset_category_id.open_asset:
if asset.date_first_depreciation == 'manual':
asset.first_depreciation_manual_date = asset.date
asset.validate()
return True
@api.onchange('asset_category_id', 'product_uom_id')
def onchange_asset_category_id(self):
if self.move_id.move_type == 'out_invoice' and self.asset_category_id:
self.account_id = self.asset_category_id.account_asset_id.id
elif self.move_id.move_type == 'in_invoice' and self.asset_category_id:
self.account_id = self.asset_category_id.account_asset_id.id
@api.onchange('product_id')
def _inverse_product_id(self):
res = super(AccountMoveLine, self)._inverse_product_id()
for rec in self:
if rec.product_id:
if rec.move_id.move_type == 'out_invoice':
rec.asset_category_id = rec.product_id.product_tmpl_id.deferred_revenue_category_id.id
elif rec.move_id.move_type == 'in_invoice':
rec.asset_category_id = rec.product_id.product_tmpl_id.asset_category_id.id
def get_invoice_line_account(self, type, product, fpos, company):
return product.asset_category_id.account_asset_id or super(AccountMoveLine, self).get_invoice_line_account(type, product, fpos, company)

View File

@@ -0,0 +1,22 @@
from odoo import api, fields, models
class ProductTemplate(models.Model):
_inherit = 'product.template'
asset_category_id = fields.Many2one(
'account.asset.category', string='Asset Type',
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):
res = super(ProductTemplate, self)._get_asset_accounts()
if self.asset_category_id:
res['stock_input'] = self.property_account_expense_id
if self.deferred_revenue_category_id:
res['stock_output'] = self.property_account_income_id
return res

View File

@@ -0,0 +1 @@
from . import account_asset_report

View File

@@ -0,0 +1,65 @@
from odoo import api, fields, models, tools
class AssetAssetReport(models.Model):
_name = "asset.asset.report"
_description = "Assets Analysis"
_auto = False
name = fields.Char(string='Year', required=False, readonly=True)
date = fields.Date(readonly=True)
depreciation_date = fields.Date(string='Depreciation Date', readonly=True)
asset_id = fields.Many2one('account.asset.asset', string='Asset', readonly=True)
asset_category_id = fields.Many2one('account.asset.category', string='Asset category', readonly=True)
partner_id = fields.Many2one('res.partner', string='Partner', 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)
installment_nbr = fields.Integer(string='Installment Count', readonly=True)
depreciation_nbr = fields.Integer(string='Depreciation Count', readonly=True)
gross_value = fields.Float(string='Gross Amount', readonly=True)
posted_value = fields.Float(string='Posted Amount', readonly=True)
unposted_value = fields.Float(string='Unposted Amount', readonly=True)
company_id = fields.Many2one('res.company', string='Company', readonly=True)
def init(self):
tools.drop_view_if_exists(self.env.cr, 'asset_asset_report')
self.env.cr.execute("""
create or replace view asset_asset_report as (
select
min(dl.id) as id,
dl.name as name,
dl.depreciation_date as depreciation_date,
a.date as date,
(CASE WHEN dlmin.id = min(dl.id)
THEN a.value
ELSE 0
END) as gross_value,
dl.amount as depreciation_value,
dl.amount as installment_value,
(CASE WHEN dl.move_check
THEN dl.amount
ELSE 0
END) as posted_value,
(CASE WHEN NOT dl.move_check
THEN dl.amount
ELSE 0
END) as unposted_value,
dl.asset_id as asset_id,
dl.move_check as move_check,
a.category_id as asset_category_id,
a.partner_id as partner_id,
a.state as state,
count(dl.*) as installment_nbr,
count(dl.*) as depreciation_nbr,
a.company_id as company_id
from account_asset_depreciation_line dl
left join account_asset_asset a on (dl.asset_id=a.id)
left join (select min(d.id) as id,ac.id as ac_id from account_asset_depreciation_line as d inner join account_asset_asset as ac ON (ac.id=d.asset_id) group by ac_id) as dlmin on dlmin.ac_id=a.id
where a.active is true
group by
dl.amount,dl.asset_id,dl.depreciation_date,dl.name,
a.date, dl.move_check, a.state, a.category_id, a.partner_id, a.company_id,
a.value, a.id, a.salvage_value, dlmin.id
)""")

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="action_account_asset_report_pivot" model="ir.ui.view">
<field name="name">asset.asset.report.pivot</field>
<field name="model">asset.asset.report</field>
<field name="arch" type="xml">
<pivot string="Assets Analysis" disable_linking="True">
<field name="asset_category_id" type="row"/>
<field name="gross_value" type="measure"/>
<field name="unposted_value" type="measure"/>
</pivot>
</field>
</record>
<record id="action_account_asset_report_graph" model="ir.ui.view">
<field name="name">asset.asset.report.graph</field>
<field name="model">asset.asset.report</field>
<field name="arch" type="xml">
<graph string="Assets Analysis">
<field name="asset_category_id" type="row"/>
<field name="gross_value" type="measure"/>
<field name="unposted_value" type="measure"/>
</graph>
</field>
</record>
<record id="view_asset_asset_report_search" model="ir.ui.view">
<field name="name">asset.asset.report.search</field>
<field name="model">asset.asset.report</field>
<field name="arch" type="xml">
<search string="Assets Analysis">
<field name="date"/>
<field name="depreciation_date"/>
<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"/>
<separator/>
<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_category_id"/>
<group>
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group>
<filter string="Asset" name="asset" context="{'group_by':'asset_id'}"/>
<filter string="Asset Category" name="asset_category"
context="{'group_by':'asset_category_id'}"/>
<filter string="Company" name="company" context="{'group_by':'company_id'}"
groups="base.group_multi_company"/>
<separator/>
<filter string="Purchase Month" name="purchase_month" help="Date of asset purchase"
context="{'group_by':'date:month'}"/>
<filter string="Depreciation Month" name="deprecation_month" help="Date of depreciation"
context="{'group_by':'depreciation_date:month'}"/>
</group>
</search>
</field>
</record>
<record id="action_asset_asset_report" model="ir.actions.act_window">
<field name="name">Assets Analysis</field>
<field name="res_model">asset.asset.report</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="context">{}</field>
<field name="help" type="html">
<p class="o_view_nocontent_empty_folder">
No content
</p><p>
From this report, you can have an overview on all depreciations. The
search bar can also be used to personalize your assets depreciation reporting.
</p>
</field>
</record>
<menuitem id="menu_action_asset_asset_report"
name="Assets"
action="action_asset_asset_report"
parent="account.account_reports_management_menu"
sequence="21"/>
</odoo>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="account_asset_category_multi_company_rule" model="ir.rule">
<field name="name">Account Asset Category multi-company</field>
<field ref="model_account_asset_category" name="model_id"/>
<field eval="True" name="global"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="account_asset_asset_multi_company_rule" model="ir.rule">
<field name="name">Account Asset multi-company</field>
<field ref="model_account_asset_asset" name="model_id"/>
<field eval="True" name="global"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,14 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_asset_category,account.asset.category,model_account_asset_category,account.group_account_user,1,0,0,0
access_asset_depreciation_confirmation_wizard,access_asset_depreciation_confirmation_wizard,model_asset_depreciation_confirmation_wizard,account.group_account_user,1,1,1,0
access_asset_modify,access_asset_modify,model_asset_modify,account.group_account_user,1,1,1,0
access_account_asset_asset,account.asset.asset,model_account_asset_asset,account.group_account_user,1,0,0,0
access_account_asset_category_manager,account.asset.category,model_account_asset_category,account.group_account_manager,1,1,1,1
access_account_asset_asset_manager,account.asset.asset,model_account_asset_asset,account.group_account_manager,1,1,1,1
access_account_asset_depreciation_line,account.asset.depreciation.line,model_account_asset_depreciation_line,account.group_account_user,1,0,0,0
access_account_asset_depreciation_line_manager,account.asset.depreciation.line,model_account_asset_depreciation_line,account.group_account_manager,1,1,1,1
access_asset_asset_report,asset.asset.report,model_asset_asset_report,account.group_account_user,1,0,0,0
access_asset_asset_report_manager,asset.asset.report,model_asset_asset_report,account.group_account_manager,1,1,1,1
access_account_asset_category_invoicing_payment,account.asset.category,model_account_asset_category,account.group_account_invoice,1,0,0,0
access_account_asset_asset_invoicing_payment,account.asset.asset,model_account_asset_asset,account.group_account_invoice,1,0,1,0
access_account_asset_depreciation_line_invoicing_payment,account.asset.depreciation.line,model_account_asset_depreciation_line,account.group_account_invoice,1,0,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_asset_category account.asset.category model_account_asset_category account.group_account_user 1 0 0 0
3 access_asset_depreciation_confirmation_wizard access_asset_depreciation_confirmation_wizard model_asset_depreciation_confirmation_wizard account.group_account_user 1 1 1 0
4 access_asset_modify access_asset_modify model_asset_modify account.group_account_user 1 1 1 0
5 access_account_asset_asset account.asset.asset model_account_asset_asset account.group_account_user 1 0 0 0
6 access_account_asset_category_manager account.asset.category model_account_asset_category account.group_account_manager 1 1 1 1
7 access_account_asset_asset_manager account.asset.asset model_account_asset_asset account.group_account_manager 1 1 1 1
8 access_account_asset_depreciation_line account.asset.depreciation.line model_account_asset_depreciation_line account.group_account_user 1 0 0 0
9 access_account_asset_depreciation_line_manager account.asset.depreciation.line model_account_asset_depreciation_line account.group_account_manager 1 1 1 1
10 access_asset_asset_report asset.asset.report model_asset_asset_report account.group_account_user 1 0 0 0
11 access_asset_asset_report_manager asset.asset.report model_asset_asset_report account.group_account_manager 1 1 1 1
12 access_account_asset_category_invoicing_payment account.asset.category model_account_asset_category account.group_account_invoice 1 0 0 0
13 access_account_asset_asset_invoicing_payment account.asset.asset model_account_asset_asset account.group_account_invoice 1 0 1 0
14 access_account_asset_depreciation_line_invoicing_payment account.asset.depreciation.line model_account_asset_depreciation_line account.group_account_invoice 1 0 1 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="70" height="70" viewBox="0 0 70 70"><defs><path id="a" d="M4 0h61c4 0 5 1 5 5v60c0 4-1 5-5 5H4c-3 0-4-1-4-5V5c0-4 1-5 4-5z"/><linearGradient id="c" x1="100%" x2="0%" y1="0%" y2="100%"><stop offset="0%" stop-color="#DA956B"/><stop offset="100%" stop-color="#CC7039"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M0 0H70V70H0z"/><path fill="#FFF" fill-opacity=".383" d="M4 1h61c2.667 0 4.333.667 5 2V0H0v3c.667-1.333 2-2 4-2z"/><path fill="#393939" d="M4 69c-2 0-4-.146-4-4.09V40.738L18.16 24H52l1 2.045v6.137l-10.585 11.3 10.05 4.09L37.071 69H4z" opacity=".324"/><path fill="#000" fill-opacity=".383" d="M4 69h61c2.667 0 4.333-1 5-3v4H0v-4c.667 2 2 3 4 3z"/><path fill="#000" d="M53 42.084v5.66c0 1.837-1.111 3.34-3.556 3.34h-28c-2.466 0-4.444-1.503-4.444-3.34V28.34c0-1.837 1.978-3.34 4.444-3.34H49c2.444 0 4 1.368 4 3.205v5.88H37c-2.667 0-4 1.857-4 3.957 0 2.1 1.333 4.042 4 4.042h16zm-15-1.39a2.656 2.656 0 0 1-2.667-2.652A2.656 2.656 0 0 1 38 35.39a2.656 2.656 0 0 1 2.667 2.653A2.656 2.656 0 0 1 38 40.695z" opacity=".3"/><path fill="#FFF" d="M53 40.084v5.66c0 1.837-1.111 3.34-3.556 3.34h-28c-2.466 0-4.444-1.503-4.444-3.34V26.34c0-1.837 1.978-3.34 4.444-3.34H49c2.444 0 4 1.368 4 3.205v5.88H37c-2.667 0-4 1.857-4 3.957 0 2.1 1.333 4.042 4 4.042h16zm-15-1.39a2.656 2.656 0 0 1-2.667-2.652A2.656 2.656 0 0 1 38 33.39a2.656 2.656 0 0 1 2.667 2.653A2.656 2.656 0 0 1 38 38.695z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,84 @@
<section class="oe_container oe_dark">
<div class="col-md-12">
<h2 class="oe_slogan" style="font-size: 35px;color:#2C0091"><b>Odoo 19 Asset Management</b></h2>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div style="text-align:center;">
<p class="fa fa-hand-o-right" style="color:CRIMSON;font-size: 25px;">
<span style="color:#2dd280;font-size: 15px;">Manage assets owned by a company or a person.</span>
</p><br/>
<p class="fa fa-hand-o-right" style="color:CRIMSON;font-size: 25px;">
<span style="color:#2dd280;font-size: 15px;">Keeps track of depreciation's, and creates corresponding journal entries</span>
</p><br/>
</div>
<br/>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_centeralign oe_websiteonly">
<h4 class="oe_slogan"><a href="https://www.youtube.com/watch?v=KudvDOTvx2I" target="_blank" style="color: #FFFFFF !important; border-radius: 0; background-color: #9c676e; border-color: #005ca7; padding: 15px; font-weight: bold;">
<i class="fa fa-youtube"></i>
Watch on YouTube
</a></h4>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Asset Category</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="asset_types.png">
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Assets</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="assets.png">
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<section class="oe_container oe_dark">
<div class="oe_row ">
<div class="oe_slogan text-center">
<img src="odoo_mates.png"/>
<div style="color:#269900;">
<h3 style="color:#2C0091;font-size: 25px;">If you need any help or want more features, just contact us:</h3><br>
<h3 style="color:#2C0091;font-size: 20px;">Email: <a href="odoomates@gmail.com">odoomates@gmail.com</a> <br></h3>
</div>
<div class="oe_slogan">
<h2>
<a target="_blank" href="https://www.facebook.com/odoomate/" target="new">
<i class="fa fa-facebook-square" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://twitter.com/odoomates/" target="new">
<i class="fa fa-twitter" style="font-size:38px;"></i>
</a>
<a href="#" target="_blank">
<i class="fa fa-linkedin" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://www.youtube.com/channel/UCVKlUZP7HAhdQgs-9iTJklQ">
<i class="fa fa-youtube-play" style="font-size:38px;"></i>
</a>
</h2>
</div>
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

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

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_assets_scss_backend" model="ir.asset">
<field name="name">aAccount Assets SCSS</field>
<field name="bundle">web.assets_backend</field>
<field name="path">/om_account_asset/static/src/scss/account_asset.scss</field>
<field name="sequence" eval="18"/>
</record>
</odoo>

View File

@@ -0,0 +1,238 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_asset_asset_form" model="ir.ui.view">
<field name="name">account.asset.asset.form</field>
<field name="model">account.asset.asset</field>
<field name="arch" type="xml">
<form string="Asset">
<header>
<button name="validate" string="Confirm" type="object" class="oe_highlight" invisible="state != 'draft'"/>
<button type="object" name="compute_depreciation_board" string="Compute Depreciation"
invisible="state != 'draft'"/>
<button name="set_to_close" invisible="state != 'open'" string="Sell or Dispose" type="object"
class="oe_highlight"/>
<button name="set_to_draft" string="Set to Draft" type="object"
invisible="entry_count != 0 or state != 'open'"/>
<button name="%(action_asset_modify)d" invisible="state != 'open'" string="Modify Depreciation" type="action"/>
<field name="state" widget="statusbar" statusbar_visible="draft,open"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" name="open_entries" type="object" icon="fa-pencil">
<field string="Items" name="entry_count" widget="statinfo"/>
</button>
</div>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name" placeholder="e.g. Laptop iBook" readonly="state != 'draft'"/>
</h1>
</div>
<group>
<group>
<field name="category_id" string="Asset Category"
domain="[('type', '=', 'purchase')]"
readonly="state != 'draft'"
context="{'default_type': 'purchase'}" help="Category of asset"/>
<field name="code" readonly="state != 'draft'"/>
<field name="date" help="Date of asset" readonly="state != 'draft'"/>
<field name="date_first_depreciation" readonly="state != 'draft'"/>
<field name="first_depreciation_manual_date"
readonly="state != 'draft'"
invisible="date_first_depreciation != 'manual'"
required="date_first_depreciation == 'manual'"/>
<field name="type" invisible="1"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
</group>
<group>
<field name="currency_id" groups="base.group_multi_currency"
readonly="state != 'draft'"/>
<field name="company_id" options="{'no_create': True}"
readonly="state != 'draft'"
groups="base.group_multi_company"/>
<field name="value" widget="monetary"
readonly="state != 'draft'" help="Gross value of asset"/>
<field name="salvage_value" widget="monetary"
readonly="state != 'draft'"
invisible="type == 'sale'"/>
<field name="value_residual" widget="monetary"/>
<field name="partner_id" string="Vendor" widget="res_partner_many2one"
readonly="state != 'draft'"
context="{'res_partner_search_mode': 'supplier'}"/>
<field name="invoice_id" string="Invoice" options="{'no_create': True}"/>
<field name="analytic_distribution" widget="analytic_distribution"/>
</group>
</group>
<notebook>
<page string="Depreciation Board">
<field name="depreciation_line_ids" mode="list"
readonly="state not in ('draft', 'open')"
options="{'reload_whole_on_button': true}">
<list string="Depreciation Lines" decoration-info="(move_check == False)"
create="false">
<field name="depreciation_date"/>
<field name="amount" widget="monetary" string="Depreciation"/>
<field name="depreciated_value" readonly="1"/>
<field name="remaining_value" readonly="1" widget="monetary" string="Residual"/>
<field name="move_check" widget="deprec_lines_toggler"
invisible="parent_state != 'open'"/>
<field name="move_posted_check" invisible="1"/>
<field name="parent_state" invisible="1"/>
</list>
<form string="Depreciation Lines" create="false">
<group>
<group>
<field name="parent_state" invisible="1"/>
<field name="name"/>
<field name="sequence"/>
<field name="move_id"/>
<field name="move_check"/>
<field name="parent_state" invisible="1"/>
</group>
<group>
<field name="amount" widget="monetary"/>
<field name="depreciation_date"/>
<field name="depreciated_value"/>
<field name="remaining_value"/>
</group>
</group>
</form>
</field>
</page>
<page string="Depreciation Information">
<group>
<field name="method" widget="radio"
invisible="type == 'sale'" readonly="state != 'draft'"/>
<field name="method_progress_factor"
readonly="state != 'draft'"
invisible="method == 'linear'"
required="method == 'degressive'"/>
<field name="method_time" string="Time Method Based On"
widget="radio"
readonly="state != 'draft'"
invisible="type != 'purchase'"/>
<field name="prorata"
invisible="method_time == 'end'"
readonly="state != 'draft'"/>
</group>
<group>
<field name="method_number"
readonly="state != 'draft'"
invisible="method_time == 'end'"
required="method_time == 'number'"/>
<field name="method_period" readonly="state != 'draft'"/>
<field name="method_end"
readonly="state != 'draft'"
invisible="method_time == 'end'"
required="method_time == 'number'"/>
</group>
</page>
</notebook>
</sheet>
<chatter/>
</form>
</field>
</record>
<record id="view_account_asset_asset_kanban" model="ir.ui.view">
<field name="name">account.asset.asset.kanban</field>
<field name="model">account.asset.asset</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile">
<field name="name"/>
<field name="category_id"/>
<field name="date"/>
<field name="state"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_global_click">
<div class="row mb4">
<div class="col-6">
<strong>
<span>
<t t-esc="record.name.value"/>
</span>
</strong>
</div>
<div class="col-6 text-end">
<strong>
<t t-esc="record.date.value"/>
</strong>
</div>
</div>
<div class="row">
<div class="col-6 text-muted">
<span>
<t t-esc="record.category_id.value"/>
</span>
</div>
<div class="col-6">
<span class="float-right text-end">
<field name="state" widget="kanban_label_selection"
options="{'classes': {'draft': 'primary', 'open': 'success', 'close': 'default'}}"/>
</span>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="view_account_asset_asset_purchase_tree" model="ir.ui.view">
<field name="name">account.asset.asset.purchase.list</field>
<field name="model">account.asset.asset</field>
<field name="arch" type="xml">
<list string="Assets" decoration-info="(state == 'draft')" decoration-muted="(state == 'close')">
<field name="name"/>
<field name="category_id" string="Asset Category"/>
<field name="date"/>
<field name="partner_id" string="Vendor"/>
<field name="value"/>
<field name="value_residual" widget="monetary"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="state"/>
</list>
</field>
</record>
<record id="view_account_asset_search" model="ir.ui.view">
<field name="name">account.asset.asset.search</field>
<field name="model">account.asset.asset</field>
<field name="arch" type="xml">
<search string="Asset Account">
<field name="name" string="Asset"/>
<field name="date"/>
<filter string="Current" name="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"/>
<field name="category_id" string="Asset Category"/>
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<group>
<filter string="Date" name="month" domain="[]" context="{'group_by':'date'}"/>
<filter string="Asset Category" name="category" domain="[]" context="{'group_by':'category_id'}"/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_account_asset_asset_form">
<field name="name">Assets</field>
<field name="res_model">account.asset.asset</field>
<field name="view_mode">list,kanban,form</field>
<field name="view_id" ref="view_account_asset_asset_purchase_tree"/>
<field name="domain">[('category_id.type', '=', 'purchase')]</field>
</record>
<menuitem id="menu_action_account_asset_asset_form"
parent="account.account_account_menu"
action="action_account_asset_asset_form"
sequence="101"
groups="account.group_account_manager"/>
</odoo>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_invoice_asset_category" model="ir.ui.view">
<field name="name">account.move.supplier.form</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_line_ids']/list/field[@name='account_id']" position="before">
<field string="Asset Category" name="asset_category_id"
force_save="1" column_invisible="parent.move_type != 'in_invoice'"
domain="[('type','=','purchase')]" context="{'default_type':'purchase'}"/>
</xpath>
<xpath expr="//field[@name='line_ids']/list/field[@name='account_id']" position="before">
<field string="Asset Category" name="asset_category_id"
column_invisible="1"/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_asset_category_form" model="ir.ui.view">
<field name="name">account.asset.category.form</field>
<field name="model">account.asset.category</field>
<field name="arch" type="xml">
<form string="Asset category">
<sheet>
<div class="oe_title">
<label for="name" string="Asset Type" class="oe_edit_only"
invisible="type != 'purchase'"/>
<label for="name" string="Deferred Revenue Type" class="oe_edit_only"
invisible="type == 'purchase'"/>
<h1>
<field name="name" placeholder="e.g. Computers"/>
</h1>
</div>
<group string="Journal Entries">
<group>
<field name="journal_id"/>
<div>
<label for="account_asset_id" invisible="type != 'purchase'"
style="font-weight: bold" class="o_light_label"/>
<label for="account_asset_id" string="Deferred Revenue Account"
invisible="type != 'sale'" style="font-weight: bold"
class="o_light_label"/>
</div>
<field name="account_asset_id" nolabel="1"
domain="[('company_ids', 'in', company_id)]"/>
<div>
<label for="account_depreciation_id" invisible="type != 'purchase'"
style="font-weight: bold" class="o_light_label"/>
<label for="account_depreciation_id" string="Recognition Income Account"
invisible="type != 'sale'"
style="font-weight: bold" class="o_light_label"/>
</div>
<field name="account_depreciation_id" nolabel="1"
domain="[('company_ids', 'in', company_id)]"/>
</group>
<group>
<div>
<label for="account_depreciation_expense_id"
invisible="type != 'purchase'"
style="font-weight: bold" class="o_light_label"/>
<label for="account_depreciation_expense_id" string="Recognition Account"
invisible="type != 'sale'"
style="font-weight: bold" class="o_light_label"/>
</div>
<field name="account_depreciation_expense_id" nolabel="1"
domain="[('company_ids', 'in', company_id)]"/>
<field name="account_analytic_id" domain="[('company_id', 'in', company_id)]"
groups="analytic.group_analytic_accounting"/>
<field name="analytic_distribution" widget="analytic_distribution"/>
</group>
</group>
<group>
<group string="Periodicity">
<field name="method_time" string="Time Method Based On" widget="radio"
invisible="type != 'purchase'"/>
<field name="method_number" string="Number of Entries"
required="method_time == 'number'"
invisible="method_time != 'number' or type == False"/>
<label for="method_period" string="One Entry Every"/>
<div>
<field name="method_period" nolabel="1"
invisible="type == False" class="oe_inline"/>
months
</div>
<field name="method_end"
required="method_time == 'end'"
invisible="method_time != 'end'"/>
</group>
<group>
<field name="type" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="company_id" options="{'no_create': True}"
groups="base.group_multi_company"/>
</group>
<group string="Additional Options">
<field name="open_asset"/>
<field name="group_entries"/>
<field name="date_first_depreciation"/>
</group>
<group invisible="type == 'sale'" string="Depreciation Method">
<field name="method" widget="radio"/>
<field name="method_progress_factor"
invisible="method_time == 'linear'" required="method == 'degressive'"/>
<field name="prorata" invisible="method_time == 'end'"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_account_asset_asset_category_kanban" model="ir.ui.view">
<field name="name">account.asset.category.kanban</field>
<field name="model">account.asset.category</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile">
<field name="name"/>
<field name="journal_id"/>
<field name="method"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
<div class="row mb4">
<div class="col-6">
<strong>
<span>
<t t-esc="record.name.value"/>
</span>
</strong>
</div>
<div class="col-6 text-end">
<span class="badge badge-pill">
<strong>
<t t-esc="record.method.value"/>
</strong>
</span>
</div>
</div>
<div>
<t t-esc="record.journal_id.value"/>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="view_account_asset_category_tree" model="ir.ui.view">
<field name="name">account.asset.category.list</field>
<field name="model">account.asset.category</field>
<field name="arch" type="xml">
<list string="Asset category">
<field name="name"/>
<field name="journal_id"/>
<field name="method"/>
<field name="company_id" groups="base.group_multi_company"/>
</list>
</field>
</record>
<record id="view_account_asset_category_search" model="ir.ui.view">
<field name="name">account.asset.category.search</field>
<field name="model">account.asset.category</field>
<field name="arch" type="xml">
<search string="Search Asset Category">
<filter string="Sales" name="sales" domain="[('type','=', 'sale')]" help="Deferred Revenues"/>
<filter string="Purchase" name="purchase" domain="[('type','=', 'purchase')]" help="Assets"/>
<field name="name" string="Category"/>
<field name="journal_id"/>
<group>
<filter string="Type" name="type" domain="[]" context="{'group_by':'type'}"/>
</group>
</search>
</field>
</record>
<record id="action_account_asset_asset_list_normal_purchase" model="ir.actions.act_window">
<field name="name">Asset Category</field>
<field name="res_model">account.asset.category</field>
<field name="domain">[('type', '=', 'purchase')]</field>
<field name="view_mode">list,kanban,form</field>
<field name="context">{'default_type': 'purchase'}</field>
</record>
<menuitem id="menu_action_account_asset_asset_list_normal_purchase"
parent="account.account_account_menu"
action="action_account_asset_asset_list_normal_purchase"
sequence="6"/>
</odoo>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<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>

View File

@@ -0,0 +1,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import asset_depreciation_confirmation_wizard
from . import asset_modify

View File

@@ -0,0 +1,29 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
class AssetDepreciationConfirmationWizard(models.TransientModel):
_name = "asset.depreciation.confirmation.wizard"
_description = "asset.depreciation.confirmation.wizard"
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
)
def asset_compute(self):
self.ensure_one()
context = self.env.context
created_move_ids = self.env['account.asset.asset'].compute_generated_entries(self.date, asset_type=context.get('asset_type'))
return {
'name': _('Created Asset Moves') if context.get('asset_type') == 'purchase' else _('Created Revenue Moves'),
'view_type': 'form',
'view_mode': 'list,form',
'res_model': 'account.move',
'view_id': False,
'domain': "[('id','in',[" + ','.join(str(id) for id in created_move_ids) + "])]",
'type': 'ir.actions.act_window',
}

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_asset_depreciation_confirmation_wizard" model="ir.ui.view">
<field name="name">asset.depreciation.confirmation.wizard</field>
<field name="model">asset.depreciation.confirmation.wizard</field>
<field name="arch" type="xml">
<form string="Compute Asset">
<div>
<p>
This wizard will post installment/depreciation lines for the selected month.<br/>
This will generate journal entries for all related installment lines on this period
of asset/revenue recognition as well.
</p>
</div>
<group>
<field name="date"/>
</group>
<footer>
<button string="Generate Entries" name="asset_compute" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_asset_depreciation_confirmation_wizard" model="ir.actions.act_window">
<field name="name">Post Depreciation Lines</field>
<field name="res_model">asset.depreciation.confirmation.wizard</field>
<field name="view_mode">list,form</field>
<field name="view_id" ref="view_asset_depreciation_confirmation_wizard"/>
<field name="target">new</field>
<field name="context">{'asset_type': 'purchase'}</field>
</record>
<menuitem id="menu_finance_entries_generate_entries"
parent="account.menu_finance_entries"
name="Generate Entries"/>
<menuitem id="menu_asset_depreciation_confirmation_wizard"
name="Generate Assets Entries"
action="action_asset_depreciation_confirmation_wizard"
parent="om_account_asset.menu_finance_entries_generate_entries"
sequence="111"
groups="account.group_account_manager"/>
</odoo>

View File

@@ -0,0 +1,67 @@
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class AssetModify(models.TransientModel):
_name = 'asset.modify'
_description = 'Modify Asset'
name = fields.Text(string='Reason', required=True)
method_number = fields.Integer(
string='Number of Depreciation', required=True
)
method_period = fields.Integer(string='Period Length')
method_end = fields.Date(string='Ending date')
asset_method_time = fields.Char(
compute='_get_asset_method_time', 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
@api.model
def default_get(self, fields):
res = super(AssetModify, self).default_get(fields)
asset_id = self.env.context.get('active_id')
asset = self.env['account.asset.asset'].browse(asset_id)
if 'name' in fields:
res.update({'name': asset.name})
if 'method_number' in fields and asset.method_time == 'number':
res.update({'method_number': asset.method_number})
if 'method_period' in fields:
res.update({'method_period': asset.method_period})
if 'method_end' in fields and asset.method_time == 'end':
res.update({'method_end': asset.method_end})
if self.env.context.get('active_id'):
active_asset = self.env['account.asset.asset'].browse(self.env.context.get('active_id'))
res['asset_method_time'] = active_asset.method_time
return res
def modify(self):
""" Modifies the duration of asset for calculating depreciation
and maintains the history of old values, in the chatter.
"""
asset_id = self.env.context.get('active_id', False)
asset = self.env['account.asset.asset'].browse(asset_id)
old_values = {
'method_number': asset.method_number,
'method_period': asset.method_period,
'method_end': asset.method_end,
}
asset_vals = {
'method_number': self.method_number,
'method_period': self.method_period,
'method_end': self.method_end,
}
if asset_vals['method_number'] <= asset.entry_count:
raise UserError(_('The number of depreciations must be greater than the number of posted or draft entries '
'to allow for complete depreciation of the asset.'))
asset.write(asset_vals)
asset.compute_depreciation_board()
tracked_fields = self.env['account.asset.asset'].fields_get(['method_number', 'method_period', 'method_end'])
changes, tracking_value_ids = asset._mail_track(tracked_fields, old_values)
if changes:
asset.message_post(subject=_('Depreciation board modified'), body=self.name, tracking_value_ids=tracking_value_ids)
return {'type': 'ir.actions.act_window_close'}

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="asset_modify_form" model="ir.ui.view">
<field name="name">wizard.asset.modify.form</field>
<field name="model">asset.modify</field>
<field name="arch" type="xml">
<form string="Modify Asset">
<field name="asset_method_time" invisible="1"/>
<group string="Asset Durations to Modify" col="4">
<group colspan="2" col="2">
<field name="name"/>
<field name="method_number" invisible="asset_method_time == 'end'"/>
</group>
<group colspan="2" col="2">
<field name="method_end" invisible="asset_method_time == 'number'"/>
<label for="method_period"/>
<div>
<field name="method_period" class="oe_inline"/> months
</div>
</group>
</group>
<footer>
<button name="modify" string="Modify" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_asset_modify" model="ir.actions.act_window">
<field name="name">Modify Asset</field>
<field name="res_model">asset.modify</field>
<field name="type">ir.actions.act_window</field>
<field name="view_mode">list,form</field>
<field name="view_id" ref="asset_modify_form"/>
<field name="target">new</field>
</record>
</odoo>

View File

@@ -0,0 +1,2 @@
from . import wizard
from . import models

View File

@@ -0,0 +1,23 @@
{
'name': 'Odoo 19 Fiscal Year & Lock Date',
'version': '19.0.1.0.1', # __odoosky_original_version__: '1.0.1'
'category': 'Accounting',
'summary': 'Odoo 19 Fiscal Year, Fiscal Year in Odoo 19, Lock Date in Odoo 19',
'description': 'Odoo 19 Fiscal Year, Fiscal Year in Odoo 19',
'live_test_url': 'https://www.youtube.com/watch?v=Kj4hR7_uNs4',
'sequence': '1',
'website': 'https://www.odoomates.tech',
'author': 'Odoo Mates, Odoo SA',
'maintainer': 'Odoo Mates',
'license': 'LGPL-3',
'support': 'odoomates@gmail.com',
'depends': ['account'],
'data': [
'security/security.xml',
'security/ir.model.access.csv',
'wizard/change_lock_date.xml',
'views/fiscal_year.xml',
'views/settings.xml',
],
'images': ['static/description/banner.png'],
}

View File

@@ -0,0 +1,291 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_fiscal_year
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-15 18:18+0000\n"
"PO-Revision-Date: 2022-04-15 18:18+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Account Period Closing"
msgstr ""
#. module: om_fiscal_year
#: model:res.groups,name:om_fiscal_year.group_fiscal_year
msgid "Allow to define fiscal years of more or less than a year"
msgstr "تسمح بتحديد السنوات المالية التي تزيد أو تقل عن عام\n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Cancel"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_change_lock_date
msgid "Change Lock Date"
msgstr "تغيير تاريخ القفل\n"
#. module: om_fiscal_year
#: model_terms:ir.actions.act_window,help:om_fiscal_year.actions_account_fiscal_year
msgid "Click here to create a new fiscal year."
msgstr "انقر هنا لإنشاء سنة مالية جديدة.\n"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_company
msgid "Companies"
msgstr "شركات"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__company_id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__company_id
msgid "Company"
msgstr "الشركة"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_config_settings
msgid "Config Settings"
msgstr "ضبط الاعدادات"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_uid
msgid "Created by"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_date
msgid "Created on"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Define fiscal years of more or less than one year"
msgstr "تحديد السنوات المالية التي تزيد أو تقل عن سنة واحدة\n"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__display_name
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__display_name
msgid "Display Name"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_to
msgid "End Date"
msgstr "تاريخ الانتهاء"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_to
msgid "Ending Date, included in the fiscal year."
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Period Closing"
msgstr "إغلاق الفترة المالية\n"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_account_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Year"
msgstr "السنة المالية\n"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.actions_account_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__group_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Years"
msgstr "السنوات المالية"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_day
msgid "Fiscalyear Last Day"
msgstr "آخر أيام السنة المالية"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_month
msgid "Fiscalyear Last Month"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__id
msgid "ID"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Journal Entries Lock Date"
msgstr "تاريخ قفل إدخالات دفتر اليومية\n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Last Day"
msgstr "بالأمس"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year____last_update
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date____last_update
msgid "Last Modified on"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_uid
msgid "Last Updated by"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_date
msgid "Last Updated on"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid "Lock Date"
msgstr "تاريخ القفل\n"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid "Lock Date for All Users"
msgstr "تاريخ القفل لجميع المستخدمين\n"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__period_lock_date
msgid "Lock Date for Non-Advisers"
msgstr "تاريخ القفل لغير المستشارين\n"
#. module: om_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_action_change_lock_date
msgid "Lock Dates"
msgstr "تواريخ القفل\n"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.action_view_change_lock_date
msgid "Lock your Fiscal Period"
msgstr "قفل الفترة المالية الخاصة بك\n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Lock your fiscal period"
msgstr "قفل الفترة المالية الخاصة بك\n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Management Closing"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__name
msgid "Name"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid ""
"No users can edit journal entries related to a tax prior and inclusive of "
"this date."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking for example."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__period_lock_date
msgid ""
"Only users with the 'Adviser' role can edit accounts prior to and inclusive "
"of this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Prevent posting of journal entries in this period."
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Save"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid "Show unposted entries"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date"
msgstr "تاريخ البداية"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date, included in the fiscal year."
msgstr "تاريخ البدء مضمن في السنة المالية.\n"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid "Tax Lock Date"
msgstr "تاريخ القفل الضريبي\n"
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid "The ending date must not be prior to the starting date."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period you want to lock. You should "
"either post or delete them."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unreconciled bank statement lines in the period you want to "
"lock.You should either reconcile or delete them."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/wizard/change_lock_date.py:0
#, python-format
msgid "You Are Not Allowed To Perform This Operation"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid ""
"You can not have an overlap between two fiscal years, please correct the "
"start and/or end dates of your fiscal years."
msgstr ""
"لا يمكن أن يكون هناك تداخل بين سنتين ماليتين ، يرجى تصحيح تواريخ البدء و / "
"أو الانتهاء للسنتين الماليتين.\n"

View File

@@ -0,0 +1,289 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_fiscal_year
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-06 02:59+0000\n"
"PO-Revision-Date: 2022-07-06 02:59+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Account Period Closing"
msgstr ""
#. module: om_fiscal_year
#: model:res.groups,name:om_fiscal_year.group_fiscal_year
msgid "Allow to define fiscal years of more or less than a year"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Cancel"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_change_lock_date
msgid "Change Lock Date"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.actions.act_window,help:om_fiscal_year.actions_account_fiscal_year
msgid "Click here to create a new fiscal year."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_company
msgid "Companies"
msgstr "الشركات "
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__company_id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__company_id
msgid "Company"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_config_settings
msgid "Config Settings"
msgstr "ضبط الاعدادات"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_uid
msgid "Created by"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_date
msgid "Created on"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Define fiscal years of more or less than one year"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__display_name
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__display_name
msgid "Display Name"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_to
msgid "End Date"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_to
msgid "Ending Date, included in the fiscal year."
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Period Closing"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_account_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Year"
msgstr "السنة المالية\n"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.actions_account_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__group_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Years"
msgstr "السنوات المالية\n"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_day
msgid "Fiscalyear Last Day"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_month
msgid "Fiscalyear Last Month"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__id
msgid "ID"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Journal Entries Lock Date"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Last Day"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year____last_update
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date____last_update
msgid "Last Modified on"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_uid
msgid "Last Updated by"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_date
msgid "Last Updated on"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid "Lock Date"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid "Lock Date for All Users"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__period_lock_date
msgid "Lock Date for Non-Advisers"
msgstr ""
#. module: om_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_action_change_lock_date
msgid "Lock Dates"
msgstr "تواريخ القفل\n"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.action_view_change_lock_date
msgid "Lock your Fiscal Period"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Lock your fiscal period"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Management Closing"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__name
msgid "Name"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid ""
"No users can edit journal entries related to a tax prior and inclusive of "
"this date."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking for example."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__period_lock_date
msgid ""
"Only users with the 'Adviser' role can edit accounts prior to and inclusive "
"of this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Prevent posting of journal entries in this period."
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Save"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid "Show unposted entries"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date, included in the fiscal year."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid "Tax Lock Date"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid "The ending date must not be prior to the starting date."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period you want to lock. You should "
"either post or delete them."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unreconciled bank statement lines in the period you want to "
"lock.You should either reconcile or delete them."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/wizard/change_lock_date.py:0
#, python-format
msgid "You Are Not Allowed To Perform This Operation"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid ""
"You can not have an overlap between two fiscal years, please correct the "
"start and/or end dates of your fiscal years."
msgstr ""

View File

@@ -0,0 +1,250 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_fiscal_year
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-22 12:36+0000\n"
"PO-Revision-Date: 2024-03-22 12:36+0000\n"
"Last-Translator: Sergio Ariel Ameghino <ariel.ameghino@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Account Period Closing"
msgstr "Cierre del período de la cuenta"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid "All Users Lock Date"
msgstr "Fecha de cierre"
#. module: om_fiscal_year
#: model:res.groups,name:om_fiscal_year.group_fiscal_year
msgid "Allow to define fiscal years of more or less than a year"
msgstr "Permitir definir años fiscales de más de 1 año o menos de 1 año"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Cancel"
msgstr "Cancelar"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_change_lock_date
msgid "Change Lock Date"
msgstr "Cambiar fecha de bloqueo"
#. module: om_fiscal_year
#: model_terms:ir.actions.act_window,help:om_fiscal_year.actions_account_fiscal_year
msgid "Click here to create a new fiscal year."
msgstr "Haga clic aquí para crear un nuevo año fiscal."
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_company
msgid "Companies"
msgstr "Compañías"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__company_id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__company_id
msgid "Company"
msgstr "Compañía"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_config_settings
msgid "Config Settings"
msgstr "Ajustes de configuración"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_date
msgid "Created on"
msgstr "Creado en"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Define fiscal years of more or less than one year"
msgstr "Definir años fiscales de más de 1 año o menos de 1 año"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__display_name
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__display_name
msgid "Display Name"
msgstr "Nombre mostrado"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_to
msgid "End Date"
msgstr "Fecha final"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_to
msgid "Ending Date, included in the fiscal year."
msgstr "Fecha de finalización, incluida en el ejercicio fiscal."
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Period Closing"
msgstr "Cierre del período fiscal"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_account_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Year"
msgstr "Año fiscal"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.actions_account_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__group_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Years"
msgstr "Años fiscales"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_day
msgid "Fiscalyear Last Day"
msgstr "Año fiscal último día"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_month
msgid "Fiscalyear Last Month"
msgstr "Año fiscal último mes"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__id
msgid "ID"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Journal Entries Lock Date"
msgstr "Fecha de bloqueo de asientos de diario"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__period_lock_date
msgid "Journals Entries Lock Date"
msgstr "Fecha de bloqueo para no asesores"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Last Day"
msgstr "Último día"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_uid
msgid "Last Updated by"
msgstr "Última actualización por"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_date
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid "Lock Date for All Users"
msgstr "Fecha de bloqueo para todos los usuarios"
#. module: om_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_action_change_lock_date
msgid "Lock Dates"
msgstr "Fechas de bloqueo"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.action_view_change_lock_date
msgid "Lock your Fiscal Period"
msgstr "Bloqueo de su período fiscal"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Lock your fiscal period"
msgstr "Bloqueo de su período fiscal"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Management Closing"
msgstr "Cierre de gestión"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__name
msgid "Name"
msgstr "Nombre"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid ""
"No users can edit journal entries related to a tax prior and inclusive of "
"this date."
msgstr ""
"Ningún usuario puede editar asientos de diario relacionados con un impuesto "
"anterior e inclusive de esta fecha."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking for example."
msgstr ""
"Ningún usuario, incluidos los asesores, puede editar cuentas antes de esta "
"fecha inclusive. Úselo para bloquear el año fiscal por ejemplo."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking."
msgstr ""
"Ningún usuario, incluidos los Asesores, puede editar cuentas antes de esta "
"fecha inclusive. Úselo para bloquear el año fiscal."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__period_lock_date
msgid ""
"Only users with the 'Adviser' role can edit accounts prior to and inclusive "
"of this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr ""
"Solo los usuarios con el rol de 'Asesor' pueden editar cuentas antes de esta"
" fecha inclusive. Úselo para el bloqueo de períodos dentro de un año fiscal "
"abierto, por ejemplo."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Prevent posting of journal entries in this period."
msgstr "Evitar la contabilización de asientos de diario en este período."
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Save"
msgstr "Guardar"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date"
msgstr "Fecha de inicio"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date, included in the fiscal year."
msgstr "Fecha de inicio, incluida en el ejercicio fiscal."
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid "Tax Lock Date"
msgstr "Fecha de bloqueo de impuestos"

View File

@@ -0,0 +1,309 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_fiscal_year
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-15 06:46+0000\n"
"PO-Revision-Date: 2022-07-06 00:19+0200\n"
"Last-Translator: Sylvain Lc\n"
"Language-Team: \n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 3.1\n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Account Period Closing"
msgstr "Clôture de la période du compte"
#. module: om_fiscal_year
#: model:res.groups,name:om_fiscal_year.group_fiscal_year
msgid "Allow to define fiscal years of more or less than a year"
msgstr "Permettre de définir des années fiscales de plus ou moins d'un an"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Cancel"
msgstr "Annuler"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_change_lock_date
msgid "Change Lock Date"
msgstr "Changer la date de cloture"
#. module: om_fiscal_year
#: model_terms:ir.actions.act_window,help:om_fiscal_year.actions_account_fiscal_year
msgid "Click here to create a new fiscal year."
msgstr "Cliquez ici pour créer une nouvelle année fiscale."
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_company
msgid "Companies"
msgstr "Sociétés"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__company_id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__company_id
msgid "Company"
msgstr "Société"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_config_settings
msgid "Config Settings"
msgstr "Paramètres de Configuration"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_date
msgid "Created on"
msgstr "Créé sur"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Define fiscal years of more or less than one year"
msgstr "Définir des exercices de plus ou de moins d'un an"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__display_name
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__display_name
msgid "Display Name"
msgstr "Afficher un nom"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_to
msgid "End Date"
msgstr "Date de fin"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_to
msgid "Ending Date, included in the fiscal year."
msgstr "Date de fin, comprise dans l'année fiscale."
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Period Closing"
msgstr "Clôture de lexercice"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_account_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Year"
msgstr "Exercice fiscal"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.actions_account_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__group_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Years"
msgstr "Exercices fiscaux"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_day
msgid "Fiscalyear Last Day"
msgstr "Dernier jour de l'exercice fiscal"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_month
msgid "Fiscalyear Last Month"
msgstr "Dernier mois de l'exercice fiscal"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__id
msgid "ID"
msgstr "ID"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Journal Entries Lock Date"
msgstr "Date de verrouillage des entrées de journal"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Last Day"
msgstr "Dernier jour"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year____last_update
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date____last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_uid
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid "Lock Date"
msgstr "Date de verrouillage"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid "Lock Date for All Users"
msgstr "Date de clôture pour tous les utilisateurs"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__period_lock_date
msgid "Lock Date for Non-Advisers"
msgstr "Date de verrouillage pour les non-conseillers"
#. module: om_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_action_change_lock_date
msgid "Lock Dates"
msgstr "Date de clôture"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.action_view_change_lock_date
msgid "Lock your Fiscal Period"
msgstr "Clôturer la période fiscale"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Lock your fiscal period"
msgstr "Clôturer la période fiscale"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Management Closing"
msgstr "Clôture de la direction"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__name
msgid "Name"
msgstr "Nom"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid ""
"No users can edit journal entries related to a tax prior and inclusive of "
"this date."
msgstr ""
"Aucun utilisateur ne peut modifier des pièces comptables relatives à une "
"taxe avant et au jour de cette date."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking for example."
msgstr ""
"Aucun utilisateur, y compris les conseillers, ne peuvent modifier les "
"comptes comptables avant cette date inclusivement. Utilisez cela pour "
"verrouiller l'exercice fiscal par exemple."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking."
msgstr ""
"Aucun utilisateur, y compris les conseillers, ne peuvent modifier les "
"comptes comptables avant cette date inclusivement. Utilisez cela pour "
"verrouiller l'exercice fiscal par exemple."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__period_lock_date
msgid ""
"Only users with the 'Adviser' role can edit accounts prior to and inclusive "
"of this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr ""
"Seuls les utilisateurs avec le rôle 'Conseiller' peuvent modifier les "
"comptes comptables avant cette date inclusivement. Utilisez cela pour "
"verrouiller des périodes pendant l'exercice fiscal par exemple."
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Prevent posting of journal entries in this period."
msgstr "Empêcher la publication dentrées de journal pendant cette période."
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Save"
msgstr "Sauvegarder"
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid "Show unposted entries"
msgstr "Montrer les Ecritures non Postées"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date"
msgstr "Date de début"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date, included in the fiscal year."
msgstr "Date de début, incluse dans l'année fiscale."
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid "Tax Lock Date"
msgstr "Date de verrouillage de la taxe"
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid "The ending date must not be prior to the starting date."
msgstr "La date de fin ne peut être antérieure à la date de début."
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period you want to lock. You should "
"either post or delete them."
msgstr ""
"Il y a toujours des entrées non comptabilisées dans la période que vous "
"souhaitez verrouiller. Vous devez les comptabiliser ou les supprimer."
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unreconciled bank statement lines in the period you want to "
"lock.You should either reconcile or delete them."
msgstr ""
"Il reste des lignes de relevé bancaire non rapprochées dans la période que "
"vous souhaitez verrouiller. Vous devez soit les rapprocher, soit les "
"supprimer."
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/wizard/change_lock_date.py:0
#, python-format
msgid "You Are Not Allowed To Perform This Operation"
msgstr "Vous nêtes pas autorisé à effectuer cette opération"
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid ""
"You can not have an overlap between two fiscal years, please correct the "
"start and/or end dates of your fiscal years."
msgstr ""
"Vous ne pouvez pas avoir de chevauchement entre deux exercices, veuillez "
"corriger les dates de début et/ou de fin de vos exercices."

View File

@@ -0,0 +1,289 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_fiscal_year
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-15 06:46+0000\n"
"PO-Revision-Date: 2022-04-15 06:46+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Account Period Closing"
msgstr ""
#. module: om_fiscal_year
#: model:res.groups,name:om_fiscal_year.group_fiscal_year
msgid "Allow to define fiscal years of more or less than a year"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Cancel"
msgstr "İptal"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_change_lock_date
msgid "Change Lock Date"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.actions.act_window,help:om_fiscal_year.actions_account_fiscal_year
msgid "Click here to create a new fiscal year."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_company
msgid "Companies"
msgstr "Şirketler"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__company_id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__company_id
msgid "Company"
msgstr "Şirket"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_config_settings
msgid "Config Settings"
msgstr "Yapılandırma Ayarları"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_uid
msgid "Created by"
msgstr "Oluşturan"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_date
msgid "Created on"
msgstr "Oluşturulma Tarihi"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Define fiscal years of more or less than one year"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__display_name
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__display_name
msgid "Display Name"
msgstr "Görüntülenen Ad"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_to
msgid "End Date"
msgstr "Bitiş Tarihi"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_to
msgid "Ending Date, included in the fiscal year."
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Period Closing"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_account_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Year"
msgstr "Hesap Yılı"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.actions_account_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__group_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Years"
msgstr "Hesap Yılları"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_day
msgid "Fiscalyear Last Day"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_month
msgid "Fiscalyear Last Month"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__id
msgid "ID"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Journal Entries Lock Date"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Last Day"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year____last_update
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date____last_update
msgid "Last Modified on"
msgstr "Son Değişiklik Tarihi"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_uid
msgid "Last Updated by"
msgstr "Son Güncellemeyi Yapan"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_date
msgid "Last Updated on"
msgstr "Son Güncelleme Tarihi"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid "Lock Date"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid "Lock Date for All Users"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__period_lock_date
msgid "Lock Date for Non-Advisers"
msgstr ""
#. module: om_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_action_change_lock_date
msgid "Lock Dates"
msgstr "Kilitleme Tarihleri"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.action_view_change_lock_date
msgid "Lock your Fiscal Period"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Lock your fiscal period"
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Management Closing"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__name
msgid "Name"
msgstr "İsim"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid ""
"No users can edit journal entries related to a tax prior and inclusive of "
"this date."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking for example."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__period_lock_date
msgid ""
"Only users with the 'Adviser' role can edit accounts prior to and inclusive "
"of this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Prevent posting of journal entries in this period."
msgstr ""
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Save"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid "Show unposted entries"
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date"
msgstr "Başlangıç Tarihi"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date, included in the fiscal year."
msgstr ""
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid "Tax Lock Date"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid "The ending date must not be prior to the starting date."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period you want to lock. You should "
"either post or delete them."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unreconciled bank statement lines in the period you want to "
"lock.You should either reconcile or delete them."
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/wizard/change_lock_date.py:0
#, python-format
msgid "You Are Not Allowed To Perform This Operation"
msgstr ""
#. module: om_fiscal_year
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid ""
"You can not have an overlap between two fiscal years, please correct the "
"start and/or end dates of your fiscal years."
msgstr ""

View File

@@ -0,0 +1,289 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_fiscal_year
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-21 02:42+0000\n"
"PO-Revision-Date: 2024-03-21 02:42+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Account Period Closing"
msgstr "會計關帳日期"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid "Lock Date for All Users"
msgstr "所有使用者關帳日期"
#. module: om_fiscal_year
#: model:res.groups,name:om_fiscal_year.group_fiscal_year
msgid "Allow to define fiscal years of more or less than a year"
msgstr "允許定義多於或少於一年的會計年度"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Cancel"
msgstr "取消"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_change_lock_date
msgid "Change Lock Date"
msgstr "更改關帳日期"
#. module: om_fiscal_year
#: model_terms:ir.actions.act_window,help:om_fiscal_year.actions_account_fiscal_year
msgid "Click here to create a new fiscal year."
msgstr "點選新增會計年度"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_company
msgid "Companies"
msgstr "公司"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__company_id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__company_id
msgid "Company"
msgstr "公司"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_res_config_settings
msgid "Config Settings"
msgstr "配置設定"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_uid
msgid "Created by"
msgstr "建立於"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__create_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__create_date
msgid "Created on"
msgstr "建立於"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Define fiscal years of more or less than one year"
msgstr "定義多於或少於一年的會計年度"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__display_name
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__display_name
msgid "Display Name"
msgstr "顯示名稱"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_to
msgid "End Date"
msgstr "結束日期"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_to
msgid "Ending Date, included in the fiscal year."
msgstr "結束日期,包含在會計年度中"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Period Closing"
msgstr "會計關帳期間"
#. module: om_fiscal_year
#: model:ir.model,name:om_fiscal_year.model_account_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Year"
msgstr "會計年度"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.actions_account_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__group_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Fiscal Years"
msgstr "會計年度"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_day
msgid "Fiscalyear Last Day"
msgstr "會計年度最後一天"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__fiscalyear_last_month
msgid "Fiscalyear Last Month"
msgstr "會計年度最後一月"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__id
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__id
msgid "ID"
msgstr "ID"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Journal Entries Lock Date"
msgstr "日記帳本關帳日期"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_res_config_settings__period_lock_date
msgid "Journals Entries Lock Date"
msgstr "日記帳本關帳日期"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Last Day"
msgstr "最後一天"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_uid
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_uid
msgid "Last Updated by"
msgstr "最後更新"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__write_date
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__write_date
msgid "Last Updated on"
msgstr "最後更新"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid "Lock Date for All Users"
msgstr "所有使用者關帳日期"
#. module: om_fiscal_year
#: model:ir.ui.menu,name:om_fiscal_year.menu_action_change_lock_date
msgid "Lock Dates"
msgstr "會計關帳日期"
#. module: om_fiscal_year
#: model:ir.actions.act_window,name:om_fiscal_year.action_view_change_lock_date
msgid "Lock your Fiscal Period"
msgstr "會計關帳期間"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.res_config_settings_view_form
msgid "Lock your fiscal period"
msgstr "會計關帳期間"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Management Closing"
msgstr "管理關帳日期"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__name
msgid "Name"
msgstr "名稱"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid ""
"No users can edit journal entries related to a tax prior and inclusive of "
"this date."
msgstr "任何使用者都無法編輯與該日期之前(含該日期)的稅務相關的日記帳分錄。"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking for example."
msgstr "任何使用者(包括管理者)都不能在「之前」(含)編輯帳戶這個日期。例如,將其用於會計年度關帳。”"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__fiscalyear_lock_date
msgid ""
"No users, including Advisers, can edit accounts prior to and inclusive of "
"this date. Use it for fiscal year locking."
msgstr "在此日期之前(包括該日期),任何使用者(包括管理者)都不能編輯帳戶。 使用它來關帳會計年度。"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_res_config_settings__period_lock_date
msgid ""
"Only users with the 'Adviser' role can edit accounts prior to and inclusive "
"of this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr "只有具有「管理者」角色的使用者才能在此日期之前(含該日期)編輯帳戶。 例如,將其用於開放會計年度內的期間關帳。"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_change_lock_date__period_lock_date
msgid "Prevent posting of journal entries in this period."
msgstr "防止在此期間過帳日記帳分錄"
#. module: om_fiscal_year
#: model_terms:ir.ui.view,arch_db:om_fiscal_year.view_change_lock_date
msgid "Save"
msgstr "保存"
#. module: om_fiscal_year
#. odoo-python
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid "Show unposted entries"
msgstr "顯示未過帳的分錄"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date"
msgstr "開始日期"
#. module: om_fiscal_year
#: model:ir.model.fields,help:om_fiscal_year.field_account_fiscal_year__date_from
msgid "Start Date, included in the fiscal year."
msgstr "開始日期,包含在會計年度中。"
#. module: om_fiscal_year
#: model:ir.model.fields,field_description:om_fiscal_year.field_change_lock_date__tax_lock_date
msgid "Tax Lock Date"
msgstr "稅額關帳日期"
#. module: om_fiscal_year
#. odoo-python
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid "The ending date must not be prior to the starting date."
msgstr "結束日期不得早於開始日期。"
#. module: om_fiscal_year
#. odoo-python
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period you want to lock. You should "
"either post or delete them."
msgstr "在您想要關帳的期間內仍有未過帳的條目。 您應該發布或刪除它們。"
#. module: om_fiscal_year
#. odoo-python
#: code:addons/om_fiscal_year/models/res_company.py:0
#, python-format
msgid ""
"There are still unreconciled bank statement lines in the period you want to "
"lock.You should either reconcile or delete them."
msgstr "您想要關帳的期間內仍有未調整的銀行對帳單行。您應該調整或刪除它們"
#. module: om_fiscal_year
#. odoo-python
#: code:addons/om_fiscal_year/wizard/change_lock_date.py:0
#, python-format
msgid "You Are Not Allowed To Perform This Operation"
msgstr "您無權執行此操作"
#. module: om_fiscal_year
#. odoo-python
#: code:addons/om_fiscal_year/models/account_fiscal_year.py:0
#, python-format
msgid ""
"You can not have an overlap between two fiscal years, please correct the "
"start and/or end dates of your fiscal years."
msgstr "兩個會計年度之間不能有重疊,請更正會計年度的開始和/或結束日期。"

View File

@@ -0,0 +1,3 @@
from . import account_fiscal_year
from . import account_settings
from . import res_company

View File

@@ -0,0 +1,48 @@
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class AccountFiscalYear(models.Model):
_name = 'account.fiscal.year'
_description = 'Fiscal Year'
name = fields.Char(string='Name', required=True)
date_from = fields.Date(string='Start Date', required=True,
help='Start Date, included in the fiscal year.')
date_to = fields.Date(string='End Date', required=True,
help='Ending Date, included in the fiscal year.')
company_id = fields.Many2one('res.company', string='Company', required=True,
default=lambda self: self.env.company)
@api.constrains('date_from', 'date_to', 'company_id')
def _check_dates(self):
'''
Check interleaving between fiscal years.
There are 3 cases to consider:
s1 s2 e1 e2
( [----)----]
s2 s1 e2 e1
[----(----] )
s1 s2 e2 e1
( [----] )
'''
for fy in self:
# Starting date must be prior to the ending date
date_from = fy.date_from
date_to = fy.date_to
if date_to < date_from:
raise ValidationError(_('The ending date must not be prior to the starting date.'))
domain = [
('id', '!=', fy.id),
('company_id', '=', fy.company_id.id),
'|', '|',
'&', ('date_from', '<=', fy.date_from), ('date_to', '>=', fy.date_from),
'&', ('date_from', '<=', fy.date_to), ('date_to', '>=', fy.date_to),
'&', ('date_from', '<=', fy.date_from), ('date_to', '>=', fy.date_to),
]
if self.search_count(domain) > 0:
raise ValidationError(_('You can not have an overlap between two fiscal years, '
'please correct the start and/or end dates of your fiscal years.'))

View File

@@ -0,0 +1,30 @@
from odoo import api, fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
fiscalyear_last_day = fields.Integer(
related='company_id.fiscalyear_last_day', readonly=False
)
fiscalyear_last_month = fields.Selection(
related='company_id.fiscalyear_last_month', readonly=False
)
tax_lock_date = fields.Date(
related='company_id.hard_lock_date', readonly=False
)
sale_lock_date = fields.Date(
related='company_id.hard_lock_date', readonly=False
)
purchase_lock_date = fields.Date(
related='company_id.hard_lock_date', readonly=False
)
hard_lock_date = fields.Date(
related='company_id.hard_lock_date', readonly=False
)
fiscalyear_lock_date = fields.Date(
related='company_id.fiscalyear_lock_date', readonly=False
)
group_fiscal_year = fields.Boolean(
string='Fiscal Years', implied_group='om_fiscal_year.group_fiscal_year'
)

View File

@@ -0,0 +1,38 @@
from odoo import api, fields, models, _
from odoo.exceptions import RedirectWarning, ValidationError
class ResCompany(models.Model):
_inherit = 'res.company'
def _validate_fiscalyear_lock(self, values):
if values.get('fiscalyear_lock_date'):
draft_entries = self.env['account.move'].search([
('company_id', 'in', self.ids),
('state', '=', 'draft'),
('date', '<=', values['fiscalyear_lock_date'])])
if draft_entries:
error_msg = _(
'There are still unposted entries in the period you want to lock. You should either post or delete them.')
action_error = {
'view_mode': 'list',
'name': 'Unposted Entries',
'res_model': 'account.move',
'type': 'ir.actions.act_window',
'domain': [('id', 'in', draft_entries.ids)],
'search_view_id': [self.env.ref('account.view_account_move_filter').id, 'search'],
'views': [[self.env.ref('account.view_move_tree').id, 'list'],
[self.env.ref('account.view_move_form').id, 'form']],
}
raise RedirectWarning(error_msg, action_error, _('Show unposted entries'))
unreconciled_statement_lines = self.env['account.bank.statement.line'].search([
('company_id', 'in', self.ids),
('is_reconciled', '=', False),
('date', '<=', values['fiscalyear_lock_date']),
('move_id.state', 'in', ('draft', 'posted')),
])
if unreconciled_statement_lines:
error_msg = _("There are still unreconciled bank statement lines in the period you want to lock."
"You should either reconcile or delete them.")
raise ValidationError(error_msg)

View File

@@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_fiscal_year,access.account.fiscal.year,model_account_fiscal_year,account.group_account_user,1,1,0,0
access_account_fiscal_year_manager,access.account.fiscal.year.manager,model_account_fiscal_year,account.group_account_manager,1,1,1,1
access_change_lock_date_manager,access.change.lock.date.manager,model_change_lock_date,account.group_account_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_fiscal_year access.account.fiscal.year model_account_fiscal_year account.group_account_user 1 1 0 0
3 access_account_fiscal_year_manager access.account.fiscal.year.manager model_account_fiscal_year account.group_account_manager 1 1 1 1
4 access_change_lock_date_manager access.change.lock.date.manager model_change_lock_date account.group_account_manager 1 1 1 1

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record id="group_fiscal_year" model="res.groups">
<field name="name">Allow to define fiscal years of more or less than a year</field>
<field name="user_ids" eval="[Command.link(ref('base.user_root')), Command.link(ref('base.user_admin'))]"/>
</record>
</data>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,60 @@
<section class="oe_container oe_dark">
<div class="col-md-12">
<h2 class="oe_slogan" style="font-size: 35px;color:#2C0091"><b>Odoo 19 Fiscal Year & Closing</b></h2>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Fiscal Year</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="fiscal_year.png" style="height:400px;">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Lock Date</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="lock_date.png" style="height:400px;">
</div>
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<section class="oe_container oe_dark">
<div class="oe_row ">
<div class="oe_slogan text-center">
<img src="odoo_mates.png"/>
<div style="color:#269900;">
<h3 style="color:#2C0091;font-size: 25px;">If you need any help or want more features, just contact us:</h3><br>
<h3 style="color:#2C0091;font-size: 20px;">Email: <a href="odoomates@gmail.com">odoomates@gmail.com</a> <br></h3>
</div>
<div class="oe_slogan">
<h2>
<a target="_blank" href="https://www.facebook.com/odoomate/" target="new">
<i class="fa fa-facebook-square" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://twitter.com/odoomates/" target="new">
<i class="fa fa-twitter" style="font-size:38px;"></i>
</a>
<a href="#" target="_blank">
<i class="fa fa-linkedin" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://www.youtube.com/channel/UCVKlUZP7HAhdQgs-9iTJklQ">
<i class="fa fa-youtube-play" style="font-size:38px;"></i>
</a>
</h2>
</div>
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_fiscal_year_tree" model="ir.ui.view">
<field name="name">account.fiscal.year.list</field>
<field name="model">account.fiscal.year</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
<field name="date_from"/>
<field name="date_to"/>
</list>
</field>
</record>
<record id="view_account_fiscal_year_form" model="ir.ui.view">
<field name="name">account.fiscal.year.form</field>
<field name="model">account.fiscal.year</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="name"/>
<field name="company_id"/>
</group>
<group>
<field name="date_from"/>
<field name="date_to"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="actions_account_fiscal_year" model="ir.actions.act_window">
<field name="name">Fiscal Years</field>
<field name="res_model">account.fiscal.year</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click here to create a new fiscal year.
</p>
</field>
</record>
<menuitem id="menu_fiscal_year"
name="Fiscal Year"
sequence="5"
parent="account.account_account_menu"
action="actions_account_fiscal_year"
groups="om_fiscal_year.group_fiscal_year"/>
</odoo>

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.accountant</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="arch" type="xml">
<setting id="fiscalyear" position="replace">
<setting class="col-12 col-lg-6" id="fiscalyear">
<div class="col-12 col-lg-12 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<separator string="Fiscal Year"/>
<div class="content-group">
<div class="row mt16">
<label for="fiscalyear_last_month" string="Last Day"
class="col-lg-3 o_light_label"/>
<field name="fiscalyear_last_month" style="width: 100px; margin-right: 8px;"/>
<field name="fiscalyear_last_day" class="oe_inline"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-12 o_setting_box">
<div class="o_setting_left_pane">
<field name="group_fiscal_year"/>
</div>
<div class="o_setting_right_pane">
<label for="group_fiscal_year"/>
<div class="text-muted">
Define fiscal years of more or less than one year
</div>
<div class="mt16">
<button name="%(om_fiscal_year.actions_account_fiscal_year)d" icon="fa-arrow-right"
type="action" string="Fiscal Years" class="btn-link"
invisible="group_fiscal_year == False"/>
</div>
</div>
</div>
</setting>
<setting class="col-xs-12 col-md-6 o_setting_box" id="fiscalyear">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<separator string="Fiscal Period Closing"/>
<div class="text-muted">
Lock your fiscal period
</div>
<div class="content-group">
<div class="row mt16">
<label for="fiscalyear_lock_date" class="col-md-5 o_light_label"/>
<field name="fiscalyear_lock_date"/>
<label for="sale_lock_date" string="Sales Lock Date" class="col-md-5 o_light_label"/>
<field name="sale_lock_date"/>
<label for="purchase_lock_date" string="Purchase Lock Date" class="col-md-5 o_light_label"/>
<field name="purchase_lock_date"/>
<label for="hard_lock_date" class="col-md-5 o_light_label"/>
<field name="hard_lock_date"/>
<label for="tax_lock_date" string="Tax Return Lock Date" class="col-md-5 o_light_label"/>
<field name="tax_lock_date"/>
</div>
</div>
</div>
</setting>
</setting>
</field>
</record>
</odoo>

View File

@@ -0,0 +1 @@
from . import change_lock_date

View File

@@ -0,0 +1,60 @@
from odoo import models, fields, api, SUPERUSER_ID, _
from odoo.exceptions import UserError
class ChangeLockDate(models.TransientModel):
_name = 'change.lock.date'
_description = 'Change Lock Date'
@api.model
def default_get(self, vals):
res = super(ChangeLockDate, self).default_get(vals)
company_rec = self.env.user.company_id
res.update({
'company_id': company_rec.id,
'hard_lock_date': company_rec.hard_lock_date,
'fiscalyear_lock_date': company_rec.fiscalyear_lock_date,
'purchase_lock_date': company_rec.purchase_lock_date,
'sale_lock_date': company_rec.sale_lock_date,
'tax_lock_date': company_rec.tax_lock_date,
})
return res
company_id = fields.Many2one(
'res.company', string="Company",
required=True, default=lambda self: self.env.user.company_id
)
tax_lock_date = fields.Date(
string="Tax Return Lock Date",
help="No users can edit journal entries related to a tax prior and inclusive of this date.")
sale_lock_date = fields.Date(
string='Sales Lock Date',
help='Prevents creation and modification of entries in sales journals up to the defined date inclusive.'
)
purchase_lock_date = fields.Date(
string='Purchase Lock date',
help='Prevents creation and modification of entries in purchase journals up to the defined date inclusive.'
)
hard_lock_date = fields.Date(
string='Hard Lock Date',
help='Like the "Global Lock Date", but no exceptions are possible.'
)
fiscalyear_lock_date = fields.Date(
string='Lock Date for All Users',
default=lambda self: self.env.user.company_id.fiscalyear_lock_date,
help='No users, including Advisers, can edit accounts prior to and inclusive of '
'this date. Use it for fiscal year locking.'
)
def update_lock_date(self):
self.ensure_one()
has_manager_group = self.env.user.has_group('account.group_account_manager')
if not (has_manager_group or self.env.uid == SUPERUSER_ID):
raise UserError(_("You Are Not Allowed To Perform This Operation"))
self.company_id.sudo().write({
'hard_lock_date': self.hard_lock_date,
'fiscalyear_lock_date': self.fiscalyear_lock_date,
'purchase_lock_date': self.purchase_lock_date,
'sale_lock_date': self.sale_lock_date,
'tax_lock_date': self.tax_lock_date,
})

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_change_lock_date" model="ir.ui.view">
<field name="name">change.lock.date.form</field>
<field name="model">change.lock.date</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group string="Management Closing">
<field name="company_id"
options="{'no_create': True, 'no_open': True}"
groups="base.group_multi_company"/>
<field name="sale_lock_date"/>
<field name="purchase_lock_date"/>
<field name="tax_lock_date"/>
</group>
<group string="Account Period Closing">
<field name="fiscalyear_lock_date"/>
<field name="hard_lock_date"/>
</group>
</group>
</sheet>
<footer>
<button string="Save" name="update_lock_date" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_view_change_lock_date" model="ir.actions.act_window">
<field name="name">Lock your Fiscal Period</field>
<field name="res_model">change.lock.date</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_change_lock_date"/>
<field name="target">new</field>
</record>
<menuitem id="menu_action_change_lock_date"
name="Lock Dates"
action="action_view_change_lock_date"
parent="account.menu_finance_entries"
sequence="100"
groups="account.group_account_manager"/>
</data>
</odoo>