Skip to content

Commit

Permalink
List and delete policy renewals with gql or when renewing policy
Browse files Browse the repository at this point in the history
Policy renewals were directly exposed by the C# REST API. The policy mobile app
needs to list, delete, and add policy renewals. The GraphQL API didn't allow
to do so.

With the present change, we can now list and delete policy renewals with a
GrapQL query and mutation (resp.). As there is already a mutation to renew
a given policy, we haven't added a dedicated GraphQL mutation to add
a policy renewal independently. As there is a background task scheduling policy
renewals, we are now soft deleting the renewals of a given policy when we
manually renew it.
  • Loading branch information
toch authored and tdethier committed Nov 15, 2023
1 parent b8530f8 commit e3ddffc
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 4 deletions.
39 changes: 37 additions & 2 deletions policy/gql_mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import graphene
from django.db import transaction

from policy.services import PolicyService
from policy.services import PolicyService, PolicyRenewalService

from .apps import PolicyConfig
from core.schema import OpenIMISMutation
from .models import Policy, PolicyMutation
from .models import Policy, PolicyMutation, PolicyRenewal
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError, PermissionDenied
from django.utils.translation import gettext as _
Expand Down Expand Up @@ -46,6 +46,8 @@ def do_mutate(cls, perms, user, **data):
from core.utils import TimeUtils
data['validity_from'] = TimeUtils.now()
policy = PolicyService(user).update_or_create(data, user)
policy_renewals = PolicyRenewal.objects.filter(policy=policy, validity_to__isnull=True)
[PolicyRenewalService(user).delete(policy_renewal) for policy_renewal in policy_renewals]
PolicyMutation.object_mutated(user, client_mutation_id=client_mutation_id, policy=policy)
return None

Expand Down Expand Up @@ -151,6 +153,39 @@ def async_mutate(cls, user, **data):
'exc': exc}]


class DeletePolicyRenewalsMutation(OpenIMISMutation):
_mutation_module = "policy"
_mutation_class = "DeletePolicyRenewalsMutation"

class Input(OpenIMISMutation.Input):
uuids = graphene.List(graphene.String)

@classmethod
def async_mutate(cls, user, **data):
try:
with transaction.atomic():
errors = []
for policy_renewal_uuid in data["uuids"]:
policy_renewal = PolicyRenewal.objects \
.filter(uuid=policy_renewal_uuid) \
.first()
if policy_renewal is None:
errors += {
'title': policy_renewal_uuid,
'list': [{'message': _(
"policy_renewal.validation.id_does_not_exist") % {'id': policy_renewal_uuid}}]
}
continue
errors += PolicyRenewalService(user).delete(policy_renewal)
if len(errors) == 1:
errors = errors[0]['list']
return errors
except Exception as exc:
return [{
'message': _("policy_renewal.mutation.failed_to_delete_policies"),
'detail': str(exc),
'exc': exc}]

class DeletePoliciesMutation(OpenIMISMutation):
_mutation_module = "policy"
_mutation_class = "DeletePoliciesMutation"
Expand Down
9 changes: 8 additions & 1 deletion policy/gql_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from graphene_django import DjangoObjectType
from django.utils.translation import gettext as _
from .apps import PolicyConfig
from .models import Policy
from .models import Policy, PolicyRenewal
from core import prefix_filterset, filter_validity, ExtendedConnection, ExtendedRelayConnection
from core.schema import OfficerGQLType
from product.schema import ProductGQLType
Expand Down Expand Up @@ -44,6 +44,13 @@ class Meta:
}
connection_class = ExtendedConnection

class PolicyRenewalGQLType(DjangoObjectType):
class Meta:
model = PolicyRenewal
interfaces = (graphene.relay.Node,)
filter_fields = {
}
connection_class = ExtendedConnection

class PolicyAndWarningsGQLType(graphene.ObjectType):
policy = graphene.Field(PolicyGQLType)
Expand Down
30 changes: 30 additions & 0 deletions policy/migrations/0008_policyrenewalmutation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 3.2.19 on 2023-08-30 16:33

import core.models
from django.db import migrations, models
import django.db.models.deletion
import uuid


class Migration(migrations.Migration):

dependencies = [
('core', '0023_alter_jsonext_column_in_tblOfficer'),
('policy', '0007_fix_policy_mutation_name'),
]

