Skip to content

Commit 6b98eea

Browse files
chg ! use validate with choices when import instead of checkboxes
1 parent e5029d3 commit 6b98eea

File tree

9 files changed

+53
-49
lines changed

9 files changed

+53
-49
lines changed

src/country_workspace/contrib/aurora/forms.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
from country_workspace.contrib.aurora.models import Registration
66
from country_workspace.models import Program
7+
from country_workspace.workspaces.admin.forms import BaseImportForm
78

89

9-
class ImportAuroraForm(forms.Form):
10+
class ImportAuroraForm(BaseImportForm):
1011
batch_name = forms.CharField(required=False, help_text="Label for this batch.")
1112
registration = forms.ModelChoiceField(
1213
queryset=Registration.objects.none(),
@@ -24,12 +25,6 @@ class ImportAuroraForm(forms.Form):
2425
initial="family_name",
2526
help_text="Which Individual's column should be used as label for the household.",
2627
)
27-
check_before = forms.BooleanField(
28-
required=False, help_text="Prevent import if errors if data is not valid against data checker."
29-
)
30-
fail_if_alien = forms.BooleanField(
31-
required=False, help_text="Fails if it finds fields which do not exists in data checker."
32-
)
3328

3429
def __init__(self, *args: Any, program: Program | None = None, **kwargs: Any) -> None:
3530
super().__init__(*args, **kwargs)

src/country_workspace/contrib/aurora/pipeline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
from country_workspace.contrib.aurora.exceptions import TooManyBeneficiaryError
77
from country_workspace.models import AsyncJob, Batch, Household, Individual
88
from country_workspace.models.household import RELATIONSHIP_HEAD, RELATIONSHIP_FIELDNAME
9-
from country_workspace.utils.config import BatchNameConfig, FailIfAlienConfig
9+
from country_workspace.utils.config import BatchNameConfig, ValidateModeConfig
1010
from country_workspace.utils.fields import clean_field_names
1111
from country_workspace.validators.beneficiaries import validate_beneficiaries
1212

1313

14-
class Config(BatchNameConfig, FailIfAlienConfig):
14+
class Config(BatchNameConfig, ValidateModeConfig):
1515
registration_reference_pk: str | None
1616
master_detail: bool
1717
household_column_prefix: NotRequired[str]

src/country_workspace/contrib/kobo/forms.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,17 @@
33
from django import forms
44

55
from country_workspace.contrib.kobo.sync import make_client
6+
from country_workspace.workspaces.admin.forms import BaseImportForm
67

78

8-
class ImportKoboForm(forms.Form):
9+
class ImportKoboForm(BaseImportForm):
910
batch_name = forms.CharField(required=False, help_text="Label for this batch")
1011
project_id = forms.ChoiceField(required=True, choices=(), help_text="Select a project")
1112
individual_records_field = forms.CharField(
1213
required=False,
1314
initial="individual_questions",
1415
help_text="Which field contains individual records",
1516
)
16-
check_before = forms.BooleanField(
17-
required=False, help_text="Prevent import if errors if data is not valid against data checker."
18-
)
19-
fail_if_alien = forms.BooleanField(
20-
required=False, help_text="Fails if it finds fields which do not exists in data checker."
21-
)
2217

2318
def __init__(self, *args: Any, kobo_country_code: str | None, **kwargs: Any) -> None:
2419
super().__init__(*args, **kwargs)

src/country_workspace/contrib/kobo/sync.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
from country_workspace.contrib.kobo.api.data.submission import Submission
1515
from country_workspace.contrib.kobo.models import KoboSubmission
1616
from country_workspace.models import AsyncJob, Batch, Household, Individual
17-
from country_workspace.utils.config import BatchNameConfig, FailIfAlienConfig
17+
from country_workspace.utils.config import BatchNameConfig, ValidateModeConfig
1818
from country_workspace.utils.fields import clean_field_names, TO_UPPERCASE_FIELDS
1919
from country_workspace.utils.functional import compose
2020

2121

22-
class Config(BatchNameConfig, FailIfAlienConfig):
22+
class Config(BatchNameConfig, ValidateModeConfig):
2323
project_id: str
2424
individual_records_field: str
2525

