mirror of
https://github.com/bringout/oca-ocb-accounting.git
synced 2026-04-18 05:41:59 +02:00
[16.1] Add lock date migration and settings UI
This commit is contained in:
parent
64fdc5b0df
commit
c7d2961320
6 changed files with 186 additions and 14 deletions
|
|
@ -0,0 +1,63 @@
|
||||||
|
from odoo import api, SUPERUSER_ID
|
||||||
|
|
||||||
|
|
||||||
|
def _table_has_column(cr, table, column):
|
||||||
|
cr.execute(
|
||||||
|
"""
|
||||||
|
SELECT 1
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = %s AND column_name = %s
|
||||||
|
""",
|
||||||
|
(table, column),
|
||||||
|
)
|
||||||
|
return bool(cr.fetchone())
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(cr, version):
|
||||||
|
if not version:
|
||||||
|
return
|
||||||
|
|
||||||
|
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||||
|
|
||||||
|
# Initialise new company lock fields using existing lock dates.
|
||||||
|
companies = env['res.company'].with_context(active_test=False).search([])
|
||||||
|
for company in companies:
|
||||||
|
vals = {}
|
||||||
|
if not company.sale_lock_date and company.period_lock_date:
|
||||||
|
vals['sale_lock_date'] = company.period_lock_date
|
||||||
|
if not company.purchase_lock_date and company.period_lock_date:
|
||||||
|
vals['purchase_lock_date'] = company.period_lock_date
|
||||||
|
if not company.hard_lock_date and company.fiscalyear_lock_date:
|
||||||
|
vals['hard_lock_date'] = company.fiscalyear_lock_date
|
||||||
|
if vals:
|
||||||
|
company.sudo().write(vals)
|
||||||
|
|
||||||
|
# If account_move_export is installed, migrate configuration defaults.
|
||||||
|
if env.registry.get('account.move.export.config'):
|
||||||
|
# Ensure new boolean fields are not left NULL and join_char has a value.
|
||||||
|
cr.execute(
|
||||||
|
"""
|
||||||
|
UPDATE account_move_export_config
|
||||||
|
SET group_lines = COALESCE(group_lines, FALSE),
|
||||||
|
lock_tax = COALESCE(lock_tax, FALSE),
|
||||||
|
lock_sale = COALESCE(lock_sale, FALSE),
|
||||||
|
lock_purchase = COALESCE(lock_purchase, FALSE),
|
||||||
|
lock_fiscalyear = COALESCE(lock_fiscalyear, FALSE),
|
||||||
|
lock_hard = COALESCE(lock_hard, FALSE),
|
||||||
|
join_char = COALESCE(NULLIF(join_char, ''), '-')
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
if _table_has_column(cr, 'account_move_export_config', 'lock'):
|
||||||
|
cr.execute(
|
||||||
|
"""
|
||||||
|
UPDATE account_move_export_config
|
||||||
|
SET lock_tax = lock_tax OR lock IN ('tax', 'period', 'fiscalyear'),
|
||||||
|
lock_sale = lock_sale OR lock IN ('period', 'fiscalyear'),
|
||||||
|
lock_purchase = lock_purchase OR lock IN ('period', 'fiscalyear'),
|
||||||
|
lock_fiscalyear = lock_fiscalyear OR lock = 'fiscalyear',
|
||||||
|
lock_hard = lock_hard OR lock = 'fiscalyear'
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
# Optionally drop the legacy column to avoid confusion.
|
||||||
|
cr.execute("ALTER TABLE account_move_export_config DROP COLUMN lock")
|
||||||
|
|
@ -38,6 +38,13 @@ class AccountAccount(models.Model):
|
||||||
currency_id = fields.Many2one('res.currency', string='Account Currency', tracking=True,
|
currency_id = fields.Many2one('res.currency', string='Account Currency', tracking=True,
|
||||||
help="Forces all journal items in this account to have a specific currency (i.e. bank journals). If no currency is set, entries can use any currency.")
|
help="Forces all journal items in this account to have a specific currency (i.e. bank journals). If no currency is set, entries can use any currency.")
|
||||||
company_currency_id = fields.Many2one(related='company_id.currency_id')
|
company_currency_id = fields.Many2one(related='company_id.currency_id')
|
||||||
|
company_ids = fields.Many2many(
|
||||||
|
'res.company',
|
||||||
|
compute='_compute_company_ids',
|
||||||
|
search='_search_company_ids',
|
||||||
|
string='Companies',
|
||||||
|
compute_sudo=True,
|
||||||
|
)
|
||||||
code = fields.Char(size=64, required=True, tracking=True, unaccent=False)
|
code = fields.Char(size=64, required=True, tracking=True, unaccent=False)
|
||||||
deprecated = fields.Boolean(default=False, tracking=True)
|
deprecated = fields.Boolean(default=False, tracking=True)
|
||||||
used = fields.Boolean(compute='_compute_used', search='_search_used')
|
used = fields.Boolean(compute='_compute_used', search='_search_used')
|
||||||
|
|
@ -344,6 +351,23 @@ class AccountAccount(models.Model):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.used = record.id in ids
|
record.used = record.id in ids
|
||||||
|
|
||||||
|
def _compute_company_ids(self):
|
||||||
|
for account in self:
|
||||||
|
account.company_ids = account.company_id
|
||||||
|
|
||||||
|
def _search_company_ids(self, operator, value):
|
||||||
|
if operator in ('in', 'not in'):
|
||||||
|
if isinstance(value, (list, tuple, set)):
|
||||||
|
values = list(value)
|
||||||
|
elif hasattr(value, 'ids'):
|
||||||
|
values = value.ids
|
||||||
|
else:
|
||||||
|
values = [value]
|
||||||
|
return [('company_id', operator, values)]
|
||||||
|
if hasattr(value, 'id'):
|
||||||
|
value = value.id
|
||||||
|
return [('company_id', operator, value)]
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _search_new_account_code(self, company, digits, prefix):
|
def _search_new_account_code(self, company, digits, prefix):
|
||||||
for num in range(1, 10000):
|
for num in range(1, 10000):
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,21 @@ class ResCompany(models.Model):
|
||||||
string="Tax Return Lock Date",
|
string="Tax Return Lock Date",
|
||||||
tracking=True,
|
tracking=True,
|
||||||
help="No users can edit journal entries related to a tax prior and inclusive of this 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",
|
||||||
|
tracking=True,
|
||||||
|
help="No users can post or modify customer invoices prior to and inclusive of this date."
|
||||||
|
)
|
||||||
|
purchase_lock_date = fields.Date(
|
||||||
|
string="Purchases Lock Date",
|
||||||
|
tracking=True,
|
||||||
|
help="No users can post or modify vendor bills prior to and inclusive of this date."
|
||||||
|
)
|
||||||
|
hard_lock_date = fields.Date(
|
||||||
|
string="Hard Lock Date",
|
||||||
|
tracking=True,
|
||||||
|
help="No users can post or modify any journal entries prior to and inclusive of this date."
|
||||||
|
)
|
||||||
transfer_account_id = fields.Many2one('account.account',
|
transfer_account_id = fields.Many2one('account.account',
|
||||||
domain="[('reconcile', '=', True), ('account_type', '=', 'asset_current'), ('deprecated', '=', False)]", string="Inter-Banks Transfer Account", help="Intermediary account used when moving money from a liqity account to another")
|
domain="[('reconcile', '=', True), ('account_type', '=', 'asset_current'), ('deprecated', '=', False)]", string="Inter-Banks Transfer Account", help="Intermediary account used when moving money from a liqity account to another")
|
||||||
expects_chart_of_accounts = fields.Boolean(string='Expects a Chart of Accounts', default=True)
|
expects_chart_of_accounts = fields.Boolean(string='Expects a Chart of Accounts', default=True)
|
||||||
|
|
@ -375,25 +390,41 @@ class ResCompany(models.Model):
|
||||||
return lock_date
|
return lock_date
|
||||||
|
|
||||||
def write(self, values):
|
def write(self, values):
|
||||||
#restrict the closing of FY if there are still unposted entries
|
# Restrict the closing of FY if there are still unposted entries
|
||||||
self._validate_fiscalyear_lock(values)
|
self._validate_fiscalyear_lock(values)
|
||||||
|
|
||||||
# Reflect the change on accounts
|
result = True
|
||||||
for company in self:
|
for company in self:
|
||||||
if values.get('bank_account_code_prefix'):
|
company_vals = values.copy()
|
||||||
new_bank_code = values.get('bank_account_code_prefix') or company.bank_account_code_prefix
|
old_bank_prefix = company.bank_account_code_prefix
|
||||||
company.reflect_code_prefix_change(company.bank_account_code_prefix, new_bank_code)
|
old_cash_prefix = company.cash_account_code_prefix
|
||||||
|
|
||||||
if values.get('cash_account_code_prefix'):
|
# Forbid currency change when entries already exist.
|
||||||
new_cash_code = values.get('cash_account_code_prefix') or company.cash_account_code_prefix
|
if 'currency_id' in company_vals and company_vals['currency_id'] != company.currency_id.id:
|
||||||
company.reflect_code_prefix_change(company.cash_account_code_prefix, new_cash_code)
|
if self.env['account.move.line'].sudo().search([('company_id', '=', company.id)], limit=1):
|
||||||
|
|
||||||
#forbid the change of currency_id if there are already some accounting entries existing
|
|
||||||
if 'currency_id' in values and values['currency_id'] != company.currency_id.id:
|
|
||||||
if self.env['account.move.line'].sudo().search([('company_id', '=', company.id)]):
|
|
||||||
raise UserError(_('You cannot change the currency of the company since some journal items already exist'))
|
raise UserError(_('You cannot change the currency of the company since some journal items already exist'))
|
||||||
|
|
||||||
return super(ResCompany, self).write(values)
|
sync_vals = {}
|
||||||
|
if 'period_lock_date' in company_vals and 'sale_lock_date' not in company_vals:
|
||||||
|
if not company.sale_lock_date or company.sale_lock_date == company.period_lock_date:
|
||||||
|
sync_vals['sale_lock_date'] = company_vals['period_lock_date']
|
||||||
|
if not company.purchase_lock_date or company.purchase_lock_date == company.period_lock_date:
|
||||||
|
sync_vals['purchase_lock_date'] = company_vals['period_lock_date']
|
||||||
|
if 'fiscalyear_lock_date' in company_vals and 'hard_lock_date' not in company_vals:
|
||||||
|
if not company.hard_lock_date or company.hard_lock_date == company.fiscalyear_lock_date:
|
||||||
|
sync_vals['hard_lock_date'] = company_vals['fiscalyear_lock_date']
|
||||||
|
if sync_vals:
|
||||||
|
company_vals.update(sync_vals)
|
||||||
|
|
||||||
|
result &= super(ResCompany, company).write(company_vals)
|
||||||
|
|
||||||
|
if 'bank_account_code_prefix' in company_vals and company.bank_account_code_prefix != old_bank_prefix:
|
||||||
|
company.reflect_code_prefix_change(old_bank_prefix, company.bank_account_code_prefix or company_vals.get('bank_account_code_prefix'))
|
||||||
|
|
||||||
|
if 'cash_account_code_prefix' in company_vals and company.cash_account_code_prefix != old_cash_prefix:
|
||||||
|
company.reflect_code_prefix_change(old_cash_prefix, company.cash_account_code_prefix or company_vals.get('cash_account_code_prefix'))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def setting_init_bank_account_action(self):
|
def setting_init_bank_account_action(self):
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,12 @@ class ResConfigSettings(models.TransientModel):
|
||||||
related='company_id.account_journal_early_pay_discount_gain_account_id',
|
related='company_id.account_journal_early_pay_discount_gain_account_id',
|
||||||
domain="[('deprecated', '=', False), ('company_id', '=', company_id), ('account_type', 'in', ('income', 'income_other', 'expense'))]",
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id), ('account_type', 'in', ('income', 'income_other', 'expense'))]",
|
||||||
)
|
)
|
||||||
|
period_lock_date = fields.Date(related='company_id.period_lock_date', readonly=False)
|
||||||
|
fiscalyear_lock_date = fields.Date(related='company_id.fiscalyear_lock_date', readonly=False)
|
||||||
|
tax_lock_date = fields.Date(related='company_id.tax_lock_date', readonly=False)
|
||||||
|
sale_lock_date = fields.Date(related='company_id.sale_lock_date', readonly=False)
|
||||||
|
purchase_lock_date = fields.Date(related='company_id.purchase_lock_date', readonly=False)
|
||||||
|
hard_lock_date = fields.Date(related='company_id.hard_lock_date', readonly=False)
|
||||||
|
|
||||||
def set_values(self):
|
def set_values(self):
|
||||||
super().set_values()
|
super().set_values()
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,54 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12 col-lg-6 o_setting_box" id="lock_dates_box">
|
||||||
|
<div class="o_setting_left_pane"/>
|
||||||
|
<div class="o_setting_right_pane">
|
||||||
|
<span class="o_form_label">Lock Dates</span>
|
||||||
|
<span class="fa fa-lg fa-building-o" title="Values set here are company-specific." aria-label="Values set here are company-specific." groups="base.group_multi_company" role="img"/>
|
||||||
|
<div class="text-muted">
|
||||||
|
Prevent posting moves before the selected cut-off dates.
|
||||||
|
</div>
|
||||||
|
<div class="content-group">
|
||||||
|
<div class="row mt16">
|
||||||
|
<label for="period_lock_date" class="col-lg-6 o_light_label">Non-Advisers Lock Date</label>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<field name="period_lock_date" widget="date"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt16">
|
||||||
|
<label for="fiscalyear_lock_date" class="col-lg-6 o_light_label">All Users Lock Date</label>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<field name="fiscalyear_lock_date" widget="date"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt16">
|
||||||
|
<label for="tax_lock_date" class="col-lg-6 o_light_label">Tax Lock Date</label>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<field name="tax_lock_date" widget="date"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt16">
|
||||||
|
<label for="sale_lock_date" class="col-lg-6 o_light_label">Sales Lock Date</label>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<field name="sale_lock_date" widget="date"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt16">
|
||||||
|
<label for="purchase_lock_date" class="col-lg-6 o_light_label">Purchases Lock Date</label>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<field name="purchase_lock_date" widget="date"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt16">
|
||||||
|
<label for="hard_lock_date" class="col-lg-6 o_light_label">Hard Lock Date</label>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<field name="hard_lock_date" widget="date"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="col-12 col-lg-6 o_setting_box">
|
<div class="col-12 col-lg-6 o_setting_box">
|
||||||
<div class="o_setting_left_pane"/>
|
<div class="o_setting_left_pane"/>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue