You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
6.8 KiB
Python
146 lines
6.8 KiB
Python
# -*- coding: UTF-8 -*-
|
|
|
|
from odoo import api, fields, models, _, Command
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class AccountBankStatement(models.Model):
|
|
_inherit = "account.bank.statement"
|
|
# _description = "Bank Statement"
|
|
# _order = "first_line_index desc"
|
|
# _check_company_auto = True
|
|
|
|
state = fields.Selection(string='Status', required=True, readonly=True, copy=False, selection=[
|
|
('open', 'New'),
|
|
('posted', 'Processing'),
|
|
('confirm', 'Validated'),
|
|
], default='open',
|
|
help="The current state of your bank statement:"
|
|
"- New: Fully editable with draft Journal Entries."
|
|
"- Processing: No longer editable with posted Journal entries, ready for the reconciliation."
|
|
"- Validated: All lines are reconciled. There is nothing left to process.")
|
|
all_lines_reconciled = fields.Boolean(compute='_compute_all_lines_reconciled',
|
|
help="Technical field indicating if all statement lines are fully reconciled.")
|
|
line_ids = fields.One2many('account.bank.statement.line', 'statement_id', string='Statement lines', states={'confirm': [('readonly', True)]}, copy=True)
|
|
move_line_count = fields.Integer(compute="_get_move_line_count")
|
|
move_line_ids = fields.One2many('account.move.line', 'statement_id', string='Entry lines',
|
|
states={'confirm': [('readonly', True)]})
|
|
country_code = fields.Char(related='company_id.country_id.code')
|
|
previous_statement_id = fields.Many2one('account.bank.statement',
|
|
help='technical field to compute starting balance correctly',
|
|
compute='_get_previous_statement', store=True)
|
|
is_valid_balance_start = fields.Boolean(string="Is Valid Balance Start", store=True,
|
|
compute="_compute_is_valid_balance_start",
|
|
help="Technical field to display a warning message in case starting balance is different than previous ending balance")
|
|
journal_type = fields.Selection(related='journal_id.type', help="Technical field used for usability purposes")
|
|
cashbox_start_id = fields.Many2one('account.bank.statement.cashbox', string="Starting Cashbox")
|
|
cashbox_end_id = fields.Many2one('account.bank.statement.cashbox', string="Ending Cashbox")
|
|
|
|
@api.depends('line_ids.is_reconciled')
|
|
def _compute_all_lines_reconciled(self):
|
|
for statement in self:
|
|
statement.all_lines_reconciled = all(st_line.is_reconciled for st_line in statement.line_ids)
|
|
|
|
@api.depends('move_line_ids')
|
|
def _get_move_line_count(self):
|
|
for statement in self:
|
|
statement.move_line_count = len(statement.move_line_ids)
|
|
|
|
@api.depends('date', 'journal_id')
|
|
def _get_previous_statement(self):
|
|
for st in self:
|
|
# Search for the previous statement
|
|
domain = [('date', '<=', st.date), ('journal_id', '=', st.journal_id.id)]
|
|
# The reason why we have to perform this test is because we have two use case here:
|
|
# First one is in case we are creating a new record, in that case that new record does
|
|
# not have any id yet. However if we are updating an existing record, the domain date <= st.date
|
|
# will find the record itself, so we have to add a condition in the search to ignore self.id
|
|
if not isinstance(st.id, models.NewId):
|
|
domain.extend(['|', '&', ('id', '<', st.id), ('date', '=', st.date), '&', ('id', '!=', st.id), ('date', '!=', st.date)])
|
|
previous_statement = self.search(domain, limit=1)
|
|
st.previous_statement_id = previous_statement.id
|
|
|
|
@api.depends('balance_start', 'previous_statement_id')
|
|
def _compute_is_valid_balance_start(self):
|
|
for bnk in self:
|
|
bnk.is_valid_balance_start = (
|
|
bnk.currency_id.is_zero(
|
|
bnk.balance_start - bnk.previous_statement_id.balance_end_real
|
|
)
|
|
if bnk.previous_statement_id
|
|
else True
|
|
)
|
|
|
|
def button_post(self):
|
|
''' Move the bank statements from 'draft' to 'posted'. '''
|
|
if any(statement.state != 'open' for statement in self):
|
|
raise UserError(_("Only new statements can be posted."))
|
|
|
|
self._check_balance_end_real_same_as_computed()
|
|
|
|
for statement in self:
|
|
if not statement.name:
|
|
statement._set_next_sequence()
|
|
|
|
self.write({'state': 'posted'})
|
|
self.line_ids.move_id._post(soft=False)
|
|
|
|
def button_validate_or_action(self):
|
|
if self.journal_type == 'cash' and not self.currency_id.is_zero(self.difference):
|
|
return self.env['ir.actions.act_window']._for_xml_id('account.action_view_account_bnk_stmt_check')
|
|
|
|
return self.button_validate()
|
|
|
|
def button_reopen(self):
|
|
''' Move the bank statements back to the 'open' state. '''
|
|
if any(statement.state == 'draft' for statement in self):
|
|
raise UserError(_("Only validated statements can be reset to new."))
|
|
|
|
self.write({'state': 'open'})
|
|
self.line_ids.move_id.button_draft()
|
|
self.line_ids.button_undo_reconciliation()
|
|
|
|
def button_reprocess(self):
|
|
"""Move the bank statements back to the 'posted' state."""
|
|
if any(statement.state != 'confirm' for statement in self):
|
|
raise UserError(_("Only Validated statements can be reset to new."))
|
|
|
|
self.write({'state': 'posted', 'date_done': False})
|
|
|
|
def button_journal_entries(self):
|
|
return {
|
|
'name': _('Journal Entries'),
|
|
'view_mode': 'tree,form',
|
|
'res_model': 'account.move',
|
|
'view_id': False,
|
|
'type': 'ir.actions.act_window',
|
|
'domain': [('id', 'in', self.line_ids.move_id.ids)],
|
|
'context': {
|
|
'journal_id': self.journal_id.id,
|
|
}
|
|
}
|
|
|
|
def open_cashbox_id(self):
|
|
self.ensure_one()
|
|
context = dict(self.env.context or {})
|
|
if context.get('balance'):
|
|
context['statement_id'] = self.id
|
|
if context['balance'] == 'start':
|
|
cashbox_id = self.cashbox_start_id.id
|
|
elif context['balance'] == 'close':
|
|
cashbox_id = self.cashbox_end_id.id
|
|
else:
|
|
cashbox_id = False
|
|
|
|
action = {
|
|
'name': _('Cash Control'),
|
|
'view_mode': 'form',
|
|
'res_model': 'account.bank.statement.cashbox',
|
|
'view_id': self.env.ref('account.view_account_bnk_stmt_cashbox_footer').id,
|
|
'type': 'ir.actions.act_window',
|
|
'res_id': cashbox_id,
|
|
'context': context,
|
|
'target': 'new'
|
|
}
|
|
|
|
return action |