src/country_workspace/datasources/rdi.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from country_workspace.contrib.kobo.api.data.helpers import VALUE_FORMAT
1515
from country_workspace.models import AsyncJob, Batch, Household, Individual
16-
from country_workspace.utils.config import BatchNameConfig, FailIfAlienConfig
16+
from country_workspace.utils.config import BatchNameConfig, ValidateModeConfig
1717
from country_workspace.utils.fields import Record, clean_field_names
1818
from country_workspace.utils.functional import compose
1919
from country_workspace.validators.beneficiaries import validate_beneficiaries
@@ -30,7 +30,7 @@
3030
PEOPLE = "people"
3131

3232

33-
class Config(BatchNameConfig, FailIfAlienConfig):
33+
class Config(BatchNameConfig, ValidateModeConfig):
3434
master_detail: bool
3535
household_pk_col: NotRequired[str]
3636
master_column_label: NotRequired[str]
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
from typing import TypedDict
2+
from country_workspace.workspaces.admin.forms import ValidateMode
23

34

45
class BatchNameConfig(TypedDict):
56
batch_name: str
67

78

8-
class CheckBeforeConfig(TypedDict):
9-
check_before: bool
10-
11-
12-
class FailIfAlienConfig(CheckBeforeConfig):
13-
fail_if_alien: bool
9+
class ValidateModeConfig(TypedDict):
10+
validate_mode: ValidateMode

src/country_workspace/validators/beneficiaries.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
from country_workspace.workspaces.exceptions import BeneficiaryValidationError
33
from country_workspace.utils.types import T_Beneficiary
44

5-
from country_workspace.utils.config import FailIfAlienConfig
5+
from country_workspace.utils.config import ValidateModeConfig
6+
from country_workspace.workspaces.admin.forms import ValidateMode
67

78

8-
def validate_beneficiaries(config: FailIfAlienConfig, beneficiary_mapping: Mapping[int, T_Beneficiary]) -> None:
9-
if config.get("check_before", False):
10-
for key, beneficiary in beneficiary_mapping.items():
11-
if not beneficiary.validate_with_checker(fail_if_alien=config.get("fail_if_alien", False)):
12-
raise BeneficiaryValidationError(beneficiary._meta.object_name, key)
9+
def validate_beneficiaries(config: ValidateModeConfig, beneficiary_mapping: Mapping[int, T_Beneficiary]) -> None:
10+
mode = ValidateMode(config["validate_mode"])
11+
if mode is ValidateMode.NONE:
12+
return
13+
14+
fail_if_alien = mode is ValidateMode.CHECK_AND_FAIL_IF_ALIEN
15+
for key, beneficiary in beneficiary_mapping.items():
16+
if not beneficiary.validate_with_checker(fail_if_alien=fail_if_alien):
17+
raise BeneficiaryValidationError(beneficiary._meta.object_name, key)

src/country_workspace/workspaces/admin/forms.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from typing import TYPE_CHECKING, Any
22

33
from django import forms
4+
from django.db.models import TextChoices
5+
from django.utils.translation import gettext_lazy as _
46

57
from country_workspace.workspaces.admin.cleaners.base import BaseActionForm
68
from country_workspace.workspaces.validators import ValidatableFileValidator
@@ -34,41 +36,54 @@ class BulkUpdateImportForm(forms.Form):
3436
)
3537

3638

37-
class ImportFileForm(forms.Form):
39+
class ValidateMode(TextChoices):
40+
NONE = "none", _("Skip validation — import data as is")
41+
CHECK_BEFORE = "check_before", _("Prevent import if data is not valid against data checker.")
42+
CHECK_AND_FAIL_IF_ALIEN = (
43+
"check_and_fail_if_alien",
44+
_("Prevent import if data is invalid AND fail if an alien field is found."),
45+
)
46+
47+
48+
class BaseImportForm(forms.Form):
3849
batch_name = forms.CharField(required=False, help_text="Label for this batch")
50+
validate_mode = forms.TypedChoiceField(
51+
choices=ValidateMode.choices,
52+
coerce=ValidateMode,
53+
empty_value=ValidateMode.CHECK_AND_FAIL_IF_ALIEN,
54+
initial=ValidateMode.CHECK_AND_FAIL_IF_ALIEN,
55+
required=True,
56+
help_text=_("How to validate data before import"),
57+
)
58+
3959

