diff --git a/backend/.coveragerc b/backend/.coveragerc
index 4d67696f1d..d98484e597 100644
--- a/backend/.coveragerc
+++ b/backend/.coveragerc
@@ -1,7 +1,7 @@
[run]
branch = True
source = hct_mis_api
-concurrency=multiprocessing
+concurrency=multiprocessing,thread
omit =
*/selenium_tests/**
diff --git a/backend/hct_mis_api/apps/core/attributes_qet_queries.py b/backend/hct_mis_api/apps/core/attributes_qet_queries.py
index 31d1b4b4ae..08ef733ce3 100644
--- a/backend/hct_mis_api/apps/core/attributes_qet_queries.py
+++ b/backend/hct_mis_api/apps/core/attributes_qet_queries.py
@@ -23,17 +23,20 @@
logger = logging.getLogger(__name__)
-def age_to_birth_date_range_query(field_name: str, age_min: Optional[int], age_max: Optional[int]) -> Q:
+def age_to_birth_date_range_query(
+ field_name: str, age_min: Optional[int], age_max: Optional[int], is_social_worker_query: bool = False
+) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
query_dict = {}
current_date = dt.date.today()
if age_min is not None:
- query_dict[f"{field_name}__lte"] = current_date - relativedelta(years=+age_min)
+ query_dict[f"{lookup_prefix}{field_name}__lte"] = current_date - relativedelta(years=+age_min)
if age_max is not None:
- query_dict[f"{field_name}__gt"] = current_date - relativedelta(years=+age_max + 1)
+ query_dict[f"{lookup_prefix}{field_name}__gt"] = current_date - relativedelta(years=+age_max + 1)
return Q(**query_dict)
-def age_to_birth_date_query(comparison_method: str, args: Any) -> Q:
+def age_to_birth_date_query(comparison_method: str, args: Any, is_social_worker_query: bool = False) -> Q:
field_name = "birth_date"
comparison_method_args_count = {
"RANGE": 2,
@@ -51,132 +54,196 @@ def age_to_birth_date_query(comparison_method: str, args: Any) -> Q:
logger.error(f"Age {comparison_method} filter query expect {args_count} arguments")
raise ValidationError(f"Age {comparison_method} filter query expect {args_count} arguments")
if comparison_method == "RANGE":
- return age_to_birth_date_range_query(field_name, *args)
+ return age_to_birth_date_range_query(field_name, *args, is_social_worker_query=is_social_worker_query)
if comparison_method == "NOT_IN_RANGE":
- return ~(age_to_birth_date_range_query(field_name, *args))
+ return ~(age_to_birth_date_range_query(field_name, *args, is_social_worker_query=is_social_worker_query))
if comparison_method == "EQUALS":
- return age_to_birth_date_range_query(field_name, args[0], args[0])
+ return age_to_birth_date_range_query(
+ field_name, args[0], args[0], is_social_worker_query=is_social_worker_query
+ )
if comparison_method == "NOT_EQUALS":
- return ~(age_to_birth_date_range_query(field_name, args[0], args[0]))
+ return ~(
+ age_to_birth_date_range_query(field_name, args[0], args[0], is_social_worker_query=is_social_worker_query)
+ )
if comparison_method == "GREATER_THAN":
- return age_to_birth_date_range_query(field_name, args[0], None)
+ return age_to_birth_date_range_query(field_name, args[0], None, is_social_worker_query=is_social_worker_query)
if comparison_method == "LESS_THAN":
- return age_to_birth_date_range_query(field_name, None, args[0])
- logger.error(f"Age filter query don't supports {comparison_method} type")
- raise ValidationError(f"Age filter query don't supports {comparison_method} type")
+ return age_to_birth_date_range_query(field_name, None, args[0], is_social_worker_query=is_social_worker_query)
+ logger.error(f"Age filter query don't supports {comparison_method} type") # pragma: no cover
+ raise ValidationError(f"Age filter query don't supports {comparison_method} type") # pragma: no cover
-def get_birth_certificate_document_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query(IDENTIFICATION_TYPE_BIRTH_CERTIFICATE, args[0])
+def get_birth_certificate_document_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query(
+ IDENTIFICATION_TYPE_BIRTH_CERTIFICATE, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_tax_id_document_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query(IDENTIFICATION_TYPE_TAX_ID, args[0])
+def get_tax_id_document_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query(
+ IDENTIFICATION_TYPE_TAX_ID, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_drivers_license_document_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query(IDENTIFICATION_TYPE_DRIVERS_LICENSE, args[0])
+def get_drivers_license_document_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query(
+ IDENTIFICATION_TYPE_DRIVERS_LICENSE, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_national_id_document_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query(IDENTIFICATION_TYPE_NATIONAL_ID, args[0])
+def get_national_id_document_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query(
+ IDENTIFICATION_TYPE_NATIONAL_ID, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_national_passport_document_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query(IDENTIFICATION_TYPE_NATIONAL_PASSPORT, args[0])
+def get_national_passport_document_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query(
+ IDENTIFICATION_TYPE_NATIONAL_PASSPORT, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_electoral_card_document_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query(IDENTIFICATION_TYPE_ELECTORAL_CARD, args[0])
+def get_electoral_card_document_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query(
+ IDENTIFICATION_TYPE_ELECTORAL_CARD, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_other_document_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query(IDENTIFICATION_TYPE_OTHER, args[0])
+def get_other_document_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query(IDENTIFICATION_TYPE_OTHER, args[0], is_social_worker_query=is_social_worker_query)
-def get_documents_number_query(document_type: str, number: str) -> Q:
- return Q(documents__type__key=document_type.lower(), documents__document_number=number)
+def get_documents_number_query(document_type: str, number: str, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return Q(
+ **{
+ f"{lookup_prefix}documents__type__key": document_type.lower(),
+ f"{lookup_prefix}documents__document_number": number,
+ }
+ )
-def get_birth_certificate_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query(IDENTIFICATION_TYPE_BIRTH_CERTIFICATE, args[0])
+def get_birth_certificate_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query(
+ IDENTIFICATION_TYPE_BIRTH_CERTIFICATE, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_tax_id_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query(IDENTIFICATION_TYPE_TAX_ID, args[0])
+def get_tax_id_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query(
+ IDENTIFICATION_TYPE_TAX_ID, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_drivers_licensee_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query(IDENTIFICATION_TYPE_DRIVERS_LICENSE, args[0])
+def get_drivers_licensee_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query(
+ IDENTIFICATION_TYPE_DRIVERS_LICENSE, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_national_id_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query(IDENTIFICATION_TYPE_NATIONAL_ID, args[0])
+def get_national_id_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query(
+ IDENTIFICATION_TYPE_NATIONAL_ID, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_national_passport_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query(IDENTIFICATION_TYPE_NATIONAL_PASSPORT, args[0])
+def get_national_passport_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query(
+ IDENTIFICATION_TYPE_NATIONAL_PASSPORT, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_electoral_card_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query(IDENTIFICATION_TYPE_ELECTORAL_CARD, args[0])
+def get_electoral_card_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query(
+ IDENTIFICATION_TYPE_ELECTORAL_CARD, args[0], is_social_worker_query=is_social_worker_query
+ )
-def get_other_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query(IDENTIFICATION_TYPE_OTHER, args[0])
+def get_other_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query(IDENTIFICATION_TYPE_OTHER, args[0], is_social_worker_query=is_social_worker_query)
-def get_documents_issuer_query(document_type: str, country_alpha3: str) -> Q:
- return Q(documents__type__type=document_type, documents__type__country__iso_code3=country_alpha3)
+def get_documents_issuer_query(document_type: str, country_alpha3: str, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return Q(
+ **{
+ f"{lookup_prefix}documents__type__type": document_type,
+ f"{lookup_prefix}documents__type__country__iso_code3": country_alpha3,
+ }
+ )
-def get_role_query(_: Any, args: Any) -> Q:
- return Q(households_and_roles__role=args[0])
+def get_role_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return Q(**{f"{lookup_prefix}households_and_roles__role": args[0]})
-def get_scope_id_number_query(_: Any, args: Any) -> Q:
- return Q(identities__partner__name=WFP, identities__number=args[0])
+def get_scope_id_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return Q(**{f"{lookup_prefix}identities__partner__name": WFP, f"{lookup_prefix}identities__number": args[0]})
-def get_scope_id_issuer_query(_: Any, args: Any) -> Q:
- return Q(identities__partner__name=WFP, identities__country__iso_code3=args[0])
+def get_scope_id_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return Q(
+ **{f"{lookup_prefix}identities__partner__name": WFP, f"{lookup_prefix}identities__country__iso_code3": args[0]}
+ )
-def get_unhcr_id_number_query(_: Any, args: Any) -> Q:
- return Q(identities__partner__name=UNHCR, identities__number=args[0])
+def get_unhcr_id_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return Q(**{f"{lookup_prefix}identities__partner__name": UNHCR, f"{lookup_prefix}identities__number": args[0]})
-def get_unhcr_id_issuer_query(_: Any, args: Any) -> Q:
- return Q(identities__partner__name=UNHCR, identities__country__iso_code3=args[0])
+def get_unhcr_id_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return Q(
+ **{
+ f"{lookup_prefix}identities__partner__name": UNHCR,
+ f"{lookup_prefix}identities__country__iso_code3": args[0],
+ }
+ )
-def get_receiver_poi_number_query(_: Any, args: Any) -> Q:
- return get_documents_number_query("receiver_poi", args[0])
+def get_receiver_poi_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_number_query("receiver_poi", args[0], is_social_worker_query=is_social_worker_query)
-def get_receiver_poi_issuer_query(_: Any, args: Any) -> Q:
- return get_documents_issuer_query("receiver_poi", args[0])
+def get_receiver_poi_issuer_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
+ return get_documents_issuer_query("receiver_poi", args[0], is_social_worker_query=is_social_worker_query)
-def get_has_phone_number_query(_: Any, args: Any) -> Q:
+def get_has_phone_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
has_phone_no = args[0] in [True, "True"]
- return ~Q(phone_no="") if has_phone_no else Q(phone_no="")
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return ~Q(**{f"{lookup_prefix}phone_no": ""}) if has_phone_no else Q(**{f"{lookup_prefix}phone_no": ""})
-def get_has_bank_account_number_query(_: Any, args: Any) -> Q:
+def get_has_bank_account_number_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
has_bank_account_number = args[0] in [True, "True"]
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
if has_bank_account_number: # Individual can have related object bank_account, but empty number
- return Q(bank_account_info__isnull=False) & ~Q(bank_account_info__bank_account_number="")
- return Q(bank_account_info__isnull=True) | Q(bank_account_info__bank_account_number="")
+ return Q(**{f"{lookup_prefix}bank_account_info__isnull": False}) & ~Q(
+ **{f"{lookup_prefix}bank_account_info__bank_account_number": ""}
+ )
+ return Q(**{f"{lookup_prefix}bank_account_info__isnull": True}) | Q(
+ **{f"{lookup_prefix}bank_account_info__bank_account_number": ""}
+ )
-def get_has_tax_id_query(_: Any, args: Any) -> Q:
+def get_has_tax_id_query(_: Any, args: Any, is_social_worker_query: bool = False) -> Q:
has_tax_id = args[0] in [True, "True"]
- return Q(documents__type__key__iexact="TAX_ID") if has_tax_id else ~Q(documents__type__key__iexact="TAX_ID")
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ return (
+ Q(**{f"{lookup_prefix}documents__type__key__iexact": "TAX_ID"})
+ if has_tax_id
+ else ~Q(**{f"{lookup_prefix}documents__type__key__iexact": "TAX_ID"})
+ )
-def country_generic_query(comparison_method: str, args: Any, lookup: Any) -> Q:
- query = Q(**{lookup: Countries.get_country_value(args[0])})
+def country_generic_query(comparison_method: str, args: Any, lookup: Any, is_social_worker_query: bool = False) -> Q:
+ lookup_prefix = "individuals__" if is_social_worker_query else ""
+ query = Q(**{lookup_prefix + lookup: Countries.get_country_value(args[0])})
if comparison_method == "EQUALS":
return query
elif comparison_method == "NOT_EQUALS":
@@ -185,15 +252,17 @@ def country_generic_query(comparison_method: str, args: Any, lookup: Any) -> Q:
raise ValidationError(f"Country filter query does not support {comparison_method} type")
-def country_query(comparison_method: str, args: Any) -> Q:
- return country_generic_query(comparison_method, args, "country")
+def country_query(comparison_method: str, args: Any, is_social_worker_query: bool = False) -> Q:
+ return country_generic_query(comparison_method, args, "country", is_social_worker_query=is_social_worker_query)
-def country_origin_query(comparison_method: str, args: Any) -> Q:
- return country_generic_query(comparison_method, args, "country_origin")
+def country_origin_query(comparison_method: str, args: Any, is_social_worker_query: bool = False) -> Q:
+ return country_generic_query(
+ comparison_method, args, "country_origin", is_social_worker_query=is_social_worker_query
+ )
-def registration_data_import_query(comparison_method: str, args: Any) -> Q:
+def registration_data_import_query(comparison_method: str, args: Any, is_social_worker_query: bool = False) -> Q:
from django.db.models import Q
return Q(registration_data_import__pk__in=args)
diff --git a/backend/hct_mis_api/apps/core/field_attributes/core_fields_attributes.py b/backend/hct_mis_api/apps/core/field_attributes/core_fields_attributes.py
index 0083f07b55..a962eea72b 100644
--- a/backend/hct_mis_api/apps/core/field_attributes/core_fields_attributes.py
+++ b/backend/hct_mis_api/apps/core/field_attributes/core_fields_attributes.py
@@ -1837,7 +1837,7 @@ def __init__(
super().__init__(*args, **kwargs)
self.scopes: Iterable = scopes or set()
if fields:
- self.extend(fields)
+ self.extend(copy.deepcopy(fields))
self.all_fields = copy.deepcopy(CORE_FIELDS_ATTRIBUTES)
def extend(self, __iterable: Iterable[dict]) -> None:
@@ -1865,11 +1865,22 @@ def _fill_label_template(self, field: dict, language: str = "English(EN)") -> Op
def from_scopes(cls, scopes: list[Scope]) -> "FieldFactory":
factory = cls()
all_fields = copy.deepcopy(factory.all_fields)
+ factory.scopes.update(scopes)
factory.extend(filter(lambda field: any(True for scope in scopes if scope in field["scope"]), all_fields))
if Scope.XLSX_PEOPLE in scopes:
for field_attr in factory:
field_attr["xlsx_field"] = "pp_" + field_attr["xlsx_field"].replace("_h_c", "_i_c")
+ return factory
+
+ @classmethod
+ def from_only_scopes(cls, scopes: list[Scope]) -> "FieldFactory":
+ factory = cls()
+ all_fields = copy.deepcopy(factory.all_fields)
factory.scopes.update(scopes)
+ factory.extend(filter(lambda field: all(scope in field["scope"] for scope in scopes), all_fields))
+ if Scope.XLSX_PEOPLE in scopes:
+ for field_attr in factory:
+ field_attr["xlsx_field"] = "pp_" + field_attr["xlsx_field"].replace("_h_c", "_i_c")
return factory
@classmethod
diff --git a/backend/hct_mis_api/apps/core/fixtures/data.json b/backend/hct_mis_api/apps/core/fixtures/data.json
index 34ad4dd8fa..955bf89f87 100644
--- a/backend/hct_mis_api/apps/core/fixtures/data.json
+++ b/backend/hct_mis_api/apps/core/fixtures/data.json
@@ -6681,8 +6681,8 @@
"description": "Partial individuals collected (Social Worker)",
"type": "SOCIAL",
"active": true,
- "individual_filters_available": false,
- "household_filters_available": true,
+ "individual_filters_available": true,
+ "household_filters_available": false,
"compatible_types": [2, 3],
"limit_to": ["c259b1a0-ae3a-494e-b343-f7c8eb060c68", "3e269a73-123b-43e1-86af-ced1b30d8e80"]
}
diff --git a/backend/hct_mis_api/apps/core/schema.py b/backend/hct_mis_api/apps/core/schema.py
index 19818984b2..4f16a34435 100644
--- a/backend/hct_mis_api/apps/core/schema.py
+++ b/backend/hct_mis_api/apps/core/schema.py
@@ -39,6 +39,7 @@
FlexibleAttributeGroup,
)
from hct_mis_api.apps.core.utils import decode_id_string
+from hct_mis_api.apps.program.models import Program
if TYPE_CHECKING:
from django.db.models.query import QuerySet
@@ -268,9 +269,14 @@ def get_fields_attr_generators(
if flex_field is not False:
yield from FlexibleAttribute.objects.order_by("created_at")
if flex_field is not True:
- yield from FieldFactory.from_scope(Scope.TARGETING).filtered_by_types(FILTERABLE_TYPES).apply_business_area(
- business_area_slug=business_area_slug, program_id=program_id
- )
+ if program_id and Program.objects.get(id=program_id).is_social_worker_program:
+ yield from FieldFactory.from_only_scopes([Scope.XLSX_PEOPLE, Scope.TARGETING]).filtered_by_types(
+ FILTERABLE_TYPES
+ ).apply_business_area(business_area_slug=business_area_slug, program_id=program_id)
+ else:
+ yield from FieldFactory.from_scope(Scope.TARGETING).filtered_by_types(FILTERABLE_TYPES).apply_business_area(
+ business_area_slug=business_area_slug, program_id=program_id
+ )
def resolve_asset(business_area_slug: str, uid: str) -> Dict:
diff --git a/backend/hct_mis_api/apps/core/tests/test_attributes_get_queries.py b/backend/hct_mis_api/apps/core/tests/test_attributes_get_queries.py
new file mode 100644
index 0000000000..61f6bd1eae
--- /dev/null
+++ b/backend/hct_mis_api/apps/core/tests/test_attributes_get_queries.py
@@ -0,0 +1,334 @@
+import datetime as dt
+
+from django.core.exceptions import ValidationError
+from django.db.models import Q
+
+from dateutil.relativedelta import relativedelta
+
+from hct_mis_api.apps.core.attributes_qet_queries import (
+ age_to_birth_date_query,
+ age_to_birth_date_range_query,
+ country_origin_query,
+ country_query,
+ get_birth_certificate_document_number_query,
+ get_birth_certificate_issuer_query,
+ get_documents_issuer_query,
+ get_drivers_license_document_number_query,
+ get_drivers_licensee_issuer_query,
+ get_electoral_card_document_number_query,
+ get_electoral_card_issuer_query,
+ get_has_bank_account_number_query,
+ get_has_phone_number_query,
+ get_has_tax_id_query,
+ get_national_id_document_number_query,
+ get_national_id_issuer_query,
+ get_national_passport_document_number_query,
+ get_national_passport_issuer_query,
+ get_other_document_number_query,
+ get_other_issuer_query,
+ get_receiver_poi_issuer_query,
+ get_receiver_poi_number_query,
+ get_role_query,
+ get_scope_id_issuer_query,
+ get_scope_id_number_query,
+ get_tax_id_document_number_query,
+ get_tax_id_issuer_query,
+ get_unhcr_id_issuer_query,
+ get_unhcr_id_number_query,
+ registration_data_import_query,
+)
+from hct_mis_api.apps.core.base_test_case import APITestCase
+from hct_mis_api.apps.core.countries import Countries
+from hct_mis_api.apps.household.models import UNHCR, WFP
+
+
+class TestAttributesGetQueries(APITestCase):
+ def setUp(self) -> None:
+ self.today = dt.date.today()
+ self.social_worker_prefix = "individuals__"
+ super().setUp()
+
+ def test_age_to_birth_date_range_query_min_only(self) -> None:
+ q = age_to_birth_date_range_query("birth_date", 30, None)
+ expected_date = self.today - relativedelta(years=30)
+ self.assertEqual(q, Q(birth_date__lte=expected_date))
+
+ def test_age_to_birth_date_range_query_max_only(self) -> None:
+ q = age_to_birth_date_range_query("birth_date", None, 20)
+ expected_date = self.today - relativedelta(years=21)
+ self.assertEqual(q, Q(birth_date__gt=expected_date))
+
+ def test_age_to_birth_date_range_query_min_and_max(self) -> None:
+ q = age_to_birth_date_range_query("birth_date", 25, 35)
+ expected_min_date = self.today - relativedelta(years=25)
+ expected_max_date = self.today - relativedelta(years=36)
+ self.assertEqual(q, Q(birth_date__lte=expected_min_date, birth_date__gt=expected_max_date))
+
+ def test_age_to_birth_date_query_equals(self) -> None:
+ q = age_to_birth_date_query("EQUALS", [30])
+ expected_date = self.today - relativedelta(years=30)
+ print("*" * 399)
+ print(q)
+ print(Q(birth_date__lte=expected_date, birth_date__gt=expected_date - relativedelta(years=1)))
+ self.assertEqual(q, Q(birth_date__lte=expected_date, birth_date__gt=expected_date - relativedelta(years=1)))
+
+ def test_age_to_birth_date_query_not_equals(self) -> None:
+ q = age_to_birth_date_query("NOT_EQUALS", [30])
+ expected_date = self.today - relativedelta(years=30)
+ self.assertEqual(q, ~(Q(birth_date__lte=expected_date, birth_date__gt=expected_date - relativedelta(years=1))))
+
+ def test_age_to_birth_date_query_range(self) -> None:
+ q = age_to_birth_date_query("RANGE", [20, 30])
+ expected_min_date = self.today - relativedelta(years=20)
+ expected_max_date = self.today - relativedelta(years=31)
+ self.assertEqual(q, Q(birth_date__lte=expected_min_date, birth_date__gt=expected_max_date))
+
+ def test_age_to_birth_date_query_not_in_range(self) -> None:
+ q = age_to_birth_date_query("NOT_IN_RANGE", [20, 30])
+ expected_min_date = self.today - relativedelta(years=20)
+ expected_max_date = self.today - relativedelta(years=31)
+ self.assertEqual(q, ~(Q(birth_date__lte=expected_min_date, birth_date__gt=expected_max_date)))
+
+ def test_age_to_birth_date_query_greater_than(self) -> None:
+ q = age_to_birth_date_query("GREATER_THAN", [25])
+ expected_min_date = self.today - relativedelta(years=25)
+ self.assertEqual(q, Q(birth_date__lte=expected_min_date))
+
+ def test_age_to_birth_date_query_less_than(self) -> None:
+ q = age_to_birth_date_query("LESS_THAN", [25])
+ expected_max_date = self.today - relativedelta(years=26)
+ self.assertEqual(q, Q(birth_date__gt=expected_max_date))
+
+ def test_invalid_comparison_method(self) -> None:
+ with self.assertRaises(ValidationError):
+ age_to_birth_date_query("INVALID_METHOD", [25])
+
+ def test_incorrect_argument_count(self) -> None:
+ with self.assertRaises(ValidationError):
+ age_to_birth_date_query("EQUALS", [])
+
+ def test_country_query_equals(self) -> None:
+ q = country_query("EQUALS", ["USA"])
+ self.assertEqual(q, Q(country=Countries.get_country_value("USA")))
+
+ def test_country_query_not_equals(self) -> None:
+ q = country_query("NOT_EQUALS", ["USA"])
+ self.assertEqual(q, ~Q(country=Countries.get_country_value("USA")))
+
+ def test_registration_data_import_query(self) -> None:
+ q = registration_data_import_query("EQUALS", [1, 2, 3])
+ self.assertEqual(q, Q(registration_data_import__pk__in=[1, 2, 3]))
+
+ def test_invalid_country_comparison_method(self) -> None:
+ with self.assertRaises(ValidationError):
+ country_query("INVALID_METHOD", ["USA"])
+
+ def test_get_has_phone_number_query_true(self) -> None:
+ q = get_has_phone_number_query(None, [True])
+ self.assertEqual(q, ~Q(phone_no=""))
+
+ def test_get_has_phone_number_query_false(self) -> None:
+ q = get_has_phone_number_query(None, [False])
+ self.assertEqual(q, Q(phone_no=""))
+
+ def test_get_birth_certificate_document_number_query(self) -> None:
+ q = get_birth_certificate_document_number_query(None, ["1234"])
+ self.assertEqual(q, Q(documents__type__key="birth_certificate", documents__document_number="1234"))
+
+ def test_get_tax_id_document_number_query(self) -> None:
+ q = get_tax_id_document_number_query(None, ["5678"])
+ self.assertEqual(q, Q(documents__type__key="tax_id", documents__document_number="5678"))
+
+ def test_get_drivers_license_document_number_query(self) -> None:
+ q = get_drivers_license_document_number_query(None, ["ABCD"])
+ self.assertEqual(q, Q(documents__type__key="drivers_license", documents__document_number="ABCD"))
+
+ def test_get_national_id_document_number_query(self) -> None:
+ q = get_national_id_document_number_query(None, ["EFGH"])
+ self.assertEqual(q, Q(documents__type__key="national_id", documents__document_number="EFGH"))
+
+ def test_get_national_passport_document_number_query(self) -> None:
+ q = get_national_passport_document_number_query(None, ["IJKL"])
+ self.assertEqual(q, Q(documents__type__key="national_passport", documents__document_number="IJKL"))
+
+ def test_get_electoral_card_document_number_query(self) -> None:
+ q = get_electoral_card_document_number_query(None, ["MNOP"])
+ self.assertEqual(q, Q(documents__type__key="electoral_card", documents__document_number="MNOP"))
+
+ def test_get_other_document_number_query(self) -> None:
+ q = get_other_document_number_query(None, ["QRST"])
+ self.assertEqual(q, Q(documents__type__key="other", documents__document_number="QRST"))
+
+ def test_get_has_bank_account_number_query_true(self) -> None:
+ # Test for individuals who have a bank account number
+ expected_query = Q(bank_account_info__isnull=False) & ~Q(bank_account_info__bank_account_number="")
+ result = get_has_bank_account_number_query(None, [True])
+ self.assertEqual(result, expected_query)
+
+ def test_get_has_bank_account_number_query_false(self) -> None:
+ # Test for individuals who do not have a bank account number
+ expected_query = Q(bank_account_info__isnull=True) | Q(bank_account_info__bank_account_number="")
+ result = get_has_bank_account_number_query(None, [False])
+ self.assertEqual(result, expected_query)
+
+ def test_get_has_bank_account_number_query_social_worker_true(self) -> None:
+ # Test with social worker prefix for individuals who have a bank account number
+ expected_query = Q(individuals__bank_account_info__isnull=False) & ~Q(
+ individuals__bank_account_info__bank_account_number=""
+ )
+ result = get_has_bank_account_number_query(None, [True], is_social_worker_query=True)
+ self.assertEqual(result, expected_query)
+
+ def test_get_has_bank_account_number_query_social_worker_false(self) -> None:
+ # Test with social worker prefix for individuals who do not have a bank account number
+ expected_query = Q(individuals__bank_account_info__isnull=True) | Q(
+ individuals__bank_account_info__bank_account_number=""
+ )
+ result = get_has_bank_account_number_query(None, [False], is_social_worker_query=True)
+ self.assertEqual(result, expected_query)
+
+ def test_get_has_tax_id_query_true(self) -> None:
+ # Test for individuals who have a tax ID
+ expected_query = Q(documents__type__key__iexact="TAX_ID")
+ result = get_has_tax_id_query(None, [True])
+ self.assertEqual(result, expected_query)
+
+ def test_get_has_tax_id_query_false(self) -> None:
+ # Test for individuals who do not have a tax ID
+ expected_query = ~Q(documents__type__key__iexact="TAX_ID")
+ result = get_has_tax_id_query(None, [False])
+ self.assertEqual(result, expected_query)
+
+ def test_get_has_tax_id_query_social_worker_true(self) -> None:
+ # Test with social worker prefix for individuals who have a tax ID
+ expected_query = Q(individuals__documents__type__key__iexact="TAX_ID")
+ result = get_has_tax_id_query(None, [True], is_social_worker_query=True)
+ self.assertEqual(result, expected_query)
+
+ def test_get_has_tax_id_query_social_worker_false(self) -> None:
+ # Test with social worker prefix for individuals who do not have a tax ID
+ expected_query = ~Q(individuals__documents__type__key__iexact="TAX_ID")
+ result = get_has_tax_id_query(None, [False], is_social_worker_query=True)
+ self.assertEqual(result, expected_query)
+
+ def test_get_role_query(self) -> None:
+ # Without social worker prefix
+ expected = Q(households_and_roles__role="manager")
+ result = get_role_query(None, ["manager"])
+ self.assertEqual(result, expected)
+
+ # With social worker prefix
+ expected = Q(individuals__households_and_roles__role="manager")
+ result = get_role_query(None, ["manager"], True)
+ self.assertEqual(result, expected)
+
+ def test_get_scope_id_number_query(self) -> None:
+ # Without social worker prefix
+ expected = Q(identities__partner__name=WFP, identities__number="123456")
+ result = get_scope_id_number_query(None, ["123456"])
+ self.assertEqual(result, expected)
+
+ # With social worker prefix
+ expected = Q(individuals__identities__partner__name=WFP, individuals__identities__number="123456")
+ result = get_scope_id_number_query(None, ["123456"], True)
+ self.assertEqual(result, expected)
+
+ def test_get_scope_id_issuer_query(self) -> None:
+ # Without social worker prefix
+ expected = Q(identities__partner__name=WFP, identities__country__iso_code3="KEN")
+ result = get_scope_id_issuer_query(None, ["KEN"])
+ self.assertEqual(result, expected)
+
+ # With social worker prefix
+ expected = Q(individuals__identities__partner__name=WFP, individuals__identities__country__iso_code3="KEN")
+ result = get_scope_id_issuer_query(None, ["KEN"], True)
+ self.assertEqual(result, expected)
+
+ def test_get_unhcr_id_number_query(self) -> None:
+ # Without social worker prefix
+ expected = Q(identities__partner__name=UNHCR, identities__number="987654")
+ result = get_unhcr_id_number_query(None, ["987654"])
+ self.assertEqual(result, expected)
+
+ # With social worker prefix
+ expected = Q(individuals__identities__partner__name=UNHCR, individuals__identities__number="987654")
+ result = get_unhcr_id_number_query(None, ["987654"], True)
+ self.assertEqual(result, expected)
+
+ def test_get_unhcr_id_issuer_query(self) -> None:
+ # Without social worker prefix
+ expected = Q(identities__partner__name=UNHCR, identities__country__iso_code3="UGA")
+ result = get_unhcr_id_issuer_query(None, ["UGA"])
+ self.assertEqual(result, expected)
+
+ expected = Q(individuals__identities__partner__name=UNHCR, individuals__identities__country__iso_code3="UGA")
+ result = get_unhcr_id_issuer_query(None, ["UGA"], True)
+ self.assertEqual(result, expected)
+
+ def test_get_national_id_issuer_query(self) -> None:
+ expected = Q(documents__type__type="NATIONAL_ID", documents__type__country__iso_code3="USA")
+ result = get_national_id_issuer_query(None, ["USA"])
+ self.assertEqual(result, expected)
+
+ def test_get_national_passport_issuer_query(self) -> None:
+ expected = Q(documents__type__type="NATIONAL_PASSPORT", documents__type__country__iso_code3="GBR")
+ result = get_national_passport_issuer_query(None, ["GBR"])
+ self.assertEqual(result, expected)
+
+ def test_get_electoral_card_issuer_query(self) -> None:
+ expected = Q(documents__type__type="ELECTORAL_CARD", documents__type__country__iso_code3="IND")
+ result = get_electoral_card_issuer_query(None, ["IND"])
+ self.assertEqual(result, expected)
+
+ def test_get_documents_issuer_query(self) -> None:
+ expected = Q(documents__type__type="GENERIC_TYPE", documents__type__country__iso_code3="FRA")
+ result = get_documents_issuer_query("GENERIC_TYPE", "FRA")
+ self.assertEqual(result, expected)
+
+ def test_get_receiver_poi_number_query(self) -> None:
+ expected = Q(documents__type__key="receiver_poi", documents__document_number="12345")
+ result = get_receiver_poi_number_query(None, ["12345"])
+ self.assertEqual(result, expected)
+
+ def test_get_receiver_poi_issuer_query(self) -> None:
+ expected = Q(documents__type__type="receiver_poi", documents__type__country__iso_code3="CAN")
+ result = get_receiver_poi_issuer_query(None, ["CAN"])
+ self.assertEqual(result, expected)
+
+ def test_country_origin_query_equals(self) -> None:
+ expected = Q(individuals__country_origin="CA")
+ result = country_origin_query("EQUALS", ["CAN"], is_social_worker_query=True)
+ self.assertEqual(result, expected)
+
+ def test_country_origin_query_not_equals(self) -> None:
+ expected = ~Q(individuals__country_origin="CA")
+ result = country_origin_query("NOT_EQUALS", ["CAN"], is_social_worker_query=True)
+ self.assertEqual(result, expected)
+
+ def test_invalid_country_origin_comparison(self) -> None:
+ with self.assertRaises(ValidationError):
+ country_origin_query("INVALID", ["CAN"], is_social_worker_query=True)
+
+ def test_get_birth_certificate_issuer_query(self) -> None:
+ country_code = "USA"
+ result = get_birth_certificate_issuer_query(None, [country_code])
+ expected = Q(documents__type__type="BIRTH_CERTIFICATE", documents__type__country__iso_code3=country_code)
+ self.assertEqual(result, expected)
+
+ def test_get_tax_id_issuer_query(self) -> None:
+ country_code = "GBR"
+ result = get_tax_id_issuer_query(None, [country_code])
+ expected = Q(documents__type__type="TAX_ID", documents__type__country__iso_code3=country_code)
+ self.assertEqual(result, expected)
+
+ def test_get_drivers_licensee_issuer_query(self) -> None:
+ country_code = "CAN"
+ result = get_drivers_licensee_issuer_query(None, [country_code])
+ expected = Q(documents__type__type="DRIVERS_LICENSE", documents__type__country__iso_code3=country_code)
+ self.assertEqual(result, expected)
+
+ def test_get_other_issuer_query(self) -> None:
+ country_code = "AUS"
+ result = get_other_issuer_query(None, [country_code])
+ expected = Q(documents__type__type="OTHER", documents__type__country__iso_code3=country_code)
+ self.assertEqual(result, expected)
diff --git a/backend/hct_mis_api/apps/core/tests/test_core_fields.py b/backend/hct_mis_api/apps/core/tests/test_core_fields.py
index 998490a239..5c12eac968 100644
--- a/backend/hct_mis_api/apps/core/tests/test_core_fields.py
+++ b/backend/hct_mis_api/apps/core/tests/test_core_fields.py
@@ -1,10 +1,89 @@
+from unittest.mock import patch
+
from hct_mis_api.apps.core.base_test_case import APITestCase
from hct_mis_api.apps.core.field_attributes.core_fields_attributes import (
CORE_FIELDS_ATTRIBUTES,
+ FieldFactory,
)
+from hct_mis_api.apps.core.field_attributes.fields_types import TYPE_STRING, Scope
class TestCoreFields(APITestCase):
+
+ def setUp(self) -> None:
+ self.scopes = [Scope.GLOBAL, Scope.XLSX_PEOPLE]
+ super().setUp()
+
def test_all_fields_have_lookup(self) -> None:
for field in CORE_FIELDS_ATTRIBUTES:
self.assertTrue(field.get("lookup"), f'{field.get("name")} does not have a lookup')
+
+ @patch(
+ "hct_mis_api.apps.core.field_attributes.core_fields_attributes.CORE_FIELDS_ATTRIBUTES",
+ [
+ {
+ "id": "b1f90314-b8b8-4bcb-9265-9d48d1fce5a4",
+ "type": TYPE_STRING,
+ "name": "given_name",
+ "lookup": "given_name",
+ "required": False,
+ "label": {"English(EN)": "Given name"},
+ "hint": "",
+ "choices": [],
+ "associated_with": "individual",
+ "xlsx_field": "given_name_i_c",
+ "scope": [Scope.GLOBAL, Scope.TARGETING, Scope.KOBO_IMPORT, Scope.INDIVIDUAL_UPDATE, Scope.XLSX_PEOPLE],
+ },
+ {
+ "id": "b1f90314-b8b8-4bcb-9265-9d48d1fce524",
+ "type": TYPE_STRING,
+ "name": "given_name1",
+ "lookup": "given_name1",
+ "required": False,
+ "label": {"English(EN)": "Given name1"},
+ "hint": "",
+ "choices": [],
+ "associated_with": "individual",
+ "xlsx_field": "given_name1_i_c",
+ "scope": [Scope.GLOBAL, Scope.TARGETING, Scope.KOBO_IMPORT, Scope.INDIVIDUAL_UPDATE],
+ },
+ {
+ "id": "36ab3421-6e7a-40d1-b816-ea5cbdcc0b6a",
+ "type": TYPE_STRING,
+ "name": "full_name",
+ "lookup": "full_name",
+ "required": True,
+ "label": {"English(EN)": "Full name"},
+ "hint": "",
+ "choices": [],
+ "associated_with": "individual",
+ "xlsx_field": "full_name_i_c",
+ "scope": [Scope.GLOBAL, Scope.XLSX_PEOPLE],
+ },
+ ],
+ )
+ def test_xlsx_people_scope_filtering(self) -> None:
+ factory_result = FieldFactory.from_only_scopes(self.scopes)
+ self.assertEqual(len(factory_result), 2)
+
+ @patch(
+ "hct_mis_api.apps.core.field_attributes.core_fields_attributes.CORE_FIELDS_ATTRIBUTES",
+ [
+ {
+ "id": "b1f90314-b8b8-4bcb-9265-9d48d1fce5a4",
+ "type": TYPE_STRING,
+ "name": "given_name",
+ "lookup": "given_name",
+ "required": False,
+ "label": {"English(EN)": "Given name"},
+ "hint": "",
+ "choices": [],
+ "associated_with": "individual",
+ "xlsx_field": "given_name_i_c",
+ "scope": [Scope.GLOBAL, Scope.TARGETING, Scope.KOBO_IMPORT, Scope.INDIVIDUAL_UPDATE, Scope.XLSX_PEOPLE],
+ }
+ ],
+ )
+ def test_xlsx_people_scope_modification(self) -> None:
+ factory_result = FieldFactory.from_only_scopes(self.scopes)
+ self.assertEqual(factory_result[0]["xlsx_field"], "pp_given_name_i_c")
diff --git a/backend/hct_mis_api/apps/household/fixtures.py b/backend/hct_mis_api/apps/household/fixtures.py
index 48ef3dee00..dbcfee845f 100644
--- a/backend/hct_mis_api/apps/household/fixtures.py
+++ b/backend/hct_mis_api/apps/household/fixtures.py
@@ -180,7 +180,7 @@ class Meta:
MARITAL_STATUS_CHOICE,
getter=lambda c: c[0],
)
- phone_no = factory.Sequence(lambda n: f"+48 609 456 {n%1000:03d}")
+ phone_no = factory.Sequence(lambda n: f"+48 609 456 {n % 1000:03d}")
phone_no_valid = True
phone_no_alternative = ""
phone_no_alternative_valid = True
@@ -363,6 +363,13 @@ def create_household_and_individuals(
individuals_data = []
if household_data.get("size") is None:
household_data["size"] = len(individuals_data)
+ if "program" not in household_data:
+ program = ProgramFactory()
+ else:
+ program = household_data["program"]
+ if "registration_data_import" not in household_data:
+ rdi = RegistrationDataImportFactory(program=program)
+ household_data["registration_data_import"] = rdi
household: Household = HouseholdFactory.build(**household_data)
household.program.save()
household.household_collection.save()
@@ -370,8 +377,16 @@ def create_household_and_individuals(
household.registration_data_import.program.save()
household.registration_data_import.save()
household.program.save()
+ for individual_data in individuals_data:
+ if "program" not in individual_data:
+ individual_data["program"] = program
+ if "registration_data_import" not in individual_data:
+ individual_data["registration_data_import"] = household_data["registration_data_import"]
individuals: List[Individual] = [
- IndividualFactory(household=household, program=household.program, **individual_data)
+ IndividualFactory(
+ household=household,
+ **individual_data,
+ )
for individual_data in individuals_data
]
household.head_of_household = individuals[0]
diff --git a/backend/hct_mis_api/apps/payment/celery_tasks.py b/backend/hct_mis_api/apps/payment/celery_tasks.py
index dd1abd6a25..1cca926d6c 100644
--- a/backend/hct_mis_api/apps/payment/celery_tasks.py
+++ b/backend/hct_mis_api/apps/payment/celery_tasks.py
@@ -21,7 +21,7 @@
)
from hct_mis_api.apps.payment.models import PaymentPlan, PaymentVerificationPlan
from hct_mis_api.apps.payment.pdf.payment_plan_export_pdf_service import (
- PaymentPlanPDFExportSevice,
+ PaymentPlanPDFExportService,
)
from hct_mis_api.apps.payment.services.payment_household_snapshot_service import (
create_payment_plan_snapshot_data,
@@ -565,7 +565,7 @@ def export_pdf_payment_plan_summary(self: Any, payment_plan_id: str, user_id: st
payment_plan.export_pdf_file_summary.delete()
payment_plan.export_pdf_file_summary = None
- service = PaymentPlanPDFExportSevice(payment_plan)
+ service = PaymentPlanPDFExportService(payment_plan)
pdf, filename = service.generate_pdf_summary()
file_pdf_obj = FileTemp(
diff --git a/backend/hct_mis_api/apps/payment/pdf/payment_plan_export_pdf_service.py b/backend/hct_mis_api/apps/payment/pdf/payment_plan_export_pdf_service.py
index d65a570122..1efcc65134 100644
--- a/backend/hct_mis_api/apps/payment/pdf/payment_plan_export_pdf_service.py
+++ b/backend/hct_mis_api/apps/payment/pdf/payment_plan_export_pdf_service.py
@@ -16,7 +16,7 @@
logger = logging.getLogger(__name__)
-class PaymentPlanPDFExportSevice:
+class PaymentPlanPDFExportService:
text_template = "payment/pdf_file_generated_email.txt"
html_template = "payment/pdf_file_generated_email.html"
@@ -24,6 +24,7 @@ def __init__(self, payment_plan: PaymentPlan):
self.payment_plan = payment_plan
self.download_link: str = ""
self.payment_plan_link: str = ""
+ self.is_social_worker_program = payment_plan.program.is_social_worker_program
@staticmethod
def get_link(api_url: Optional[str] = None) -> str:
@@ -58,7 +59,10 @@ def get_email_context(self, user: "User") -> Dict:
def generate_pdf_summary(self) -> Any:
self.generate_web_links()
- template_name = "payment/payment_plan_summary_pdf_template.html"
+ if self.is_social_worker_program:
+ template_name = "payment/people_payment_plan_summary_pdf_template.html"
+ else:
+ template_name = "payment/payment_plan_summary_pdf_template.html"
filename = f"PaymentPlanSummary-{self.payment_plan.unicef_id}.pdf"
delivery_mechanism_per_payment_plan = self.payment_plan.delivery_mechanisms.select_related(
"financial_service_provider"
diff --git a/backend/hct_mis_api/apps/payment/templates/payment/payment_plan_summary_pdf_template.html b/backend/hct_mis_api/apps/payment/templates/payment/payment_plan_summary_pdf_template.html
index 2efc61708d..02153c6b5b 100644
--- a/backend/hct_mis_api/apps/payment/templates/payment/payment_plan_summary_pdf_template.html
+++ b/backend/hct_mis_api/apps/payment/templates/payment/payment_plan_summary_pdf_template.html
@@ -9,7 +9,7 @@
LETTER OF AUTHORIZATION
-
+
Start Date
@@ -96,9 +96,9 @@ PAYMENT PLAN ACCEPTANCE PROCESS
-
-
-
+
+
+
Name of Approver
@@ -167,8 +167,8 @@ PAYMENT PLAN ACCEPTANCE PROCESS
- Link to Payment Plan: {{ payment_plan_link }}
+Link to Payment Plan: {{ payment_plan_link }}
Generated on {% now "N j, Y" %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/backend/hct_mis_api/apps/payment/templates/payment/people_payment_plan_summary_pdf_template.html b/backend/hct_mis_api/apps/payment/templates/payment/people_payment_plan_summary_pdf_template.html
new file mode 100644
index 0000000000..921ad2fce6
--- /dev/null
+++ b/backend/hct_mis_api/apps/payment/templates/payment/people_payment_plan_summary_pdf_template.html
@@ -0,0 +1,174 @@
+{% extends "export/pdf_base.html" %}
+
+{% block table %}
+
+
+ LETTER OF AUTHORIZATION
+
+
+
+
+
+
+
+
+ Start Date
+ {{ payment_plan.start_date|date:"j N Y" }}
+ Programme Name
+ {{ payment_plan.program_cycle.program.name }}
+
+
+ End Date
+ {{ payment_plan.end_date|date:"j N Y" }}
+ Delivery mechanism
+ {{ delivery_mechanism_per_payment_plan }}
+
+
+ Dispersion Start Date
+ {{ payment_plan.dispersion_start_date|date:"j N Y" }}
+ FSP
+ {{ fsp.name }}
+
+
+ Dispersion End Date
+ {{ payment_plan.dispersion_end_date|date:"j N Y" }}
+ Vision Vendor number
+ {{ fsp.vision_vendor_number }}
+
+
+
+
+ Target Population
+ {{ payment_plan.target_population.name }}
+
+
+
+
+
+ Total number of people covered
+ {{ payment_plan.total_individuals_count }}
+ Total entitlement
+ {{ payment_plan.total_entitled_quantity|default_if_none:"0" }}
+
+
+
+
+ Currency
+ {{ payment_plan.currency }}
+
+
+
+
+ Total entitlement (USD)
+ {{ payment_plan.total_entitled_quantity_usd|default_if_none:"0" }}
+
+
+
+
+
+
+
+
+
+
+ Total People redeemed
+ {{reconciliation.reconciled|default_if_none:"0"}}
+ Total amount redeemed ({{ payment_plan.currency }})
+ {{reconciliation.reconciled_local|default_if_none:"0"}}
+ Total amount redeemed (USD)
+ {{reconciliation.reconciled_usd|default_if_none:"0"}}
+
+
+ Total pending People
+ {{reconciliation.pending|default_if_none:"0"}}
+ Total amount unredeemed ({{ payment_plan.currency }})
+ {{reconciliation.pending_local|default_if_none:"0"}}
+ Total amount unredeemed (USD)
+ {{reconciliation.pending_usd|default_if_none:"0"}}
+
+
+
+
+
+ PAYMENT PLAN ACCEPTANCE PROCESS
+
+
+
+
+
+
+
+
+
+
+ Name of Approver
+ {{ approval.created_by.get_full_name }}
+ Name of authorizer
+ {{ authorization.created_by.get_full_name }}
+ Name of Releaser
+ {{ release.created_by.get_full_name }}
+
+
+ Approval date
+ {{ approval.created_at|date:"j N Y" }}
+ Authorization date
+ {{ authorization.created_at|date:"j N Y" }}
+ Release date
+ {{ release.created_at|date:"j N Y" }}
+
+
+ Comment
+ {{ approval.comment }}
+ Comment
+ {{ authorization.comment }}
+ Comment
+ {{ release.comment }}
+
+
+ Signature
+
+ Signature
+
+ Signature
+
+
+
+
+
+
+
+
+
+
+
+
+ FSP Authorized signatory 1
+
+
+
+
+
+
+
+
+ FSP Authorized signatory 2
+
+
+
+
+
+
+
+
+
+Link to Payment Plan: {{ payment_plan_link }}
+
+Generated on {% now "N j, Y" %}
+
+{% endblock %}
diff --git a/backend/hct_mis_api/apps/payment/tests/test_payment_plan_pdf_export_service.py b/backend/hct_mis_api/apps/payment/tests/test_payment_plan_pdf_export_service.py
new file mode 100644
index 0000000000..f9dc686114
--- /dev/null
+++ b/backend/hct_mis_api/apps/payment/tests/test_payment_plan_pdf_export_service.py
@@ -0,0 +1,95 @@
+from typing import Any
+from unittest.mock import MagicMock, patch
+
+from django.test import TestCase
+
+from hct_mis_api.apps.core.fixtures import create_afghanistan
+from hct_mis_api.apps.core.models import DataCollectingType
+from hct_mis_api.apps.payment.fixtures import (
+ ApprovalFactory,
+ ApprovalProcessFactory,
+ DeliveryMechanismPerPaymentPlanFactory,
+ FinancialServiceProviderFactory,
+ PaymentPlanFactory,
+)
+from hct_mis_api.apps.payment.models import Approval, GenericPayment
+from hct_mis_api.apps.payment.pdf.payment_plan_export_pdf_service import (
+ PaymentPlanPDFExportService,
+)
+from hct_mis_api.apps.program.fixtures import ProgramFactory
+
+
+class TestPaymentPlanPDFExportService(TestCase):
+ def setUp(self) -> None:
+ create_afghanistan()
+ self.payment_plan = PaymentPlanFactory(
+ program=ProgramFactory(data_collecting_type__type=DataCollectingType.Type.STANDARD)
+ )
+ self.payment_plan.unicef_id = "PP-0060-24-00000007"
+ self.payment_plan.save()
+ self.pdf_export_service = PaymentPlanPDFExportService(self.payment_plan)
+
+ financial_service_provider1 = FinancialServiceProviderFactory(
+ delivery_mechanisms=[GenericPayment.DELIVERY_TYPE_CASH]
+ )
+
+ DeliveryMechanismPerPaymentPlanFactory(
+ payment_plan=self.payment_plan,
+ delivery_mechanism=GenericPayment.DELIVERY_TYPE_CASH,
+ financial_service_provider=financial_service_provider1,
+ delivery_mechanism_order=1,
+ )
+ approval_process = ApprovalProcessFactory(
+ payment_plan=self.payment_plan,
+ )
+ ApprovalFactory(type=Approval.APPROVAL, approval_process=approval_process)
+
+ @patch(
+ "hct_mis_api.apps.payment.pdf.payment_plan_export_pdf_service.PaymentPlanPDFExportService.get_link",
+ return_value="http://www_link/download-payment-plan-summary-pdf/111",
+ )
+ def test_generate_web_links(self, get_link_mock: Any) -> None:
+ expected_download_link = "http://www_link/download-payment-plan-summary-pdf/111"
+ self.pdf_export_service.generate_web_links()
+ self.assertEqual(self.pdf_export_service.download_link, expected_download_link)
+ self.assertEqual(self.pdf_export_service.payment_plan_link, expected_download_link)
+
+ @patch(
+ "hct_mis_api.apps.payment.pdf.payment_plan_export_pdf_service.PaymentPlanPDFExportService.get_link",
+ return_value="http://www_link/download-payment-plan-summary-pdf/111",
+ )
+ def test_generate_pdf_summary(self, get_link_mock: Any) -> None:
+ pdf1, filename1 = self.pdf_export_service.generate_pdf_summary()
+
+ self.assertEqual(self.payment_plan.program.data_collecting_type.type, DataCollectingType.Type.STANDARD)
+
+ self.assertTrue(isinstance(pdf1, bytes))
+ self.assertEqual(filename1, "PaymentPlanSummary-PP-0060-24-00000007.pdf")
+
+ self.payment_plan.program.data_collecting_type.type = DataCollectingType.Type.SOCIAL
+ self.payment_plan.program.data_collecting_type.save()
+ self.payment_plan.program.data_collecting_type.refresh_from_db(fields=["type"])
+
+ self.assertEqual(self.payment_plan.program.data_collecting_type.type, DataCollectingType.Type.SOCIAL)
+ pdf2, filename2 = self.pdf_export_service.generate_pdf_summary()
+ self.assertTrue(isinstance(pdf2, bytes))
+ self.assertEqual(filename2, "PaymentPlanSummary-PP-0060-24-00000007.pdf")
+
+ def test_get_email_context(self) -> None:
+ user_mock = MagicMock()
+ user_mock.first_name = "First"
+ user_mock.last_name = "Last"
+ user_mock.email = "first.last@email_tivix.com"
+ expected_context = {
+ "first_name": "First",
+ "last_name": "Last",
+ "email": "first.last@email_tivix.com",
+ "message": "Payment Plan Summary PDF file(s) have been generated, "
+ "and below you will find the link to download the file(s).",
+ "link": "",
+ "title": "Payment Plan Payment List files generated",
+ }
+
+ context = self.pdf_export_service.get_email_context(user_mock)
+
+ self.assertDictEqual(context, expected_context)
diff --git a/backend/hct_mis_api/apps/targeting/graphql_types.py b/backend/hct_mis_api/apps/targeting/graphql_types.py
index f35e959bde..a1839d4b89 100644
--- a/backend/hct_mis_api/apps/targeting/graphql_types.py
+++ b/backend/hct_mis_api/apps/targeting/graphql_types.py
@@ -1,3 +1,4 @@
+import uuid
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type
import graphene
@@ -26,17 +27,20 @@
from graphene.types.structures import List as GrapheneList
- from hct_mis_api.apps.core.models import BusinessArea
from hct_mis_api.apps.targeting.models import TargetingIndividualBlockRuleFilter
-def get_field_by_name(field_name: str, business_area: "BusinessArea") -> Dict:
- factory = FieldFactory.from_scope(Scope.TARGETING)
- factory.apply_business_area(business_area.slug)
+def get_field_by_name(field_name: str, target_population: target_models.TargetPopulation) -> Dict:
+ scopes = [Scope.TARGETING]
+ if target_population.program.is_social_worker_program:
+ scopes.append(Scope.XLSX_PEOPLE)
+ factory = FieldFactory.from_only_scopes(scopes)
+ factory.apply_business_area(target_population.business_area.slug)
field = factory.to_dict_by("name")[field_name]
- choices = field.get("choices")
+ choices = field.get("choices") or field.get("_choices")
if choices and callable(choices):
field["choices"] = choices()
+ field["id"] = uuid.uuid4()
return field
@@ -61,9 +65,12 @@ def resolve_field_attribute(parent, info: Any) -> Optional[Dict]:
return FlexibleAttribute.objects.get(name=parent.field_name)
else:
field_attribute = get_field_by_name(
- parent.field_name, parent.targeting_criteria_rule.targeting_criteria.target_population.business_area
+ parent.field_name, parent.targeting_criteria_rule.targeting_criteria.target_population
+ )
+ parent.targeting_criteria_rule
+ return filter_choices(
+ field_attribute, parent.arguments # type: ignore # can't convert graphene list to list
)
- return filter_choices(field_attribute, parent.arguments) # type: ignore # can't convert graphene list to list
class Meta:
model = target_models.TargetingCriteriaRuleFilter
@@ -82,7 +89,7 @@ def resolve_field_attribute(parent, info: Any) -> Any:
field_attribute = get_field_by_name(
parent.field_name,
- parent.individuals_filters_block.targeting_criteria_rule.targeting_criteria.target_population.business_area,
+ parent.individuals_filters_block.targeting_criteria_rule.targeting_criteria.target_population,
)
return filter_choices(field_attribute, parent.arguments) # type: ignore # can't convert graphene list to list
diff --git a/backend/hct_mis_api/apps/targeting/models.py b/backend/hct_mis_api/apps/targeting/models.py
index 07f3d23f16..1f1c0ea5b4 100644
--- a/backend/hct_mis_api/apps/targeting/models.py
+++ b/backend/hct_mis_api/apps/targeting/models.py
@@ -45,7 +45,6 @@
from django.db.models.query import QuerySet
-
logger = logging.getLogger(__name__)
@@ -446,7 +445,19 @@ class TargetingCriteriaRuleFilter(TimeStampedUUIDModel, TargetingCriteriaFilterB
:Residential Status != Refugee
"""
+ @property
+ def is_social_worker_program(self) -> bool:
+ try:
+ return self.targeting_criteria_rule.targeting_criteria.target_population.program.is_social_worker_program
+ except (
+ AttributeError,
+ TargetingCriteriaRuleFilter.targeting_criteria_rule.RelatedObjectDoesNotExist,
+ ):
+ return False
+
def get_core_fields(self) -> List:
+ if self.is_social_worker_program:
+ return FieldFactory.from_only_scopes([Scope.TARGETING, Scope.XLSX_PEOPLE])
return FieldFactory.from_scope(Scope.TARGETING).associated_with_household()
comparison_method = models.CharField(
@@ -475,6 +486,10 @@ class TargetingIndividualBlockRuleFilter(TimeStampedUUIDModel, TargetingCriteria
:Residential Status != Refugee
"""
+ @property
+ def is_social_worker_program(self) -> bool:
+ return False
+
def get_core_fields(self) -> List:
return FieldFactory.from_scope(Scope.TARGETING).associated_with_individual()
diff --git a/backend/hct_mis_api/apps/targeting/services/targeting_service.py b/backend/hct_mis_api/apps/targeting/services/targeting_service.py
index 9c79493790..3c46288270 100644
--- a/backend/hct_mis_api/apps/targeting/services/targeting_service.py
+++ b/backend/hct_mis_api/apps/targeting/services/targeting_service.py
@@ -329,7 +329,9 @@ def get_query_for_core_field(self) -> Q:
core_field_attr = core_field_attrs[0]
get_query = core_field_attr.get("get_query")
if get_query:
- return get_query(self.comparison_method, self.arguments)
+ return get_query(
+ self.comparison_method, self.arguments, is_social_worker_query=self.is_social_worker_program
+ )
lookup = core_field_attr.get("lookup")
if not lookup:
logger.error(
diff --git a/backend/selenium_tests/conftest.py b/backend/selenium_tests/conftest.py
index 259b5300e3..f9b390e17c 100644
--- a/backend/selenium_tests/conftest.py
+++ b/backend/selenium_tests/conftest.py
@@ -25,6 +25,9 @@
from page_object.registration_data_import.registration_data_import import (
RegistrationDataImport,
)
+from page_object.targeting.targeting import Targeting
+from page_object.targeting.targeting_create import TargetingCreate
+from page_object.targeting.targeting_details import TargetingDetails
from pytest_django.live_server_helper import LiveServer
from pytest_html_reporter import attach
from requests import Session
@@ -48,6 +51,9 @@ def pytest_addoption(parser) -> None: # type: ignore
def pytest_configure() -> None:
+ # delete all old screenshots
+ for file in os.listdir("report/screenshot"):
+ os.remove(os.path.join("report/screenshot", file))
from django.conf import settings
settings.DEBUG = True
@@ -240,6 +246,21 @@ def pageIndividualsDetails(request: FixtureRequest, browser: Chrome) -> Individu
yield IndividualsDetails(browser)
+@pytest.fixture
+def pageTargeting(request: FixtureRequest, browser: Chrome) -> Targeting:
+ yield Targeting(browser)
+
+
+@pytest.fixture
+def pageTargetingDetails(request: FixtureRequest, browser: Chrome) -> TargetingDetails:
+ yield TargetingDetails(browser)
+
+
+@pytest.fixture
+def pageTargetingCreate(request: FixtureRequest, browser: Chrome) -> TargetingCreate:
+ yield TargetingCreate(browser)
+
+
@pytest.fixture
def pageGrievanceDetailsPage(request: FixtureRequest, browser: Chrome) -> GrievanceDetailsPage:
yield GrievanceDetailsPage(browser)
diff --git a/backend/selenium_tests/girevance/grievance_tickets/test_grievance_tickets.py b/backend/selenium_tests/girevance/grievance_tickets/test_grievance_tickets.py
index 7d072396c0..fa4442db23 100644
--- a/backend/selenium_tests/girevance/grievance_tickets/test_grievance_tickets.py
+++ b/backend/selenium_tests/girevance/grievance_tickets/test_grievance_tickets.py
@@ -37,6 +37,8 @@ def create_programs(django_db_setup: Generator[None, None, None], django_db_bloc
@pytest.mark.usefixtures("login")
class TestSmokeGrievanceTickets:
+
+ @pytest.mark.skip(reason="Unstable test")
def test_check_grievance_tickets_user_generated_page(
self,
create_programs: None,
@@ -146,7 +148,6 @@ def test_check_grievance_tickets_details_page(
@pytest.mark.usefixtures("login")
class TestGrievanceTicketsHappyPath:
-
@pytest.mark.skip(reason="ToDo")
def test_grievance_tickets_create_new_ticket(
self,
diff --git a/backend/selenium_tests/helpers/helper.py b/backend/selenium_tests/helpers/helper.py
index 3503ec9906..4245ed6c1d 100644
--- a/backend/selenium_tests/helpers/helper.py
+++ b/backend/selenium_tests/helpers/helper.py
@@ -2,7 +2,7 @@
from time import sleep
from typing import Literal, Union
-from selenium.webdriver import Chrome
+from selenium.webdriver import Chrome, Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
@@ -77,6 +77,19 @@ def select_option_by_name(self, optionName: str) -> None:
self.wait_for(selectOption).click()
self.wait_for_disappear(selectOption)
+ def select_multiple_option_by_name(self, *optionNames: [str]) -> None:
+ for optionName in optionNames:
+ selectOption = f'li[data-cy="select-option-{optionName}"]'
+ self.wait_for(selectOption).click()
+ actions = ActionChains(self.driver)
+ actions.send_keys(Keys.ESCAPE).perform() # type: ignore
+ try:
+ self.wait_for_disappear(selectOption)
+ except BaseException:
+ sleep(1)
+ self.wait_for(selectOption).click()
+ self.wait_for_disappear(selectOption)
+
@staticmethod
def choose_option(list_options: list, name: str) -> bool:
for option in list_options:
diff --git a/backend/selenium_tests/page_object/targeting/create_new.py b/backend/selenium_tests/page_object/targeting/create_new.py
deleted file mode 100644
index cd4bda0e98..0000000000
--- a/backend/selenium_tests/page_object/targeting/create_new.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from page_object.base_components import BaseComponents
-from selenium.webdriver.remote.webelement import WebElement
-
-
-class CreateNew(BaseComponents):
- # Locators
- targetingCriteria = 'h6[data-cy="title-targeting-criteria"]'
- # Texts
- textTargetingCriteria = "Targeting Criteria"
- # Elements
-
- def getTargetingCriteria(self) -> WebElement:
- return self.wait_for(self.targetingCriteria)
diff --git a/backend/selenium_tests/page_object/targeting/t_details_page.py b/backend/selenium_tests/page_object/targeting/t_details_page.py
deleted file mode 100644
index 17f3fa6a95..0000000000
--- a/backend/selenium_tests/page_object/targeting/t_details_page.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from page_object.base_components import BaseComponents
-from selenium.webdriver.remote.webelement import WebElement
-
-
-class TDetailsPage(BaseComponents):
- # Locators
- titlePage = 'h5[data-cy="page-header-title"]'
- status = 'div[data-cy="target-population-status"]'
- # Texts
- # Elements
-
- def getTitlePage(self) -> WebElement:
- return self.wait_for(self.titlePage)
-
- def getStatus(self) -> WebElement:
- return self.wait_for(self.status)
diff --git a/backend/selenium_tests/page_object/targeting/targeting.py b/backend/selenium_tests/page_object/targeting/targeting.py
index 5f86be9233..e60742905d 100644
--- a/backend/selenium_tests/page_object/targeting/targeting.py
+++ b/backend/selenium_tests/page_object/targeting/targeting.py
@@ -1,6 +1,8 @@
from page_object.base_components import BaseComponents
from selenium.webdriver.remote.webelement import WebElement
+from hct_mis_api.apps.core.utils import encode_id_base64
+
class Targeting(BaseComponents):
# Locators
@@ -10,7 +12,8 @@ class Targeting(BaseComponents):
programFilter = 'div[data-cy="filters-program"]'
minNumberOfHouseholds = 'div[data-cy="filters-total-households-count-min"]'
maxNumberOfHouseholds = 'div[data-cy="filters-total-households-count-max"]'
- buttonCreateNew = 'a[data-cy="button-target-population-create-new"]'
+ buttonCreateNew = 'button[data-cy="button-new-tp"]'
+ buttonCreateNewByFilters = 'li[data-cy="menu-item-filters"]'
tabTitle = 'h6[data-cy="table-title"]'
tabColumnLabel = 'span[data-cy="table-label"]'
statusOptions = 'li[role="option"]'
@@ -31,6 +34,13 @@ class Targeting(BaseComponents):
buttonApply = 'button[data-cy="button-filters-apply"]'
buttonClear = 'button[data-cy="button-filters-clear"]'
+ def navigate_to_page(self, business_area_slug: str, program_id: str) -> None:
+ self.driver.get(self.get_page_url(business_area_slug, program_id))
+
+ def get_page_url(self, business_area_slug: str, program_id: str) -> str:
+ encoded_program_id = encode_id_base64(program_id, "Program")
+ return f"{self.driver.live_server.url}/{business_area_slug}/programs/{encoded_program_id}/target-population"
+
# Elements
def getTitlePage(self) -> WebElement:
@@ -54,6 +64,9 @@ def getMaxNumberOfHouseholdsFilter(self) -> WebElement:
def getButtonCreateNew(self) -> WebElement:
return self.wait_for(self.buttonCreateNew)
+ def getButtonCreateNewByFilters(self) -> WebElement:
+ return self.wait_for(self.buttonCreateNewByFilters)
+
def getTabTitle(self) -> WebElement:
return self.wait_for(self.tabTitle)
diff --git a/backend/selenium_tests/page_object/targeting/targeting_create.py b/backend/selenium_tests/page_object/targeting/targeting_create.py
new file mode 100644
index 0000000000..b530446a26
--- /dev/null
+++ b/backend/selenium_tests/page_object/targeting/targeting_create.py
@@ -0,0 +1,58 @@
+from page_object.base_components import BaseComponents
+from selenium.webdriver.remote.webelement import WebElement
+
+
+class TargetingCreate(BaseComponents):
+ # Locators
+ targetingCriteria = 'h6[data-cy="title-targeting-criteria"]'
+ addCriteriaButton = 'div[data-cy="button-target-population-add-criteria"]'
+ addHouseholdRuleButton = '[data-cy="button-household-rule"]'
+ addIndividualRuleButton = '[data-cy="button-individual-rule"]'
+ addPeopleRuleButton = '[data-cy="button-household-rule"]'
+ titlePage = 'h5[data-cy="page-header-title"]'
+ fieldName = 'input[data-cy="input-name"]'
+ targetingCriteriaAutoComplete = 'input[data-cy="autocomplete-target-criteria-option-{}"]'
+ targetingCriteriaValue = '[data-cy="select-filters[{}].value"]'
+ targetingCriteriaAddDialogSaveButton = 'button[data-cy="button-target-population-add-criteria"]'
+ criteriaContainer = 'div[data-cy="criteria-container"]'
+ targetPopulationSaveButton = 'button[data-cy="button-target-population-create"]'
+ # Texts
+ textTargetingCriteria = "Targeting Criteria"
+
+ # Elements
+
+ def getTargetingCriteria(self) -> WebElement:
+ return self.wait_for(self.targetingCriteria)
+
+ def getTitlePage(self) -> WebElement:
+ return self.wait_for(self.titlePage)
+
+ def getAddCriteriaButton(self) -> WebElement:
+ return self.wait_for(self.addCriteriaButton)
+
+ def getAddHouseholdRuleButton(self) -> WebElement:
+ return self.wait_for(self.addHouseholdRuleButton)
+
+ def getAddIndividualRuleButton(self) -> WebElement:
+ return self.wait_for(self.addIndividualRuleButton)
+
+ def getAddPeopleRuleButton(self) -> WebElement:
+ return self.wait_for(self.addPeopleRuleButton)
+
+ def getTargetingCriteriaAutoComplete(self, index: int = 0) -> WebElement:
+ return self.wait_for(self.targetingCriteriaAutoComplete.format(index))
+
+ def getTargetingCriteriaValue(self, index: int = 0) -> WebElement:
+ return self.wait_for(self.targetingCriteriaValue.format(index))
+
+ def getTargetingCriteriaAddDialogSaveButton(self) -> WebElement:
+ return self.wait_for(self.targetingCriteriaAddDialogSaveButton)
+
+ def getCriteriaContainer(self) -> WebElement:
+ return self.wait_for(self.criteriaContainer)
+
+ def getFieldName(self) -> WebElement:
+ return self.wait_for(self.fieldName)
+
+ def getTargetPopulationSaveButton(self) -> WebElement:
+ return self.wait_for(self.targetPopulationSaveButton)
diff --git a/backend/selenium_tests/page_object/targeting/targeting_details.py b/backend/selenium_tests/page_object/targeting/targeting_details.py
new file mode 100644
index 0000000000..41f3b80100
--- /dev/null
+++ b/backend/selenium_tests/page_object/targeting/targeting_details.py
@@ -0,0 +1,37 @@
+from page_object.base_components import BaseComponents
+from selenium.webdriver.remote.webelement import WebElement
+
+
+class TargetingDetails(BaseComponents):
+ # Locators
+ titlePage = 'h5[data-cy="page-header-title"]'
+ status = 'div[data-cy="target-population-status"]'
+ criteria_container = 'div[data-cy="criteria-container"]'
+ lock_button = 'button[data-cy="button-target-population-lock"]'
+ household_table_cell = "table tr:nth-of-type({}) td:nth-of-type({})"
+ people_table_rows = '[data-cy="target-population-people-row"]'
+ household_table_rows = '[data-cy="target-population-household-row"]'
+
+ # Texts
+ # Elements
+
+ def getTitlePage(self) -> WebElement:
+ return self.wait_for(self.titlePage)
+
+ def getStatus(self) -> WebElement:
+ return self.wait_for(self.status)
+
+ def getCriteriaContainer(self) -> WebElement:
+ return self.wait_for(self.criteria_container)
+
+ def getLockButton(self) -> WebElement:
+ return self.wait_for(self.lock_button)
+
+ def getHouseholdTableCell(self, row: int, column: int) -> WebElement:
+ return self.wait_for(self.household_table_cell.format(row, column))
+
+ def getPeopleTableRows(self) -> list[WebElement]:
+ return self.get_elements(self.people_table_rows)
+
+ def getHouseholdTableRows(self) -> list[WebElement]:
+ return self.get_elements(self.household_table_rows)
diff --git a/backend/selenium_tests/programme_management/test_programme_management.py b/backend/selenium_tests/programme_management/test_programme_management.py
index d48290ea7b..2d8d9da0da 100644
--- a/backend/selenium_tests/programme_management/test_programme_management.py
+++ b/backend/selenium_tests/programme_management/test_programme_management.py
@@ -397,6 +397,7 @@ def test_create_programme_add_partners_Business_Area(
assert "UNHCR" in pageProgrammeDetails.getLabelPartnerName().text
assert "Business Area" in pageProgrammeDetails.getLabelAreaAccess().text
+ @pytest.mark.skip(reason="Unstable test")
@pytest.mark.parametrize(
"test_data",
[
diff --git a/backend/selenium_tests/registration_data_import/test_registration_data_import.py b/backend/selenium_tests/registration_data_import/test_registration_data_import.py
index f705a1b60e..596da1fb4a 100644
--- a/backend/selenium_tests/registration_data_import/test_registration_data_import.py
+++ b/backend/selenium_tests/registration_data_import/test_registration_data_import.py
@@ -116,6 +116,7 @@ def test_smoke_registration_data_details_page(
class TestRegistrationDataImport:
+ @pytest.mark.skip(reason="Unstable test")
def test_smoke_registration_data_import_happy_path(
self,
registration_datahub: None,
diff --git a/backend/selenium_tests/targeting/test_create_targeting.py b/backend/selenium_tests/targeting/test_create_targeting.py
new file mode 100644
index 0000000000..0fe1396f29
--- /dev/null
+++ b/backend/selenium_tests/targeting/test_create_targeting.py
@@ -0,0 +1,167 @@
+from datetime import datetime
+
+from django.db import transaction
+
+import pytest
+from dateutil.relativedelta import relativedelta
+from page_object.targeting.targeting import Targeting
+from page_object.targeting.targeting_create import TargetingCreate
+from page_object.targeting.targeting_details import TargetingDetails
+from selenium.webdriver import ActionChains, Keys
+
+from hct_mis_api.apps.core.fixtures import DataCollectingTypeFactory
+from hct_mis_api.apps.core.models import BusinessArea, DataCollectingType
+from hct_mis_api.apps.household.fixtures import create_household_and_individuals
+from hct_mis_api.apps.household.models import HEARING, HOST, REFUGEE, SEEING, Household
+from hct_mis_api.apps.program.fixtures import ProgramFactory
+from hct_mis_api.apps.program.models import Program
+
+pytestmark = pytest.mark.django_db(transaction=True)
+
+
+@pytest.fixture
+def sw_program() -> Program:
+ return get_program_with_dct_type_and_name(
+ "SW Program", dct_type=DataCollectingType.Type.SOCIAL, status=Program.ACTIVE
+ )
+
+
+@pytest.fixture
+def non_sw_program() -> Program:
+ return get_program_with_dct_type_and_name(
+ "Non SW Program", dct_type=DataCollectingType.Type.STANDARD, status=Program.ACTIVE
+ )
+
+
+@pytest.fixture
+def household_with_disability() -> Household:
+ program = Program.objects.first()
+ with transaction.atomic():
+ household, individuals = create_household_and_individuals(
+ household_data={"business_area": program.business_area, "program": program, "residence_status": HOST},
+ individuals_data=[
+ {"business_area": program.business_area, "observed_disability": [SEEING, HEARING]},
+ ],
+ )
+ return household
+
+
+@pytest.fixture
+def household_without_disabilities() -> Household:
+ program = Program.objects.first()
+ with transaction.atomic():
+ household, individuals = create_household_and_individuals(
+ household_data={"business_area": program.business_area, "program": program, "residence_status": HOST},
+ individuals_data=[
+ {"business_area": program.business_area, "observed_disability": []},
+ ],
+ )
+ return household
+
+
+@pytest.fixture
+def household_refugee() -> Household:
+ program = Program.objects.first()
+ with transaction.atomic():
+ household, individuals = create_household_and_individuals(
+ household_data={"business_area": program.business_area, "program": program, "residence_status": REFUGEE},
+ individuals_data=[
+ {"business_area": program.business_area, "observed_disability": []},
+ ],
+ )
+ return household
+
+
+def get_program_with_dct_type_and_name(
+ name: str, dct_type: str = DataCollectingType.Type.STANDARD, status: str = Program.ACTIVE
+) -> Program:
+ BusinessArea.objects.filter(slug="afghanistan").update(is_payment_plan_applicable=True)
+ dct = DataCollectingTypeFactory(type=dct_type)
+ program = ProgramFactory(
+ name=name,
+ start_date=datetime.now() - relativedelta(months=1),
+ end_date=datetime.now() + relativedelta(months=1),
+ data_collecting_type=dct,
+ status=status,
+ )
+ return program
+
+
+@pytest.mark.usefixtures("login")
+class TestCreateTargeting:
+ def test_create_targeting_for_people(
+ self,
+ sw_program: Program,
+ household_with_disability: Household,
+ household_without_disabilities: Household,
+ pageTargeting: Targeting,
+ pageTargetingCreate: TargetingCreate,
+ pageTargetingDetails: TargetingDetails,
+ ) -> None:
+ pageTargeting.navigate_to_page("afghanistan", sw_program.id)
+ pageTargeting.getButtonCreateNew().click()
+ pageTargeting.getButtonCreateNewByFilters().click()
+ assert "New Target Population" in pageTargetingCreate.getTitlePage().text
+ pageTargetingCreate.getAddCriteriaButton().click()
+ assert pageTargetingCreate.getAddPeopleRuleButton().text.upper() == "ADD PEOPLE RULE"
+ pageTargetingCreate.getAddPeopleRuleButton().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().send_keys("Does the Social Worker have disability?")
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().send_keys(Keys.ARROW_DOWN)
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().send_keys(Keys.ENTER)
+ pageTargetingCreate.getTargetingCriteriaValue().click()
+ pageTargetingCreate.select_multiple_option_by_name(HEARING, SEEING)
+ pageTargetingCreate.getTargetingCriteriaAddDialogSaveButton().click()
+ disability_expected_criteria_text = "Does the Social Worker have disability?: Difficulty hearing (even if using a hearing aid), Difficulty seeing (even if wearing glasses)"
+ assert pageTargetingCreate.getCriteriaContainer().text == disability_expected_criteria_text
+ targeting_name = "Test targeting people"
+ pageTargetingCreate.getFieldName().send_keys(targeting_name)
+ pageTargetingCreate.getTargetPopulationSaveButton().click()
+ pageTargetingDetails.getLockButton()
+ assert pageTargetingDetails.getTitlePage().text == targeting_name
+ assert pageTargetingDetails.getCriteriaContainer().text == disability_expected_criteria_text
+ assert Household.objects.count() == 2
+ assert (
+ pageTargetingDetails.getHouseholdTableCell(1, 1).text
+ == household_with_disability.individuals.first().unicef_id
+ )
+ assert len(pageTargetingDetails.getPeopleTableRows()) == 1
+
+ def test_create_targeting_for_normal_program(
+ self,
+ non_sw_program: Program,
+ household_with_disability: Household,
+ household_without_disabilities: Household,
+ household_refugee: Household,
+ pageTargeting: Targeting,
+ pageTargetingCreate: TargetingCreate,
+ pageTargetingDetails: TargetingDetails,
+ ) -> None:
+ pageTargeting.navigate_to_page("afghanistan", non_sw_program.id)
+ pageTargeting.getButtonCreateNew().click()
+ pageTargeting.getButtonCreateNewByFilters().click()
+ assert "New Target Population" in pageTargetingCreate.getTitlePage().text
+ pageTargetingCreate.getAddCriteriaButton().click()
+ assert pageTargetingCreate.getAddPeopleRuleButton().text.upper() == "ADD HOUSEHOLD RULE"
+ pageTargetingCreate.getAddHouseholdRuleButton().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().send_keys("Residence Status")
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().send_keys(Keys.ARROW_DOWN)
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().send_keys(Keys.ENTER)
+ pageTargetingCreate.getTargetingCriteriaValue().click()
+ pageTargetingCreate.select_option_by_name(REFUGEE)
+ pageTargetingCreate.getTargetingCriteriaAddDialogSaveButton().click()
+ disability_expected_criteria_text = "Residence status: Displaced | Refugee / Asylum Seeker"
+ assert pageTargetingCreate.getCriteriaContainer().text == disability_expected_criteria_text
+ targeting_name = "Test targeting people"
+ pageTargetingCreate.getFieldName().send_keys(targeting_name)
+ pageTargetingCreate.getTargetPopulationSaveButton().click()
+ pageTargetingDetails.getLockButton()
+ assert pageTargetingDetails.getTitlePage().text == targeting_name
+ assert pageTargetingDetails.getCriteriaContainer().text == disability_expected_criteria_text
+ assert Household.objects.count() == 3
+ assert Program.objects.count() == 1
+ assert pageTargetingDetails.getHouseholdTableCell(1, 1).text == household_refugee.unicef_id
+ actions = ActionChains(pageTargetingDetails.driver)
+ actions.move_to_element(pageTargetingDetails.getHouseholdTableCell(1, 1)).perform() # type: ignore
+ assert len(pageTargetingDetails.getHouseholdTableRows()) == 1
diff --git a/compose.selenium.yml b/compose.selenium.yml
index 95b15ca0ee..e9edacc8cc 100644
--- a/compose.selenium.yml
+++ b/compose.selenium.yml
@@ -3,7 +3,7 @@ version: '3.7'
volumes:
backend-data-selenium:
backend-web-app-selenium:
- db-selenium:
+ db-selenium-data:
data_es-selenium:
services:
@@ -21,11 +21,11 @@ services:
- CELERY_BROKER_URL=redis://redis:6379/0
- CELERY_RESULT_BACKEND=redis://redis:6379/0
- CACHE_LOCATION=redis://redis:6379/1
- - DATABASE_URL=postgis://postgres:postgres@db:5432/postgres
- - DATABASE_URL_HUB_MIS=postgis://postgres:postgres@db:5432/mis_datahub
- - DATABASE_URL_HUB_CA=postgis://postgres:postgres@db:5432/ca_datahub
- - DATABASE_URL_HUB_ERP=postgis://postgres:postgres@db:5432/erp_datahub
- - DATABASE_URL_HUB_REGISTRATION=postgis://postgres:postgres@db:5432/rdi_datahub
+ - DATABASE_URL=postgis://postgres:postgres@db_selenium:5432/postgres
+ - DATABASE_URL_HUB_MIS=postgis://postgres:postgres@db_selenium:5432/mis_datahub
+ - DATABASE_URL_HUB_CA=postgis://postgres:postgres@db_selenium:5432/ca_datahub
+ - DATABASE_URL_HUB_ERP=postgis://postgres:postgres@db_selenium:5432/erp_datahub
+ - DATABASE_URL_HUB_REGISTRATION=postgis://postgres:postgres@db_selenium:5432/rdi_datahub
- USE_DUMMY_EXCHANGE_RATES=yes
- CELERY_TASK_ALWAYS_EAGER=true
build:
@@ -35,9 +35,9 @@ services:
volumes:
- ./backend/report/screenshot/:/code/screenshot/
- ./backend/report/:/code/report/
- - backend-data:/data
- backend-data-selenium:/data
- ./backend/selenium_tests:/code/selenium_tests
+ - ./backend/hct_mis_api:/code/hct_mis_api
- type: volume
source: backend-web-app-selenium
target: /code/hct_mis_api/apps/web/static
@@ -45,13 +45,13 @@ services:
nocopy: false
command: |
sh -c "
- waitforit -host=db -port=5432 -timeout=30 &&
+ waitforit -host=db_selenium -port=5432 -timeout=30 &&
pytest -svvv selenium_tests --html-report=./report/report.html
"
ports:
- "8080:8080"
depends_on:
- db:
+ db_selenium:
condition: service_started
redis:
condition: service_started
@@ -78,13 +78,11 @@ services:
redis:
restart: always
image: redis:4.0.11-alpine3.8
- expose:
- - "6379"
- db:
+ db_selenium:
image: kartoza/postgis:14-3
volumes:
- - db-selenium:/var/lib/postgresql/data
+ - db-selenium-data:/var/lib/postgresql/data
- ./postgres/init:/docker-entrypoint-initdb.d
environment:
- POSTGRES_MULTIPLE_DATABASES=unicef_hct_mis_cashassist,rdi_datahub,mis_datahub,erp_datahub,ca_datahub
@@ -94,8 +92,6 @@ services:
- PGUSER=postgres
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_SSL_MODE=off
- ports:
- - "5433:5432"
elasticsearch:
image: unicef/hct-elasticsearch
diff --git a/deployment/docker-compose.selenium.yml b/deployment/docker-compose.selenium.yml
index 3b5a138712..3940dd0634 100644
--- a/deployment/docker-compose.selenium.yml
+++ b/deployment/docker-compose.selenium.yml
@@ -1,11 +1,6 @@
version: '3.7'
-
volumes:
- backend-data:
backend-web-app:
- db:
- data_es:
-
services:
selenium:
stdin_open: true
@@ -30,7 +25,6 @@ services:
- ../backend:/code/
- ../backend/report/screenshot/:/code/screenshot/
- ../backend/report/:/code/report/
- - backend-data:/data
- type: volume
source: backend-web-app
target: /code/hct_mis_api/apps/web
@@ -71,7 +65,6 @@ services:
db:
image: kartoza/postgis:14-3
volumes:
- - db:/var/lib/postgresql/data
- ./postgres/init:/docker-entrypoint-initdb.d
environment:
- POSTGRES_MULTIPLE_DATABASES=unicef_hct_mis_cashassist,rdi_datahub,mis_datahub,erp_datahub,ca_datahub
@@ -101,7 +94,5 @@ services:
memlock:
soft: -1
hard: -1
- volumes:
- - data_es:/usr/share/elasticsearch/data
ports:
- 9200:9200
diff --git a/frontend/src/__generated__/graphql.tsx b/frontend/src/__generated__/graphql.tsx
index ec389de103..d8cf54f96b 100644
--- a/frontend/src/__generated__/graphql.tsx
+++ b/frontend/src/__generated__/graphql.tsx
@@ -9229,17 +9229,17 @@ export type _TableTotalCashTransferredDataNode = {
totalHouseholds?: Maybe;
};
-export type GrievanceTicketDetailedFragment = { __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, category: number, consent: boolean, createdAt: any, updatedAt: any, description: string, language: string, admin?: string | null, area: string, adminUrl?: string | null, issueType?: number | null, priority?: number | null, urgency?: number | null, comments?: string | null, partner?: { __typename?: 'PartnerType', id: string, name: string } | null, businessArea: { __typename?: 'UserBusinessAreaNode', postponeDeduplication: boolean }, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, pCode?: string | null } | null, assignedTo?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, paymentRecord?: { __typename?: 'PaymentRecordAndPaymentNode', id?: string | null, caId?: string | null, deliveredQuantity?: number | null, entitlementQuantity?: number | null, objType?: string | null, parent?: { __typename?: 'CashPlanAndPaymentPlanNode', id?: string | null, unicefId?: string | null, objType?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null, relatedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, linkedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, category: number, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, existingTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, category: number, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, addIndividualTicketDetails?: { __typename?: 'TicketAddIndividualDetailsNode', id: string, individualData?: any | null, approveStatus: boolean, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, roleReassignData: any, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null, deleteIndividualTicketDetails?: { __typename?: 'TicketDeleteIndividualDetailsNode', id: string, roleReassignData: any, approveStatus: boolean } | null, deleteHouseholdTicketDetails?: { __typename?: 'TicketDeleteHouseholdDetailsNode', id: string, approveStatus: boolean, reasonHousehold?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, systemFlaggingTicketDetails?: { __typename?: 'TicketSystemFlaggingDetailsNode', id: string, approveStatus: boolean, roleReassignData: any, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, fullName: string, birthDate: any, lastRegistrationDate: any, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, documentNumber: string, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> } }, sanctionListIndividual: { __typename?: 'SanctionListIndividualNode', id: string, fullName: string, referenceNumber: string, datesOfBirth: { __typename?: 'SanctionListIndividualDateOfBirthNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDateOfBirthNodeEdge', node?: { __typename?: 'SanctionListIndividualDateOfBirthNode', id: string, date: any } | null } | null> }, documents: { __typename?: 'SanctionListIndividualDocumentNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDocumentNodeEdge', node?: { __typename?: 'SanctionListIndividualDocumentNode', id: string, documentNumber: string, typeOfDocument: string } | null } | null> } } } | null, paymentVerificationTicketDetails?: { __typename?: 'TicketPaymentVerificationDetailsNode', id: string, newStatus?: TicketPaymentVerificationDetailsNewStatus | null, oldReceivedAmount?: number | null, newReceivedAmount?: number | null, approveStatus: boolean, paymentVerificationStatus: TicketPaymentVerificationDetailsPaymentVerificationStatus, hasMultiplePaymentVerifications?: boolean | null, paymentVerification?: { __typename?: 'PaymentVerificationNode', id: string, receivedAmount?: number | null } | null, paymentVerifications: { __typename?: 'PaymentVerificationNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', node?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null> } } | null, needsAdjudicationTicketDetails?: { __typename?: 'TicketNeedsAdjudicationDetailsNode', id: string, hasDuplicatedDocument?: boolean | null, isMultipleDuplicatesVersion: boolean, roleReassignData: any, extraData?: { __typename?: 'TicketNeedsAdjudicationDetailsExtraDataNode', goldenRecords?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null, possibleDuplicate?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, birthDate: any, lastRegistrationDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null }, possibleDuplicate?: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, possibleDuplicates?: Array<{ __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null> | null, selectedIndividual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, activeIndividualsCount?: number | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, selectedIndividuals?: Array<{ __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, activeIndividualsCount?: number | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null> | null } | null, ticketNotes: { __typename?: 'TicketNoteNodeConnection', edges: Array<{ __typename?: 'TicketNoteNodeEdge', node?: { __typename?: 'TicketNoteNode', id: string, createdAt: any, updatedAt: any, description: string, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null } | null> }, programs?: Array<{ __typename?: 'ProgramNode', name: string, id: string } | null> | null, documentation?: Array<{ __typename?: 'GrievanceDocumentNode', id: string, createdAt: any, updatedAt: any, name?: string | null, fileSize?: number | null, contentType: string, filePath?: string | null, fileName?: string | null, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null> | null };
+export type GrievanceTicketDetailedFragment = { __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, category: number, consent: boolean, createdAt: any, updatedAt: any, description: string, language: string, admin?: string | null, area: string, adminUrl?: string | null, issueType?: number | null, priority?: number | null, urgency?: number | null, comments?: string | null, partner?: { __typename?: 'PartnerType', id: string, name: string } | null, businessArea: { __typename?: 'UserBusinessAreaNode', postponeDeduplication: boolean }, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, pCode?: string | null } | null, assignedTo?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, paymentRecord?: { __typename?: 'PaymentRecordAndPaymentNode', id?: string | null, caId?: string | null, deliveredQuantity?: number | null, entitlementQuantity?: number | null, objType?: string | null, parent?: { __typename?: 'CashPlanAndPaymentPlanNode', id?: string | null, unicefId?: string | null, objType?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null, relatedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, linkedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, category: number, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, existingTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, category: number, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, addIndividualTicketDetails?: { __typename?: 'TicketAddIndividualDetailsNode', id: string, individualData?: any | null, approveStatus: boolean, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, roleReassignData: any, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null, deleteIndividualTicketDetails?: { __typename?: 'TicketDeleteIndividualDetailsNode', id: string, roleReassignData: any, approveStatus: boolean } | null, deleteHouseholdTicketDetails?: { __typename?: 'TicketDeleteHouseholdDetailsNode', id: string, approveStatus: boolean, reasonHousehold?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, systemFlaggingTicketDetails?: { __typename?: 'TicketSystemFlaggingDetailsNode', id: string, approveStatus: boolean, roleReassignData: any, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, fullName: string, birthDate: any, lastRegistrationDate: any, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, documentNumber: string, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> } }, sanctionListIndividual: { __typename?: 'SanctionListIndividualNode', id: string, fullName: string, referenceNumber: string, datesOfBirth: { __typename?: 'SanctionListIndividualDateOfBirthNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDateOfBirthNodeEdge', node?: { __typename?: 'SanctionListIndividualDateOfBirthNode', id: string, date: any } | null } | null> }, documents: { __typename?: 'SanctionListIndividualDocumentNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDocumentNodeEdge', node?: { __typename?: 'SanctionListIndividualDocumentNode', id: string, documentNumber: string, typeOfDocument: string } | null } | null> } } } | null, paymentVerificationTicketDetails?: { __typename?: 'TicketPaymentVerificationDetailsNode', id: string, newStatus?: TicketPaymentVerificationDetailsNewStatus | null, oldReceivedAmount?: number | null, newReceivedAmount?: number | null, approveStatus: boolean, paymentVerificationStatus: TicketPaymentVerificationDetailsPaymentVerificationStatus, hasMultiplePaymentVerifications?: boolean | null, paymentVerification?: { __typename?: 'PaymentVerificationNode', id: string, receivedAmount?: number | null } | null, paymentVerifications: { __typename?: 'PaymentVerificationNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', node?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null> } } | null, needsAdjudicationTicketDetails?: { __typename?: 'TicketNeedsAdjudicationDetailsNode', id: string, hasDuplicatedDocument?: boolean | null, isMultipleDuplicatesVersion: boolean, roleReassignData: any, extraData?: { __typename?: 'TicketNeedsAdjudicationDetailsExtraDataNode', goldenRecords?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null, possibleDuplicate?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, birthDate: any, lastRegistrationDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null }, possibleDuplicate?: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, possibleDuplicates?: Array<{ __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null> | null, selectedIndividual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, activeIndividualsCount?: number | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, currency?: string | null, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, adminAreaTitle?: string | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, selectedIndividuals?: Array<{ __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, activeIndividualsCount?: number | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, currency?: string | null, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, adminAreaTitle?: string | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null> | null } | null, ticketNotes: { __typename?: 'TicketNoteNodeConnection', edges: Array<{ __typename?: 'TicketNoteNodeEdge', node?: { __typename?: 'TicketNoteNode', id: string, createdAt: any, updatedAt: any, description: string, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null } | null> }, programs?: Array<{ __typename?: 'ProgramNode', name: string, id: string } | null> | null, documentation?: Array<{ __typename?: 'GrievanceDocumentNode', id: string, createdAt: any, updatedAt: any, name?: string | null, fileSize?: number | null, contentType: string, filePath?: string | null, fileName?: string | null, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null> | null };
export type HouseholdMinimalFragment = { __typename?: 'HouseholdNode', id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, flexFields?: any | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, address: string, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } };
-export type HouseholdDetailedFragment = { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } };
+export type HouseholdDetailedFragment = { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } };
export type MergedHouseholdMinimalFragment = { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, size?: number | null, firstRegistrationDate: any, hasDuplicates?: boolean | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string }, admin1?: { __typename?: 'AreaNode', id: string, name: string } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null };
-export type IndividualMinimalFragment = { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null };
+export type IndividualMinimalFragment = { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null };
-export type IndividualDetailedFragment = { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } };
+export type IndividualDetailedFragment = { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } };
export type MergedIndividualMinimalFragment = { __typename?: 'IndividualNode', id: string, unicefId?: string | null, age?: number | null, fullName: string, birthDate: any, sex: IndividualSex, role?: string | null, relationship?: IndividualRelationship | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, fullName?: string | null, score?: number | null, proximityToScore?: number | null, age?: number | null, location?: string | null } | null> | null, deduplicationBatchResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, fullName?: string | null, score?: number | null, proximityToScore?: number | null, age?: number | null, location?: string | null } | null> | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', id: string, datahubId?: any | null } | null };
@@ -9342,7 +9342,7 @@ export type ApproveHouseholdDataChangeMutationVariables = Exact<{
}>;
-export type ApproveHouseholdDataChangeMutation = { __typename?: 'Mutations', approveHouseholdDataChange?: { __typename?: 'HouseholdDataChangeApproveMutation', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, status: number, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null } | null } | null };
+export type ApproveHouseholdDataChangeMutation = { __typename?: 'Mutations', approveHouseholdDataChange?: { __typename?: 'HouseholdDataChangeApproveMutation', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, status: number, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null } | null } | null };
export type ApproveIndividualDataChangeMutationVariables = Exact<{
grievanceTicketId: Scalars['ID']['input'];
@@ -9360,7 +9360,7 @@ export type ApproveIndividualDataChangeMutationVariables = Exact<{
}>;
-export type ApproveIndividualDataChangeMutation = { __typename?: 'Mutations', approveIndividualDataChange?: { __typename?: 'IndividualDataChangeApproveMutation', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, status: number, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null } | null } | null };
+export type ApproveIndividualDataChangeMutation = { __typename?: 'Mutations', approveIndividualDataChange?: { __typename?: 'IndividualDataChangeApproveMutation', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, status: number, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null } | null } | null };
export type ApproveNeedsAdjudicationMutationVariables = Exact<{
grievanceTicketId: Scalars['ID']['input'];
@@ -9443,7 +9443,7 @@ export type GrievanceTicketStatusChangeMutationVariables = Exact<{
}>;
-export type GrievanceTicketStatusChangeMutation = { __typename?: 'Mutations', grievanceStatusChange?: { __typename?: 'GrievanceStatusChangeMutation', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, category: number, consent: boolean, createdAt: any, updatedAt: any, description: string, language: string, admin?: string | null, area: string, adminUrl?: string | null, issueType?: number | null, priority?: number | null, urgency?: number | null, comments?: string | null, partner?: { __typename?: 'PartnerType', id: string, name: string } | null, businessArea: { __typename?: 'UserBusinessAreaNode', postponeDeduplication: boolean }, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, pCode?: string | null } | null, assignedTo?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, paymentRecord?: { __typename?: 'PaymentRecordAndPaymentNode', id?: string | null, caId?: string | null, deliveredQuantity?: number | null, entitlementQuantity?: number | null, objType?: string | null, parent?: { __typename?: 'CashPlanAndPaymentPlanNode', id?: string | null, unicefId?: string | null, objType?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null, relatedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, linkedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, category: number, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, existingTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, category: number, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, addIndividualTicketDetails?: { __typename?: 'TicketAddIndividualDetailsNode', id: string, individualData?: any | null, approveStatus: boolean, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, roleReassignData: any, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null, deleteIndividualTicketDetails?: { __typename?: 'TicketDeleteIndividualDetailsNode', id: string, roleReassignData: any, approveStatus: boolean } | null, deleteHouseholdTicketDetails?: { __typename?: 'TicketDeleteHouseholdDetailsNode', id: string, approveStatus: boolean, reasonHousehold?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, systemFlaggingTicketDetails?: { __typename?: 'TicketSystemFlaggingDetailsNode', id: string, approveStatus: boolean, roleReassignData: any, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, fullName: string, birthDate: any, lastRegistrationDate: any, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, documentNumber: string, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> } }, sanctionListIndividual: { __typename?: 'SanctionListIndividualNode', id: string, fullName: string, referenceNumber: string, datesOfBirth: { __typename?: 'SanctionListIndividualDateOfBirthNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDateOfBirthNodeEdge', node?: { __typename?: 'SanctionListIndividualDateOfBirthNode', id: string, date: any } | null } | null> }, documents: { __typename?: 'SanctionListIndividualDocumentNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDocumentNodeEdge', node?: { __typename?: 'SanctionListIndividualDocumentNode', id: string, documentNumber: string, typeOfDocument: string } | null } | null> } } } | null, paymentVerificationTicketDetails?: { __typename?: 'TicketPaymentVerificationDetailsNode', id: string, newStatus?: TicketPaymentVerificationDetailsNewStatus | null, oldReceivedAmount?: number | null, newReceivedAmount?: number | null, approveStatus: boolean, paymentVerificationStatus: TicketPaymentVerificationDetailsPaymentVerificationStatus, hasMultiplePaymentVerifications?: boolean | null, paymentVerification?: { __typename?: 'PaymentVerificationNode', id: string, receivedAmount?: number | null } | null, paymentVerifications: { __typename?: 'PaymentVerificationNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', node?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null> } } | null, needsAdjudicationTicketDetails?: { __typename?: 'TicketNeedsAdjudicationDetailsNode', id: string, hasDuplicatedDocument?: boolean | null, isMultipleDuplicatesVersion: boolean, roleReassignData: any, extraData?: { __typename?: 'TicketNeedsAdjudicationDetailsExtraDataNode', goldenRecords?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null, possibleDuplicate?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, birthDate: any, lastRegistrationDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null }, possibleDuplicate?: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, possibleDuplicates?: Array<{ __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null> | null, selectedIndividual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, activeIndividualsCount?: number | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, selectedIndividuals?: Array<{ __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, activeIndividualsCount?: number | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null> | null } | null, ticketNotes: { __typename?: 'TicketNoteNodeConnection', edges: Array<{ __typename?: 'TicketNoteNodeEdge', node?: { __typename?: 'TicketNoteNode', id: string, createdAt: any, updatedAt: any, description: string, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null } | null> }, programs?: Array<{ __typename?: 'ProgramNode', name: string, id: string } | null> | null, documentation?: Array<{ __typename?: 'GrievanceDocumentNode', id: string, createdAt: any, updatedAt: any, name?: string | null, fileSize?: number | null, contentType: string, filePath?: string | null, fileName?: string | null, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null> | null } | null } | null };
+export type GrievanceTicketStatusChangeMutation = { __typename?: 'Mutations', grievanceStatusChange?: { __typename?: 'GrievanceStatusChangeMutation', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, category: number, consent: boolean, createdAt: any, updatedAt: any, description: string, language: string, admin?: string | null, area: string, adminUrl?: string | null, issueType?: number | null, priority?: number | null, urgency?: number | null, comments?: string | null, partner?: { __typename?: 'PartnerType', id: string, name: string } | null, businessArea: { __typename?: 'UserBusinessAreaNode', postponeDeduplication: boolean }, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, pCode?: string | null } | null, assignedTo?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, paymentRecord?: { __typename?: 'PaymentRecordAndPaymentNode', id?: string | null, caId?: string | null, deliveredQuantity?: number | null, entitlementQuantity?: number | null, objType?: string | null, parent?: { __typename?: 'CashPlanAndPaymentPlanNode', id?: string | null, unicefId?: string | null, objType?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null, relatedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, linkedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, category: number, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, existingTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, category: number, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, addIndividualTicketDetails?: { __typename?: 'TicketAddIndividualDetailsNode', id: string, individualData?: any | null, approveStatus: boolean, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, roleReassignData: any, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null, deleteIndividualTicketDetails?: { __typename?: 'TicketDeleteIndividualDetailsNode', id: string, roleReassignData: any, approveStatus: boolean } | null, deleteHouseholdTicketDetails?: { __typename?: 'TicketDeleteHouseholdDetailsNode', id: string, approveStatus: boolean, reasonHousehold?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, systemFlaggingTicketDetails?: { __typename?: 'TicketSystemFlaggingDetailsNode', id: string, approveStatus: boolean, roleReassignData: any, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, fullName: string, birthDate: any, lastRegistrationDate: any, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, documentNumber: string, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> } }, sanctionListIndividual: { __typename?: 'SanctionListIndividualNode', id: string, fullName: string, referenceNumber: string, datesOfBirth: { __typename?: 'SanctionListIndividualDateOfBirthNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDateOfBirthNodeEdge', node?: { __typename?: 'SanctionListIndividualDateOfBirthNode', id: string, date: any } | null } | null> }, documents: { __typename?: 'SanctionListIndividualDocumentNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDocumentNodeEdge', node?: { __typename?: 'SanctionListIndividualDocumentNode', id: string, documentNumber: string, typeOfDocument: string } | null } | null> } } } | null, paymentVerificationTicketDetails?: { __typename?: 'TicketPaymentVerificationDetailsNode', id: string, newStatus?: TicketPaymentVerificationDetailsNewStatus | null, oldReceivedAmount?: number | null, newReceivedAmount?: number | null, approveStatus: boolean, paymentVerificationStatus: TicketPaymentVerificationDetailsPaymentVerificationStatus, hasMultiplePaymentVerifications?: boolean | null, paymentVerification?: { __typename?: 'PaymentVerificationNode', id: string, receivedAmount?: number | null } | null, paymentVerifications: { __typename?: 'PaymentVerificationNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', node?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null> } } | null, needsAdjudicationTicketDetails?: { __typename?: 'TicketNeedsAdjudicationDetailsNode', id: string, hasDuplicatedDocument?: boolean | null, isMultipleDuplicatesVersion: boolean, roleReassignData: any, extraData?: { __typename?: 'TicketNeedsAdjudicationDetailsExtraDataNode', goldenRecords?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null, possibleDuplicate?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, birthDate: any, lastRegistrationDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null }, possibleDuplicate?: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, possibleDuplicates?: Array<{ __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null> | null, selectedIndividual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, activeIndividualsCount?: number | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, currency?: string | null, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, adminAreaTitle?: string | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, selectedIndividuals?: Array<{ __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, activeIndividualsCount?: number | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, currency?: string | null, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, adminAreaTitle?: string | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null> | null } | null, ticketNotes: { __typename?: 'TicketNoteNodeConnection', edges: Array<{ __typename?: 'TicketNoteNodeEdge', node?: { __typename?: 'TicketNoteNode', id: string, createdAt: any, updatedAt: any, description: string, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null } | null> }, programs?: Array<{ __typename?: 'ProgramNode', name: string, id: string } | null> | null, documentation?: Array<{ __typename?: 'GrievanceDocumentNode', id: string, createdAt: any, updatedAt: any, name?: string | null, fileSize?: number | null, contentType: string, filePath?: string | null, fileName?: string | null, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null> | null } | null } | null };
export type ReassignRoleGrievanceMutationVariables = Exact<{
grievanceTicketId: Scalars['ID']['input'];
@@ -10194,7 +10194,7 @@ export type GrievanceTicketQueryVariables = Exact<{
}>;
-export type GrievanceTicketQuery = { __typename?: 'Query', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, category: number, consent: boolean, createdAt: any, updatedAt: any, description: string, language: string, admin?: string | null, area: string, adminUrl?: string | null, issueType?: number | null, priority?: number | null, urgency?: number | null, comments?: string | null, partner?: { __typename?: 'PartnerType', id: string, name: string } | null, businessArea: { __typename?: 'UserBusinessAreaNode', postponeDeduplication: boolean }, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, pCode?: string | null } | null, assignedTo?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, paymentRecord?: { __typename?: 'PaymentRecordAndPaymentNode', id?: string | null, caId?: string | null, deliveredQuantity?: number | null, entitlementQuantity?: number | null, objType?: string | null, parent?: { __typename?: 'CashPlanAndPaymentPlanNode', id?: string | null, unicefId?: string | null, objType?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null, relatedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, linkedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, category: number, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, existingTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, category: number, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, addIndividualTicketDetails?: { __typename?: 'TicketAddIndividualDetailsNode', id: string, individualData?: any | null, approveStatus: boolean, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, roleReassignData: any, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null, deleteIndividualTicketDetails?: { __typename?: 'TicketDeleteIndividualDetailsNode', id: string, roleReassignData: any, approveStatus: boolean } | null, deleteHouseholdTicketDetails?: { __typename?: 'TicketDeleteHouseholdDetailsNode', id: string, approveStatus: boolean, reasonHousehold?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, systemFlaggingTicketDetails?: { __typename?: 'TicketSystemFlaggingDetailsNode', id: string, approveStatus: boolean, roleReassignData: any, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, fullName: string, birthDate: any, lastRegistrationDate: any, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, documentNumber: string, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> } }, sanctionListIndividual: { __typename?: 'SanctionListIndividualNode', id: string, fullName: string, referenceNumber: string, datesOfBirth: { __typename?: 'SanctionListIndividualDateOfBirthNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDateOfBirthNodeEdge', node?: { __typename?: 'SanctionListIndividualDateOfBirthNode', id: string, date: any } | null } | null> }, documents: { __typename?: 'SanctionListIndividualDocumentNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDocumentNodeEdge', node?: { __typename?: 'SanctionListIndividualDocumentNode', id: string, documentNumber: string, typeOfDocument: string } | null } | null> } } } | null, paymentVerificationTicketDetails?: { __typename?: 'TicketPaymentVerificationDetailsNode', id: string, newStatus?: TicketPaymentVerificationDetailsNewStatus | null, oldReceivedAmount?: number | null, newReceivedAmount?: number | null, approveStatus: boolean, paymentVerificationStatus: TicketPaymentVerificationDetailsPaymentVerificationStatus, hasMultiplePaymentVerifications?: boolean | null, paymentVerification?: { __typename?: 'PaymentVerificationNode', id: string, receivedAmount?: number | null } | null, paymentVerifications: { __typename?: 'PaymentVerificationNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', node?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null> } } | null, needsAdjudicationTicketDetails?: { __typename?: 'TicketNeedsAdjudicationDetailsNode', id: string, hasDuplicatedDocument?: boolean | null, isMultipleDuplicatesVersion: boolean, roleReassignData: any, extraData?: { __typename?: 'TicketNeedsAdjudicationDetailsExtraDataNode', goldenRecords?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null, possibleDuplicate?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, birthDate: any, lastRegistrationDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null }, possibleDuplicate?: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, possibleDuplicates?: Array<{ __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null> | null, selectedIndividual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, activeIndividualsCount?: number | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, selectedIndividuals?: Array<{ __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, activeIndividualsCount?: number | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null> | null } | null, ticketNotes: { __typename?: 'TicketNoteNodeConnection', edges: Array<{ __typename?: 'TicketNoteNodeEdge', node?: { __typename?: 'TicketNoteNode', id: string, createdAt: any, updatedAt: any, description: string, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null } | null> }, programs?: Array<{ __typename?: 'ProgramNode', name: string, id: string } | null> | null, documentation?: Array<{ __typename?: 'GrievanceDocumentNode', id: string, createdAt: any, updatedAt: any, name?: string | null, fileSize?: number | null, contentType: string, filePath?: string | null, fileName?: string | null, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null> | null } | null };
+export type GrievanceTicketQuery = { __typename?: 'Query', grievanceTicket?: { __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, category: number, consent: boolean, createdAt: any, updatedAt: any, description: string, language: string, admin?: string | null, area: string, adminUrl?: string | null, issueType?: number | null, priority?: number | null, urgency?: number | null, comments?: string | null, partner?: { __typename?: 'PartnerType', id: string, name: string } | null, businessArea: { __typename?: 'UserBusinessAreaNode', postponeDeduplication: boolean }, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, pCode?: string | null } | null, assignedTo?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, paymentRecord?: { __typename?: 'PaymentRecordAndPaymentNode', id?: string | null, caId?: string | null, deliveredQuantity?: number | null, entitlementQuantity?: number | null, objType?: string | null, parent?: { __typename?: 'CashPlanAndPaymentPlanNode', id?: string | null, unicefId?: string | null, objType?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null, relatedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, linkedTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, unicefId?: string | null, category: number, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, existingTickets?: Array<{ __typename?: 'GrievanceTicketNode', id: string, category: number, unicefId?: string | null, status: number, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null> | null, addIndividualTicketDetails?: { __typename?: 'TicketAddIndividualDetailsNode', id: string, individualData?: any | null, approveStatus: boolean, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, individualDataUpdateTicketDetails?: { __typename?: 'TicketIndividualDataUpdateDetailsNode', id: string, individualData?: any | null, roleReassignData: any, individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null } | null, householdDataUpdateTicketDetails?: { __typename?: 'TicketHouseholdDataUpdateDetailsNode', id: string, householdData?: any | null, household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null } | null, deleteIndividualTicketDetails?: { __typename?: 'TicketDeleteIndividualDetailsNode', id: string, roleReassignData: any, approveStatus: boolean } | null, deleteHouseholdTicketDetails?: { __typename?: 'TicketDeleteHouseholdDetailsNode', id: string, approveStatus: boolean, reasonHousehold?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } | null } | null, systemFlaggingTicketDetails?: { __typename?: 'TicketSystemFlaggingDetailsNode', id: string, approveStatus: boolean, roleReassignData: any, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, fullName: string, birthDate: any, lastRegistrationDate: any, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, documentNumber: string, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> } }, sanctionListIndividual: { __typename?: 'SanctionListIndividualNode', id: string, fullName: string, referenceNumber: string, datesOfBirth: { __typename?: 'SanctionListIndividualDateOfBirthNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDateOfBirthNodeEdge', node?: { __typename?: 'SanctionListIndividualDateOfBirthNode', id: string, date: any } | null } | null> }, documents: { __typename?: 'SanctionListIndividualDocumentNodeConnection', edges: Array<{ __typename?: 'SanctionListIndividualDocumentNodeEdge', node?: { __typename?: 'SanctionListIndividualDocumentNode', id: string, documentNumber: string, typeOfDocument: string } | null } | null> } } } | null, paymentVerificationTicketDetails?: { __typename?: 'TicketPaymentVerificationDetailsNode', id: string, newStatus?: TicketPaymentVerificationDetailsNewStatus | null, oldReceivedAmount?: number | null, newReceivedAmount?: number | null, approveStatus: boolean, paymentVerificationStatus: TicketPaymentVerificationDetailsPaymentVerificationStatus, hasMultiplePaymentVerifications?: boolean | null, paymentVerification?: { __typename?: 'PaymentVerificationNode', id: string, receivedAmount?: number | null } | null, paymentVerifications: { __typename?: 'PaymentVerificationNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', node?: { __typename?: 'PaymentVerificationNode', id: string } | null } | null> } } | null, needsAdjudicationTicketDetails?: { __typename?: 'TicketNeedsAdjudicationDetailsNode', id: string, hasDuplicatedDocument?: boolean | null, isMultipleDuplicatesVersion: boolean, roleReassignData: any, extraData?: { __typename?: 'TicketNeedsAdjudicationDetailsExtraDataNode', goldenRecords?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null, possibleDuplicate?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, goldenRecordsIndividual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, birthDate: any, lastRegistrationDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null }, possibleDuplicate?: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null, possibleDuplicates?: Array<{ __typename?: 'IndividualNode', id: string, unicefId?: string | null, lastRegistrationDate: any, fullName: string, birthDate: any, sex: IndividualSex, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', unicefId?: string | null, id: string, village: string, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null } | null, deduplicationGoldenRecordResults?: Array<{ __typename?: 'DeduplicationResultNode', hitId?: string | null, proximityToScore?: number | null, score?: number | null } | null> | null } | null> | null, selectedIndividual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, activeIndividualsCount?: number | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, currency?: string | null, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, adminAreaTitle?: string | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null, selectedIndividuals?: Array<{ __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, activeIndividualsCount?: number | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, adminUrl?: string | null, createdAt: any, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, currency?: string | null, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unhcrId: string, adminAreaTitle?: string | null, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, individual: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null> | null } | null, ticketNotes: { __typename?: 'TicketNoteNodeConnection', edges: Array<{ __typename?: 'TicketNoteNodeEdge', node?: { __typename?: 'TicketNoteNode', id: string, createdAt: any, updatedAt: any, description: string, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null } | null> }, programs?: Array<{ __typename?: 'ProgramNode', name: string, id: string } | null> | null, documentation?: Array<{ __typename?: 'GrievanceDocumentNode', id: string, createdAt: any, updatedAt: any, name?: string | null, fileSize?: number | null, contentType: string, filePath?: string | null, fileName?: string | null, createdBy?: { __typename?: 'UserNode', id: string, firstName: string, lastName: string, email: string } | null } | null> | null } | null };
export type GrievanceTicketFlexFieldsQueryVariables = Exact<{
id: Scalars['ID']['input'];
@@ -10267,7 +10267,7 @@ export type PaymentQueryVariables = Exact<{
}>;
-export type PaymentQuery = { __typename?: 'Query', payment?: { __typename?: 'PaymentNode', id: string, unicefId?: string | null, distributionModality?: string | null, status: PaymentStatus, statusDate: any, snapshotCollectorBankName?: string | null, snapshotCollectorBankAccountNumber?: string | null, debitCardNumber?: string | null, debitCardIssuer?: string | null, currency: string, entitlementQuantity?: number | null, deliveredQuantity?: number | null, deliveryDate?: any | null, deliveredQuantityUsd?: number | null, deliveryType?: PaymentDeliveryType | null, transactionReferenceId?: string | null, additionalCollectorName?: string | null, additionalDocumentType?: string | null, additionalDocumentNumber?: string | null, reasonForUnsuccessfulPayment?: string | null, snapshotCollectorFullName?: string | null, adminUrl?: string | null, targetPopulation?: { __typename?: 'TargetPopulationNode', id: string, name: string } | null, sourcePayment?: { __typename?: 'PaymentNode', id: string, unicefId?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string, status: PaymentVerificationStatus, statusDate?: any | null, receivedAmount?: number | null, isManuallyEditable?: boolean | null, adminUrl?: string | null } | null, household: { __typename?: 'HouseholdNode', id: string, size?: number | null, status?: string | null, unicefId?: string | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, phoneNo: string, phoneNoAlternative: string, phoneNoValid?: boolean | null, phoneNoAlternativeValid?: boolean | null, fullName: string } }, collector: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, email: string, phoneNo: string, phoneNoValid?: boolean | null, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null }, parent: { __typename?: 'PaymentPlanNode', id: string, status: PaymentPlanStatus, isFollowUp: boolean, unicefId?: string | null, program: { __typename?: 'ProgramNode', id: string, name: string }, verificationPlans?: { __typename?: 'PaymentVerificationPlanNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationPlanNodeEdge', node?: { __typename?: 'PaymentVerificationPlanNode', id: string, status: PaymentVerificationPlanStatus, verificationChannel: PaymentVerificationPlanVerificationChannel } | null } | null> } | null }, serviceProvider?: { __typename?: 'FinancialServiceProviderNode', id: string, fullName?: string | null } | null } | null };
+export type PaymentQuery = { __typename?: 'Query', payment?: { __typename?: 'PaymentNode', id: string, unicefId?: string | null, distributionModality?: string | null, status: PaymentStatus, statusDate: any, snapshotCollectorBankName?: string | null, snapshotCollectorBankAccountNumber?: string | null, debitCardNumber?: string | null, debitCardIssuer?: string | null, currency: string, entitlementQuantity?: number | null, deliveredQuantity?: number | null, deliveryDate?: any | null, deliveredQuantityUsd?: number | null, deliveryType?: PaymentDeliveryType | null, transactionReferenceId?: string | null, additionalCollectorName?: string | null, additionalDocumentType?: string | null, additionalDocumentNumber?: string | null, reasonForUnsuccessfulPayment?: string | null, snapshotCollectorFullName?: string | null, adminUrl?: string | null, targetPopulation?: { __typename?: 'TargetPopulationNode', id: string, name: string } | null, sourcePayment?: { __typename?: 'PaymentNode', id: string, unicefId?: string | null } | null, verification?: { __typename?: 'PaymentVerificationNode', id: string, status: PaymentVerificationStatus, statusDate?: any | null, receivedAmount?: number | null, isManuallyEditable?: boolean | null, adminUrl?: string | null } | null, household: { __typename?: 'HouseholdNode', id: string, size?: number | null, status?: string | null, unicefId?: string | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, phoneNo: string, phoneNoAlternative: string, phoneNoValid?: boolean | null, phoneNoAlternativeValid?: boolean | null, fullName: string } }, collector: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, email: string, phoneNo: string, phoneNoValid?: boolean | null, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null }, parent: { __typename?: 'PaymentPlanNode', id: string, status: PaymentPlanStatus, isFollowUp: boolean, unicefId?: string | null, program: { __typename?: 'ProgramNode', id: string, name: string }, verificationPlans?: { __typename?: 'PaymentVerificationPlanNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationPlanNodeEdge', node?: { __typename?: 'PaymentVerificationPlanNode', id: string, status: PaymentVerificationPlanStatus, verificationChannel: PaymentVerificationPlanVerificationChannel } | null } | null> } | null }, serviceProvider?: { __typename?: 'FinancialServiceProviderNode', id: string, fullName?: string | null } | null } | null };
export type PaymentPlanQueryVariables = Exact<{
id: Scalars['ID']['input'];
@@ -10353,7 +10353,7 @@ export type AllPaymentsForTableQueryVariables = Exact<{
}>;
-export type AllPaymentsForTableQuery = { __typename?: 'Query', allPayments?: { __typename?: 'PaymentNodeConnection', totalCount?: number | null, pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null, endCursor?: string | null }, edges: Array<{ __typename?: 'PaymentNodeEdge', cursor: string, node?: { __typename?: 'PaymentNode', id: string, unicefId?: string | null, status: PaymentStatus, entitlementQuantity?: number | null, entitlementQuantityUsd?: number | null, currency: string, deliveredQuantity?: number | null, deliveredQuantityUsd?: number | null, paymentPlanHardConflicted?: boolean | null, paymentPlanSoftConflicted?: boolean | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, size?: number | null, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null }, paymentPlanHardConflictedData?: Array<{ __typename?: 'PaymentConflictDataNode', paymentPlanUnicefId?: string | null, paymentPlanId?: string | null, paymentPlanStartDate?: string | null, paymentPlanEndDate?: string | null, paymentPlanStatus?: string | null, paymentId?: string | null, paymentUnicefId?: string | null } | null> | null, paymentPlanSoftConflictedData?: Array<{ __typename?: 'PaymentConflictDataNode', paymentPlanUnicefId?: string | null, paymentPlanId?: string | null, paymentPlanStartDate?: string | null, paymentPlanEndDate?: string | null, paymentPlanStatus?: string | null, paymentId?: string | null, paymentUnicefId?: string | null } | null> | null, collector: { __typename?: 'IndividualNode', id: string, fullName: string }, financialServiceProvider?: { __typename?: 'FinancialServiceProviderNode', id: string, name: string } | null } | null } | null> } | null };
+export type AllPaymentsForTableQuery = { __typename?: 'Query', allPayments?: { __typename?: 'PaymentNodeConnection', totalCount?: number | null, pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null, endCursor?: string | null }, edges: Array<{ __typename?: 'PaymentNodeEdge', cursor: string, node?: { __typename?: 'PaymentNode', id: string, unicefId?: string | null, status: PaymentStatus, entitlementQuantity?: number | null, entitlementQuantityUsd?: number | null, currency: string, deliveredQuantity?: number | null, deliveredQuantityUsd?: number | null, paymentPlanHardConflicted?: boolean | null, paymentPlanSoftConflicted?: boolean | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, size?: number | null, admin2?: { __typename?: 'AreaNode', id: string, name: string } | null, individuals?: { __typename?: 'IndividualNodeConnection', edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string } | null } | null> } | null }, paymentPlanHardConflictedData?: Array<{ __typename?: 'PaymentConflictDataNode', paymentPlanUnicefId?: string | null, paymentPlanId?: string | null, paymentPlanStartDate?: string | null, paymentPlanEndDate?: string | null, paymentPlanStatus?: string | null, paymentId?: string | null, paymentUnicefId?: string | null } | null> | null, paymentPlanSoftConflictedData?: Array<{ __typename?: 'PaymentConflictDataNode', paymentPlanUnicefId?: string | null, paymentPlanId?: string | null, paymentPlanStartDate?: string | null, paymentPlanEndDate?: string | null, paymentPlanStatus?: string | null, paymentId?: string | null, paymentUnicefId?: string | null } | null> | null, collector: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string }, financialServiceProvider?: { __typename?: 'FinancialServiceProviderNode', id: string, name: string } | null } | null } | null> } | null };
export type CashPlanQueryVariables = Exact<{
id: Scalars['ID']['input'];
@@ -10395,7 +10395,7 @@ export type PaymentRecordQueryVariables = Exact<{
}>;
-export type PaymentRecordQuery = { __typename?: 'Query', paymentRecord?: { __typename?: 'PaymentRecordNode', id: string, status: PaymentRecordStatus, statusDate: any, caId?: string | null, caHashId?: any | null, registrationCaId?: string | null, fullName: string, distributionModality: string, totalPersonsCovered: number, currency: string, entitlementQuantity?: number | null, deliveredQuantity?: number | null, deliveryDate?: any | null, entitlementCardIssueDate?: any | null, entitlementCardNumber?: string | null, deliveredQuantityUsd?: number | null, deliveryType?: PaymentRecordDeliveryType | null, transactionReferenceId?: string | null, targetPopulation: { __typename?: 'TargetPopulationNode', id: string, name: string }, verification?: { __typename?: 'PaymentVerificationNode', id: string, status: PaymentVerificationStatus, statusDate?: any | null, receivedAmount?: number | null, isManuallyEditable?: boolean | null, adminUrl?: string | null } | null, household: { __typename?: 'HouseholdNode', id: string, size?: number | null, status?: string | null, unicefId?: string | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, phoneNo: string, phoneNoAlternative: string, phoneNoValid?: boolean | null, phoneNoAlternativeValid?: boolean | null } }, parent?: { __typename?: 'CashPlanNode', id: string, unicefId?: string | null, caId?: string | null, program: { __typename?: 'ProgramNode', id: string, name: string }, verificationPlans?: { __typename?: 'PaymentVerificationPlanNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationPlanNodeEdge', node?: { __typename?: 'PaymentVerificationPlanNode', id: string, status: PaymentVerificationPlanStatus, verificationChannel: PaymentVerificationPlanVerificationChannel } | null } | null> } | null } | null, serviceProvider: { __typename?: 'ServiceProviderNode', id: string, fullName?: string | null, shortName?: string | null } } | null };
+export type PaymentRecordQuery = { __typename?: 'Query', paymentRecord?: { __typename?: 'PaymentRecordNode', id: string, status: PaymentRecordStatus, statusDate: any, caId?: string | null, caHashId?: any | null, registrationCaId?: string | null, fullName: string, distributionModality: string, totalPersonsCovered: number, currency: string, entitlementQuantity?: number | null, deliveredQuantity?: number | null, deliveryDate?: any | null, entitlementCardIssueDate?: any | null, entitlementCardNumber?: string | null, deliveredQuantityUsd?: number | null, deliveryType?: PaymentRecordDeliveryType | null, transactionReferenceId?: string | null, targetPopulation: { __typename?: 'TargetPopulationNode', id: string, name: string }, verification?: { __typename?: 'PaymentVerificationNode', id: string, status: PaymentVerificationStatus, statusDate?: any | null, receivedAmount?: number | null, isManuallyEditable?: boolean | null, adminUrl?: string | null } | null, household: { __typename?: 'HouseholdNode', id: string, size?: number | null, status?: string | null, unicefId?: string | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, phoneNo: string, phoneNoAlternative: string, phoneNoValid?: boolean | null, phoneNoAlternativeValid?: boolean | null, fullName: string } }, parent?: { __typename?: 'CashPlanNode', id: string, unicefId?: string | null, caId?: string | null, program: { __typename?: 'ProgramNode', id: string, name: string }, verificationPlans?: { __typename?: 'PaymentVerificationPlanNodeConnection', edges: Array<{ __typename?: 'PaymentVerificationPlanNodeEdge', node?: { __typename?: 'PaymentVerificationPlanNode', id: string, status: PaymentVerificationPlanStatus, verificationChannel: PaymentVerificationPlanVerificationChannel } | null } | null> } | null } | null, serviceProvider: { __typename?: 'ServiceProviderNode', id: string, fullName?: string | null, shortName?: string | null } } | null };
export type AllPaymentVerificationLogEntriesQueryVariables = Exact<{
businessArea: Scalars['String']['input'];
@@ -10427,7 +10427,7 @@ export type AllPaymentVerificationsQueryVariables = Exact<{
}>;
-export type AllPaymentVerificationsQuery = { __typename?: 'Query', allPaymentVerifications?: { __typename?: 'PaymentVerificationNodeConnection', totalCount?: number | null, pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null, endCursor?: string | null }, edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', cursor: string, node?: { __typename?: 'PaymentVerificationNode', id: string, status: PaymentVerificationStatus, receivedAmount?: number | null, paymentVerificationPlan: { __typename?: 'PaymentVerificationPlanNode', id: string, unicefId?: string | null, verificationChannel: PaymentVerificationPlanVerificationChannel }, payment?: { __typename?: 'GenericPaymentNode', id?: string | null, unicefId?: string | null, deliveredQuantity?: number | null, currency?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, unicefId?: string | null, id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, familyName: string, phoneNo: string, phoneNoAlternative: string } } | null } | null } | null } | null> } | null };
+export type AllPaymentVerificationsQuery = { __typename?: 'Query', allPaymentVerifications?: { __typename?: 'PaymentVerificationNodeConnection', totalCount?: number | null, pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null, endCursor?: string | null }, edges: Array<{ __typename?: 'PaymentVerificationNodeEdge', cursor: string, node?: { __typename?: 'PaymentVerificationNode', id: string, status: PaymentVerificationStatus, receivedAmount?: number | null, paymentVerificationPlan: { __typename?: 'PaymentVerificationPlanNode', id: string, unicefId?: string | null, verificationChannel: PaymentVerificationPlanVerificationChannel }, payment?: { __typename?: 'GenericPaymentNode', id?: string | null, unicefId?: string | null, deliveredQuantity?: number | null, currency?: string | null, household?: { __typename?: 'HouseholdNode', status?: string | null, unicefId?: string | null, id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, unicefId?: string | null, fullName: string, familyName: string, phoneNo: string, phoneNoAlternative: string } } | null } | null } | null } | null> } | null };
export type AllRapidProFlowsQueryVariables = Exact<{
businessAreaSlug: Scalars['String']['input'];
@@ -10585,7 +10585,7 @@ export type HouseholdQueryVariables = Exact<{
}>;
-export type HouseholdQuery = { __typename?: 'Query', household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null };
+export type HouseholdQuery = { __typename?: 'Query', household?: { __typename?: 'HouseholdNode', activeIndividualsCount?: number | null, countryOrigin?: string | null, country?: string | null, zipCode?: string | null, femaleAgeGroup05Count?: number | null, femaleAgeGroup611Count?: number | null, femaleAgeGroup1217Count?: number | null, femaleAgeGroup1859Count?: number | null, femaleAgeGroup60Count?: number | null, pregnantCount?: number | null, maleAgeGroup05Count?: number | null, maleAgeGroup611Count?: number | null, maleAgeGroup1217Count?: number | null, maleAgeGroup1859Count?: number | null, maleAgeGroup60Count?: number | null, femaleAgeGroup05DisabledCount?: number | null, femaleAgeGroup611DisabledCount?: number | null, femaleAgeGroup1217DisabledCount?: number | null, femaleAgeGroup1859DisabledCount?: number | null, femaleAgeGroup60DisabledCount?: number | null, maleAgeGroup05DisabledCount?: number | null, maleAgeGroup611DisabledCount?: number | null, maleAgeGroup1217DisabledCount?: number | null, maleAgeGroup1859DisabledCount?: number | null, maleAgeGroup60DisabledCount?: number | null, fchildHoh?: boolean | null, childHoh?: boolean | null, start?: any | null, deviceid: string, orgNameEnumerator: string, returnee?: boolean | null, address: string, nameEnumerator: string, lastSyncAt?: any | null, consentSharing?: Array | null, orgEnumerator: HouseholdOrgEnumerator, updatedAt: any, consent?: boolean | null, collectIndividualData: HouseholdCollectIndividualData, flexFields?: any | null, registrationId?: string | null, id: string, status?: string | null, adminUrl?: string | null, createdAt: any, residenceStatus?: string | null, maleChildrenCount?: number | null, femaleChildrenCount?: number | null, childrenDisabledCount?: number | null, size?: number | null, totalCashReceived?: any | null, totalCashReceivedUsd?: any | null, currency?: string | null, firstRegistrationDate: any, lastRegistrationDate: any, sanctionListPossibleMatch?: boolean | null, sanctionListConfirmedMatch?: boolean | null, hasDuplicates?: boolean | null, unicefId?: string | null, unhcrId: string, geopoint?: any | null, village: string, adminAreaTitle?: string | null, individuals?: { __typename?: 'IndividualNodeConnection', totalCount?: number | null, edges: Array<{ __typename?: 'IndividualNodeEdge', node?: { __typename?: 'IndividualNode', id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, email: string, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, countryIso3?: string | null, documentNumber: string, photo?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> }, household?: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null, status?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null } | null } | null> } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> }, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, paymentrecordSet: { __typename?: 'PaymentRecordNodeConnection', edges: Array<{ __typename?: 'PaymentRecordNodeEdge', node?: { __typename?: 'PaymentRecordNode', id: string, fullName: string, parent?: { __typename?: 'CashPlanNode', id: string, totalPersonsCovered: number, totalDeliveredQuantity?: number | null, assistanceMeasurement: string, program: { __typename?: 'ProgramNode', id: string, name: string } } | null } | null } | null> }, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin3?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin4?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, headOfHousehold: { __typename?: 'IndividualNode', id: string, fullName: string, givenName: string, familyName: string } } | null };
export type HouseholdChoiceDataQueryVariables = Exact<{ [key: string]: never; }>;
@@ -10604,7 +10604,7 @@ export type IndividualQueryVariables = Exact<{
}>;
-export type IndividualQuery = { __typename?: 'Query', individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, address: string, countryOrigin?: string | null, unicefId?: string | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null };
+export type IndividualQuery = { __typename?: 'Query', individual?: { __typename?: 'IndividualNode', givenName: string, familyName: string, estimatedBirthDate?: boolean | null, pregnant?: boolean | null, lastSyncAt?: any | null, deduplicationBatchStatus: IndividualDeduplicationBatchStatus, disability: IndividualDisability, importedIndividualId?: any | null, commsDisability: string, firstRegistrationDate: any, whoAnswersAltPhone: string, memoryDisability: string, middleName: string, whoAnswersPhone: string, phoneNoAlternative: string, phoneNoAlternativeValid?: boolean | null, email: string, hearingDisability: string, observedDisability?: Array | null, individualId: string, seeingDisability: string, physicalDisability: string, selfcareDisability: string, photo?: string | null, workStatus: string, enrolledInNutritionProgramme?: boolean | null, administrationOfRutf?: boolean | null, flexFields?: any | null, preferredLanguage?: string | null, paymentDeliveryPhoneNo?: string | null, id: string, age?: number | null, lastRegistrationDate: any, adminUrl?: string | null, createdAt: any, updatedAt: any, fullName: string, sex: IndividualSex, unicefId?: string | null, birthDate: any, maritalStatus: IndividualMaritalStatus, phoneNo: string, phoneNoValid?: boolean | null, sanctionListPossibleMatch: boolean, sanctionListConfirmedMatch: boolean, deduplicationGoldenRecordStatus: IndividualDeduplicationGoldenRecordStatus, sanctionListLastCheck?: any | null, role?: string | null, relationship?: IndividualRelationship | null, status?: string | null, paymentChannels?: Array<{ __typename?: 'BankAccountInfoNode', id: string, bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null> | null, documents: { __typename?: 'DocumentNodeConnection', edges: Array<{ __typename?: 'DocumentNodeEdge', node?: { __typename?: 'DocumentNode', id: string, country?: string | null, photo?: string | null, documentNumber: string, countryIso3?: string | null, type: { __typename?: 'DocumentTypeNode', label: string, key: string } } | null } | null> }, household?: { __typename?: 'HouseholdNode', status?: string | null, id: string, residenceStatus?: string | null, address: string, village: string, zipCode?: string | null, geopoint?: any | null, country?: string | null, countryOrigin?: string | null, unicefId?: string | null, totalCashReceivedUsd?: any | null, lastRegistrationDate: any, start?: any | null, firstRegistrationDate: any, registrationDataImport?: { __typename?: 'RegistrationDataImportNode', name: string, dataSource: RegistrationDataImportDataSource, importDate: any, importedBy?: { __typename?: 'UserNode', firstName: string, lastName: string, email: string, username: string } | null } | null, deliveredQuantities?: Array<{ __typename?: 'DeliveredQuantityNode', totalDeliveredQuantity?: any | null, currency?: string | null } | null> | null, adminArea?: { __typename?: 'AreaNode', id: string, name: string, level: number } | null, admin1?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, admin2?: { __typename?: 'AreaNode', id: string, name: string, level: number, pCode?: string | null } | null, programs: { __typename?: 'ProgramNodeConnection', edges: Array<{ __typename?: 'ProgramNodeEdge', node?: { __typename?: 'ProgramNode', id: string, name: string } | null } | null> } } | null, headingHousehold?: { __typename?: 'HouseholdNode', id: string, headOfHousehold: { __typename?: 'IndividualNode', id: string, givenName: string, familyName: string, fullName: string } } | null, householdsAndRoles: Array<{ __typename?: 'IndividualRoleInHouseholdNode', id: any, role?: IndividualRoleInHouseholdRole | null, household: { __typename?: 'HouseholdNode', id: string, unicefId?: string | null } }>, bankAccountInfo?: { __typename?: 'BankAccountInfoNode', bankName: string, bankAccountNumber: string, accountHolderName: string, bankBranchName: string } | null, identities: { __typename?: 'IndividualIdentityNodeConnection', edges: Array<{ __typename?: 'IndividualIdentityNodeEdge', node?: { __typename?: 'IndividualIdentityNode', id: string, partner?: string | null, country?: string | null, number: string } | null } | null> } } | null };
export type IndividualChoiceDataQueryVariables = Exact<{ [key: string]: never; }>;
@@ -11130,6 +11130,10 @@ export const IndividualMinimalFragmentDoc = gql`
}
}
}
+ totalCashReceivedUsd
+ lastRegistrationDate
+ start
+ firstRegistrationDate
}
}
`;
@@ -11186,10 +11190,30 @@ export const IndividualDetailedFragmentDoc = gql`
enrolledInNutritionProgramme
administrationOfRutf
household {
+ registrationDataImport {
+ name
+ dataSource
+ importDate
+ importedBy {
+ firstName
+ lastName
+ email
+ username
+ }
+ }
status
id
+ residenceStatus
address
+ village
+ zipCode
+ geopoint
+ country
countryOrigin
+ deliveredQuantities {
+ totalDeliveredQuantity
+ currency
+ }
adminArea {
id
name
@@ -18188,6 +18212,7 @@ export const PaymentDocument = gql`
unicefId
headOfHousehold {
id
+ unicefId
phoneNo
phoneNoAlternative
phoneNoValid
@@ -18984,6 +19009,15 @@ export const AllPaymentsForTableDocument = gql`
id
name
}
+ individuals {
+ edges {
+ node {
+ id
+ unicefId
+ fullName
+ }
+ }
+ }
}
entitlementQuantity
entitlementQuantityUsd
@@ -19012,6 +19046,7 @@ export const AllPaymentsForTableDocument = gql`
}
collector {
id
+ unicefId
fullName
}
financialServiceProvider {
@@ -19396,10 +19431,12 @@ export const PaymentRecordDocument = gql`
unicefId
headOfHousehold {
id
+ unicefId
phoneNo
phoneNoAlternative
phoneNoValid
phoneNoAlternativeValid
+ fullName
}
}
parent {
@@ -19600,6 +19637,7 @@ export const AllPaymentVerificationsDocument = gql`
id
headOfHousehold {
id
+ unicefId
fullName
familyName
phoneNo
diff --git a/frontend/src/apollo/fragments/IndividualFragments.ts b/frontend/src/apollo/fragments/IndividualFragments.ts
index e6fe557b68..dcb2c2959f 100644
--- a/frontend/src/apollo/fragments/IndividualFragments.ts
+++ b/frontend/src/apollo/fragments/IndividualFragments.ts
@@ -72,6 +72,10 @@ export const individualMinimal = gql`
}
}
}
+ totalCashReceivedUsd
+ lastRegistrationDate
+ start
+ firstRegistrationDate
}
}
`;
@@ -129,10 +133,30 @@ export const individualDetailed = gql`
enrolledInNutritionProgramme
administrationOfRutf
household {
+ registrationDataImport {
+ name
+ dataSource
+ importDate
+ importedBy {
+ firstName
+ lastName
+ email
+ username
+ }
+ }
status
id
+ residenceStatus
address
+ village
+ zipCode
+ geopoint
+ country
countryOrigin
+ deliveredQuantities {
+ totalDeliveredQuantity
+ currency
+ }
adminArea {
id
name
diff --git a/frontend/src/apollo/queries/paymentmodule/Payment.ts b/frontend/src/apollo/queries/paymentmodule/Payment.ts
index 9711020cab..7b16b50c4a 100644
--- a/frontend/src/apollo/queries/paymentmodule/Payment.ts
+++ b/frontend/src/apollo/queries/paymentmodule/Payment.ts
@@ -39,6 +39,7 @@ export const Payment = gql`
unicefId
headOfHousehold {
id
+ unicefId
phoneNo
phoneNoAlternative
phoneNoValid
diff --git a/frontend/src/apollo/queries/payments/AllPaymentsForTable.ts b/frontend/src/apollo/queries/payments/AllPaymentsForTable.ts
index b432b9ae2d..71f1cee9b7 100644
--- a/frontend/src/apollo/queries/payments/AllPaymentsForTable.ts
+++ b/frontend/src/apollo/queries/payments/AllPaymentsForTable.ts
@@ -40,6 +40,15 @@ export const AllPaymentsForTable = gql`
id
name
}
+ individuals {
+ edges {
+ node {
+ id
+ unicefId
+ fullName
+ }
+ }
+ }
}
entitlementQuantity
entitlementQuantityUsd
@@ -68,6 +77,7 @@ export const AllPaymentsForTable = gql`
}
collector {
id
+ unicefId
fullName
}
financialServiceProvider {
diff --git a/frontend/src/apollo/queries/payments/PaymentRecord.ts b/frontend/src/apollo/queries/payments/PaymentRecord.ts
index b03185c93d..c1c0f5c29e 100644
--- a/frontend/src/apollo/queries/payments/PaymentRecord.ts
+++ b/frontend/src/apollo/queries/payments/PaymentRecord.ts
@@ -37,10 +37,12 @@ export const PAYMENT_RECORD_QUERY = gql`
unicefId
headOfHousehold {
id
+ unicefId
phoneNo
phoneNoAlternative
phoneNoValid
phoneNoAlternativeValid
+ fullName
}
}
parent {
diff --git a/frontend/src/apollo/queries/payments/verification/AllPaymentVerifications.ts b/frontend/src/apollo/queries/payments/verification/AllPaymentVerifications.ts
index 008586441e..da63ceba93 100644
--- a/frontend/src/apollo/queries/payments/verification/AllPaymentVerifications.ts
+++ b/frontend/src/apollo/queries/payments/verification/AllPaymentVerifications.ts
@@ -54,6 +54,7 @@ export const AllPaymentVerifications = gql`
id
headOfHousehold {
id
+ unicefId
fullName
familyName
phoneNo
diff --git a/frontend/src/components/core/Drawer/menuItems.tsx b/frontend/src/components/core/Drawer/menuItems.tsx
index e702744f9a..002523cb86 100644
--- a/frontend/src/components/core/Drawer/menuItems.tsx
+++ b/frontend/src/components/core/Drawer/menuItems.tsx
@@ -35,12 +35,11 @@ export type MenuItem = {
flag?: string;
external?: boolean;
scopes: string[];
- isSocialWorker?: boolean
+ isSocialWorker?: boolean;
};
export const SCOPE_PROGRAM = 'SCOPE_PROGRAM';
export const SCOPE_ALL_PROGRAMS = 'SCOPE_ALL_PROGRAMS';
-
export const menuItems: MenuItem[] = [
{
name: 'Country Dashboard',
@@ -55,16 +54,6 @@ export const menuItems: MenuItem[] = [
href: '/registration-data-import',
selectedRegexp: /^\/registration-data-import.*$/,
icon: ,
- isSocialWorker: false,
- permissions: [PERMISSIONS.RDI_VIEW_DETAILS, PERMISSIONS.RDI_VIEW_LIST],
- scopes: [SCOPE_PROGRAM],
- },
- {
- name: 'Registration Data Import',
- href: '/registration-data-import-for-people',
- selectedRegexp: /^\/registration-data-import.*$/,
- icon: ,
- isSocialWorker: true,
permissions: [PERMISSIONS.RDI_VIEW_DETAILS, PERMISSIONS.RDI_VIEW_LIST],
scopes: [SCOPE_PROGRAM],
},
diff --git a/frontend/src/components/core/Table/TableComponent.tsx b/frontend/src/components/core/Table/TableComponent.tsx
index 87c765640d..2ae099617a 100644
--- a/frontend/src/components/core/Table/TableComponent.tsx
+++ b/frontend/src/components/core/Table/TableComponent.tsx
@@ -27,6 +27,7 @@ const Root = styled('div')`
const Paper = styled(MuiPaper)`
width: 100%;
margin-bottom: 8px;
+ overflow: clip;
`;
const Table = styled(MuiTable)`
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.tsx b/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.tsx
index c6dd72e03c..44ac95c41f 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.tsx
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.tsx
@@ -1,26 +1,14 @@
import Step from '@mui/material/Step';
import StepLabel from '@mui/material/StepLabel';
import Stepper from '@mui/material/Stepper';
-import CancelIcon from '@mui/icons-material/Cancel';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
-import styled from 'styled-components';
import { PaymentPlanQuery } from '@generated/graphql';
-import { StepIconProps } from '@mui/material';
-
-const StyledCancelIcon = styled(CancelIcon)`
- color: #e90202;
-`;
interface AcceptanceProcessStepperProps {
acceptanceProcess: PaymentPlanQuery['paymentPlan']['approvalProcess']['edges'][0]['node'];
}
-const StepIconWrapper: React.FC = (props) => {
- const { error } = props;
- return error ? : null;
-};
-
export function AcceptanceProcessStepper({
acceptanceProcess,
}: AcceptanceProcessStepperProps): React.ReactElement {
@@ -70,12 +58,7 @@ export function AcceptanceProcessStepper({
{steps.map((step) => (
-
- {step.name}
-
+ {step.name}
))}
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/__snapshots__/AcceptanceProcessRow.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/__snapshots__/AcceptanceProcessRow.test.tsx.snap
index efb0d6f90b..7a81fdfaba 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/__snapshots__/AcceptanceProcessRow.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/__snapshots__/AcceptanceProcessRow.test.tsx.snap
@@ -3,7 +3,7 @@
exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow should render 1`] = `
Sent for approval by Root Rootkowski
on
@@ -164,7 +164,7 @@ exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/Acceptanc
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/FspSection.tsx b/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/FspSection.tsx
index 6c90ee58d9..f860d4bccc 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/FspSection.tsx
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/FspSection.tsx
@@ -14,10 +14,10 @@ interface FspSectionProps {
paymentPlan: PaymentPlanQuery['paymentPlan'];
}
-export function FspSection({
+export const FspSection = ({
baseUrl,
paymentPlan,
-}: FspSectionProps): React.ReactElement {
+}: FspSectionProps): React.ReactElement => {
const { t } = useTranslation();
const { id } = useParams();
const { isActiveProgram } = useProgramContext();
@@ -64,7 +64,7 @@ export function FspSection({
{deliveryMechanisms.map((el) => (
<>
-
+
{el.chosenConfiguration && (
@@ -108,4 +108,4 @@ export function FspSection({
);
-}
+};
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/__snapshots__/FspSection.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/__snapshots__/FspSection.test.tsx.snap
index ab4b7cab8d..2e2f368f76 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/__snapshots__/FspSection.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/FspSection/__snapshots__/FspSection.test.tsx.snap
@@ -17,12 +17,14 @@ exports[`components/paymentmodule/PaymentPlanDetails/FspSection should render Ed
FSPs
Edit FSP
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/__snapshots__/ImportXlsxPaymentPlanPaymentList.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/__snapshots__/ImportXlsxPaymentPlanPaymentList.test.tsx.snap
index ab32a0dd96..8a98fe1402 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/__snapshots__/ImportXlsxPaymentPlanPaymentList.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/__snapshots__/ImportXlsxPaymentPlanPaymentList.test.tsx.snap
@@ -6,10 +6,9 @@ exports[`components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymen
class="MuiBox-root css-0"
>
Upload File
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/__snapshots__/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/__snapshots__/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx.snap
index 1cd192e7de..23514352ac 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/__snapshots__/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/__snapshots__/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx.snap
@@ -8,10 +8,9 @@ exports[`components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymen
class="MuiBox-root css-0"
>
Upload Reconciliation Info
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/AcceptedPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/AcceptedPaymentPlanHeaderButtons.test.tsx.snap
index d98b82a59c..5f30b8cb0e 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/AcceptedPaymentPlanHeaderButtons.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/AcceptedPaymentPlanHeaderButtons.test.tsx.snap
@@ -110,10 +110,9 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/He
class="MuiBox-root css-1ynyhby"
>
Export Xlsx
+
Approve
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InAuthorizationPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InAuthorizationPaymentPlanHeaderButtons.test.tsx.snap
index 3af7a42e17..c888f0a2cb 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InAuthorizationPaymentPlanHeaderButtons.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InAuthorizationPaymentPlanHeaderButtons.test.tsx.snap
@@ -23,13 +23,15 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/He
class="MuiBox-root css-hpgf8j"
>
Authorize
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InReviewPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InReviewPaymentPlanHeaderButtons.test.tsx.snap
index a0cfbf55b6..dccbd8e964 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InReviewPaymentPlanHeaderButtons.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InReviewPaymentPlanHeaderButtons.test.tsx.snap
@@ -23,13 +23,15 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/He
class="MuiBox-root css-hpgf8j"
>
Mark as released
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/LockedPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/LockedPaymentPlanHeaderButtons.test.tsx.snap
index ff59c49adc..39fd92a70f 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/LockedPaymentPlanHeaderButtons.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/LockedPaymentPlanHeaderButtons.test.tsx.snap
@@ -9,13 +9,15 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/He
class="MuiBox-root css-hpgf8j"
>
Lock FSP
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/OpenPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/OpenPaymentPlanHeaderButtons.test.tsx.snap
index 669d84c029..2653fdf16b 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/OpenPaymentPlanHeaderButtons.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/OpenPaymentPlanHeaderButtons.test.tsx.snap
@@ -9,9 +9,8 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/He
class="MuiBox-root css-hpgf8j"
>
+
Approve
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/AuthorizePaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/AuthorizePaymentPlan.test.tsx.snap
index 4198408cbb..37fd359063 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/AuthorizePaymentPlan.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/AuthorizePaymentPlan.test.tsx.snap
@@ -6,13 +6,15 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/Au
class="MuiBox-root css-hpgf8j"
>
Authorize
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/DeletePaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/DeletePaymentPlan.test.tsx.snap
index 2f3eabf90d..11626906a4 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/DeletePaymentPlan.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/DeletePaymentPlan.test.tsx.snap
@@ -6,9 +6,8 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/De
class="MuiBox-root css-hpgf8j"
>
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/MarkAsReleasedPaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/MarkAsReleasedPaymentPlan.test.tsx.snap
index ec84606438..1e7d743b4c 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/MarkAsReleasedPaymentPlan.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/MarkAsReleasedPaymentPlan.test.tsx.snap
@@ -6,13 +6,15 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/Ma
class="MuiBox-root css-hpgf8j"
>
Mark as released
+
diff --git a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/PaymentPlanDetailsHeader.test.tsx.snap b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/PaymentPlanDetailsHeader.test.tsx.snap
index ec84606438..1e7d743b4c 100644
--- a/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/PaymentPlanDetailsHeader.test.tsx.snap
+++ b/frontend/src/components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/PaymentPlanDetailsHeader.test.tsx.snap
@@ -6,13 +6,15 @@ exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/Ma
class="MuiBox-root css-hpgf8j"
>
Mark as released
+
diff --git a/frontend/src/components/paymentmodulepeople/CreateFollowUpPaymentPlan/CreateFollowUpPaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/CreateFollowUpPaymentPlan/CreateFollowUpPaymentPlan.tsx
new file mode 100644
index 0000000000..76ec71820e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateFollowUpPaymentPlan/CreateFollowUpPaymentPlan.tsx
@@ -0,0 +1,267 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ Grid,
+ Typography,
+} from '@mui/material';
+import CalendarTodayRoundedIcon from '@mui/icons-material/CalendarTodayRounded';
+import { Field, Form, Formik } from 'formik';
+import moment from 'moment';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import * as Yup from 'yup';
+import { useNavigate } from 'react-router-dom';
+import {
+ PaymentPlanQuery,
+ useCreateFollowUpPpMutation,
+} from '@generated/graphql';
+import { PERMISSIONS, hasPermissions } from '../../../config/permissions';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { usePermissions } from '@hooks/usePermissions';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { FormikDateField } from '@shared/Formik/FormikDateField';
+import { today, tomorrow } from '@utils/utils';
+import { DividerLine } from '@core/DividerLine';
+import { FieldBorder } from '@core/FieldBorder';
+import { GreyText } from '@core/GreyText';
+import { LabelizedField } from '@core/LabelizedField';
+import { LoadingButton } from '@core/LoadingButton';
+import { useProgramContext } from '../../../programContext';
+
+export interface CreateFollowUpPaymentPlanProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function CreateFollowUpPaymentPlan({
+ paymentPlan,
+}: CreateFollowUpPaymentPlanProps): React.ReactElement {
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const { baseUrl } = useBaseUrl();
+ const permissions = usePermissions();
+ const [mutate, { loading }] = useCreateFollowUpPpMutation();
+ const { isActiveProgram } = useProgramContext();
+ const { showMessage } = useSnackbar();
+
+ const { id, totalWithdrawnHouseholdsCount, unsuccessfulPaymentsCount } =
+ paymentPlan;
+
+ if (permissions === null) return null;
+
+ const validationSchema = Yup.object().shape({
+ dispersionStartDate: Yup.date().required(
+ t('Dispersion Start Date is required'),
+ ),
+ dispersionEndDate: Yup.date()
+ .required(t('Dispersion End Date is required'))
+ .min(today, t('Dispersion End Date cannot be in the past'))
+ .when(
+ 'dispersionStartDate',
+ (dispersionStartDate: any, schema: Yup.DateSchema) =>
+ dispersionStartDate
+ ? schema.min(
+ new Date(dispersionStartDate),
+ `${t('Dispersion End Date has to be greater than')} ${moment(
+ dispersionStartDate,
+ ).format('YYYY-MM-DD')}`,
+ )
+ : schema,
+ ),
+ });
+
+ type FormValues = Yup.InferType;
+ const initialValues: FormValues = {
+ dispersionStartDate: null,
+ dispersionEndDate: null,
+ };
+
+ const handleSubmit = async (values: FormValues): Promise => {
+ try {
+ const res = await mutate({
+ variables: {
+ paymentPlanId: id,
+ dispersionStartDate: values.dispersionStartDate,
+ dispersionEndDate: values.dispersionEndDate,
+ },
+ });
+ setDialogOpen(false);
+ showMessage(t('Payment Plan Created'));
+ navigate(
+ `/${baseUrl}/payment-module/followup-payment-plans/${res.data.createFollowUpPaymentPlan.paymentPlan.id}`,
+ );
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ return (
+
+ {({ submitForm, values }) => (
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/CreateFollowUpPaymentPlan/index.tsx b/frontend/src/components/paymentmodulepeople/CreateFollowUpPaymentPlan/index.tsx
new file mode 100644
index 0000000000..d7e8301ae6
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateFollowUpPaymentPlan/index.tsx
@@ -0,0 +1 @@
+export { CreateFollowUpPaymentPlan } from './CreateFollowUpPaymentPlan';
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/CreatePaymentPlanHeader.test.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/CreatePaymentPlanHeader.test.tsx
new file mode 100644
index 0000000000..3fd618a996
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/CreatePaymentPlanHeader.test.tsx
@@ -0,0 +1,19 @@
+import * as React from 'react';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { render } from '../../../../testUtils/testUtils';
+import { CreatePaymentPlanHeader } from './CreatePaymentPlanHeader';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/CreatePaymentPlanHeader', () => {
+ it('should render', () => {
+ const { container } = render(
+ Promise.resolve()}
+ baseUrl={fakeBaseUrl}
+ permissions={[PERMISSIONS.PM_VIEW_LIST]}
+ loadingCreate={false}
+ />,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/CreatePaymentPlanHeader.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/CreatePaymentPlanHeader.tsx
new file mode 100644
index 0000000000..ee3b47ddc6
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/CreatePaymentPlanHeader.tsx
@@ -0,0 +1,59 @@
+import { Box, Button } from '@mui/material';
+import { Link } from 'react-router-dom';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { BreadCrumbsItem } from '@core/BreadCrumbs';
+import { PageHeader } from '@core/PageHeader';
+import { LoadingButton } from '@core/LoadingButton';
+
+interface CreatePaymentPlanHeaderProps {
+ handleSubmit: () => Promise;
+ baseUrl: string;
+ permissions: string[];
+ loadingCreate: boolean;
+}
+
+export function CreatePaymentPlanHeader({
+ handleSubmit,
+ baseUrl,
+ permissions,
+ loadingCreate,
+}: CreatePaymentPlanHeaderProps): React.ReactElement {
+ const { t } = useTranslation();
+
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/`,
+ },
+ ];
+
+ return (
+
+
+
+
+ {t('Cancel')}
+
+
+
+ {t('Save')}
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/__snapshots__/CreatePaymentPlanHeader.test.tsx.snap b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/__snapshots__/CreatePaymentPlanHeader.test.tsx.snap
new file mode 100644
index 0000000000..3728f6561e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/__snapshots__/CreatePaymentPlanHeader.test.tsx.snap
@@ -0,0 +1,103 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/CreatePaymentPlanHeader should render 1`] = `
+
+
+
+
+
+
+
+
+
+
+ New Payment Plan
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/index.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/index.tsx
new file mode 100644
index 0000000000..f9d44b6eaf
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/CreatePaymentPlanHeader/index.tsx
@@ -0,0 +1 @@
+export { CreatePaymentPlanHeader } from './CreatePaymentPlanHeader';
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanParameters/PaymentPlanParameters.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanParameters/PaymentPlanParameters.tsx
new file mode 100644
index 0000000000..781ef5bc1b
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanParameters/PaymentPlanParameters.tsx
@@ -0,0 +1,124 @@
+import { OverviewContainer } from '@core/OverviewContainer';
+import { Title } from '@core/Title';
+import { useTargetPopulationLazyQuery } from '@generated/graphql';
+import { Grid, Typography } from '@mui/material';
+import { FormikCurrencyAutocomplete } from '@shared/Formik/FormikCurrencyAutocomplete';
+import { FormikDateField } from '@shared/Formik/FormikDateField';
+import { tomorrow } from '@utils/utils';
+import { Field } from 'formik';
+import * as React from 'react';
+import { useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
+import { PaperContainer } from '../../../targeting/PaperContainer';
+import { CalendarTodayRounded } from '@mui/icons-material';
+
+interface PaymentPlanParametersProps {
+ values;
+ paymentPlan?;
+}
+
+export const PaymentPlanParameters = ({
+ values,
+ paymentPlan,
+}: PaymentPlanParametersProps): React.ReactElement => {
+ const { t } = useTranslation();
+ const [loadTargetPopulation, { data, loading }] =
+ useTargetPopulationLazyQuery();
+
+ useEffect(() => {
+ if (values.targetingId) {
+ loadTargetPopulation({
+ variables: {
+ id: values.targetingId,
+ },
+ });
+ }
+ }, [values.targetingId, loadTargetPopulation]);
+
+ return (
+
+
+ {t('Parameters')}
+
+
+
+
+ }
+ data-cy="input-start-date"
+ tooltip={t(
+ 'The first day of the period intended to be covered by the payment plan. Note that individuals/households cannot be paid twice from the same programme within this period.',
+ )}
+ />
+
+
+ }
+ data-cy="input-end-date"
+ tooltip={t(
+ 'The last day of the period intended to be covered by the payment plan. Note that individuals/households cannot be paid twice from the same programme within this period.',
+ )}
+ />
+
+
+
+
+
+ }
+ data-cy="input-dispersion-start-date"
+ tooltip={t(
+ 'The first day from which payments could be delivered.',
+ )}
+ />
+
+
+ }
+ data-cy="input-dispersion-end-date"
+ tooltip={t('The last day on which payments could be delivered.')}
+ />
+
+
+
+
+ );
+};
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanParameters/index.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanParameters/index.tsx
new file mode 100644
index 0000000000..170b75cdd1
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanParameters/index.tsx
@@ -0,0 +1 @@
+export { PaymentPlanParameters } from './PaymentPlanParameters';
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting.test.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting.test.tsx
new file mode 100644
index 0000000000..fc841d4be1
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting.test.tsx
@@ -0,0 +1,16 @@
+import * as React from 'react';
+import { fakeAllTargetPopulation } from '../../../../../fixtures/targeting/fakeAllTargetPopulation';
+import { render } from '../../../../testUtils/testUtils';
+import { PaymentPlanTargeting } from './PaymentPlanTargeting';
+
+describe('components/paymentmodule/PaymentPlanTargeting', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting.tsx
new file mode 100644
index 0000000000..6e4d16f8f7
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting.tsx
@@ -0,0 +1,68 @@
+import { Box, Grid, Typography } from '@mui/material';
+import styled from 'styled-components';
+import { Field } from 'formik';
+import get from 'lodash/get';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { FormikSelectField } from '@shared/Formik/FormikSelectField';
+import { AllTargetPopulationsQuery } from '@generated/graphql';
+import { GreyText } from '@core/GreyText';
+import { LoadingComponent } from '@core/LoadingComponent';
+import { OverviewContainer } from '@core/OverviewContainer';
+import { Title } from '@core/Title';
+import { PaperContainer } from '../../../targeting/PaperContainer';
+
+const StyledBox = styled(Box)`
+ width: 100%;
+`;
+
+export function PaymentPlanTargeting({
+ allTargetPopulations,
+ loading,
+ disabled,
+}: {
+ allTargetPopulations: AllTargetPopulationsQuery;
+ loading: boolean;
+ disabled?: boolean;
+}): React.ReactElement {
+ const { t } = useTranslation();
+ if (loading) return ;
+
+ const allTargetPopulationsEdges = get(
+ allTargetPopulations,
+ 'allTargetPopulation.edges',
+ [],
+ );
+ const mappedTargetPopulations = allTargetPopulationsEdges.map((edge) => ({
+ name: edge.node.name,
+ value: edge.node.id,
+ }));
+
+ return (
+
+
+ {t('Targeting')}
+
+
+
+ {t('Select Target Population')}
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/__snapshots__/PaymentPlanTargeting.test.tsx.snap b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/__snapshots__/PaymentPlanTargeting.test.tsx.snap
new file mode 100644
index 0000000000..41a68c3f9e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/__snapshots__/PaymentPlanTargeting.test.tsx.snap
@@ -0,0 +1,118 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanTargeting should render 1`] = `
+
+
+
+
+ Targeting
+
+
+
+
+
+ Select Target Population
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/index.tsx b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/index.tsx
new file mode 100644
index 0000000000..a1341e5f4c
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreatePaymentPlan/PaymentPlanTargeting/index.tsx
@@ -0,0 +1 @@
+export { PaymentPlanTargeting } from './PaymentPlanTargeting';
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/CreateSetUpFspHeader.test.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/CreateSetUpFspHeader.test.tsx
new file mode 100644
index 0000000000..655d3b6d15
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/CreateSetUpFspHeader.test.tsx
@@ -0,0 +1,17 @@
+import * as React from 'react';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { render } from '../../../../testUtils/testUtils';
+import { CreateSetUpFspHeader } from './CreateSetUpFspHeader';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/CreateSetUpFsp/CreateSetUpFspHeader', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/CreateSetUpFspHeader.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/CreateSetUpFspHeader.tsx
new file mode 100644
index 0000000000..288e2b1491
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/CreateSetUpFspHeader.tsx
@@ -0,0 +1,41 @@
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useParams, useLocation } from 'react-router-dom';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { BreadCrumbsItem } from '@core/BreadCrumbs';
+import { PageHeader } from '@core/PageHeader';
+
+interface CreateSetUpFspHeaderProps {
+ baseUrl: string;
+ permissions: string[];
+}
+
+export function CreateSetUpFspHeader({
+ baseUrl,
+ permissions,
+}: CreateSetUpFspHeaderProps): React.ReactElement {
+ const location = useLocation();
+ const { t } = useTranslation();
+ const { id } = useParams();
+ const isFollowUp = location.pathname.indexOf('followup') !== -1;
+
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/${
+ isFollowUp ? 'followup-payment-plans' : 'payment-plans'
+ }/${id}`,
+ },
+ ];
+
+ return (
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/__snapshots__/CreateSetUpFspHeader.test.tsx.snap b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/__snapshots__/CreateSetUpFspHeader.test.tsx.snap
new file mode 100644
index 0000000000..1e89a32368
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/__snapshots__/CreateSetUpFspHeader.test.tsx.snap
@@ -0,0 +1,73 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/CreateSetUpFsp/CreateSetUpFspHeader should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/index.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/index.tsx
new file mode 100644
index 0000000000..09d01af2b8
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/CreateSetUpFspHeader/index.tsx
@@ -0,0 +1 @@
+export { CreateSetUpFspHeader } from './CreateSetUpFspHeader';
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/DeliveryMechanismRow.test.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/DeliveryMechanismRow.test.tsx
new file mode 100644
index 0000000000..2d0aa40c41
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/DeliveryMechanismRow.test.tsx
@@ -0,0 +1,45 @@
+import * as React from 'react';
+import { render } from '../../../../testUtils/testUtils';
+import { fakeDeliveryMechanisms } from '../../../../../fixtures/paymentmodule/fakeDeliveryMechanisms';
+import { fakeFspsData } from '../../../../../fixtures/paymentmodule/fakeFspsData';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { DeliveryMechanismRow } from './DeliveryMechanismRow';
+
+describe('components/paymentmodule/CreateSetUpFsp/DeliveryMechanismRow', () => {
+ it('should render', () => {
+ const values = {
+ deliveryMechanisms: [
+ {
+ deliveryMechanism: '',
+ fsp: '',
+ chosenConfiguration: '',
+ },
+ ],
+ };
+ const mapping = fakeFspsData?.availableFspsForDeliveryMechanisms[0];
+ const mappedFsps = mapping?.fsps.map((el) => ({
+ name: el.name,
+ value: el.id,
+ }));
+ const deliveryMechanismsChoices =
+ fakeDeliveryMechanisms.allDeliveryMechanisms.map((el) => ({
+ name: el.name,
+ value: el.value,
+ }));
+
+ const { container } = render(
+ {}}
+ />,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/DeliveryMechanismRow.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/DeliveryMechanismRow.tsx
new file mode 100644
index 0000000000..0788048ed6
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/DeliveryMechanismRow.tsx
@@ -0,0 +1,115 @@
+import { Box, Grid } from '@mui/material';
+import { Field } from 'formik';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { FormikSelectField } from '@shared/Formik/FormikSelectField';
+import { LabelizedField } from '@core/LabelizedField';
+
+interface DeliveryMechanismRowProps {
+ index: number;
+ step: number;
+ values;
+ arrayHelpers;
+ deliveryMechanismsChoices;
+ fspsChoices;
+ permissions: string[];
+ setFieldValue: (name, value) => void;
+}
+
+export function DeliveryMechanismRow({
+ index,
+ step,
+ values,
+ deliveryMechanismsChoices,
+ fspsChoices,
+ setFieldValue,
+}: DeliveryMechanismRowProps): React.ReactElement {
+ const { t } = useTranslation();
+ const chosenFsp = values.deliveryMechanisms[index].fsp;
+
+ const handleFspChange = (e): void => {
+ setFieldValue(`deliveryMechanisms[${index}].chosenConfiguration`, '');
+ setFieldValue(`deliveryMechanisms[${index}].fsp`, e.target.value);
+ };
+
+ return (
+
+
+
+
+
+ {/* {index + 1} */}
+ {step === 0 && deliveryMechanismsChoices && (
+
+ )}
+ {step === 1 && (
+
+ )}
+
+
+
+ {step === 1 && fspsChoices && (
+ <>
+
+
+ handleFspChange(e)}
+ />
+
+
+ {fspsChoices.find((el) => el.value == chosenFsp)?.configurations
+ .length > 0 && (
+
+
+ el.value == chosenFsp)
+ ?.configurations
+ ? fspsChoices
+ .find((el) => el.value == chosenFsp)
+ ?.configurations.map((el) => ({
+ name: el.label,
+ value: el.key,
+ }))
+ : []
+ }
+ />
+
+
+ )}
+ >
+ )}
+ {/* {step === 0 && values.deliveryMechanisms[index].deliveryMechanism && (
+
+ {hasPermissions(
+ PERMISSIONS.PM_LOCK_AND_UNLOCK_FSP,
+ permissions,
+ ) ? (
+ arrayHelpers.remove(index)}>
+
+
+ ) : null}
+
+ )} */}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/__snapshots__/DeliveryMechanismRow.test.tsx.snap b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/__snapshots__/DeliveryMechanismRow.test.tsx.snap
new file mode 100644
index 0000000000..2460961dc4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/__snapshots__/DeliveryMechanismRow.test.tsx.snap
@@ -0,0 +1,91 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/CreateSetUpFsp/DeliveryMechanismRow should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/index.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/index.tsx
new file mode 100644
index 0000000000..c6bd3dadb9
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/DeliveryMechanismRow/index.tsx
@@ -0,0 +1 @@
+export { DeliveryMechanismRow } from './DeliveryMechanismRow';
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/SetUpFspButtonActions.test.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/SetUpFspButtonActions.test.tsx
new file mode 100644
index 0000000000..34ab26c331
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/SetUpFspButtonActions.test.tsx
@@ -0,0 +1,26 @@
+import { act } from '@testing-library/react';
+import * as React from 'react';
+import wait from 'waait';
+import { render } from '../../../../testUtils/testUtils';
+import { SetUpFspButtonActions } from './SetUpFspButtonActions';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/CreateSetUpFsp/SetUpFspButtonActions', () => {
+ it('should render', async () => {
+ const step = 0;
+ const setStep = jest.fn();
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const submitForm = (_values): Promise => Promise.resolve();
+ const { container } = render(
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/SetUpFspButtonActions.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/SetUpFspButtonActions.tsx
new file mode 100644
index 0000000000..ab32785967
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/SetUpFspButtonActions.tsx
@@ -0,0 +1,50 @@
+import { Box, Button } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { Link, useLocation } from 'react-router-dom';
+
+interface SetUpFspButtonActionsProps {
+ step: number;
+ submitForm: (values) => void;
+ baseUrl: string;
+ paymentPlanId: string;
+ handleBackStep: () => void;
+}
+
+export function SetUpFspButtonActions({
+ step,
+ submitForm,
+ baseUrl,
+ paymentPlanId,
+ handleBackStep,
+}: SetUpFspButtonActionsProps): React.ReactElement {
+ const { t } = useTranslation();
+ const location = useLocation();
+ const isFollowUp = location.pathname.indexOf('followup') !== -1;
+
+ return (
+
+
+ {step === 0 && (
+
+ {t('Cancel')}
+
+ )}
+ {step === 1 && {t('Back')} }
+
+
+ {t(step === 0 ? 'Next' : 'Save')}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/__snapshots__/SetUpFspButtonActions.test.tsx.snap b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/__snapshots__/SetUpFspButtonActions.test.tsx.snap
new file mode 100644
index 0000000000..c0a492860f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/__snapshots__/SetUpFspButtonActions.test.tsx.snap
@@ -0,0 +1,35 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/CreateSetUpFsp/SetUpFspButtonActions should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/index.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/index.tsx
new file mode 100644
index 0000000000..42d66d381f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspButtonActions/index.tsx
@@ -0,0 +1 @@
+export { SetUpFspButtonActions } from './SetUpFspButtonActions';
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/SetUpFspCore.test.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/SetUpFspCore.test.tsx
new file mode 100644
index 0000000000..a8069c80e9
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/SetUpFspCore.test.tsx
@@ -0,0 +1,35 @@
+import { act } from '@testing-library/react';
+import * as React from 'react';
+import wait from 'waait';
+import { MockedProvider } from '@apollo/react-testing';
+import { render } from '../../../../testUtils/testUtils';
+import { fakeDeliveryMechanisms } from '../../../../../fixtures/paymentmodule/fakeDeliveryMechanisms';
+import { fakeChooseDeliveryMechForPaymentPlanMutation } from '../../../../../fixtures/paymentmodule/fakeChooseDeliveryMechForPaymentPlanMutation';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { SetUpFspCore } from './SetUpFspCore';
+
+describe('components/paymentmodule/CreateSetUpFsp/SetUpFspCore', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/SetUpFspCore.tsx b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/SetUpFspCore.tsx
new file mode 100644
index 0000000000..39605ae1b5
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/SetUpFspCore.tsx
@@ -0,0 +1,272 @@
+import { useLocation, useNavigate, useParams } from 'react-router-dom';
+import { Box } from '@mui/material';
+import Step from '@mui/material/Step';
+import StepLabel from '@mui/material/StepLabel';
+import Stepper from '@mui/material/Stepper';
+import { FieldArray, Form, Formik } from 'formik';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useSnackbar } from '@hooks/useSnackBar';
+import {
+ AvailableFspsForDeliveryMechanismsDocument,
+ PaymentPlanDocument,
+ useAllDeliveryMechanismsQuery,
+ useAssignFspToDeliveryMechMutation,
+ useAvailableFspsForDeliveryMechanismsQuery,
+ useChooseDeliveryMechForPaymentPlanMutation,
+} from '@generated/graphql';
+import { AutoSubmitFormOnEnter } from '@core/AutoSubmitFormOnEnter';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { LoadingComponent } from '@core/LoadingComponent';
+import { DeliveryMechanismRow } from '../DeliveryMechanismRow';
+import { SetUpFspButtonActions } from '../SetUpFspButtonActions/SetUpFspButtonActions';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+export interface FormValues {
+ deliveryMechanisms: {
+ chosenConfiguration: string;
+ deliveryMechanism: string;
+ fsp: string;
+ }[];
+}
+
+interface SetUpFspCoreProps {
+ permissions: string[];
+ initialValues: FormValues;
+}
+
+export const SetUpFspCore = ({
+ permissions,
+ initialValues,
+}: SetUpFspCoreProps): React.ReactElement => {
+ const { baseUrl } = useBaseUrl();
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const { id } = useParams();
+ const location = useLocation();
+
+ const { data: deliveryMechanismsData, loading: deliveryMechanismLoading } =
+ useAllDeliveryMechanismsQuery({
+ fetchPolicy: 'network-only',
+ });
+
+ const { data: fspsData } = useAvailableFspsForDeliveryMechanismsQuery({
+ variables: {
+ input: {
+ paymentPlanId: id,
+ },
+ },
+ fetchPolicy: 'network-only',
+ });
+
+ const isEdit = location.pathname.indexOf('edit') !== -1;
+ const isFollowUp = location.pathname.indexOf('followup') !== -1;
+
+ const [activeStep, setActiveStep] = useState(isEdit ? 1 : 0);
+ // const [warning, setWarning] = useState('');
+
+ const [chooseDeliveryMechanisms] =
+ useChooseDeliveryMechForPaymentPlanMutation();
+
+ const [assignFspToDeliveryMechanism] = useAssignFspToDeliveryMechMutation();
+
+ const { showMessage } = useSnackbar();
+
+ if (!deliveryMechanismsData) return null;
+ if (deliveryMechanismLoading) return ;
+
+ const steps = [
+ t('Choose Delivery Mechanism'),
+ t('Assign FSP per Delivery Mechanism'),
+ ];
+
+ const handleBackStep = (): void => {
+ setActiveStep((prevActiveStep) => prevActiveStep - 1);
+ };
+
+ const handleNextStep = (): void => {
+ setActiveStep((prevActiveStep) => prevActiveStep + 1);
+ };
+
+ const handleChooseDeliveryMechanisms = async (
+ values: FormValues,
+ ): Promise => {
+ // setWarning('');
+ const mappedDeliveryMechanisms = values.deliveryMechanisms.map(
+ (el) => el.deliveryMechanism,
+ );
+ try {
+ await chooseDeliveryMechanisms({
+ variables: {
+ input: {
+ paymentPlanId: id,
+ deliveryMechanisms: mappedDeliveryMechanisms,
+ },
+ },
+ refetchQueries: () => [
+ {
+ query: AvailableFspsForDeliveryMechanismsDocument,
+ variables: {
+ input: {
+ paymentPlanId: id,
+ },
+ },
+ },
+ {
+ query: PaymentPlanDocument,
+ variables: {
+ id,
+ },
+ },
+ ],
+ });
+
+ showMessage(t('Delivery Mechanisms have been set'));
+ handleNextStep();
+ } catch (e) {
+ // if (
+ // e.graphQLErrors.length &&
+ // e.graphQLErrors[0]?.message.includes('sufficient')
+ // ) {
+ // setWarning(e.graphQLErrors[0].message);
+ // }
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ const handleAssignFspToDeliveryMechanism = async (
+ values: FormValues,
+ ): Promise => {
+ const mappings = values.deliveryMechanisms.map((el, index) => ({
+ fspId: el.fsp,
+ deliveryMechanism: el.deliveryMechanism,
+ order: index + 1,
+ chosenConfiguration: el.chosenConfiguration,
+ }));
+ try {
+ await assignFspToDeliveryMechanism({
+ variables: {
+ input: {
+ paymentPlanId: id,
+ mappings,
+ },
+ },
+ });
+ showMessage(t('FSPs have been assigned to the delivery mechanisms'));
+ navigate(
+ `/${baseUrl}/payment-module/${
+ isFollowUp ? 'followup-payment-plans' : 'payment-plans'
+ }/${id}`,
+ );
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ const handleSubmit = (values: FormValues): void => {
+ if (activeStep === 0) {
+ handleChooseDeliveryMechanisms(values);
+ }
+ if (activeStep === 1) {
+ handleAssignFspToDeliveryMechanism(values);
+ }
+ };
+
+ return (
+ handleSubmit(values)}
+ enableReinitialize
+ >
+ {({ values, submitForm, setFieldValue }) => (
+
+ )}
+
+ );
+};
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/__snapshots__/SetUpFspCore.test.tsx.snap b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/__snapshots__/SetUpFspCore.test.tsx.snap
new file mode 100644
index 0000000000..fbfec4c224
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/__snapshots__/SetUpFspCore.test.tsx.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/CreateSetUpFsp/SetUpFspCore should render 1`] = `
`;
diff --git a/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/index.ts b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/index.ts
new file mode 100644
index 0000000000..a5c5325281
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/CreateSetUpFsp/SetUpFspCore/index.ts
@@ -0,0 +1 @@
+export { SetUpFspCore } from './SetUpFspCore';
diff --git a/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/EditFspHeader.test.tsx b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/EditFspHeader.test.tsx
new file mode 100644
index 0000000000..a792d7be1f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/EditFspHeader.test.tsx
@@ -0,0 +1,18 @@
+import * as React from 'react';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { render } from '../../../../testUtils/testUtils';
+import { EditFspHeader } from './EditFspHeader';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/EditFspHeader', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/EditFspHeader.tsx b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/EditFspHeader.tsx
new file mode 100644
index 0000000000..b172074a59
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/EditFspHeader.tsx
@@ -0,0 +1,50 @@
+import { Box, Button } from '@mui/material';
+import { Link } from 'react-router-dom';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { BreadCrumbsItem } from '@core/BreadCrumbs';
+import { PageHeader } from '@core/PageHeader';
+
+interface EditFspHeaderProps {
+ handleSubmit: () => Promise;
+ baseUrl: string;
+ permissions: string[];
+}
+
+export function EditFspHeader({
+ handleSubmit,
+ baseUrl,
+ permissions,
+}: EditFspHeaderProps): React.ReactElement {
+ const { t } = useTranslation();
+
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/`,
+ },
+ ];
+
+ return (
+
+
+
+
+ {t('Cancel')}
+
+
+
+ {t('Save')}
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/__snapshots__/EditFspHeader.test.tsx.snap b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/__snapshots__/EditFspHeader.test.tsx.snap
new file mode 100644
index 0000000000..2765a47825
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/__snapshots__/EditFspHeader.test.tsx.snap
@@ -0,0 +1,102 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/EditFspHeader should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/index.tsx b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/index.tsx
new file mode 100644
index 0000000000..f26f8e67c2
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditFsp/EditFspHeader/index.tsx
@@ -0,0 +1 @@
+export { EditFspHeader } from './EditFspHeader';
diff --git a/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/EditPaymentPlanHeader.test.tsx b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/EditPaymentPlanHeader.test.tsx
new file mode 100644
index 0000000000..0d4ae4fbb3
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/EditPaymentPlanHeader.test.tsx
@@ -0,0 +1,20 @@
+import * as React from 'react';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { render } from '../../../../testUtils/testUtils';
+import { EditPaymentPlanHeader } from './EditPaymentPlanHeader';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/EditPaymentPlanHeader', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/EditPaymentPlanHeader.tsx b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/EditPaymentPlanHeader.tsx
new file mode 100644
index 0000000000..ea3fabdfa8
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/EditPaymentPlanHeader.tsx
@@ -0,0 +1,89 @@
+import { Box, Button } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { Link } from 'react-router-dom';
+import styled from 'styled-components';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import {
+ paymentPlanBackgroundActionStatusToColor,
+ paymentPlanStatusToColor,
+} from '@utils/utils';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { BreadCrumbsItem } from '@core/BreadCrumbs';
+import { PageHeader } from '@core/PageHeader';
+import { StatusBox } from '@core/StatusBox';
+
+const StatusWrapper = styled.div`
+ width: 140px;
+ margin-left: 30px;
+`;
+
+interface EditPaymentPlanHeaderProps {
+ handleSubmit: () => Promise;
+ baseUrl: string;
+ permissions: string[];
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function EditPaymentPlanHeader({
+ handleSubmit,
+ baseUrl,
+ permissions,
+ paymentPlan,
+}: EditPaymentPlanHeaderProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { id, isFollowUp } = paymentPlan;
+
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/${
+ isFollowUp ? 'followup-payment-plans' : 'payment-plans'
+ }/${id}`,
+ },
+ ];
+
+ return (
+
+ {t(isFollowUp ? 'Follow-up Payment Plan' : 'Payment Plan')} ID{' '}
+ {paymentPlan.unicefId}
+
+
+
+ {paymentPlan.backgroundActionStatus && (
+
+
+
+ )}
+
+ }
+ breadCrumbs={
+ hasPermissions(PERMISSIONS.PM_VIEW_LIST, permissions)
+ ? breadCrumbsItems
+ : null
+ }
+ >
+
+
+
+ {t('Cancel')}
+
+
+
+ {t('Save')}
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/__snapshots__/EditPaymentPlanHeader.test.tsx.snap b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/__snapshots__/EditPaymentPlanHeader.test.tsx.snap
new file mode 100644
index 0000000000..05d08e0289
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/__snapshots__/EditPaymentPlanHeader.test.tsx.snap
@@ -0,0 +1,123 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/EditPaymentPlanHeader should render 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ Payment Plan
+ ID
+
+ PP-0060-22-00000001
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/index.tsx b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/index.tsx
new file mode 100644
index 0000000000..4f11d8dd2d
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditPaymentPlan/EditPaymentPlanHeader/index.tsx
@@ -0,0 +1 @@
+export { EditPaymentPlanHeader } from './EditPaymentPlanHeader';
diff --git a/frontend/src/components/paymentmodulepeople/EditSetUpFsp/DeliveryMechanismWarning.test.tsx b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/DeliveryMechanismWarning.test.tsx
new file mode 100644
index 0000000000..0f24c5a234
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/DeliveryMechanismWarning.test.tsx
@@ -0,0 +1,12 @@
+import * as React from 'react';
+import { render } from '../../../testUtils/testUtils';
+import { DeliveryMechanismWarning } from './DeliveryMechanismWarning';
+
+describe('components/paymentmodule/DeliveryMechanismWarning', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/EditSetUpFsp/DeliveryMechanismWarning.tsx b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/DeliveryMechanismWarning.tsx
new file mode 100644
index 0000000000..02b28166d7
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/DeliveryMechanismWarning.tsx
@@ -0,0 +1,37 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import styled from 'styled-components';
+import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
+
+const WarningBox = styled(Box)`
+ width: 70%;
+ background-color: #fef7f7;
+ color: #e90202;
+`;
+
+const ErrorOutline = styled(ErrorOutlineIcon)`
+ color: #e90202;
+ margin-right: 5px;
+`;
+
+interface DeliveryMechanismWarningProps {
+ warning: string;
+}
+
+export function DeliveryMechanismWarning({
+ warning,
+}: DeliveryMechanismWarningProps): React.ReactElement {
+ return (
+
+
+ {warning}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/EditSetUpFspHeader.test.tsx b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/EditSetUpFspHeader.test.tsx
new file mode 100644
index 0000000000..97f909993d
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/EditSetUpFspHeader.test.tsx
@@ -0,0 +1,13 @@
+import * as React from 'react';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { render } from '../../../../testUtils/testUtils';
+import { EditSetUpFspHeader } from './EditSetUpFspHeader';
+
+describe('components/paymentmodule/EditSetUpFsp/EditSetUpFspHeader', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/EditSetUpFspHeader.tsx b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/EditSetUpFspHeader.tsx
new file mode 100644
index 0000000000..b9d4988812
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/EditSetUpFspHeader.tsx
@@ -0,0 +1,40 @@
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useParams, useLocation } from 'react-router-dom';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { BreadCrumbsItem } from '@core/BreadCrumbs';
+import { PageHeader } from '@core/PageHeader';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+interface EditFspHeaderProps {
+ permissions: string[];
+}
+
+export function EditSetUpFspHeader({
+ permissions,
+}: EditFspHeaderProps): React.ReactElement {
+ const { baseUrl } = useBaseUrl();
+ const location = useLocation();
+ const { t } = useTranslation();
+ const { id } = useParams();
+ const isFollowUp = location.pathname.indexOf('followup') !== -1;
+
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/${
+ isFollowUp ? 'followup-payment-plans' : 'payment-plans'
+ }/${id}`,
+ },
+ ];
+ return (
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/__snapshots__/EditSetUpFspHeader.test.tsx.snap b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/__snapshots__/EditSetUpFspHeader.test.tsx.snap
new file mode 100644
index 0000000000..26e98efb68
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/__snapshots__/EditSetUpFspHeader.test.tsx.snap
@@ -0,0 +1,44 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/EditSetUpFsp/EditSetUpFspHeader should render 1`] = `
+
+
+
+
+
+
+
+
+ Edit Set up FSP
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/index.tsx b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/index.tsx
new file mode 100644
index 0000000000..57a5c58d7c
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/EditSetUpFspHeader/index.tsx
@@ -0,0 +1 @@
+export { EditSetUpFspHeader } from './EditSetUpFspHeader';
diff --git a/frontend/src/components/paymentmodulepeople/EditSetUpFsp/__snapshots__/DeliveryMechanismWarning.test.tsx.snap b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/__snapshots__/DeliveryMechanismWarning.test.tsx.snap
new file mode 100644
index 0000000000..d39a172317
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/EditSetUpFsp/__snapshots__/DeliveryMechanismWarning.test.tsx.snap
@@ -0,0 +1,23 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/DeliveryMechanismWarning should render 1`] = `
+
+
+
+
+
+ Test DM warning comp
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails.tsx b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails.tsx
new file mode 100644
index 0000000000..e6ebf97da4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails.tsx
@@ -0,0 +1,104 @@
+import { Grid, Typography } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { renderUserName } from '@utils/utils';
+import { BlackLink } from '@core/BlackLink';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { LabelizedField } from '@core/LabelizedField';
+import { OverviewContainer } from '@core/OverviewContainer';
+import { Title } from '@core/Title';
+import { UniversalMoment } from '@core/UniversalMoment';
+
+interface FollowUpPaymentPlanDetailsProps {
+ baseUrl: string;
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function FollowUpPaymentPlanDetails({
+ baseUrl,
+ paymentPlan,
+}: FollowUpPaymentPlanDetailsProps): React.ReactElement {
+ const { t } = useTranslation();
+ const {
+ createdBy,
+ program,
+ currency,
+ startDate,
+ endDate,
+ dispersionStartDate,
+ dispersionEndDate,
+ sourcePaymentPlan: {
+ id: sourcePaymentPlanId,
+ unicefId: sourcePaymentPlanUnicefId,
+ },
+ targetPopulation,
+ } = paymentPlan;
+
+ return (
+
+
+
+ {t('Details')}
+
+
+
+
+
+
+ {sourcePaymentPlanUnicefId}
+
+
+
+
+
+ {renderUserName(createdBy)}
+
+
+
+
+
+ {program.name}
+
+
+
+
+
+
+ {targetPopulation.name}
+
+
+
+
+ {currency}
+
+
+
+ {startDate}
+
+
+
+
+ {endDate}
+
+
+
+
+ {dispersionStartDate}
+
+
+
+
+ {dispersionEndDate}
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails/index.tsx b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails/index.tsx
new file mode 100644
index 0000000000..a2c1d44a85
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails/index.tsx
@@ -0,0 +1 @@
+export { FollowUpPaymentPlanDetails } from './FollowUpPaymentPlanDetails';
diff --git a/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetailsHeader/FollowUpPaymentPlanDetailsHeader.tsx b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetailsHeader/FollowUpPaymentPlanDetailsHeader.tsx
new file mode 100644
index 0000000000..1d9ec7d830
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetailsHeader/FollowUpPaymentPlanDetailsHeader.tsx
@@ -0,0 +1,205 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import {
+ paymentPlanBackgroundActionStatusToColor,
+ paymentPlanStatusToColor,
+} from '@utils/utils';
+import { BreadCrumbsItem } from '../../../core/BreadCrumbs';
+import { PageHeader } from '../../../core/PageHeader';
+import { StatusBox } from '../../../core/StatusBox';
+import { AcceptedPaymentPlanHeaderButtons } from '../../PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons';
+import { InApprovalPaymentPlanHeaderButtons } from '../../PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons';
+import { InAuthorizationPaymentPlanHeaderButtons } from '../../PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons';
+import { InReviewPaymentPlanHeaderButtons } from '../../PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons';
+import { LockedFspPaymentPlanHeaderButtons } from '../../PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedFspPaymentPlanHeaderButtons';
+import { LockedPaymentPlanHeaderButtons } from '../../PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons';
+import { OpenPaymentPlanHeaderButtons } from '../../PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons';
+import { PaymentPlanQuery } from '@generated/graphql';
+
+const StatusWrapper = styled.div`
+ width: 140px;
+ margin-left: 30px;
+`;
+
+interface FollowUpPaymentPlanDetailsHeaderProps {
+ baseUrl: string;
+ permissions: string[];
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function FollowUpPaymentPlanDetailsHeader({
+ baseUrl,
+ permissions,
+ paymentPlan,
+}: FollowUpPaymentPlanDetailsHeaderProps): React.ReactElement {
+ const { t } = useTranslation();
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/`,
+ },
+ ];
+
+ const canRemove = hasPermissions(PERMISSIONS.PM_CREATE, permissions);
+ const canEdit = hasPermissions(PERMISSIONS.PM_CREATE, permissions);
+ const canLock = hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK, permissions);
+ const canUnlock = hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK, permissions);
+ const canSendForApproval = hasPermissions(
+ PERMISSIONS.PM_SEND_FOR_APPROVAL,
+ permissions,
+ );
+ const canApprove = hasPermissions(
+ PERMISSIONS.PM_ACCEPTANCE_PROCESS_APPROVE,
+ permissions,
+ );
+ const canAuthorize = hasPermissions(
+ PERMISSIONS.PM_ACCEPTANCE_PROCESS_AUTHORIZE,
+ permissions,
+ );
+ const canMarkAsReleased = hasPermissions(
+ PERMISSIONS.PM_ACCEPTANCE_PROCESS_FINANCIAL_REVIEW,
+ permissions,
+ );
+ const canDownloadXlsx = hasPermissions(
+ PERMISSIONS.PM_DOWNLOAD_XLSX_FOR_FSP,
+ permissions,
+ );
+ const canExportXlsx = hasPermissions(
+ PERMISSIONS.PM_EXPORT_XLSX_FOR_FSP,
+ permissions,
+ );
+ const canSendToPaymentGateway =
+ hasPermissions(PERMISSIONS.PM_SEND_TO_PAYMENT_GATEWAY, permissions) &&
+ paymentPlan.canSendToPaymentGateway;
+ const canSplit =
+ hasPermissions(PERMISSIONS.PM_SPLIT, permissions) && paymentPlan.canSplit;
+
+ let buttons: React.ReactElement | null = null;
+ switch (paymentPlan.status) {
+ case 'OPEN':
+ buttons = (
+
+ );
+ break;
+ case 'LOCKED':
+ buttons = (
+
+ );
+ break;
+ case 'LOCKED_FSP':
+ buttons = (
+
+ );
+ break;
+ case 'IN_APPROVAL':
+ buttons = (
+
+ );
+ break;
+ case 'IN_AUTHORIZATION':
+ buttons = (
+
+ );
+ break;
+ case 'IN_REVIEW':
+ buttons = (
+
+ );
+ break;
+ case 'ACCEPTED':
+ buttons = (
+
+ );
+ break;
+ case 'FINISHED': // TODO: may create another one for that explicitly but good for now
+ buttons = (
+
+ );
+ break;
+ default:
+ break;
+ }
+
+ return (
+
+ {t('Follow-up Payment Plan')} ID:{' '}
+
+ {paymentPlan.unicefId}
+
+
+
+
+ {paymentPlan.backgroundActionStatus && (
+
+
+
+ )}
+
+ }
+ breadCrumbs={
+ hasPermissions(PERMISSIONS.PM_VIEW_DETAILS, permissions)
+ ? breadCrumbsItems
+ : null
+ }
+ >
+ {buttons}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetailsHeader/index.tsx b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetailsHeader/index.tsx
new file mode 100644
index 0000000000..3cce216c8c
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetailsHeader/index.tsx
@@ -0,0 +1 @@
+export { FollowUpPaymentPlanDetailsHeader } from './FollowUpPaymentPlanDetailsHeader';
diff --git a/frontend/src/components/paymentmodulepeople/ForceFailedButton.tsx b/frontend/src/components/paymentmodulepeople/ForceFailedButton.tsx
new file mode 100644
index 0000000000..0dc65c7fd5
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/ForceFailedButton.tsx
@@ -0,0 +1,88 @@
+import { Box, Button, DialogContent, DialogTitle } from '@mui/material';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { Dialog } from '@containers/dialogs/Dialog';
+import { DialogActions } from '@containers/dialogs/DialogActions';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { useMarkPayAsFailedMutation } from '@generated/graphql';
+
+export interface ForceFailedButtonProps {
+ paymentId: string;
+ disabled?: boolean;
+}
+export function ForceFailedButton({
+ paymentId,
+ disabled = false,
+}: ForceFailedButtonProps): React.ReactElement {
+ const { t } = useTranslation();
+ const [isOpenModal, setOpenModal] = useState(false);
+ const { showMessage } = useSnackbar();
+ const [mutate, { loading }] = useMarkPayAsFailedMutation();
+
+ const submit = async (): Promise => {
+ try {
+ await mutate({
+ variables: {
+ paymentId,
+ },
+ });
+ setOpenModal(false);
+ showMessage(t('Payment has been marked as failed.'));
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ return (
+
+
+ setOpenModal(true)}
+ data-cy="button-mark-as-failed"
+ disabled={disabled}
+ >
+ {t('Mark as failed')}
+
+
+ setOpenModal(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Mark as failed')}
+
+
+
+
+ {t('Are you sure you would like to mark payment as failed?')}
+
+
+
+
+
+ setOpenModal(false)}>{t('CANCEL')}
+ submit()}
+ data-cy="button-submit"
+ disabled={loading}
+ >
+ {t('Mark as failed')}
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/FspHeader.test.tsx b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/FspHeader.test.tsx
new file mode 100644
index 0000000000..ea164432d4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/FspHeader.test.tsx
@@ -0,0 +1,17 @@
+import * as React from 'react';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { render } from '../../../../testUtils/testUtils';
+import { FspHeader } from './FspHeader';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/FspPlanDetails/FspHeader', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/FspHeader.tsx b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/FspHeader.tsx
new file mode 100644
index 0000000000..2e23c74d5e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/FspHeader.tsx
@@ -0,0 +1,52 @@
+import { Box, Button } from '@mui/material';
+import { Link } from 'react-router-dom';
+import EditIcon from '@mui/icons-material/EditRounded';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { BreadCrumbsItem } from '@core/BreadCrumbs';
+import { PageHeader } from '@core/PageHeader';
+
+interface FspHeaderProps {
+ baseUrl: string;
+ permissions: string[];
+}
+
+export function FspHeader({
+ baseUrl,
+ permissions,
+}: FspHeaderProps): React.ReactElement {
+ const { t } = useTranslation();
+
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/`,
+ },
+ ];
+
+ return (
+
+
+
+ }
+ >
+ {t('Edit')}
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/__snapshots__/FspHeader.test.tsx.snap b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/__snapshots__/FspHeader.test.tsx.snap
new file mode 100644
index 0000000000..527bfacab5
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/__snapshots__/FspHeader.test.tsx.snap
@@ -0,0 +1,107 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/FspPlanDetails/FspHeader should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/index.tsx b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/index.tsx
new file mode 100644
index 0000000000..ab635206c2
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/FspHeader/index.tsx
@@ -0,0 +1 @@
+export { FspHeader } from './FspHeader';
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/TotalAmount.test.tsx b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/TotalAmount.test.tsx
new file mode 100644
index 0000000000..5e4808db46
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/TotalAmount.test.tsx
@@ -0,0 +1,10 @@
+import * as React from 'react';
+import { render } from '../../../../testUtils/testUtils';
+import { TotalAmount } from './TotalAmount';
+
+describe('components/paymentmodule/FspPlanDetails/TotalAmount', () => {
+ it('should render', () => {
+ const { container } = render( );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/TotalAmount.tsx b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/TotalAmount.tsx
new file mode 100644
index 0000000000..5c9f3f3063
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/TotalAmount.tsx
@@ -0,0 +1,25 @@
+import { Box, Typography } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { Title } from '@core/Title';
+
+export function TotalAmount(): React.ReactElement {
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+
+ {t('Total Amount')}
+ (PLN)
+ {t('per FSP')}
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/__snapshots__/TotalAmount.test.tsx.snap b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/__snapshots__/TotalAmount.test.tsx.snap
new file mode 100644
index 0000000000..7959353b18
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/__snapshots__/TotalAmount.test.tsx.snap
@@ -0,0 +1,29 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/FspPlanDetails/TotalAmount should render 1`] = `
+
+
+
+
+
+
+ Total Amount
+ (PLN)
+ per FSP
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/index.tsx b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/index.tsx
new file mode 100644
index 0000000000..b19eebb2f7
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/FspPlanDetails/TotalAmount/index.tsx
@@ -0,0 +1 @@
+export { TotalAmount } from './TotalAmount';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentDetails/PaymentDetails.tsx b/frontend/src/components/paymentmodulepeople/PaymentDetails/PaymentDetails.tsx
new file mode 100644
index 0000000000..588c3d448f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentDetails/PaymentDetails.tsx
@@ -0,0 +1,312 @@
+import { Grid, Paper, Typography } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import {
+ PaymentDeliveryType,
+ PaymentQuery,
+ PaymentStatus,
+ PaymentVerificationStatus,
+} from '@generated/graphql';
+import { UniversalActivityLogTable } from '@containers/tables/UniversalActivityLogTable';
+import { useBusinessArea } from '@hooks/useBusinessArea';
+import {
+ formatCurrencyWithSymbol,
+ getPhoneNoLabel,
+ paymentStatusDisplayMap,
+ paymentStatusToColor,
+ verificationRecordsStatusToColor,
+} from '@utils/utils';
+import { BlackLink } from '@core/BlackLink';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { DividerLine } from '@core/DividerLine';
+import { LabelizedField } from '@core/LabelizedField';
+import { StatusBox } from '@core/StatusBox';
+import { Title } from '@core/Title';
+import { UniversalMoment } from '@core/UniversalMoment';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+const Overview = styled(Paper)`
+ margin: 20px;
+ padding: ${({ theme }) => theme.spacing(8)}
+ ${({ theme }) => theme.spacing(11)};
+`;
+
+interface PaymentDetailsProps {
+ payment: PaymentQuery['payment'];
+ canViewActivityLog: boolean;
+ canViewHouseholdDetails: boolean;
+}
+
+export function PaymentDetails({
+ payment,
+ canViewActivityLog,
+ canViewHouseholdDetails,
+}: PaymentDetailsProps): React.ReactElement {
+ const businessArea = useBusinessArea();
+ const { t } = useTranslation();
+ const { programId } = useBaseUrl();
+
+ let paymentVerification: PaymentQuery['payment']['verification'] = null;
+ if (
+ payment.verification &&
+ payment.verification.status !== PaymentVerificationStatus.Pending
+ ) {
+ paymentVerification = payment.verification;
+ }
+
+ const showFailureReason = [
+ PaymentStatus.NotDistributed,
+ PaymentStatus.ForceFailed,
+ PaymentStatus.TransactionErroneous,
+ ].includes(payment.status);
+
+ return (
+ <>
+
+
+ {t('Details')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {payment.deliveryDate}}
+ />
+
+
+
+
+ {payment.targetPopulation?.name}
+
+
+
+
+
+
+
+
+
+
+
+ {paymentVerification != null ? (
+
+
+ {t('Verification Details')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : null}
+
+
+ {t('Household')}
+
+
+
+
+ {payment.household?.id && canViewHouseholdDetails ? (
+
+ {payment.household.unicefId}
+
+ ) : (
+
+ {payment.household?.id ? payment.household.unicefId : '-'}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {t('Entitlement Details')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {payment.deliveryType === PaymentDeliveryType.DepositToCard && (
+ <>
+
+
+
+
+
+
+ >
+ )}
+
+
+
+
+ {t('Reconciliation Details')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showFailureReason && (
+
+
+
+ )}
+
+
+
+
+
+ {canViewActivityLog && (
+
+ )}
+ >
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentDetails/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentDetails/index.tsx
new file mode 100644
index 0000000000..25f9811c5e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentDetails/index.tsx
@@ -0,0 +1 @@
+export { PaymentDetails } from './PaymentDetails';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcess.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcess.tsx
new file mode 100644
index 0000000000..5c6372bc27
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcess.tsx
@@ -0,0 +1,111 @@
+import { Box, Button, Typography } from '@mui/material';
+import ExpandLessIcon from '@mui/icons-material/ExpandLess';
+import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import {
+ PaymentPlanQuery,
+ PaymentPlanStatus,
+ useExportPdfPpSummaryMutation,
+} from '@generated/graphql';
+import { PERMISSIONS, hasPermissions } from '../../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { LoadingButton } from '@core/LoadingButton';
+import { Title } from '@core/Title';
+import { useProgramContext } from '../../../../programContext';
+import { AcceptanceProcessRow } from './AcceptanceProcessRow';
+
+const ButtonContainer = styled(Box)`
+ width: 200px;
+`;
+
+interface AcceptanceProcessProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function AcceptanceProcess({
+ paymentPlan,
+}: AcceptanceProcessProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { showMessage } = useSnackbar();
+ const permissions = usePermissions();
+ const { isActiveProgram } = useProgramContext();
+
+ const { edges } = paymentPlan.approvalProcess;
+ const [showAll, setShowAll] = useState(false);
+ const [mutate, { loading: exportPdfLoading }] =
+ useExportPdfPpSummaryMutation();
+
+ const matchDataSize = (
+ data: PaymentPlanQuery['paymentPlan']['approvalProcess']['edges'],
+ ): PaymentPlanQuery['paymentPlan']['approvalProcess']['edges'] =>
+ showAll ? data : [data[0]];
+
+ if (!edges.length) {
+ return null;
+ }
+ const handleExportPdf = async (): Promise => {
+ try {
+ await mutate({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ },
+ });
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ } finally {
+ showMessage(t('PDF generated. Please check your email.'));
+ }
+ };
+
+ const canExportPdf =
+ hasPermissions(PERMISSIONS.PM_EXPORT_PDF_SUMMARY, permissions) &&
+ (paymentPlan.status === PaymentPlanStatus.Accepted ||
+ paymentPlan.status === PaymentPlanStatus.Finished);
+
+ return (
+
+
+
+
+ {t('Acceptance Process')}
+
+ {canExportPdf && (
+
+ {t('Download Payment Plan Summary')}
+
+ )}
+
+ {matchDataSize(edges).map((edge) => (
+
+ ))}
+ {edges.length > 1 && (
+
+ setShowAll(!showAll)}
+ endIcon={showAll ? : }
+ >
+ {showAll ? t('HIDE') : t('SHOW PREVIOUS')}
+
+
+ )}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow.test.tsx
new file mode 100644
index 0000000000..2c7bfeac78
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow.test.tsx
@@ -0,0 +1,16 @@
+import * as React from 'react';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../testUtils/testUtils';
+import { AcceptanceProcessRow } from './AcceptanceProcessRow';
+
+describe('components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow.tsx
new file mode 100644
index 0000000000..d34e5e84c1
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow.tsx
@@ -0,0 +1,124 @@
+import { Box, Grid } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { renderUserName } from '@utils/utils';
+import { DividerLine } from '@core/DividerLine';
+import { AcceptanceProcessStepper } from './AcceptanceProcessStepper/AcceptanceProcessStepper';
+import { GreyInfoCard } from './GreyInfoCard';
+
+const StyledBox = styled(Box)`
+ width: 100%;
+`;
+
+interface AcceptanceProcessRowProps {
+ acceptanceProcess: PaymentPlanQuery['paymentPlan']['approvalProcess']['edges'][0]['node'];
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function AcceptanceProcessRow({
+ acceptanceProcess,
+ paymentPlan,
+}: AcceptanceProcessRowProps): React.ReactElement {
+ const { t } = useTranslation();
+ const {
+ actions,
+ sentForApprovalDate,
+ sentForApprovalBy,
+ sentForAuthorizationDate,
+ sentForAuthorizationBy,
+ sentForFinanceReleaseDate,
+ sentForFinanceReleaseBy,
+ rejectedOn,
+ } = acceptanceProcess;
+
+ const { approvalProcess } = paymentPlan;
+
+ const getRejectedOnString = (stage: string): string => {
+ switch (stage) {
+ case 'IN_APPROVAL':
+ return t('Rejected in Approval stage');
+ case 'IN_AUTHORIZATION':
+ return t('Rejected in Authorization stage');
+ case 'IN_REVIEW':
+ return t('Rejected in Finance Release stage');
+
+ default:
+ return '';
+ }
+ };
+
+ return (
+
+
+
+
+ {actions.approval.length > 0 && (
+
+ )}
+
+
+ {actions.authorization.length > 0 && (
+
+ )}
+
+
+ {actions.financeRelease.length > 0 && (
+
+ )}
+
+ {actions.reject.length > 0 && (
+
+
+ {rejectedOn === 'IN_APPROVAL' && (
+
+ )}
+
+
+ {rejectedOn === 'IN_AUTHORIZATION' && (
+
+ )}
+
+
+ {rejectedOn === 'IN_REVIEW' && (
+
+ )}
+
+
+ )}
+
+ {approvalProcess.totalCount > 1 && }
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.test.tsx
new file mode 100644
index 0000000000..73beda5b83
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.test.tsx
@@ -0,0 +1,54 @@
+import { act } from '@testing-library/react';
+import * as React from 'react';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../../testUtils/testUtils';
+import { AcceptanceProcessStepper } from './AcceptanceProcessStepper';
+
+describe('components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper', () => {
+ it('should render default step Sent for Approval Date', async () => {
+ const { container } = render(
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+ expect(container).toMatchSnapshot();
+ });
+ it('should render step Sent for Approval Date', async () => {
+ const { container } = render(
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+ expect(container).toMatchSnapshot();
+ });
+ it('should render step Sent for Authorization Date', async () => {
+ const { container } = render(
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+ expect(container).toMatchSnapshot();
+ });
+ it('should render step Sent for Finance Release Date', async () => {
+ const { container } = render(
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.tsx
new file mode 100644
index 0000000000..44ac95c41f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/AcceptanceProcessStepper.tsx
@@ -0,0 +1,66 @@
+import Step from '@mui/material/Step';
+import StepLabel from '@mui/material/StepLabel';
+import Stepper from '@mui/material/Stepper';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { PaymentPlanQuery } from '@generated/graphql';
+
+interface AcceptanceProcessStepperProps {
+ acceptanceProcess: PaymentPlanQuery['paymentPlan']['approvalProcess']['edges'][0]['node'];
+}
+
+export function AcceptanceProcessStepper({
+ acceptanceProcess,
+}: AcceptanceProcessStepperProps): React.ReactElement {
+ const {
+ rejectedOn,
+ actions,
+ approvalNumberRequired,
+ authorizationNumberRequired,
+ financeReleaseNumberRequired,
+ } = acceptanceProcess;
+ const { t } = useTranslation();
+ const steps = [
+ {
+ name: `${t('Approval')} (${
+ actions.approval.length
+ }/${approvalNumberRequired})`,
+ hasError: rejectedOn === 'IN_APPROVAL',
+ isCompleted: actions.approval.length === approvalNumberRequired,
+ },
+ {
+ name: `${t('Authorization')} (${
+ actions.authorization.length
+ }/${authorizationNumberRequired})`,
+ hasError: rejectedOn === 'IN_AUTHORIZATION',
+ isCompleted: actions.authorization.length === authorizationNumberRequired,
+ },
+ {
+ name: `${t('Finance Release')} (${
+ actions.financeRelease.length
+ }/${financeReleaseNumberRequired})`,
+ hasError: rejectedOn === 'IN_REVIEW',
+ isCompleted:
+ actions.financeRelease.length === financeReleaseNumberRequired,
+ },
+ ];
+ const getActiveStep = (): number => {
+ if (actions.authorization.length === authorizationNumberRequired) {
+ return 2;
+ }
+ if (actions.approval.length === approvalNumberRequired) {
+ return 1;
+ }
+ return 0;
+ };
+
+ return (
+
+ {steps.map((step) => (
+
+ {step.name}
+
+ ))}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/__snapshots__/AcceptanceProcessStepper.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/__snapshots__/AcceptanceProcessStepper.test.tsx.snap
new file mode 100644
index 0000000000..3810b41072
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/__snapshots__/AcceptanceProcessStepper.test.tsx.snap
@@ -0,0 +1,557 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper should render default step Sent for Approval Date 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ Approval (1/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+ Authorization (0/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+ Finance Release (0/1)
+
+
+
+
+
+
+`;
+
+exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper should render step Sent for Approval Date 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ Approval (1/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+ Authorization (0/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+ Finance Release (0/1)
+
+
+
+
+
+
+`;
+
+exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper should render step Sent for Authorization Date 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ Approval (1/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+ Authorization (0/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+ Finance Release (0/1)
+
+
+
+
+
+
+`;
+
+exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper should render step Sent for Finance Release Date 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ Approval (1/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+ Authorization (0/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+ Finance Release (0/1)
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/index.tsx
new file mode 100644
index 0000000000..b13214ef87
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessStepper/index.tsx
@@ -0,0 +1 @@
+export { AcceptanceProcessStepper } from './AcceptanceProcessStepper';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard.test.tsx
new file mode 100644
index 0000000000..8149bc9266
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard.test.tsx
@@ -0,0 +1,19 @@
+import * as React from 'react';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../testUtils/testUtils';
+import { GreyInfoCard } from './GreyInfoCard';
+
+describe('components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard.tsx
new file mode 100644
index 0000000000..e2b683e32d
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard.tsx
@@ -0,0 +1,85 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import styled from 'styled-components';
+import { UniversalMoment } from '@core/UniversalMoment';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { MessageDialog } from './MessageDialog';
+
+const GreyText = styled.div`
+ color: #9e9e9e;
+`;
+
+const GreyTitle = styled.div`
+ color: #7c8990;
+ text-transform: uppercase;
+ font-size: 12px;
+`;
+
+const IconPlaceholder = styled.div`
+ width: 16px;
+ height: 16px;
+`;
+
+const GreyBox = styled(Box)`
+ background-color: #f4f5f6;
+`;
+
+interface GreyInfoCardProps {
+ topMessage: string;
+ topDate: string;
+ approvals: PaymentPlanQuery['paymentPlan']['approvalProcess']['edges'][number]['node']['actions']['approval'];
+}
+
+export function GreyInfoCard({
+ topMessage,
+ topDate,
+ approvals,
+}: GreyInfoCardProps): React.ReactElement {
+ const mappedApprovals = approvals.map((action) => {
+ const { info, createdAt, comment, createdBy } = action;
+ return (
+ info && (
+
+ {info}
+
+
+ on {createdAt}
+
+
+
+ {comment ? (
+
+ ) : (
+
+ )}
+
+
+ )
+ );
+ });
+
+ return (
+
+
+
+ {topMessage} on
+ {topDate}
+
+
+
+ {mappedApprovals}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/MessageDialog.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/MessageDialog.test.tsx
new file mode 100644
index 0000000000..bc4ecad8b4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/MessageDialog.test.tsx
@@ -0,0 +1,17 @@
+import * as React from 'react';
+import { fakeApolloMe } from '../../../../../fixtures/core/fakeApolloMe';
+import { render } from '../../../../testUtils/testUtils';
+import { MessageDialog } from './MessageDialog';
+
+describe('components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/MessageDialog', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/MessageDialog.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/MessageDialog.tsx
new file mode 100644
index 0000000000..2535b14a58
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/MessageDialog.tsx
@@ -0,0 +1,102 @@
+import {
+ Box,
+ Button,
+ DialogContent,
+ DialogTitle,
+ IconButton,
+} from '@mui/material';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import MessageIcon from '@mui/icons-material/Message';
+import styled from 'styled-components';
+import { Dialog } from '@containers/dialogs/Dialog';
+import { DialogActions } from '@containers/dialogs/DialogActions';
+import { UniversalMoment } from '@core/UniversalMoment';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DividerLine } from '@core/DividerLine';
+import { renderUserName } from '@utils/utils';
+import { UserNode } from '@generated/graphql';
+
+const DialogTitleWrapper = styled.div`
+ border-bottom: 1px solid ${({ theme }) => theme.hctPalette.lighterGray};
+`;
+
+const DialogFooter = styled.div`
+ padding: 12px 16px;
+ margin: 0;
+ border-top: 1px solid ${({ theme }) => theme.hctPalette.lighterGray};
+ text-align: right;
+`;
+
+const GreyText = styled.div`
+ color: #9e9e9e;
+`;
+
+const MessageIconContainer = styled(Box)`
+ position: relative;
+ top: 4px;
+ font-size: 16px;
+ color: #043f91;
+`;
+
+export interface MessageDialogProps {
+ comment: string;
+ author: Pick;
+ date: string;
+}
+export function MessageDialog({
+ comment,
+ author,
+ date,
+}: MessageDialogProps): React.ReactElement {
+ const { t } = useTranslation();
+ const [MessageDialogOpen, setMessageDialogOpen] = useState(false);
+ return (
+ <>
+ setMessageDialogOpen(true)}>
+
+
+
+
+ setMessageDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Comment')}
+
+
+
+
+
+ {renderUserName(author)}{' '}
+
+
+ on {date}
+
+
+
+
+ {comment}
+
+
+
+
+
+ setMessageDialogOpen(false)}
+ >
+ {t('Close')}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/AcceptanceProcessRow.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/AcceptanceProcessRow.test.tsx.snap
new file mode 100644
index 0000000000..7a81fdfaba
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/AcceptanceProcessRow.test.tsx.snap
@@ -0,0 +1,207 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcessRow should render 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+ Approval (1/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+ Authorization (0/1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+ Finance Release (0/1)
+
+
+
+
+
+
+
+
+
+
+ Sent for approval by Root Rootkowski
+ on
+
+ 30 Aug 2022
+
+
+
+
+
+ Approved by Root Rootkowski
+
+
+ on
+
+ 30 Aug 2022
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/GreyInfoCard.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/GreyInfoCard.test.tsx.snap
new file mode 100644
index 0000000000..5fee6dc88f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/GreyInfoCard.test.tsx.snap
@@ -0,0 +1,55 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/GreyInfoCard should render 1`] = `
+
+
+
+
+ Test top message
+ on
+
+ 1 Jan 2022
+
+
+
+
+
+ Approved by Root Rootkowski
+
+
+ on
+
+ 30 Aug 2022
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/MessageDialog.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/MessageDialog.test.tsx.snap
new file mode 100644
index 0000000000..d1d6f43191
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/__snapshots__/MessageDialog.test.tsx.snap
@@ -0,0 +1,30 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/MessageDialog should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/index.tsx
new file mode 100644
index 0000000000..251d9cbc1c
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/AcceptanceProcess/index.tsx
@@ -0,0 +1 @@
+export { AcceptanceProcess } from './AcceptanceProcess';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/Entitlement.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/Entitlement.test.tsx
new file mode 100644
index 0000000000..db1f3c7fa6
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/Entitlement.test.tsx
@@ -0,0 +1,24 @@
+import * as React from 'react';
+import { MockedProvider } from '@apollo/react-testing';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloAllSteficonRules } from '../../../../../fixtures/steficon/fakeApolloAllSteficonRules';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../testUtils/testUtils';
+import { Entitlement } from './Entitlement';
+import {PERMISSIONS} from "../../../../config/permissions";
+
+describe('components/paymentmodule/PaymentPlanDetails/Entitlement', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/Entitlement.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/Entitlement.tsx
new file mode 100644
index 0000000000..d4a14683c1
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/Entitlement.tsx
@@ -0,0 +1,347 @@
+import {
+ Box,
+ Button,
+ FormControl,
+ Grid,
+ InputLabel,
+ MenuItem,
+ Select,
+ Typography,
+} from '@mui/material';
+import { GetApp } from '@mui/icons-material';
+import AttachFileIcon from '@mui/icons-material/AttachFile';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { useSnackbar } from '@hooks/useSnackBar';
+import {
+ PaymentPlanBackgroundActionStatus,
+ PaymentPlanDocument,
+ PaymentPlanQuery,
+ PaymentPlanStatus,
+ useAllSteficonRulesQuery,
+ useExportXlsxPpListMutation,
+ useSetSteficonRuleOnPpListMutation,
+} from '@generated/graphql';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { LabelizedField } from '@core/LabelizedField';
+import { LoadingButton } from '@core/LoadingButton';
+import { LoadingComponent } from '@core/LoadingComponent';
+import { Title } from '@core/Title';
+import { UniversalMoment } from '@core/UniversalMoment';
+import { BigValue } from '../../../rdi/details/RegistrationDetails/RegistrationDetails';
+import { ImportXlsxPaymentPlanPaymentList } from '../ImportXlsxPaymentPlanPaymentList/ImportXlsxPaymentPlanPaymentList';
+import { useProgramContext } from '../../../../programContext';
+
+const GreyText = styled.p`
+ color: #9e9e9e;
+ font-size: 16px;
+`;
+
+const GreyTextSmall = styled.p`
+ color: #9e9e9e;
+ font-size: 14px;
+`;
+
+const OrDivider = styled.div`
+ border-top: 1px solid #b1b1b5;
+ height: 2px;
+ width: 50%;
+ margin-top: 20px;
+`;
+
+const Divider = styled.div`
+ border-top: 1px solid #b1b1b5;
+ height: 20px;
+`;
+
+const DividerLabel = styled.div`
+ width: 40px;
+ height: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ font-weight: 500;
+ color: #253b46;
+ text-transform: uppercase;
+ padding: 5px;
+ border: 1px solid #b1b1b5;
+ border-radius: 50%;
+ background-color: #fff;
+ margin-top: 20px;
+`;
+
+const DownloadIcon = styled(GetApp)`
+ color: #043f91;
+`;
+
+const SpinaczIconContainer = styled(Box)`
+ position: relative;
+ top: 4px;
+ font-size: 16px;
+ color: #666666;
+`;
+
+const BoxWithBorderRight = styled(Box)`
+ border-right: 1px solid #b1b1b5;
+`;
+
+interface EntitlementProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ permissions: string[];
+}
+
+export function Entitlement({
+ paymentPlan,
+ permissions,
+}: EntitlementProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { showMessage } = useSnackbar();
+ const { isActiveProgram } = useProgramContext();
+
+ const [steficonRuleValue, setSteficonRuleValue] = useState(
+ paymentPlan.steficonRule?.rule.id || '',
+ );
+ const options = {
+ refetchQueries: () => [
+ {
+ query: PaymentPlanDocument,
+ variables: {
+ id: paymentPlan.id,
+ },
+ },
+ ],
+ };
+
+ const [setSteficonRule, { loading: loadingSetSteficonRule }] =
+ useSetSteficonRuleOnPpListMutation(options);
+
+ const { data: steficonData, loading } = useAllSteficonRulesQuery({
+ variables: { enabled: true, deprecated: false, type: 'PAYMENT_PLAN' },
+ fetchPolicy: 'network-only',
+ });
+ const [mutateExport, { loading: loadingExport }] =
+ useExportXlsxPpListMutation();
+
+ if (!steficonData) {
+ return null;
+ }
+ if (loading) {
+ return ;
+ }
+
+ const canApplySteficonRule = hasPermissions(
+ PERMISSIONS.PM_APPLY_RULE_ENGINE_FORMULA_WITH_ENTITLEMENTS,
+ permissions,
+ );
+
+ const shouldDisableEntitlementSelect =
+ !canApplySteficonRule ||
+ paymentPlan.status !== PaymentPlanStatus.Locked ||
+ !isActiveProgram;
+
+ const shouldDisableDownloadTemplate =
+ paymentPlan.status !== PaymentPlanStatus.Locked || !isActiveProgram;
+
+ const shouldDisableExportXlsx =
+ loadingExport ||
+ paymentPlan.status !== PaymentPlanStatus.Locked ||
+ paymentPlan?.backgroundActionStatus ===
+ PaymentPlanBackgroundActionStatus.XlsxExporting ||
+ !isActiveProgram;
+
+ return (
+
+
+
+
+ {t('Entitlement')}
+
+ {t('Select Entitlement Formula')}
+
+
+
+
+ {t('Entitlement Formula')}
+
+ setSteficonRuleValue(event.target.value)}
+ >
+ {steficonData.allSteficonRules.edges.map((each, index) => (
+
+ {each.node.name}
+
+ ))}
+
+
+
+
+
+ {
+ try {
+ await setSteficonRule({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ steficonRuleId: steficonRuleValue,
+ },
+ });
+ showMessage(
+ t('Formula is executing, please wait until completed'),
+ );
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ }}
+ >
+ {t('Apply')}
+
+
+
+
+
+
+ Or
+
+
+
+
+
+
+ {paymentPlan.hasPaymentListExportFile ? (
+ }
+ component="a"
+ download
+ data-cy="button-download-template"
+ href={`/api/download-payment-plan-payment-list/${paymentPlan.id}`}
+ disabled={shouldDisableDownloadTemplate}
+ >
+ {t('DOWNLOAD TEMPLATE')}
+
+ ) : (
+ }
+ data-cy="button-export-xlsx"
+ onClick={async () => {
+ try {
+ await mutateExport({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ },
+ });
+ showMessage(
+ t('Exporting XLSX started. Please check your email.'),
+ );
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ }}
+ >
+ {t('Export Xlsx')}
+
+ )}
+
+
+ {t(
+ 'Template contains payment list with all targeted households',
+ )}
+
+
+
+
+
+
+
+
+ {paymentPlan?.importedFileName ? (
+
+
+
+
+
+
+ {paymentPlan?.importedFileName}
+
+
+
+ {paymentPlan?.importedFileDate ? (
+
+ {paymentPlan?.importedFileDate}
+
+ ) : null}
+
+
+ ) : (
+
+ {t(
+ 'Uploaded file should contain entitlement for each household',
+ )}
+
+ )}
+
+
+
+ {paymentPlan.totalEntitledQuantityUsd ? (
+ <>
+
+
+
+ {`${paymentPlan.totalEntitledQuantity} ${paymentPlan.currency} (${paymentPlan.totalEntitledQuantityUsd} USD)`}
+
+
+ >
+ ) : null}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/__snapshots__/Entitlement.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/__snapshots__/Entitlement.test.tsx.snap
new file mode 100644
index 0000000000..adbc5d0ea5
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/__snapshots__/Entitlement.test.tsx.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/Entitlement should render 1`] = `
`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/index.tsx
new file mode 100644
index 0000000000..95bae78325
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/Entitlement/index.tsx
@@ -0,0 +1 @@
+export { Entitlement } from './Entitlement';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/ExcludeSection.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/ExcludeSection.tsx
new file mode 100644
index 0000000000..2b86536934
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/ExcludeSection.tsx
@@ -0,0 +1,443 @@
+import {
+ Box,
+ Button,
+ Collapse,
+ FormHelperText,
+ Grid,
+ Typography,
+} from '@mui/material';
+import { Field, Form, Formik } from 'formik';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import * as Yup from 'yup';
+import {
+ PaymentPlanDocument,
+ PaymentPlanQuery,
+ PaymentPlanStatus,
+ useExcludeHouseholdsPpMutation,
+} from '@generated/graphql';
+import { PERMISSIONS, hasPermissions } from '../../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { FormikTextField } from '@shared/Formik/FormikTextField';
+import { StyledTextField } from '@shared/StyledTextField';
+import { ButtonTooltip } from '@core/ButtonTooltip';
+import { GreyText } from '@core/GreyText';
+import { PaperContainer } from '../../../targeting/PaperContainer';
+import { useProgramContext } from '../../../../programContext';
+import { ExcludedItem } from './ExcludedItem';
+
+interface ExcludeSectionProps {
+ initialOpen?: boolean;
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function ExcludeSection({
+ initialOpen = false,
+ paymentPlan,
+}: ExcludeSectionProps): React.ReactElement {
+ const {
+ status,
+ backgroundActionStatus,
+ exclusionReason,
+ excludeHouseholdError,
+ } = paymentPlan;
+
+ const initialExcludedIds = paymentPlan?.excludedHouseholds?.map(
+ (el) => el.unicefId,
+ );
+ const [isExclusionsOpen, setExclusionsOpen] = useState(initialOpen);
+ const [idsValue, setIdsValue] = useState('');
+ const [excludedIds, setExcludedIds] = useState(
+ initialExcludedIds || [],
+ );
+ const [deletedIds, setDeletedIds] = useState([]);
+ const { t } = useTranslation();
+ const permissions = usePermissions();
+ const { isActiveProgram } = useProgramContext();
+
+ const hasExcludePermission = hasPermissions(
+ PERMISSIONS.PM_EXCLUDE_BENEFICIARIES_FROM_FOLLOW_UP_PP,
+ permissions,
+ );
+ const hasOpenOrLockedStatus =
+ status === PaymentPlanStatus.Locked || status === PaymentPlanStatus.Open;
+
+ const getTooltipText = (): string => {
+ if (!hasOpenOrLockedStatus) {
+ return t(
+ 'Households can only be excluded from a Payment Plan in status open or locked',
+ );
+ }
+ if (!hasExcludePermission) {
+ return t('Permission denied');
+ }
+ return '';
+ };
+
+ const { showMessage } = useSnackbar();
+ const [errors, setErrors] = useState([]);
+ const [isEdit, setEdit] = useState(false);
+
+ const [mutate, { error }] = useExcludeHouseholdsPpMutation();
+
+ const handleIdsChange = (event): void => {
+ if (event.target.value === '') {
+ setErrors([]);
+ }
+ setIdsValue(event.target.value);
+ };
+ const initialValues = {
+ exclusionReason: paymentPlan.exclusionReason || '',
+ };
+ const validationSchema = Yup.object().shape({
+ exclusionReason: Yup.string().max(500, t('Too long')),
+ });
+
+ const handleSave = async (values): Promise => {
+ const idsToSave = excludedIds.filter((id) => !deletedIds.includes(id));
+ try {
+ await mutate({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ excludedHouseholdsIds: idsToSave,
+ exclusionReason: values.exclusionReason || null,
+ },
+ refetchQueries: () => [
+ {
+ query: PaymentPlanDocument,
+ variables: { id: paymentPlan.id },
+ fetchPolicy: 'network-only',
+ },
+ 'AllPaymentsForTable',
+ ],
+ awaitRefetchQueries: true,
+ });
+ if (!error) {
+ showMessage(t('Households exclusion started'));
+ setExclusionsOpen(false);
+ }
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ const handleApply = (): void => {
+ const idRegex =
+ /^(\s*HH-\d{2}-\d{4}\.\d{4}\s*)(,\s*HH-\d{2}-\d{4}\.\d{4}\s*)*$/;
+ const ids = idsValue.trim().split(/,\s*|\s+/);
+ const invalidIds: string[] = [];
+ const alreadyExcludedIds: string[] = [];
+ const newExcludedIds: string[] = [];
+
+ for (const id of ids) {
+ if (!idRegex.test(id)) {
+ invalidIds.push(id);
+ } else if (excludedIds.includes(id.trim())) {
+ alreadyExcludedIds.push(id);
+ } else {
+ newExcludedIds.push(id);
+ }
+ }
+
+ const idErrors: string[] = [];
+ if (invalidIds.length > 0) {
+ idErrors.push(` Invalid IDs: ${invalidIds.join(', ')}`);
+ }
+ if (alreadyExcludedIds.length > 0) {
+ idErrors.push(` IDs already excluded: ${alreadyExcludedIds.join(', ')}`);
+ }
+
+ if (idErrors.length > 0) {
+ setErrors(idErrors);
+ } else {
+ setErrors([]);
+ setExcludedIds([...excludedIds, ...newExcludedIds]);
+ setIdsValue('');
+ }
+ };
+
+ const handleDelete = (id: string): void => {
+ if (!deletedIds.includes(id)) {
+ setDeletedIds([...deletedIds, id]);
+ }
+ };
+
+ const handleUndo = (id: string): void => {
+ if (deletedIds.includes(id)) {
+ setDeletedIds(deletedIds.filter((deletedId) => deletedId !== id));
+ }
+ };
+
+ const handleCheckIfDeleted = (id: string): boolean => deletedIds.includes(id);
+
+ const numberOfExcluded = excludedIds.length - deletedIds.length;
+
+ const renderButtons = (submitForm, values, resetForm): React.ReactElement => {
+ const noExclusions = numberOfExcluded === 0;
+ const editMode = isExclusionsOpen && isEdit;
+ const previewMode =
+ (!isExclusionsOpen && numberOfExcluded > 0) ||
+ (!isExclusionsOpen && deletedIds.length > 0);
+
+ const resetExclusions = (): void => {
+ setExclusionsOpen(false);
+ setErrors([]);
+ setIdsValue('');
+ resetForm();
+ setEdit(false);
+ };
+
+ const saveExclusions = (): void => {
+ submitForm();
+ };
+ const saveExclusionsDisabled =
+ !hasExcludePermission ||
+ !hasOpenOrLockedStatus ||
+ excludedIds.length === 0 ||
+ Boolean(backgroundActionStatus);
+
+ const editExclusionsDisabled =
+ !hasExcludePermission || !hasOpenOrLockedStatus;
+
+ if (editMode) {
+ return (
+
+
+
+ {t('Cancel')}
+
+
+
+ {t('Save')}
+
+
+ );
+ }
+
+ if (previewMode) {
+ return (
+ {
+ setExclusionsOpen(true);
+ setEdit(false);
+ }}
+ data-cy="button-preview-exclusions"
+ >
+ {t('Preview Exclusion')}
+
+ );
+ }
+
+ if (isExclusionsOpen) {
+ return (
+
+
+
+ {t('Close')}
+
+
+ {hasExcludePermission && (
+ setEdit(true)}
+ data-cy="button-edit-exclusions"
+ >
+ {t('Edit')}
+
+ )}
+
+ );
+ }
+
+ if (noExclusions && !deletedIds.length) {
+ return (
+ {
+ setExclusionsOpen(true);
+ setEdit(true);
+ }}
+ disabled={!isActiveProgram}
+ >
+ {t('Create')}
+
+ );
+ }
+
+ return null;
+ };
+
+ const renderInputAndApply = (): React.ReactElement => {
+ const applyDisabled =
+ !hasExcludePermission ||
+ !hasOpenOrLockedStatus ||
+ Boolean(backgroundActionStatus);
+
+ if (isEdit || numberOfExcluded === 0) {
+ return (
+
+
+
+
+
+
+
+ 0}
+ />
+
+
+
+ {
+ handleApply();
+ }}
+ >
+ {t('Apply')}
+
+
+
+
+ );
+ }
+ return null;
+ };
+
+ const formatErrorToArray = (errorsString): string[] => {
+ // Remove brackets and quotes
+ const formattedError = errorsString.replace(/\[|\]|'|"/g, '');
+
+ // Split the formatted error into an array of strings
+ const errorArray = formattedError.split(', ');
+
+ return errorArray;
+ };
+
+ return (
+ handleSave(values)}
+ enableReinitialize
+ >
+ {({ submitForm, values, resetForm }) => (
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/ExcludedItem.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/ExcludedItem.tsx
new file mode 100644
index 0000000000..61c90a8a8a
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/ExcludedItem.tsx
@@ -0,0 +1,62 @@
+import { Box, Button, IconButton } from '@mui/material';
+import { Delete } from '@mui/icons-material';
+import * as React from 'react';
+import styled from 'styled-components';
+import { useTranslation } from 'react-i18next';
+
+const StyledBox = styled(Box)`
+ width: 100%;
+ height: 30px;
+ background-color: #f4f5f6;
+ color: '#404040';
+`;
+
+interface IdDivProps {
+ isDeleted: boolean;
+}
+
+const IdDiv = styled.div`
+ text-decoration: ${({ isDeleted }) => (isDeleted ? 'line-through' : 'none')};
+`;
+interface ExcludedItemProps {
+ id: string;
+ onDelete;
+ onUndo;
+ isDeleted: boolean;
+ isEdit: boolean;
+}
+
+export function ExcludedItem({
+ id,
+ onDelete,
+ onUndo,
+ isDeleted,
+ isEdit,
+}: ExcludedItemProps): React.ReactElement {
+ const { t } = useTranslation();
+
+ return (
+
+ {id}
+ {isEdit &&
+ (isDeleted ? (
+
+ {t('Undo')}
+
+ ) : (
+
+
+
+ ))}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/index.tsx
new file mode 100644
index 0000000000..1b6726c1f6
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ExcludeSection/index.tsx
@@ -0,0 +1 @@
+export { ExcludeSection } from './ExcludeSection';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/FspSection.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/FspSection.test.tsx
new file mode 100644
index 0000000000..4628bdc4b8
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/FspSection.test.tsx
@@ -0,0 +1,24 @@
+import * as React from 'react';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../testUtils/testUtils';
+import { FspSection } from './FspSection';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/PaymentPlanDetails/FspSection', () => {
+ it('should render Set Up FSP', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should render Edit FSP', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/FspSection.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/FspSection.tsx
new file mode 100644
index 0000000000..6c90ee58d9
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/FspSection.tsx
@@ -0,0 +1,111 @@
+import { Box, Button, Grid, Typography } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { Link, useParams } from 'react-router-dom';
+import { PaymentPlanQuery, PaymentPlanStatus } from '@generated/graphql';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { DividerLine } from '@core/DividerLine';
+import { LabelizedField } from '@core/LabelizedField';
+import { useProgramContext } from '../../../../programContext';
+import { VolumeByDeliveryMechanismSection } from './VolumeByDeliveryMechanismSection';
+
+interface FspSectionProps {
+ baseUrl: string;
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function FspSection({
+ baseUrl,
+ paymentPlan,
+}: FspSectionProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { id } = useParams();
+ const { isActiveProgram } = useProgramContext();
+
+ const { deliveryMechanisms, isFollowUp } = paymentPlan;
+ const showFspDisplay = deliveryMechanisms.length;
+ const shouldDisableSetUpFsp = (): boolean => {
+ if (paymentPlan.isFollowUp) {
+ return false;
+ }
+ if (!paymentPlan.totalEntitledQuantityUsd) {
+ return true;
+ }
+ if (!isActiveProgram) {
+ return true;
+ }
+ return false;
+ };
+
+ return showFspDisplay ? (
+
+
+
+ {t('FSPs')}
+ {paymentPlan.status === PaymentPlanStatus.Locked && (
+
+ {t('Edit FSP')}
+
+ )}
+
+
+ {deliveryMechanisms.map((el) => (
+ <>
+
+
+
+ {el.chosenConfiguration && (
+
+
+
+ )}
+ >
+ ))}
+
+
+
+
+
+ ) : (
+
+
+
+ {t('FSPs')}
+
+ {t('Set up FSP')}
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/VolumeByDeliveryMechanismSection.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/VolumeByDeliveryMechanismSection.test.tsx
new file mode 100644
index 0000000000..c7da617d07
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/VolumeByDeliveryMechanismSection.test.tsx
@@ -0,0 +1,13 @@
+import * as React from 'react';
+import { fakeApolloPaymentPlan } from '../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../../testUtils/testUtils';
+import { VolumeByDeliveryMechanismSection } from './VolumeByDeliveryMechanismSection';
+
+describe('components/paymentmodule/PaymentPlanDetails/VolumeByDeliveryMechanismSection', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/VolumeByDeliveryMechanismSection.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/VolumeByDeliveryMechanismSection.tsx
new file mode 100644
index 0000000000..b8da6f6bb7
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/VolumeByDeliveryMechanismSection.tsx
@@ -0,0 +1,135 @@
+import { Box, Grid, Typography } from '@mui/material';
+import * as React from 'react';
+import { Pie } from 'react-chartjs-2';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { LabelizedField } from '@core/LabelizedField';
+import { FieldBorder } from '@core/FieldBorder';
+
+const Title = styled.div`
+ padding-bottom: ${({ theme }) => theme.spacing(2)};
+`;
+
+const ContentWrapper = styled.div`
+ display: flex;
+`;
+
+const ChartContainer = styled.div`
+ width: 100px;
+ height: 100px;
+ margin: 0 auto;
+`;
+
+interface VolumeByDeliveryMechanismSectionProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+const DeliveryMechanismsColorsMap = new Map([
+ ['Cardless cash withdrawal', '#FC942A'],
+ ['Cash', '#D8E1EE'],
+ ['Cash by FSP', '#D8E1EE'],
+ ['Cheque', '#10CB16'],
+ ['Deposit to Card', '#4E606A'],
+ ['In Kind', ' #d8d8d8'],
+ ['Mobile Money', '#e4e4e4'],
+ ['Other', '#EF4343'],
+ ['Pre-paid card', '#D9D1CE'],
+ ['Referral', '#715247'],
+ ['Transfer', '#003C8F'],
+ ['Transfer to Account', '#003C8F'],
+ ['Voucher', '#00ADEF'],
+]);
+
+export const getDeliveryMechanismColor = (
+ deliveryMechanism: string,
+): string => {
+ if (DeliveryMechanismsColorsMap.has(deliveryMechanism)) {
+ return DeliveryMechanismsColorsMap.get(deliveryMechanism);
+ }
+ return '#CCC';
+};
+
+export const VolumeByDeliveryMechanismSection: React.FC<
+ VolumeByDeliveryMechanismSectionProps
+> = ({ paymentPlan }) => {
+ const { t } = useTranslation();
+ const { volumeByDeliveryMechanism } = paymentPlan;
+
+ const mappedDeliveryMechanism = volumeByDeliveryMechanism.map(
+ (vdm, index) => (
+
+
+
+
+
+ ),
+ );
+
+ const chartLabels = volumeByDeliveryMechanism.map(
+ (el) => `${el.deliveryMechanism.name} (${el.deliveryMechanism.fsp?.name})`,
+ );
+
+ const chartData = volumeByDeliveryMechanism.map((el) => el.volumeUsd);
+
+ const chartColors = (): string[] => {
+ const defaultColorsArray = volumeByDeliveryMechanism.map((el) =>
+ getDeliveryMechanismColor(el.deliveryMechanism.name),
+ );
+
+ return defaultColorsArray;
+ };
+
+ const data = {
+ labels: chartLabels,
+ datasets: [
+ {
+ data: chartData,
+ backgroundColor: chartColors(),
+ },
+ ],
+ } as any;
+
+ const options = {
+ legend: {
+ display: false,
+ },
+ } as any;
+
+ return (
+
+
+
+ {t('Volume by Delivery Mechanism')}
+ {' '}
+
+
+
+ {mappedDeliveryMechanism}
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/__snapshots__/VolumeByDeliveryMechanismSection.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/__snapshots__/VolumeByDeliveryMechanismSection.test.tsx.snap
new file mode 100644
index 0000000000..1dac7d9f68
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/__snapshots__/VolumeByDeliveryMechanismSection.test.tsx.snap
@@ -0,0 +1,127 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/VolumeByDeliveryMechanismSection should render 1`] = `
+
+
+
+
+ Volume by Delivery Mechanism
+
+
+
+
+
+
+
+
+
+ Cash (Miranda Ltd)
+
+
+
+ 0 PLN (0 USD)
+
+
+
+
+
+
+
+
+
+ In Kind (Frazier-Watson)
+
+
+
+ 0 PLN (0 USD)
+
+
+
+
+
+
+
+
+
+ Transfer (Bray Group)
+
+
+
+ 0 PLN (0 USD)
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/index.tsx
new file mode 100644
index 0000000000..e24b4c32d9
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/VolumeByDeliveryMechanismSection/index.tsx
@@ -0,0 +1 @@
+export { VolumeByDeliveryMechanismSection } from './VolumeByDeliveryMechanismSection';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/__snapshots__/FspSection.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/__snapshots__/FspSection.test.tsx.snap
new file mode 100644
index 0000000000..2e2f368f76
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/__snapshots__/FspSection.test.tsx.snap
@@ -0,0 +1,264 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/FspSection should render Edit FSP 1`] = `
+
+
+
+
+
+
+
+
+ Cash
+
+
+
+ Miranda Ltd
+
+
+
+
+
+
+
+ In Kind
+
+
+
+ Frazier-Watson
+
+
+
+
+
+
+
+ Transfer
+
+
+
+ Bray Group
+
+
+
+
+
+
+
+
+
+ Volume by Delivery Mechanism
+
+
+
+
+
+
+
+
+
+ Cash (Miranda Ltd)
+
+
+
+ 0 PLN (0 USD)
+
+
+
+
+
+
+
+
+
+ In Kind (Frazier-Watson)
+
+
+
+ 0 PLN (0 USD)
+
+
+
+
+
+
+
+
+
+ Transfer (Bray Group)
+
+
+
+ 0 PLN (0 USD)
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`components/paymentmodule/PaymentPlanDetails/FspSection should render Set Up FSP 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/index.tsx
new file mode 100644
index 0000000000..e5a99c5a4f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/FspSection/index.tsx
@@ -0,0 +1 @@
+export { FspSection } from './FspSection';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/ImportXlsxPaymentPlanPaymentList.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/ImportXlsxPaymentPlanPaymentList.test.tsx
new file mode 100644
index 0000000000..95ca714eb6
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/ImportXlsxPaymentPlanPaymentList.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeImportXlsxPpListMutation } from '../../../../../fixtures/paymentmodule/fakeImportXlsxPpListMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { ImportXlsxPaymentPlanPaymentList } from './ImportXlsxPaymentPlanPaymentList';
+import { PERMISSIONS } from '../../../../config/permissions';
+
+describe('components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/ImportXlsxPaymentPlanPaymentList.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/ImportXlsxPaymentPlanPaymentList.tsx
new file mode 100644
index 0000000000..d6fbc9ddbc
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/ImportXlsxPaymentPlanPaymentList.tsx
@@ -0,0 +1,166 @@
+import { Box, Button, Dialog, DialogActions, DialogTitle } from '@mui/material';
+import { Publish } from '@mui/icons-material';
+import get from 'lodash/get';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { ImportErrors } from '@containers/tables/payments/VerificationRecordsTable/errors/ImportErrors';
+import { useSnackbar } from '@hooks/useSnackBar';
+import {
+ ImportXlsxPpListMutation,
+ PaymentPlanDocument,
+ PaymentPlanQuery,
+ PaymentPlanStatus,
+ useImportXlsxPpListMutation,
+} from '@generated/graphql';
+import { DropzoneField } from '@core/DropzoneField';
+import { useProgramContext } from '../../../../programContext';
+import { LoadingButton } from '@core/LoadingButton';
+
+const Error = styled.div`
+ color: ${({ theme }) => theme.palette.error.dark};
+ padding: 20px;
+`;
+
+interface ImportXlsxPaymentPlanPaymentListProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ permissions: string[];
+}
+
+export function ImportXlsxPaymentPlanPaymentList({
+ paymentPlan,
+ permissions,
+}: ImportXlsxPaymentPlanPaymentListProps): React.ReactElement {
+ const { showMessage } = useSnackbar();
+ const [open, setOpenImport] = useState(false);
+ const [fileToImport, setFileToImport] = useState(null);
+ const { isActiveProgram } = useProgramContext();
+ const { t } = useTranslation();
+
+ const [mutate, { data: uploadData, loading: fileLoading, error }] =
+ useImportXlsxPpListMutation();
+
+ const xlsxErrors: ImportXlsxPpListMutation['importXlsxPaymentPlanPaymentList']['errors'] =
+ get(uploadData, 'importXlsxPaymentPlanPaymentList.errors');
+
+ const handleImport = async (): Promise => {
+ if (fileToImport) {
+ try {
+ const { data, errors } = await mutate({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ file: fileToImport,
+ },
+ refetchQueries: () => [
+ {
+ query: PaymentPlanDocument,
+ variables: {
+ id: paymentPlan.id,
+ },
+ },
+ ],
+ });
+ if (!errors && !data?.importXlsxPaymentPlanPaymentList.errors?.length) {
+ setOpenImport(false);
+ showMessage(t('Your import was successful!'));
+ }
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ }
+ };
+
+ const canUploadFile = hasPermissions(
+ PERMISSIONS.PM_IMPORT_XLSX_WITH_ENTITLEMENTS,
+ permissions,
+ );
+
+ const shouldDisableUpload =
+ paymentPlan.status !== PaymentPlanStatus.Locked ||
+ !canUploadFile ||
+ !isActiveProgram;
+
+ return (
+ <>
+
+ }
+ color="primary"
+ data-cy="button-import"
+ onClick={() => setOpenImport(true)}
+ disabled={shouldDisableUpload}
+ >
+ {t('Upload File')}
+
+
+ setOpenImport(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ >
+
+ {t('Select File to Import')}
+ <>
+ {
+ if (files.length === 0) {
+ return;
+ }
+ const file = files[0];
+ const fileSizeMB = file.size / (1024 * 1024);
+ if (fileSizeMB > 200) {
+ showMessage(
+ `File size is too big. It should be under 200MB, File size is ${fileSizeMB}MB`,
+ );
+ return;
+ }
+
+ setFileToImport(file);
+ }}
+ />
+ {fileToImport &&
+ (error?.graphQLErrors?.length || xlsxErrors?.length) ? (
+
+ Errors
+ {error
+ ? error.graphQLErrors.map((x) => (
+ {x.message}
+ ))
+ : null}
+
+
+ ) : null}
+ >
+
+ {
+ setOpenImport(false);
+ setFileToImport(null);
+ }}
+ >
+ CANCEL
+
+ handleImport()}
+ data-cy="button-import-entitlement"
+ >
+ {t('IMPORT')}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/__snapshots__/ImportXlsxPaymentPlanPaymentList.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/__snapshots__/ImportXlsxPaymentPlanPaymentList.test.tsx.snap
new file mode 100644
index 0000000000..8a98fe1402
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/__snapshots__/ImportXlsxPaymentPlanPaymentList.test.tsx.snap
@@ -0,0 +1,36 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList should render 1`] = `
+
+
+
+
+
+
+
+
+ Upload File
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/index.ts b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/index.ts
new file mode 100644
index 0000000000..dd9e53d522
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentList/index.ts
@@ -0,0 +1 @@
+export { ImportXlsxPaymentPlanPaymentList } from './ImportXlsxPaymentPlanPaymentList';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx
new file mode 100644
index 0000000000..1c2ad98944
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx
@@ -0,0 +1,48 @@
+import * as React from 'react';
+import { MockedProvider } from '@apollo/react-testing';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeImportXlsxPpListPerFspMutation } from '../../../../../fixtures/paymentmodule/fakeImportXlsxPpListPerFspMutation';
+import {
+ fakeApolloPaymentPlan,
+ fakeApolloPaymentPlanWithWrongBackgroundActionStatus,
+} from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../testUtils/testUtils';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { ImportXlsxPaymentPlanPaymentListPerFsp } from './ImportXlsxPaymentPlanPaymentListPerFsp';
+
+describe('components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should not render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/ImportXlsxPaymentPlanPaymentListPerFsp.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/ImportXlsxPaymentPlanPaymentListPerFsp.tsx
new file mode 100644
index 0000000000..699ee884af
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/ImportXlsxPaymentPlanPaymentListPerFsp.tsx
@@ -0,0 +1,183 @@
+import { Box, Button, Dialog, DialogActions, DialogTitle } from '@mui/material';
+import { Publish } from '@mui/icons-material';
+import get from 'lodash/get';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { ImportErrors } from '@containers/tables/payments/VerificationRecordsTable/errors/ImportErrors';
+import { useSnackbar } from '@hooks/useSnackBar';
+import {
+ ImportXlsxPpListPerFspMutation,
+ PaymentPlanBackgroundActionStatus,
+ PaymentPlanDocument,
+ PaymentPlanQuery,
+ useImportXlsxPpListPerFspMutation,
+} from '@generated/graphql';
+import { DropzoneField } from '@core/DropzoneField';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { useProgramContext } from '../../../../programContext';
+import { LoadingButton } from '@core/LoadingButton';
+
+const Error = styled.div`
+ color: ${({ theme }) => theme.palette.error.dark};
+ padding: 20px;
+`;
+
+const UploadIcon = styled(Publish)`
+ color: #043f91;
+`;
+
+const DisabledUploadIcon = styled(Publish)`
+ color: #00000042;
+`;
+
+interface ImportXlsxPaymentPlanPaymentListPerFspProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ permissions: string[];
+}
+
+const allowedState = [
+ null,
+ PaymentPlanBackgroundActionStatus.XlsxExportError,
+ PaymentPlanBackgroundActionStatus.XlsxImportError,
+ PaymentPlanBackgroundActionStatus.RuleEngineError,
+];
+
+export function ImportXlsxPaymentPlanPaymentListPerFsp({
+ paymentPlan,
+ permissions,
+}: ImportXlsxPaymentPlanPaymentListPerFspProps): React.ReactElement {
+ const { showMessage } = useSnackbar();
+ const [open, setOpenImport] = useState(false);
+ const [fileToImport, setFileToImport] = useState(null);
+ const { isActiveProgram } = useProgramContext();
+ const { t } = useTranslation();
+
+ const [mutate, { data: uploadData, loading: fileLoading, error }] =
+ useImportXlsxPpListPerFspMutation();
+
+ const xlsxErrors: ImportXlsxPpListPerFspMutation['importXlsxPaymentPlanPaymentListPerFsp']['errors'] =
+ get(uploadData, 'importXlsxPaymentPlanPaymentListPerFsp.errors');
+ const canUploadReconciliation =
+ hasPermissions(
+ PERMISSIONS.PM_IMPORT_XLSX_WITH_RECONCILIATION,
+ permissions,
+ ) && allowedState.includes(paymentPlan.backgroundActionStatus);
+
+ const handleImport = async (): Promise => {
+ if (fileToImport) {
+ try {
+ const { data, errors } = await mutate({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ file: fileToImport,
+ },
+ refetchQueries: () => [
+ {
+ query: PaymentPlanDocument,
+ variables: {
+ id: paymentPlan.id,
+ },
+ },
+ ],
+ });
+ if (
+ !errors &&
+ !data?.importXlsxPaymentPlanPaymentListPerFsp.errors?.length
+ ) {
+ setOpenImport(false);
+ showMessage(t('Your import was successful!'));
+ }
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ }
+ };
+
+ return (
+ <>
+ {canUploadReconciliation && (
+
+ :
+ }
+ color="primary"
+ data-cy="button-import"
+ onClick={() => setOpenImport(true)}
+ disabled={!isActiveProgram}
+ >
+ {t('Upload Reconciliation Info')}
+
+
+ )}
+ setOpenImport(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ >
+
+ {t('Select File to Import')}
+ <>
+ {
+ if (files.length === 0) {
+ return;
+ }
+ const file = files[0];
+ const fileSizeMB = file.size / (1024 * 1024);
+ if (fileSizeMB > 200) {
+ showMessage(
+ `File size is too big. It should be under 200MB, File size is ${fileSizeMB}MB`,
+ );
+ return;
+ }
+
+ setFileToImport(file);
+ }}
+ />
+ {fileToImport &&
+ (error?.graphQLErrors?.length || xlsxErrors?.length) ? (
+
+ Errors
+ {error
+ ? error.graphQLErrors.map((x) => (
+ {x.message}
+ ))
+ : null}
+
+
+ ) : null}
+ >
+
+ {
+ setOpenImport(false);
+ setFileToImport(null);
+ }}
+ >
+ CANCEL
+
+ handleImport()}
+ data-cy="button-import-submit"
+ >
+ {t('IMPORT')}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/__snapshots__/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/__snapshots__/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx.snap
new file mode 100644
index 0000000000..23514352ac
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/__snapshots__/ImportXlsxPaymentPlanPaymentListPerFsp.test.tsx.snap
@@ -0,0 +1,38 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp should not render 1`] = `
`;
+
+exports[`components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp should render 1`] = `
+
+
+
+
+
+
+
+
+ Upload Reconciliation Info
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/index.ts b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/index.ts
new file mode 100644
index 0000000000..b0cec4a3f6
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp/index.ts
@@ -0,0 +1 @@
+export { ImportXlsxPaymentPlanPaymentListPerFsp } from './ImportXlsxPaymentPlanPaymentListPerFsp';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/PaymentPlanDetails.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/PaymentPlanDetails.test.tsx
new file mode 100644
index 0000000000..ccd2f56e01
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/PaymentPlanDetails.test.tsx
@@ -0,0 +1,17 @@
+import * as React from 'react';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { render } from '../../../../testUtils/testUtils';
+import { PaymentPlanDetails } from './PaymentPlanDetails';
+import { fakeBaseUrl } from '../../../../../fixtures/core/fakeBaseUrl';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetails', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/PaymentPlanDetails.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/PaymentPlanDetails.tsx
new file mode 100644
index 0000000000..5d0c5ba1ad
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/PaymentPlanDetails.tsx
@@ -0,0 +1,108 @@
+import { Grid, Typography } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { renderUserName } from '@utils/utils';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { BlackLink } from '@core/BlackLink';
+import { ContainerColumnWithBorder } from '@core/ContainerColumnWithBorder';
+import { LabelizedField } from '@core/LabelizedField';
+import { OverviewContainer } from '@core/OverviewContainer';
+import { Title } from '@core/Title';
+import { UniversalMoment } from '@core/UniversalMoment';
+import { FieldBorder } from '@core/FieldBorder';
+import { RelatedFollowUpPaymentPlans } from './RelatedFollowUpPaymentPlans';
+
+interface PaymentPlanDetailsProps {
+ baseUrl: string;
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export const PaymentPlanDetails = ({
+ baseUrl,
+ paymentPlan,
+}: PaymentPlanDetailsProps): React.ReactElement => {
+ const { t } = useTranslation();
+ const {
+ createdBy,
+ program,
+ targetPopulation,
+ currency,
+ startDate,
+ endDate,
+ dispersionStartDate,
+ dispersionEndDate,
+ followUps,
+ } = paymentPlan;
+
+ return (
+
+
+
+ {t('Details')}
+
+
+
+
+
+
+ {renderUserName(createdBy)}
+
+
+
+
+
+ {program.name}
+
+
+
+
+
+
+ {targetPopulation.name}
+
+
+
+
+
+ {currency}
+
+
+
+
+ {startDate}
+
+
+
+
+ {endDate}
+
+
+
+
+ {dispersionStartDate}
+
+
+
+
+ {dispersionEndDate}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/RelatedFollowUpPaymentPlans.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/RelatedFollowUpPaymentPlans.tsx
new file mode 100644
index 0000000000..1002958170
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/RelatedFollowUpPaymentPlans.tsx
@@ -0,0 +1,58 @@
+import * as React from 'react';
+import { useState } from 'react';
+import Button from '@mui/material/Button';
+import { Box } from '@mui/material';
+import { useTranslation } from 'react-i18next';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { BlackLink } from '@core/BlackLink';
+import { LabelizedField } from '@core/LabelizedField';
+
+interface RelatedFollowUpPaymentPlansProps {
+ baseUrl: string;
+ followUps: PaymentPlanQuery['paymentPlan']['followUps'];
+}
+
+export function RelatedFollowUpPaymentPlans({
+ followUps,
+ baseUrl,
+}: RelatedFollowUpPaymentPlansProps): React.ReactElement {
+ const { t } = useTranslation();
+ const [showAll, setShowAll] = useState(false);
+
+ const handleButtonClick = (): void => {
+ setShowAll(!showAll);
+ };
+
+ let followUpLinks = null;
+ if (followUps?.edges?.length > 0) {
+ const truncatedFollowUps = showAll
+ ? followUps.edges
+ : followUps.edges.slice(0, 5);
+ followUpLinks = truncatedFollowUps.map((followUp) => (
+
+ {followUp?.node?.unicefId}
+
+
+ ));
+ }
+
+ return (
+
+
+ {followUpLinks || '-'}
+ {followUps?.edges?.length > 5 && (
+
+ {showAll ? t('Hide') : t('See all')}
+
+ )}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/__snapshots__/PaymentPlanDetails.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/__snapshots__/PaymentPlanDetails.test.tsx.snap
new file mode 100644
index 0000000000..7439af2ea4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/__snapshots__/PaymentPlanDetails.test.tsx.snap
@@ -0,0 +1,272 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetails should render 1`] = `
+
+
+
+
+
+ Details
+
+
+
+
+
+
+
+
+ Created By
+
+
+
+ Matthew Sosa
+
+
+
+
+
+
+
+
+ Target Population
+
+
+
+
+
+
+
+ Currency
+
+
+
+ PLN
+
+
+
+
+
+
+
+ Start Date
+
+
+
+
+ 27 Oct 2020
+
+
+
+
+
+
+
+
+ End Date
+
+
+
+
+ 8 Sep 2021
+
+
+
+
+
+
+
+
+ Dispersion Start Date
+
+
+
+
+ 19 May 2028
+
+
+
+
+
+
+
+
+ Dispersion End Date
+
+
+
+
+ 7 Aug 2029
+
+
+
+
+
+
+
+
+
+
+
+ Related Follow-Up Payment Plans
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/index.tsx
new file mode 100644
index 0000000000..a33564d3b8
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetails/index.tsx
@@ -0,0 +1 @@
+export { PaymentPlanDetails } from './PaymentPlanDetails';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan.test.tsx
new file mode 100644
index 0000000000..320632e959
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { ApprovePaymentPlan } from './ApprovePaymentPlan';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan.tsx
new file mode 100644
index 0000000000..3bab4929ee
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan.tsx
@@ -0,0 +1,145 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+} from '@mui/material';
+import * as Yup from 'yup';
+import { Field, Form, Formik } from 'formik';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { FormikTextField } from '@shared/Formik/FormikTextField/FormikTextField';
+import { LoadingButton } from '@core/LoadingButton';
+import { GreyText } from '@core/GreyText';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { Action, PaymentPlanQuery } from '@generated/graphql';
+import { AutoSubmitFormOnEnter } from '@core/AutoSubmitFormOnEnter';
+import { useProgramContext } from '../../../../programContext';
+
+export interface ApprovePaymentPlanProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function ApprovePaymentPlan({
+ paymentPlan,
+}: ApprovePaymentPlanProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { isActiveProgram } = useProgramContext();
+
+ const [approveDialogOpen, setApproveDialogOpen] = useState(false);
+ const { showMessage } = useSnackbar();
+
+ const { mutatePaymentPlanAction: approve, loading: loadingApprove } =
+ usePaymentPlanAction(
+ Action.Approve,
+ paymentPlan.id,
+ () => showMessage(t('Payment Plan has been approved.')),
+ () => setApproveDialogOpen(false),
+ );
+ const initialValues = {
+ comment: '',
+ };
+
+ const validationSchema = Yup.object().shape({
+ comment: Yup.string().min(4, 'Too short').max(255, 'Too long'),
+ });
+
+ const shouldShowLastApproverMessage = (): boolean => {
+ const approvalNumberRequired =
+ paymentPlan.approvalProcess?.edges[0]?.node.approvalNumberRequired;
+
+ const approvalsCount =
+ paymentPlan.approvalProcess?.edges[0]?.node.actions.approval.length;
+
+ return approvalNumberRequired - 1 === approvalsCount;
+ };
+
+ return (
+ {
+ approve(values.comment);
+ resetForm({});
+ }}
+ validationSchema={validationSchema}
+ >
+ {({ submitForm }) => (
+ <>
+ {approveDialogOpen && }
+
+ setApproveDialogOpen(true)}
+ data-cy="button-approve"
+ disabled={!isActiveProgram}
+ >
+ {t('Approve')}
+
+
+ setApproveDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Approve Payment Plan')}
+
+
+
+
+ {t('Are you sure you want to approve this Payment Plan?')}
+
+ {shouldShowLastApproverMessage() && (
+
+
+ {t(
+ 'Note: You are the last approver. Upon proceeding, this Payment Plan will be automatically moved to authorization stage.',
+ )}
+
+
+ )}
+
+
+
+
+
+ setApproveDialogOpen(false)}>
+ CANCEL
+
+
+ {t('Approve')}
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan.test.tsx
new file mode 100644
index 0000000000..1d6811b78b
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { AuthorizePaymentPlan } from './AuthorizePaymentPlan';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan.tsx
new file mode 100644
index 0000000000..c6eb505765
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan.tsx
@@ -0,0 +1,144 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+} from '@mui/material';
+import * as Yup from 'yup';
+import { Field, Form, Formik } from 'formik';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { FormikTextField } from '@shared/Formik/FormikTextField/FormikTextField';
+import { LoadingButton } from '@core/LoadingButton';
+import { GreyText } from '@core/GreyText';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { Action, PaymentPlanQuery } from '@generated/graphql';
+import { AutoSubmitFormOnEnter } from '@core/AutoSubmitFormOnEnter';
+import { useProgramContext } from '../../../../programContext';
+
+export interface AuthorizePaymentPlanProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function AuthorizePaymentPlan({
+ paymentPlan,
+}: AuthorizePaymentPlanProps): React.ReactElement {
+ const { t } = useTranslation();
+ const [authorizeDialogOpen, setAuthorizeDialogOpen] = useState(false);
+ const { isActiveProgram } = useProgramContext();
+
+ const { showMessage } = useSnackbar();
+ const { mutatePaymentPlanAction: authorize, loading: loadingAuthorize } =
+ usePaymentPlanAction(
+ Action.Authorize,
+ paymentPlan.id,
+ () => showMessage(t('Payment Plan has been authorized.')),
+ () => setAuthorizeDialogOpen(false),
+ );
+ const initialValues = {
+ comment: '',
+ };
+
+ const validationSchema = Yup.object().shape({
+ comment: Yup.string().min(4, 'Too short').max(255, 'Too long'),
+ });
+
+ const shouldShowLastAuthorizerMessage = (): boolean => {
+ const authorizationNumberRequired =
+ paymentPlan.approvalProcess?.edges[0]?.node.authorizationNumberRequired;
+
+ const authorizationsCount =
+ paymentPlan.approvalProcess?.edges[0]?.node.actions.authorization.length;
+
+ return authorizationNumberRequired - 1 === authorizationsCount;
+ };
+
+ return (
+ {
+ authorize(values.comment);
+ resetForm({});
+ }}
+ validationSchema={validationSchema}
+ >
+ {({ submitForm }) => (
+ <>
+ {authorizeDialogOpen && }
+
+ setAuthorizeDialogOpen(true)}
+ data-cy="button-authorize"
+ disabled={!isActiveProgram}
+ >
+ {t('Authorize')}
+
+
+ setAuthorizeDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Authorize')}
+
+
+
+
+ {t('Are you sure you want to authorize this Payment Plan?')}
+
+ {shouldShowLastAuthorizerMessage() && (
+
+
+ {t(
+ 'Note: Upon Proceeding, this Payment Plan will be automatically moved to Finance Release stage.',
+ )}
+
+
+ )}
+
+
+
+
+
+ setAuthorizeDialogOpen(false)}>
+ CANCEL
+
+
+ {t('Authorize')}
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan.test.tsx
new file mode 100644
index 0000000000..90c5f77132
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { DeletePaymentPlan } from './DeletePaymentPlan';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan.tsx
new file mode 100644
index 0000000000..5a2f47d07a
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan.tsx
@@ -0,0 +1,98 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ IconButton,
+} from '@mui/material';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { Delete } from '@mui/icons-material';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { PaymentPlanQuery, useDeletePpMutation } from '@generated/graphql';
+import { LoadingButton } from '@core/LoadingButton';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { useProgramContext } from '../../../../programContext';
+import { useNavigate } from 'react-router-dom';
+
+export interface DeletePaymentPlanProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function DeletePaymentPlan({
+ paymentPlan,
+}: DeletePaymentPlanProps): React.ReactElement {
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
+ const { baseUrl } = useBaseUrl();
+ const { showMessage } = useSnackbar();
+ const [mutate, { loading: loadingDelete }] = useDeletePpMutation();
+ const { id } = paymentPlan;
+ const { isActiveProgram } = useProgramContext();
+
+ const handleDelete = async (): Promise => {
+ try {
+ await mutate({
+ variables: {
+ paymentPlanId: id,
+ },
+ });
+ showMessage(t('Payment Plan Deleted'));
+ navigate(`/${baseUrl}/payment-module`);
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+ return (
+ <>
+
+ setDeleteDialogOpen(true)}
+ disabled={!isActiveProgram}
+ >
+
+
+
+ setDeleteDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Delete Payment Plan')}
+
+
+
+
+ {t('Are you sure you want to remove this Payment Plan?')}
+
+
+
+
+
+ setDeleteDialogOpen(false)}>CANCEL
+ handleDelete()}
+ data-cy="button-submit"
+ >
+ {t('Delete')}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons.test.tsx
new file mode 100644
index 0000000000..7d498ef5ba
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons.test.tsx
@@ -0,0 +1,50 @@
+import { MockedProvider } from "@apollo/react-testing";
+import { act } from "react-dom/test-utils";
+import wait from "waait";
+import * as React from "react";
+import { fakeApolloPaymentPlan } from "../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan";
+import { fakeExportXlsxPpListPerFspMutation } from "../../../../../../fixtures/paymentmodule/fakeExportXlsxPpListPerFspMutation";
+import { render } from "../../../../../testUtils/testUtils";
+import { AcceptedPaymentPlanHeaderButtons } from "./AcceptedPaymentPlanHeaderButtons";
+
+describe("components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons", () => {
+ it("should render disabled buttons", async () => {
+ const { container } = render(
+
+
+
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+
+ it("should render not disabled buttons", async () => {
+ const { container } = render(
+
+
+
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons.tsx
new file mode 100644
index 0000000000..1cb868b3b4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons.tsx
@@ -0,0 +1,130 @@
+import { Box, Button } from '@mui/material';
+import { GetApp } from '@mui/icons-material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { LoadingButton } from '../../../../core/LoadingButton';
+import { CreateFollowUpPaymentPlan } from '../../../CreateFollowUpPaymentPlan';
+import { useProgramContext } from '../../../../../programContext';
+import { usePaymentPlanAction } from '../../../../../hooks/usePaymentPlanAction';
+import {
+ Action,
+ PaymentPlanBackgroundActionStatus,
+ PaymentPlanQuery,
+ useExportXlsxPpListPerFspMutation,
+} from '../../../../../__generated__/graphql';
+import { SplitIntoPaymentLists } from '../SplitIntoPaymentLists';
+
+export interface AcceptedPaymentPlanHeaderButtonsProps {
+ canDownloadXlsx: boolean;
+ canExportXlsx: boolean;
+ canSendToPaymentGateway: boolean;
+ canSplit: boolean;
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function AcceptedPaymentPlanHeaderButtons({
+ canDownloadXlsx,
+ canExportXlsx,
+ canSendToPaymentGateway,
+ canSplit,
+ paymentPlan,
+}: AcceptedPaymentPlanHeaderButtonsProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { showMessage } = useSnackbar();
+ const { isActiveProgram } = useProgramContext();
+
+ const [mutateExport, { loading: loadingExport }] =
+ useExportXlsxPpListPerFspMutation();
+
+ const {
+ mutatePaymentPlanAction: sendToPaymentGateway,
+ loading: LoadingSendToPaymentGateway,
+ } = usePaymentPlanAction(Action.SendToPaymentGateway, paymentPlan.id, () =>
+ showMessage(t('Sending to Payment Gateway started')),
+ );
+
+ const shouldDisableExportXlsx =
+ loadingExport ||
+ !paymentPlan.hasFspDeliveryMechanismXlsxTemplate ||
+ !canExportXlsx ||
+ paymentPlan?.backgroundActionStatus ===
+ PaymentPlanBackgroundActionStatus.XlsxExporting ||
+ !isActiveProgram;
+
+ return (
+
+ <>
+ {paymentPlan.canCreateFollowUp && (
+
+
+
+ )}
+
+
+
+ {!paymentPlan.hasPaymentListExportFile && (
+
+ }
+ data-cy="button-export-xlsx"
+ onClick={async () => {
+ try {
+ await mutateExport({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ },
+ });
+ showMessage(t('Exporting XLSX started'));
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ }}
+ >
+ {t('Export Xlsx')}
+
+
+ )}
+ {paymentPlan.hasPaymentListExportFile && (
+
+
+ {t('Download XLSX')}
+
+
+ )}
+ {canSendToPaymentGateway && (
+
+ sendToPaymentGateway()}
+ data-cy="button-send-to-payment-gateway"
+ disabled={LoadingSendToPaymentGateway}
+ >
+ {t('Send to FSP')}
+
+
+ )}
+ >
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons.test.tsx
new file mode 100644
index 0000000000..26ed5e409e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons.test.tsx
@@ -0,0 +1,26 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../../testUtils/testUtils';
+import { InApprovalPaymentPlanHeaderButtons } from './InApprovalPaymentPlanHeaderButtons';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons', () => {
+ it('should render with buttons', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons.tsx
new file mode 100644
index 0000000000..037f25eba3
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons.tsx
@@ -0,0 +1,24 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { ApprovePaymentPlan } from '../ApprovePaymentPlan';
+import { RejectPaymentPlan } from '../RejectPaymentPlan';
+
+export interface InApprovalPaymentPlanHeaderButtonsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ canReject: boolean;
+ canApprove: boolean;
+}
+
+export function InApprovalPaymentPlanHeaderButtons({
+ paymentPlan,
+ canReject,
+ canApprove,
+}: InApprovalPaymentPlanHeaderButtonsProps): React.ReactElement {
+ return (
+
+ {canReject && }
+ {canApprove && }
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons.test.tsx
new file mode 100644
index 0000000000..832069b346
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons.test.tsx
@@ -0,0 +1,26 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../../testUtils/testUtils';
+import { InAuthorizationPaymentPlanHeaderButtons } from './InAuthorizationPaymentPlanHeaderButtons';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons', () => {
+ it('should render with buttons', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons.tsx
new file mode 100644
index 0000000000..353dd0cc63
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons.tsx
@@ -0,0 +1,24 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { AuthorizePaymentPlan } from '../AuthorizePaymentPlan';
+import { RejectPaymentPlan } from '../RejectPaymentPlan';
+
+export interface InAuthorizationPaymentPlanHeaderButtonsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ canReject: boolean;
+ canAuthorize: boolean;
+}
+
+export function InAuthorizationPaymentPlanHeaderButtons({
+ paymentPlan,
+ canReject,
+ canAuthorize,
+}: InAuthorizationPaymentPlanHeaderButtonsProps): React.ReactElement {
+ return (
+
+ {canReject && }
+ {canAuthorize && }
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons.test.tsx
new file mode 100644
index 0000000000..e91bf0a023
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons.test.tsx
@@ -0,0 +1,26 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../../testUtils/testUtils';
+import { InReviewPaymentPlanHeaderButtons } from './InReviewPaymentPlanHeaderButtons';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons', () => {
+ it('should render with buttons', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons.tsx
new file mode 100644
index 0000000000..c1476cde3f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons.tsx
@@ -0,0 +1,26 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { MarkAsReleasedPaymentPlan } from '../MarkAsReleasedPaymentPlan';
+import { RejectPaymentPlan } from '../RejectPaymentPlan';
+
+export interface InReviewPaymentPlanHeaderButtonsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ canReject: boolean;
+ canMarkAsReleased: boolean;
+}
+
+export function InReviewPaymentPlanHeaderButtons({
+ paymentPlan,
+ canReject,
+ canMarkAsReleased,
+}: InReviewPaymentPlanHeaderButtonsProps): React.ReactElement {
+ return (
+
+ {canReject && }
+ {canMarkAsReleased && (
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedFspPaymentPlanHeaderButtons.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedFspPaymentPlanHeaderButtons.tsx
new file mode 100644
index 0000000000..22a153564e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedFspPaymentPlanHeaderButtons.tsx
@@ -0,0 +1,68 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { Action, PaymentPlanQuery } from '@generated/graphql';
+import { LoadingButton } from '@core/LoadingButton';
+import { useProgramContext } from '../../../../../programContext';
+
+export interface LockedFspPaymentPlanHeaderButtonsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ canUnlock: boolean;
+ canSendForApproval: boolean;
+}
+
+export function LockedFspPaymentPlanHeaderButtons({
+ paymentPlan,
+ canUnlock,
+ canSendForApproval,
+}: LockedFspPaymentPlanHeaderButtonsProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { id } = paymentPlan;
+ const { showMessage } = useSnackbar();
+ const { isActiveProgram } = useProgramContext();
+
+ const { mutatePaymentPlanAction: unlock, loading: loadingUnlock } =
+ usePaymentPlanAction(Action.UnlockFsp, id, () =>
+ showMessage(t('Payment Plan FSPs have been unlocked.')),
+ );
+ const {
+ mutatePaymentPlanAction: sendForApproval,
+ loading: loadingSendForApproval,
+ } = usePaymentPlanAction(Action.SendForApproval, id, () =>
+ showMessage(t('Payment Plan has been sent for approval.')),
+ );
+
+ return (
+
+ {canUnlock && (
+
+ unlock()}
+ disabled={!isActiveProgram}
+ >
+ {t('Unlock FSP')}
+
+
+ )}
+ {canSendForApproval && (
+
+ sendForApproval()}
+ data-cy="button-send-for-approval"
+ disabled={!isActiveProgram}
+ >
+ {t('Send For Approval')}
+
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons.test.tsx
new file mode 100644
index 0000000000..7e1f6f40a2
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons.test.tsx
@@ -0,0 +1,27 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../../testUtils/testUtils';
+import { PERMISSIONS } from '../../../../../config/permissions';
+import { LockedPaymentPlanHeaderButtons } from './LockedPaymentPlanHeaderButtons';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons', () => {
+ it('should render with buttons', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons.tsx
new file mode 100644
index 0000000000..1d7f0445ec
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons.tsx
@@ -0,0 +1,50 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { Action, PaymentPlanQuery } from '@generated/graphql';
+import { LoadingButton } from '@core/LoadingButton';
+import { LockFspPaymentPlan } from '../LockFspPaymentPlan';
+import { useProgramContext } from '../../../../../programContext';
+
+export interface LockedPaymentPlanHeaderButtonsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ canUnlock: boolean;
+ permissions: string[];
+}
+
+export function LockedPaymentPlanHeaderButtons({
+ paymentPlan,
+ canUnlock,
+ permissions,
+}: LockedPaymentPlanHeaderButtonsProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { id } = paymentPlan;
+ const { showMessage } = useSnackbar();
+ const { isActiveProgram } = useProgramContext();
+
+ const { mutatePaymentPlanAction: unlock, loading: loadingUnlock } =
+ usePaymentPlanAction(Action.Unlock, id, () =>
+ showMessage(t('Payment Plan has been unlocked.')),
+ );
+
+ return (
+
+ {canUnlock && (
+
+ unlock()}
+ disabled={!isActiveProgram}
+ >
+ {t('Unlock')}
+
+
+ )}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons.test.tsx
new file mode 100644
index 0000000000..440e60517a
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons.test.tsx
@@ -0,0 +1,27 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../../testUtils/testUtils';
+import { OpenPaymentPlanHeaderButtons } from './OpenPaymentPlanHeaderButtons';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons', () => {
+ it('should render with buttons', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons.tsx
new file mode 100644
index 0000000000..7927f5e2d1
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons.tsx
@@ -0,0 +1,56 @@
+import { Box, Button } from '@mui/material';
+import { EditRounded } from '@mui/icons-material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { Link } from 'react-router-dom';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { DeletePaymentPlan } from '../DeletePaymentPlan';
+import { LockPaymentPlan } from '../LockPaymentPlan';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { useProgramContext } from '../../../../../programContext';
+
+export interface OpenPaymentPlanHeaderButtonsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ canRemove: boolean;
+ canEdit: boolean;
+ canLock: boolean;
+}
+
+export function OpenPaymentPlanHeaderButtons({
+ paymentPlan,
+ canRemove,
+ canEdit,
+ canLock,
+}: OpenPaymentPlanHeaderButtonsProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { baseUrl } = useBaseUrl();
+ const { isActiveProgram } = useProgramContext();
+ const { id, isFollowUp } = paymentPlan;
+
+ return (
+
+ {canRemove && }
+ {canEdit && (
+
+ }
+ component={Link}
+ to={`/${baseUrl}/payment-module/${
+ isFollowUp ? 'followup-payment-plans' : 'payment-plans'
+ }/${id}/edit`}
+ disabled={!isActiveProgram}
+ >
+ {t('Edit')}
+
+
+ )}
+ {canLock && (
+
+
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/AcceptedPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/AcceptedPaymentPlanHeaderButtons.test.tsx.snap
new file mode 100644
index 0000000000..5f30b8cb0e
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/AcceptedPaymentPlanHeaderButtons.test.tsx.snap
@@ -0,0 +1,156 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons should render disabled buttons 1`] = `
+
+
+
+
+
+
+
+
+
+
+ Export Xlsx
+
+
+
+
+`;
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons should render not disabled buttons 1`] = `
+
+
+
+
+
+
+
+
+
+
+ Export Xlsx
+
+
+
+
+
+ Send to FSP
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InApprovalPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InApprovalPaymentPlanHeaderButtons.test.tsx.snap
new file mode 100644
index 0000000000..22231e7d0f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InApprovalPaymentPlanHeaderButtons.test.tsx.snap
@@ -0,0 +1,39 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InApprovalPaymentPlanHeaderButtons should render with buttons 1`] = `
+
+
+
+
+ Reject
+
+
+
+
+
+ Approve
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InAuthorizationPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InAuthorizationPaymentPlanHeaderButtons.test.tsx.snap
new file mode 100644
index 0000000000..c888f0a2cb
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InAuthorizationPaymentPlanHeaderButtons.test.tsx.snap
@@ -0,0 +1,39 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InAuthorizationPaymentPlanHeaderButtons should render with buttons 1`] = `
+
+
+
+
+ Reject
+
+
+
+
+
+ Authorize
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InReviewPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InReviewPaymentPlanHeaderButtons.test.tsx.snap
new file mode 100644
index 0000000000..dccbd8e964
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/InReviewPaymentPlanHeaderButtons.test.tsx.snap
@@ -0,0 +1,39 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/InReviewPaymentPlanHeaderButtons should render with buttons 1`] = `
+
+
+
+
+ Reject
+
+
+
+
+
+ Mark as released
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/LockedPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/LockedPaymentPlanHeaderButtons.test.tsx.snap
new file mode 100644
index 0000000000..39fd92a70f
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/LockedPaymentPlanHeaderButtons.test.tsx.snap
@@ -0,0 +1,25 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/LockedPaymentPlanHeaderButtons should render with buttons 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/OpenPaymentPlanHeaderButtons.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/OpenPaymentPlanHeaderButtons.test.tsx.snap
new file mode 100644
index 0000000000..2653fdf16b
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/__snapshots__/OpenPaymentPlanHeaderButtons.test.tsx.snap
@@ -0,0 +1,82 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/OpenPaymentPlanHeaderButtons should render with buttons 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockFspPaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockFspPaymentPlan.tsx
new file mode 100644
index 0000000000..4e0e554ba0
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockFspPaymentPlan.tsx
@@ -0,0 +1,97 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+} from '@mui/material';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { Action, PaymentPlanQuery } from '@generated/graphql';
+import { LoadingButton } from '@core/LoadingButton';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import { useProgramContext } from '../../../../programContext';
+
+export interface LockFspPaymentPlanProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ permissions: string[];
+}
+
+export function LockFspPaymentPlan({
+ paymentPlan,
+ permissions,
+}: LockFspPaymentPlanProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { showMessage } = useSnackbar();
+ const { isActiveProgram } = useProgramContext();
+ const [lockDialogOpen, setLockDialogOpen] = useState(false);
+ const { mutatePaymentPlanAction: lock, loading: loadingLock } =
+ usePaymentPlanAction(
+ Action.LockFsp,
+ paymentPlan.id,
+ () => showMessage(t('Payment Plan FSPs are locked.')),
+ () => setLockDialogOpen(false),
+ );
+
+ const canLockFsp =
+ paymentPlan.deliveryMechanisms.length > 0 &&
+ hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK_FSP, permissions);
+
+ return (
+ <>
+
+ setLockDialogOpen(true)}
+ data-cy="button-lock-plan"
+ disabled={!canLockFsp || !isActiveProgram}
+ >
+ {t('Lock FSP')}
+
+
+ setLockDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Lock FSP')}
+
+
+
+
+ {t(
+ 'After you lock the FSP in this Payment Plan, you will be able to send the Payment Plan for approval.',
+ )}
+
+
+
+
+
+ setLockDialogOpen(false)}>CANCEL
+ lock()}
+ data-cy="button-submit"
+ >
+ {t('Lock FSP')}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan.test.tsx
new file mode 100644
index 0000000000..f2a3718c76
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { LockPaymentPlan } from './LockPaymentPlan';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan.tsx
new file mode 100644
index 0000000000..9aaff57a92
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan.tsx
@@ -0,0 +1,103 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+} from '@mui/material';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { Action, PaymentPlanQuery } from '@generated/graphql';
+import { GreyText } from '@core/GreyText';
+import { LoadingButton } from '@core/LoadingButton';
+
+export interface LockPaymentPlanProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function LockPaymentPlan({
+ paymentPlan,
+}: LockPaymentPlanProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { showMessage } = useSnackbar();
+ const [lockDialogOpen, setLockDialogOpen] = useState(false);
+ const { mutatePaymentPlanAction: lock, loading: loadingLock } =
+ usePaymentPlanAction(
+ Action.Lock,
+ paymentPlan.id,
+ () => showMessage(t('Payment Plan has been locked.')),
+ () => setLockDialogOpen(false),
+ );
+
+ return (
+ <>
+
+ setLockDialogOpen(true)}
+ data-cy="button-lock-plan"
+ >
+ {t('Lock')}
+
+
+ setLockDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Lock Payment Plan')}
+
+
+
+
+ {t(
+ 'After you lock this Payment Plan, you will be able to run entitlement formula for selected target population.',
+ )}
+
+ {paymentPlan.paymentsConflictsCount > 0 && (
+
+
+ {t('Note:')}{' '}
+ {paymentPlan.paymentsConflictsCount === 1
+ ? t('There is')
+ : t('There are')}{' '}
+ {paymentPlan.paymentsConflictsCount}{' '}
+ {paymentPlan.paymentsConflictsCount === 1
+ ? t('household')
+ : t('households')}{' '}
+ {t('that will be ignored in this Payment Plan.')}
+
+
+ )}
+
+
+
+
+ setLockDialogOpen(false)}>CANCEL
+ lock()}
+ data-cy="button-submit"
+ >
+ {t('Lock')}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan.test.tsx
new file mode 100644
index 0000000000..51b4c41e26
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { MarkAsReleasedPaymentPlan } from './MarkAsReleasedPaymentPlan';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan.tsx
new file mode 100644
index 0000000000..f283692c21
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan.tsx
@@ -0,0 +1,146 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+} from '@mui/material';
+import { Field, Form, Formik } from 'formik';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import * as Yup from 'yup';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { FormikTextField } from '@shared/Formik/FormikTextField/FormikTextField';
+import { Action, PaymentPlanQuery } from '@generated/graphql';
+import { AutoSubmitFormOnEnter } from '@core/AutoSubmitFormOnEnter';
+import { GreyText } from '@core/GreyText';
+import { LoadingButton } from '@core/LoadingButton';
+import { useProgramContext } from '../../../../programContext';
+
+export interface MarkAsReleasedPaymentPlanProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function MarkAsReleasedPaymentPlan({
+ paymentPlan,
+}: MarkAsReleasedPaymentPlanProps): React.ReactElement {
+ const { t } = useTranslation();
+ const { isActiveProgram } = useProgramContext();
+ const [markAsReleasedDialogOpen, setMarkAsReleasedDialogOpen] =
+ useState(false);
+ const { showMessage } = useSnackbar();
+ const { mutatePaymentPlanAction: review, loading: loadingReview } =
+ usePaymentPlanAction(
+ Action.Review,
+ paymentPlan.id,
+ () => showMessage(t('Payment Plan has been marked as reviewed.')),
+ () => setMarkAsReleasedDialogOpen(false),
+ );
+
+ const shouldShowLastReviewerMessage = (): boolean => {
+ const financeReleaseNumberRequired =
+ paymentPlan.approvalProcess?.edges[0]?.node.financeReleaseNumberRequired;
+ const financeReleasesCount =
+ paymentPlan.approvalProcess?.edges[0]?.node.actions.financeRelease.length;
+
+ return financeReleaseNumberRequired - 1 === financeReleasesCount;
+ };
+
+ const initialValues = {
+ comment: '',
+ };
+
+ const validationSchema = Yup.object().shape({
+ comment: Yup.string().min(4, 'Too short').max(255, 'Too long'),
+ });
+
+ return (
+ {
+ review(values.comment);
+ resetForm({});
+ }}
+ validationSchema={validationSchema}
+ >
+ {({ submitForm }) => (
+ <>
+ {markAsReleasedDialogOpen && }
+
+ setMarkAsReleasedDialogOpen(true)}
+ data-cy="button-mark-as-released"
+ disabled={!isActiveProgram}
+ >
+ {t('Mark as released')}
+
+
+ setMarkAsReleasedDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Mark as Released')}
+
+
+
+
+ {t(
+ 'Are you sure you want to mark this Payment Plan as released?',
+ )}
+
+ {shouldShowLastReviewerMessage() && (
+
+
+ {t(
+ 'Note: You are the last reviewer. Upon proceeding, this Payment Plan will be automatically moved to accepted status',
+ )}
+
+
+ )}
+
+
+
+
+
+ setMarkAsReleasedDialogOpen(false)}>
+ CANCEL
+
+
+ {t('Mark as released')}
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/PaymentPlanDetailsHeader.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/PaymentPlanDetailsHeader.test.tsx
new file mode 100644
index 0000000000..51b4c41e26
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/PaymentPlanDetailsHeader.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { MarkAsReleasedPaymentPlan } from './MarkAsReleasedPaymentPlan';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/PaymentPlanDetailsHeader.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/PaymentPlanDetailsHeader.tsx
new file mode 100644
index 0000000000..6778ffd540
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/PaymentPlanDetailsHeader.tsx
@@ -0,0 +1,203 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { hasPermissions, PERMISSIONS } from '../../../../config/permissions';
+import {
+ paymentPlanBackgroundActionStatusToColor,
+ paymentPlanStatusToColor,
+} from '@utils/utils';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { BreadCrumbsItem } from '@core/BreadCrumbs';
+import { PageHeader } from '@core/PageHeader';
+import { StatusBox } from '@core/StatusBox';
+import { AcceptedPaymentPlanHeaderButtons } from './HeaderButtons/AcceptedPaymentPlanHeaderButtons';
+import { InApprovalPaymentPlanHeaderButtons } from './HeaderButtons/InApprovalPaymentPlanHeaderButtons';
+import { InAuthorizationPaymentPlanHeaderButtons } from './HeaderButtons/InAuthorizationPaymentPlanHeaderButtons';
+import { InReviewPaymentPlanHeaderButtons } from './HeaderButtons/InReviewPaymentPlanHeaderButtons';
+import { LockedFspPaymentPlanHeaderButtons } from './HeaderButtons/LockedFspPaymentPlanHeaderButtons';
+import { LockedPaymentPlanHeaderButtons } from './HeaderButtons/LockedPaymentPlanHeaderButtons';
+import { OpenPaymentPlanHeaderButtons } from './HeaderButtons/OpenPaymentPlanHeaderButtons';
+import { AdminButton } from '@core/AdminButton';
+
+interface PaymentPlanDetailsHeaderProps {
+ baseUrl: string;
+ permissions: string[];
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function PaymentPlanDetailsHeader({
+ baseUrl,
+ permissions,
+ paymentPlan,
+}: PaymentPlanDetailsHeaderProps): React.ReactElement {
+ const { t } = useTranslation();
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/`,
+ },
+ ];
+
+ const canRemove = hasPermissions(PERMISSIONS.PM_CREATE, permissions);
+ const canEdit = hasPermissions(PERMISSIONS.PM_CREATE, permissions);
+ const canLock = hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK, permissions);
+ const canUnlock = hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK, permissions);
+ const canSendForApproval = hasPermissions(
+ PERMISSIONS.PM_SEND_FOR_APPROVAL,
+ permissions,
+ );
+ const canApprove = hasPermissions(
+ PERMISSIONS.PM_ACCEPTANCE_PROCESS_APPROVE,
+ permissions,
+ );
+ const canAuthorize = hasPermissions(
+ PERMISSIONS.PM_ACCEPTANCE_PROCESS_AUTHORIZE,
+ permissions,
+ );
+ const canMarkAsReleased = hasPermissions(
+ PERMISSIONS.PM_ACCEPTANCE_PROCESS_FINANCIAL_REVIEW,
+ permissions,
+ );
+ const canDownloadXlsx = hasPermissions(
+ PERMISSIONS.PM_DOWNLOAD_XLSX_FOR_FSP,
+ permissions,
+ );
+ const canExportXlsx = hasPermissions(
+ PERMISSIONS.PM_EXPORT_XLSX_FOR_FSP,
+ permissions,
+ );
+ const canSendToPaymentGateway =
+ hasPermissions(PERMISSIONS.PM_SEND_TO_PAYMENT_GATEWAY, permissions) &&
+ paymentPlan.canSendToPaymentGateway;
+ const canSplit =
+ hasPermissions(PERMISSIONS.PM_SPLIT, permissions) && paymentPlan.canSplit;
+
+ let buttons: React.ReactElement | null = null;
+ switch (paymentPlan.status) {
+ case 'OPEN':
+ buttons = (
+
+ );
+ break;
+ case 'LOCKED':
+ buttons = (
+
+ );
+ break;
+ case 'LOCKED_FSP':
+ buttons = (
+
+ );
+ break;
+ case 'IN_APPROVAL':
+ buttons = (
+
+ );
+ break;
+ case 'IN_AUTHORIZATION':
+ buttons = (
+
+ );
+ break;
+ case 'IN_REVIEW':
+ buttons = (
+
+ );
+ break;
+ case 'ACCEPTED':
+ buttons = (
+
+ );
+ break;
+ case 'FINISHED': // TODO: may create another one for that explicitly but good for now
+ buttons = (
+
+ );
+ break;
+ default:
+ break;
+ }
+
+ return (
+
+
+ {t('Payment Plan')} ID:
+
+ {paymentPlan.unicefId}
+
+
+
+
+
+ {paymentPlan.backgroundActionStatus && (
+
+
+
+ )}
+
+ }
+ breadCrumbs={
+ hasPermissions(PERMISSIONS.PM_VIEW_DETAILS, permissions)
+ ? breadCrumbsItems
+ : null
+ }
+ flags={ }
+ >
+ {buttons}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan.test.tsx
new file mode 100644
index 0000000000..5f3f121dcb
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan.test.tsx
@@ -0,0 +1,22 @@
+import { MockedProvider } from '@apollo/react-testing';
+import * as React from 'react';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { RejectPaymentPlan } from './RejectPaymentPlan';
+
+describe('components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan.tsx
new file mode 100644
index 0000000000..8d164aeb44
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan.tsx
@@ -0,0 +1,129 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+} from '@mui/material';
+import { Field, Form, Formik } from 'formik';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import * as Yup from 'yup';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { FormikTextField } from '@shared/Formik/FormikTextField/FormikTextField';
+import { Action } from '@generated/graphql';
+import { AutoSubmitFormOnEnter } from '@core/AutoSubmitFormOnEnter';
+import { ErrorButton } from '@core/ErrorButton';
+import { GreyText } from '@core/GreyText';
+import { LoadingButton } from '@core/LoadingButton';
+import { useProgramContext } from '../../../../programContext';
+
+export interface RejectPaymentPlanProps {
+ paymentPlanId: string;
+}
+
+export function RejectPaymentPlan({
+ paymentPlanId,
+}: RejectPaymentPlanProps): React.ReactElement {
+ const { t } = useTranslation();
+ const [rejectDialogOpen, setRejectDialogOpen] = useState(false);
+ const { showMessage } = useSnackbar();
+ const { isActiveProgram } = useProgramContext();
+ const { mutatePaymentPlanAction: reject, loading: loadingReject } =
+ usePaymentPlanAction(
+ Action.Reject,
+ paymentPlanId,
+ () => showMessage(t('Payment Plan has been rejected.')),
+ () => setRejectDialogOpen(false),
+ );
+
+ const initialValues = {
+ comment: '',
+ };
+
+ const validationSchema = Yup.object().shape({
+ comment: Yup.string().min(4, 'Too short').max(255, 'Too long'),
+ });
+
+ return (
+ {
+ reject(values.comment);
+ setRejectDialogOpen(false);
+ resetForm({});
+ }}
+ validationSchema={validationSchema}
+ >
+ {({ submitForm }) => (
+ <>
+ {rejectDialogOpen && }
+
+ setRejectDialogOpen(true)}>
+ {t('Reject')}
+
+
+ setRejectDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Reject Payment Plan')}
+
+
+
+
+ {t('Are you sure you want to reject this payment plan?')}
+
+
+
+ {t(
+ 'Note: Upon proceeding this payment plan will be automatically moved to locked status.',
+ )}
+
+
+
+
+
+
+
+ setRejectDialogOpen(false)}>
+ CANCEL
+
+
+ {t('Reject')}
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/SplitIntoPaymentLists.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/SplitIntoPaymentLists.tsx
new file mode 100644
index 0000000000..338c2b6e34
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/SplitIntoPaymentLists.tsx
@@ -0,0 +1,164 @@
+import { Field, Form, Formik } from 'formik';
+import React, { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import * as Yup from 'yup';
+import { FormikSelectField } from '@shared/Formik/FormikSelectField';
+import { DialogContainer } from '@containers/dialogs/DialogContainer';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { PaymentPlanQuery, useSplitPpMutation } from '@generated/graphql';
+import { LoadingButton } from '@core/LoadingButton';
+import { FormikTextField } from '@shared/Formik/FormikTextField';
+import {
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ Grid,
+} from '@mui/material';
+import ReorderIcon from '@mui/icons-material/Reorder';
+
+interface FormValues {
+ splitType: string;
+ paymentsNo: number;
+}
+
+const initialValues: FormValues = {
+ splitType: '',
+ paymentsNo: 0,
+};
+
+interface SplitIntoPaymentListsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ canSplit: boolean;
+}
+
+export const SplitIntoPaymentLists = ({
+ paymentPlan,
+ canSplit,
+}: SplitIntoPaymentListsProps): React.ReactElement => {
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const { t } = useTranslation();
+ const [mutate, { loading }] = useSplitPpMutation();
+ const { showMessage } = useSnackbar();
+
+ let minPaymentsNoMessage = 'Payments Number must be greater than 10';
+ let maxPaymentsNoMessage = `Payments Number must be less than ${paymentPlan.paymentItems.totalCount}`;
+
+ if (paymentPlan.paymentItems.totalCount <= 10) {
+ const msg = `There are too few payments (${paymentPlan.paymentItems.totalCount}) to split`;
+ minPaymentsNoMessage = msg;
+ maxPaymentsNoMessage = msg;
+ }
+
+ const validationSchema = Yup.object().shape({
+ splitType: Yup.string().required('Split Type is required'),
+ paymentsNo: Yup.number().when('splitType', {
+ is: 'BY_RECORDS',
+ then: (schema) =>
+ schema
+ .required('Payments Number is required')
+ .min(10, minPaymentsNoMessage)
+ .max(
+ paymentPlan.paymentItems.totalCount,
+ maxPaymentsNoMessage,
+ ),
+ }),
+ });
+
+ const handleSplit = async (values): Promise => {
+ try {
+ const { errors } = await mutate({
+ variables: {
+ paymentPlanId: paymentPlan.id,
+ splitType: values.splitType,
+ paymentsNo: values.paymentsNo,
+ },
+ });
+ if (!errors) {
+ setDialogOpen(false);
+ showMessage(t('Split was successful!'));
+ }
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ return (
+ {
+ await handleSplit(values);
+ }}
+ >
+ {({ values, submitForm }) => (
+
+ )}
+
+ );
+};
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/ApprovePaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/ApprovePaymentPlan.test.tsx.snap
new file mode 100644
index 0000000000..f6385c55fe
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/ApprovePaymentPlan.test.tsx.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/ApprovePaymentPlan should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/AuthorizePaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/AuthorizePaymentPlan.test.tsx.snap
new file mode 100644
index 0000000000..37fd359063
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/AuthorizePaymentPlan.test.tsx.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/AuthorizePaymentPlan should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/DeletePaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/DeletePaymentPlan.test.tsx.snap
new file mode 100644
index 0000000000..11626906a4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/DeletePaymentPlan.test.tsx.snap
@@ -0,0 +1,30 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/DeletePaymentPlan should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/LockPaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/LockPaymentPlan.test.tsx.snap
new file mode 100644
index 0000000000..ef53d3dbe4
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/LockPaymentPlan.test.tsx.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/LockPaymentPlan should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/MarkAsReleasedPaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/MarkAsReleasedPaymentPlan.test.tsx.snap
new file mode 100644
index 0000000000..1e7d743b4c
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/MarkAsReleasedPaymentPlan.test.tsx.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan should render 1`] = `
+
+
+
+ Mark as released
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/PaymentPlanDetailsHeader.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/PaymentPlanDetailsHeader.test.tsx.snap
new file mode 100644
index 0000000000..1e7d743b4c
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/PaymentPlanDetailsHeader.test.tsx.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/MarkAsReleasedPaymentPlan should render 1`] = `
+
+
+
+ Mark as released
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/RejectPaymentPlan.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/RejectPaymentPlan.test.tsx.snap
new file mode 100644
index 0000000000..6e10334a9d
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/__snapshots__/RejectPaymentPlan.test.tsx.snap
@@ -0,0 +1,20 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader/RejectPaymentPlan should render 1`] = `
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/index.tsx
new file mode 100644
index 0000000000..0e269627f2
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/index.tsx
@@ -0,0 +1 @@
+export { PaymentPlanDetailsHeader } from './PaymentPlanDetailsHeader';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/PeoplePaymentPlanDetailsResults.test.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/PeoplePaymentPlanDetailsResults.test.tsx
new file mode 100644
index 0000000000..dea943a00c
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/PeoplePaymentPlanDetailsResults.test.tsx
@@ -0,0 +1,21 @@
+import { MockedProvider } from '@apollo/react-testing';
+import { act } from 'react-dom/test-utils';
+import wait from 'waait';
+import { fakeApolloPaymentPlan } from '../../../../../fixtures/paymentmodule/fakeApolloPaymentPlan';
+import { fakeActionPpMutation } from '../../../../../fixtures/paymentmodule/fakeApolloActionPaymentPlanMutation';
+import { render } from '../../../../testUtils/testUtils';
+import { PeoplePaymentPlanDetailsResults } from './PeoplePaymentPlanDetailsResults';
+
+describe('components/paymentmodule/PaymentPlanDetails/PeoplePaymentPlanDetailsHeader/PaymentPlanDetailsResults', () => {
+ it('should render', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await act(() => wait(0)); // wait for the mutation to complete
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/PeoplePaymentPlanDetailsResults.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/PeoplePaymentPlanDetailsResults.tsx
new file mode 100644
index 0000000000..ac4e6a8e70
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/PeoplePaymentPlanDetailsResults.tsx
@@ -0,0 +1,173 @@
+import { Grid, Typography } from '@mui/material';
+import * as React from 'react';
+import { Pie } from 'react-chartjs-2';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { MiśTheme } from '../../../../theme';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { LabelizedField } from '@core/LabelizedField';
+import { PaperContainer } from '../../../targeting/PaperContainer';
+import { FieldBorder } from '@core/FieldBorder';
+
+const colors = {
+ femaleChildren: '#5F02CF',
+ maleChildren: '#1D6A64',
+ femaleAdult: '#DFCCF5',
+ maleAdult: '#B1E3E0',
+};
+
+const Title = styled.div`
+ padding-bottom: ${({ theme }) => theme.spacing(2)};
+`;
+
+const ContentWrapper = styled.div`
+ display: flex;
+`;
+
+const SummaryBorder = styled.div`
+ padding: ${({ theme }) => theme.spacing(4)};
+ border-color: #b1b1b5;
+ border-left-width: 1px;
+ border-left-style: solid;
+`;
+
+const SummaryValue = styled.div`
+ font-family: ${({ theme }: { theme: MiśTheme }) =>
+ theme.hctTypography.fontFamily};
+ color: #253b46;
+ font-size: 36px;
+ line-height: 32px;
+ margin-top: ${({ theme }) => theme.spacing(2)};
+`;
+
+const ChartContainer = styled.div`
+ width: 100px;
+ height: 100px;
+ margin: 0 auto;
+`;
+
+interface PeoplePaymentPlanDetailsResultsProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export const PeoplePaymentPlanDetailsResults = ({
+ paymentPlan,
+}: PeoplePaymentPlanDetailsResultsProps): React.ReactElement => {
+ const { t } = useTranslation();
+ const {
+ femaleChildrenCount,
+ maleChildrenCount,
+ femaleAdultsCount,
+ maleAdultsCount,
+ totalIndividualsCount,
+ } = paymentPlan;
+
+ return (
+
+
+ {t('Results')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {totalIndividualsCount || '0'}
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/__snapshots__/PeoplePaymentPlanDetailsResults.test.tsx.snap b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/__snapshots__/PeoplePaymentPlanDetailsResults.test.tsx.snap
new file mode 100644
index 0000000000..21b1e61c2a
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/__snapshots__/PeoplePaymentPlanDetailsResults.test.tsx.snap
@@ -0,0 +1,204 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/PaymentPlanDetails/PeoplePaymentPlanDetailsHeader/PaymentPlanDetailsResults should render 1`] = `
+
+
+
+
+ Results
+
+
+
+
+
+
+
+
+
+
+ Female Children
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ Female Adults
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ Male Children
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ Male Adults
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total Number of People
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/index.tsx
new file mode 100644
index 0000000000..cc6c0fdb81
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults/index.tsx
@@ -0,0 +1 @@
+export { PeoplePaymentPlanDetailsResults } from './PeoplePaymentPlanDetailsResults';
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ReconciliationSummary/ReconciliationSummary.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ReconciliationSummary/ReconciliationSummary.tsx
new file mode 100644
index 0000000000..fd5e28c081
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ReconciliationSummary/ReconciliationSummary.tsx
@@ -0,0 +1,153 @@
+import * as React from 'react';
+import { Grid, Typography } from '@mui/material';
+import { Pie } from 'react-chartjs-2';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { PaperContainer } from '../../../targeting/PaperContainer';
+import { LabelizedField } from '@core/LabelizedField';
+import { FieldBorder } from '@core/FieldBorder';
+
+const Title = styled.div`
+ padding-bottom: ${({ theme }) => theme.spacing(2)};
+`;
+
+const ContentWrapper = styled.div`
+ display: flex;
+`;
+
+const ChartContainer = styled.div`
+ width: 100px;
+ height: 100px;
+ margin: 0 auto;
+`;
+
+const ReconciliationWrapUp = styled.div`
+ padding-bottom: 8px;
+`;
+
+interface ReconciliationSummaryProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+}
+
+export function ReconciliationSummary({
+ paymentPlan,
+}: ReconciliationSummaryProps): React.ReactElement {
+ const { t } = useTranslation();
+
+ const {
+ reconciliationSummary: {
+ deliveredFully,
+ deliveredPartially,
+ unsuccessful,
+ notDelivered,
+ numberOfPayments,
+ pending,
+ reconciled,
+ },
+ } = paymentPlan;
+
+ const datasets = [
+ {
+ label: t('Delivered fully'),
+ value: deliveredFully,
+ color: '#10CB16',
+ },
+ {
+ label: t('Delivered partially'),
+ value: deliveredPartially,
+ color: '#FC942A',
+ },
+ {
+ label: t('Not delivered'),
+ value: notDelivered,
+ color: '#EF4343',
+ },
+ {
+ label: t('Unsuccessful'),
+ value: unsuccessful,
+ color: '#EF4343',
+ },
+ {
+ label: t('Pending'),
+ value: pending,
+ color: '#4E606A',
+ },
+ ];
+
+ const reconciledInPercent = ((reconciled / numberOfPayments) * 100).toFixed(
+ 0,
+ );
+ return (
+
+
+ {t('Reconciliation Summary')}
+
+
+
+
+
+
+ {datasets.map(({ color, label, value }) => (
+
+
+
+
+
+ ))}
+
+
+ label),
+ datasets: [
+ {
+ data: datasets.map(({ value }) => value),
+ backgroundColor: datasets.map(({ color }) => color),
+ },
+ ],
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ReconciliationSummary/index.tsx b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ReconciliationSummary/index.tsx
new file mode 100644
index 0000000000..a6fbc19b96
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/ReconciliationSummary/index.tsx
@@ -0,0 +1 @@
+export { ReconciliationSummary } from './ReconciliationSummary';
diff --git a/frontend/src/components/paymentmodulepeople/RevertForceFailedButton.tsx b/frontend/src/components/paymentmodulepeople/RevertForceFailedButton.tsx
new file mode 100644
index 0000000000..ed4def1b43
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/RevertForceFailedButton.tsx
@@ -0,0 +1,134 @@
+import { Box, Button, DialogContent, DialogTitle } from '@mui/material';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { Field, Form, Formik } from 'formik';
+import * as Yup from 'yup';
+import CalendarTodayRoundedIcon from '@mui/icons-material/CalendarTodayRounded';
+import { Dialog } from '@containers/dialogs/Dialog';
+import { DialogActions } from '@containers/dialogs/DialogActions';
+import { DialogFooter } from '@containers/dialogs/DialogFooter';
+import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { FormikTextField } from '@shared/Formik/FormikTextField';
+import { FormikDateField } from '@shared/Formik/FormikDateField';
+import { useRevertMarkPayAsFailedMutation } from '@generated/graphql';
+
+export interface RevertForceFailedButtonProps {
+ paymentId: string;
+ disabled?: boolean;
+}
+export function RevertForceFailedButton({
+ paymentId,
+ disabled = false,
+}: RevertForceFailedButtonProps): React.ReactElement {
+ const { t } = useTranslation();
+ const [isOpenModal, setOpenModal] = useState(false);
+ const { showMessage } = useSnackbar();
+ const [mutate, { loading }] = useRevertMarkPayAsFailedMutation();
+
+ const validationSchema = Yup.object().shape({
+ deliveredQuantity: Yup.number()
+ .min(0)
+ .max(99999999, t('Number is too big')),
+ deliveryDate: Yup.date().required(t('Delivery date is required')),
+ });
+
+ const submit = async (values, { resetForm }): Promise => {
+ try {
+ await mutate({
+ variables: {
+ paymentId,
+ deliveredQuantity: values.deliveredQuantity,
+ deliveryDate: values.deliveryDate,
+ },
+ });
+ setOpenModal(false);
+ showMessage(t('Force failed has been reverted.'));
+ resetForm();
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ return (
+
+
+ setOpenModal(true)}
+ data-cy="button-revert-mark-as-failed"
+ disabled={disabled}
+ >
+ {t('Revert mark as failed')}
+
+
+
+ {({ submitForm, resetForm }) => (
+ setOpenModal(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Revert mark as failed')}
+
+
+
+
+
+
+ {
+ setOpenModal(false);
+ resetForm();
+ }}
+ >
+ {t('CANCEL')}
+
+
+ {t('Revert mark as failed')}
+
+
+
+
+ )}
+
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/WarningMissingAmount.test.tsx b/frontend/src/components/paymentmodulepeople/WarningMissingAmount.test.tsx
new file mode 100644
index 0000000000..2f625ad645
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/WarningMissingAmount.test.tsx
@@ -0,0 +1,13 @@
+import * as React from 'react';
+import { render } from '../../testUtils/testUtils';
+import { WarningMissingAmount } from './WarningMissingAmount';
+
+describe('components/paymentmodule/WarningMissingAmount', () => {
+ it('should render', () => {
+ const { container } = render(
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/components/paymentmodulepeople/WarningMissingAmount.tsx b/frontend/src/components/paymentmodulepeople/WarningMissingAmount.tsx
new file mode 100644
index 0000000000..16dc9fa3f7
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/WarningMissingAmount.tsx
@@ -0,0 +1,28 @@
+import { Box } from '@mui/material';
+import WarningIcon from '@mui/icons-material/Warning';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+
+const WarnIcon = styled(WarningIcon)`
+ color: ${({ theme }) => theme.hctPalette.orange};
+`;
+
+interface WarningMissingAmountProps {
+ amount: number;
+ currency: string;
+}
+
+export function WarningMissingAmount({
+ amount,
+ currency,
+}: WarningMissingAmountProps): React.ReactElement {
+ const { t } = useTranslation();
+
+ return (
+
+
+ {t('Missing')} {amount} {currency}
+
+ );
+}
diff --git a/frontend/src/components/paymentmodulepeople/__snapshots__/WarningMissingAmount.test.tsx.snap b/frontend/src/components/paymentmodulepeople/__snapshots__/WarningMissingAmount.test.tsx.snap
new file mode 100644
index 0000000000..d5eea3e5db
--- /dev/null
+++ b/frontend/src/components/paymentmodulepeople/__snapshots__/WarningMissingAmount.test.tsx.snap
@@ -0,0 +1,26 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/paymentmodule/WarningMissingAmount should render 1`] = `
+
+
+
+
+
+ Missing
+
+ 100000
+
+ USD
+
+
+`;
diff --git a/frontend/src/components/payments/HouseholdDetails.tsx b/frontend/src/components/payments/HouseholdDetails.tsx
new file mode 100644
index 0000000000..445da74a01
--- /dev/null
+++ b/frontend/src/components/payments/HouseholdDetails.tsx
@@ -0,0 +1,56 @@
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { Overview } from '@components/payments/Overview';
+import { Title } from '@core/Title';
+import { Grid, Typography } from '@mui/material';
+import { LabelizedField } from '@core/LabelizedField';
+import { getPhoneNoLabel } from '@utils/utils';
+
+export const HouseholdDetails = ({ household }): React.ReactElement => {
+ const { t } = useTranslation();
+ return (
+
+
+ {t('Household')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/components/payments/IndividualDetails.tsx b/frontend/src/components/payments/IndividualDetails.tsx
new file mode 100644
index 0000000000..d4d250dced
--- /dev/null
+++ b/frontend/src/components/payments/IndividualDetails.tsx
@@ -0,0 +1,47 @@
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { Overview } from '@components/payments/Overview';
+import { Title } from '@core/Title';
+import { Grid, Typography } from '@mui/material';
+import { LabelizedField } from '@core/LabelizedField';
+import { getPhoneNoLabel } from '@utils/utils';
+
+export const IndividualDetails = ({ individual }): React.ReactElement => {
+ const { t } = useTranslation();
+ return (
+
+
+ {t('Individual')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/components/payments/Overview.tsx b/frontend/src/components/payments/Overview.tsx
new file mode 100644
index 0000000000..6275e48e31
--- /dev/null
+++ b/frontend/src/components/payments/Overview.tsx
@@ -0,0 +1,8 @@
+import styled from 'styled-components';
+import { Paper } from '@mui/material';
+
+export const Overview = styled(Paper)`
+ margin: 20px;
+ padding: ${({ theme }) => theme.spacing(8)}
+ ${({ theme }) => theme.spacing(11)};
+`;
diff --git a/frontend/src/components/payments/VerificationPaymentDetails.tsx b/frontend/src/components/payments/VerificationPaymentDetails.tsx
index 38618b3c67..cdcaf12807 100644
--- a/frontend/src/components/payments/VerificationPaymentDetails.tsx
+++ b/frontend/src/components/payments/VerificationPaymentDetails.tsx
@@ -1,12 +1,10 @@
-import { Grid, Paper, Typography } from '@mui/material';
+import { Grid, Typography } from '@mui/material';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
-import styled from 'styled-components';
import { UniversalActivityLogTable } from '@containers/tables/UniversalActivityLogTable';
import {
choicesToDict,
formatCurrencyWithSymbol,
- getPhoneNoLabel,
paymentStatusDisplayMap,
paymentStatusToColor,
verificationRecordsStatusToColor,
@@ -17,12 +15,10 @@ import { LabelizedField } from '@core/LabelizedField';
import { StatusBox } from '@core/StatusBox';
import { UniversalMoment } from '@core/UniversalMoment';
import { Title } from '@core/Title';
-
-const Overview = styled(Paper)`
- margin: 20px;
- padding: ${({ theme }) => theme.spacing(8)}
- ${({ theme }) => theme.spacing(11)};
-`;
+import { Overview } from '@components/payments/Overview';
+import { HouseholdDetails } from '@components/payments/HouseholdDetails';
+import { useProgramContext } from '../../programContext';
+import { IndividualDetails } from '@components/payments/IndividualDetails';
interface VerificationPaymentDetailsProps {
payment: PaymentQuery['payment'];
@@ -36,6 +32,7 @@ export function VerificationPaymentDetails({
choicesData,
}: VerificationPaymentDetailsProps): React.ReactElement {
const { t } = useTranslation();
+ const { isSocialDctType } = useProgramContext();
const deliveryTypeDict = choicesToDict(
choicesData.paymentRecordDeliveryTypeChoices,
);
@@ -94,49 +91,11 @@ export function VerificationPaymentDetails({
-
-
- {t('Household')}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ {isSocialDctType ? (
+
+ ) : (
+
+ )}
{t('Entitlement Details')}
diff --git a/frontend/src/components/payments/VerificationPaymentRecordDetails.tsx b/frontend/src/components/payments/VerificationPaymentRecordDetails.tsx
index 6963b740b7..284f59beef 100644
--- a/frontend/src/components/payments/VerificationPaymentRecordDetails.tsx
+++ b/frontend/src/components/payments/VerificationPaymentRecordDetails.tsx
@@ -1,12 +1,10 @@
-import { Grid, Paper, Typography } from '@mui/material';
+import { Grid, Typography } from '@mui/material';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
-import styled from 'styled-components';
import { UniversalActivityLogTable } from '@containers/tables/UniversalActivityLogTable';
import {
choicesToDict,
formatCurrencyWithSymbol,
- getPhoneNoLabel,
paymentRecordStatusToColor,
paymentStatusDisplayMap,
verificationRecordsStatusToColor,
@@ -19,12 +17,10 @@ import { UniversalMoment } from '@core/UniversalMoment';
import { BlackLink } from '@core/BlackLink';
import { Title } from '@core/Title';
import { useBaseUrl } from '@hooks/useBaseUrl';
-
-const Overview = styled(Paper)`
- margin: 20px;
- padding: ${({ theme }) => theme.spacing(8)}
- ${({ theme }) => theme.spacing(11)};
-`;
+import { Overview } from '@components/payments/Overview';
+import { HouseholdDetails } from '@components/payments/HouseholdDetails';
+import { useProgramContext } from '../../programContext';
+import { IndividualDetails } from '@components/payments/IndividualDetails';
interface VerificationPaymentRecordDetailsProps {
paymentRecord: PaymentRecordQuery['paymentRecord'];
@@ -39,6 +35,7 @@ export function VerificationPaymentRecordDetails({
}: VerificationPaymentRecordDetailsProps): React.ReactElement {
const { t } = useTranslation();
const { baseUrl } = useBaseUrl();
+ const { isSocialDctType } = useProgramContext();
const deliveryTypeDict = choicesToDict(
choicesData.paymentRecordDeliveryTypeChoices,
);
@@ -106,49 +103,13 @@ export function VerificationPaymentRecordDetails({
-
-
- {t('Household')}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ {isSocialDctType ? (
+
+ ) : (
+
+ )}
{t('Entitlement Details')}
diff --git a/frontend/src/components/people/PeopleBioData/PeopleBioData.tsx b/frontend/src/components/people/PeopleBioData/PeopleBioData.tsx
index 8a215dda8d..3ca73b34a7 100644
--- a/frontend/src/components/people/PeopleBioData/PeopleBioData.tsx
+++ b/frontend/src/components/people/PeopleBioData/PeopleBioData.tsx
@@ -20,6 +20,7 @@ import { Title } from '@core/Title';
import { UniversalMoment } from '@core/UniversalMoment';
import { DocumentPopulationPhotoModal } from '../../population/DocumentPopulationPhotoModal';
import { LinkedGrievancesModal } from '../../population/LinkedGrievancesModal/LinkedGrievancesModal';
+import { useProgramContext } from '../../../programContext';
const Overview = styled(Paper)`
padding: ${({ theme }) => theme.spacing(8)}
@@ -37,15 +38,15 @@ interface PeopleBioDataProps {
choicesData: HouseholdChoiceDataQuery;
grievancesChoices: GrievancesChoiceDataQuery;
}
-export function PeopleBioData({
+export const PeopleBioData = ({
individual,
baseUrl,
businessArea,
choicesData,
grievancesChoices,
-}: PeopleBioDataProps): React.ReactElement {
+}: PeopleBioDataProps): React.ReactElement => {
const { t } = useTranslation();
-
+ const { selectedProgram } = useProgramContext();
const maritalStatusChoicesDict = choicesToDict(
choicesData.maritalStatusChoices,
);
@@ -58,6 +59,10 @@ export function PeopleBioData({
choicesData.severityOfDisabilityChoices,
);
+ const residenceChoicesDict = choicesToDict(
+ choicesData.residenceStatusChoices,
+ );
+
const mappedIndividualDocuments = individual?.documents?.edges?.map(
(edge) => (
@@ -127,6 +132,77 @@ export function PeopleBioData({
);
};
+ let peopleFromHouseholdData = null;
+ if (individual?.household) {
+ const household = individual.household;
+ peopleFromHouseholdData = (
+ <>
+
+
+ {residenceChoicesDict[household?.residenceStatus]}
+
+
+
+
+ {household?.country}
+
+
+
+
+ {household.countryOrigin}
+
+
+
+
+ {household.address}
+
+
+
+
+ {household.village}
+
+
+
+
+ {household.zipCode}
+
+
+
+
+ {household?.admin1?.name}
+
+
+
+
+ {household?.admin2?.name}
+
+
+
+
+ {household?.admin3?.name}
+
+
+
+
+ {household?.admin4?.name}
+
+
+
+
+ {household?.geopoint
+ ? `${household?.geopoint?.coordinates[0]}, ${household?.geopoint?.coordinates[1]}`
+ : '-'}
+
+
+
+
+ {selectedProgram?.dataCollectingType?.label}
+
+
+ >
+ );
+ }
+
return (
@@ -198,6 +274,7 @@ export function PeopleBioData({
{individual?.preferredLanguage}
+ {peopleFromHouseholdData}
@@ -302,4 +379,4 @@ export function PeopleBioData({
);
-}
+};
diff --git a/frontend/src/components/people/PeopleBioData/__snapshots__/PeopleBioData.test.tsx.snap b/frontend/src/components/people/PeopleBioData/__snapshots__/PeopleBioData.test.tsx.snap
index 48379da029..c5fc519143 100644
--- a/frontend/src/components/people/PeopleBioData/__snapshots__/PeopleBioData.test.tsx.snap
+++ b/frontend/src/components/people/PeopleBioData/__snapshots__/PeopleBioData.test.tsx.snap
@@ -297,6 +297,241 @@ exports[`components/population/IndividualBioData should render 1`] = `
+
+
+
+ Residence Status
+
+
+ -
+
+
+
+
+
+
+
+ Country of Origin
+
+
+
+ San Marino
+
+
+
+
+
+
+
+ Address
+
+
+
+ 938 Luna Cliffs Apt. 551
+Jameschester, SC 24934
+
+
+
+
+
+
+
+
+
+ Administrative Level 1
+
+
+
+ Ghazni
+
+
+
+
+
+
+
+ Administrative Level 2
+
+
+
+ Abband
+
+
+
+
+
+
+
+ Administrative Level 3
+
+
+ -
+
+
+
+
+
+
+ Administrative Level 4
+
+
+ -
+
+
+
+
+
+
+ Geolocation
+
+
+
+ -
+
+
+
+
+
+
+
+ Data Collecting Type
+
+
+
+ data collecting type
+
+
+
+
diff --git a/frontend/src/components/people/PeopleFilter.tsx b/frontend/src/components/people/PeopleFilter.tsx
new file mode 100644
index 0000000000..8088a41099
--- /dev/null
+++ b/frontend/src/components/people/PeopleFilter.tsx
@@ -0,0 +1,285 @@
+import { Grid, MenuItem } from '@mui/material';
+import CakeIcon from '@mui/icons-material/Cake';
+import FlashOnIcon from '@mui/icons-material/FlashOn';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useLocation, useNavigate } from 'react-router-dom';
+import {
+ DataCollectingTypeType,
+ IndividualChoiceDataQuery,
+ ProgramNode,
+} from '@generated/graphql';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { AdminAreaAutocomplete } from '@shared/autocompletes/AdminAreaAutocomplete';
+import { individualTableOrderOptions } from '@utils/constants';
+import { createHandleApplyFilterChange } from '@utils/utils';
+import { DatePickerFilter } from '@core/DatePickerFilter';
+import { FiltersSection } from '@core/FiltersSection';
+import { NumberTextField } from '@core/NumberTextField';
+import { SearchTextField } from '@core/SearchTextField';
+import { SelectFilter } from '@core/SelectFilter';
+import { useProgramContext } from '../../programContext';
+
+interface PeopleFilterProps {
+ filter;
+ programs?: ProgramNode[];
+ choicesData: IndividualChoiceDataQuery;
+ setFilter: (filter) => void;
+ initialFilter;
+ appliedFilter;
+ setAppliedFilter: (filter) => void;
+ isOnPaper?: boolean;
+}
+
+export function PeopleFilter({
+ filter,
+ programs,
+ choicesData,
+ setFilter,
+ initialFilter,
+ appliedFilter,
+ setAppliedFilter,
+ isOnPaper = true,
+}: PeopleFilterProps): React.ReactElement {
+ const { t } = useTranslation();
+ const navigate = useNavigate();
+ const location = useLocation();
+ const { isAllPrograms } = useBaseUrl();
+ const { selectedProgram } = useProgramContext();
+
+ const { handleFilterChange, applyFilterChanges, clearFilter } =
+ createHandleApplyFilterChange(
+ initialFilter,
+ navigate,
+ location,
+ filter,
+ setFilter,
+ appliedFilter,
+ setAppliedFilter,
+ );
+ const handleApplyFilter = (): void => {
+ applyFilterChanges();
+ };
+
+ const handleClearFilter = (): void => {
+ clearFilter();
+ };
+
+ // Show admin area filter only for social programs
+ const showAdminAreaFilter =
+ selectedProgram?.dataCollectingType?.type?.toUpperCase() ===
+ DataCollectingTypeType.Social;
+
+ return (
+
+
+
+ handleFilterChange('search', e.target.value)}
+ data-cy="ind-filters-search"
+ />
+
+
+
+
+ handleFilterChange('documentType', e.target.value)
+ }
+ label={t('Document Type')}
+ value={filter.documentType}
+ borderRadius="0px 4px 4px 0px"
+ data-cy="filters-document-type"
+ fullWidth
+ disableClearable
+ >
+ {choicesData?.documentTypeChoices.map(({ name, value }) => (
+
+ {name}
+
+ ))}
+
+
+
+
+ handleFilterChange('documentNumber', e.target.value)
+ }
+ data-cy="filters-document-number"
+ />
+
+
+ {isAllPrograms && (
+
+ handleFilterChange('program', e.target.value)}
+ label={t('Programme')}
+ value={filter.program}
+ fullWidth
+ icon={ }
+ data-cy="filters-program"
+ >
+ {programs.map((program) => (
+
+ {program.name}
+
+ ))}
+
+
+ )}
+ {showAdminAreaFilter && (
+
+
+
+ )}
+
+ handleFilterChange('sex', e.target.value)}
+ value={filter.sex}
+ label={t('Gender')}
+ data-cy="ind-filters-gender"
+ fullWidth
+ >
+ {t('Female')}
+ {t('Male')}
+
+
+
+ {
+ if (e.target.value < 0 || e.target.value > 120) return;
+ handleFilterChange('ageMin', e.target.value);
+ }}
+ icon={ }
+ />
+
+
+ {
+ if (e.target.value < 0 || e.target.value > 120) return;
+ handleFilterChange('ageMax', e.target.value);
+ }}
+ icon={ }
+ />
+
+
+ handleFilterChange('flags', e.target.value)}
+ label={t('Flags')}
+ multiple
+ fullWidth
+ value={filter.flags}
+ data-cy="ind-filters-flags"
+ >
+ {choicesData?.flagChoices.map((each, index) => (
+
+ {each.name}
+
+ ))}
+
+
+
+ handleFilterChange('orderBy', e.target.value)}
+ label={t('Sort by')}
+ value={filter.orderBy}
+ fullWidth
+ data-cy="ind-filters-order-by"
+ disableClearable
+ >
+ {individualTableOrderOptions.map((order) => (
+
+ {order.name}
+
+ ))}
+
+
+
+ handleFilterChange('status', e.target.value)}
+ label={t('Status')}
+ value={filter.status}
+ data-cy="ind-filters-status"
+ >
+
+ Active
+
+
+ Duplicate
+
+
+ Withdrawn
+
+
+
+
+
+ handleFilterChange('lastRegistrationDateMin', date)
+ }
+ value={filter.lastRegistrationDateMin}
+ data-cy="ind-filters-reg-date-from"
+ />
+
+
+
+ handleFilterChange('lastRegistrationDateMax', date)
+ }
+ value={filter.lastRegistrationDateMax}
+ data-cy="ind-filters-reg-date-to"
+ />
+
+ {isAllPrograms && (
+
+
+ handleFilterChange('programState', e.target.value)
+ }
+ label={t('Programme State')}
+ value={filter.programState}
+ fullWidth
+ disableClearable
+ data-cy="filters-program-state"
+ >
+ {t('Active Programmes')}
+ {t('All Programmes')}
+
+
+ )}
+
+
+ );
+}
diff --git a/frontend/src/components/population/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap b/frontend/src/components/population/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap
index be06704955..aaeb48050b 100644
--- a/frontend/src/components/population/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap
+++ b/frontend/src/components/population/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap
@@ -425,7 +425,12 @@ exports[`components/population/HouseholdDetails should render 1`] = `
- -
+
+ data collecting type
+
diff --git a/frontend/src/components/population/IndividualVulnerabilities/IndividualVunerabilities.tsx b/frontend/src/components/population/IndividualVulnerabilities/IndividualVunerabilities.tsx
index d5923854bd..2ab4e02f7f 100644
--- a/frontend/src/components/population/IndividualVulnerabilities/IndividualVunerabilities.tsx
+++ b/frontend/src/components/population/IndividualVulnerabilities/IndividualVunerabilities.tsx
@@ -17,7 +17,7 @@ const Overview = styled(Paper)`
padding: ${({ theme }) => theme.spacing(8)}
${({ theme }) => theme.spacing(11)};
margin-top: ${({ theme }) => theme.spacing(6)};
- margin-bottom: ${({ theme }) => theme.spacing(6)};
+ margin-bottom: ${({ theme }) => theme.spacing(4)};
`;
interface IndividualVulnerabilitesProps {
individual: IndividualNode;
diff --git a/frontend/src/components/population/IndividualVulnerabilities/__snapshots__/IndividualVulnerabilities.test.tsx.snap b/frontend/src/components/population/IndividualVulnerabilities/__snapshots__/IndividualVulnerabilities.test.tsx.snap
index 4c371be04f..590139aec1 100644
--- a/frontend/src/components/population/IndividualVulnerabilities/__snapshots__/IndividualVulnerabilities.test.tsx.snap
+++ b/frontend/src/components/population/IndividualVulnerabilities/__snapshots__/IndividualVulnerabilities.test.tsx.snap
@@ -4,7 +4,7 @@ exports[`components/population/IndividualVulnerabilities should render 1`] = `
=> {
setSubmitDisabled(true);
@@ -65,15 +61,9 @@ export function CreateImportFromXlsxForm({
},
},
});
- if (programData.program.isSocialWorkerProgram) {
- navigate(
- `/${baseUrl}/registration-data-import-for-people/${data.data.registrationXlsxImport.registrationDataImport.id}`,
- );
- } else {
- navigate(
- `/${baseUrl}/registration-data-import/${data.data.registrationXlsxImport.registrationDataImport.id}`,
- );
- }
+ navigate(
+ `/${baseUrl}/registration-data-import/${data.data.registrationXlsxImport.registrationDataImport.id}`,
+ );
} catch (e) {
e.graphQLErrors.map((x) => showMessage(x.message));
setSubmitDisabled(false);
diff --git a/frontend/src/components/rdi/details/RegistrationDataImportDetailsPageHeader.tsx b/frontend/src/components/rdi/details/RegistrationDataImportDetailsPageHeader.tsx
index 1f05f7dfad..e5bcfaff6b 100644
--- a/frontend/src/components/rdi/details/RegistrationDataImportDetailsPageHeader.tsx
+++ b/frontend/src/components/rdi/details/RegistrationDataImportDetailsPageHeader.tsx
@@ -135,7 +135,7 @@ export const RegistrationDataImportDetailsPageHeader = ({
const breadCrumbsItems: BreadCrumbsItem[] = [
{
title: t('Registration Data import'),
- to: `/${baseUrl}/registration-data-import/`,
+ to: '..',
},
];
@@ -144,7 +144,7 @@ export const RegistrationDataImportDetailsPageHeader = ({
navigate(`/${baseUrl}/registration-data-import/`)}
+ handleBack={() => navigate('..')}
flags={ }
>
{registration.erased ? null : buttons}
diff --git a/frontend/src/components/rdi/details/households/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap b/frontend/src/components/rdi/details/households/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap
index 94617c6478..c155affb71 100644
--- a/frontend/src/components/rdi/details/households/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap
+++ b/frontend/src/components/rdi/details/households/HouseholdDetails/__snapshots__/HouseholdDetails.test.tsx.snap
@@ -236,7 +236,12 @@ exports[`components/rdi/details/households/HouseholdDetails should render 1`] =
- -
+
+ data collecting type
+
diff --git a/frontend/src/components/targeting/Results.tsx b/frontend/src/components/targeting/ResultsForHouseholds.tsx
similarity index 99%
rename from frontend/src/components/targeting/Results.tsx
rename to frontend/src/components/targeting/ResultsForHouseholds.tsx
index c8db483d5a..9183f8a1d5 100644
--- a/frontend/src/components/targeting/Results.tsx
+++ b/frontend/src/components/targeting/ResultsForHouseholds.tsx
@@ -53,7 +53,7 @@ interface ResultsProps {
targetPopulation: TargetPopulationQuery['targetPopulation'];
}
-export function Results({
+export function ResultsForHouseholds({
targetPopulation,
}: ResultsProps): React.ReactElement {
const { t } = useTranslation();
diff --git a/frontend/src/components/targeting/ResultsForPeople.tsx b/frontend/src/components/targeting/ResultsForPeople.tsx
new file mode 100644
index 0000000000..86bad362b8
--- /dev/null
+++ b/frontend/src/components/targeting/ResultsForPeople.tsx
@@ -0,0 +1,76 @@
+import { Grid, Typography } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import {
+ TargetPopulationBuildStatus,
+ TargetPopulationQuery,
+} from '@generated/graphql';
+import { MiśTheme } from '../../theme';
+import { LabelizedField } from '@core/LabelizedField';
+import { PaperContainer } from './PaperContainer';
+
+const Title = styled.div`
+ padding-bottom: ${({ theme }) => theme.spacing(2)};
+`;
+
+const ContentWrapper = styled.div`
+ display: flex;
+`;
+
+const SummaryBorder = styled.div`
+ padding: ${({ theme }) => theme.spacing(4)};
+ border-color: #b1b1b5;
+ border-left-width: 1px;
+ border-left-style: solid;
+`;
+
+const SummaryValue = styled.div`
+ font-family: ${({ theme }: { theme: MiśTheme }) =>
+ theme.hctTypography.fontFamily};
+ color: #253b46;
+ font-size: 36px;
+ line-height: 32px;
+ margin-top: ${({ theme }) => theme.spacing(2)};
+`;
+
+interface ResultsProps {
+ targetPopulation: TargetPopulationQuery['targetPopulation'];
+}
+
+export function ResultsForPeople({
+ targetPopulation,
+}: ResultsProps): React.ReactElement {
+ const { t } = useTranslation();
+ if (targetPopulation.buildStatus !== TargetPopulationBuildStatus.Ok) {
+ return null;
+ }
+ return (
+
+
+
+ {t('Results')}
+
+
+
+
+
+
+
+
+
+
+
+ {targetPopulation.totalHouseholdsCount || '0'}
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/targeting/SubField.tsx b/frontend/src/components/targeting/SubField.tsx
index d5ea2c0e33..eaca95ca9d 100644
--- a/frontend/src/components/targeting/SubField.tsx
+++ b/frontend/src/components/targeting/SubField.tsx
@@ -17,7 +17,12 @@ const InlineField = styled.div`
width: 48%;
`;
-export function SubField({ field, index, baseName }): React.ReactElement {
+export function SubField({
+ field,
+ index,
+ baseName,
+ choicesDict,
+}): React.ReactElement {
const { t } = useTranslation();
switch (field.fieldAttribute.type) {
case 'DECIMAL':
@@ -104,7 +109,7 @@ export function SubField({ field, index, baseName }): React.ReactElement {
) : null}
-
+
{recordInfo}
{hasPermissions(PERMISSIONS.ACTIVITY_LOG_VIEW, permissions) && (
diff --git a/frontend/src/components/targeting/TargetPopulationForPeopleFilters.tsx b/frontend/src/components/targeting/TargetPopulationForPeopleFilters.tsx
new file mode 100644
index 0000000000..7ba9a203dc
--- /dev/null
+++ b/frontend/src/components/targeting/TargetPopulationForPeopleFilters.tsx
@@ -0,0 +1,130 @@
+import { Grid, MenuItem } from '@mui/material';
+import { Group, Person } from '@mui/icons-material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useLocation, useNavigate } from 'react-router-dom';
+import { TargetPopulationStatus } from '@generated/graphql';
+import {
+ createHandleApplyFilterChange,
+ targetPopulationStatusMapping,
+} from '@utils/utils';
+import { DatePickerFilter } from '@core/DatePickerFilter';
+import { NumberTextField } from '@core/NumberTextField';
+import { SearchTextField } from '@core/SearchTextField';
+import { SelectFilter } from '@core/SelectFilter';
+import { FiltersSection } from '@core/FiltersSection';
+
+interface TargetPopulationFiltersProps {
+ filter;
+ setFilter: (filter) => void;
+ initialFilter;
+ appliedFilter;
+ setAppliedFilter: (filter) => void;
+}
+export const TargetPopulationForPeopleFilters = ({
+ filter,
+ setFilter,
+ initialFilter,
+ appliedFilter,
+ setAppliedFilter,
+}: TargetPopulationFiltersProps): React.ReactElement => {
+ const { t } = useTranslation();
+ const navigate = useNavigate();
+ const location = useLocation();
+ const isAccountability = location.pathname.includes('accountability');
+
+ const { handleFilterChange, applyFilterChanges, clearFilter } =
+ createHandleApplyFilterChange(
+ initialFilter,
+ navigate,
+ location,
+ filter,
+ setFilter,
+ appliedFilter,
+ setAppliedFilter,
+ );
+ const handleApplyFilter = (): void => {
+ applyFilterChanges();
+ };
+
+ const handleClearFilter = (): void => {
+ clearFilter();
+ };
+
+ const preparedStatusChoices = isAccountability
+ ? Object.values(TargetPopulationStatus).filter((key) => key !== 'OPEN')
+ : Object.values(TargetPopulationStatus);
+
+ return (
+
+
+
+ handleFilterChange('name', e.target.value)}
+ data-cy="filters-search"
+ fullWidth
+ />
+
+
+ handleFilterChange('status', e.target.value)}
+ value={filter.status}
+ label={t('Status')}
+ icon={ }
+ fullWidth
+ data-cy="filters-status"
+ >
+ {preparedStatusChoices.sort().map((key) => (
+
+ {targetPopulationStatusMapping(key)}
+
+ ))}
+
+
+
+
+ handleFilterChange('totalHouseholdsCountMin', e.target.value)
+ }
+ icon={ }
+ data-cy="filters-total-households-count-min"
+ />
+
+
+
+ handleFilterChange('totalHouseholdsCountMax', e.target.value)
+ }
+ icon={ }
+ data-cy="filters-total-households-count-max"
+ />
+
+
+ handleFilterChange('createdAtRangeMin', date)}
+ value={filter.createdAtRangeMin}
+ />
+
+
+ handleFilterChange('createdAtRangeMax', date)}
+ value={filter.createdAtRangeMax}
+ />
+
+
+
+ );
+};
diff --git a/frontend/src/components/targeting/TargetingCriteria/Criteria.tsx b/frontend/src/components/targeting/TargetingCriteria/Criteria.tsx
index 3e29df9c2c..dc775e9ac7 100644
--- a/frontend/src/components/targeting/TargetingCriteria/Criteria.tsx
+++ b/frontend/src/components/targeting/TargetingCriteria/Criteria.tsx
@@ -60,7 +60,16 @@ const CriteriaSetBox = styled.div`
margin: ${({ theme }) => theme.spacing(2)} 0;
`;
-const CriteriaField = ({ field }): React.ReactElement => {
+const CriteriaField = ({ field, choicesDict }): React.ReactElement => {
+ const extractChoiceLabel = (choiceField, argument) => {
+ let choices = choicesDict?.[choiceField.fieldName];
+ if (!choices) {
+ choices = choiceField.fieldAttribute.choices;
+ }
+ return choices?.length
+ ? choices.find((each) => each.value === argument)?.labelEn
+ : argument;
+ };
const { t } = useTranslation();
let fieldElement;
switch (field.comparisonMethod) {
@@ -89,13 +98,7 @@ const CriteriaField = ({ field }): React.ReactElement => {
{field.fieldAttribute.type === 'BOOL' ? (
{field.arguments[0] === 'True' ? t('Yes') : t('No')}
) : (
-
- {field.fieldAttribute.choices?.length
- ? field.fieldAttribute.choices.find(
- (each) => each.value === field.arguments[0],
- )?.labelEn
- : field.arguments[0]}
-
+ {extractChoiceLabel(field, field.arguments[0])}
)}
);
@@ -119,35 +122,17 @@ const CriteriaField = ({ field }): React.ReactElement => {
);
break;
case 'CONTAINS':
- fieldElement =
- field.arguments.length > 1 ? (
-
- {field.fieldAttribute.labelEn || field.fieldName}:{' '}
- {field.arguments.map((argument, index) => (
- <>
-
- {field.fieldAttribute.choices?.length
- ? field.fieldAttribute.choices.find(
- (each) => each.value === argument,
- )?.labelEn
- : field.arguments[0]}
-
- {index !== field.arguments.length - 1 && ', '}
- >
- ))}
-
- ) : (
-
- {field.fieldAttribute.labelEn || field.fieldName}:{' '}
-
- {field.fieldAttribute.choices?.length
- ? field.fieldAttribute.choices.find(
- (each) => each.value === field.arguments[0],
- )?.labelEn
- : field.arguments[0]}
-
-
- );
+ fieldElement = (
+
+ {field.fieldAttribute.labelEn || field.fieldName}:{' '}
+ {field.arguments.map((argument, index) => (
+ <>
+ {extractChoiceLabel(field, argument)}
+ {index !== field.arguments.length - 1 && ', '}
+ >
+ ))}
+
+ );
break;
default:
fieldElement = (
@@ -168,6 +153,7 @@ interface CriteriaProps {
isEdit: boolean;
canRemove: boolean;
alternative?: boolean;
+ choicesDict;
}
export function Criteria({
@@ -176,6 +162,7 @@ export function Criteria({
editFunction = () => null,
isEdit,
canRemove,
+ choicesDict,
alternative = null,
individualsFiltersBlocks,
}: CriteriaProps): React.ReactElement {
@@ -183,14 +170,14 @@ export function Criteria({
{rules.map((each, index) => (
// eslint-disable-next-line
-
+
))}
{individualsFiltersBlocks.map((item) => (
// eslint-disable-next-line
{item.individualBlockFilters.map((filter) => (
// eslint-disable-next-line
-
+
))}
))}
diff --git a/frontend/src/components/targeting/TargetingCriteria/CriteriaAutocomplete.tsx b/frontend/src/components/targeting/TargetingCriteria/CriteriaAutocomplete.tsx
index 3a366cfa27..dc8422ce6d 100644
--- a/frontend/src/components/targeting/TargetingCriteria/CriteriaAutocomplete.tsx
+++ b/frontend/src/components/targeting/TargetingCriteria/CriteriaAutocomplete.tsx
@@ -18,12 +18,20 @@ export function CriteriaAutocomplete({
}): React.ReactElement {
const [open, setOpen] = useState(false);
const [newValue, setNewValue] = useState(null);
+ const [choicesWithoutDuplicates, setChoicesWithoutDuplicates] = useState();
+
useEffect(() => {
const optionValue =
otherProps.choices.find((choice) => choice.name === field.value) || null;
setNewValue(optionValue);
}, [field.value, otherProps.choices]);
-
+ useEffect(() => {
+ const uniqueChoices = otherProps.choices.filter(
+ (choice, index, self) =>
+ index === self.findIndex((t) => t.name === choice.name),
+ );
+ setChoicesWithoutDuplicates(uniqueChoices);
+ }, [ otherProps.choices]);
const isInvalid =
get(otherProps.form.errors, field.name) &&
get(otherProps.form.touched, field.name);
@@ -39,7 +47,7 @@ export function CriteriaAutocomplete({
onClose={() => {
setOpen(false);
}}
- options={otherProps.choices}
+ options={choicesWithoutDuplicates || []}
value={newValue}
getOptionLabel={(option) => {
if (option) {
diff --git a/frontend/src/components/targeting/TargetingCriteria/TargetingCriteria.tsx b/frontend/src/components/targeting/TargetingCriteria/TargetingCriteria.tsx
index c4eea0a51d..3c38817b39 100644
--- a/frontend/src/components/targeting/TargetingCriteria/TargetingCriteria.tsx
+++ b/frontend/src/components/targeting/TargetingCriteria/TargetingCriteria.tsx
@@ -1,11 +1,14 @@
import { TargetCriteriaForm } from '@containers/forms/TargetCriteriaForm';
-import { TargetPopulationQuery } from '@generated/graphql';
+import {
+ DataCollectingTypeType,
+ TargetPopulationQuery,
+} from '@generated/graphql';
import { AddCircleOutline } from '@mui/icons-material';
import { Box, Button, Checkbox, FormControlLabel, Grid } from '@mui/material';
import { FormikCheckboxField } from '@shared/Formik/FormikCheckboxField';
import { Field } from 'formik';
import * as React from 'react';
-import { Fragment, useState } from 'react';
+import { Fragment, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom';
import styled from 'styled-components';
@@ -16,6 +19,8 @@ import {
} from './TargetingCriteriaDisabled';
import { VulnerabilityScoreComponent } from './VulnerabilityScoreComponent';
import { useProgramContext } from 'src/programContext';
+import { useCachedImportedIndividualFieldsQuery } from '@hooks/useCachedImportedIndividualFields';
+import { useBaseUrl } from '@hooks/useBaseUrl';
const Title = styled.div`
padding: ${({ theme }) => theme.spacing(3)} ${({ theme }) => theme.spacing(4)};
@@ -92,9 +97,22 @@ export const TargetingCriteria = ({
const { t } = useTranslation();
const location = useLocation();
const { selectedProgram } = useProgramContext();
+ const { businessArea, programId } = useBaseUrl();
+ const { data: allCoreFieldsAttributesData, loading } =
+ useCachedImportedIndividualFieldsQuery(businessArea, programId);
const [isOpen, setOpen] = useState(false);
const [criteriaIndex, setIndex] = useState(null);
const [criteriaObject, setCriteria] = useState({});
+ const [allDataChoicesDict, setAllDataChoicesDict] = useState(null);
+ useEffect(() => {
+ if (loading) return;
+ const allDataChoicesDictTmp =
+ allCoreFieldsAttributesData?.allFieldsAttributes?.reduce((acc, item) => {
+ acc[item.name] = item.choices;
+ return acc;
+ }, {});
+ setAllDataChoicesDict(allDataChoicesDictTmp);
+ }, [allCoreFieldsAttributesData, loading]);
const regex = /(create|edit-tp)/;
const isDetailsPage = !regex.test(location.pathname);
const openModal = (criteria): void => {
@@ -128,7 +146,8 @@ export const TargetingCriteria = ({
selectedProgram?.dataCollectingType?.individualFiltersAvailable;
let householdFiltersAvailable =
selectedProgram?.dataCollectingType?.householdFiltersAvailable;
-
+ const isSocialWorkingProgram =
+ selectedProgram?.dataCollectingType?.type === DataCollectingTypeType.Social;
// Allow use filters on non-migrated programs
if (individualFiltersAvailable === undefined) {
individualFiltersAvailable = true;
@@ -168,6 +187,7 @@ export const TargetingCriteria = ({
open={isOpen}
onClose={() => closeModal()}
addCriteria={addCriteria}
+ isSocialWorkingProgram={isSocialWorkingProgram}
individualFiltersAvailable={individualFiltersAvailable}
householdFiltersAvailable={householdFiltersAvailable}
/>
@@ -180,6 +200,7 @@ export const TargetingCriteria = ({
1}
rules={criteria.filters}
individualsFiltersBlocks={
diff --git a/frontend/src/containers/forms/TargetCriteriaBlockFilter.tsx b/frontend/src/containers/forms/TargetCriteriaBlockFilter.tsx
index a89c3f5430..0c9af6e230 100644
--- a/frontend/src/containers/forms/TargetCriteriaBlockFilter.tsx
+++ b/frontend/src/containers/forms/TargetCriteriaBlockFilter.tsx
@@ -10,11 +10,13 @@ export function TargetCriteriaBlockFilter({
each,
onChange,
onDelete,
+ choicesDict,
}: {
blockIndex: number;
index: number;
data: ImportedIndividualFieldsQuery;
each;
+ choicesDict;
onChange: (e, object) => void;
onDelete: () => void;
}): React.ReactElement {
@@ -34,6 +36,7 @@ export function TargetCriteriaBlockFilter({
diff --git a/frontend/src/containers/forms/TargetCriteriaFilter.tsx b/frontend/src/containers/forms/TargetCriteriaFilter.tsx
index 6b00cbe23d..c7da1004c9 100644
--- a/frontend/src/containers/forms/TargetCriteriaFilter.tsx
+++ b/frontend/src/containers/forms/TargetCriteriaFilter.tsx
@@ -37,6 +37,7 @@ export function TargetingCriteriaFilter({
onChange,
values,
onClick,
+ choicesDict,
}: {
index: number;
data: ImportedIndividualFieldsQuery;
@@ -44,6 +45,7 @@ export function TargetingCriteriaFilter({
onChange: (e, object) => void;
values;
onClick: () => void;
+ choicesDict;
}): React.ReactElement {
const { t } = useTranslation();
const shouldShowDivider = index + 1 < values.filters.length;
@@ -60,7 +62,12 @@ export function TargetingCriteriaFilter({
/>
{each.fieldName && (
-
+
)}
{shouldShowDivider && (
diff --git a/frontend/src/containers/forms/TargetCriteriaFilterBlocks.tsx b/frontend/src/containers/forms/TargetCriteriaFilterBlocks.tsx
index 63ce4e7a95..9b8cbeaa2f 100644
--- a/frontend/src/containers/forms/TargetCriteriaFilterBlocks.tsx
+++ b/frontend/src/containers/forms/TargetCriteriaFilterBlocks.tsx
@@ -71,11 +71,13 @@ export function TargetCriteriaFilterBlocks({
blockIndex,
data,
values,
+ choicesToDict,
onDelete,
}: {
blockIndex: number;
data: ImportedIndividualFieldsQuery;
values;
+ choicesToDict;
onDelete: () => void;
}): React.ReactElement {
const { t } = useTranslation();
@@ -104,6 +106,7 @@ export function TargetCriteriaFilterBlocks({
index={index}
data={data}
each={each}
+ choicesDict={choicesToDict}
onChange={(e, object) => {
if (object) {
return chooseFieldType(object, arrayHelpers, index);
diff --git a/frontend/src/containers/forms/TargetCriteriaForm.tsx b/frontend/src/containers/forms/TargetCriteriaForm.tsx
index f82486591e..5aac059286 100644
--- a/frontend/src/containers/forms/TargetCriteriaForm.tsx
+++ b/frontend/src/containers/forms/TargetCriteriaForm.tsx
@@ -84,6 +84,7 @@ interface TargetCriteriaFormPropTypes {
onClose: () => void;
individualFiltersAvailable: boolean;
householdFiltersAvailable: boolean;
+ isSocialWorkingProgram: boolean;
}
const associatedWith = (type) => (item) => item.associatedWith === type;
@@ -96,6 +97,7 @@ export const TargetCriteriaForm = ({
onClose,
individualFiltersAvailable,
householdFiltersAvailable,
+ isSocialWorkingProgram,
}: TargetCriteriaFormPropTypes): React.ReactElement => {
const { t } = useTranslation();
const { businessArea, programId } = useBaseUrl();
@@ -110,6 +112,7 @@ export const TargetCriteriaForm = ({
const initialValue = mapCriteriaToInitialValues(criteria);
const [individualData, setIndividualData] = useState(null);
const [householdData, setHouseholdData] = useState(null);
+ const [allDataChoicesDict, setAllDataChoicesDict] = useState(null);
useEffect(() => {
if (loading) return;
const filteredIndividualData = {
@@ -125,10 +128,17 @@ export const TargetCriteriaForm = ({
),
};
setHouseholdData(filteredHouseholdData);
+ const allDataChoicesDictTmp = data?.allFieldsAttributes?.reduce(
+ (acc, item) => {
+ acc[item.name] = item.choices;
+ return acc;
+ },
+ {},
+ );
+ setAllDataChoicesDict(allDataChoicesDictTmp);
}, [data, loading]);
if (!data) return null;
-
const validate = ({
filters,
individualsFiltersBlocks,
@@ -256,7 +266,8 @@ export const TargetCriteriaForm = ({
// eslint-disable-next-line
key={index}
index={index}
- data={householdData}
+ data={isSocialWorkingProgram ? data : householdData}
+ choicesDict={allDataChoicesDict}
each={each}
onChange={(e, object) => {
if (object) {
@@ -271,7 +282,7 @@ export const TargetCriteriaForm = ({
)}
/>
- {householdFiltersAvailable ? (
+ {householdFiltersAvailable || isSocialWorkingProgram ? (
}
data-cy="button-household-rule"
>
- ADD HOUSEHOLD RULE
+ ADD {isSocialWorkingProgram ? 'PEOPLE' : 'HOUSEHOLD'} RULE
) : null}
- {individualFiltersAvailable ? (
+ {individualFiltersAvailable && !isSocialWorkingProgram ? (
<>
{householdFiltersAvailable ? (
@@ -310,6 +321,7 @@ export const TargetCriteriaForm = ({
blockIndex={index}
data={individualData}
values={values}
+ choicesToDict={allDataChoicesDict}
onDelete={() => arrayHelpers.remove(index)}
/>
))}
diff --git a/frontend/src/containers/pages/accountability/feedback/FeedbackPage.tsx b/frontend/src/containers/pages/accountability/feedback/FeedbackPage.tsx
index 9a6855437e..3ba476b7fc 100644
--- a/frontend/src/containers/pages/accountability/feedback/FeedbackPage.tsx
+++ b/frontend/src/containers/pages/accountability/feedback/FeedbackPage.tsx
@@ -9,7 +9,7 @@ import {
import { usePermissions } from '@hooks/usePermissions';
import { PageHeader } from '@components/core/PageHeader';
import { PermissionDenied } from '@components/core/PermissionDenied';
-import { FeedbackTable } from '../../../tables/Feedback/FeedbackTable';
+import { FeedbackTable } from '@containers/tables/Feedback';
import { FeedbackFilters } from '@components/accountability/Feedback/FeedbackTable/FeedbackFilters';
import { getFilterFromQueryParams } from '@utils/utils';
import { useBaseUrl } from '@hooks/useBaseUrl';
@@ -17,11 +17,11 @@ import { ButtonTooltip } from '@components/core/ButtonTooltip';
import { useProgramContext } from '../../../../programContext';
export function FeedbackPage(): React.ReactElement {
- const { baseUrl } = useBaseUrl();
+ const { baseUrl, isAllPrograms } = useBaseUrl();
const permissions = usePermissions();
const { t } = useTranslation();
const location = useLocation();
- const { isActiveProgram, isAllPrograms } = useProgramContext();
+ const { isActiveProgram } = useProgramContext();
const initialFilter = {
feedbackId: '',
diff --git a/frontend/src/containers/pages/paymentmodulepeople/CreatePeoplePaymentPlanPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/CreatePeoplePaymentPlanPage.tsx
new file mode 100644
index 0000000000..10b95d608d
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/CreatePeoplePaymentPlanPage.tsx
@@ -0,0 +1,151 @@
+import { Form, Formik } from 'formik';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { format, parseISO } from 'date-fns';
+import * as Yup from 'yup';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { CreatePaymentPlanHeader } from '@components/paymentmodule/CreatePaymentPlan/CreatePaymentPlanHeader/CreatePaymentPlanHeader';
+import { PaymentPlanParameters } from '@components/paymentmodule/CreatePaymentPlan/PaymentPlanParameters';
+import { PaymentPlanTargeting } from '@components/paymentmodule/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { useSnackbar } from '@hooks/useSnackBar';
+import {
+ useAllTargetPopulationsQuery,
+ useCreatePpMutation,
+} from '@generated/graphql';
+import { AutoSubmitFormOnEnter } from '@components/core/AutoSubmitFormOnEnter';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { useNavigate } from 'react-router-dom';
+
+export const CreatePeoplePaymentPlanPage = (): React.ReactElement => {
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const [mutate, { loading: loadingCreate }] = useCreatePpMutation();
+ const { showMessage } = useSnackbar();
+ const { baseUrl, businessArea, programId } = useBaseUrl();
+ const permissions = usePermissions();
+
+ const { data: allTargetPopulationsData, loading: loadingTargetPopulations } =
+ useAllTargetPopulationsQuery({
+ variables: {
+ businessArea,
+ paymentPlanApplicable: true,
+ program: [programId],
+ },
+ fetchPolicy: 'network-only',
+ });
+
+ if (loadingTargetPopulations) return ;
+ if (!allTargetPopulationsData) return null;
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_CREATE, permissions))
+ return ;
+
+ const validationSchema = Yup.object().shape({
+ targetingId: Yup.string().required(t('Target Population is required')),
+ startDate: Yup.date().required(t('Start Date is required')),
+ endDate: Yup.date()
+ .required(t('End Date is required'))
+ .when('startDate', (startDate: any, schema: Yup.DateSchema) =>
+ startDate && typeof startDate === 'string'
+ ? schema.min(
+ parseISO(startDate),
+ `${t('End date has to be greater than')} ${format(parseISO(startDate), 'yyyy-MM-dd')}`,
+ )
+ : schema,
+ ),
+ currency: Yup.string().nullable().required(t('Currency is required')),
+ dispersionStartDate: Yup.date().required(
+ t('Dispersion Start Date is required'),
+ ),
+ dispersionEndDate: Yup.date()
+ .required(t('Dispersion End Date is required'))
+ .min(new Date(), t('Dispersion End Date cannot be in the past'))
+ .when(
+ 'dispersionStartDate',
+ (dispersionStartDate: any, schema: Yup.DateSchema) =>
+ dispersionStartDate && typeof dispersionStartDate === 'string'
+ ? schema.min(
+ parseISO(dispersionStartDate),
+ `${t('Dispersion End Date has to be greater than')} ${format(parseISO(dispersionStartDate), 'yyyy-MM-dd')}`,
+ )
+ : schema,
+ ),
+ });
+
+ type FormValues = Yup.InferType;
+ const initialValues: FormValues = {
+ targetingId: '',
+ startDate: null,
+ endDate: null,
+ currency: null,
+ dispersionStartDate: null,
+ dispersionEndDate: null,
+ };
+
+ const handleSubmit = async (values: FormValues): Promise => {
+ try {
+ const startDate = values.startDate
+ ? format(new Date(values.startDate), 'yyyy-MM-dd')
+ : null;
+ const endDate = values.endDate
+ ? format(new Date(values.endDate), 'yyyy-MM-dd')
+ : null;
+ const dispersionStartDate = values.dispersionStartDate
+ ? format(new Date(values.dispersionStartDate), 'yyyy-MM-dd')
+ : null;
+ const dispersionEndDate = values.dispersionEndDate
+ ? format(new Date(values.dispersionEndDate), 'yyyy-MM-dd')
+ : null;
+
+ const res = await mutate({
+ variables: {
+ //@ts-ignore
+ input: {
+ businessAreaSlug: businessArea,
+ ...values,
+ startDate,
+ endDate,
+ dispersionStartDate,
+ dispersionEndDate,
+ },
+ },
+ });
+ showMessage(t('Payment Plan Created'));
+ navigate(
+ `/${baseUrl}/payment-module/payment-plans/${res.data.createPaymentPlan.paymentPlan.id}`,
+ );
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ return (
+
+ {({ submitForm, values }) => (
+
+ )}
+
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/EditPeopleFollowUpPaymentPlanPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/EditPeopleFollowUpPaymentPlanPage.tsx
new file mode 100644
index 0000000000..4fa43891d3
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/EditPeopleFollowUpPaymentPlanPage.tsx
@@ -0,0 +1,157 @@
+import { Form, Formik } from 'formik';
+import moment from 'moment';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useNavigate, useParams } from 'react-router-dom';
+import * as Yup from 'yup';
+import {
+ useAllTargetPopulationsQuery,
+ usePaymentPlanQuery,
+ useUpdatePpMutation,
+} from '@generated/graphql';
+import { AutoSubmitFormOnEnter } from '@components/core/AutoSubmitFormOnEnter';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { PaymentPlanParameters } from '@components/paymentmodule/CreatePaymentPlan/PaymentPlanParameters';
+import { PaymentPlanTargeting } from '@components/paymentmodule/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting';
+import { EditPaymentPlanHeader } from '@components/paymentmodule/EditPaymentPlan/EditPaymentPlanHeader';
+import { PERMISSIONS, hasPermissions } from '../../../config/permissions';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { usePermissions } from '@hooks/usePermissions';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { today } from '@utils/utils';
+
+export const EditPeopleFollowUpPaymentPlanPage = (): React.ReactElement => {
+ const navigate = useNavigate();
+ const { id } = useParams();
+ const { t } = useTranslation();
+ const { data: paymentPlanData, loading: loadingPaymentPlan } =
+ usePaymentPlanQuery({
+ variables: {
+ id,
+ },
+ fetchPolicy: 'cache-and-network',
+ });
+
+ const [mutate] = useUpdatePpMutation();
+ const { showMessage } = useSnackbar();
+ const { baseUrl, businessArea, programId } = useBaseUrl();
+ const permissions = usePermissions();
+
+ const { data: allTargetPopulationsData, loading: loadingTargetPopulations } =
+ useAllTargetPopulationsQuery({
+ variables: {
+ businessArea,
+ paymentPlanApplicable: false,
+ program: [programId],
+ },
+ });
+ if (loadingTargetPopulations || loadingPaymentPlan)
+ return ;
+ if (!allTargetPopulationsData || !paymentPlanData) return null;
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_CREATE, permissions))
+ return ;
+
+ const { paymentPlan } = paymentPlanData;
+
+ const initialValues = {
+ targetingId: paymentPlan.targetPopulation.id,
+ startDate: paymentPlan.startDate,
+ endDate: paymentPlan.endDate,
+ currency: {
+ name: paymentPlan.currencyName,
+ value: paymentPlan.currency,
+ },
+ dispersionStartDate: paymentPlan.dispersionStartDate,
+ dispersionEndDate: paymentPlan.dispersionEndDate,
+ };
+
+ const validationSchema = Yup.object().shape({
+ targetingId: Yup.string().required(t('Target Population is required')),
+ currency: Yup.string().nullable().required(t('Currency is required')),
+ startDate: Yup.date().required(t('Start Date is required')),
+ endDate: Yup.date()
+ .required(t('End Date is required'))
+ .when('startDate', (startDate: any, schema: Yup.DateSchema) =>
+ startDate
+ ? schema.min(
+ startDate,
+ `${t('End date has to be greater than')} ${moment(
+ startDate,
+ ).format('YYYY-MM-DD')}`,
+ )
+ : schema,
+ ),
+ dispersionStartDate: Yup.date().required(
+ t('Dispersion Start Date is required'),
+ ),
+ dispersionEndDate: Yup.date()
+ .required(t('Dispersion End Date is required'))
+ .min(today, t('Dispersion End Date cannot be in the past'))
+ .when(
+ 'dispersionStartDate',
+ (dispersionStartDate: any, schema: Yup.DateSchema) =>
+ dispersionStartDate
+ ? schema.min(
+ dispersionStartDate,
+ `${t('Dispersion End Date has to be greater than')} ${moment(
+ dispersionStartDate,
+ ).format('YYYY-MM-DD')}`,
+ )
+ : schema,
+ ),
+ });
+
+ const handleSubmit = async (values): Promise => {
+ try {
+ const res = await mutate({
+ variables: {
+ input: {
+ paymentPlanId: id,
+ targetingId: values.targetingId,
+ startDate: values.startDate,
+ endDate: values.endDate,
+ dispersionStartDate: values.dispersionStartDate,
+ dispersionEndDate: values.dispersionEndDate,
+ currency: values.currency?.value
+ ? values.currency.value
+ : values.currency,
+ },
+ },
+ });
+ showMessage(t('Follow-up Payment Plan Edited'));
+ navigate(
+ `/${baseUrl}/payment-module/followup-payment-plans/${res.data.updatePaymentPlan.paymentPlan.id}`,
+ );
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ return (
+
+ {({ submitForm, values }) => (
+
+ )}
+
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/EditPeopleFollowUpSetUpFspPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/EditPeopleFollowUpSetUpFspPage.tsx
new file mode 100644
index 0000000000..c235845f8a
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/EditPeopleFollowUpSetUpFspPage.tsx
@@ -0,0 +1,47 @@
+import * as React from 'react';
+import { useParams } from 'react-router-dom';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { SetUpFspCore } from '@components/paymentmodule/CreateSetUpFsp/SetUpFspCore/SetUpFspCore';
+import { EditSetUpFspHeader } from '@components/paymentmodule/EditSetUpFsp/EditSetUpFspHeader';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { usePaymentPlanQuery } from '@generated/graphql';
+
+export const EditPeopleFollowUpSetUpFspPage = (): React.ReactElement => {
+ const { id } = useParams();
+
+ const { data: paymentPlanData, loading: paymentPlanLoading } =
+ usePaymentPlanQuery({
+ variables: {
+ id,
+ },
+ fetchPolicy: 'cache-and-network',
+ });
+
+ const permissions = usePermissions();
+
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK_FSP, permissions))
+ return ;
+ if (!paymentPlanData) return null;
+ if (paymentPlanLoading) return ;
+
+ const mappedInitialDeliveryMechanisms =
+ paymentPlanData.paymentPlan.deliveryMechanisms.map((el) => ({
+ deliveryMechanism: el.name,
+ fsp: el.fsp?.id || '',
+ chosenConfiguration: el.chosenConfiguration || '',
+ }));
+
+ const initialValues = {
+ deliveryMechanisms: mappedInitialDeliveryMechanisms,
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/EditPeoplePaymentPlanPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/EditPeoplePaymentPlanPage.tsx
new file mode 100644
index 0000000000..c7cda427bc
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/EditPeoplePaymentPlanPage.tsx
@@ -0,0 +1,155 @@
+import { Form, Formik } from 'formik';
+import * as React from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+import moment from 'moment';
+import * as Yup from 'yup';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { PaymentPlanParameters } from '@components/paymentmodule/CreatePaymentPlan/PaymentPlanParameters';
+import { PaymentPlanTargeting } from '@components/paymentmodule/CreatePaymentPlan/PaymentPlanTargeting/PaymentPlanTargeting';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { useSnackbar } from '@hooks/useSnackBar';
+import { today } from '@utils/utils';
+import {
+ useAllTargetPopulationsQuery,
+ usePaymentPlanQuery,
+ useUpdatePpMutation,
+} from '@generated/graphql';
+import { EditPaymentPlanHeader } from '@components/paymentmodule/EditPaymentPlan/EditPaymentPlanHeader';
+import { AutoSubmitFormOnEnter } from '@components/core/AutoSubmitFormOnEnter';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+export const EditPeoplePaymentPlanPage = (): React.ReactElement => {
+ const navigate = useNavigate();
+ const { id } = useParams();
+ const { t } = useTranslation();
+ const { data: paymentPlanData, loading: loadingPaymentPlan } =
+ usePaymentPlanQuery({
+ variables: {
+ id,
+ },
+ fetchPolicy: 'cache-and-network',
+ });
+
+ const [mutate] = useUpdatePpMutation();
+ const { showMessage } = useSnackbar();
+ const { baseUrl, businessArea, programId } = useBaseUrl();
+ const permissions = usePermissions();
+
+ const { data: allTargetPopulationsData, loading: loadingTargetPopulations } =
+ useAllTargetPopulationsQuery({
+ variables: {
+ businessArea,
+ paymentPlanApplicable: false,
+ program: [programId],
+ },
+ });
+ if (loadingTargetPopulations || loadingPaymentPlan)
+ return ;
+ if (!allTargetPopulationsData || !paymentPlanData) return null;
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_CREATE, permissions))
+ return ;
+ const { paymentPlan } = paymentPlanData;
+
+ const initialValues = {
+ targetingId: paymentPlan.targetPopulation.id,
+ startDate: paymentPlan.startDate,
+ endDate: paymentPlan.endDate,
+ currency: {
+ name: paymentPlan.currencyName,
+ value: paymentPlan.currency,
+ },
+ dispersionStartDate: paymentPlan.dispersionStartDate,
+ dispersionEndDate: paymentPlan.dispersionEndDate,
+ };
+
+ const validationSchema = Yup.object().shape({
+ targetingId: Yup.string().required(t('Target Population is required')),
+ startDate: Yup.date(),
+ endDate: Yup.date()
+ .required(t('End Date is required'))
+ .when('startDate', (startDate: any, schema: Yup.DateSchema) =>
+ startDate
+ ? schema.min(
+ startDate as Date,
+ `${t('End date has to be greater than')} ${moment(
+ startDate,
+ ).format('YYYY-MM-DD')}`,
+ )
+ : schema,
+ ),
+ dispersionStartDate: Yup.date().required(
+ t('Dispersion Start Date is required'),
+ ),
+ dispersionEndDate: Yup.date()
+ .required(t('Dispersion End Date is required'))
+ .min(today, t('Dispersion End Date cannot be in the past'))
+ .when(
+ 'dispersionStartDate',
+ (dispersionStartDate: any, schema: Yup.DateSchema) =>
+ dispersionStartDate
+ ? schema.min(
+ dispersionStartDate as Date,
+ `${t('Dispersion End Date has to be greater than')} ${moment(
+ dispersionStartDate,
+ ).format('YYYY-MM-DD')}`,
+ )
+ : schema,
+ ),
+ });
+
+ const handleSubmit = async (values): Promise => {
+ try {
+ const res = await mutate({
+ variables: {
+ input: {
+ paymentPlanId: id,
+ targetingId: values.targetingId,
+ startDate: values.startDate,
+ endDate: values.endDate,
+ dispersionStartDate: values.dispersionStartDate,
+ dispersionEndDate: values.dispersionEndDate,
+ currency: values.currency?.value
+ ? values.currency.value
+ : values.currency,
+ },
+ },
+ });
+ showMessage(t('Payment Plan Edited'));
+ navigate(
+ `/${baseUrl}/payment-module/payment-plans/${res.data.updatePaymentPlan.paymentPlan.id}`,
+ );
+ } catch (e) {
+ e.graphQLErrors.map((x) => showMessage(x.message));
+ }
+ };
+
+ return (
+
+ {({ submitForm, values }) => (
+
+ )}
+
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/EditPeopleSetUpFspPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/EditPeopleSetUpFspPage.tsx
new file mode 100644
index 0000000000..2e7d505514
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/EditPeopleSetUpFspPage.tsx
@@ -0,0 +1,47 @@
+import * as React from 'react';
+import { useParams } from 'react-router-dom';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { SetUpFspCore } from '@components/paymentmodule/CreateSetUpFsp/SetUpFspCore/SetUpFspCore';
+import { EditSetUpFspHeader } from '@components/paymentmodule/EditSetUpFsp/EditSetUpFspHeader';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { usePaymentPlanQuery } from '@generated/graphql';
+
+export const EditPeopleSetUpFspPage = (): React.ReactElement => {
+ const { id } = useParams();
+
+ const { data: paymentPlanData, loading: paymentPlanLoading } =
+ usePaymentPlanQuery({
+ variables: {
+ id,
+ },
+ fetchPolicy: 'cache-and-network',
+ });
+
+ const permissions = usePermissions();
+
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK_FSP, permissions))
+ return ;
+ if (!paymentPlanData) return null;
+ if (paymentPlanLoading) return ;
+
+ const mappedInitialDeliveryMechanisms =
+ paymentPlanData.paymentPlan.deliveryMechanisms.map((el) => ({
+ deliveryMechanism: el.name,
+ fsp: el.fsp?.id || '',
+ chosenConfiguration: el.chosenConfiguration || '',
+ }));
+
+ const initialValues = {
+ deliveryMechanisms: mappedInitialDeliveryMechanisms,
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/PeopleFollowUpPaymentPlanDetailsPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/PeopleFollowUpPaymentPlanDetailsPage.tsx
new file mode 100644
index 0000000000..e926bf6b35
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/PeopleFollowUpPaymentPlanDetailsPage.tsx
@@ -0,0 +1,94 @@
+import * as React from 'react';
+import { useEffect } from 'react';
+import { useParams } from 'react-router-dom';
+import { PaymentPlanStatus, usePaymentPlanQuery } from '@generated/graphql';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { FollowUpPaymentPlanDetails } from '@components/paymentmodule/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetails';
+import { FollowUpPaymentPlanDetailsHeader } from '@components/paymentmodule/FollowUpPaymentPlanDetails/FollowUpPaymentPlanDetailsHeader';
+import { AcceptanceProcess } from '@components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcess';
+import { Entitlement } from '@components/paymentmodule/PaymentPlanDetails/Entitlement/Entitlement';
+import { FspSection } from '@components/paymentmodule/PaymentPlanDetails/FspSection';
+import { PaymentPlanDetailsResults } from '@components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsResults';
+import { ReconciliationSummary } from '@components/paymentmodule/PaymentPlanDetails/ReconciliationSummary';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { isPermissionDeniedError } from '@utils/utils';
+import { PaymentsTable } from '../../tables/paymentmodule/PaymentsTable';
+import { UniversalActivityLogTable } from '../../tables/UniversalActivityLogTable';
+import { ExcludeSection } from '@components/paymentmodule/PaymentPlanDetails/ExcludeSection';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+export const PeopleFollowUpPaymentPlanDetailsPage = (): React.ReactElement => {
+ const { id } = useParams();
+ const permissions = usePermissions();
+ const { baseUrl, businessArea } = useBaseUrl();
+ const { data, loading, startPolling, stopPolling, error } =
+ usePaymentPlanQuery({
+ variables: {
+ id,
+ },
+ fetchPolicy: 'cache-and-network',
+ });
+
+ const status = data?.paymentPlan?.status;
+
+ useEffect(() => {
+ if (PaymentPlanStatus.Preparing === status) {
+ startPolling(3000);
+ } else {
+ stopPolling();
+ }
+ return stopPolling;
+ }, [status, startPolling, stopPolling]);
+
+ if (loading && !data) return ;
+ if (permissions === null || !data) return null;
+
+ if (
+ !hasPermissions(PERMISSIONS.PM_VIEW_DETAILS, permissions) ||
+ isPermissionDeniedError(error)
+ )
+ return ;
+
+ const shouldDisplayEntitlement =
+ status !== PaymentPlanStatus.Open && status !== PaymentPlanStatus.Accepted;
+
+ const shouldDisplayFsp = status !== PaymentPlanStatus.Open;
+ const shouldDisplayReconciliationSummary =
+ status === PaymentPlanStatus.Accepted ||
+ status === PaymentPlanStatus.Finished;
+
+ const { paymentPlan } = data;
+ return (
+ <>
+
+
+
+ {shouldDisplayEntitlement && (
+
+ )}
+ {shouldDisplayFsp && (
+
+ )}
+
+
+
+ {shouldDisplayReconciliationSummary && (
+
+ )}
+ {hasPermissions(PERMISSIONS.ACTIVITY_LOG_VIEW, permissions) && (
+
+ )}
+ >
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentDetailsPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentDetailsPage.tsx
new file mode 100644
index 0000000000..cb818aa86a
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentDetailsPage.tsx
@@ -0,0 +1,100 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useParams } from 'react-router-dom';
+import { BreadCrumbsItem } from '@components/core/BreadCrumbs';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PageHeader } from '@components/core/PageHeader';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import {
+ PaymentPlanStatus,
+ PaymentStatus,
+ useCashAssistUrlPrefixQuery,
+ usePaymentQuery,
+} from '@generated/graphql';
+import { PaymentDetails } from '@components/paymentmodule/PaymentDetails';
+import { RevertForceFailedButton } from '@components/paymentmodule/RevertForceFailedButton';
+import { ForceFailedButton } from '@components/paymentmodule/ForceFailedButton';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { AdminButton } from '@core/AdminButton';
+
+export const PeoplePaymentDetailsPage = (): React.ReactElement => {
+ const { t } = useTranslation();
+ const { id } = useParams();
+ const { data: caData, loading: caLoading } = useCashAssistUrlPrefixQuery({
+ fetchPolicy: 'cache-first',
+ });
+ const { data, loading } = usePaymentQuery({
+ variables: { id },
+ fetchPolicy: 'cache-and-network',
+ });
+ const paymentPlanStatus = data?.payment?.parent?.status;
+ const paymentPlanIsFollowUp = data?.payment?.parent?.isFollowUp;
+ const permissions = usePermissions();
+ const { baseUrl } = useBaseUrl();
+ if (loading || caLoading) return ;
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_VIEW_DETAILS, permissions))
+ return ;
+
+ if (!data || !caData) return null;
+ const { payment } = data;
+ const breadCrumbsItems: BreadCrumbsItem[] = [
+ {
+ title: t('Payment Module'),
+ to: `/${baseUrl}/payment-module/`,
+ },
+ {
+ title: ` ${paymentPlanIsFollowUp ? 'Follow-up ' : ''} Payment Plan ${
+ payment.parent.unicefId
+ }`,
+ to: `/${baseUrl}/payment-module/${
+ paymentPlanIsFollowUp ? 'followup-payment-plans' : 'payment-plans'
+ }/${data.payment.parent.id}/`,
+ },
+ ];
+
+ const renderButton = (): React.ReactElement | null => {
+ if (
+ (hasPermissions(PERMISSIONS.PM_MARK_PAYMENT_AS_FAILED, permissions) &&
+ paymentPlanStatus === PaymentPlanStatus.Accepted) ||
+ paymentPlanStatus === PaymentPlanStatus.Finished
+ ) {
+ const ButtonComponent =
+ payment.status === PaymentStatus.ForceFailed
+ ? RevertForceFailedButton
+ : ForceFailedButton;
+ return ;
+ }
+ return null;
+ };
+
+ const canViewHouseholdDetails = hasPermissions(
+ PERMISSIONS.POPULATION_VIEW_HOUSEHOLDS_DETAILS,
+ permissions,
+ );
+
+ return (
+ <>
+ }
+ >
+ {renderButton()}
+
+
+
+
+ >
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentModulePage.tsx b/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentModulePage.tsx
new file mode 100644
index 0000000000..82cc700cbd
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentModulePage.tsx
@@ -0,0 +1,81 @@
+import * as React from 'react';
+import { useState } from 'react';
+import { Link, useLocation } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+import { PageHeader } from '@components/core/PageHeader';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { TableWrapper } from '@components/core/TableWrapper';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { getFilterFromQueryParams } from '@utils/utils';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { ButtonTooltip } from '@components/core/ButtonTooltip';
+import { useProgramContext } from '../../../programContext';
+import { PeoplePaymentPlansTable } from '@containers/tables/paymentmodulePeople/PeoplePaymentPlansTable';
+import { PeoplePaymentPlansFilters } from '@containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansFilters';
+
+const initialFilter = {
+ search: '',
+ dispersionStartDate: '',
+ dispersionEndDate: '',
+ status: [],
+ totalEntitledQuantityFrom: '',
+ totalEntitledQuantityTo: '',
+ isFollowUp: '',
+};
+
+export const PeoplePaymentModulePage = (): React.ReactElement => {
+ const { t } = useTranslation();
+ const { baseUrl } = useBaseUrl();
+ const permissions = usePermissions();
+ const location = useLocation();
+ const { isActiveProgram } = useProgramContext();
+
+ const [filter, setFilter] = useState(
+ getFilterFromQueryParams(location, initialFilter),
+ );
+ const [appliedFilter, setAppliedFilter] = useState(
+ getFilterFromQueryParams(location, initialFilter),
+ );
+
+ if (permissions === null) return null;
+
+ if (!hasPermissions(PERMISSIONS.PM_VIEW_LIST, permissions))
+ return ;
+
+ return (
+ <>
+
+ {hasPermissions(PERMISSIONS.PM_CREATE, permissions) && (
+
+ {t('NEW PAYMENT PLAN')}
+
+ )}
+
+
+
+
+
+ >
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentPlanDetailsPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentPlanDetailsPage.tsx
new file mode 100644
index 0000000000..7378cb691d
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/PeoplePaymentPlanDetailsPage.tsx
@@ -0,0 +1,110 @@
+import { Box } from '@mui/material';
+import * as React from 'react';
+import { useEffect } from 'react';
+import { useParams } from 'react-router-dom';
+import {
+ PaymentPlanBackgroundActionStatus,
+ PaymentPlanStatus,
+ usePaymentPlanQuery,
+} from '@generated/graphql';
+import { LoadingComponent } from '@components/core/LoadingComponent';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { AcceptanceProcess } from '@components/paymentmodule/PaymentPlanDetails/AcceptanceProcess/AcceptanceProcess';
+import { Entitlement } from '@components/paymentmodule/PaymentPlanDetails/Entitlement/Entitlement';
+import { ExcludeSection } from '@components/paymentmodule/PaymentPlanDetails/ExcludeSection';
+import { FspSection } from '@components/paymentmodule/PaymentPlanDetails/FspSection';
+import { PaymentPlanDetails } from '@components/paymentmodule/PaymentPlanDetails/PaymentPlanDetails';
+import { PaymentPlanDetailsHeader } from '@components/paymentmodule/PaymentPlanDetails/PaymentPlanDetailsHeader';
+import { ReconciliationSummary } from '@components/paymentmodule/PaymentPlanDetails/ReconciliationSummary';
+import { PERMISSIONS, hasPermissions } from '../../../config/permissions';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { usePermissions } from '@hooks/usePermissions';
+import { isPermissionDeniedError } from '@utils/utils';
+import { UniversalActivityLogTable } from '../../tables/UniversalActivityLogTable';
+import { PeoplePaymentPlanDetailsResults } from '@components/paymentmodulepeople/PaymentPlanDetails/PeoplePaymentPlanDetailsResults';
+import { PeoplePaymentsTable } from '@containers/tables/paymentmodulePeople/PeoplePaymentsTable';
+
+export const PeoplePaymentPlanDetailsPage = (): React.ReactElement => {
+ const { id } = useParams();
+ const permissions = usePermissions();
+ const { baseUrl, businessArea } = useBaseUrl();
+ const { data, loading, startPolling, stopPolling, error } =
+ usePaymentPlanQuery({
+ variables: {
+ id,
+ },
+ fetchPolicy: 'cache-and-network',
+ });
+
+ const status = data?.paymentPlan?.status;
+ const backgroundActionStatus = data?.paymentPlan?.backgroundActionStatus;
+
+ useEffect(() => {
+ if (
+ PaymentPlanStatus.Preparing === status ||
+ (backgroundActionStatus !== null &&
+ backgroundActionStatus !==
+ PaymentPlanBackgroundActionStatus.ExcludeBeneficiariesError)
+ ) {
+ startPolling(3000);
+ } else {
+ stopPolling();
+ }
+ return stopPolling;
+ }, [status, backgroundActionStatus, startPolling, stopPolling]);
+
+ if (loading && !data) return ;
+ if (permissions === null || !data) return null;
+
+ if (
+ !hasPermissions(PERMISSIONS.PM_VIEW_DETAILS, permissions) ||
+ isPermissionDeniedError(error)
+ )
+ return ;
+
+ const shouldDisplayEntitlement =
+ status !== PaymentPlanStatus.Open && status !== PaymentPlanStatus.Accepted;
+
+ const shouldDisplayFsp = status !== PaymentPlanStatus.Open;
+ const shouldDisplayReconciliationSummary =
+ status === PaymentPlanStatus.Accepted ||
+ status === PaymentPlanStatus.Finished;
+
+ const { paymentPlan } = data;
+
+ return (
+
+
+
+ {status !== PaymentPlanStatus.Preparing && (
+ <>
+
+ {shouldDisplayEntitlement && (
+
+ )}
+ {shouldDisplayFsp && (
+
+ )}
+
+
+
+ {shouldDisplayReconciliationSummary && (
+
+ )}
+ {hasPermissions(PERMISSIONS.ACTIVITY_LOG_VIEW, permissions) && (
+
+ )}
+ >
+ )}
+
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/SetUpPeopleFollowUpFspPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/SetUpPeopleFollowUpFspPage.tsx
new file mode 100644
index 0000000000..44b10b4c93
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/SetUpPeopleFollowUpFspPage.tsx
@@ -0,0 +1,33 @@
+import * as React from 'react';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { CreateSetUpFspHeader } from '@components/paymentmodule/CreateSetUpFsp/CreateSetUpFspHeader';
+import { SetUpFspCore } from '@components/paymentmodule/CreateSetUpFsp/SetUpFspCore/SetUpFspCore';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+export const SetUpPeopleFollowUpFspPage = (): React.ReactElement => {
+ const { baseUrl } = useBaseUrl();
+ const permissions = usePermissions();
+
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK_FSP, permissions))
+ return ;
+
+ const initialValues = {
+ deliveryMechanisms: [
+ {
+ deliveryMechanism: '',
+ fsp: '',
+ chosenConfiguration: '',
+ },
+ ],
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
diff --git a/frontend/src/containers/pages/paymentmodulepeople/SetUpPeopleFspPage.tsx b/frontend/src/containers/pages/paymentmodulepeople/SetUpPeopleFspPage.tsx
new file mode 100644
index 0000000000..0be8ddca47
--- /dev/null
+++ b/frontend/src/containers/pages/paymentmodulepeople/SetUpPeopleFspPage.tsx
@@ -0,0 +1,33 @@
+import * as React from 'react';
+import { PermissionDenied } from '@components/core/PermissionDenied';
+import { CreateSetUpFspHeader } from '@components/paymentmodule/CreateSetUpFsp/CreateSetUpFspHeader';
+import { SetUpFspCore } from '@components/paymentmodule/CreateSetUpFsp/SetUpFspCore/SetUpFspCore';
+import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
+import { usePermissions } from '@hooks/usePermissions';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+export const SetUpPeopleFspPage = (): React.ReactElement => {
+ const { baseUrl } = useBaseUrl();
+ const permissions = usePermissions();
+
+ if (permissions === null) return null;
+ if (!hasPermissions(PERMISSIONS.PM_LOCK_AND_UNLOCK_FSP, permissions))
+ return ;
+
+ const initialValues = {
+ deliveryMechanisms: [
+ {
+ deliveryMechanism: '',
+ fsp: '',
+ chosenConfiguration: '',
+ },
+ ],
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
diff --git a/frontend/src/containers/pages/payments/CashPlanVerificationDetailsPage.tsx b/frontend/src/containers/pages/payments/CashPlanVerificationDetailsPage.tsx
index 4bb6c0d389..57cd225cf5 100644
--- a/frontend/src/containers/pages/payments/CashPlanVerificationDetailsPage.tsx
+++ b/frontend/src/containers/pages/payments/CashPlanVerificationDetailsPage.tsx
@@ -30,6 +30,8 @@ import {
import { UniversalActivityLogTablePaymentVerification } from '../../tables/UniversalActivityLogTablePaymentVerification';
import { VerificationRecordsTable } from '../../tables/payments/VerificationRecordsTable';
import { VerificationRecordsFilters } from '../../tables/payments/VerificationRecordsTable/VerificationRecordsFilters';
+import { useProgramContext } from '../../../programContext';
+import { PeopleVerificationRecordsTable } from '@containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTable';
const Container = styled.div`
display: flex;
@@ -60,6 +62,7 @@ const initialFilter = {
export function CashPlanVerificationDetailsPage(): React.ReactElement {
const { t } = useTranslation();
+ const { isSocialDctType } = useProgramContext();
const permissions = usePermissions();
const { baseUrl, businessArea, isAllPrograms } = useBaseUrl();
@@ -159,6 +162,33 @@ export function CashPlanVerificationDetailsPage(): React.ReactElement {
);
+ const renderVerificationRecordsTable = () => {
+ if (isSocialDctType) {
+ return (
+
+ );
+ }
+ return (
+
+ );
+ };
+
return (
<>
{toolbar}
@@ -190,17 +220,7 @@ export function CashPlanVerificationDetailsPage(): React.ReactElement {
verifications={cashPlan.verificationPlans}
/>
-
-
-
+ {renderVerificationRecordsTable()}
>
) : null}
{canSeeActivationMessage() ? (
diff --git a/frontend/src/containers/pages/payments/PaymentPlanVerificationDetailsPage.tsx b/frontend/src/containers/pages/payments/PaymentPlanVerificationDetailsPage.tsx
index 0660796c0e..e2951d8b1c 100644
--- a/frontend/src/containers/pages/payments/PaymentPlanVerificationDetailsPage.tsx
+++ b/frontend/src/containers/pages/payments/PaymentPlanVerificationDetailsPage.tsx
@@ -29,6 +29,8 @@ import {
import { UniversalActivityLogTablePaymentVerification } from '../../tables/UniversalActivityLogTablePaymentVerification';
import { VerificationsTable } from '../../tables/payments/VerificationRecordsTable';
import { VerificationRecordsFilters } from '../../tables/payments/VerificationRecordsTable/VerificationRecordsFilters';
+import { useProgramContext } from '../../../programContext';
+import { PeopleVerificationsTable } from '@containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationsTable';
const Container = styled.div`
display: flex;
@@ -76,6 +78,7 @@ export function PaymentPlanVerificationDetailsPage(): React.ReactElement {
});
const { data: choicesData, loading: choicesLoading } =
useCashPlanVerificationSamplingChoicesQuery();
+ const { isSocialDctType } = useProgramContext();
if (loading || choicesLoading) return ;
@@ -166,6 +169,33 @@ export function PaymentPlanVerificationDetailsPage(): React.ReactElement {
);
+ const renderVerificationsTable = () => {
+ if (isSocialDctType) {
+ return (
+
+ );
+ }
+ return (
+
+ );
+ };
+
return (
<>
{toolbar}
@@ -195,17 +225,7 @@ export function PaymentPlanVerificationDetailsPage(): React.ReactElement {
setAppliedFilter={setAppliedFilter}
verifications={paymentPlan.verificationPlans}
/>
-
-
-
+ {renderVerificationsTable()}
>
) : null}
{canSeeActivationMessage() ? (
diff --git a/frontend/src/containers/pages/people/PeopleDetailsPage.tsx b/frontend/src/containers/pages/people/PeopleDetailsPage.tsx
index f84701f236..19d2fdbed6 100644
--- a/frontend/src/containers/pages/people/PeopleDetailsPage.tsx
+++ b/frontend/src/containers/pages/people/PeopleDetailsPage.tsx
@@ -1,9 +1,10 @@
-import { Box } from '@mui/material';
+import { Box, Grid, Paper, Typography } from '@mui/material';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import styled from 'styled-components';
import {
+ HouseholdNode,
IndividualNode,
useAllIndividualsFlexFieldsAttributesQuery,
useGrievancesChoiceDataQuery,
@@ -20,19 +21,43 @@ import { IndividualVulnerabilities } from '@components/population/IndividualVuln
import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
import { useBaseUrl } from '@hooks/useBaseUrl';
import { usePermissions } from '@hooks/usePermissions';
-import { isPermissionDeniedError } from '@utils/utils';
+import {
+ formatCurrencyWithSymbol,
+ isPermissionDeniedError,
+} from '@utils/utils';
import { UniversalActivityLogTable } from '../../tables/UniversalActivityLogTable';
import { AdminButton } from '@core/AdminButton';
import { PeopleBioData } from '@components/people/PeopleBioData/PeopleBioData';
+import { Title } from '@core/Title';
+import { LabelizedField } from '@core/LabelizedField';
+import {
+ BigValue,
+ BigValueContainer,
+} from '@components/rdi/details/RegistrationDetails/RegistrationDetails';
+import { UniversalMoment } from '@core/UniversalMoment';
+import { PaymentRecordAndPaymentPeopleTable } from '@containers/tables/payments/PaymentRecordAndPaymentPeopleTable';
const Container = styled.div`
- padding: 20px;
+ padding: 20px 20px 00px 20px;
&& {
display: flex;
flex-direction: column;
width: 100%;
}
`;
+const OverviewPaper = styled(Paper)`
+ margin: 0px 0px 20px 0px;
+ padding: 20px ${({ theme }) => theme.spacing(11)};
+`;
+const Overview = styled(Paper)`
+ margin: 15px 0px 20px 0px;
+ padding: 20px ${({ theme }) => theme.spacing(11)};
+`;
+const SubTitle = styled(Typography)`
+ && {
+ font-size: 16px;
+ }
+`;
export function PeopleDetailsPage(): React.ReactElement {
const { t } = useTranslation();
@@ -83,6 +108,7 @@ export function PeopleDetailsPage(): React.ReactElement {
];
const { individual } = data;
+ const household = individual?.household;
return (
<>
@@ -122,10 +148,132 @@ export function PeopleDetailsPage(): React.ReactElement {
flexFieldsData={flexFieldsData}
individual={individual as IndividualNode}
/>
- {hasPermissions(PERMISSIONS.ACTIVITY_LOG_VIEW, permissions) && (
-
+
+
+ {t('Benefits')}
+
+
+
+
+ {household?.deliveredQuantities?.length ? (
+
+
+
+
+ {household?.deliveredQuantities?.map((item) => (
+
+ {item.currency === 'USD'
+ ? formatCurrencyWithSymbol(
+ item.totalDeliveredQuantity,
+ item.currency,
+ )
+ : `(${formatCurrencyWithSymbol(
+ item.totalDeliveredQuantity,
+ item.currency,
+ )})`}
+
+ ))}
+
+
+
+
+ ) : (
+ <>->
+ )}
+
+
+
+
+
+
+ {formatCurrencyWithSymbol(
+ household?.totalCashReceivedUsd,
+ 'USD',
+ )}
+
+
+
+
+
+
+ {hasPermissions(
+ PERMISSIONS.PROGRAMME_VIEW_LIST_AND_DETAILS,
+ permissions,
+ ) && (
+
)}
+
+
+
+ {t('Registration Details')}
+
+
+
+
+ {household?.registrationDataImport?.dataSource}
+
+
+
+
+ {household?.registrationDataImport?.name}
+
+
+
+
+
+
+ {household?.lastRegistrationDate}
+
+
+
+
+
+
+ {household?.registrationDataImport?.importedBy?.email}
+
+
+
+ {household?.registrationDataImport?.dataSource === 'XLS' ? null : (
+ <>
+
+ {t('Data Collection')}
+
+
+
+ {household?.start}
+
+
+
+
+
+ {household?.firstRegistrationDate}
+
+
+
+
+
+ {/* //TODO: Figure it out. deviceId removed from the model? */}
+ {/* {household?.deviceid} */} -
+
+
+
+ >
+ )}
+
+ {hasPermissions(PERMISSIONS.ACTIVITY_LOG_VIEW, permissions) && (
+
+ )}
>
);
}
diff --git a/frontend/src/containers/pages/people/PeoplePage.tsx b/frontend/src/containers/pages/people/PeoplePage.tsx
index 29007793f2..c42442d5b1 100644
--- a/frontend/src/containers/pages/people/PeoplePage.tsx
+++ b/frontend/src/containers/pages/people/PeoplePage.tsx
@@ -10,14 +10,14 @@ import {
import { LoadingComponent } from '@components/core/LoadingComponent';
import { PageHeader } from '@components/core/PageHeader';
import { PermissionDenied } from '@components/core/PermissionDenied';
-import { IndividualsFilter } from '@components/population/IndividualsFilter';
import { hasPermissions, PERMISSIONS } from '../../../config/permissions';
import { useBaseUrl } from '@hooks/useBaseUrl';
import { usePermissions } from '@hooks/usePermissions';
import { getFilterFromQueryParams } from '@utils/utils';
import { PeopleListTable } from '@containers/tables/people/PeopleListTable';
+import { PeopleFilter } from '@components/people/PeopleFilter';
-export function PeoplePage(): React.ReactElement {
+export const PeoplePage = (): React.ReactElement => {
const { t } = useTranslation();
const location = useLocation();
const { businessArea } = useBaseUrl();
@@ -64,7 +64,7 @@ export function PeoplePage(): React.ReactElement {
return (
<>
-
>
);
-}
+};
diff --git a/frontend/src/containers/pages/program/CreateProgramPage.tsx b/frontend/src/containers/pages/program/CreateProgramPage.tsx
index 09e8525dd3..2b2e5038ba 100644
--- a/frontend/src/containers/pages/program/CreateProgramPage.tsx
+++ b/frontend/src/containers/pages/program/CreateProgramPage.tsx
@@ -17,14 +17,10 @@ import { PartnersStep } from '@components/programs/CreateProgram/PartnersStep';
import { programValidationSchema } from '@components/programs/CreateProgram/programValidationSchema';
import { useBaseUrl } from '@hooks/useBaseUrl';
import { useSnackbar } from '@hooks/useSnackBar';
-import {
- hasPermissionInModule,
- PERMISSIONS,
-} from '../../../config/permissions';
+import { hasPermissionInModule } from '../../../config/permissions';
import { usePermissions } from '@hooks/usePermissions';
import { BreadCrumbsItem } from '@components/core/BreadCrumbs';
import { useNavigate } from 'react-router-dom';
-import { decodeIdString } from '@utils/utils';
export const CreateProgramPage = (): ReactElement => {
const navigate = useNavigate();
diff --git a/frontend/src/containers/pages/program/DuplicateProgramPage.tsx b/frontend/src/containers/pages/program/DuplicateProgramPage.tsx
index a1ab3cbcd9..b7c62acc96 100644
--- a/frontend/src/containers/pages/program/DuplicateProgramPage.tsx
+++ b/frontend/src/containers/pages/program/DuplicateProgramPage.tsx
@@ -19,10 +19,7 @@ import { programValidationSchema } from '@components/programs/CreateProgram/prog
import { useBaseUrl } from '@hooks/useBaseUrl';
import { useSnackbar } from '@hooks/useSnackBar';
import { BreadCrumbsItem } from '@components/core/BreadCrumbs';
-import {
- hasPermissionInModule,
- PERMISSIONS,
-} from '../../../config/permissions';
+import { hasPermissionInModule } from '../../../config/permissions';
import { usePermissions } from '@hooks/usePermissions';
import { decodeIdString } from '@utils/utils';
@@ -53,8 +50,8 @@ export const DuplicateProgramPage = (): ReactElement => {
: 0;
const partnersToSet =
values.partnerAccess === ProgramPartnerAccess.SelectedPartnersAccess
- ? values.partners.map(({ id, areas, areaAccess }) => ({
- partner: id,
+ ? values.partners.map(({ id: partnerId, areas, areaAccess }) => ({
+ partner: partnerId,
areas: areaAccess === 'ADMIN_AREA' ? areas : [],
areaAccess,
}))
diff --git a/frontend/src/containers/pages/program/EditProgramPage.tsx b/frontend/src/containers/pages/program/EditProgramPage.tsx
index 255d021898..1222ddfe72 100644
--- a/frontend/src/containers/pages/program/EditProgramPage.tsx
+++ b/frontend/src/containers/pages/program/EditProgramPage.tsx
@@ -21,10 +21,7 @@ import { useBaseUrl } from '@hooks/useBaseUrl';
import { useSnackbar } from '@hooks/useSnackBar';
import { decodeIdString } from '@utils/utils';
import { BreadCrumbsItem } from '@components/core/BreadCrumbs';
-import {
- hasPermissionInModule,
- PERMISSIONS,
-} from '../../../config/permissions';
+import { hasPermissionInModule } from '../../../config/permissions';
import { usePermissions } from '@hooks/usePermissions';
export const EditProgramPage = (): ReactElement => {
@@ -98,8 +95,8 @@ export const EditProgramPage = (): ReactElement => {
: 0;
const partnersToSet =
values.partnerAccess === ProgramPartnerAccess.SelectedPartnersAccess
- ? values.partners.map(({ id, areas, areaAccess }) => ({
- partner: id,
+ ? values.partners.map(({ id: partnerId, areas, areaAccess }) => ({
+ partner: partnerId,
areas: areaAccess === 'ADMIN_AREA' ? areas : [],
areaAccess,
}))
diff --git a/frontend/src/containers/pages/rdi/people/RegistrationDataImportForPeopleDetailsPage.tsx b/frontend/src/containers/pages/rdi/people/PeopleRegistrationDataImportDetailsPage.tsx
similarity index 98%
rename from frontend/src/containers/pages/rdi/people/RegistrationDataImportForPeopleDetailsPage.tsx
rename to frontend/src/containers/pages/rdi/people/PeopleRegistrationDataImportDetailsPage.tsx
index cb5e46fd2e..4792203fc8 100644
--- a/frontend/src/containers/pages/rdi/people/RegistrationDataImportForPeopleDetailsPage.tsx
+++ b/frontend/src/containers/pages/rdi/people/PeopleRegistrationDataImportDetailsPage.tsx
@@ -57,7 +57,7 @@ const TabPanel = ({
);
};
-export const RegistrationDataImportForPeopleDetailsPage =
+export const PeopleRegistrationDataImportDetailsPage =
(): React.ReactElement => {
const { t } = useTranslation();
const { id } = useParams();
diff --git a/frontend/src/containers/pages/rdi/people/RegistrationDataForPeopleImportPage.tsx b/frontend/src/containers/pages/rdi/people/PeopleRegistrationDataImportPage.tsx
similarity index 96%
rename from frontend/src/containers/pages/rdi/people/RegistrationDataForPeopleImportPage.tsx
rename to frontend/src/containers/pages/rdi/people/PeopleRegistrationDataImportPage.tsx
index 7da7c8c6e2..ba709eacaf 100644
--- a/frontend/src/containers/pages/rdi/people/RegistrationDataForPeopleImportPage.tsx
+++ b/frontend/src/containers/pages/rdi/people/PeopleRegistrationDataImportPage.tsx
@@ -21,7 +21,7 @@ const initialFilter = {
importDateRangeMax: '',
};
-export function RegistrationDataForPeopleImportPage(): React.ReactElement {
+export function PeopleRegistrationDataImportPage(): React.ReactElement {
const location = useLocation();
const permissions = usePermissions();
const { t } = useTranslation();
diff --git a/frontend/src/containers/pages/rdi/people/RegistrationPeopleDetailsPage.tsx b/frontend/src/containers/pages/rdi/people/PeopleRegistrationDetailsPage.tsx
similarity index 81%
rename from frontend/src/containers/pages/rdi/people/RegistrationPeopleDetailsPage.tsx
rename to frontend/src/containers/pages/rdi/people/PeopleRegistrationDetailsPage.tsx
index 4ae9fe69c1..01d3fc17af 100644
--- a/frontend/src/containers/pages/rdi/people/RegistrationPeopleDetailsPage.tsx
+++ b/frontend/src/containers/pages/rdi/people/PeopleRegistrationDetailsPage.tsx
@@ -18,7 +18,6 @@ import {
useHouseholdChoiceDataQuery,
useImportedIndividualQuery,
} from '@generated/graphql';
-import { useBaseUrl } from '@hooks/useBaseUrl';
const Container = styled.div`
padding: 20px;
@@ -29,10 +28,9 @@ const Container = styled.div`
}
`;
-export function RegistrationPeopleDetailsPage(): React.ReactElement {
+export function PeopleRegistrationDetailsPage(): React.ReactElement {
const { t } = useTranslation();
const { id } = useParams();
- const { baseUrl } = useBaseUrl();
const permissions = usePermissions();
const { data: flexFieldsData, loading: flexFieldsDataLoading } =
useAllIndividualsFlexFieldsAttributesQuery();
@@ -55,27 +53,18 @@ export function RegistrationPeopleDetailsPage(): React.ReactElement {
const breadCrumbsItems: BreadCrumbsItem[] = [
...(hasPermissions(PERMISSIONS.RDI_VIEW_LIST, permissions)
? [
- {
- title: t('Registration Data import'),
- to: `/${baseUrl}/registration-data-import/`,
- },
- ]
+ {
+ title: t('Registration Data import'),
+ to: '../..',
+ },
+ ]
: []),
{
title: importedIndividual.registrationDataImport.name,
- to: `/${baseUrl}/registration-data-import/${btoa(
- `RegistrationDataImportNode:${importedIndividual.registrationDataImport.hctId}`,
- )}`,
+ to: '..',
},
];
- if (importedIndividual?.household?.id) {
- breadCrumbsItems.push({
- title: `${t('HOUSEHOLD ID')}: ${importedIndividual?.household.importId}`,
- to: `/${baseUrl}/registration-data-import/household/${importedIndividual?.household?.id}`,
- });
- }
-
return (
{
const location = useLocation();
const { t } = useTranslation();
const permissions = usePermissions();
-
+ const { programId } = useBaseUrl();
+ const { data: programData } = useProgramQuery({
+ variables: { id: programId },
+ });
const [filter, setFilter] = useState(
getFilterFromQueryParams(location, initialFilter),
);
@@ -42,7 +49,13 @@ export const TargetPopulationsPage = (): React.ReactElement => {
if (!hasPermissions(PERMISSIONS.TARGETING_VIEW_LIST, permissions))
return ;
-
+ if (!programData) return null;
+ let Table = TargetPopulationTable;
+ let Filters = TargetPopulationFilters;
+ if (programData.program.isSocialWorkerProgram) {
+ Table = TargetPopulationForPeopleTable;
+ Filters = TargetPopulationForPeopleFilters;
+ }
return (
<>
@@ -59,14 +72,14 @@ export const TargetPopulationsPage = (): React.ReactElement => {
{canCreate && }
>
-
- {
- const paymentModuleRoutes = [
- {
- path: 'payment-module/new-plan',
- element: ,
- },
+ const { isSocialDctType } = useProgramContext();
+ let children = [];
+
+ if (isSocialDctType) {
+ children = [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'new-plan',
+ element: ,
+ },
+ {
+ path: 'followup-payment-plans/:id',
+ children: [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/create',
+ element: ,
+ },
+ ],
+ },
+ {
+ path: 'payment-plans/:id',
+ children: [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/create',
+ element: ,
+ },
+ ],
+ },
+ {
+ path: 'payments/:id',
+ element: ,
+ },
+ ];
+ } else {
+ children = [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'new-plan',
+ element: ,
+ },
+ {
+ path: 'followup-payment-plans/:id',
+ children: [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/create',
+ element: ,
+ },
+ ],
+ },
+ {
+ path: 'payment-plans/:id',
+ children: [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/edit',
+ element: ,
+ },
+ {
+ path: 'setup-fsp/create',
+ element: ,
+ },
+ ],
+ },
+ {
+ path: 'payments/:id',
+ element: ,
+ },
+ ];
+ }
+
+ return useRoutes([
{
path: 'payment-module',
- element: ,
- },
- {
- path: 'payment-module/followup-payment-plans/:id/edit',
- element: ,
- },
- {
- path: 'payment-module/followup-payment-plans/:id/setup-fsp/edit',
- element: ,
- },
- {
- path: 'payment-module/followup-payment-plans/:id/setup-fsp/create',
- element: ,
- },
- {
- path: 'payment-module/payment-plans/:id/setup-fsp/edit',
- element: ,
+ children,
},
- {
- path: 'payment-module/payment-plans/:id/edit',
- element: ,
- },
- {
- path: 'payment-module/payments/:id',
- element: ,
- },
- {
- path: 'payment-module/payment-plans/:id/setup-fsp/create',
- element: ,
- },
- {
- path: 'payment-module/payment-plans/:id',
- element: ,
- },
- {
- path: 'payment-module/followup-payment-plans/:id',
- element: ,
- },
- ];
-
- return useRoutes(paymentModuleRoutes);
+ ]);
};
diff --git a/frontend/src/containers/routers/RegistrationRoutes.tsx b/frontend/src/containers/routers/RegistrationRoutes.tsx
index a2caa0967c..32d63b4947 100644
--- a/frontend/src/containers/routers/RegistrationRoutes.tsx
+++ b/frontend/src/containers/routers/RegistrationRoutes.tsx
@@ -4,41 +4,56 @@ import { RegistrationDataImportDetailsPage } from '../pages/rdi/RegistrationData
import { RegistrationDataImportPage } from '../pages/rdi/RegistrationDataImportPage';
import { RegistrationHouseholdDetailsPage } from '../pages/rdi/RegistrationHouseholdDetailsPage';
import { RegistrationIndividualDetailsPage } from '../pages/rdi/RegistrationIndividualDetailsPage';
-import { RegistrationPeopleDetailsPage } from '@containers/pages/rdi/people/RegistrationPeopleDetailsPage';
-import {
- RegistrationDataImportForPeopleDetailsPage,
-} from '@containers/pages/rdi/people/RegistrationDataImportForPeopleDetailsPage';
-import { RegistrationDataForPeopleImportPage } from '@containers/pages/rdi/people/RegistrationDataForPeopleImportPage';
+import { useProgramContext } from '../../programContext';
+import { PeopleRegistrationDataImportPage } from '@containers/pages/rdi/people/PeopleRegistrationDataImportPage';
+import { PeopleRegistrationDetailsPage } from '@containers/pages/rdi/people/PeopleRegistrationDetailsPage';
+import { PeopleRegistrationDataImportDetailsPage } from '@containers/pages/rdi/people/PeopleRegistrationDataImportDetailsPage';
export const RegistrationRoutes = (): React.ReactElement => {
+ const { isSocialDctType } = useProgramContext();
+
+ let children = [];
+
+ if (isSocialDctType) {
+ children = [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'people/:id',
+ element: ,
+ },
+ {
+ path: ':id',
+ element: ,
+ },
+ ];
+ } else {
+ children = [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'household/:id',
+ element: ,
+ },
+ {
+ path: 'individual/:id',
+ element: ,
+ },
+ {
+ path: ':id',
+ element: ,
+ },
+ ];
+ }
+
const registrationRoutes = [
- {
- path: 'registration-data-import/household/:id',
- element: ,
- },
- {
- path: 'registration-data-import/individual/:id',
- element: ,
- },
- {
- path: 'registration-data-import-for-people/people/:id',
- element: ,
- },
- {
- path: 'registration-data-import-for-people/:id',
- element: ,
- },
- {
- path: 'registration-data-import-for-people',
- element: ,
- },
- {
- path: 'registration-data-import/:id',
- element: ,
- },
{
path: 'registration-data-import',
- element: ,
+ children,
},
];
diff --git a/frontend/src/containers/tables/Communication/CommunicationTable/__snapshots__/CommunicationTable.test.tsx.snap b/frontend/src/containers/tables/Communication/CommunicationTable/__snapshots__/CommunicationTable.test.tsx.snap
index 499fe17899..d890db0ec5 100644
--- a/frontend/src/containers/tables/Communication/CommunicationTable/__snapshots__/CommunicationTable.test.tsx.snap
+++ b/frontend/src/containers/tables/Communication/CommunicationTable/__snapshots__/CommunicationTable.test.tsx.snap
@@ -9,7 +9,7 @@ exports[`containers/tables//Communication/CommunicationTable should render loadi
class="sc-fsYfdN iJWUfq"
>
diff --git a/frontend/src/containers/tables/ProgrammesTable/ProgrammesHeadCells.tsx b/frontend/src/containers/tables/ProgrammesTable/ProgrammesHeadCells.tsx
index f2d67837d0..d64076c10f 100644
--- a/frontend/src/containers/tables/ProgrammesTable/ProgrammesHeadCells.tsx
+++ b/frontend/src/containers/tables/ProgrammesTable/ProgrammesHeadCells.tsx
@@ -30,7 +30,7 @@ AllProgramsQuery['allPrograms']['edges'][number]['node']
},
{
disablePadding: false,
- label: 'Num. of Households',
+ label: 'Program Size',
// disabled because number_of_households is not a field in the program model
id: 'number_of_households',
numeric: true,
diff --git a/frontend/src/containers/tables/ProgrammesTable/__snapshots__/ProgrammesTable.test.tsx.snap b/frontend/src/containers/tables/ProgrammesTable/__snapshots__/ProgrammesTable.test.tsx.snap
index 5d38693d0d..793ebb6572 100644
--- a/frontend/src/containers/tables/ProgrammesTable/__snapshots__/ProgrammesTable.test.tsx.snap
+++ b/frontend/src/containers/tables/ProgrammesTable/__snapshots__/ProgrammesTable.test.tsx.snap
@@ -9,7 +9,7 @@ exports[`containers/tables/ProgrammesTable should render loading 1`] = `
class="sc-fsYfdN iJWUfq"
>
- Num. of Households
+ Program Size
- Num. of Households
+ Program Size
();
const initialVariables: AllPaymentsForTableQueryVariables = {
businessArea,
@@ -61,8 +61,8 @@ export function PaymentsTable({
)}
isOnPaper={false}
headCells={headCells}
diff --git a/frontend/src/containers/tables/paymentmodule/PaymentsTable/PaymentsTableHeadCells.tsx b/frontend/src/containers/tables/paymentmodule/PaymentsTable/PaymentsTableHeadCells.tsx
index 549a06db09..18ea482670 100644
--- a/frontend/src/containers/tables/paymentmodule/PaymentsTable/PaymentsTableHeadCells.tsx
+++ b/frontend/src/containers/tables/paymentmodule/PaymentsTable/PaymentsTableHeadCells.tsx
@@ -2,7 +2,7 @@ import { AllPaymentsForTableQuery } from '@generated/graphql';
import { HeadCell } from '@components/core/Table/EnhancedTableHead';
export const headCells: HeadCell<
-AllPaymentsForTableQuery['allPayments']['edges'][number]['node']
+ AllPaymentsForTableQuery['allPayments']['edges'][number]['node']
>[] = [
{
disablePadding: false,
@@ -12,13 +12,13 @@ AllPaymentsForTableQuery['allPayments']['edges'][number]['node']
},
{
disablePadding: false,
- label: 'Payment Id',
+ label: 'Payment ID',
id: 'unicef_id',
numeric: false,
},
{
disablePadding: false,
- label: 'Household Id',
+ label: 'Household ID',
id: 'household__unicef_id',
numeric: false,
},
diff --git a/frontend/src/containers/tables/paymentmodule/PaymentsTable/__snapshots__/PaymentsTable.test.tsx.snap b/frontend/src/containers/tables/paymentmodule/PaymentsTable/__snapshots__/PaymentsTable.test.tsx.snap
index f9eac8ed53..871a2b57fd 100644
--- a/frontend/src/containers/tables/paymentmodule/PaymentsTable/__snapshots__/PaymentsTable.test.tsx.snap
+++ b/frontend/src/containers/tables/paymentmodule/PaymentsTable/__snapshots__/PaymentsTable.test.tsx.snap
@@ -73,7 +73,7 @@ exports[`containers/tables/paymentmodule/PaymentsTable should render loading 1`]
role="button"
tabindex="0"
>
- Payment Id
+ Payment ID
- Household Id
+ Household ID
- Payment Id
+ Payment ID
- Household Id
+ Household ID
{
+ const navigate = useNavigate();
+ const { baseUrl } = useBaseUrl();
+ const paymentPlanPath = `/${baseUrl}/payment-module/${
+ plan.isFollowUp ? 'followup-payment-plans' : 'payment-plans'
+ }/${plan.id}`;
+ const handleClick = (): void => {
+ navigate(paymentPlanPath);
+ };
+ const { data: statusChoicesData } =
+ useCashPlanVerificationStatusChoicesQuery();
+
+ if (!statusChoicesData) return null;
+
+ const followUpLinks = (): React.ReactElement => {
+ if (!plan.followUps?.edges?.length) return <>->;
+ return (
+
+ {plan.followUps?.edges?.map((followUp) => {
+ const followUpPaymentPlanPath = `/${baseUrl}/payment-module/followup-payment-plans/${followUp?.node?.id}`;
+ return (
+
+
+ {followUp?.node?.unicefId}
+
+
+ );
+ })}
+
+ );
+ };
+
+ return (
+
+
+ {plan.isFollowUp ? 'Follow-up: ' : ''}
+ {canViewDetails ? (
+ {plan.unicefId}
+ ) : (
+ plan.unicefId
+ )}
+
+
+
+
+ {plan.targetPopulation.name}
+ {plan.totalIndividualsCount || '-'}
+ {plan.currencyName}
+
+ {`${formatCurrencyWithSymbol(
+ plan.totalEntitledQuantity,
+ plan.currency,
+ )}`}
+
+
+ {`${formatCurrencyWithSymbol(
+ plan.totalDeliveredQuantity,
+ plan.currency,
+ )}`}
+
+
+ {`${formatCurrencyWithSymbol(
+ plan.totalUndeliveredQuantity,
+ plan.currency,
+ )}`}
+
+
+ {plan.dispersionStartDate}
+
+
+ {plan.dispersionEndDate}
+
+ {followUpLinks()}
+
+ );
+};
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansFilters.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansFilters.tsx
new file mode 100644
index 0000000000..789c9f875a
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansFilters.tsx
@@ -0,0 +1,191 @@
+import { Box, Checkbox, FormControlLabel, Grid, MenuItem } from '@mui/material';
+import moment from 'moment';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import { useLocation, useNavigate } from 'react-router-dom';
+import {
+ AllPaymentPlansForTableQueryVariables,
+ usePaymentPlanStatusChoicesQueryQuery,
+} from '@generated/graphql';
+import { DatePickerFilter } from '@components/core/DatePickerFilter';
+import { FiltersSection } from '@components/core/FiltersSection';
+import { NumberTextField } from '@components/core/NumberTextField';
+import { SearchTextField } from '@components/core/SearchTextField';
+import { SelectFilter } from '@components/core/SelectFilter';
+import { createHandleApplyFilterChange } from '@utils/utils';
+
+export type FilterProps = Pick<
+ AllPaymentPlansForTableQueryVariables,
+ | 'search'
+ | 'status'
+ | 'totalEntitledQuantityFrom'
+ | 'totalEntitledQuantityTo'
+ | 'dispersionStartDate'
+ | 'dispersionEndDate'
+ | 'isFollowUp'
+>;
+
+interface PeoplePaymentPlansFiltersProps {
+ filter;
+ setFilter: (filter) => void;
+ initialFilter;
+ appliedFilter;
+ setAppliedFilter: (filter) => void;
+}
+export const PeoplePaymentPlansFilters = ({
+ filter,
+ setFilter,
+ initialFilter,
+ appliedFilter,
+ setAppliedFilter,
+}: PeoplePaymentPlansFiltersProps): React.ReactElement => {
+ const { t } = useTranslation();
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ const { handleFilterChange, applyFilterChanges, clearFilter } =
+ createHandleApplyFilterChange(
+ initialFilter,
+ navigate,
+ location,
+ filter,
+ setFilter,
+ appliedFilter,
+ setAppliedFilter,
+ );
+ const handleApplyFilter = (): void => {
+ applyFilterChanges();
+ };
+
+ const handleClearFilter = (): void => {
+ clearFilter();
+ };
+
+ const { data: statusChoicesData } = usePaymentPlanStatusChoicesQueryQuery();
+
+ if (!statusChoicesData) {
+ return null;
+ }
+
+ return (
+
+
+
+ handleFilterChange('search', e.target.value)}
+ />
+
+
+ handleFilterChange('status', e.target.value)}
+ variant="outlined"
+ label={t('Status')}
+ multiple
+ value={filter.status}
+ fullWidth
+ >
+ {statusChoicesData.paymentPlanStatusChoices.map((item) => (
+
+ {item.name}
+
+ ))}
+
+
+
+
+ handleFilterChange('totalEntitledQuantityFrom', e.target.value)
+ }
+ data-cy="filters-total-entitled-quantity-from"
+ />
+
+
+
+ handleFilterChange('totalEntitledQuantityTo', e.target.value)
+ }
+ error={Boolean(
+ filter.totalEntitledQuantityFrom &&
+ filter.totalEntitledQuantityTo &&
+ filter.totalEntitledQuantityFrom >
+ filter.totalEntitledQuantityTo,
+ )}
+ data-cy="filters-total-entitled-quantity-to"
+ />
+
+
+ {
+ if (
+ filter.dispersionEndDate &&
+ moment(date).isAfter(filter.dispersionEndDate)
+ ) {
+ handleFilterChange(
+ 'dispersionStartDate',
+ date ? moment(date).format('YYYY-MM-DD') : '',
+ );
+ handleFilterChange('dispersionEndDate', '');
+ } else {
+ handleFilterChange(
+ 'dispersionStartDate',
+ date ? moment(date).format('YYYY-MM-DD') : '',
+ );
+ }
+ }}
+ value={filter.dispersionStartDate}
+ />
+
+
+
+ handleFilterChange(
+ 'dispersionEndDate',
+ date ? moment(date).format('YYYY-MM-DD') : '',
+ )
+ }
+ value={filter.dispersionEndDate}
+ minDate={filter.dispersionStartDate}
+ minDateMessage={ }
+ />
+
+
+
+ {
+ if (e.target.checked) {
+ handleFilterChange('isFollowUp', true);
+ } else {
+ handleFilterChange('isFollowUp', false);
+ }
+ }}
+ />
+ }
+ label={t('Show only Follow-up plans')}
+ />
+
+
+
+
+ );
+};
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansHeadCells.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansHeadCells.tsx
new file mode 100644
index 0000000000..573e86eaef
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansHeadCells.tsx
@@ -0,0 +1,68 @@
+export const headCells = [
+ {
+ disablePadding: false,
+ label: 'Payment Plan ID',
+ id: 'id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Status',
+ id: 'status',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Target Population',
+ id: 'targetPopulation',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Num. of People',
+ id: 'totalIndividualsCount',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Currency',
+ id: 'currency',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Total Entitled Quantity',
+ id: 'totalEntitledQuantity',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Total Delivered Quantity',
+ id: 'totalDeliveredQuantity',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Total Undelivered Quantity',
+ id: 'totalUndeliveredQuantity',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Dispersion Start Date',
+ id: 'dispersionStartDate',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Dispersion End Date',
+ id: 'dispersionEndDate',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Follow-up Payment Plans',
+ id: 'followup-id',
+ numeric: false,
+ },
+];
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansTable.test.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansTable.test.tsx
new file mode 100644
index 0000000000..23c61fe29a
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansTable.test.tsx
@@ -0,0 +1,58 @@
+import { MockedProvider } from '@apollo/react-testing';
+import { act } from '@testing-library/react';
+import wait from 'waait';
+import { fakeApolloAllPaymentPlansForTable } from '../../../../../fixtures/payments/fakeApolloAllPaymentPlansForTable';
+import { render } from '../../../../testUtils/testUtils';
+import { PeoplePaymentPlansTable } from './PeoplePaymentPlansTable';
+
+describe('containers/tables/payments/PeoplePaymentPlansTable', () => {
+ it('should render with data', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should render loading', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansTable.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansTable.tsx
new file mode 100644
index 0000000000..a1b9cff5e3
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/PeoplePaymentPlansTable.tsx
@@ -0,0 +1,53 @@
+import { ReactElement } from 'react';
+import { useTranslation } from 'react-i18next';
+import {
+ AllPaymentPlansForTableQueryVariables,
+ PaymentPlanNode,
+ useAllPaymentPlansForTableQuery,
+} from '@generated/graphql';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { UniversalTable } from '../../UniversalTable';
+import { PeoplePaymentPlanTableRow } from './PeoplePaymentPlanTableRow';
+import { headCells } from './PeoplePaymentPlansHeadCells';
+
+interface PeoplePaymentPlansTableProps {
+ filter;
+ canViewDetails: boolean;
+}
+
+export const PeoplePaymentPlansTable = ({
+ filter,
+ canViewDetails,
+}: PeoplePaymentPlansTableProps): ReactElement => {
+ const { t } = useTranslation();
+ const { programId, businessArea } = useBaseUrl();
+ const initialVariables: AllPaymentPlansForTableQueryVariables = {
+ businessArea,
+ search: filter.search,
+ status: filter.status,
+ totalEntitledQuantityFrom: filter.totalEntitledQuantityFrom || null,
+ totalEntitledQuantityTo: filter.totalEntitledQuantityTo || null,
+ dispersionStartDate: filter.dispersionStartDate || null,
+ dispersionEndDate: filter.dispersionEndDate || null,
+ isFollowUp: filter.isFollowUp ? true : null,
+ program: programId,
+ };
+
+ return (
+
+ defaultOrderBy="-createdAt"
+ title={t('Payment Plans')}
+ headCells={headCells}
+ query={useAllPaymentPlansForTableQuery}
+ queriedObjectName="allPaymentPlans"
+ initialVariables={initialVariables}
+ renderRow={(row) => (
+
+ )}
+ />
+ );
+};
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/__snapshots__/PeoplePaymentPlansTable.test.tsx.snap b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/__snapshots__/PeoplePaymentPlansTable.test.tsx.snap
new file mode 100644
index 0000000000..b16386856e
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/__snapshots__/PeoplePaymentPlansTable.test.tsx.snap
@@ -0,0 +1,957 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`containers/tables/payments/PeoplePaymentPlansTable should render loading 1`] = `
+
+
+
+
+
+
+
+ Payment Plans
+
+
+
+
+
+
+
+
+
+ Payment Plan ID
+
+
+
+
+
+
+
+ Status
+
+
+
+
+
+
+
+ Target Population
+
+
+
+
+
+
+
+ Num. of People
+
+
+
+
+
+
+
+ Currency
+
+
+
+
+
+
+
+ Total Entitled Quantity
+
+
+
+
+
+
+
+ Total Delivered Quantity
+
+
+
+
+
+
+
+ Total Undelivered Quantity
+
+
+
+
+
+
+
+ Dispersion Start Date
+
+
+
+
+
+
+
+ Dispersion End Date
+
+
+
+
+
+
+
+ Follow-up Payment Plans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`containers/tables/payments/PeoplePaymentPlansTable should render with data 1`] = `
+
+
+
+
+
+
+
+ Payment Plans
+
+
+
+
+
+
+
+
+
+ Payment Plan ID
+
+
+
+
+
+
+
+ Status
+
+
+
+
+
+
+
+ Target Population
+
+
+
+
+
+
+
+ Num. of People
+
+
+
+
+
+
+
+ Currency
+
+
+
+
+
+
+
+ Total Entitled Quantity
+
+
+
+
+
+
+
+ Total Delivered Quantity
+
+
+
+
+
+
+
+ Total Undelivered Quantity
+
+
+
+
+
+
+
+ Dispersion Start Date
+
+
+
+
+
+
+
+ Dispersion End Date
+
+
+
+
+
+
+
+ Follow-up Payment Plans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/index.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/index.tsx
new file mode 100644
index 0000000000..6bd6609127
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentPlansTable/index.tsx
@@ -0,0 +1 @@
+export { PeoplePaymentPlansTable } from './PeoplePaymentPlansTable';
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTable.test.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTable.test.tsx
new file mode 100644
index 0000000000..6ac7d5b327
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTable.test.tsx
@@ -0,0 +1,46 @@
+import { MockedProvider } from '@apollo/react-testing';
+import { act } from '@testing-library/react';
+import wait from 'waait';
+import { fakeApolloAllPaymentsForTable } from '../../../../../fixtures/payments/fakeApolloAllPaymentsForTable';
+import { fakeApolloAllPaymentPlansForTable } from '../../../../../fixtures/payments/fakeApolloAllPaymentPlansForTable';
+import { render } from '../../../../testUtils/testUtils';
+import { PaymentPlanQuery } from '@generated/graphql';
+import { PERMISSIONS } from '../../../../config/permissions';
+import { PeoplePaymentsTable } from './PeoplePaymentsTable';
+
+const paymentPlan = fakeApolloAllPaymentPlansForTable[0].result.data
+ .allPaymentPlans.edges[0].node as PaymentPlanQuery['paymentPlan'];
+
+describe('containers/tables/paymentmodule/PeoplePaymentsTable', () => {
+ it('should render with data', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should render loading', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTable.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTable.tsx
new file mode 100644
index 0000000000..0b3fc44e56
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTable.tsx
@@ -0,0 +1,97 @@
+import { Box, Paper, Typography } from '@mui/material';
+import * as React from 'react';
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { TableWrapper } from '@components/core/TableWrapper';
+import { ImportXlsxPaymentPlanPaymentListPerFsp } from '@components/paymentmodule/PaymentPlanDetails/ImportXlsxPaymentPlanPaymentListPerFsp';
+import {
+ AllPaymentsForTableQuery,
+ AllPaymentsForTableQueryVariables,
+ PaymentPlanQuery,
+ PaymentPlanStatus,
+ useAllPaymentsForTableQuery,
+} from '@generated/graphql';
+import { UniversalTable } from '../../UniversalTable';
+import { PeoplePaymentsTableRow } from './PeoplePaymentsTableRow';
+import { WarningTooltipTable } from './WarningTooltipTable';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { headCells } from './PeoplePaymentsTableHeadCells';
+
+const StyledBox = styled(Box)`
+ background-color: #fff;
+`;
+interface PeoplePaymentsTableProps {
+ businessArea: string;
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ permissions: string[];
+ canViewDetails?: boolean;
+}
+
+export const PeoplePaymentsTable = ({
+ businessArea,
+ paymentPlan,
+ permissions,
+ canViewDetails = false,
+}: PeoplePaymentsTableProps): React.ReactElement => {
+ const { baseUrl } = useBaseUrl();
+ const { t } = useTranslation();
+ const [dialogPayment, setDialogPayment] = useState<
+ AllPaymentsForTableQuery['allPayments']['edges'][number]['node'] | null
+ >();
+ const initialVariables: AllPaymentsForTableQueryVariables = {
+ businessArea,
+ paymentPlanId: paymentPlan.id,
+ };
+
+ return (
+ <>
+
+
+
+
+ {t('Payee List')}
+
+ {(paymentPlan.status === PaymentPlanStatus.Accepted ||
+ paymentPlan.status === PaymentPlanStatus.Finished) && (
+
+ )}
+
+
+ isOnPaper={false}
+ headCells={headCells}
+ query={useAllPaymentsForTableQuery}
+ rowsPerPageOptions={[10, 25, 50]}
+ queriedObjectName="allPayments"
+ initialVariables={initialVariables}
+ defaultOrderBy="createdAt"
+ defaultOrderDirection="desc"
+ renderRow={(row) => (
+ {
+ setDialogPayment(payment);
+ }}
+ />
+ )}
+ />
+
+
+ setDialogPayment(null)}
+ canViewDetails={canViewDetails}
+ baseUrl={baseUrl}
+ />
+ >
+ );
+};
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTableHeadCells.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTableHeadCells.tsx
new file mode 100644
index 0000000000..78dfcdd88d
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTableHeadCells.tsx
@@ -0,0 +1,63 @@
+import { AllPaymentsForTableQuery } from '@generated/graphql';
+import { HeadCell } from '@components/core/Table/EnhancedTableHead';
+
+export const headCells: HeadCell<
+ AllPaymentsForTableQuery['allPayments']['edges'][number]['node']
+>[] = [
+ {
+ disablePadding: false,
+ label: '',
+ id: 'flag',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Payment ID',
+ id: 'unicef_id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Individual ID',
+ id: 'individual__unicef_id',
+ numeric: false,
+ disableSort: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Individual Name',
+ id: 'individual__full_name',
+ numeric: false,
+ disableSort: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Administrative Level 2',
+ id: 'household__admin2__name',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'FSP',
+ id: 'financial_service_provider__name',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Entitlement',
+ id: 'entitlement_quantity_usd',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Delivered Quantity',
+ id: 'delivered_quantity',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Reconciliation',
+ id: 'mark',
+ numeric: false,
+ },
+];
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTableRow.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTableRow.tsx
new file mode 100644
index 0000000000..70dbf723ad
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/PeoplePaymentsTableRow.tsx
@@ -0,0 +1,177 @@
+import TableCell from '@mui/material/TableCell';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import CheckCircleOutlineRoundedIcon from '@mui/icons-material/CheckCircleOutlineRounded';
+import ErrorOutlineRoundedIcon from '@mui/icons-material/ErrorOutlineRounded';
+import { BlackLink } from '@components/core/BlackLink';
+import { ClickableTableRow } from '@components/core/Table/ClickableTableRow';
+import { WarningTooltip } from '@components/core/WarningTooltip';
+import {
+ formatCurrencyWithSymbol,
+ opacityToHex,
+ renderSomethingOrDash,
+} from '@utils/utils';
+import { AllPaymentsForTableQuery, PaymentStatus } from '@generated/graphql';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+export const StyledLink = styled.div`
+ color: #000;
+ text-decoration: underline;
+ cursor: pointer;
+ display: flex;
+ align-content: center;
+`;
+
+const RoutedBox = styled.div`
+ color: ${({ theme }) => theme.hctPalette.red};
+ background-color: ${({ theme }) =>
+ `${theme.hctPalette.red}${opacityToHex(0.15)}`};
+ border-radius: 16px;
+ font-family: Roboto;
+ font-size: 10px;
+ font-weight: 500;
+ letter-spacing: 1.2px;
+ line-height: 16px;
+ padding: ${({ theme }) => theme.spacing(1)};
+ text-align: center;
+ margin-right: 20px;
+`;
+
+const OrangeError = styled(ErrorOutlineRoundedIcon)`
+ color: ${({ theme }) => theme.hctPalette.orange};
+`;
+
+const RedError = styled(ErrorOutlineRoundedIcon)`
+ color: ${({ theme }) => theme.hctPalette.red};
+`;
+
+const GreenCheck = styled(CheckCircleOutlineRoundedIcon)`
+ color: ${({ theme }) => theme.hctPalette.green};
+`;
+
+interface PeoplePaymentsTableRowProps {
+ payment: AllPaymentsForTableQuery['allPayments']['edges'][number]['node'];
+ canViewDetails: boolean;
+ onWarningClick?: (
+ payment: AllPaymentsForTableQuery['allPayments']['edges'][number]['node'],
+ ) => void;
+}
+
+export const PeoplePaymentsTableRow = ({
+ payment,
+ canViewDetails,
+ onWarningClick,
+}: PeoplePaymentsTableRowProps): React.ReactElement => {
+ const { t } = useTranslation();
+ const { baseUrl } = useBaseUrl();
+ const paymentDetailsPath = `/${baseUrl}/payment-module/payments/${payment.id}`;
+
+ const handleDialogWarningOpen = (
+ e: React.SyntheticEvent,
+ ): void => {
+ e.stopPropagation();
+ onWarningClick(payment);
+ };
+
+ const renderDeliveredQuantity = (): React.ReactElement => {
+ const { deliveredQuantity, currency, deliveredQuantityUsd, status } =
+ payment;
+ if (status === PaymentStatus.TransactionErroneous) {
+ return UNSUCCESSFUL ;
+ }
+ if (deliveredQuantity === null) {
+ return <>>;
+ }
+ return (
+ <>
+ {`${formatCurrencyWithSymbol(deliveredQuantity, currency)}
+ (${formatCurrencyWithSymbol(deliveredQuantityUsd, 'USD')})`}
+ >
+ );
+ };
+
+ const renderMark = (): React.ReactElement => {
+ const { deliveredQuantity, entitlementQuantity } = payment;
+
+ if (deliveredQuantity === null) {
+ return <>>;
+ }
+ if (deliveredQuantity === 0) {
+ return ;
+ }
+ if (deliveredQuantity === entitlementQuantity) {
+ return ;
+ }
+ return ;
+ };
+
+ const individual = payment?.household?.individuals?.edges?.[0]?.node;
+ const individualDetailsPath = `/${baseUrl}/population/individuals/${individual?.id}`;
+
+ return (
+
+
+ {(payment.paymentPlanHardConflicted ||
+ payment.paymentPlanSoftConflicted) && (
+ handleDialogWarningOpen(e)}
+ message={t(
+ 'This individual is also included in other Payment Plans. Click this icon to view details.',
+ )}
+ confirmed={payment.paymentPlanHardConflicted}
+ />
+ )}
+
+
+ {canViewDetails ? (
+ {payment.unicefId}
+ ) : (
+ payment.unicefId
+ )}
+
+
+ {canViewDetails ? (
+
+ {individual?.unicefId}
+
+ ) : (
+ individual?.unicefId
+ )}
+
+
+ {canViewDetails ? (
+
+ {individual?.fullName}
+
+ ) : (
+ individual?.fullName
+ )}
+
+
+ {renderSomethingOrDash(payment.household.admin2?.name)}
+
+
+
+ {payment.financialServiceProvider
+ ? payment.financialServiceProvider.name
+ : '-'}
+
+
+ {payment.entitlementQuantity != null && payment.entitlementQuantity >= 0
+ ? `${formatCurrencyWithSymbol(
+ payment.entitlementQuantity,
+ payment.currency,
+ )} (${formatCurrencyWithSymbol(
+ payment.entitlementQuantityUsd,
+ 'USD',
+ )})`
+ : '-'}
+
+
+ {renderDeliveredQuantity()}
+
+ {renderMark()}
+
+ );
+};
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/WarningTooltipTable/WarningTooltipTable.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/WarningTooltipTable/WarningTooltipTable.tsx
new file mode 100644
index 0000000000..070b51e7f1
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/WarningTooltipTable/WarningTooltipTable.tsx
@@ -0,0 +1,168 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ Grid,
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableRow,
+} from '@mui/material';
+import * as React from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import { BlackLink } from '@components/core/BlackLink';
+import { LabelizedField } from '@components/core/LabelizedField';
+import { StatusBox } from '@components/core/StatusBox';
+import { ClickableTableRow } from '@components/core/Table/ClickableTableRow';
+import { UniversalMoment } from '@components/core/UniversalMoment';
+import { paymentPlanStatusToColor } from '@utils/utils';
+import {
+ AllPaymentsForTableQuery,
+ PaymentConflictDataNode,
+ PaymentPlanQuery,
+} from '@generated/graphql';
+import { DialogFooter } from '../../../../dialogs/DialogFooter';
+import { DialogTitleWrapper } from '../../../../dialogs/DialogTitleWrapper';
+
+const StyledTable = styled(Table)`
+ min-width: 100px;
+`;
+const Bold = styled.div`
+ font-weight: bold;
+ padding: 0 5px;
+`;
+
+const GreyBox = styled(Box)`
+ background-color: #f3f3f3;
+`;
+
+interface WarningTooltipTableProps {
+ paymentPlan: PaymentPlanQuery['paymentPlan'];
+ payment: AllPaymentsForTableQuery['allPayments']['edges'][number]['node'];
+ setDialogOpen: (dialogOpen: boolean) => void;
+ baseUrl: string;
+ canViewDetails: boolean;
+}
+
+export function WarningTooltipTable({
+ paymentPlan,
+ payment,
+ setDialogOpen,
+ baseUrl,
+ canViewDetails = false,
+}: WarningTooltipTableProps): React.ReactElement {
+ const { t } = useTranslation();
+ if (!payment) return null;
+ const mappedPaymentPlanRows = (): React.ReactElement[] => {
+ const {
+ paymentPlanSoftConflicted,
+ paymentPlanHardConflicted,
+ paymentPlanHardConflictedData,
+ paymentPlanSoftConflictedData,
+ } = payment;
+
+ const renderRow = (row: PaymentConflictDataNode): React.ReactElement => (
+
+
+ {canViewDetails ? (
+
+ {row.paymentPlanUnicefId}
+
+ ) : (
+ row.paymentPlanUnicefId
+ )}
+
+
+ {row.paymentPlanStartDate}
+
+
+ {row.paymentPlanEndDate}
+
+
+
+
+ {row.paymentUnicefId}
+
+ );
+
+ if (paymentPlanHardConflicted) {
+ return paymentPlanHardConflictedData.map((el) => renderRow(el));
+ }
+ if (paymentPlanSoftConflicted) {
+ return paymentPlanSoftConflictedData.map((el) => renderRow(el));
+ }
+ return [];
+ };
+
+ return (
+ setDialogOpen(false)}
+ scroll="paper"
+ aria-labelledby="form-dialog-title"
+ maxWidth="md"
+ >
+
+ {t('Warning')}
+
+
+
+ {t('Payment Plan ID')} {paymentPlan.unicefId} {' '}
+ {t('details')}:
+
+
+
+
+
+ {paymentPlan.startDate}
+
+
+
+
+ {paymentPlan.endDate}
+
+
+
+
+
+ {t('Household ID')} {payment.household?.unicefId} {' '}
+ {t('is also included in the following Payment Plans')}:
+
+
+
+
+ {t('Payment Plan ID')}
+ {t('Start Date')}
+ {t('End Date')}
+ {t('Status')}
+ {t('Payment ID')}
+
+
+ {mappedPaymentPlanRows()}
+
+
+
+
+ {
+ e.stopPropagation();
+ setDialogOpen(false);
+ }}
+ >
+ {t('CLOSE')}
+
+
+
+
+ );
+}
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/WarningTooltipTable/index.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/WarningTooltipTable/index.tsx
new file mode 100644
index 0000000000..f4bfcdcdcb
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/WarningTooltipTable/index.tsx
@@ -0,0 +1 @@
+export { WarningTooltipTable } from './WarningTooltipTable';
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/__snapshots__/PeoplePaymentsTable.test.tsx.snap b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/__snapshots__/PeoplePaymentsTable.test.tsx.snap
new file mode 100644
index 0000000000..95c2658c85
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/__snapshots__/PeoplePaymentsTable.test.tsx.snap
@@ -0,0 +1,1119 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`containers/tables/paymentmodule/PeoplePaymentsTable should render loading 1`] = `
+
+
+
+
+
+ Payee List
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Payment ID
+
+
+
+
+
+
+
+ Individual ID
+
+
+
+
+ Individual Name
+
+
+
+
+ Administrative Level 2
+
+
+
+
+
+
+
+ FSP
+
+
+
+
+
+
+
+ Entitlement
+
+
+
+
+
+
+
+ Delivered Quantity
+
+
+
+
+
+
+
+ Reconciliation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ RCPT-0060-23-0.000.043
+
+
+
+
+ -
+
+
+ Test FSP 1
+
+
+ -
+
+
+
+
+
+
+
+ RCPT-0060-23-0.000.044
+
+
+
+
+ -
+
+
+ Test FSP 1
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`containers/tables/paymentmodule/PeoplePaymentsTable should render with data 1`] = `
+
+
+
+
+
+ Payee List
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Payment ID
+
+
+
+
+
+
+
+ Individual ID
+
+
+
+
+ Individual Name
+
+
+
+
+ Administrative Level 2
+
+
+
+
+
+
+
+ FSP
+
+
+
+
+
+
+
+ Entitlement
+
+
+
+
+
+
+
+ Delivered Quantity
+
+
+
+
+
+
+
+ Reconciliation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ RCPT-0060-23-0.000.043
+
+
+
+
+ -
+
+
+ Test FSP 1
+
+
+ -
+
+
+
+
+
+
+
+ RCPT-0060-23-0.000.044
+
+
+
+
+ -
+
+
+ Test FSP 1
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/index.tsx b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/index.tsx
new file mode 100644
index 0000000000..f7d7aeb6cf
--- /dev/null
+++ b/frontend/src/containers/tables/paymentmodulePeople/PeoplePaymentsTable/index.tsx
@@ -0,0 +1 @@
+export { PeoplePaymentsTable } from './PeoplePaymentsTable';
diff --git a/frontend/src/containers/tables/payments/CashPlanTable/__snapshots__/CashPlanTable.test.tsx.snap b/frontend/src/containers/tables/payments/CashPlanTable/__snapshots__/CashPlanTable.test.tsx.snap
index 4eee1e9933..b7589e5b83 100644
--- a/frontend/src/containers/tables/payments/CashPlanTable/__snapshots__/CashPlanTable.test.tsx.snap
+++ b/frontend/src/containers/tables/payments/CashPlanTable/__snapshots__/CashPlanTable.test.tsx.snap
@@ -6,7 +6,7 @@ exports[`containers/tables/payments/CashPlanTable should render loading 1`] = `
class="sc-iBdnpw dcYiFg"
>
{
+ it('should render with data', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should render loading', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTable.tsx b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTable.tsx
new file mode 100644
index 0000000000..7786b06b03
--- /dev/null
+++ b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTable.tsx
@@ -0,0 +1,50 @@
+import { ReactElement } from 'react';
+import { useTranslation } from 'react-i18next';
+import {
+ AllPaymentRecordsAndPaymentsQueryVariables,
+ HouseholdNode,
+ PaymentRecordAndPaymentNode,
+ useAllPaymentRecordsAndPaymentsQuery,
+} from '@generated/graphql';
+import { UniversalTable } from '../../UniversalTable';
+import { headCells } from './PaymentRecordAndPaymentPeopleTableHeadCells';
+import { PaymentRecordAndPaymentPeopleTableRow } from './PaymentRecordAndPaymentPeopleTableRow';
+
+interface PaymentRecordHouseholdTableProps {
+ household?: HouseholdNode;
+ openInNewTab?: boolean;
+ businessArea: string;
+ canViewPaymentRecordDetails: boolean;
+}
+export function PaymentRecordAndPaymentPeopleTable({
+ household,
+ openInNewTab = false,
+ businessArea,
+ canViewPaymentRecordDetails,
+}: PaymentRecordHouseholdTableProps): ReactElement {
+ const { t } = useTranslation();
+ const initialVariables = {
+ household: household?.id,
+ businessArea,
+ };
+ return (
+
+ title={t('Payment Records')}
+ headCells={headCells}
+ query={useAllPaymentRecordsAndPaymentsQuery}
+ queriedObjectName="allPaymentRecordsAndPayments"
+ initialVariables={initialVariables}
+ renderRow={(row) => (
+
+ )}
+ />
+ );
+}
diff --git a/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTableHeadCells.tsx b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTableHeadCells.tsx
new file mode 100644
index 0000000000..dda392e1de
--- /dev/null
+++ b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTableHeadCells.tsx
@@ -0,0 +1,35 @@
+import { HeadCell } from '@components/core/Table/EnhancedTableHead';
+import { PaymentRecordAndPaymentNode } from '@generated/graphql';
+
+export const headCells: HeadCell[] = [
+ {
+ disablePadding: false,
+ label: 'Payment ID',
+ id: 'caId',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Status',
+ id: 'status',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Entitlement Quantity',
+ id: 'entitlement_quantity',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Delivered Quantity',
+ id: 'delivered_quantity',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Delivery Date',
+ id: 'delivery_date',
+ numeric: true,
+ },
+];
diff --git a/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTableRow.tsx b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTableRow.tsx
new file mode 100644
index 0000000000..f31d3dff26
--- /dev/null
+++ b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/PaymentRecordAndPaymentPeopleTableRow.tsx
@@ -0,0 +1,80 @@
+import TableCell from '@mui/material/TableCell';
+import * as React from 'react';
+import { useNavigate } from 'react-router-dom';
+import { PaymentRecordAndPaymentNode } from '@generated/graphql';
+import { ClickableTableRow } from '@components/core/Table/ClickableTableRow';
+import { StatusBox } from '@components/core/StatusBox';
+import {
+ formatCurrencyWithSymbol,
+ paymentRecordStatusToColor,
+ paymentStatusDisplayMap,
+} from '@utils/utils';
+import { UniversalMoment } from '@components/core/UniversalMoment';
+import { BlackLink } from '@components/core/BlackLink';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+interface PaymentRecordAndPaymentPeopleTableRowrops {
+ paymentRecordOrPayment: PaymentRecordAndPaymentNode;
+ openInNewTab: boolean;
+ canViewDetails: boolean;
+}
+
+export function PaymentRecordAndPaymentPeopleTableRow({
+ paymentRecordOrPayment,
+ openInNewTab,
+ canViewDetails,
+}: PaymentRecordAndPaymentPeopleTableRowrops): React.ReactElement {
+ const { baseUrl } = useBaseUrl();
+ const navigate = useNavigate();
+ const paymentRecordDetailsPath = `/${baseUrl}/payment-records/${paymentRecordOrPayment.id}`;
+ const paymentDetailsPath = `/${baseUrl}/payment-module/payments/${paymentRecordOrPayment.id}`;
+ const detailsPath =
+ paymentRecordOrPayment.objType === 'PaymentRecord'
+ ? paymentRecordDetailsPath
+ : paymentDetailsPath;
+ const handleClick = (): void => {
+ if (openInNewTab) {
+ window.open(detailsPath);
+ } else {
+ navigate(detailsPath);
+ }
+ };
+ return (
+
+
+ {canViewDetails ? (
+ {paymentRecordOrPayment.caId}
+ ) : (
+ paymentRecordOrPayment.caId
+ )}
+
+
+
+
+
+ {formatCurrencyWithSymbol(
+ paymentRecordOrPayment.entitlementQuantity,
+ paymentRecordOrPayment.currency,
+ )}
+
+
+ {formatCurrencyWithSymbol(
+ paymentRecordOrPayment.deliveredQuantity,
+ paymentRecordOrPayment.currency,
+ )}
+
+
+ {paymentRecordOrPayment.deliveryDate}
+
+
+ );
+}
diff --git a/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/__snapshots__/PaymentRecordAndPaymentPeopleTable.test.tsx.snap b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/__snapshots__/PaymentRecordAndPaymentPeopleTable.test.tsx.snap
new file mode 100644
index 0000000000..72ec5d6cc7
--- /dev/null
+++ b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/__snapshots__/PaymentRecordAndPaymentPeopleTable.test.tsx.snap
@@ -0,0 +1,649 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`containers/tables/payments/PaymentRecordAndPaymentPeopleTable should render loading 1`] = `
+
+
+
+
+
+
+
+ Payment Records
+
+
+
+
+
+
+
+
+
+ Payment ID
+
+
+
+
+
+
+
+ Status
+
+
+
+
+
+
+
+ Entitlement Quantity
+
+
+
+
+
+
+
+ Delivered Quantity
+
+
+
+
+
+
+
+ Delivery Date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`containers/tables/payments/PaymentRecordAndPaymentPeopleTable should render with data 1`] = `
+
+
+
+
+
+
+
+ Payment Records
+
+
+
+
+
+
+
+
+
+ Payment ID
+
+
+
+
+
+
+
+ Status
+
+
+
+
+
+
+
+ Entitlement Quantity
+
+
+
+
+
+
+
+ Delivered Quantity
+
+
+
+
+
+
+
+ Delivery Date
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No results
+
+
+ Try adjusting your search or your filters to find what you are looking for.
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/index.ts b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/index.ts
new file mode 100644
index 0000000000..4f6f1f3fbe
--- /dev/null
+++ b/frontend/src/containers/tables/payments/PaymentRecordAndPaymentPeopleTable/index.ts
@@ -0,0 +1,3 @@
+import { PaymentRecordAndPaymentPeopleTable } from './PaymentRecordAndPaymentPeopleTable';
+
+export { PaymentRecordAndPaymentPeopleTable };
diff --git a/frontend/src/containers/tables/payments/PaymentRecordTable/__snapshots__/PaymentRecordTable.test.tsx.snap b/frontend/src/containers/tables/payments/PaymentRecordTable/__snapshots__/PaymentRecordTable.test.tsx.snap
index 3ae7fee8e5..ecd954e58e 100644
--- a/frontend/src/containers/tables/payments/PaymentRecordTable/__snapshots__/PaymentRecordTable.test.tsx.snap
+++ b/frontend/src/containers/tables/payments/PaymentRecordTable/__snapshots__/PaymentRecordTable.test.tsx.snap
@@ -6,7 +6,7 @@ exports[`containers/tables/payments/PaymentRecordTable should render loading 1`]
class="sc-iBdnpw dcYiFg"
>
[] = [
+ {
+ disablePadding: false,
+ label: 'Payment ID',
+ id: 'payment_record__ca_id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Verification Channel',
+ id: 'payment_verification_plan__verification_channel',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Verification Plan Id',
+ id: 'payment_verification_plan__unicef_id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Verification Status',
+ id: 'status',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Individual (Full name)',
+ id: 'payment_record__head_of_household__family_name',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Individual ID',
+ id: 'payment_record__household__head_of_household__unicef_id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Household Status',
+ id: 'payment_record__household__status',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Delivered',
+ id: 'payment_record__delivered_quantity',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Received',
+ id: 'received_amount',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Phone #',
+ id: 'payment_record__head_of_household__phone_no',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Alt. Phone #',
+ id: 'payment_record__head_of_household__phone_no_alternative',
+ numeric: false,
+ },
+];
diff --git a/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTable.tsx b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTable.tsx
new file mode 100644
index 0000000000..5abd7ff84b
--- /dev/null
+++ b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTable.tsx
@@ -0,0 +1,52 @@
+import { ReactElement } from 'react';
+import { useTranslation } from 'react-i18next';
+import {
+ AllPaymentVerificationsQueryVariables,
+ PaymentVerificationNode,
+ useAllPaymentVerificationsQuery,
+} from '@generated/graphql';
+import { UniversalTable } from '../../../UniversalTable';
+import { headCells } from './PeopleVerificationRecordsHeadCells';
+import { PeopleVerificationRecordsTableRow } from '@containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTableRow';
+
+interface PeopleVerificationRecordsTableProps {
+ paymentPlanId?: string;
+ filter;
+ canViewRecordDetails: boolean;
+ businessArea: string;
+}
+
+export function PeopleVerificationRecordsTable({
+ paymentPlanId,
+ filter,
+ canViewRecordDetails,
+ businessArea,
+}: PeopleVerificationRecordsTableProps): ReactElement {
+ const { t } = useTranslation();
+
+ const initialVariables: AllPaymentVerificationsQueryVariables = {
+ ...filter,
+ businessArea,
+ paymentPlanId,
+ };
+
+ return (
+
+ title={t('Verification Records')}
+ headCells={headCells}
+ query={useAllPaymentVerificationsQuery}
+ queriedObjectName="allPaymentVerifications"
+ initialVariables={initialVariables}
+ renderRow={(paymentVerification) => (
+
+ )}
+ />
+ );
+}
diff --git a/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTableRow.tsx b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTableRow.tsx
new file mode 100644
index 0000000000..c15f8334cf
--- /dev/null
+++ b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTableRow.tsx
@@ -0,0 +1,91 @@
+import { TableRow } from '@mui/material';
+import TableCell from '@mui/material/TableCell';
+import * as React from 'react';
+import { BlackLink } from '@core/BlackLink';
+import { StatusBox } from '@core/StatusBox';
+import { AnonTableCell } from '@core/Table/AnonTableCell';
+import {
+ formatCurrencyWithSymbol,
+ householdStatusToColor,
+ verificationRecordsStatusToColor,
+} from '@utils/utils';
+import { PaymentVerificationNode } from '@generated/graphql';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+interface VerificationRecordsTableRowProps {
+ paymentVerification: PaymentVerificationNode;
+ canViewRecordDetails: boolean;
+ showStatusColumn?: boolean;
+}
+
+export function PeopleVerificationRecordsTableRow({
+ paymentVerification,
+ canViewRecordDetails,
+ showStatusColumn = true,
+}: VerificationRecordsTableRowProps): React.ReactElement {
+ const { baseUrl } = useBaseUrl();
+
+ const nodeType = atob(paymentVerification.payment.id).split(':')[0];
+ const linkPath = `/${baseUrl}/verification/payment${
+ nodeType === 'PaymentRecordNode' ? '-record' : ''
+ }/${paymentVerification.payment.id}`;
+
+ return (
+
+
+ {canViewRecordDetails ? (
+
+ {paymentVerification.payment?.unicefId}
+
+ ) : (
+ {paymentVerification.payment?.unicefId}
+ )}
+
+
+ {paymentVerification.paymentVerificationPlan.verificationChannel}
+
+
+ {paymentVerification.paymentVerificationPlan.unicefId}
+
+
+
+
+
+ {paymentVerification.payment.household.headOfHousehold.fullName}
+
+
+ {paymentVerification.payment.household.headOfHousehold.unicefId}
+
+ {showStatusColumn && (
+
+
+
+ )}
+
+ {formatCurrencyWithSymbol(
+ paymentVerification.payment.deliveredQuantity,
+ paymentVerification.payment.currency,
+ )}
+
+
+ {formatCurrencyWithSymbol(
+ paymentVerification.receivedAmount,
+ paymentVerification.payment.currency,
+ )}
+
+
+ {paymentVerification.payment.household.headOfHousehold.phoneNo}
+
+
+ {paymentVerification.payment.household.headOfHousehold
+ .phoneNoAlternative || '-'}
+
+
+ );
+}
diff --git a/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationsHeadCells.tsx b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationsHeadCells.tsx
new file mode 100644
index 0000000000..5a103be5a8
--- /dev/null
+++ b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationsHeadCells.tsx
@@ -0,0 +1,65 @@
+import { HeadCell } from '@core/Table/EnhancedTableHead';
+import { PaymentVerificationNode } from '@generated/graphql';
+
+export const headCells: HeadCell[] = [
+ {
+ disablePadding: false,
+ label: 'Payment ID',
+ id: 'payment_record__ca_id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Verification Channel',
+ id: 'payment_verification_plan__verification_channel',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Verification Plan Id',
+ id: 'payment_verification_plan__unicef_id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Verification Status',
+ id: 'status',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Individual (Full name)',
+ id: 'payment_record__head_of_household__family_name',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Individual ID',
+ id: 'payment_record__head_of_household__unicef_id',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Delivered',
+ id: 'payment_record__delivered_quantity',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Received',
+ id: 'received_amount',
+ numeric: true,
+ },
+ {
+ disablePadding: false,
+ label: 'Phone #',
+ id: 'payment_record__head_of_household__phone_no',
+ numeric: false,
+ },
+ {
+ disablePadding: false,
+ label: 'Alt. Phone #',
+ id: 'payment_record__head_of_household__phone_no_alternative',
+ numeric: false,
+ },
+];
diff --git a/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationsTable.tsx b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationsTable.tsx
new file mode 100644
index 0000000000..b395d0a587
--- /dev/null
+++ b/frontend/src/containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationsTable.tsx
@@ -0,0 +1,53 @@
+import { ReactElement } from 'react';
+import { useTranslation } from 'react-i18next';
+import {
+ AllPaymentVerificationsQueryVariables,
+ PaymentVerificationNode,
+ useAllPaymentVerificationsQuery,
+} from '@generated/graphql';
+import { UniversalTable } from '../../../UniversalTable';
+import { headCells } from './PeopleVerificationsHeadCells';
+import { PeopleVerificationRecordsTableRow } from '@containers/tables/payments/VerificationRecordsTable/People/PeopleVerificationRecordsTableRow';
+
+interface PeopleVerificationsTableProps {
+ paymentPlanId?: string;
+ filter;
+ canViewRecordDetails: boolean;
+ businessArea: string;
+}
+
+export function PeopleVerificationsTable({
+ paymentPlanId,
+ filter,
+ canViewRecordDetails,
+ businessArea,
+}: PeopleVerificationsTableProps): ReactElement {
+ const { t } = useTranslation();
+
+ const initialVariables: AllPaymentVerificationsQueryVariables = {
+ ...filter,
+ businessArea,
+ paymentPlanId,
+ };
+
+ return (
+
+ title={t('Verification Records')}
+ headCells={headCells}
+ query={useAllPaymentVerificationsQuery}
+ queriedObjectName="allPaymentVerifications"
+ initialVariables={initialVariables}
+ renderRow={(paymentVerification) => (
+
+ )}
+ />
+ );
+}
diff --git a/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationRecordsTable.tsx b/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationRecordsTable.tsx
index 98b8180923..ea2a842230 100644
--- a/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationRecordsTable.tsx
+++ b/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationRecordsTable.tsx
@@ -32,8 +32,8 @@ export function VerificationRecordsTable({
return (
title={t('Verification Records')}
headCells={headCells}
diff --git a/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationsTable.tsx b/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationsTable.tsx
index 3d9269c167..a97a137d82 100644
--- a/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationsTable.tsx
+++ b/frontend/src/containers/tables/payments/VerificationRecordsTable/VerificationsTable.tsx
@@ -26,19 +26,14 @@ export function VerificationsTable({
const initialVariables: AllPaymentVerificationsQueryVariables = {
...filter,
- // TODO: cleanup
- // paymentVerificationPlan: filter.cashPlanPaymentVerification,
- // search: filter.search,
- // status: filter.status,
- // verificationChannel: filter.verificationChannel,
businessArea,
paymentPlanId,
};
return (
title={t('Verification Records')}
headCells={headCells}
diff --git a/frontend/src/containers/tables/payments/VerificationRecordsTable/__snapshots__/VerificationRecordsTable.test.tsx.snap b/frontend/src/containers/tables/payments/VerificationRecordsTable/__snapshots__/VerificationRecordsTable.test.tsx.snap
index 7b92892143..14a3dd1029 100644
--- a/frontend/src/containers/tables/payments/VerificationRecordsTable/__snapshots__/VerificationRecordsTable.test.tsx.snap
+++ b/frontend/src/containers/tables/payments/VerificationRecordsTable/__snapshots__/VerificationRecordsTable.test.tsx.snap
@@ -6,7 +6,7 @@ exports[`containers/tables/payments/VerificationRecordsTable should render loadi
class="sc-iBdnpw dcYiFg"
>
{
businessArea="afghanistan"
filter={initialFilter}
canViewDetails
- choicesData={fakeHouseholdChoices}
/>
,
);
@@ -52,7 +50,6 @@ describe('containers/tables/population/PeopleListTable', () => {
businessArea="afghanistan"
filter={initialFilter}
canViewDetails
- choicesData={fakeHouseholdChoices}
/>
,
);
diff --git a/frontend/src/containers/tables/people/PeopleListTable/PeopleListTable.tsx b/frontend/src/containers/tables/people/PeopleListTable/PeopleListTable.tsx
index 4a24d46fe4..194b0a4f8f 100644
--- a/frontend/src/containers/tables/people/PeopleListTable/PeopleListTable.tsx
+++ b/frontend/src/containers/tables/people/PeopleListTable/PeopleListTable.tsx
@@ -3,7 +3,6 @@ import { useTranslation } from 'react-i18next';
import {
AllIndividualsForPopulationTableQueryVariables,
AllIndividualsQueryVariables,
- HouseholdChoiceDataQuery,
IndividualNode,
useAllIndividualsForPopulationTableQuery,
} from '@generated/graphql';
@@ -18,14 +17,12 @@ interface PeopleListTableProps {
filter;
businessArea: string;
canViewDetails: boolean;
- choicesData: HouseholdChoiceDataQuery;
}
export function PeopleListTable({
businessArea,
filter,
canViewDetails,
- choicesData,
}: PeopleListTableProps): React.ReactElement {
const { t } = useTranslation();
const { programId } = useBaseUrl();
diff --git a/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableHeadCells.tsx b/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableHeadCells.tsx
index 4b772a94dc..5b372b6e97 100644
--- a/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableHeadCells.tsx
+++ b/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableHeadCells.tsx
@@ -23,6 +23,13 @@ export const headCells: HeadCell
[] = [
numeric: false,
dataCy: 'individual-name',
},
+ {
+ disablePadding: false,
+ label: 'Type',
+ id: '-birthDate',
+ numeric: true,
+ dataCy: 'individual-age',
+ },
{
disablePadding: false,
label: 'Age',
diff --git a/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableRow.tsx b/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableRow.tsx
index 6fc190221d..bb5ddcd16f 100644
--- a/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableRow.tsx
+++ b/frontend/src/containers/tables/people/PeopleListTable/PeopleListTableRow.tsx
@@ -1,7 +1,8 @@
import TableCell from '@mui/material/TableCell';
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
-import { IndividualNode } from '@generated/graphql';
+import { useTranslation } from 'react-i18next';
+import { IndividualNode, IndividualRelationship } from '@generated/graphql';
import { BlackLink } from '@components/core/BlackLink';
import { AnonTableCell } from '@components/core/Table/AnonTableCell';
import { ClickableTableRow } from '@components/core/Table/ClickableTableRow';
@@ -20,6 +21,7 @@ export const PeopleListTableRow = ({
}: IndividualsListTableRowProps): React.ReactElement => {
const navigate = useNavigate();
const { baseUrl } = useBaseUrl();
+ const { t } = useTranslation();
const individualDetailsPath = `/${baseUrl}/population/people/${individual.id}`;
const handleClick = (): void => {
@@ -41,6 +43,11 @@ export const PeopleListTableRow = ({
{individual.unicefId}
{individual.fullName}
+
+ {individual.relationship === IndividualRelationship.Head
+ ? t('Beneficiary')
+ : t('Non-beneficiary')}
+
{individual.age}
{sexToCapitalize(individual.sex)}
{individual.household?.admin2?.name}
diff --git a/frontend/src/containers/tables/people/PeopleListTable/__snapshots__/PeopleListTable.test.tsx.snap b/frontend/src/containers/tables/people/PeopleListTable/__snapshots__/PeopleListTable.test.tsx.snap
index 372267b604..1a7d544dde 100644
--- a/frontend/src/containers/tables/people/PeopleListTable/__snapshots__/PeopleListTable.test.tsx.snap
+++ b/frontend/src/containers/tables/people/PeopleListTable/__snapshots__/PeopleListTable.test.tsx.snap
@@ -9,7 +9,7 @@ exports[`containers/tables/population/PeopleListTable should render loading 1`]
class="sc-fsYfdN iJWUfq"
>
+
+
+ Type
+
+
{
- navigate(importDetailsForPeoplePath);
+ navigate(importDetailsForPeoplePath);
};
const renderImportedBy = (): string => {
if (registrationDataImport?.importedBy) {
diff --git a/frontend/src/containers/tables/rdi/RegistrationDataImportForPeopleTable/__snapshots__/RegistrationDataImportForPeopleTable.test.tsx.snap b/frontend/src/containers/tables/rdi/RegistrationDataImportForPeopleTable/__snapshots__/RegistrationDataImportForPeopleTable.test.tsx.snap
index c89bd3b873..8f2b67e0fc 100644
--- a/frontend/src/containers/tables/rdi/RegistrationDataImportForPeopleTable/__snapshots__/RegistrationDataImportForPeopleTable.test.tsx.snap
+++ b/frontend/src/containers/tables/rdi/RegistrationDataImportForPeopleTable/__snapshots__/RegistrationDataImportForPeopleTable.test.tsx.snap
@@ -9,7 +9,7 @@ exports[`containers/tables/rdi/RegistrationDataImportTable should render loading
class="sc-fsYfdN iJWUfq"
>
Test Import
diff --git a/frontend/src/containers/tables/rdi/RegistrationDataImportTable/__snapshots__/RegistrationDataImportTable.test.tsx.snap b/frontend/src/containers/tables/rdi/RegistrationDataImportTable/__snapshots__/RegistrationDataImportTable.test.tsx.snap
index 3a628e9434..032b777cc7 100644
--- a/frontend/src/containers/tables/rdi/RegistrationDataImportTable/__snapshots__/RegistrationDataImportTable.test.tsx.snap
+++ b/frontend/src/containers/tables/rdi/RegistrationDataImportTable/__snapshots__/RegistrationDataImportTable.test.tsx.snap
@@ -9,7 +9,7 @@ exports[`containers/tables/rdi/RegistrationDataImportTable should render loading
class="sc-fsYfdN iJWUfq"
>
{
+ const initialFilter = {
+ name: '',
+ status: '',
+ totalHouseholdsCountMin: null,
+ totalHouseholdsCountMax: null,
+ createdAtRangeMin: '',
+ createdAtRangeMax: '',
+ };
+
+ it('should render with data', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+ await act(() => wait(0)); // wait for response
+
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should render loading', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTable.tsx b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTable.tsx
new file mode 100644
index 0000000000..cc1b154c43
--- /dev/null
+++ b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTable.tsx
@@ -0,0 +1,88 @@
+import { ReactElement } from 'react';
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import {
+ AllTargetPopulationsQueryVariables,
+ TargetPopulationNode,
+ useAllTargetPopulationsQuery,
+} from '@generated/graphql';
+import { TableWrapper } from '@components/core/TableWrapper';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+import { dateToIsoString } from '@utils/utils';
+import { UniversalTable } from '../../UniversalTable';
+import { headCells } from './TargetPopulationForPeopleTableHeadCells';
+import { TargetPopulationForPeopleTableRow } from './TargetPopulationForPeopleTableRow';
+
+interface TargetPopulationProps {
+ filter;
+ canViewDetails: boolean;
+ enableRadioButton?: boolean;
+ selectedTargetPopulation?;
+ handleChange?;
+ noTableStyling?;
+ noTitle?;
+}
+
+const NoTableStyling = styled.div`
+ .MuiPaper-elevation1 {
+ box-shadow: none;
+ padding: 0 !important;
+ }
+`;
+
+export function TargetPopulationForPeopleTable({
+ filter,
+ canViewDetails,
+ enableRadioButton,
+ selectedTargetPopulation,
+ handleChange,
+ noTableStyling,
+ noTitle,
+}: TargetPopulationProps): ReactElement {
+ const { t } = useTranslation();
+ const { businessArea, programId } = useBaseUrl();
+ const initialVariables: AllTargetPopulationsQueryVariables = {
+ name: filter.name,
+ totalHouseholdsCountMin: filter.totalHouseholdsCountMin || null,
+ totalHouseholdsCountMax: filter.totalHouseholdsCountMax || null,
+ status: filter.status,
+ businessArea,
+ program: [programId],
+ createdAtRange: JSON.stringify({
+ min: dateToIsoString(filter.createdAtRangeMin, 'startOfDay'),
+ max: dateToIsoString(filter.createdAtRangeMax, 'endOfDay'),
+ }),
+ };
+ const handleRadioChange = (id: string): void => {
+ handleChange(id);
+ };
+
+ const renderTable = (): React.ReactElement => (
+
+
+ title={noTitle ? null : t('Target Populations')}
+ headCells={enableRadioButton ? headCells : headCells.slice(1)}
+ rowsPerPageOptions={[10, 15, 20]}
+ query={useAllTargetPopulationsQuery}
+ queriedObjectName="allTargetPopulation"
+ defaultOrderBy="createdAt"
+ defaultOrderDirection="desc"
+ initialVariables={initialVariables}
+ renderRow={(row) => (
+
+ )}
+ />
+
+ );
+ return noTableStyling ? (
+
{renderTable()}
+ ) : (
+ renderTable()
+ );
+}
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTableHeadCells.tsx b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTableHeadCells.tsx
new file mode 100644
index 0000000000..74241f621b
--- /dev/null
+++ b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTableHeadCells.tsx
@@ -0,0 +1,54 @@
+import { HeadCell } from '@components/core/Table/EnhancedTableHead';
+import { TargetPopulationNode } from '@generated/graphql';
+
+export const headCells: HeadCell
[] = [
+ {
+ disablePadding: false,
+ label: '',
+ id: 'radio',
+ numeric: false,
+ dataCy: 'radio-id',
+ },
+ {
+ disablePadding: false,
+ label: 'Name',
+ id: 'name',
+ numeric: false,
+ dataCy: 'name',
+ },
+ {
+ disablePadding: false,
+ label: 'Status',
+ id: 'status',
+ numeric: false,
+ dataCy: 'status',
+ },
+ {
+ disablePadding: false,
+ label: 'Num. of People',
+ id: 'total_households_count',
+ numeric: false,
+ dataCy: 'num-of-households',
+ },
+ {
+ disablePadding: false,
+ label: 'Date Created',
+ id: 'created_at',
+ numeric: false,
+ dataCy: 'date-created',
+ },
+ {
+ disablePadding: false,
+ label: 'Last Edited',
+ id: 'updated_at',
+ numeric: false,
+ dataCy: 'last-edited',
+ },
+ {
+ disablePadding: false,
+ label: 'Created by',
+ id: 'created_by',
+ numeric: false,
+ dataCy: 'created-by',
+ },
+];
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTableRow.tsx b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTableRow.tsx
new file mode 100644
index 0000000000..dbd643f24b
--- /dev/null
+++ b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/TargetPopulationForPeopleTableRow.tsx
@@ -0,0 +1,87 @@
+import TableCell from '@mui/material/TableCell';
+import * as React from 'react';
+import { useNavigate } from 'react-router-dom';
+import { Radio } from '@mui/material';
+import { BlackLink } from '@components/core/BlackLink';
+import { StatusBox } from '@components/core/StatusBox';
+import { ClickableTableRow } from '@components/core/Table/ClickableTableRow';
+import { UniversalMoment } from '@components/core/UniversalMoment';
+import { targetPopulationStatusToColor } from '@utils/utils';
+import { TargetPopulationNode } from '@generated/graphql';
+import { useBaseUrl } from '@hooks/useBaseUrl';
+
+interface TargetPopulationTableRowProps {
+ targetPopulation: TargetPopulationNode;
+ canViewDetails: boolean;
+ selectedTargetPopulation?;
+ radioChangeHandler?: (id: string) => void;
+}
+
+export function TargetPopulationForPeopleTableRow({
+ targetPopulation,
+ canViewDetails,
+ radioChangeHandler,
+ selectedTargetPopulation,
+}: TargetPopulationTableRowProps): React.ReactElement {
+ const navigate = useNavigate();
+ const { baseUrl } = useBaseUrl();
+ const targetPopulationDetailsPath = `/${baseUrl}/target-population/${targetPopulation.id}`;
+ const handleClick = (): void => {
+ if (radioChangeHandler !== undefined) {
+ radioChangeHandler(targetPopulation.id);
+ } else {
+ navigate(targetPopulationDetailsPath);
+ }
+ };
+ return (
+
+ {radioChangeHandler && (
+
+ {
+ radioChangeHandler(targetPopulation.id);
+ }}
+ value={targetPopulation.id}
+ name="radio-button-household"
+ inputProps={{ 'aria-label': targetPopulation.id }}
+ />
+
+ )}
+
+ {canViewDetails ? (
+
+ {targetPopulation.name}
+
+ ) : (
+ targetPopulation.name
+ )}
+
+
+
+
+
+ {targetPopulation.totalHouseholdsCount || '0'}
+
+
+ {targetPopulation.createdAt}
+
+
+ {targetPopulation.updatedAt}
+
+
+ {targetPopulation.createdBy?.firstName}{' '}
+ {targetPopulation.createdBy?.lastName}
+
+
+ );
+}
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/__snapshots__/TargetPopulationForPeopleTable.test.tsx.snap b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/__snapshots__/TargetPopulationForPeopleTable.test.tsx.snap
new file mode 100644
index 0000000000..fa52f8cf62
--- /dev/null
+++ b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/__snapshots__/TargetPopulationForPeopleTable.test.tsx.snap
@@ -0,0 +1,1118 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`containers/tables/targeting/TargetPopulation/TargetPopulationTable should render loading 1`] = `
+
+
+
+
+
+
+
+
+ Target Populations
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+ Status
+
+
+
+
+
+
+
+ Num. of People
+
+
+
+
+
+
+
+ Date Created
+
+
+
+
+
+
+
+ Last Edited
+
+
+
+
+
+
+
+ Created by
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`containers/tables/targeting/TargetPopulation/TargetPopulationTable should render with data 1`] = `
+
+
+
+
+
+
+
+
+ Target Populations
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+ Status
+
+
+
+
+
+
+
+ Num. of People
+
+
+
+
+
+
+
+ Date Created
+
+
+
+
+
+
+
+ Last Edited
+
+
+
+
+
+
+
+ Created by
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Our ball many investment look like.
+
+
+
+
+
+ READY FOR CASH ASSIST
+
+
+
+
+ 0
+
+
+
+ 29 Sep 2023
+
+
+
+
+ 29 Sep 2023
+
+
+
+ Mary
+
+ Reyes
+
+
+
+
+
+ Less road structure audience those modern.
+
+
+
+
+
+ READY FOR CASH ASSIST
+
+
+
+
+ 0
+
+
+
+ 29 Sep 2023
+
+
+
+
+ 29 Sep 2023
+
+
+
+ Elizabeth
+
+ Coleman
+
+
+
+
+
+ Score visit write ask whole myself.
+
+
+
+
+
+ READY FOR CASH ASSIST
+
+
+
+
+ 0
+
+
+
+ 29 Sep 2023
+
+
+
+
+ 29 Sep 2023
+
+
+
+ Jennifer
+
+ Bailey
+
+
+
+
+
+ Test Target Population
+
+
+
+
+
+
+ 2
+
+
+
+ 29 Sep 2023
+
+
+
+
+ 29 Sep 2023
+
+
+
+ Root
+
+ Rootkowski
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/index.tsx b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/index.tsx
new file mode 100644
index 0000000000..17f34f6460
--- /dev/null
+++ b/frontend/src/containers/tables/targeting/TargetPopulationForPeopleTable/index.tsx
@@ -0,0 +1,3 @@
+import { TargetPopulationForPeopleTable } from './TargetPopulationForPeopleTable';
+
+export { TargetPopulationForPeopleTable };
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationHouseholdTable/TargetPopulationHouseholdRow.tsx b/frontend/src/containers/tables/targeting/TargetPopulationHouseholdTable/TargetPopulationHouseholdRow.tsx
index 8ba33d2896..bc71eab85f 100644
--- a/frontend/src/containers/tables/targeting/TargetPopulationHouseholdTable/TargetPopulationHouseholdRow.tsx
+++ b/frontend/src/containers/tables/targeting/TargetPopulationHouseholdTable/TargetPopulationHouseholdRow.tsx
@@ -29,6 +29,7 @@ export function TargetPopulationHouseholdTableRow({
hover
onClick={canViewDetails ? handleClick : undefined}
role="checkbox"
+ data-cy="target-population-household-row"
key={household.id}
>
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationPeopleTable/TargetPopulationPeopleRow.tsx b/frontend/src/containers/tables/targeting/TargetPopulationPeopleTable/TargetPopulationPeopleRow.tsx
index a8b22d82d5..876a00c901 100644
--- a/frontend/src/containers/tables/targeting/TargetPopulationPeopleTable/TargetPopulationPeopleRow.tsx
+++ b/frontend/src/containers/tables/targeting/TargetPopulationPeopleTable/TargetPopulationPeopleRow.tsx
@@ -29,6 +29,7 @@ export function TargetPopulationPeopleTableRow({
hover
onClick={canViewDetails ? handleClick : undefined}
role="checkbox"
+ data-cy="target-population-people-row"
key={household.id}
>
diff --git a/frontend/src/containers/tables/targeting/TargetPopulationTable/__snapshots__/TargetPopulationTable.test.tsx.snap b/frontend/src/containers/tables/targeting/TargetPopulationTable/__snapshots__/TargetPopulationTable.test.tsx.snap
index a58f246254..9f7f08ed4d 100644
--- a/frontend/src/containers/tables/targeting/TargetPopulationTable/__snapshots__/TargetPopulationTable.test.tsx.snap
+++ b/frontend/src/containers/tables/targeting/TargetPopulationTable/__snapshots__/TargetPopulationTable.test.tsx.snap
@@ -9,7 +9,7 @@ exports[`containers/tables/targeting/TargetPopulation/TargetPopulationTable shou
class="sc-fsYfdN iJWUfq"
>
void;
+ isActiveProgram: boolean;
+ isSocialDctType: boolean;
+ isStandardDctType: boolean;
+};
+
export const ProgramContext = createContext(null);
export function ProgramProvider({
@@ -54,5 +66,5 @@ export function ProgramProvider({
);
}
-// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
-export const useProgramContext = () => useContext(ProgramContext);
+export const useProgramContext = (): ProgramContent =>
+ useContext(ProgramContext);
diff --git a/frontend/src/shared/Formik/FormikSelectField/FormikSelectField.tsx b/frontend/src/shared/Formik/FormikSelectField/FormikSelectField.tsx
index b4fb0b0938..df289278b5 100644
--- a/frontend/src/shared/Formik/FormikSelectField/FormikSelectField.tsx
+++ b/frontend/src/shared/Formik/FormikSelectField/FormikSelectField.tsx
@@ -70,6 +70,23 @@ export function FormikSelectField({
id={`textField-${field.name}`}
error={isInvalid}
renderValue={(selected) => {
+ if (Array.isArray(selected)) {
+ return selected
+ .map((s) => {
+ const selectedItem = otherProps.choices.find(
+ (choice) =>
+ choice.value === s ||
+ choice.name === s ||
+ choice.label === s,
+ );
+ return selectedItem
+ ? selectedItem.labelEn ||
+ selectedItem.name ||
+ selectedItem.label
+ : s;
+ })
+ .join(', ');
+ }
const selectedItem = otherProps.choices.find(
(choice) => choice.value === selected || choice.name === selected,
);
@@ -108,7 +125,7 @@ export function FormikSelectField({
{each.description ? (
diff --git a/frontend/src/testUtils/testUtils.tsx b/frontend/src/testUtils/testUtils.tsx
index 71a10f6efd..18d14756f5 100644
--- a/frontend/src/testUtils/testUtils.tsx
+++ b/frontend/src/testUtils/testUtils.tsx
@@ -59,7 +59,22 @@ export class ApolloLoadingLink extends MockLink {
}
export const fakeContextProgram = {
- id: 1,
- name: 'someName',
- status: ProgramStatus.Active,
+ selectedProgram: {
+ id: '1',
+ name: 'someName',
+ status: ProgramStatus.Active,
+ dataCollectingType: {
+ id: '1',
+ householdFiltersAvailable: true,
+ individualFiltersAvailable: true,
+ label: 'data collecting type',
+ code: '123',
+ type: 'full',
+ children: null,
+ },
+ },
+ setSelectedProgram: () => {},
+ isActiveProgram: true,
+ isSocialDctType: false,
+ isStandardDctType: true,
};
diff --git a/frontend/src/utils/en.json b/frontend/src/utils/en.json
index 6302512b9a..90f59a1dce 100644
--- a/frontend/src/utils/en.json
+++ b/frontend/src/utils/en.json
@@ -873,5 +873,6 @@
"Action completed successfully": "Action completed successfully",
"Sent for Approval by": "Sent for Approval by",
"Approved by": "Approved by",
- "Authorized by": "Authorized by"
+ "Authorized by": "Authorized by",
+ "This individual is also included in other Payment Plans. Click this icon to view details.": "This individual is also included in other Payment Plans. Click this icon to view details."
}