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.

191 lines
6.4 KiB

  1. # Copyright 2019 ForgeFlow, S.L.
  2. # Copyright 2020 CorporateHub (https://corporatehub.eu)
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
  4. from odoo import api, fields, models, _
  5. from base64 import b64decode
  6. import json
  7. from os import path
  8. class AccountBankStatementImportSheetMappingWizard(models.TransientModel):
  9. _name = 'account.bank.statement.import.sheet.mapping.wizard'
  10. _description = 'Account Bank Statement Import Sheet Mapping Wizard'
  11. _inherit = ['multi.step.wizard.mixin']
  12. data_file = fields.Binary(
  13. string='Bank Statement File',
  14. required=True,
  15. )
  16. filename = fields.Char()
  17. header = fields.Char()
  18. file_encoding = fields.Selection(
  19. string='Encoding',
  20. selection=lambda self: self._selection_file_encoding(),
  21. )
  22. delimiter = fields.Selection(
  23. string='Delimiter',
  24. selection=lambda self: self._selection_delimiter(),
  25. )
  26. quotechar = fields.Char(
  27. string='Text qualifier',
  28. size=1,
  29. )
  30. timestamp_column = fields.Char(
  31. string='Timestamp column',
  32. )
  33. currency_column = fields.Char(
  34. string='Currency column',
  35. help=(
  36. 'In case statement is multi-currency, column to get currency of '
  37. 'transaction from'
  38. ),
  39. )
  40. amount_column = fields.Char(
  41. string='Amount column',
  42. help='Amount of transaction in journal\'s currency',
  43. )
  44. balance_column = fields.Char(
  45. string='Balance column',
  46. help='Balance after transaction in journal\'s currency',
  47. )
  48. original_currency_column = fields.Char(
  49. string='Original currency column',
  50. help=(
  51. 'In case statement provides original currency for transactions '
  52. 'with automatic currency conversion, column to get original '
  53. 'currency of transaction from'
  54. ),
  55. )
  56. original_amount_column = fields.Char(
  57. string='Original amount column',
  58. help=(
  59. 'In case statement provides original currency for transactions '
  60. 'with automatic currency conversion, column to get original '
  61. 'transaction amount in original transaction currency from'
  62. ),
  63. )
  64. debit_credit_column = fields.Char(
  65. string='Debit/credit column',
  66. help=(
  67. 'Some statement formats use absolute amount value and indicate sign'
  68. 'of the transaction by specifying if it was a debit or a credit one'
  69. ),
  70. )
  71. debit_value = fields.Char(
  72. string='Debit value',
  73. help='Value of debit/credit column that indicates if it\'s a debit',
  74. default='D',
  75. )
  76. credit_value = fields.Char(
  77. string='Credit value',
  78. help='Value of debit/credit column that indicates if it\'s a credit',
  79. default='C',
  80. )
  81. transaction_id_column = fields.Char(
  82. string='Unique transaction ID column',
  83. )
  84. description_column = fields.Char(
  85. string='Description column',
  86. )
  87. notes_column = fields.Char(
  88. string='Notes column',
  89. )
  90. reference_column = fields.Char(
  91. string='Reference column',
  92. )
  93. partner_name_column = fields.Char(
  94. string='Partner Name column',
  95. )
  96. bank_name_column = fields.Char(
  97. string='Bank Name column',
  98. help='Partner\'s bank',
  99. )
  100. bank_account_column = fields.Char(
  101. string='Bank Account column',
  102. help='Partner\'s bank account',
  103. )
  104. @api.model
  105. def _selection_file_encoding(self):
  106. return self.env['account.bank.statement.import.sheet.mapping']._fields[
  107. 'file_encoding'
  108. ].selection
  109. @api.model
  110. def _selection_delimiter(self):
  111. return self.env['account.bank.statement.import.sheet.mapping']._fields[
  112. 'delimiter'
  113. ].selection
  114. @api.onchange('data_file')
  115. def _onchange_data_file(self):
  116. Parser = self.env['account.bank.statement.import.sheet.parser']
  117. Mapping = self.env['account.bank.statement.import.sheet.mapping']
  118. if not self.data_file:
  119. return
  120. csv_options = {}
  121. if self.delimiter:
  122. csv_options['delimiter'] = \
  123. Mapping._decode_column_delimiter_character(self.delimiter)
  124. if self.quotechar:
  125. csv_options['quotechar'] = self.quotechar
  126. header = Parser.parse_header(
  127. b64decode(self.data_file),
  128. self.file_encoding,
  129. csv_options
  130. )
  131. self.header = json.dumps(header)
  132. @api.model
  133. def statement_columns(self):
  134. header = self.env.context.get('header')
  135. if not header:
  136. return []
  137. return [(x, x) for x in json.loads(header)]
  138. @api.multi
  139. def _get_mapping_values(self):
  140. """Hook for extension"""
  141. self.ensure_one()
  142. return {
  143. 'name': _('Mapping from %s') % path.basename(self.filename),
  144. 'float_thousands_sep': 'comma',
  145. 'float_decimal_sep': 'dot',
  146. 'file_encoding': self.file_encoding,
  147. 'delimiter': self.delimiter,
  148. 'quotechar': self.quotechar,
  149. 'timestamp_format': '%d/%m/%Y',
  150. 'timestamp_column': self.timestamp_column,
  151. 'currency_column': self.currency_column,
  152. 'amount_column': self.amount_column,
  153. 'balance_column': self.balance_column,
  154. 'original_currency_column': self.original_currency_column,
  155. 'original_amount_column': self.original_amount_column,
  156. 'debit_credit_column': self.debit_credit_column,
  157. 'debit_value': self.debit_value,
  158. 'credit_value': self.credit_value,
  159. 'transaction_id_column': self.transaction_id_column,
  160. 'description_column': self.description_column,
  161. 'notes_column': self.notes_column,
  162. 'reference_column': self.reference_column,
  163. 'partner_name_column': self.partner_name_column,
  164. 'bank_name_column': self.bank_name_column,
  165. 'bank_account_column': self.bank_account_column,
  166. }
  167. @api.multi
  168. def import_mapping(self):
  169. self.ensure_one()
  170. mapping = self.env['account.bank.statement.import.sheet.mapping']\
  171. .create(self._get_mapping_values())
  172. return {
  173. 'type': 'ir.actions.act_window',
  174. 'name': _('Imported Mapping'),
  175. 'res_model': 'account.bank.statement.import.sheet.mapping',
  176. 'res_id': mapping.id,
  177. 'view_mode': 'form',
  178. 'view_id': False,
  179. 'target': 'current',
  180. }