Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MERGING RELEASE branches #90

Merged
merged 15 commits into from
Oct 18, 2023
40 changes: 12 additions & 28 deletions insuree/gql_mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import pathlib
import base64
import graphene

from insuree.apps import InsureeConfig
from insuree.services import validate_insuree_number, InsureeService, FamilyService, InsureePolicyService

from .apps import InsureeConfig
from core.schema import OpenIMISMutation
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError, PermissionDenied
Expand All @@ -33,8 +32,7 @@ class InsureeBase:
chf_id = graphene.String(max_length=12, required=False)
last_name = graphene.String(max_length=100, required=True)
other_names = graphene.String(max_length=100, required=True)
gender_id = graphene.String(max_length=1, required=True,
description="Was mandatory in Legacy but not in modular")
gender_id = graphene.String(max_length=1, required=True)
dob = graphene.Date(required=True)
head = graphene.Boolean(required=False)
marital = graphene.String(max_length=1, required=False)
Expand All @@ -56,6 +54,9 @@ class InsureeBase:
health_facility_id = graphene.Int(required=False)
offline = graphene.Boolean(required=False)
json_ext = graphene.types.json.JSONString(required=False)
status = graphene.String(required=True)
status_reason = graphene.String(required=False)
status_date = graphene.Date(required=False)


class CreateInsureeInputType(InsureeBase, OpenIMISMutation.Input):
Expand Down Expand Up @@ -100,23 +101,6 @@ class UpdateFamilyInputType(FamilyInputType):
pass


def create_file(date, insuree_id, photo_bin):
date_iso = date.isoformat()
root = InsureeConfig.insuree_photos_root_path
file_dir = '%s/%s/%s/%s' % (
date_iso[0:4],
date_iso[5:7],
date_iso[8:10],
insuree_id
)
file_name = uuid.uuid4()
file_path = '%s/%s' % (file_dir, file_name)
pathlib.Path('%s/%s' % (root, file_dir)).mkdir(parents=True, exist_ok=True)
f = open('%s/%s' % (root, file_path), "xb")
f.write(base64.b64decode(photo_bin))
f.close()
return file_dir, file_name


