Skip to content

Commit

Permalink
Merge pull request #240 from wilsonc86/reinstate_licence_activity
Browse files Browse the repository at this point in the history
WildlifeCompliance: work on reinstate licence activity
  • Loading branch information
wilsonc86 committed Jun 25, 2019
2 parents 4741dac + e80d67d commit 22b35b0
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 310 deletions.
55 changes: 33 additions & 22 deletions wildlifecompliance/components/applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ class Application(RevisionedMixin):
CUSTOMER_STATUS_AMENDMENT_REQUIRED,
]

# List of statuses from above that allow a customer to view an application
# (read-only)
CUSTOMER_VIEWABLE_STATE = [
CUSTOMER_STATUS_UNDER_REVIEW,
CUSTOMER_STATUS_ACCEPTED,
CUSTOMER_STATUS_PARTIALLY_APPROVED,
CUSTOMER_STATUS_DECLINED,
]

PROCESSING_STATUS_DRAFT = 'draft'
PROCESSING_STATUS_AWAITING_APPLICANT_RESPONSE = 'awaiting_applicant_response'
PROCESSING_STATUS_APPROVED = 'approved'
Expand All @@ -185,15 +194,6 @@ class Application(RevisionedMixin):
(PROCESSING_STATUS_UNDER_REVIEW, 'Under Review'),
)

# List of statuses from above that allow a customer to view an application
# (read-only)
CUSTOMER_VIEWABLE_STATE = [
PROCESSING_STATUS_UNDER_REVIEW,
PROCESSING_STATUS_APPROVED,
PROCESSING_STATUS_DECLINED,
PROCESSING_STATUS_PARTIALLY_APPROVED,
]

ID_CHECK_STATUS_NOT_CHECKED = 'not_checked'
ID_CHECK_STATUS_AWAITING_UPDATE = 'awaiting_update'
ID_CHECK_STATUS_UPDATED = 'updated'
Expand Down Expand Up @@ -2194,6 +2194,7 @@ def purposes(self):

