Skip to content

Commit

Permalink
Merge pull request #4134 from unicef/189537/PDU-targeting
Browse files Browse the repository at this point in the history
PDU Targeting
  • Loading branch information
pkujawa authored Aug 24, 2024
2 parents 9b0c985 + 26a6b9c commit 6a528fa
Show file tree
Hide file tree
Showing 76 changed files with 3,356 additions and 973 deletions.
18 changes: 18 additions & 0 deletions backend/hct_mis_api/apps/core/migrations/0085_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.25 on 2024-08-19 15:45

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0084_migration'),
]

operations = [
migrations.AlterField(
model_name='periodicfielddata',
name='subtype',
field=models.CharField(choices=[('DATE', 'Date'), ('DECIMAL', 'Number'), ('STRING', 'Text'), ('BOOL', 'Boolean (true/false)')], max_length=16),
),
]
4 changes: 2 additions & 2 deletions backend/hct_mis_api/apps/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,13 @@ class PeriodicFieldData(models.Model):
STRING = "STRING"
DECIMAL = "DECIMAL"
DATE = "DATE"
BOOLEAN = "BOOLEAN"
BOOL = "BOOL"

TYPE_CHOICES = Choices(
(DATE, _("Date")),
(DECIMAL, _("Number")),
(STRING, _("Text")),
(BOOLEAN, _("Boolean (true/false)")),
(BOOL, _("Boolean (true/false)")),
)

subtype = models.CharField(max_length=16, choices=TYPE_CHOICES)
Expand Down
4 changes: 3 additions & 1 deletion backend/hct_mis_api/apps/core/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ def get_fields_attr_generators(
flex_field: Optional[bool] = None, business_area_slug: Optional[str] = None, program_id: Optional[str] = None
) -> Generator:
if flex_field is not False:
yield from FlexibleAttribute.objects.exclude(type=FlexibleAttribute.PDU).order_by("created_at")
yield from FlexibleAttribute.objects.filter(Q(program__isnull=True) | Q(program__id=program_id)).order_by(
"created_at"
)
if flex_field is not True:
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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
},
{
'displayName': 'Boolean (true/false)',
'value': 'BOOLEAN'
'value': 'BOOL'
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion backend/hct_mis_api/apps/core/tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def setUpTestData(cls) -> None:
# Create a PDU field for a different program
other_program = ProgramFactory(business_area=cls.business_area, status=Program.ACTIVE, name="Other Program")
pdu_data_different_program = PeriodicFieldDataFactory(
subtype=PeriodicFieldData.BOOLEAN,
subtype=PeriodicFieldData.BOOL,
number_of_rounds=1,
rounds_names=["Round 1"],
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def test_receiving_reconciliations_from_fsp(self, mock_get_exchange_rate: Any) -
"comparisonMethod": "EQUALS",
"arguments": ["True"],
"fieldName": "consent",
"isFlexField": False,
"flexFieldClassification": "NOT_FLEX_FIELD",
}
],
"individualsFiltersBlocks": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def setUpTestData(cls) -> None:
{
"comparisonMethod": "EQUALS",
"fieldName": "consent",
"isFlexField": False,
"flexFieldClassification": "NOT_FLEX_FIELD",
"arguments": [True],
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def update_pdu_flex_attributes(self) -> None:
self.delete_pdu_flex_attributes(flexible_attribute_ids_to_preserve=flexible_attribute_ids_to_preserve)

def update_pdu_flex_attributes_in_program_update(self) -> None:
if self.program.registration_imports.exists():
if self.program.registration_imports.exists() or self.program.targetpopulation_set.exists():
self.increase_pdu_rounds_for_program_with_rdi()
else:
self.update_pdu_flex_attributes()
Expand Down Expand Up @@ -116,6 +116,6 @@ def _validate_pdu_data_for_program_with_rdi(pdu_data_object: PeriodicFieldData,
new_number_of_rounds = pdu_data["number_of_rounds"]
new_rounds_names = pdu_data["rounds_names"]
if new_number_of_rounds <= current_number_of_rounds:
raise GraphQLError("It is not possible to decrease the number of rounds for a Program with RDI")
raise GraphQLError("It is not possible to decrease the number of rounds for a Program with RDI or TP")
if current_rounds_names != new_rounds_names[:current_number_of_rounds]:
raise GraphQLError("It is not possible to change the names of existing rounds for a Program with RDI")
raise GraphQLError("It is not possible to change the names of existing rounds for a Program with RDI or TP")
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def _get_form_field_for_value(self, flexible_attribute: FlexibleAttribute) -> fo
return forms.CharField(required=False)
elif flexible_attribute.pdu_data.subtype == PeriodicFieldData.DECIMAL:
return forms.FloatField(required=False)
elif flexible_attribute.pdu_data.subtype == PeriodicFieldData.BOOLEAN:
elif flexible_attribute.pdu_data.subtype == PeriodicFieldData.BOOL:
return StrictBooleanField(required=False)
elif flexible_attribute.pdu_data.subtype == PeriodicFieldData.DATE:
return forms.DateField(required=False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def setUpTestData(cls) -> None:
)
cls.boolean_attribute = create_pdu_flexible_attribute(
label="Boolean Attribute",
subtype=PeriodicFieldData.BOOLEAN,
subtype=PeriodicFieldData.BOOL,
number_of_rounds=1,
rounds_names=["May"],
program=cls.program,
Expand Down
4 changes: 3 additions & 1 deletion backend/hct_mis_api/apps/periodic_data_update/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ def field_label_to_field_name(input_string: str) -> str:
"""

input_string = input_string.replace(" ", "_")
input_string = re.sub(r"[^\w\s-]", "", input_string)
input_string = re.sub(r"[^\w]", "", input_string)
input_string = re.sub(r"__+", "_", input_string)
input_string = input_string.strip("_")
return input_string.lower()


Expand Down
5 changes: 5 additions & 0 deletions backend/hct_mis_api/apps/program/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class ProgramNode(BaseNodePermissionMixin, AdminUrlNodeMixin, DjangoObjectType):
partners = graphene.List(PartnerNode)
is_social_worker_program = graphene.Boolean()
pdu_fields = graphene.List(PeriodicFieldNode)
target_populations_count = graphene.Int()
cycles = DjangoFilterConnectionField(ProgramCycleNode, filterset_class=ProgramCycleFilter)

class Meta:
Expand Down Expand Up @@ -151,6 +152,10 @@ def resolve_is_social_worker_program(program: Program, info: Any, **kwargs: Any)
def resolve_pdu_fields(program: Program, info: Any, **kwargs: Any) -> QuerySet:
return program.pdu_fields.order_by("name")

@staticmethod
def resolve_target_populations_count(program: Program, info: Any, **kwargs: Any) -> int:
return program.targetpopulation_set.count()


class CashPlanNode(BaseNodePermissionMixin, DjangoObjectType):
permission_classes: Tuple[Type[BasePermission], ...] = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@
'Round 3C',
'Round 4D'
],
'subtype': 'BOOLEAN'
'subtype': 'BOOL'
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@
'Round 3C',
'Round 4D'
],
'subtype': 'BOOLEAN'
'subtype': 'BOOL'
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@
'Round A',
'Round B'
],
'subtype': 'BOOLEAN'
'subtype': 'BOOL'
}
}
],
'status': 'ACTIVE'
'status': 'ACTIVE',
'targetPopulationsCount': 1
}
}
}
Expand Down
Loading

0 comments on commit 6a528fa

Please sign in to comment.