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.

94 lines
3.7 KiB

  1. # -*- coding: utf-8 -*-
  2. import logging
  3. import StringIO
  4. from openerp import api, models
  5. from openerp.tools.translate import _
  6. from openerp.exceptions import Warning as UserError
  7. _logger = logging.getLogger(__name__)
  8. try:
  9. from ofxparse import OfxParser as ofxparser
  10. except ImportError:
  11. _logger.warn("ofxparse not found, OFX parsing disabled.")
  12. ofxparser = None
  13. class AccountBankStatementImport(models.TransientModel):
  14. _inherit = 'account.bank.statement.import'
  15. @api.model
  16. def _check_ofx(self, data_file):
  17. if ofxparser is None:
  18. return False
  19. try:
  20. ofx = ofxparser.parse(StringIO.StringIO(data_file))
  21. except:
  22. return False
  23. return ofx
  24. @api.model
  25. def _parse_file(self, data_file):
  26. ofx = self._check_ofx(data_file)
  27. if not ofx:
  28. return super(AccountBankStatementImport, self)._parse_file(
  29. data_file)
  30. transactions = []
  31. total_amt = 0.00
  32. try:
  33. for transaction in ofx.account.statement.transactions:
  34. # Since ofxparse doesn't provide account numbers, we'll have
  35. # to find res.partner and res.partner.bank here
  36. # (normal behavious is to provide 'account_number', which the
  37. # generic module uses to find partner/bank)
  38. bank_account_id = partner_id = False
  39. if transaction.payee:
  40. banks = self.env['res.partner.bank'].search(
  41. [('owner_name', '=', transaction.payee)], limit=1)
  42. if banks:
  43. bank_account = banks[0]
  44. bank_account_id = bank_account.id
  45. partner_id = bank_account.partner_id.id
  46. vals_line = {
  47. 'date': transaction.date,
  48. 'name': transaction.payee + (
  49. transaction.memo and ': ' + transaction.memo or ''),
  50. 'ref': transaction.id,
  51. 'amount': transaction.amount,
  52. 'unique_import_id': '%s-%s-%s' % (
  53. transaction.id, transaction.payee, transaction.memo),
  54. 'bank_account_id': bank_account_id,
  55. 'partner_id': partner_id,
  56. }
  57. # Memo (<NAME>) and payee (<PAYEE>) are not required
  58. # field in OFX statement, cf section 11.4.3 Statement
  59. # Transaction <STMTTRN> of the OFX specs: the required
  60. # elements are in bold, cf 1.5 Conventions and these 2
  61. # fields are not in bold.
  62. # But the 'name' field of account.bank.statement.line is
  63. # required=True, so we must always have a value !
  64. # The field TRNTYPE is a required field in OFX
  65. if not vals_line['name']:
  66. vals_line['name'] = transaction.type.capitalize()
  67. if transaction.checknum:
  68. vals_line['name'] += ' %s' % transaction.checknum
  69. total_amt += float(transaction.amount)
  70. transactions.append(vals_line)
  71. except Exception, e:
  72. raise UserError(_(
  73. "The following problem occurred during import. "
  74. "The file might not be valid.\n\n %s" % e.message
  75. ))
  76. balance = float(ofx.account.statement.balance)
  77. vals_bank_statement = {
  78. 'name': ofx.account.number,
  79. 'transactions': transactions,
  80. 'balance_start': balance - total_amt,
  81. 'balance_end_real': balance,
  82. }
  83. return ofx.account.statement.currency, ofx.account.number, [
  84. vals_bank_statement]