@property
def can_amend(self):
# TODO: check for situation where a new licence of same purpose exists
# Returns true if the activity can be included in a Amendment Application
return ApplicationSelectedActivity.get_current_activities_for_application_type(
Application.APPLICATION_TYPE_AMENDMENT,
Expand All @@ -2202,6 +2203,7 @@ def can_amend(self):

@property
def can_renew(self):
# TODO: check for situation where a new licence of same purpose exists
# Returns true if the activity can be included in a Renewal Application
return ApplicationSelectedActivity.get_current_activities_for_application_type(
Application.APPLICATION_TYPE_RENEWAL,
Expand All @@ -2210,38 +2212,40 @@ def can_renew(self):

@property
def can_reactivate_renew(self):
# TODO: check for situation where a new licence of same purpose exists
# TODO: clarify business logic for when an activity renew is allowed to be reactivate.
return ApplicationSelectedActivity.get_current_activities_for_application_type(
Application.APPLICATION_TYPE_NEW_LICENCE,
Application.APPLICATION_TYPE_SYSTEM_GENERATED,
activity_ids=[self.id]
).count() > 0

@property
def can_surrender(self):
# TODO: clarify business logic for when an activity is allowed to be surrendered.
return ApplicationSelectedActivity.get_current_activities_for_application_type(
Application.APPLICATION_TYPE_NEW_LICENCE,
Application.APPLICATION_TYPE_SYSTEM_GENERATED,
activity_ids=[self.id]
).count() > 0

@property
def can_cancel(self):
# TODO: clarify business logic for when an activity is allowed to be cancelled.
return ApplicationSelectedActivity.get_current_activities_for_application_type(
Application.APPLICATION_TYPE_NEW_LICENCE,
Application.APPLICATION_TYPE_SYSTEM_GENERATED,
activity_ids=[self.id]
).count() > 0

@property
def can_suspend(self):
# TODO: clarify business logic for when an activity is allowed to be suspended.
# Returns true if the activity_status is CURRENT
return ApplicationSelectedActivity.get_current_activities_for_application_type(
Application.APPLICATION_TYPE_NEW_LICENCE,
Application.APPLICATION_TYPE_SYSTEM_GENERATED,
activity_ids=[self.id]
).count() > 0
).exclude(activity_status=ApplicationSelectedActivity.ACTIVITY_STATUS_SUSPENDED).count() > 0

@property
def can_reissue(self):
# TODO: check for situation where a new licence of same purpose exists
# Returns true if the activity has expired, excluding if it was surrendered or cancelled
current_date = timezone.now().date()
return ApplicationSelectedActivity.objects.filter(
Expand All @@ -2258,11 +2262,15 @@ def can_reissue(self):

@property
def can_reinstate(self):
# Returns true if the activity has not yet expired and is currently suspended
# TODO: check for situation where a new licence of same purpose exists
# Returns true if the activity has not yet expired and is currently suspended or cancelled
current_date = timezone.now().date()
return self.expiry_date and\
self.expiry_date >= current_date and\
self.activity_status == ApplicationSelectedActivity.ACTIVITY_STATUS_SUSPENDED
self.activity_status in [
ApplicationSelectedActivity.ACTIVITY_STATUS_SUSPENDED,
ApplicationSelectedActivity.ACTIVITY_STATUS_CANCELLED
]

@property
def base_fees(self):
Expand Down Expand Up @@ -2297,6 +2305,9 @@ def payment_status(self):

@staticmethod
def get_current_activities_for_application_type(application_type, **kwargs):
# Retrieves the current activities for an ApplicationSelectedActivity, filterable by LicenceActivity ID
# and Application.APPLICATION_TYPE in the case of the additional date_filter (use
# Application.APPLICATION_TYPE_SYSTEM_GENERATED for no APPLICATION_TYPE filters)
applications = kwargs.get('applications', Application.objects.none())
activity_ids = kwargs.get('activity_ids', [])

Expand Down Expand Up @@ -2362,11 +2373,11 @@ def process_licence_fee_payment(self, request, application):
return self.licence_fee_paid and send_activity_invoice_email_notification(application, self, invoice_ref, request)

def reactivate_renew(self, request):
pass
# with transaction.atomic():
# self.activity_status = ApplicationSelectedActivity.ACTIVITY_STATUS_SURRENDERED
# self.updated_by = request.user
# self.save()
# TODO: this needs work, reactivate renew logic to be clarified and function adjusted
with transaction.atomic():
self.activity_status = ApplicationSelectedActivity.ACTIVITY_STATUS_EXPIRED
self.updated_by = request.user
self.save()

def surrender(self, request):
with transaction.atomic():
Expand Down
2 changes: 1 addition & 1 deletion wildlifecompliance/components/applications/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ class ApplicationSerializer(BaseApplicationSerializer):
can_be_processed = serializers.SerializerMethodField(read_only=True)

def get_readonly(self, obj):
return obj.can_user_view
return not obj.can_user_edit

def get_amendment_requests(self, obj):
return ExternalAmendmentRequestSerializer(
Expand Down
48 changes: 36 additions & 12 deletions wildlifecompliance/components/licences/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def reactivate_renew_purposes(self, request, pk=None, *args, **kwargs):
if not set(purpose_ids_list).issubset(can_reactivate_renew_purposes_ids_list):
raise serializers.ValidationError(
'Renew for selected purposes cannot be reactivated')
instance.reactivate_renew_purposes(request)
instance.apply_action_to_purposes(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_REACTIVATE_RENEW)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
Expand All @@ -319,12 +319,12 @@ def surrender_licence(self, request, pk=None, *args, **kwargs):
try:
if pk:
instance = self.get_object()
instance.surrender_licence(request)
instance.apply_action_to_licence(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_SURRENDER)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
raise serializers.ValidationError(
'Licence ID list must be specified')
'Licence ID must be specified')
except serializers.ValidationError:
print(traceback.print_exc())
raise
Expand Down Expand Up @@ -357,7 +357,7 @@ def surrender_purposes(self, request, pk=None, *args, **kwargs):
if not set(purpose_ids_list).issubset(can_surrender_purposes_ids_list):
raise serializers.ValidationError(
'Selected purposes cannot be surrendered')
instance.surrender_purposes(request)
instance.apply_action_to_purposes(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_SURRENDER)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
Expand All @@ -381,12 +381,12 @@ def cancel_licence(self, request, pk=None, *args, **kwargs):
'You are not authorised to cancel licences')
if pk:
instance = self.get_object()
instance.cancel_licence(request)
instance.apply_action_to_licence(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_CANCEL)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
raise serializers.ValidationError(
'Licence ID list must be specified')
'Licence ID must be specified')
except serializers.ValidationError:
print(traceback.print_exc())
raise
Expand Down Expand Up @@ -422,7 +422,7 @@ def cancel_purposes(self, request, pk=None, *args, **kwargs):
if not set(purpose_ids_list).issubset(can_cancel_purposes_ids_list):
raise serializers.ValidationError(
'Selected purposes cannot be cancelled')
instance.cancel_purposes(request)
instance.apply_action_to_purposes(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_CANCEL)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
Expand All @@ -446,12 +446,12 @@ def suspend_licence(self, request, pk=None, *args, **kwargs):
'You are not authorised to suspend licences')
if pk:
instance = self.get_object()
instance.suspend_licence(request)
instance.apply_action_to_licence(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_SUSPEND)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
raise serializers.ValidationError(
'Licence ID list must be specified')
'Licence ID must be specified')
except serializers.ValidationError:
print(traceback.print_exc())
raise
Expand Down Expand Up @@ -482,12 +482,12 @@ def suspend_purposes(self, request, pk=None, *args, **kwargs):
first().licence_activity_id
instance = self.get_object()
can_suspend_purposes = instance.get_latest_purposes_for_licence_activity_and_action(
licence_activity_id, 'suspend')
licence_activity_id, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_SUSPEND)
can_suspend_purposes_ids_list = [purpose.id for purpose in can_suspend_purposes.order_by('id')]
if not set(purpose_ids_list).issubset(can_suspend_purposes_ids_list):
raise serializers.ValidationError(
'Selected purposes cannot be suspended')
instance.suspend_purposes(request)
instance.apply_action_to_purposes(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_SUSPEND)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
Expand All @@ -503,6 +503,30 @@ def suspend_purposes(self, request, pk=None, *args, **kwargs):
print(traceback.print_exc())
raise serializers.ValidationError(str(e))

