diff --git a/budgetweb/__init__.py b/budgetweb/__init__.py index 8db4ea1..99597d1 100755 --- a/budgetweb/__init__.py +++ b/budgetweb/__init__.py @@ -1,4 +1,4 @@ -VERSION = (1, 2, 7) +VERSION = (1, 2, 8) def get_version(): diff --git a/budgetweb/management/commands/import_accounting.py b/budgetweb/management/commands/import_accounting.py index 43a55c5..cfeb9f0 100644 --- a/budgetweb/management/commands/import_accounting.py +++ b/budgetweb/management/commands/import_accounting.py @@ -12,6 +12,10 @@ def to_decimal(amount): return Decimal((amount.replace(' ', '').replace(',', '.')) or 0) +class RowError(Exception): + pass + + class Command(BaseCommand): help = 'Import the accounting' @@ -22,7 +26,7 @@ def handle(self, *args, **options): accountings = [] period = models.PeriodeBudget.active.first() - errors = [] + self.errors = [] # Structure du fichier : @@ -45,9 +49,9 @@ def handle(self, *args, **options): in structure_models.Structure.active.all()} pfis = {pfi.code: pfi for pfi in structure_models.PlanFinancement.active.all()} - dan = {an.code_nature_comptable: an for an + dan = {(an.code_nature_comptable, an.is_fleche): an for an in structure_models.NatureComptableDepense.active.all()} - ran = {an.code_nature_comptable: an for an + ran = {(an.code_nature_comptable, an.is_fleche): an for an in structure_models.NatureComptableRecette.active.all()} domains = {d.code: d for d in structure_models.DomaineFonctionnel.active.all()} @@ -58,50 +62,53 @@ def handle(self, *args, **options): with open(filename, encoding='iso-8859-1') as h: reader = csv.reader(h, delimiter=';', quotechar='"') for index, row in enumerate(reader): - self.row_errors = [] if index == 0: # Ignore header continue - (year, structure, pfi, accounting_type, enveloppe, nature, - domain, ae, cp, d_dc, ar, re, r_dc, commentary) = row - - if accounting_type.lower().startswith('d'): - # Dépense - model = models.Depense - nature = self.get_object(dan, nature, 'nature') - functional_domain = self.get_object( - domains, domain, 'domaine fonctionnel') - - amounts = { - 'montant_dc': to_decimal(d_dc), - 'montant_cp': to_decimal(cp), - 'montant_ae': to_decimal(ae), - 'naturecomptabledepense': nature, - 'domainefonctionnel': functional_domain, - } - else: - # Recette - model = models.Recette - nature = self.get_object(ran, nature, 'nature') - - amounts = { - 'montant_dc': to_decimal(r_dc), - 'montant_re': to_decimal(re), - 'montant_ar': to_decimal(ar), - 'naturecomptablerecette': nature, - 'domainefonctionnel': domain, - } - - accountings.append(model( - pfi=pfis[pfi], structure=structures[structure], - commentaire=commentary or None, - periodebudget=period, annee=year, **amounts)) - - errors.extend(self.row_errors) - - if errors: - print('ERRORS :\n\n{}'.format('\n'.join(errors))) + try: + (year, structure, pfi, accounting_type, enveloppe, nature, + domain, ae, cp, d_dc, ar, re, r_dc, commentary) = row + + pfi = self.get_object(pfis, pfi, 'PFI') + if accounting_type.lower().startswith('d'): + # Dépense + model = models.Depense + nature = self.get_object(dan, (nature, pfi.is_fleche), 'nature') + functional_domain = self.get_object( + domains, domain, 'domaine fonctionnel', msg=f'- nature : {nature}') + + amounts = { + 'montant_dc': to_decimal(d_dc), + 'montant_cp': to_decimal(cp), + 'montant_ae': to_decimal(ae), + 'naturecomptabledepense': nature, + 'domainefonctionnel': functional_domain, + } + else: + # Recette + model = models.Recette + nature = self.get_object(ran, (nature, pfi.is_fleche), 'nature') + + amounts = { + 'montant_dc': to_decimal(r_dc), + 'montant_re': to_decimal(re), + 'montant_ar': to_decimal(ar), + 'naturecomptablerecette': nature, + 'domainefonctionnel': domain, + } + + structure = self.get_object(structures, structure, 'structure') + accountings.append(model( + pfi=pfi, structure=structure, + commentaire=commentary or None, + periodebudget=period, annee=year, **amounts)) + + except RowError: + continue + + if self.errors: + print('ERRORS :\n\n{}'.format('\n'.join(self.errors))) else: sid = transaction.savepoint() try: @@ -114,8 +121,10 @@ def handle(self, *args, **options): else: transaction.savepoint_commit(sid) - def get_object(self, dict, key, name): + def get_object(self, dct, key, name, msg=''): try: - return dict[key] + return dct[key] except KeyError: - self.row_errors.append(f'{name.title()} "{key}" does not exist') + msg = '' or f' {msg}' + self.errors.append(f'{name.title()} "{key}" does not exist{msg}') + raise RowError