60+
class ImportFileForm(BaseImportForm):
4061
pk_column_name = forms.CharField(
4162
required=True,
4263
initial="household_id",
43-
help_text="Which column contains the unique identifier of the record.It is mandatory from Master/detail",
64+
help_text=_("Which column contains the unique identifier of the record. It is mandatory from Master/detail"),
4465
)
4566

4667
master_column_label = forms.CharField(
4768
required=False,
4869
initial="household_id",
49-
help_text="Which column contains the 'link' to the household record.",
70+
help_text=_("Which column contains the 'link' to the household record."),
5071
)
5172

5273
detail_column_label = forms.CharField(
5374
required=False,
5475
initial="household_id",
55-
help_text="Which column should be used as label for the household. It can use interpolation",
76+
help_text=_("Which column should be used as label for the household. It can use interpolation"),
5677
)
5778

5879
people_column_prefix = forms.CharField(
5980
required=False,
6081
initial="pp_",
61-
help_text="People' column group prefix",
82+
help_text=_("People' column group prefix"),
6283
)
6384

6485
first_line = forms.IntegerField(required=True, initial=0, help_text="First line to process")
6586

66-
check_before = forms.BooleanField(
67-
required=False, help_text="Prevent import if errors if data is not valid against data checker."
68-
)
69-
fail_if_alien = forms.BooleanField(
70-
required=False, help_text="Fails if it finds fields which do not exists in data checker."
71-
)
7287
file = forms.FileField(validators=[ValidatableFileValidator()])
7388

7489
def __init__(self, *args: Any, beneficiary_group: BeneficiaryGroup | None = None, **kwargs: Any) -> None:

src/country_workspace/workspaces/admin/program.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,8 @@ def import_rdi(self, request: HttpRequest, program: CountryProgram) -> "ImportFi
342342
master_detail := (program.beneficiary_group.master_detail if program.beneficiary_group else False)
343343
),
344344
"batch_name": form.cleaned_data["batch_name"] or batch_name_default(),
345+
"validate_mode": form.cleaned_data["validate_mode"],
345346
"first_line": form.cleaned_data["first_line"],
346-
"check_before": (check_before := form.cleaned_data.get("check_before", False)),
347-
"fail_if_alien": form.cleaned_data.get("fail_if_alien", False) if check_before else False,
348347
**(
349348
{
350349
"household_pk_col": form.cleaned_data.get("pk_column_name"),
@@ -376,13 +375,12 @@ def import_aurora(self, request: HttpRequest, program: "CountryProgram") -> "Imp
376375
if form.is_valid():
377376
config: AuroraConfig = {
378377
"batch_name": form.cleaned_data["batch_name"] or batch_name_default(),
378+
"validate_mode": form.cleaned_data["validate_mode"],
379379
"registration_reference_pk": getattr(form.cleaned_data.get("registration"), "reference_pk", None),
380380
"individuals_column_prefix": form.cleaned_data["individuals_column_prefix"],
381381
"master_detail": (
382382
master_detail := (program.beneficiary_group.master_detail if program.beneficiary_group else False)
383383
),
384-
"check_before": (check_before := form.cleaned_data.get("check_before", False)),
385-
"fail_if_alien": form.cleaned_data.get("fail_if_alien", False) if check_before else False,
386384
**(
387385
{
388386
"household_column_prefix": form.cleaned_data.get("household_column_prefix"),
@@ -411,10 +409,9 @@ def import_kobo(self, request: HttpRequest, program: "CountryProgram") -> Import
411409
if form.is_valid():
412410
config: KoboConfig = {
413411
"batch_name": form.cleaned_data["batch_name"] or batch_name_default(),
412+
"validate_mode": form.cleaned_data["validate_mode"],
414413
"project_id": form.cleaned_data["project_id"],
415414
"individual_records_field": form.cleaned_data["individual_records_field"],
416-
"check_before": (check_before := form.cleaned_data.get("check_before", False)),
417-
"fail_if_alien": form.cleaned_data.get("fail_if_alien", False) if check_before else False,
418415
}
419416
job: AsyncJob = AsyncJob.objects.create(
420417
description=KOBO_IMPORT_JOB_DESCRIPTION.format(program_name=program.name),

0 commit comments

Comments
 (0)