operations = [
migrations.CreateModel(
name='PolicyRenewalMutation',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('mutation', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='policy_renewals', to='core.mutationlog')),
('policy_renewal', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='mutations', to='policy.policyrenewal')),
],
options={
'db_table': 'policy_renewal_PolicyMutation',
'managed': True,
},
bases=(models.Model, core.models.ObjectMutation),
),
]
10 changes: 10 additions & 0 deletions policy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,13 @@ class PolicyMutation(core_models.UUIDModel, core_models.ObjectMutation):
class Meta:
managed = True
db_table = "policy_PolicyMutation"

class PolicyRenewalMutation(core_models.UUIDModel, core_models.ObjectMutation):
policy_renewal = models.ForeignKey(PolicyRenewal, models.DO_NOTHING,
related_name='mutations')
mutation = models.ForeignKey(
core_models.MutationLog, models.DO_NOTHING, related_name='policy_renewals')

class Meta:
managed = True
db_table = "policy_renewal_PolicyMutation"
23 changes: 22 additions & 1 deletion policy/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import graphene_django_optimizer as gql_optimizer
from graphene_django.filter import DjangoFilterConnectionField
from core.models import Officer
from .models import PolicyMutation
from .models import PolicyMutation, PolicyRenewalMutation
from product.models import Product
from contribution.models import Premium
from insuree.models import Family, Insuree, InsureePolicy
Expand Down Expand Up @@ -48,6 +48,7 @@ class Query(graphene.ObjectType):
showInactive=graphene.Boolean(),
orderBy=graphene.List(of_type=graphene.String),
)

# Note:
# A Policy is bound to a Family...
# but an insuree of the family is only covered by the family policy
Expand Down Expand Up @@ -91,6 +92,11 @@ class Query(graphene.ObjectType):
region=graphene.String(),
)

policy_renewals = DjangoFilterConnectionField(PolicyRenewalGQLType)

def resolve_policy_renewals(self, info, **kwargs):
return PolicyRenewal.objects.filter(validity_to__isnull=True)

def resolve_policy_values(self, info, **kwargs):
if not info.context.user.has_perms(PolicyConfig.gql_query_policies_perms):
raise PermissionDenied(_("unauthorized"))
Expand Down Expand Up @@ -319,6 +325,7 @@ class Mutation(graphene.ObjectType):
create_policy = CreatePolicyMutation.Field()
update_policy = UpdatePolicyMutation.Field()
delete_policies = DeletePoliciesMutation.Field()
delete_policy_renewals = DeletePolicyRenewalsMutation.Field()
renew_policy = RenewPolicyMutation.Field()
suspend_policies = SuspendPoliciesMutation.Field()

Expand All @@ -336,6 +343,20 @@ def on_policy_mutation(sender, **kwargs):
policy=policy, mutation_id=kwargs['mutation_log_id'])
return []

def on_policy_renewal_mutation(sender, **kwargs):
uuids = kwargs['data'].get('uuids', [])
if not uuids:
uuid = kwargs['data'].get('policy_renewal_uuid', None)
uuids = [uuid] if uuid else []
if not uuids:
return []
impacted_policy_renewals = PolicyRenewal.objects.filter(uuid__in=uuids).all()
for policy_renewal in impacted_policy_renewals:
PolicyRenewalMutation.objects.create(
policy_renewal=policy_renewal, mutation_id=kwargs['mutation_log_id'])
return []


def bind_signals():
signal_mutation_module_validate["policy"].connect(on_policy_mutation)
signal_mutation_module_validate["policy"].connect(on_policy_renewal_mutation)
21 changes: 21 additions & 0 deletions policy/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ def reset_policy_before_update(policy):
policy.officer_id = None


class PolicyRenewalService:
def __init__(self, user):
self.user = user

def delete(self, policy_renewal):
try:
policy_renewal = PolicyRenewal.objects.get(uuid=policy_renewal.uuid)
logger.debug(f'YEAHHHH {policy_renewal.uuid}')
# policy_renewal.details.all().delete()
policy_renewal.delete_history()
return []
except Exception as exc:
logger.error(f'ERROR {exc}')
return {
'title': policy_renewal.uuid,
'list': [{
'message': _("policy_renewal.mutation.failed_to_delete_policy_renewal") % {'policy_renewal': str(policy_renewal)},
'detail': policy_renewal.uuid}]
}


class PolicyService:
def __init__(self, user):
self.user = user
Expand Down

0 comments on commit e3ddffc

Please sign in to comment.