@detail_route(methods=['POST', ])
def reinstate_licence(self, request, pk=None, *args, **kwargs):
try:
if not request.user.has_perm('wildlifecompliance.issuing_officer'):
raise serializers.ValidationError(
'You are not authorised to reinstate licences')
if pk:
instance = self.get_object()
instance.apply_action_to_licence(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_REINSTATE)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
raise serializers.ValidationError(
'Licence ID must be specified')
except serializers.ValidationError:
print(traceback.print_exc())
raise
except ValidationError as e:
print(traceback.print_exc())
raise serializers.ValidationError(repr(e.error_dict))
except Exception as e:
print(traceback.print_exc())
raise serializers.ValidationError(str(e))

@detail_route(methods=['POST', ])
def reinstate_purposes(self, request, pk=None, *args, **kwargs):
try:
Expand All @@ -528,7 +552,7 @@ def reinstate_purposes(self, request, pk=None, *args, **kwargs):
if not set(purpose_ids_list).issubset(can_reinstate_purposes_ids_list):
raise serializers.ValidationError(
'Selected purposes cannot be reinstated')
instance.reinstate_purposes(request)
instance.apply_action_to_purposes(request, WildlifeLicence.ACTIVITY_PURPOSE_ACTION_REINSTATE)
serializer = DTExternalWildlifeLicenceSerializer(instance, context={'request': request})
return Response(serializer.data)
else:
Expand Down
Loading

0 comments on commit 22b35b0

Please sign in to comment.