Skip to content

Commit 609fe78

Browse files
authored
Merge pull request #149 from unicef/feature/fieldsets-for-account-and-document
Add fieldsets for document and account
2 parents 26763e3 + 6873e0a commit 609fe78

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed

src/country_workspace/contrib/hope/apps.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.apps import AppConfig
22

33
from .geo import Admin1Choice, Admin2Choice, Admin3Choice, Admin4Choice, CountryChoice
4+
from .lookups import FinancialInstitutionChoice
45

56

67
class Config(AppConfig):
@@ -19,6 +20,7 @@ def ready(self) -> None:
1920
field_registry.register(Admin2Choice)
2021
field_registry.register(Admin3Choice)
2122
field_registry.register(Admin4Choice)
23+
field_registry.register(FinancialInstitutionChoice)
2224

2325
from country_workspace.contrib.hope.validators import FullHouseholdValidator
2426
from country_workspace.validators.registry import beneficiary_validator_registry

src/country_workspace/contrib/hope/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@
66
HOUSEHOLD_CHECKER_NAME: Final[str] = "HOPE Household core"
77
INDIVIDUAL_CHECKER_NAME: Final[str] = "HOPE Individual core"
88
PEOPLE_CHECKER_NAME: Final[str] = "HOPE People core"
9+
10+
DOCUMENT_FIELDSET_NAME = "HOPE Document"
11+
ACCOUNT_FIELDSET_NAME = "HOPE Account"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from typing import Any
2+
3+
from django import forms
4+
5+
from country_workspace.contrib.hope.geo import APIChoicesMixin
6+
7+
8+
class FinancialInstitutionChoice(APIChoicesMixin, forms.ChoiceField):
9+
path: str = "lookups/financial-institution"
10+
11+
def __init__(self, choices: list[tuple[str, str]] | None = None, **kwargs: Any) -> None:
12+
super().__init__(choices=choices or [], **kwargs)
13+
self.choices = self.get_choices()
14+
15+
def get_choices(self) -> list[tuple[str, str]]:
16+
data = self.fetch_api()
17+
return [
18+
(
19+
rec["id"],
20+
rec["name"],
21+
)
22+
for rec in data
23+
]
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Generated by HCW 0.1.0 on 2025 06 23 11:12:31
2+
from concurrency.utils import fqn
3+
from django.db import transaction
4+
from hope_flex_fields.models import Fieldset, DataChecker, DataCheckerFieldset, FieldDefinition
5+
from hope_flex_fields.registry import field_registry
6+
from hope_flex_fields.utils import get_kwargs_from_field_class, get_common_attrs
7+
from packaging.version import Version
8+
9+
from django import forms
10+
11+
from country_workspace.contrib.hope.constants import (
12+
INDIVIDUAL_CHECKER_NAME,
13+
DOCUMENT_FIELDSET_NAME,
14+
ACCOUNT_FIELDSET_NAME,
15+
)
16+
from country_workspace.contrib.hope.lookups import FinancialInstitutionChoice
17+
from country_workspace.utils.flex_fields import Base64ImageField
18+
19+
_script_for_version = Version("0.1.0")
20+
21+
22+
fields_to_remove = [
23+
("national_id_issuer", {"field_type": forms.CharField}, {}),
24+
("national_id_no", {"field_type": forms.CharField}, {}),
25+
("national_id_photo", {"field_type": forms.CharField}, {}),
26+
("phone_no", {"field_type": forms.CharField}, {}),
27+
]
28+
29+
document_fields = [
30+
("document_number", {"field_type": forms.CharField}, {}),
31+
("photo", {"field_type": Base64ImageField}, {}),
32+
("issuance_date", {"field_type": forms.DateField}, {}),
33+
("expiry_date", {"field_type": forms.DateField}, {}),
34+
("country", {"name": "CountryChoice"}, {}),
35+
]
36+
37+
account_fields = [
38+
("number", {"field_type": forms.CharField}, {}),
39+
("data", {"field_type": forms.JSONField}, {}),
40+
("unique_key", {"field_type": forms.CharField}, {}),
41+
("financial_institution", {"name": "FinancialInstitutionChoice"}, {}),
42+
]
43+
44+
45+
def remove_document_and_account_fields_from_individual_fieldset() -> None:
46+
fieldset = Fieldset.objects.get(name=INDIVIDUAL_CHECKER_NAME)
47+
for field_name, _, _ in fields_to_remove:
48+
fieldset.fields.get(name=field_name).delete()
49+
50+
51+
def add_document_and_account_fields_to_individual_fieldset() -> None:
52+
individual_fieldset, _ = Fieldset.objects.get_or_create(name=INDIVIDUAL_CHECKER_NAME)
53+
for field_name, field_def, field_attrs in fields_to_remove:
54+
individual_fieldset.fields.get_or_create(
55+
name=field_name,
56+
definition=FieldDefinition.objects.get(**field_def),
57+
defaults={"attrs": field_attrs or {}},
58+
)
59+
60+
61+
def add_financial_institution_field_definitions() -> None:
62+
field_registry.register(FinancialInstitutionChoice)
63+
FieldDefinition.objects.get_or_create(
64+
name=FinancialInstitutionChoice.__name__,
65+
field_type=fqn(FinancialInstitutionChoice),
66+
defaults={"attrs": get_kwargs_from_field_class(FinancialInstitutionChoice, get_common_attrs())},
67+
)
68+
69+
70+
def remove_financial_institution_field_definitions() -> None:
71+
FieldDefinition.objects.filter(
72+
name=FinancialInstitutionChoice.__name__,
73+
field_type=fqn(FinancialInstitutionChoice),
74+
).delete()
75+
76+
77+
def add_fields_to_fieldsets(fieldset: Fieldset, fields: list) -> None:
78+
for field_name, field_def, field_attrs in fields:
79+
fieldset.fields.get_or_create(
80+
name=field_name, definition=FieldDefinition.objects.get(**field_def), defaults={"attrs": field_attrs or {}}
81+
)
82+
83+
84+
def add_account_and_document_fieldsets() -> None:
85+
ind_datachecker = DataChecker.objects.get(name=INDIVIDUAL_CHECKER_NAME)
86+
87+
document_fieldset, _ = Fieldset.objects.get_or_create(name=DOCUMENT_FIELDSET_NAME)
88+
account_fieldset, _ = Fieldset.objects.get_or_create(name=ACCOUNT_FIELDSET_NAME)
89+
for fieldset, prefixes in (
90+
(document_fieldset, ("national_id__", "national_passport__")),
91+
(account_fieldset, ("phone__", "bank__")),
92+
):
93+
for prefix in prefixes:
94+
DataCheckerFieldset.objects.get_or_create(checker=ind_datachecker, fieldset=fieldset, prefix=prefix)
95+
96+
for fieldset, fields in ((document_fieldset, document_fields), (account_fieldset, account_fields)):
97+
add_fields_to_fieldsets(fieldset, fields)
98+
99+
100+
def remove_account_and_document_fieldsets() -> None:
101+
Fieldset.objects.filter(name__in=[DOCUMENT_FIELDSET_NAME, ACCOUNT_FIELDSET_NAME]).delete()
102+
103+
104+
def forward() -> None:
105+
with transaction.atomic():
106+
remove_document_and_account_fields_from_individual_fieldset()
107+
108+
add_financial_institution_field_definitions()
109+
110+
add_account_and_document_fieldsets()
111+
112+
113+
def backward() -> None:
114+
with transaction.atomic():
115+
remove_account_and_document_fieldsets()
116+
117+
remove_financial_institution_field_definitions()
118+
119+
add_document_and_account_fields_to_individual_fieldset()
120+
121+
122+
class Scripts:
123+
requires = []
124+
operations = [(forward, backward)]

0 commit comments

Comments
 (0)