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

# -*- 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