def update_or_create_insuree(data, user):
data.pop('client_mutation_id', None)
Expand Down Expand Up @@ -215,7 +199,7 @@ def async_mutate(cls, user, **data):
for family_uuid in data["uuids"]:
family = Family.objects \
.prefetch_related('members') \
.filter(uuid=family_uuid) \
.filter(uuid__iexact=family_uuid) \
.first()
if family is None:
errors.append({
Expand Down Expand Up @@ -319,7 +303,7 @@ def async_mutate(cls, user, **data):
for insuree_uuid in data["uuids"]:
insuree = Insuree.objects \
.prefetch_related('family') \
.filter(uuid=insuree_uuid) \
.filter(uuid__iexact=insuree_uuid) \
.first()
if insuree is None:
errors.append({
Expand Down Expand Up @@ -361,7 +345,7 @@ def async_mutate(cls, user, **data):
for insuree_uuid in data["uuids"]:
insuree = Insuree.objects \
.prefetch_related('family') \
.filter(uuid=insuree_uuid) \
.filter(uuid__iexact=insuree_uuid) \
.first()
if insuree is None:
errors += {
Expand Down Expand Up @@ -402,8 +386,8 @@ def async_mutate(cls, user, **data):
if not user.has_perms(InsureeConfig.gql_mutation_update_families_perms):
raise PermissionDenied(_("unauthorized"))
try:
family = Family.objects.get(uuid=data['uuid'])
insuree = Insuree.objects.get(uuid=data['insuree_uuid'])
family = Family.objects.get(uuid__iexact=data['uuid'])
insuree = Insuree.objects.get(uuid__iexact=data['insuree_uuid'])
family.save_history()
prev_head = family.head_insuree
if prev_head:
Expand Down Expand Up @@ -442,8 +426,8 @@ def async_mutate(cls, user, **data):
not user.has_perms(InsureeConfig.gql_mutation_update_insurees_perms):
raise PermissionDenied(_("unauthorized"))
try:
family = Family.objects.get(uuid=data['family_uuid'])
insuree = Insuree.objects.get(uuid=data['insuree_uuid'])
family = Family.objects.get(uuid__iexact=data['family_uuid'])
insuree = Insuree.objects.get(uuid__iexact=data['insuree_uuid'])
insuree.save_history()
insuree.family = family
insuree.save()
Expand Down
19 changes: 16 additions & 3 deletions insuree/gql_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from .apps import InsureeConfig
from .models import Insuree, InsureePhoto, Education, Profession, Gender, IdentificationType, \
Family, FamilyType, ConfirmationType, Relation, InsureePolicy, FamilyMutation, InsureeMutation
Family, FamilyType, ConfirmationType, Relation, InsureePolicy, FamilyMutation, InsureeMutation, InsureeStatusReason
from location.schema import LocationGQLType
from policy.gql_queries import PolicyGQLType
from core import prefix_filterset, filter_validity, ExtendedConnection
Expand Down Expand Up @@ -90,6 +90,18 @@ class Meta:
}


class InsureeStatusReasonGQLType(DjangoObjectType):
class Meta:
model = InsureeStatusReason
interfaces = (graphene.relay.Node,)
filter_fields = {
"code": ["exact"],
"insuree_status_reason": ["exact", 'icontains', 'istartswith'],
"status_type": ["exact"]
}
connection_class = ExtendedConnection


class InsureeGQLType(DjangoObjectType):
age = graphene.Int(source='age')
client_mutation_id = graphene.String()
Expand Down Expand Up @@ -128,7 +140,7 @@ def resolve_photo(self, info):
class Meta:
model = Insuree
filter_fields = {
"uuid": ["exact"],
"uuid": ["exact","iexact"],
"chf_id": ["exact", "istartswith", "icontains", "iexact"],
"last_name": ["exact", "istartswith", "icontains", "iexact"],
"other_names": ["exact", "istartswith", "icontains", "iexact"],
Expand All @@ -139,6 +151,7 @@ class Meta:
"passport": ["exact", "istartswith", "icontains", "iexact", "isnull"],
"gender__code": ["exact", "isnull"],
"marital": ["exact", "isnull"],
"status": ["exact"],
"validity_from": ["exact", "lt", "lte", "gt", "gte", "isnull"],
"validity_to": ["exact", "lt", "lte", "gt", "gte", "isnull"],
**prefix_filterset("photo__", PhotoGQLType._meta.filter_fields),
Expand Down Expand Up @@ -188,7 +201,7 @@ class Meta:
"is_offline": ["exact"],
**prefix_filterset("location__", LocationGQLType._meta.filter_fields),
**prefix_filterset("head_insuree__", InsureeGQLType._meta.filter_fields),
** prefix_filterset("members__", InsureeGQLType._meta.filter_fields)
**prefix_filterset("members__", InsureeGQLType._meta.filter_fields)
}
interfaces = (graphene.relay.Node,)
connection_class = ExtendedConnection
Expand Down
2 changes: 0 additions & 2 deletions insuree/management/commands/generateinsurees.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ def handle(self, *args, **options):
last_name=fake.last_name(),
other_names=fake.first_name(),
dob=fake.date_between(start_date='-105y', end_date='today'),
chf_id=random.randrange(100000000, 999999999),
)
family_props = dict(
location_id=self.get_random_village(),
Expand All @@ -61,7 +60,6 @@ def handle(self, *args, **options):
props["other_names"] = fake.first_name()
props["dob"] = fake.date_between(start_date='-105y', end_date='today')
props["family_id"] = insuree.family_id
props["chf_id"] = random.randrange(100000000, 999999999)
member = create_test_insuree(with_family=False, custom_props=props)
if verbose:
print("Created family member", member_num, member.other_names)
Expand Down
47 changes: 47 additions & 0 deletions insuree/migrations/0017_auto_20230923_2238.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 3.2.16 on 2023-09-23 22:38

import core.fields
import datetime
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('insuree', '0016_alter_jsonext_column'),
]

operations = [
migrations.CreateModel(
name='InsureeStatusReason',
fields=[
('validity_from', core.fields.DateTimeField(db_column='ValidityFrom', default=datetime.datetime.now)),
('validity_to', core.fields.DateTimeField(blank=True, db_column='ValidityTo', null=True)),
('legacy_id', models.IntegerField(blank=True, db_column='LegacyID', null=True)),
('id', models.SmallIntegerField(db_column='StatusReasonId', primary_key=True, serialize=False)),
('insuree_status_reason', models.CharField(db_column='StatusReason', max_length=50)),
('code', models.CharField(db_column='Code', max_length=5)),
('status_type', models.CharField(choices=[('AC', 'Active'), ('IN', 'Inactive'), ('DE', 'Dead')], default='AC', max_length=2)),
],
options={
'db_table': 'tblInsureeStatusReason',
'managed': True,
},
),
migrations.AddField(
model_name='insuree',
name='status',
field=models.CharField(choices=[('AC', 'Active'), ('IN', 'Inactive'), ('DE', 'Dead')], default='AC', max_length=2),
),
migrations.AddField(
model_name='insuree',
name='status_date',
field=core.fields.DateField(blank=True, db_column='status_date', null=True),
),
migrations.AddField(
model_name='insuree',
name='status_reason',
field=models.ForeignKey(blank=True, db_column='StatusReason', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='insurees', to='insuree.insureestatusreason'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.16 on 2023-10-05 14:01

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('insuree', '0017_auto_20230923_2238'),
]

operations = [
migrations.AddField(
model_name='confirmationtype',
name='is_confirmation_number_required',
field=models.BooleanField(default=False),
),
]
22 changes: 22 additions & 0 deletions insuree/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class ConfirmationType(models.Model):
db_column='SortOrder', blank=True, null=True)
alt_language = models.CharField(
db_column='AltLanguage', max_length=50, blank=True, null=True)
is_confirmation_number_required = models.BooleanField(default=False)

class Meta:
managed = True
Expand Down Expand Up @@ -197,6 +198,23 @@ class Meta:
db_table = 'tblRelations'


class InsureeStatus(models.TextChoices):
ACTIVE = "AC"
INACTIVE = "IN"
DEAD = "DE"


class InsureeStatusReason(core_models.VersionedModel):
id = models.SmallIntegerField(db_column='StatusReasonId', primary_key=True)
insuree_status_reason = models.CharField(db_column='StatusReason', max_length=50)
code = models.CharField(db_column='Code', max_length=5)
status_type = models.CharField(max_length=2, choices=InsureeStatus.choices, default=InsureeStatus.ACTIVE)

class Meta:
managed = True
db_table = 'tblInsureeStatusReason'


class Insuree(core_models.VersionedModel, core_models.ExtendableModel):
id = models.AutoField(db_column='InsureeID', primary_key=True)
uuid = models.CharField(db_column='InsureeUUID', max_length=36, default=uuid.uuid4, unique=True)
Expand Down Expand Up @@ -256,6 +274,10 @@ def is_adult(self, reference_date=None):
related_name='insurees')

offline = models.BooleanField(db_column='isOffline', blank=True, null=True)
status = models.CharField(max_length=2, choices=InsureeStatus.choices, default=InsureeStatus.ACTIVE)
status_date = core.fields.DateField(db_column='status_date', null=True, blank=True)
status_reason = models.ForeignKey(InsureeStatusReason, models.DO_NOTHING, db_column='StatusReason',
blank=True, null=True, related_name='insurees')
audit_user_id = models.IntegerField(db_column='AuditUserID')
# row_id = models.BinaryField(db_column='RowID', blank=True, null=True)

Expand Down
21 changes: 13 additions & 8 deletions insuree/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import graphene_django_optimizer as gql_optimizer
from location.models import Location, UserDistrict

from .apps import InsureeConfig
from insuree.apps import InsureeConfig
from .models import FamilyMutation, InsureeMutation
from django.utils.translation import gettext as _
from location.apps import LocationConfig
Expand Down Expand Up @@ -81,6 +81,10 @@ class Query(graphene.ObjectType):
family_types = graphene.List(FamilyTypeGQLType)
confirmation_types = graphene.List(ConfirmationTypeGQLType)
relations = graphene.List(RelationGQLType)
insuree_status_reasons = DjangoFilterConnectionField(
InsureeStatusReasonGQLType,
str=graphene.String()
)
families = FamiliesConnectionField(
FamilyGQLType,
null_as_false_poverty=graphene.Boolean(),
Expand Down Expand Up @@ -186,16 +190,17 @@ def resolve_insurees(self, info, **kwargs):
# Limit the list by the logged in user location mapping
user_districts = UserDistrict.get_user_districts(
info.context.user._u)

filters += [Q(family__location__parent__parent__in=Location.objects.filter(
uuid__in=user_districts.values_list('location__uuid', flat=True)))]
user_disctricts = Location.objects.filter(
uuid__in=user_districts.values_list('location__uuid', flat=True))
filters += [Q(family__location__parent__parent__in=user_disctricts)|
Q(current_village__parent__parent__in=user_disctricts)]

return gql_optimizer.query(Insuree.objects.filter(*filters).all(), info)

def resolve_family_members(self, info, **kwargs):
if not info.context.user.has_perms(InsureeConfig.gql_query_insuree_family_members):
raise PermissionDenied(_("unauthorized"))
family = Family.objects.get(Q(uuid=kwargs.get('family_uuid')))
family = Family.objects.get(Q(uuid__iexact=kwargs.get('family_uuid')))
return Insuree.objects.filter(
Q(family=family),
*filter_validity(**kwargs)
Expand Down Expand Up @@ -246,7 +251,7 @@ def resolve_families(self, info, **kwargs):
officer = kwargs.get('officer', None)
if officer:
officer_policies_families = Policy.objects.filter(
officer__uuid=officer).values_list('family', flat=True)
officer__uuid__iexact=officer).values_list('family', flat=True)
filters.append(Q(id__in=officer_policies_families))

null_as_false_poverty = kwargs.get('null_as_false_poverty')
Expand Down Expand Up @@ -336,7 +341,7 @@ def on_family_mutation(kwargs, k='uuid'):
family_uuid = kwargs['data'].get('uuid', None)
if not family_uuid:
return []
impacted_family = Family.objects.get(Q(uuid=family_uuid))
impacted_family = Family.objects.get(Q(uuid__iexact=family_uuid))
FamilyMutation.objects.create(
family=impacted_family, mutation_id=kwargs['mutation_log_id'])
return []
Expand All @@ -360,7 +365,7 @@ def on_insuree_mutation(kwargs, k='uuid'):
insuree_uuid = kwargs['data'].get('uuid', None)
if not insuree_uuid:
return []
impacted_insuree = Insuree.objects.get(Q(uuid=insuree_uuid))
impacted_insuree = Insuree.objects.get(Q(uuid__iexact=insuree_uuid))
InsureeMutation.objects.create(
insuree=impacted_insuree, mutation_id=kwargs['mutation_log_id'])
return []
Expand Down
Loading