From d4a4fe3b2980f83c8bc8ff4aaff8b650193f045d Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Sun, 3 Sep 2023 11:07:52 +0200 Subject: [PATCH] [ADD] import analytic accounts (KOST1/2) --- .../examples/datev_export.csv | 4 +- .../tests/test_datev_import_csv_dtvf.py | 18 +++++ datev_import_csv_dtvf/wizard/import_move.py | 69 ++++++++++++++++++- 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/datev_import_csv_dtvf/examples/datev_export.csv b/datev_import_csv_dtvf/examples/datev_export.csv index 2f5c69c9..510af6f4 100644 --- a/datev_import_csv_dtvf/examples/datev_export.csv +++ b/datev_import_csv_dtvf/examples/datev_export.csv @@ -1,6 +1,6 @@ EXTF,700,22,Buchungsstapel,12,20230417083808874,,,,,12345,1234,20220101,4,20221201,20221231,Buchungsstapel 20220101,MM,1,,,EUR,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -Umsatz (ohne Soll/Haben-Kz),Soll/Haben-Kennzeichen,WKZ Umsatz,Kurs,Basis-Umsatz,WKZ Basis-Umsatz,Konto,Gegenkonto (ohne BU-Schlüssel),BU-Schlüssel,Belegdatum,Belegfeld 1,Belegfeld 2,Skonto,Buchungstext,Postensperre,Diverse Adressnummer,Geschäftspartnerbank,Sachverhalt,Zinssperre,Beleglink,Beleginfo - Art 1,Beleginfo - Inhalt 1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -"0,01",H,,,,,4900,1588,,3112,MISC/2022/12/990001,,,Buchungsstapel 20220101,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,0,JA,2123e4a7-c837-4c0a-93e7-b66f59f5facc,,,0,,,,,,,,1,,,,1,,,,0 +Umsatz (ohne Soll/Haben-Kz),Soll/Haben-Kennzeichen,WKZ Umsatz,Kurs,Basis-Umsatz,WKZ Basis-Umsatz,Konto,Gegenkonto (ohne BU-Schlüssel),BU-Schlüssel,Belegdatum,Belegfeld 1,Belegfeld 2,Skonto,Buchungstext,Postensperre,Diverse Adressnummer,Geschäftspartnerbank,Sachverhalt,Zinssperre,Beleglink,Beleginfo - Art 1,Beleginfo - Inhalt 1,Beleginfo - Art 2,Beleginfo - Inhalt 2,Beleginfo - Art 3,Beleginfo - Inhalt 3,Beleginfo - Art 4,Beleginfo - Inhalt 4,Beleginfo - Art 5,Beleginfo - Inhalt 5,Beleginfo - Art 6,Beleginfo - Inhalt 6,Beleginfo - Art 7,Beleginfo - Inhalt 7,Beleginfo - Art 8,Beleginfo - Inhalt 8,Kost1 - Kostenstelle,Kost2 - Kostenstelle,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"0,01",H,,,,,4900,1588,,3112,MISC/2022/12/990001,,,Buchungsstapel 20220101,,,,,,,,,,,,,,,,,,,,,,,4811,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,0,JA,2123e4a7-c837-4c0a-93e7-b66f59f5facc,,,0,,,,,,,,1,,,,1,,,,0 10000,H,,,,,1210,0731,,3112,MISC/2022/12/990002,,,Buchungsstapel 20220101,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,0,JA,b8353f4a-a980-4057-a169-60b07f2cab4a,,,0,,,,,,,,1,,,,0,,,,0 900,H,,,,,2735,0974,,3112,MISC/2022/12/990003,,,Buchungsstapel 20220101,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,0,JA,f9998b58-e899-4974-b472-766423f12aec,,,0,,,,,,,,1,,,,0,,,,0 10000,S,,,,,1202,0731,,3112,MISC/2022/12/990004,,,Buchungsstapel 20220101,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,,,,0,JA,201b0c44-0a7b-497a-898f-b44723ff4c5b,,,0,,,,,,,,1,,,,1,,,,0 diff --git a/datev_import_csv_dtvf/tests/test_datev_import_csv_dtvf.py b/datev_import_csv_dtvf/tests/test_datev_import_csv_dtvf.py index 4d60d894..d2261d74 100644 --- a/datev_import_csv_dtvf/tests/test_datev_import_csv_dtvf.py +++ b/datev_import_csv_dtvf/tests/test_datev_import_csv_dtvf.py @@ -87,6 +87,21 @@ def setUp(self): ) self.env["account.account"].search([("code", "=", "7095")]).code = "7095000" self.env["account.account"].search([("code", "=", "1700")]).code = "170" + for code in ("4811",): + if self.env["account.analytic.account"].search( + [ + ("code", "=", code), + ("company_id", "=", self.env.company.id), + ] + ): + continue + self.env["account.analytic.account"].create( + { + "name": code, + "code": code, + "plan_id": self.env.ref("analytic.analytic_plan_internal").id, + } + ) def test_wizard(self): wizard = self.env["account.move.import"].create( @@ -113,6 +128,9 @@ def test_wizard(self): last_line = move.line_ids[-1:] self.assertEqual(last_line.account_id.code, "2450") self.assertEqual(last_line.debit, 72) + analytic_lines = move.line_ids.mapped("analytic_line_ids") + self.assertEqual(len(analytic_lines), 2) + self.assertEqual(sum(analytic_lines.mapped("amount")), 0) def test_wizard_broken_file(self): wizard = self.env["account.move.import"].create( diff --git a/datev_import_csv_dtvf/wizard/import_move.py b/datev_import_csv_dtvf/wizard/import_move.py index b5209866..58fc01cf 100644 --- a/datev_import_csv_dtvf/wizard/import_move.py +++ b/datev_import_csv_dtvf/wizard/import_move.py @@ -129,6 +129,30 @@ def genericcsv2pivot(self, fileobj): "doc_field_2", "discount", "name", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "/", + "analytic_account_1", + "analytic_account_2", ] first_line = fileobj.readline().decode() dialect = unicodecsv.Sniffer().sniff(first_line) @@ -175,6 +199,8 @@ def genericcsv2pivot(self, fileobj): else self.force_move_ref, "indicator": l.get("indicator", "").upper(), "line": i, + "analytic_account_1": l["analytic_account_1"], + "analytic_account_2": l["analytic_account_2"], } res.append(vals) return res @@ -200,10 +226,21 @@ def create_moves_from_pivot(self, pivot, post=False): # noqa: C901 [("company_id", "=", company_id)], ["code"] ) } + # analytic account + analytic_speed_dict = { + ( + analytic_account["code"] or analytic_account["name"] + ).upper(): analytic_account["id"] + for analytic_account in self.env["account.analytic.account"].search_read( + [("company_id", "=", company_id)], ["code", "name"] + ) + } key2label = { "account": _("account codes"), "contra_account": _("contra account codes"), "journal": _("journal codes"), + "analytic_account_1": _("analytic account codes"), + "analytic_account_2": _("analytic account codes"), } errors = {"other": []} for key in key2label.keys(): @@ -231,7 +268,7 @@ def match_account(line, speed_dict, id_field, code_field): line[id_field] = account_id break if not line.get(id_field): - errors["account"].setdefault(line[code_field], []).append(l["line"]) + errors[code_field].setdefault(line[code_field], []).append(l["line"]) # MATCHES + CHECKS for l in pivot: # noqa: E741 @@ -271,6 +308,20 @@ def match_account(line, speed_dict, id_field, code_field): errors["other"].append( _("Line %(line)d: bad value for debit (%(debit)s).") % l ) + if l["analytic_account_1"]: + match_account( + l, + analytic_speed_dict, + "analytic_account_1_id", + "analytic_account_1", + ) + if l["analytic_account_2"]: + match_account( + l, + analytic_speed_dict, + "analytic_account_2_id", + "analytic_account_2", + ) # test that they don't have both a value # LIST OF ERRORS msg = "" @@ -383,6 +434,14 @@ def _prepare_move_line_01(self, pivot_line, sequence, indicator): "account_id": pivot_line["account_id"], "import_external_id": "%s-%s" % (sequence, pivot_line.get("line")), "indicator": indicator, + "analytic_distribution": { + pivot_line.get(analytic_account_id_field): 100.0 + for analytic_account_id_field in ( + "analytic_account_1_id", + "analytic_account_2_id", + ) + if pivot_line.get(analytic_account_id_field) + }, } ) return vals @@ -409,6 +468,14 @@ def _prepare_move_line_02(self, pivot_line, sequence, indicator): "account_id": pivot_line["contra_account_id"], "import_external_id": "%s-%s" % (sequence, pivot_line.get("line")), "indicator": indicator, + "analytic_distribution": { + pivot_line.get(analytic_account_id_field): 100.0 + for analytic_account_id_field in ( + "analytic_account_1_id", + "analytic_account_2_id", + ) + if pivot_line.get(analytic_account_id_field) + }, } ) return vals