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.

327 lines
12 KiB

  1. # Copyright 2019 ForgeFlow, S.L.
  2. # Copyright 2020 Brainbean Apps (https://brainbeanapps.com)
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
  4. from odoo import fields
  5. from odoo.exceptions import UserError
  6. from odoo.tests import common
  7. from base64 import b64encode
  8. from os import path
  9. class TestAccountBankStatementImportTxtXlsx(common.TransactionCase):
  10. def setUp(self):
  11. super().setUp()
  12. self.now = fields.Datetime.now()
  13. self.currency_eur = self.env.ref('base.EUR')
  14. self.currency_usd = self.env.ref('base.USD')
  15. self.sample_statement_map = self.env.ref(
  16. 'account_bank_statement_import_txt_xlsx.sample_statement_map'
  17. )
  18. self.AccountJournal = self.env['account.journal']
  19. self.AccountBankStatement = self.env['account.bank.statement']
  20. self.AccountBankStatementImport = self.env[
  21. 'account.bank.statement.import'
  22. ]
  23. self.AccountBankStatementImportSheetMapping = self.env[
  24. 'account.bank.statement.import.sheet.mapping'
  25. ]
  26. self.AccountBankStatementImportSheetMappingWizard = self.env[
  27. 'account.bank.statement.import.sheet.mapping.wizard'
  28. ]
  29. def _data_file(self, filename, encoding=None):
  30. mode = 'rt' if encoding else 'rb'
  31. with open(path.join(path.dirname(__file__), filename), mode) as file:
  32. data = file.read()
  33. if encoding:
  34. data = data.encode(encoding)
  35. return b64encode(data)
  36. def test_import_csv_file(self):
  37. journal = self.AccountJournal.create({
  38. 'name': 'Bank',
  39. 'type': 'bank',
  40. 'code': 'BANK',
  41. 'currency_id': self.currency_usd.id,
  42. })
  43. wizard = self.AccountBankStatementImport.with_context({
  44. 'journal_id': journal.id,
  45. }).create({
  46. 'filename': 'fixtures/sample_statement_en.csv',
  47. 'data_file': self._data_file(
  48. 'fixtures/sample_statement_en.csv',
  49. 'utf-8'
  50. ),
  51. 'sheet_mapping_id': self.sample_statement_map.id,
  52. })
  53. wizard.with_context({
  54. 'journal_id': journal.id,
  55. 'account_bank_statement_import_txt_xlsx_test': True,
  56. }).import_file()
  57. statement = self.AccountBankStatement.search([
  58. ('journal_id', '=', journal.id),
  59. ])
  60. self.assertEqual(len(statement), 1)
  61. self.assertEqual(len(statement.line_ids), 2)
  62. def test_import_empty_csv_file(self):
  63. journal = self.AccountJournal.create({
  64. 'name': 'Bank',
  65. 'type': 'bank',
  66. 'code': 'BANK',
  67. 'currency_id': self.currency_usd.id,
  68. })
  69. wizard = self.AccountBankStatementImport.with_context({
  70. 'journal_id': journal.id,
  71. }).create({
  72. 'filename': 'fixtures/empty_statement_en.csv',
  73. 'data_file': self._data_file(
  74. 'fixtures/empty_statement_en.csv',
  75. 'utf-8'
  76. ),
  77. 'sheet_mapping_id': self.sample_statement_map.id,
  78. })
  79. with self.assertRaises(UserError):
  80. wizard.with_context({
  81. 'journal_id': journal.id,
  82. 'account_bank_statement_import_txt_xlsx_test': True,
  83. }).import_file()
  84. statement = self.AccountBankStatement.search([
  85. ('journal_id', '=', journal.id),
  86. ])
  87. self.assertEqual(len(statement), 0)
  88. def test_import_xlsx_file(self):
  89. journal = self.AccountJournal.create({
  90. 'name': 'Bank',
  91. 'type': 'bank',
  92. 'code': 'BANK',
  93. 'currency_id': self.currency_usd.id,
  94. })
  95. wizard = self.AccountBankStatementImport.with_context({
  96. 'journal_id': journal.id,
  97. }).create({
  98. 'filename': 'fixtures/sample_statement_en.xlsx',
  99. 'data_file': self._data_file('fixtures/sample_statement_en.xlsx'),
  100. 'sheet_mapping_id': self.sample_statement_map.id,
  101. })
  102. wizard.with_context({
  103. 'journal_id': journal.id,
  104. 'account_bank_statement_import_txt_xlsx_test': True,
  105. }).import_file()
  106. statement = self.AccountBankStatement.search([
  107. ('journal_id', '=', journal.id),
  108. ])
  109. self.assertEqual(len(statement), 1)
  110. self.assertEqual(len(statement.line_ids), 2)
  111. def test_import_empty_xlsx_file(self):
  112. journal = self.AccountJournal.create({
  113. 'name': 'Bank',
  114. 'type': 'bank',
  115. 'code': 'BANK',
  116. 'currency_id': self.currency_usd.id,
  117. })
  118. wizard = self.AccountBankStatementImport.with_context({
  119. 'journal_id': journal.id,
  120. }).create({
  121. 'filename': 'fixtures/empty_statement_en.xlsx',
  122. 'data_file': self._data_file('fixtures/empty_statement_en.xlsx'),
  123. 'sheet_mapping_id': self.sample_statement_map.id,
  124. })
  125. with self.assertRaises(UserError):
  126. wizard.with_context({
  127. 'journal_id': journal.id,
  128. 'account_bank_statement_import_txt_xlsx_test': True,
  129. }).import_file()
  130. statement = self.AccountBankStatement.search([
  131. ('journal_id', '=', journal.id),
  132. ])
  133. self.assertEqual(len(statement), 0)
  134. def test_mapping_import_wizard_xlsx(self):
  135. with common.Form(
  136. self.AccountBankStatementImportSheetMappingWizard) as form:
  137. form.filename = 'fixtures/empty_statement_en.xlsx'
  138. form.data_file = self._data_file(
  139. 'fixtures/empty_statement_en.xlsx'
  140. )
  141. self.assertEqual(len(form.header), 90)
  142. self.assertEqual(
  143. len(
  144. self.AccountBankStatementImportSheetMappingWizard
  145. .with_context(
  146. header=form.header,
  147. ).statement_columns()
  148. ),
  149. 7
  150. )
  151. form.timestamp_column = 'Date'
  152. form.amount_column = 'Amount'
  153. wizard = form.save()
  154. wizard.import_mapping()
  155. def test_mapping_import_wizard_csv(self):
  156. with common.Form(
  157. self.AccountBankStatementImportSheetMappingWizard) as form:
  158. form.filename = 'fixtures/empty_statement_en.csv'
  159. form.data_file = self._data_file(
  160. 'fixtures/empty_statement_en.csv'
  161. )
  162. self.assertEqual(len(form.header), 90)
  163. self.assertEqual(
  164. len(
  165. self.AccountBankStatementImportSheetMappingWizard
  166. .with_context(
  167. header=form.header,
  168. ).statement_columns()
  169. ),
  170. 7
  171. )
  172. form.timestamp_column = 'Date'
  173. form.amount_column = 'Amount'
  174. wizard = form.save()
  175. wizard.import_mapping()
  176. def test_original_currency(self):
  177. journal = self.AccountJournal.create({
  178. 'name': 'Bank',
  179. 'type': 'bank',
  180. 'code': 'BANK',
  181. 'currency_id': self.currency_usd.id,
  182. })
  183. wizard = self.AccountBankStatementImport.with_context({
  184. 'journal_id': journal.id,
  185. }).create({
  186. 'filename': 'fixtures/original_currency.csv',
  187. 'data_file': self._data_file(
  188. 'fixtures/original_currency.csv',
  189. 'utf-8'
  190. ),
  191. 'sheet_mapping_id': self.sample_statement_map.id,
  192. })
  193. wizard.with_context({
  194. 'journal_id': journal.id,
  195. 'account_bank_statement_import_txt_xlsx_test': True,
  196. }).import_file()
  197. statement = self.AccountBankStatement.search([
  198. ('journal_id', '=', journal.id),
  199. ])
  200. self.assertEqual(len(statement), 1)
  201. self.assertEqual(len(statement.line_ids), 1)
  202. line = statement.line_ids
  203. self.assertEqual(line.currency_id, self.currency_eur)
  204. self.assertEqual(line.amount_currency, 1000.0)
  205. def test_multi_currency(self):
  206. journal = self.AccountJournal.create({
  207. 'name': 'Bank',
  208. 'type': 'bank',
  209. 'code': 'BANK',
  210. 'currency_id': self.currency_usd.id,
  211. })
  212. statement_map = self.sample_statement_map.copy({
  213. 'currency_column': 'Currency',
  214. 'original_currency_column': None,
  215. 'original_amount_column': None,
  216. })
  217. wizard = self.AccountBankStatementImport.with_context({
  218. 'journal_id': journal.id,
  219. }).create({
  220. 'filename': 'fixtures/multi_currency.csv',
  221. 'data_file': self._data_file(
  222. 'fixtures/multi_currency.csv',
  223. 'utf-8'
  224. ),
  225. 'sheet_mapping_id': statement_map.id,
  226. })
  227. wizard.with_context({
  228. 'journal_id': journal.id,
  229. 'account_bank_statement_import_txt_xlsx_test': True,
  230. }).import_file()
  231. statement = self.AccountBankStatement.search([
  232. ('journal_id', '=', journal.id),
  233. ])
  234. self.assertEqual(len(statement), 1)
  235. self.assertEqual(len(statement.line_ids), 1)
  236. line = statement.line_ids
  237. self.assertFalse(line.currency_id)
  238. self.assertEqual(line.amount, -33.5)
  239. def test_balance(self):
  240. journal = self.AccountJournal.create({
  241. 'name': 'Bank',
  242. 'type': 'bank',
  243. 'code': 'BANK',
  244. 'currency_id': self.currency_usd.id,
  245. })
  246. statement_map = self.sample_statement_map.copy({
  247. 'balance_column': 'Balance',
  248. 'original_currency_column': None,
  249. 'original_amount_column': None,
  250. })
  251. wizard = self.AccountBankStatementImport.with_context({
  252. 'journal_id': journal.id,
  253. }).create({
  254. 'filename': 'fixtures/balance.csv',
  255. 'data_file': self._data_file(
  256. 'fixtures/balance.csv',
  257. 'utf-8'
  258. ),
  259. 'sheet_mapping_id': statement_map.id,
  260. })
  261. wizard.with_context({
  262. 'journal_id': journal.id,
  263. 'account_bank_statement_import_txt_xlsx_test': True,
  264. }).import_file()
  265. statement = self.AccountBankStatement.search([
  266. ('journal_id', '=', journal.id),
  267. ])
  268. self.assertEqual(len(statement), 1)
  269. self.assertEqual(len(statement.line_ids), 2)
  270. self.assertEqual(statement.balance_start, 10.0)
  271. self.assertEqual(statement.balance_end_real, 1510.0)
  272. self.assertEqual(statement.balance_end, 1510.0)
  273. def test_debit_credit(self):
  274. journal = self.AccountJournal.create({
  275. 'name': 'Bank',
  276. 'type': 'bank',
  277. 'code': 'BANK',
  278. 'currency_id': self.currency_usd.id,
  279. })
  280. statement_map = self.sample_statement_map.copy({
  281. 'balance_column': 'Balance',
  282. 'original_currency_column': None,
  283. 'original_amount_column': None,
  284. 'debit_credit_column': 'D/C',
  285. 'debit_value': 'D',
  286. 'credit_value': 'C',
  287. })
  288. wizard = self.AccountBankStatementImport.with_context({
  289. 'journal_id': journal.id,
  290. }).create({
  291. 'filename': 'fixtures/debit_credit.csv',
  292. 'data_file': self._data_file(
  293. 'fixtures/debit_credit.csv',
  294. 'utf-8'
  295. ),
  296. 'sheet_mapping_id': statement_map.id,
  297. })
  298. wizard.with_context({
  299. 'journal_id': journal.id,
  300. 'account_bank_statement_import_txt_xlsx_test': True,
  301. }).import_file()
  302. statement = self.AccountBankStatement.search([
  303. ('journal_id', '=', journal.id),
  304. ])
  305. self.assertEqual(len(statement), 1)
  306. self.assertEqual(len(statement.line_ids), 2)
  307. self.assertEqual(statement.balance_start, 10.0)
  308. self.assertEqual(statement.balance_end_real, 1510.0)
  309. self.assertEqual(statement.balance_end, 1510.0)