Files
ihrm/asset/cbv/request_and_allocation.py

593 lines
19 KiB
Python

"""
Request and allocation page
"""
from typing import Any
from django.contrib import messages
from django.http import HttpResponse
from django.shortcuts import render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.views.generic.edit import DeleteView
from asset.filters import AssetAllocationFilter, AssetRequestFilter, CustomAssetFilter
from asset.forms import AssetAllocationForm, AssetRequestForm
from asset.models import Asset, AssetAssignment, AssetRequest, ReturnImages
from base.methods import filtersubordinates
from employee.models import Employee
from horilla.horilla_middlewares import _thread_locals
from horilla_views.cbv_methods import login_required, permission_required
from horilla_views.generic.cbv.views import (
HorillaDetailedView,
HorillaFormView,
HorillaListView,
HorillaNavView,
HorillaTabView,
TemplateView,
)
from notifications.signals import notify
@method_decorator(login_required, name="dispatch")
class RequestAndAllocationView(TemplateView):
"""
for request and allocation page
"""
template_name = "cbv/request_and_allocation/request_and_allocation.html"
@method_decorator(login_required, name="dispatch")
class AllocationList(HorillaListView):
"""
For both asset allocation and asset tab
"""
# view_id = "view-container"
bulk_update_fields = ["asset_id__expiry_date"]
model = AssetAssignment
filter_class = AssetAllocationFilter
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.search_url = reverse("list-asset")
columns = [
(_("Asset"), "asset_id", "get_avatar"),
(_("Category"), "asset_id__asset_category_id"),
(_("Expiry Date"), "asset_id__expiry_date"),
]
header_attrs = {
"action": """ style = "width:180px !important" """,
"asset_id__asset_name": """ style = "width:250px !important" """,
"asset_id__asset_category_id": """ style = "width:250px !important" """,
"asset_id__expiry_date": """ style = "width:250px !important" """,
}
sortby_mapping = [
("Category", "asset_id__asset_category_id__asset_category_name"),
("Expiry Date", "asset_id__expiry_date"),
]
action_method = "asset_action"
row_attrs = """
hx-get='{detail_view_asset}?instance_ids={ordered_ids}'
hx-target="#genericModalBody"
data-target="#genericModal"
data-toggle="oh-modal-toggle"
"""
@method_decorator(login_required, name="dispatch")
class AssetList(AllocationList):
"""
Asset tab
"""
# view_id = "assetlist"
def get_queryset(self):
"""
Returns a queryset of AssetRequest objects filtered by
the current user's employee ID.
"""
queryset = super().get_queryset()
employee = self.request.user.employee_get
queryset = queryset.filter(assigned_to_employee_id=employee).exclude(
return_status__isnull=False
)
return queryset
selected_instances_key_id = "assetlistInstances"
@method_decorator(login_required, name="dispatch")
class AssetAllocationList(AllocationList):
"""
Asset allocation tab
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.search_url = reverse("list-asset-allocation")
if any(
self.request.user.has_perm(p)
for p in [
"asset.delete_assetassignment",
"asset.change_assetassignment",
"asset.add_assetassignment",
]
):
self.action_method = "allocation_action"
self.option_method = "allocation_option"
columns = [
(
_("Allocated User"),
"assigned_to_employee_id",
"assigned_to_employee_id__get_avatar",
),
(_("Asset"), "asset_id"),
(_("Assigned Date"), "assigned_date"),
(_("Return Date"), "return_status_col"),
]
sortby_mapping = [
("Allocated User", "assigned_to_employee_id__get_full_name"),
("Asset", "asset_id__asset_name"),
("Assigned Date", "assigned_date"),
("Return Date", "return_status_col"),
]
row_attrs = """
hx-get='{detail_view_asset_allocation}?instance_ids={ordered_ids}'
hx-target="#genericModalBody"
data-target="#genericModal"
data-toggle="oh-modal-toggle"
"""
@method_decorator(login_required, name="dispatch")
class AssetRequestList(HorillaListView):
"""
Asset Request Tab
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.search_url = reverse("list-asset-request")
# self.view_id = "view-container"
if self.request.user.has_perm("asset.add_assetassignment"):
self.action_method = "action_col"
self.option_method = "option_col"
model = AssetRequest
filter_class = AssetRequestFilter
def get_queryset(self):
"""
Returns a filtered queryset of AssetRequest objects
based on user permissions and employee ID.
"""
queryset = super().get_queryset()
queryset = filtersubordinates(
request=self.request,
perm="asset.view_assetrequest",
queryset=queryset,
field="requested_employee_id",
) | queryset.filter(requested_employee_id=self.request.user.employee_get)
return queryset
columns = [
(
_("Request User"),
"requested_employee_id",
"requested_employee_id__get_avatar",
),
(_("Asset Category"), "asset_category_id"),
(_("Requested Date"), "asset_request_date"),
(_("Status"), "status_col"),
]
header_attrs = {"action": """ style = "width:180px !important" """}
sortby_mapping = [
("Request User", "requested_employee_id__get_full_name"),
("Asset Category", "asset_category_id__asset_category_name"),
("Requested Date", "asset_request_date"),
("Status", "status_col"),
]
row_attrs = """
hx-get='{detail_view_asset_request}?instance_ids={ordered_ids}'
hx-target="#genericModalBody"
data-target="#genericModal"
data-toggle="oh-modal-toggle"
"""
@method_decorator(login_required, name="dispatch")
@method_decorator(
permission_required(perm="asset.delete_assetassignment"), name="dispatch"
)
class AssetAllocationDelete(DeleteView):
"""
This the Asset Allocation Delete View
"""
model = AssetAssignment
def post(self, request, *args, **kwargs):
self.object = self.get_object()
self.object.delete()
messages.success(request, _("Allocation deleted successfully"))
return HorillaFormView.HttpResponse()
@method_decorator(login_required, name="dispatch")
@method_decorator(
permission_required(perm="asset.delete_assetrequest"), name="dispatch"
)
class AssetRequestDelete(DeleteView):
"""
This the Asset Request Delete View
"""
model = AssetRequest
def post(self, request, *args, **kwargs):
self.object = self.get_object()
self.object.delete()
messages.success(request, _("Asset request deleted successfully"))
return HorillaFormView.HttpResponse()
@method_decorator(login_required, name="dispatch")
class RequestAndAllocationTab(HorillaTabView):
"""
Tab View
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.tabs = [
{
"title": _("Asset"),
"url": f"{reverse('list-asset')}",
},
{
"title": _("Asset Request"),
"url": f"{reverse('list-asset-request')}",
"actions": [
{
"action": "Create Request",
"attrs": f"""
data-toggle="oh-modal-toggle"
data-target="#genericModal"
hx-get="{reverse('asset-request-creation')}"
hx-target="#genericModalBody"
style="cursor: pointer;"
""",
}
],
},
]
if self.request.user.has_perm("asset.view_assetassignment"):
self.tabs.append(
{
"title": _("Asset Allocation"),
"url": f"{reverse('list-asset-allocation')}",
"actions": [
{
"action": "Create Allocation",
"attrs": f"""
data-toggle="oh-modal-toggle"
data-target="#genericModal"
hx-get="{reverse('asset-allocate-creation')}"
hx-target="#genericModalBody"
style="cursor: pointer;"
""",
}
],
},
)
@method_decorator(login_required, name="dispatch")
class RequestAndAllocationNav(HorillaNavView):
"""
Nav bar
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.search_url = reverse("tab-asset-request-allocation")
nav_title = _("Asset")
filter_instance = AssetAllocationFilter()
filter_form_context_name = "asset_allocation_filter_form"
filter_body_template = "cbv/request_and_allocation/filter.html"
search_swap_target = "#listContainer"
def get_context_data(self, **kwargs):
"""
context data
"""
context = super().get_context_data(**kwargs)
assets_filter_form = CustomAssetFilter()
asset_request_filter_form = AssetRequestFilter()
context["assets_filter_form"] = assets_filter_form.form
context["asset_request_filter_form"] = asset_request_filter_form.form
return context
group_by_fields = [
("requested_employee_id", _("Asset Request / Employee")),
("asset_category_id", _("Asset Request / Asset Category")),
("asset_request_date", _("Asset Request / Request Date")),
("asset_request_status", _("Asset Request / Status")),
("assigned_to_employee_id", _("Asset Allocation / Employee")),
("assigned_date", _("Asset Allocation / Assigned Date")),
("return_date", _("Asset Allocation / Return Date")),
]
@method_decorator(login_required, name="dispatch")
class AssetDetailView(HorillaDetailedView):
"""
detail view of asset tab
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.body = [
(_("Tracking Id"), "asset_id__asset_tracking_id"),
(_("Batch No"), "asset_id__asset_lot_number_id"),
(_("Assigned Date"), "assigned_date"),
(_("Status"), "asset_detail_status"),
(_("Assigned by"), "assigned_by_employee_id"),
(_("Description"), "asset_id__asset_description"),
# ("Category","asset_id__asset_category_id")
]
self.cols = {
"asset_id__asset_description": 12,
}
action_method = "asset_detail_action"
model = AssetAssignment
title = _("Asset Information")
header = {
"title": "asset_id__asset_name",
"subtitle": "asset_id__asset_category_id",
"avatar": "get_avatar",
}
@method_decorator(login_required, name="dispatch")
class AssetRequestDetailView(HorillaDetailedView):
"""
detail view of asset request tab
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.body = [
(_("Asset Category"), "asset_category_id"),
(_("Requested Date"), "asset_request_date"),
(_("Status"), "status_col"),
(_("Request Description"), "description"),
]
self.cols = {
"description": 12,
}
model = AssetRequest
title = _("Details")
header = {
"title": "requested_employee_id",
"subtitle": "asset_request_detail_subtitle",
"avatar": "requested_employee_id__get_avatar",
}
action_method = "detail_action_col"
@method_decorator(login_required, name="dispatch")
class AssetAllocationDetailView(HorillaDetailedView):
"""
detail view of asset allocation tab
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.body = [
(_("Returned Status"), "return_status"),
(_("Allocated User"), "assigned_by_employee_id"),
(_("Allocated Date"), "assigned_date"),
(_("Return Date"), "return_date"),
(_("Asset"), "asset_id"),
(_("Status"), "detail_status"),
(_("Return Description"), "return_condition"),
]
self.cols = {
"return_condition": 12,
}
model = AssetAssignment
title = _("Details")
header = {
"title": "assigned_to_employee_id",
"subtitle": "asset_allocation_detail_subtitle",
"avatar": "assigned_to_employee_id__get_avatar",
}
action_method = "asset_allocation_detail_action"
@method_decorator(login_required, name="dispatch")
class AssetRequestCreateForm(HorillaFormView):
"""
Create Asset request
"""
model = AssetRequest
form_class = AssetRequestForm
template_name = "cbv/request_and_allocation/forms/req_form.html"
new_display_title = _("Asset Request")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.GET.get("pk"):
pk = self.request.GET.get("pk")
self.form.fields["requested_employee_id"].queryset = (
Employee.objects.filter(id=pk)
)
self.form.fields["requested_employee_id"].initial = pk
if self.form.instance.pk:
self.form_class.verbose_name = _("Asset Request")
return context
def form_valid(self, form: AssetRequestForm) -> HttpResponse:
"""
Handles validation and saving of an AssetRequestForm.
"""
if form.is_valid():
message = _("Asset Request Created Successfully")
form.save()
messages.success(self.request, message)
return self.HttpResponse()
return super().form_valid(form)
@method_decorator(login_required, name="dispatch")
@method_decorator(permission_required(perm="asset.add_asset"), name="dispatch")
class AssetAllocationFormView(HorillaFormView):
"""
Create Asset Allocation
"""
model = AssetAssignment
form_class = AssetAllocationForm
template_name = "cbv/request_and_allocation/forms/allo_form.html"
new_display_title = _("Asset Allocation")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.form.instance.pk:
self.form_class.verbose_name = _("Asset Allocation")
return context
def form_valid(self, form: AssetAllocationForm) -> HttpResponse:
"""
form valid function
"""
if form.is_valid():
asset = form.instance.asset_id
asset.asset_status = "In use"
asset.save()
message = _("Asset allocated Successfully")
form.save()
request = getattr(_thread_locals, "request", None)
files = request.FILES.getlist("assign_images")
attachments = []
if request.FILES:
for file in files:
attachment = ReturnImages()
attachment.image = file
attachment.save()
attachments.append(attachment)
form.instance.assign_images.add(*attachments)
messages.success(self.request, message)
return self.HttpResponse()
return super().form_valid(form)
class AssetApproveFormView(HorillaFormView):
"""
Create Asset Allocation
"""
model = AssetAssignment
form_class = AssetAllocationForm
template_name = "cbv/request_and_allocation/forms/asset_approve_form.html"
new_display_title = _("Asset Allocation")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
req_id = self.kwargs.get("req_id")
asset_request = AssetRequest.objects.filter(id=req_id).first()
asset_category = asset_request.asset_category_id
assets = asset_category.asset_set.filter(asset_status="Available")
self.form.fields["asset_id"].queryset = assets
self.form.fields["assigned_to_employee_id"].initial = (
asset_request.requested_employee_id
)
self.form.fields["assigned_by_employee_id"].initial = (
self.request.user.employee_get
)
return context
def form_invalid(self, form: Any) -> HttpResponse:
if not form.is_valid():
errors = form.errors.as_data()
return render(
self.request, self.template_name, {"form": form, "errors": errors}
)
return super().form_invalid(form)
def form_valid(self, form: AssetAllocationForm) -> HttpResponse:
"""
form valid function
"""
req_id = self.kwargs.get("req_id")
asset_request = AssetRequest.objects.filter(id=req_id).first()
if form.is_valid():
asset = form.instance.asset_id.id
asset = Asset.objects.filter(id=asset).first()
asset.asset_status = "In use"
asset.save()
# form = form.save(commit=False)
# form.assigned_by_employee_id = self.request.user.employee_get
form.save()
asset_request.asset_request_status = "Approved"
asset_request.save()
request = getattr(_thread_locals, "request", None)
files = request.FILES.getlist("assign_images")
attachments = []
if request.FILES:
for file in files:
attachment = ReturnImages()
attachment.image = file
attachment.save()
attachments.append(attachment)
form.instance.assign_images.add(*attachments)
messages.success(self.request, _("Asset request approved successfully!."))
notify.send(
self.request.user.employee_get,
recipient=asset_request.requested_employee_id.employee_user_id,
verb="Your asset request approved!.",
verb_ar="تم الموافقة على طلب الأصول الخاص بك!",
verb_de="Ihr Antragsantrag wurde genehmigt!",
verb_es="¡Su solicitud de activo ha sido aprobada!",
verb_fr="Votre demande d'actif a été approuvée !",
redirect=reverse("asset-request-allocation-view")
+ f"?asset_request_date={asset_request.asset_request_date}\
&asset_request_status={asset_request.asset_request_status}",
icon="bag-check",
)
return HttpResponse("<script>window.location.reload()</script>")
return super().form_valid(form)