|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +from django.db import models |
| 3 | +from django.utils.translation import gettext_lazy as _ |
| 4 | +from enumfields import EnumIntegerField |
| 5 | +import reversion |
| 6 | + |
| 7 | +from tally_ho.apps.tally.models.result_form import ResultForm |
| 8 | +from tally_ho.apps.tally.models.user_profile import UserProfile |
| 9 | +from tally_ho.libs.models.base_model import BaseModel |
| 10 | +from tally_ho.libs.models.enums.request_reason import RequestReason |
| 11 | +from tally_ho.libs.models.enums.request_status import RequestStatus |
| 12 | +from tally_ho.libs.models.enums.request_type import RequestType |
| 13 | + |
| 14 | + |
| 15 | +@reversion.register() |
| 16 | +class WorkflowRequest(BaseModel): |
| 17 | + class Meta: |
| 18 | + app_label = 'tally' |
| 19 | + indexes = [ |
| 20 | + models.Index(fields=['result_form', 'request_type', 'status']) |
| 21 | + ] |
| 22 | + |
| 23 | + request_type = EnumIntegerField( |
| 24 | + RequestType, verbose_name=_("Request Type")) |
| 25 | + status = EnumIntegerField( |
| 26 | + RequestStatus, |
| 27 | + default=RequestStatus.PENDING, |
| 28 | + verbose_name=_("Request Status")) |
| 29 | + result_form = models.ForeignKey( |
| 30 | + ResultForm, |
| 31 | + on_delete=models.PROTECT, |
| 32 | + related_name='workflow_requests') |
| 33 | + requester = models.ForeignKey( |
| 34 | + UserProfile, |
| 35 | + on_delete=models.PROTECT, |
| 36 | + related_name='initiated_requests') |
| 37 | + request_reason = EnumIntegerField(RequestReason, verbose_name=_("Reason")) |
| 38 | + request_comment = models.TextField(verbose_name=_("Request Comment")) |
| 39 | + approver = models.ForeignKey( |
| 40 | + UserProfile, |
| 41 | + on_delete=models.PROTECT, |
| 42 | + related_name='approved_rejected_requests', |
| 43 | + null=True, |
| 44 | + blank=True) |
| 45 | + approval_comment = models.TextField( |
| 46 | + verbose_name=_("Approval/Rejection Comment"), null=True, blank=True) |
| 47 | + resolved_date = models.DateTimeField(null=True, blank=True) |
| 48 | + |
| 49 | + def __str__(self): |
| 50 | + return str( |
| 51 | + f"{self.get_request_type_display()} request for " |
| 52 | + f"{self.result_form.barcode} - Status: " |
| 53 | + f"{self.get_status_display()}") |
| 54 | + |
| 55 | + def is_pending(self): |
| 56 | + return self.status == RequestStatus.PENDING |
| 57 | + |
| 58 | + def is_approved(self): |
| 59 | + return self.status == RequestStatus.APPROVED |
| 60 | + |
| 61 | + def is_rejected(self): |
| 62 | + return self.status == RequestStatus.REJECTED |
| 63 | + |
| 64 | + def can_be_actioned_by(self, user): |
| 65 | + """ |
| 66 | + Logic to determine if the user (Tally Manager/Super Admin) |
| 67 | + can approve/reject |
| 68 | + :param user: Logged in user |
| 69 | + :return: bool |
| 70 | + """ |
| 71 | + from tally_ho.libs.permissions import groups |
| 72 | + return user.is_authenticated and\ |
| 73 | + groups.is_tally_manager(user) or\ |
| 74 | + groups.is_super_administrator(user) |
| 75 | + |
| 76 | + def can_be_viewed_by(self, user): |
| 77 | + """ |
| 78 | + Logic to determine who can view the request |
| 79 | + Audit Clerks/Supervisors, or any |
| 80 | + Tally Manager/Super Admin |
| 81 | + :param user: Logged in user |
| 82 | + :return: bool |
| 83 | + """ |
| 84 | + from tally_ho.libs.permissions import groups |
| 85 | + return ( |
| 86 | + user.is_authenticated and ( |
| 87 | + groups.is_audit_clerk(user) or |
| 88 | + groups.is_audit_supervisor(user) or |
| 89 | + groups.is_tally_manager(user) or |
| 90 | + groups.is_super_administrator(user) |
| 91 | + ) |
| 92 | + ) |
0 commit comments