diff --git a/account_statement_import_txt_xlsx/migrations/14.0.1.0.0/pre-migrate.py b/account_statement_import_txt_xlsx/migrations/14.0.1.0.0/pre-migrate.py deleted file mode 100644 index 6bef441e..00000000 --- a/account_statement_import_txt_xlsx/migrations/14.0.1.0.0/pre-migrate.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2021 Tecnativa - Carlos Roca -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from openupgradelib import openupgrade - -_model_renames = [ - ( - "account.bank.statement.import.sheet.mapping", - "account.statement.import.sheet.mapping", - ), - ( - "account.bank.statement.import.sheet.parser", - "account.statement.import.sheet.parser", - ), - ( - "account.bank.statement.import.sheet.mapping.wizard", - "account.statement.import.sheet.mapping.wizard", - ), -] - -_table_renames = [ - ( - "account_bank_statement_import_sheet_mapping", - "account_statement_import_sheet_mapping", - ), - ( - "account_bank_statement_import_sheet_parser", - "account_statement_import_sheet_parser", - ), - ( - "account_bank_statement_import_sheet_mapping_wizard", - "account_statement_import_sheet_mapping_wizard", - ), -] - - -@openupgrade.migrate() -def migrate(env, version): - openupgrade.rename_models(env.cr, _model_renames) - openupgrade.rename_tables(env.cr, _table_renames) diff --git a/account_statement_import_txt_xlsx/migrations/15.0.1.1.0/pre-migrate.py b/account_statement_import_txt_xlsx/migrations/15.0.1.1.0/pre-migrate.py new file mode 100644 index 00000000..e610de6f --- /dev/null +++ b/account_statement_import_txt_xlsx/migrations/15.0.1.1.0/pre-migrate.py @@ -0,0 +1,42 @@ +# Copyright 2022 AppsToGROW - Henrik Norlin +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +_fields_to_add = [ + ( + "amount_debit_column", + "account.statement.import.sheet.mapping", + "account_statement_import_sheet_mapping", + "char", + "varchar", + "account_statement_import_txt_xlsx", + ), + ( + "amount_credit_column", + "account.statement.import.sheet.mapping", + "account_statement_import_sheet_mapping", + "char", + "varchar", + "account_statement_import_txt_xlsx", + ), +] + + +def add_fields_and_drop_not_null(env): + cr = env.cr + sql_debit_exists = """SELECT count(id) FROM ir_model_fields + WHERE name = 'amount_debit_column' + AND model = 'account.statement.import.sheet.mapping';""" + cr.execute(sql_debit_exists) + if cr.fetchone()[0] > 0: + openupgrade.add_fields(env, _fields_to_add) + cr.execute( + """ALTER TABLE account_statement_import_sheet_mapping + ALTER COLUMN amount_column DROP NOT NULL;""" + ) + + +@openupgrade.migrate() +def migrate(env, version): + add_fields_and_drop_not_null(env) diff --git a/account_statement_import_txt_xlsx/models/account_statement_import_sheet_mapping.py b/account_statement_import_txt_xlsx/models/account_statement_import_sheet_mapping.py index 5a14e293..cd75449d 100644 --- a/account_statement_import_txt_xlsx/models/account_statement_import_sheet_mapping.py +++ b/account_statement_import_txt_xlsx/models/account_statement_import_sheet_mapping.py @@ -63,16 +63,15 @@ class AccountStatementImportSheetMapping(models.Model): ), ) amount_column = fields.Char( - required=True, help="Amount of transaction in journal's currency", ) - amount2_column = fields.Char( - string="Amount2 column", - help="Some statements have two amount columns, for IN and OUT", + amount_debit_column = fields.Char( + string="Debit amount column", + help="Debit amount of transaction in journal's currency", ) - amount2_reverse = fields.Boolean( - string="Amount2 reverse +/-", - help="If there are positive numbers for money going OUT, reverse +/-", + amount_credit_column = fields.Char( + string="Credit amount column", + help="Credit amount of transaction in journal's currency", ) balance_column = fields.Char( help="Balance after transaction in journal's currency", @@ -120,6 +119,19 @@ class AccountStatementImportSheetMapping(models.Model): help="Partner's bank account", ) + _sql_constraints = [ + ( + "check_amount_columns", + ( + "CHECK(" + "amount_column IS NULL " + "OR (amount_debit_column IS NULL AND amount_credit_column IS NULL)" + ")" + ), + "Use amount_column OR (amount_debit_column AND amount_credit_column).", + ), + ] + @api.onchange("float_thousands_sep") def onchange_thousands_separator(self): if "dot" == self.float_thousands_sep == self.float_decimal_sep: diff --git a/account_statement_import_txt_xlsx/models/account_statement_import_sheet_parser.py b/account_statement_import_txt_xlsx/models/account_statement_import_sheet_parser.py index df2bbffc..dd76c88f 100644 --- a/account_statement_import_txt_xlsx/models/account_statement_import_sheet_parser.py +++ b/account_statement_import_txt_xlsx/models/account_statement_import_sheet_parser.py @@ -112,9 +112,18 @@ class AccountStatementImportSheetParser(models.TransientModel): columns["currency_column"] = ( header.index(mapping.currency_column) if mapping.currency_column else None ) - columns["amount_column"] = header.index(mapping.amount_column) - columns["amount2_column"] = ( - header.index(mapping.amount2_column) if mapping.amount2_column else None + columns["amount_column"] = ( + header.index(mapping.amount_column) if mapping.amount_column else None + ) + columns["amount_debit_column"] = ( + header.index(mapping.amount_debit_column) + if mapping.amount_debit_column + else None + ) + columns["amount_credit_column"] = ( + header.index(mapping.amount_credit_column) + if mapping.amount_credit_column + else None ) columns["balance_column"] = ( header.index(mapping.balance_column) if mapping.balance_column else None @@ -192,13 +201,17 @@ class AccountStatementImportSheetParser(models.TransientModel): if columns["currency_column"] is not None else currency_code ) - factor = -1 if mapping["amount2_reverse"] else 1 - if values[columns["amount_column"]] in (False, "", "0.00"): - amount = values[columns["amount2_column"]] - amount = factor * self._parse_decimal(amount, mapping) - else: - amount = values[columns.get("amount_column")] - amount = self._parse_decimal(amount, mapping) + + def _decimal(column_name): + if columns[column_name]: + return self._parse_decimal(values[columns[column_name]], mapping) + + amount = _decimal("amount_column") + if not amount: + amount = abs(_decimal("amount_debit_column") or 0) + if not amount: + amount = -abs(_decimal("amount_credit_column") or 0) + balance = ( values[columns["balance_column"]] if columns["balance_column"] is not None diff --git a/account_statement_import_txt_xlsx/tests/fixtures/amount2.csv b/account_statement_import_txt_xlsx/tests/fixtures/amount2.csv deleted file mode 100644 index 9bff8eec..00000000 --- a/account_statement_import_txt_xlsx/tests/fixtures/amount2.csv +++ /dev/null @@ -1,3 +0,0 @@ -"Date","Label","Amount","Amount2","Balance","Partner Name","Bank Account" -"12/15/2018","Your best supplier","0.00","33.50","-23.50","John Doe","123456789" -"12/15/2018","Your payment","1,533.50","0.00","1,510.00","Azure Interior","" diff --git a/account_statement_import_txt_xlsx/tests/fixtures/debit_credit_amount.csv b/account_statement_import_txt_xlsx/tests/fixtures/debit_credit_amount.csv new file mode 100644 index 00000000..f7e8e75a --- /dev/null +++ b/account_statement_import_txt_xlsx/tests/fixtures/debit_credit_amount.csv @@ -0,0 +1,5 @@ +"Date","Label","Debit","Credit","Balance","Partner Name","Bank Account" +"12/15/2018","Credit 20.00","0.00","20.00","-10.00","John Doe","123456789" +"12/15/2018","Credit 13.50","0.00","-13.50","-23.50","John Doe","123456789" +"12/15/2018","Debit 33.50","-33.50","0.00","10.00","Azure Interior","" +"12/15/2018","Debit 1500","1,500.00","0.00","1,510.00","Azure Interior","" diff --git a/account_statement_import_txt_xlsx/tests/test_account_statement_import_txt_xlsx.py b/account_statement_import_txt_xlsx/tests/test_account_statement_import_txt_xlsx.py index 0a28dad9..90de8c68 100644 --- a/account_statement_import_txt_xlsx/tests/test_account_statement_import_txt_xlsx.py +++ b/account_statement_import_txt_xlsx/tests/test_account_statement_import_txt_xlsx.py @@ -364,7 +364,7 @@ class TestAccountBankStatementImportTxtXlsx(common.TransactionCase): self.assertEqual(statement.balance_end_real, 1510.0) self.assertEqual(statement.balance_end, 1510.0) - def test_amount2(self): + def test_debit_credit_amount(self): journal = self.AccountJournal.create( { "name": "Bank", @@ -376,17 +376,18 @@ class TestAccountBankStatementImportTxtXlsx(common.TransactionCase): ) statement_map = self.sample_statement_map.copy( { - "amount2_column": "Amount2", - "amount2_reverse": True, + "amount_debit_column": "Debit", + "amount_credit_column": "Credit", "balance_column": "Balance", + "amount_column": None, "original_currency_column": None, "original_amount_column": None, } ) - data = self._data_file("fixtures/amount2.csv", "utf-8") + data = self._data_file("fixtures/debit_credit_amount.csv", "utf-8") wizard = self.AccountStatementImport.with_context(journal_id=journal.id).create( { - "statement_filename": "fixtures/amount2.csv", + "statement_filename": "fixtures/debit_credit_amount.csv", "statement_file": data, "sheet_mapping_id": statement_map.id, } @@ -396,7 +397,7 @@ class TestAccountBankStatementImportTxtXlsx(common.TransactionCase): ).import_file_button() statement = self.AccountBankStatement.search([("journal_id", "=", journal.id)]) self.assertEqual(len(statement), 1) - self.assertEqual(len(statement.line_ids), 2) + self.assertEqual(len(statement.line_ids), 4) self.assertEqual(statement.balance_start, 10.0) self.assertEqual(statement.balance_end_real, 1510.0) self.assertEqual(statement.balance_end, 1510.0) diff --git a/account_statement_import_txt_xlsx/views/account_statement_import_sheet_mapping.xml b/account_statement_import_txt_xlsx/views/account_statement_import_sheet_mapping.xml index 9981063b..32409bb0 100644 --- a/account_statement_import_txt_xlsx/views/account_statement_import_sheet_mapping.xml +++ b/account_statement_import_txt_xlsx/views/account_statement_import_sheet_mapping.xml @@ -38,10 +38,6 @@ - - + + diff --git a/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.py b/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.py index 3b84ba94..d1314edb 100644 --- a/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.py +++ b/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.py @@ -42,13 +42,13 @@ class AccountStatementImportSheetMappingWizard(models.TransientModel): amount_column = fields.Char( help="Amount of transaction in journal's currency", ) - amount2_column = fields.Char( - string="Amount2 column", - help="Some statements have two amount columns, for IN and OUT", + amount_debit_column = fields.Char( + string="Debit amount column", + help="Debit amount of transaction in journal's currency", ) - amount2_reverse = fields.Boolean( - string="Amount2 reverse +/-", - help="If there are positive numbers for money going OUT, reverse +/-", + amount_credit_column = fields.Boolean( + string="Credit amount column", + help="Credit amount of transaction in journal's currency", ) balance_column = fields.Char( help="Balance after transaction in journal's currency", diff --git a/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.xml b/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.xml index 9ebadc38..dc5021a7 100644 --- a/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.xml +++ b/account_statement_import_txt_xlsx/wizards/account_statement_import_sheet_mapping_wizard.xml @@ -50,10 +50,15 @@ widget="dynamic_dropdown" values="statement_columns" context="{'header': header}" - attrs="{'required': [('state', '=', 'final')]}" /> +