forked from Mapan/odoo17e
91 lines
5.3 KiB
Python
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
|