diff --git a/sage_validation/file_validator/forms.py b/sage_validation/file_validator/forms.py index 641343486905b67a05afef718e921a95b03571b6..0e22efedb8e46f10a7bd5799f11702a555996ecc 100644 --- a/sage_validation/file_validator/forms.py +++ b/sage_validation/file_validator/forms.py @@ -7,7 +7,8 @@ from typing import ClassVar from django import forms from django.core.files.uploadedfile import UploadedFile -from sage_validation.file_validator.models import MeoCostCentres, MeoValidSageAccounts, XxData, MeoValidSuppliers +from sage_validation.file_validator.models import MeoCostCentres, MeoValidSageAccounts, XxData, MeoValidSuppliers, \ + MeoNominal class CSVUploadForm(forms.Form): @@ -72,7 +73,6 @@ class CSVUploadForm(forms.Form): self._validate_headers(fieldnames) error_list = [] - # Step 3: Validate 'Source' and 'SYSTraderTranType' values data = list(reader) error_list.extend(self._validate_source_and_trader_type(data)) error_list.extend(self._validate_nominal_analysis_account(data)) @@ -174,16 +174,16 @@ class CSVUploadForm(forms.Form): return errors - @staticmethod - def _validate_nc_cc_dep_combination_against_meo_sage_account(data: Iterable[dict]) -> list[str]: - """Validate that the combination of 'AccountCostCentre', 'AccountDepartment', and 'AccountNumber' exists in MEO. + + def _validate_nc_cc_dep_combination_against_meo_sage_account(self, data: Iterable[dict]) -> list[str]: + """Validate that all occurrences of 'NominalAnalysisNominalCostCentre/{N}', + 'NominalAnalysisNominalDepartment/{N}', and 'NominalAnalysisNominalAccountNumber/{N}' exist in MEO. Args: data (Iterable[dict]): The rows of data to validate. Returns: List[str]: A list of error messages, if any. - """ errors = [] @@ -195,34 +195,45 @@ class CSVUploadForm(forms.Form): obj.xx_value: (obj.project, obj.overhead) for obj in XxData.objects.using("meo").all() } + + fieldnames = list(data[0].keys()) + max_repeat = self._get_max_repeat(fieldnames, "NominalAnalysisNominalCostCentre") + for index, row in enumerate(data, start=1): - cc = row.get("NominalAnalysisNominalCostCentre/1") - dep = row.get("NominalAnalysisNominalDepartment/1") - nominal_account_name = row.get("NominalAnalysisNominalAccountNumber/1") + for repeat in range(1, max_repeat + 1): + cc_field = f"NominalAnalysisNominalCostCentre/{repeat}" + dep_field = f"NominalAnalysisNominalDepartment/{repeat}" + nominal_account_field = f"NominalAnalysisNominalAccountNumber/{repeat}" - if not cc or not dep or not nominal_account_name: - continue + cc = row.get(cc_field) + dep = row.get(dep_field) + nominal_account_name = row.get(nominal_account_field) - cc_type = cost_centre_map.get(cc) - if not cc_type: - errors.append(f"Row {index}: 'NominalAnalysisNominalCostCentre/1' ({cc}) is not a valid cost centre.") - continue + if not cc or not dep or not nominal_account_name: + continue - xx_data = xx_data_map.get(nominal_account_name) - if not xx_data: - errors.append( - f"Row {index}: 'NominalAnalysisNominalAccountNumber/1' ({nominal_account_name}) is not valid.") - continue + cc_type = cost_centre_map.get(cc) + if not cc_type: + errors.append(f"Row {index}: '{cc_field}' ({cc}) is not a valid cost centre.") + continue - nc = xx_data[0] if cc_type == "Project" else xx_data[1] + xx_data = xx_data_map.get(nominal_account_name) - if not MeoValidSageAccounts.objects.using("meo").filter( - account_cost_centre=cc, account_department=dep, account_number=nc - ).exists(): - errors.append( - f"Row {index}: The combination of 'NominalAnalysisNominalCostCentre/1' ({cc}), " - f"'NominalAnalysisNominalDepartment/1' ({dep}), and 'NominalAnalysisNominalAccountNumber/1' " - f"({nominal_account_name}) does not exist in MEO valid Sage accounts." - ) + if xx_data: + nc = xx_data[0] if cc_type == "Project" else xx_data[1] + elif MeoNominal.objects.using("meo").filter(nom=nominal_account_name).exists(): + nc = nominal_account_name + else: + errors.append(f"Row {index}: '{nominal_account_field}' ({nominal_account_name}) is not valid.") + continue + + if not MeoValidSageAccounts.objects.using("meo").filter( + account_cost_centre=cc, account_department=dep, account_number=nc + ).exists(): + errors.append( + f"Row {index}: The combination of '{cc_field}' ({cc}), " + f"'{dep_field}' ({dep}), and '{nominal_account_field}' " + f"({nominal_account_name}) does not exist in MEO valid Sage accounts." + ) return errors