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.

358 lines
13 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 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_original_currency_empty(self):
  206. journal = self.AccountJournal.create({
  207. 'name': 'Bank',
  208. 'type': 'bank',
  209. 'code': 'BANK',
  210. 'currency_id': self.currency_usd.id,
  211. })
  212. wizard = self.AccountBankStatementImport.with_context({
  213. 'journal_id': journal.id,
  214. }).create({
  215. 'filename': 'fixtures/original_currency_empty.csv',
  216. 'data_file': self._data_file(
  217. 'fixtures/original_currency_empty.csv',
  218. 'utf-8'
  219. ),
  220. 'sheet_mapping_id': self.sample_statement_map.id,
  221. })
  222. wizard.with_context({
  223. 'journal_id': journal.id,
  224. 'account_bank_statement_import_txt_xlsx_test': True,
  225. }).import_file()
  226. statement = self.AccountBankStatement.search([
  227. ('journal_id', '=', journal.id),
  228. ])
  229. self.assertEqual(len(statement), 1)
  230. self.assertEqual(len(statement.line_ids), 1)
  231. line = statement.line_ids
  232. self.assertFalse(line.currency_id)
  233. self.assertEqual(line.amount_currency, 0.0)
  234. def test_multi_currency(self):
  235. journal = self.AccountJournal.create({
  236. 'name': 'Bank',
  237. 'type': 'bank',
  238. 'code': 'BANK',
  239. 'currency_id': self.currency_usd.id,
  240. })
  241. statement_map = self.sample_statement_map.copy({
  242. 'currency_column': 'Currency',
  243. 'original_currency_column': None,
  244. 'original_amount_column': None,
  245. })
  246. wizard = self.AccountBankStatementImport.with_context({
  247. 'journal_id': journal.id,
  248. }).create({
  249. 'filename': 'fixtures/multi_currency.csv',
  250. 'data_file': self._data_file(
  251. 'fixtures/multi_currency.csv',
  252. 'utf-8'
  253. ),
  254. 'sheet_mapping_id': statement_map.id,
  255. })
  256. wizard.with_context({
  257. 'journal_id': journal.id,
  258. 'account_bank_statement_import_txt_xlsx_test': True,
  259. }).import_file()
  260. statement = self.AccountBankStatement.search([
  261. ('journal_id', '=', journal.id),
  262. ])
  263. self.assertEqual(len(statement), 1)
  264. self.assertEqual(len(statement.line_ids), 1)
  265. line = statement.line_ids
  266. self.assertFalse(line.currency_id)
  267. self.assertEqual(line.amount, -33.5)
  268. def test_balance(self):
  269. journal = self.AccountJournal.create({
  270. 'name': 'Bank',
  271. 'type': 'bank',
  272. 'code': 'BANK',
  273. 'currency_id': self.currency_usd.id,
  274. })
  275. statement_map = self.sample_statement_map.copy({
  276. 'balance_column': 'Balance',
  277. 'original_currency_column': None,
  278. 'original_amount_column': None,
  279. })
  280. wizard = self.AccountBankStatementImport.with_context({
  281. 'journal_id': journal.id,
  282. }).create({
  283. 'filename': 'fixtures/balance.csv',
  284. 'data_file': self._data_file(
  285. 'fixtures/balance.csv',
  286. 'utf-8'
  287. ),
  288. 'sheet_mapping_id': statement_map.id,
  289. })
  290. wizard.with_context({
  291. 'journal_id': journal.id,
  292. 'account_bank_statement_import_txt_xlsx_test': True,
  293. }).import_file()
  294. statement = self.AccountBankStatement.search([
  295. ('journal_id', '=', journal.id),
  296. ])
  297. self.assertEqual(len(statement), 1)
  298. self.assertEqual(len(statement.line_ids), 2)
  299. self.assertEqual(statement.balance_start, 10.0)
  300. self.assertEqual(statement.balance_end_real, 1510.0)
  301. self.assertEqual(statement.balance_end, 1510.0)
  302. def test_debit_credit(self):
  303. journal = self.AccountJournal.create({
  304. 'name': 'Bank',
  305. 'type': 'bank',
  306. 'code': 'BANK',
  307. 'currency_id': self.currency_usd.id,
  308. })
  309. statement_map = self.sample_statement_map.copy({
  310. 'balance_column': 'Balance',
  311. 'original_currency_column': None,
  312. 'original_amount_column': None,
  313. 'debit_credit_column': 'D/C',
  314. 'debit_value': 'D',
  315. 'credit_value': 'C',
  316. })
  317. wizard = self.AccountBankStatementImport.with_context({
  318. 'journal_id': journal.id,
  319. }).create({
  320. 'filename': 'fixtures/debit_credit.csv',
  321. 'data_file': self._data_file(
  322. 'fixtures/debit_credit.csv',
  323. 'utf-8'
  324. ),
  325. 'sheet_mapping_id': statement_map.id,
  326. })
  327. wizard.with_context({
  328. 'journal_id': journal.id,
  329. 'account_bank_statement_import_txt_xlsx_test': True,
  330. }).import_file()
  331. statement = self.AccountBankStatement.search([
  332. ('journal_id', '=', journal.id),
  333. ])
  334. self.assertEqual(len(statement), 1)
  335. self.assertEqual(len(statement.line_ids), 2)
  336. self.assertEqual(statement.balance_start, 10.0)
  337. self.assertEqual(statement.balance_end_real, 1510.0)
  338. self.assertEqual(statement.balance_end, 1510.0)