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.

122 lines
4.8 KiB

  1. # -*- coding: utf-8 -*-
  2. '''
  3. Created on 09 Octobre 2016
  4. @author: Thibault Francois (thibault@françois.be)
  5. '''
  6. from StringIO import StringIO
  7. import csv
  8. import datetime
  9. import md5
  10. from openerp import models, _
  11. ACCOUNT = "Compte donneur d'ordre"
  12. CURRENCY = "Devise"
  13. DATE = "Date"
  14. AMOUNT = "Montant"
  15. COUNTERPART_NUMBER = "Compte contrepartie"
  16. COUNTERPART_NAME = "Contrepartie"
  17. COMMUNICATION = "Communication"
  18. TRANSACTION_TYPE = "Type d'op\xc3\xa9ration"
  19. class CodaBankStatementImport(models.TransientModel):
  20. _inherit = 'account.bank.statement.import'
  21. _date_format = "%d/%m/%Y"
  22. _decimal_sep = "."
  23. _csv_delimiter = ";"
  24. _csv_quote = '"'
  25. _header = ['Date', 'Montant', 'Devise', 'Contrepartie', 'Compte contrepartie', "Type d'op\xc3\xa9ration", 'Communication', "Compte donneur d'ordre"]
  26. def _generate_note_crelan(self, move):
  27. notes = []
  28. notes.append("%s: %s" % (_('Counter Party Name'), move[COUNTERPART_NAME]))
  29. notes.append("%s: %s" % (_('Counter Party Account'), move[COUNTERPART_NUMBER]))
  30. notes.append("%s: %s" % (_('Communication'), move[COMMUNICATION]))
  31. return '\n'.join(notes)
  32. def _get_move_value_crelan(self, move, sequence):
  33. move_data = {
  34. 'name': move[TRANSACTION_TYPE] + ": " + move[COMMUNICATION],
  35. 'note': self._generate_note_crelan(move),
  36. 'date': self._to_iso_date(move[DATE]),
  37. 'amount': float(move[AMOUNT]),
  38. 'account_number': move[COUNTERPART_NUMBER], #ok
  39. 'partner_name': move[COUNTERPART_NAME], #ok
  40. 'ref': move[DATE] + '-' + move[AMOUNT] + '-' + move[COUNTERPART_NUMBER] + '-' + move[COUNTERPART_NAME],
  41. 'sequence': sequence, #ok
  42. 'unique_import_id' : move[DATE] + '-' + move[AMOUNT] + '-' + move[COUNTERPART_NUMBER] + '-' + move[COUNTERPART_NAME] + '-' + md5.new(move[COMMUNICATION]).hexdigest()
  43. }
  44. return move_data
  45. def _get_statement_data_crelan(self, balance_start, balance_end, begin_date, end_date):
  46. statement_data = {
  47. 'name' : _("Bank Statement from %s to %s") % (begin_date, end_date),
  48. 'date' : self._to_iso_date(end_date),
  49. 'balance_start': balance_start, #ok
  50. 'balance_end_real' : balance_end, #ok
  51. 'transactions' : []
  52. }
  53. return statement_data
  54. def _get_acc_number_crelan(self, acc_number):
  55. #Check if we match the exact acc_number or the end of an acc number
  56. journal = self.env['account.journal'].search([('bank_acc_number', '=like', '%' + acc_number)])
  57. if not journal or len(journal) > 1: #if not found or ambiguious
  58. return acc_number
  59. return journal.bank_acc_number
  60. def _get_acc_balance_crelan(self, acc_number):
  61. if not self.init_balance == None:
  62. return self.init_balance
  63. journal = self.env['account.journal'].search([('bank_acc_number', '=like', '%' + acc_number)])
  64. if not journal or len(journal) > 1: #if not found or ambiguious
  65. self.init_balance = 0.0
  66. else:
  67. lang = self._context.get('lang', 'en_US')
  68. l = self.env['res.lang'].search([('code', '=', lang)])
  69. balance = journal.get_journal_dashboard_datas()['last_balance'][:-1]
  70. self.init_balance = float(balance.strip().replace(l.thousands_sep, '').replace(l.decimal_point, '.'))
  71. return self.init_balance
  72. def _to_iso_date(self, orig_date):
  73. date_obj = datetime.datetime.strptime(orig_date, self._date_format)
  74. return date_obj.strftime('%Y-%m-%d')
  75. def _parse_file(self, data_file):
  76. try:
  77. csv_file = StringIO(data_file)
  78. data = csv.DictReader(csv_file, delimiter=self._csv_delimiter, quotechar=self._csv_quote)
  79. if not data.fieldnames == self._header:
  80. raise ValueError()
  81. except ValueError:
  82. return super(CodaBankStatementImport, self)._parse_file(data_file)
  83. currency_code = False
  84. account_number = False
  85. self.init_balance = None
  86. begin_date = False
  87. end_date = False
  88. transactions = []
  89. i = 1
  90. sum_transaction = 0
  91. for statement in data:
  92. begin_date = begin_date or statement[DATE]
  93. end_date = statement[DATE]
  94. account_number = statement[ACCOUNT]
  95. balance = self._get_acc_balance_crelan(account_number)
  96. currency_code = statement[CURRENCY]
  97. transactions.append(self._get_move_value_crelan(statement, i))
  98. sum_transaction += float(statement[AMOUNT])
  99. i += 1
  100. stmt = self._get_statement_data_crelan(balance, balance+ sum_transaction, begin_date, end_date)
  101. stmt['transactions'] = transactions
  102. return currency_code, self._get_acc_number_crelan(account_number), [stmt]