You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.3 KiB

  1. import logging
  2. import io
  3. from odoo import api, models, _
  4. from odoo.exceptions import UserError
  5. from odoo.addons.base_iban.models.res_partner_bank import _map_iban_template
  6. from odoo.addons.base_iban.models.res_partner_bank import validate_iban
  7. _logger = logging.getLogger(__name__)
  8. try:
  9. from ofxparse import OfxParser
  10. except ImportError:
  11. _logger.debug("ofxparse not found.")
  12. OfxParser = None
  13. class AccountBankStatementImport(models.TransientModel):
  14. _inherit = 'account.bank.statement.import'
  15. def _check_journal_bank_account(self, journal, account_number):
  16. res = super(
  17. AccountBankStatementImport, self
  18. )._check_journal_bank_account(journal, account_number)
  19. if not res:
  20. e_acc_num = journal.bank_account_id.sanitized_acc_number
  21. e_acc_num = e_acc_num.replace(" ", "")
  22. validate_iban(e_acc_num)
  23. country_code = e_acc_num[:2].lower()
  24. iban_template = _map_iban_template[country_code].replace(
  25. " ", "")
  26. e_acc_num = "".join(
  27. [c for c, t in zip(e_acc_num, iban_template) if t == "C"])
  28. res = (e_acc_num == account_number)
  29. return res
  30. @api.model
  31. def _check_ofx(self, data_file):
  32. if not OfxParser:
  33. return False
  34. try:
  35. ofx = OfxParser.parse(io.BytesIO(data_file))
  36. except Exception as e:
  37. _logger.debug(e)
  38. return False
  39. return ofx
  40. @api.model
  41. def _prepare_ofx_transaction_line(self, transaction):
  42. # Since ofxparse doesn't provide account numbers,
  43. # we cannot provide the key 'bank_account_id',
  44. # nor the key 'account_number'
  45. # If you read odoo10/addons/account_bank_statement_import/
  46. # account_bank_statement_import.py, it's the only 2 keys
  47. # we can provide to match a partner.
  48. name = transaction.payee
  49. if transaction.checknum:
  50. name += " " + transaction.checknum
  51. if transaction.memo:
  52. name += " : " + transaction.memo
  53. vals = {
  54. 'date': transaction.date,
  55. 'name': name,
  56. 'ref': transaction.id,
  57. 'amount': float(transaction.amount),
  58. 'unique_import_id': transaction.id,
  59. }
  60. return vals
  61. def _parse_file(self, data_file):
  62. ofx = self._check_ofx(data_file)
  63. if not ofx:
  64. return super(AccountBankStatementImport, self)._parse_file(
  65. data_file)
  66. transactions = []
  67. total_amt = 0.00
  68. try:
  69. for transaction in ofx.account.statement.transactions:
  70. vals = self._prepare_ofx_transaction_line(transaction)
  71. if vals:
  72. transactions.append(vals)
  73. total_amt += vals['amount']
  74. except Exception as e:
  75. raise UserError(_(
  76. "The following problem occurred during import. "
  77. "The file might not be valid.\n\n %s") % e.message)
  78. balance = float(ofx.account.statement.balance)
  79. vals_bank_statement = {
  80. 'name': ofx.account.number,
  81. 'transactions': transactions,
  82. 'balance_start': balance - total_amt,
  83. 'balance_end_real': balance,
  84. }
  85. return ofx.account.statement.currency, ofx.account.number, [
  86. vals_bank_statement]