1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/account_online_synchronization/models/account_bank_statement.py
2024-12-10 09:04:09 +07:00

91 lines
5.3 KiB
Python

# -*- coding: utf-8 -*-
import threading
import time
from odoo import api, fields, models, SUPERUSER_ID, tools, _
from odoo.tools import date_utils
from odoo.exceptions import UserError, ValidationError
STATEMENT_LINE_CREATION_BATCH_SIZE = 500 # When importing transactions, batch the process to commit after importing batch_size
class AccountBankStatementLine(models.Model):
_inherit = 'account.bank.statement.line'
online_transaction_identifier = fields.Char("Online Transaction Identifier", readonly=True)
online_partner_information = fields.Char(readonly=True)
online_account_id = fields.Many2one(comodel_name='account.online.account', readonly=True)
online_link_id = fields.Many2one(
comodel_name='account.online.link',
related='online_account_id.account_online_link_id',
store=True,
readonly=True,
)
@api.model
def _online_sync_bank_statement(self, transactions, online_account):
"""
build bank statement lines from a list of transaction and post messages is also post in the online_account of the journal.
:param transactions: A list of transactions that will be created.
The format is : [{
'id': online id, (unique ID for the transaction)
'date': transaction date, (The date of the transaction)
'name': transaction description, (The description)
'amount': transaction amount, (The amount of the transaction. Negative for debit, positive for credit)
}, ...]
:param online_account: The online account for this statement
Return: The number of imported transaction for the journal
"""
start_time = time.time()
lines_to_reconcile = self.env['account.bank.statement.line']
try:
for journal in online_account.journal_ids:
# Since the synchronization succeeded, set it as the bank_statements_source of the journal
journal.sudo().write({'bank_statements_source': 'online_sync'})
if not transactions:
continue
sorted_transactions = sorted(transactions, key=lambda transaction: transaction['date'])
total = self.env.context.get('transactions_total') or sum([transaction['amount'] for transaction in transactions])
# For first synchronization, an opening line is created to fill the missing bank statement data
any_st_line = self.search_count([('journal_id', '=', journal.id)], limit=1)
journal_currency = journal.currency_id or journal.company_id.currency_id
# If there are neither statement and the ending balance != 0, we create an opening bank statement
if not any_st_line and not journal_currency.is_zero(online_account.balance - total):
opening_st_line = self.with_context(skip_statement_line_cron_trigger=True).create({
'date': date_utils.subtract(sorted_transactions[0]['date'], days=1),
'journal_id': journal.id,
'payment_ref': _("Opening statement: first synchronization"),
'amount': online_account.balance - total,
})
lines_to_reconcile += opening_st_line
filtered_transactions = online_account._get_filtered_transactions(sorted_transactions)
do_commit = not (hasattr(threading.current_thread(), 'testing') and threading.current_thread().testing)
if filtered_transactions:
# split transactions import in batch and commit after each batch except in testing mode
for index in range(0, len(filtered_transactions), STATEMENT_LINE_CREATION_BATCH_SIZE):
lines_to_reconcile += self.with_user(SUPERUSER_ID).with_context(skip_statement_line_cron_trigger=True).create(filtered_transactions[index:index+STATEMENT_LINE_CREATION_BATCH_SIZE])
if do_commit:
self.env.cr.commit()
# Set last sync date as the last transaction date
journal.account_online_account_id.sudo().write({'last_sync': filtered_transactions[-1]['date']})
if lines_to_reconcile:
# 'limit_time_real_cron' defaults to -1.
# Manual fallback applied for non-POSIX systems where this key is disabled (set to None).
cron_limit_time = tools.config['limit_time_real_cron'] or -1
limit_time = (cron_limit_time if cron_limit_time > 0 else 180) - (time.time() - start_time)
if limit_time > 0:
lines_to_reconcile._cron_try_auto_reconcile_statement_lines(limit_time=limit_time)
# Catch any configuration error that would prevent creating the entries, reset fetching_status flag and re-raise the error
# Otherwise flag is never reset and user is under the impression that we are still fetching transactions
except (UserError, ValidationError) as e:
self.env.cr.rollback()
online_account.account_online_link_id._log_information('error', subject=_("Error"), message=str(e))
self.env.cr.commit()
raise
return lines_to_reconcile