[ADD] ASSET: Asset history tracking
This commit is contained in:
@@ -230,3 +230,68 @@ class AssetAllocationReGroup:
|
||||
("assigned_date", "Assigned Date"),
|
||||
("return_date", "Return Date"),
|
||||
]
|
||||
|
||||
|
||||
class AssetHistoryFilter(CustomFilterSet):
|
||||
"""
|
||||
Custom filter set for AssetAssignment instances for filtering in asset history view.
|
||||
"""
|
||||
|
||||
search = django_filters.CharFilter(
|
||||
field_name="asset_id__asset_name", lookup_expr="icontains"
|
||||
)
|
||||
returned_assets = django_filters.CharFilter(
|
||||
field_name="return_status", method="exclude_none"
|
||||
)
|
||||
return_date_gte = django_filters.DateFilter(
|
||||
field_name="return_date",
|
||||
lookup_expr="gte",
|
||||
widget=forms.DateInput(attrs={"type": "date"}),
|
||||
)
|
||||
return_date_lte = django_filters.DateFilter(
|
||||
field_name="return_date",
|
||||
lookup_expr="lte",
|
||||
widget=forms.DateInput(attrs={"type": "date"}),
|
||||
)
|
||||
assigned_date_gte = django_filters.DateFilter(
|
||||
field_name="assigned_date",
|
||||
lookup_expr="gte",
|
||||
widget=forms.DateInput(attrs={"type": "date"}),
|
||||
)
|
||||
assigned_date_lte = django_filters.DateFilter(
|
||||
field_name="assigned_date",
|
||||
lookup_expr="lte",
|
||||
widget=forms.DateInput(attrs={"type": "date"}),
|
||||
)
|
||||
|
||||
def exclude_none(self, queryset, name, value):
|
||||
if value == "True":
|
||||
queryset = queryset.filter(return_status__isnull=False)
|
||||
return queryset
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
Specifies the model and fields to be used for filtering AssetAllocation instances.
|
||||
|
||||
Attributes:
|
||||
model (class): The model class AssetAssignment to be filtered.
|
||||
fields (str): A special value "__all__" to include all fields
|
||||
of the model in the filter.
|
||||
"""
|
||||
|
||||
model = AssetAssignment
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class AssetHistoryReGroup:
|
||||
"""
|
||||
Class to keep the field name for group by option
|
||||
"""
|
||||
|
||||
fields = [
|
||||
("", "Select"),
|
||||
("asset_id", "Asset"),
|
||||
("assigned_to_employee_id", "Employee"),
|
||||
("assigned_date", "Assigned Date"),
|
||||
("return_date", "Return Date"),
|
||||
]
|
||||
|
||||
@@ -11,6 +11,7 @@ from django import forms
|
||||
from base.forms import ModelForm
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from employee.forms import MultipleFileField
|
||||
from employee.models import Employee
|
||||
from asset.models import Asset, AssetDocuments, AssetReport, AssetRequest, AssetAssignment, AssetCategory, AssetLot
|
||||
from base.methods import reload_queryset
|
||||
@@ -256,6 +257,9 @@ class AssetAllocationForm(ModelForm):
|
||||
asset_status="Available"
|
||||
)
|
||||
|
||||
self.fields["assign_images"] = MultipleFileField()
|
||||
self.fields["assign_images"].required = True
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
Specifies the model and fields to be used for the AssetAllocationForm.
|
||||
@@ -269,7 +273,7 @@ class AssetAllocationForm(ModelForm):
|
||||
|
||||
model = AssetAssignment
|
||||
fields = "__all__"
|
||||
exclude = ["return_date", "return_condition", "assigned_date"]
|
||||
exclude = ["return_date", "return_condition", "assigned_date", "return_images"]
|
||||
widgets = {
|
||||
"asset_id": forms.Select(attrs={"class": "oh-select oh-select-2 "}),
|
||||
"assigned_to_employee_id": forms.Select(
|
||||
@@ -300,7 +304,7 @@ class AssetReturnForm(ModelForm):
|
||||
"""
|
||||
|
||||
model = AssetAssignment
|
||||
fields = ["return_date", "return_condition", "return_status"]
|
||||
fields = ["return_date", "return_condition", "return_status", "return_images"]
|
||||
widgets = {
|
||||
"return_date": forms.DateInput(
|
||||
attrs={"type": "date", "class": "oh-input w-100", "required": "true"}
|
||||
@@ -324,6 +328,8 @@ class AssetReturnForm(ModelForm):
|
||||
super(AssetReturnForm, self).__init__(*args, **kwargs)
|
||||
self.fields["return_date"].initial = date.today()
|
||||
|
||||
self.fields["return_images"] = MultipleFileField(label="Images")
|
||||
self.fields["return_images"].required = True
|
||||
|
||||
def clean_return_date(self):
|
||||
return_date = self.cleaned_data.get("return_date")
|
||||
|
||||
@@ -103,6 +103,9 @@ class AssetDocuments(models.Model):
|
||||
return f'document for {self.asset_report}'
|
||||
|
||||
|
||||
class ReturnImages(models.Model):
|
||||
image = models.FileField(upload_to="asset/return_images/", blank=True, null=True)
|
||||
|
||||
class AssetAssignment(models.Model):
|
||||
"""
|
||||
Represents the allocation and return of assets to and from employees.
|
||||
@@ -130,6 +133,11 @@ class AssetAssignment(models.Model):
|
||||
)
|
||||
return_request = models.BooleanField(default = False)
|
||||
objects = HorillaCompanyManager("asset_id__asset_lot_number_id__company_id")
|
||||
return_images = models.ManyToManyField(ReturnImages,blank=True,related_name="return_images")
|
||||
assign_images = models.ManyToManyField(ReturnImages,blank=True,related_name="assign_images")
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.assigned_to_employee_id} --- {self.asset_id} --- {self.return_status}"
|
||||
|
||||
|
||||
class AssetRequest(models.Model):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
<div class="oh-modal__dialog-title">{% trans "Asset Return Form" %}</div>
|
||||
<form hx-post="{%url 'asset-allocate-return' asset_id=asset_id %}" hx-target="#asset-request-allocation-modal-target" method="post">
|
||||
<form hx-post="{%url 'asset-allocate-return' asset_id=asset_id %}" hx-target="#asset-request-allocation-modal-target" method="post" hx-encoding="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="m-3">
|
||||
<div class="oh-input__group ">
|
||||
@@ -16,6 +16,10 @@
|
||||
<label class="oh-input__label" for="objective">{% trans "Return Condition" %}</label>
|
||||
{{asset_return_form.return_condition}}
|
||||
</div>
|
||||
<div class="oh-input__group ">
|
||||
<label class="oh-input__label" for="objective">{% trans "Return Condition Images" %}</label>
|
||||
{{asset_return_form.return_images}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-footer justify-content-between mt-3">
|
||||
<button
|
||||
|
||||
115
asset/templates/asset_history/asset_history_filter.html
Normal file
115
asset/templates/asset_history/asset_history_filter.html
Normal file
@@ -0,0 +1,115 @@
|
||||
{% load static %} {% load i18n %} {% load mathfilters %} {% load widget_tweaks %}
|
||||
<div class="oh-dropdown__filter-body">
|
||||
<div class="oh-accordion">
|
||||
<div class="oh-accordion-header">{% trans "Asset History" %}</div>
|
||||
<div class="oh-accordion-body">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.assigned_to_employee_id.id_for_label}}"
|
||||
>{% trans "Allocated User" %}</label
|
||||
>
|
||||
{{f.form.assigned_to_employee_id}}
|
||||
</div>
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.asset_id.id_for_label}}"
|
||||
>{% trans "Asset" %}</label
|
||||
>
|
||||
{{f.form.asset_id}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.assigned_date.id_for_label}}"
|
||||
>{% trans "Asset Allocated Date" %}</label
|
||||
>
|
||||
{{ f.form.assigned_date |attr:"type:date" }}
|
||||
</div>
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.return_status.id_for_label}}"
|
||||
>{% trans "Status" %}</label
|
||||
>
|
||||
{{f.form.return_status}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.return_date.id_for_label}}"
|
||||
>{% trans "Return Date" %}</label
|
||||
>
|
||||
{{ f.form.return_date|attr:"type:date" }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.assigned_by_employee_id.id_for_label}}"
|
||||
>{% trans "Allocated By" %}</label
|
||||
>
|
||||
{{f.form.assigned_by_employee_id}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="oh-accordion">
|
||||
<div class="oh-accordion-header">{% trans "Advanced" %}</div>
|
||||
<div class="oh-accordion-body">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.return_date_gte.id_for_label}}"
|
||||
>{% trans "Return Date Greater Or Equal" %}</label
|
||||
>
|
||||
{{f.form.return_date_gte}}
|
||||
</div>
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.return_date_lte.id_for_label}}"
|
||||
>{% trans "Assign Date Greater Or Equal" %}</label
|
||||
>
|
||||
{{f.form.assigned_date_gte}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.return_date_gte.id_for_label}}"
|
||||
>{% trans "Return Date lesser Or Equal" %}</label
|
||||
>
|
||||
{{f.form.return_date_lte}}
|
||||
</div>
|
||||
<div class="oh-input-group">
|
||||
<label
|
||||
class="oh-label"
|
||||
for="{{f.form.return_date_lte.id_for_label}}"
|
||||
>{% trans "Assign Date Lesser Or Equal" %}</label
|
||||
>
|
||||
{{f.form.assigned_date_lte}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-dropdown__filter-footer">
|
||||
<button class="oh-btn oh-btn--secondary oh-btn--small w-100 filterButton">
|
||||
{% trans "Filter" %}
|
||||
</button>
|
||||
</div>
|
||||
<script src="{% static '/base/filter.js' %}"></script>
|
||||
141
asset/templates/asset_history/asset_history_list.html
Normal file
141
asset/templates/asset_history/asset_history_list.html
Normal file
@@ -0,0 +1,141 @@
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load basefilters %}
|
||||
{% include 'filter_tags.html' %}
|
||||
<div class="oh-table_sticky--wrapper" id="historyTable">
|
||||
<div class="oh-sticky-table">
|
||||
<div class="oh-sticky-table__table">
|
||||
<div class="oh-sticky-table__thead" >
|
||||
<div class="oh-sticky-table__tr">
|
||||
<div class="oh-sticky-table__th {% if request.sort_option.order == '-asset_id__asset_name' %}arrow-up {% elif request.sort_option.order == 'asset_id__asset_name' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-get="{% url 'asset-history-search' %}?{{pd}}&sortby=asset_id__asset_name" hx-target="#historyTable">{% trans "Asset" %}</div>
|
||||
<div class="oh-sticky-table__th {% if request.sort_option.order == '-assigned_to_employee_id__employee_first_name' %}arrow-up {% elif request.sort_option.order == 'assigned_to_employee_id__employee_first_name' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-get="{% url 'asset-history-search' %}?{{pd}}&sortby=assigned_to_employee_id__employee_first_name" hx-target="#historyTable">{% trans "Employee" %}</div>
|
||||
<div class="oh-sticky-table__th {% if request.sort_option.order == '-assigned_date' %}arrow-up {% elif request.sort_option.order == 'assigned_date' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-get="{% url 'asset-history-search' %}?{{pd}}&sortby=assigned_date" hx-target="#historyTable">{% trans "Assigned Date" %}</div>
|
||||
<div class="oh-sticky-table__th {% if request.sort_option.order == '-return_date' %}arrow-up {% elif request.sort_option.order == 'return_date' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-get="{% url 'asset-history-search' %}?{{pd}}&sortby=return_date" hx-target="#historyTable">{% trans "Returned Date" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Return Status" %}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__tbody">
|
||||
{% for asset_assignement in asset_assignments %}
|
||||
<div class="oh-sticky-table__tr" hx-get='{% url "asset-history-single-view" asset_assignement.id %}' hx-target="#historySingleModalBody" data-toggle="oh-modal-toggle", data-target= "#historySingleModal" >
|
||||
<div class="oh-sticky-table__sd">
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img
|
||||
src="https://ui-avatars.com/api/?name={{asset_assignement.asset_id.asset_name}}&background=random"
|
||||
class="oh-profile__image"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<span class="oh-profile__name oh-text--dark">{{asset_assignement.asset_id}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
{{asset_assignement.assigned_to_employee_id}}
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">{{asset_assignement.assigned_date}} </div>
|
||||
<div class="oh-sticky-table__td">{{asset_assignement.return_date}}</div>
|
||||
<div class="oh-sticky-table__td">{{asset_assignement.return_status}}</div>
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-pagination">
|
||||
<span class="oh-pagination__page">
|
||||
{% trans "Page" %} {{ asset_assignments.number }} {% trans "of" %} {{ asset_assignments.paginator.num_pages }}.
|
||||
</span>
|
||||
<nav class="oh-pagination__nav">
|
||||
<div class="oh-pagination__input-container me-3">
|
||||
<span class="oh-pagination__label me-1">{% trans "Page" %}</span>
|
||||
<input
|
||||
type="number"
|
||||
name="page"
|
||||
class="oh-pagination__input"
|
||||
value="{{asset_assignments.number}}"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}"
|
||||
hx-target="#historyTable"
|
||||
min="1"
|
||||
/>
|
||||
<span class="oh-pagination__label">{% trans "of" %} {{asset_assignments.paginator.num_pages}}</span>
|
||||
</div>
|
||||
<ul class="oh-pagination__items">
|
||||
{% if asset_assignments.has_previous %}
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#historyTable' hx-get="{% url 'asset-history-search' %}?{{pd}}&page=1" class="oh-pagination__link" onclick="tickCheckboxes();">{% trans "First" %}</a>
|
||||
</li>
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#historyTable' hx-get="{% url 'asset-history-search' %}?{{pd}}&page={{ asset_assignments.previous_page_number }}" class="oh-pagination__link" onclick="tickCheckboxes();">{% trans "Previous" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if asset_assignments.has_next %}
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#historyTable' hx-get="{% url 'asset-history-search' %}?{{pd}}&page={{ asset_assignments.next_page_number }}" class="oh-pagination__link" onclick="tickCheckboxes();">{% trans "Next" %}</a>
|
||||
</li>
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#historyTable' hx-get="{% url 'asset-history-search' %}?{{pd}}&page={{ asset_assignments.paginator.num_pages }}" class="oh-pagination__link" onclick="tickCheckboxes();">{% trans "Last" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="historySingleModal"
|
||||
role="dialog"
|
||||
aria-labelledby="historySingleModal"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="oh-modal__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="historySingleModalLabel">
|
||||
{% trans "Asset Details" %}
|
||||
</h2>
|
||||
<button class="oh-modal__close" aria-label="Close" >
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
<div class="oh-modal__dialog-body p-0 pt-2" id='historySingleModalBody'></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// This lines is used to set default selected stage for exits lines
|
||||
|
||||
function enlargeImage(src,$element) {
|
||||
$("#enlargeImageContainer").empty()
|
||||
var enlargeImageContainer = $("#enlargeImageContainer")
|
||||
enlargeImageContainer.empty()
|
||||
style = 'width:100%; height:90%; box-shadow: 0 10px 10px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.2); background:white'
|
||||
var enlargedImage = $('<iframe>').attr({ src: src, style: style })
|
||||
var name = $('<span>').text(src.split('/').pop().replace(/_/g, ' '))
|
||||
enlargeImageContainer.append(enlargedImage)
|
||||
enlargeImageContainer.append(name)
|
||||
setTimeout(function () {
|
||||
enlargeImageContainer.show()
|
||||
|
||||
const iframe = document.querySelector('iframe').contentWindow
|
||||
var iframe_document = iframe.document
|
||||
iframe_image = iframe_document.getElementsByTagName('img')[0]
|
||||
$(iframe_image).attr('style', 'width:100%; height:100%;')
|
||||
}, 100)
|
||||
}
|
||||
|
||||
function hideEnlargeImage() {
|
||||
var enlargeImageContainer = $('#enlargeImageContainer')
|
||||
enlargeImageContainer.empty()
|
||||
}
|
||||
|
||||
$(document).on('click', function (event) {
|
||||
if (!$(event.target).closest('#enlargeImageContainer').length) {
|
||||
hideEnlargeImage()
|
||||
}
|
||||
})
|
||||
function submitForm(elem) {
|
||||
$(elem).siblings(".add_more_submit").click();
|
||||
}
|
||||
</script>
|
||||
|
||||
159
asset/templates/asset_history/asset_history_nav.html
Normal file
159
asset/templates/asset_history/asset_history_nav.html
Normal file
@@ -0,0 +1,159 @@
|
||||
|
||||
{% load i18n %}
|
||||
{% load basefilters %}
|
||||
{% if perms.attendance.add_attendanceovertime or request.user|is_reportingmanager %}
|
||||
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="assetHistory"
|
||||
role="dialog"
|
||||
aria-labelledby="assetHistory"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="oh-modal__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="assetHistoryLavel">
|
||||
{% trans "Export Hour Accounts" %}
|
||||
</h2>
|
||||
<button class="oh-modal__close" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
<div
|
||||
class="oh-modal__dialog-body p-0 pt-2"
|
||||
id="assetHistoryModalBody"
|
||||
>
|
||||
{% comment %} <form
|
||||
action="{%url 'attendance-account-info-export' %}"
|
||||
method="get"
|
||||
onsubmit="event.stopPropagation();$(this).parents().find('.oh-modal--show').last().toggleClass('oh-modal--show');"
|
||||
id="assetHistoryForm"
|
||||
>
|
||||
{% csrf_token %} {% include 'attendance/attendance_account/attendance_account_export_filter.html'%}
|
||||
<div class="oh-dropdown__filter-footer">
|
||||
<button class="oh-btn oh-btn--secondary oh-btn--small w-100">
|
||||
{% trans "Export" %}
|
||||
</button>
|
||||
</div>
|
||||
</form> {% endcomment %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<section class="oh-wrapper oh-main__topbar" x-data="{searchShow: false}">
|
||||
<div class="oh-main__titlebar oh-main__titlebar--left">
|
||||
<h1 class="oh-main__titlebar-title fw-bold">
|
||||
<a href="{% url 'asset-history' %}" class='text-dark'>
|
||||
{% trans "Asset History" %}
|
||||
</a>
|
||||
</h1>
|
||||
<a
|
||||
class="oh-main__titlebar-search-toggle"
|
||||
role="button"
|
||||
aria-label="Toggle Search"
|
||||
@click="searchShow = !searchShow"
|
||||
>
|
||||
<ion-icon
|
||||
name="search-outline"
|
||||
class="oh-main__titlebar-serach-icon"
|
||||
></ion-icon>
|
||||
</a>
|
||||
</div>
|
||||
<div class="oh-main__titlebar oh-main__titlebar--right">
|
||||
<div
|
||||
class="oh-input-group oh-input__search-group"
|
||||
:class="searchShow ? 'oh-input__search-group--show' : ''"
|
||||
>
|
||||
<ion-icon
|
||||
name="search-outline"
|
||||
class="oh-input-group__icon oh-input-group__icon--left"
|
||||
></ion-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="oh-input oh-input__icon"
|
||||
aria-label="Search Input"
|
||||
id="attendance-search"
|
||||
name='search'
|
||||
placeholder="{% trans 'Search' %}"
|
||||
hx-get="{% url 'asset-history-search' %}"
|
||||
hx-trigger="keyup changed delay:500ms, search"
|
||||
hx-target="#historyTable"
|
||||
hx-swap="innerHTML"
|
||||
/>
|
||||
</div>
|
||||
<div class="oh-main__titlebar-button-container">
|
||||
<form
|
||||
hx-get="{% url 'asset-history-search' %}"
|
||||
hx-swap="innerHTML"
|
||||
hx-target="#historyTable"
|
||||
id="filterForm"
|
||||
class="d-flex"
|
||||
>
|
||||
<div class="oh-dropdown" x-data="{open: false}">
|
||||
<button class="oh-btn ml-2" @click="open = !open" onclick="event.preventDefault()">
|
||||
<ion-icon name="filter" class="mr-1"></ion-icon>{% trans "Filter" %}<div id="filterCount"></div>
|
||||
</button>
|
||||
<div
|
||||
class="oh-dropdown__menu oh-dropdown__menu--right oh-dropdown__filter p-4"
|
||||
x-show="open"
|
||||
@click.outside="open = false"
|
||||
style="display: none;
|
||||
width: 550px;"
|
||||
>
|
||||
{% include 'asset_history/asset_history_filter.html' %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-dropdown" x-data="{open: false}">
|
||||
<button class="oh-btn ml-2" @click="open = !open" onclick="event.preventDefault()">
|
||||
<ion-icon name="library-outline" class="mr-1"></ion-icon>{% trans "Group By" %}
|
||||
<div id="filterCount"></div>
|
||||
</button>
|
||||
<div
|
||||
class="oh-dropdown__menu oh-dropdown__menu--right oh-dropdown__filter p-4"
|
||||
x-show="open"
|
||||
@click.outside="open = false"
|
||||
style="display: none"
|
||||
>
|
||||
<div class="oh-accordion">
|
||||
<label for="id_field">{% trans "Group By" %}</label>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label" for="id_field">{% trans "Field" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<select
|
||||
class="oh-select mt-1 w-100"
|
||||
id="id_field"
|
||||
name="field"
|
||||
class="select2-selection select2-selection--single"
|
||||
>
|
||||
{% for field in gp_fields %}
|
||||
<option value="{{ field.0 }}">{% trans field.1 %}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#attendance-search').keydown(function (e) {
|
||||
var val = $(this).val();
|
||||
$('.pg').attr('hx-vals', `{"search":${val}}`);
|
||||
});
|
||||
$(document).ready(function(){
|
||||
$('#id_field').on('change',function(){
|
||||
$('.filterButton')[0].click();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
</section>
|
||||
153
asset/templates/asset_history/asset_history_single_view.html
Normal file
153
asset/templates/asset_history/asset_history_single_view.html
Normal file
@@ -0,0 +1,153 @@
|
||||
{% load static %} {% load i18n %}
|
||||
{% comment %} <div class="oh-modal__dialog oh-modal__dialog--navigation m-0 p-0">
|
||||
<button
|
||||
hx-get="{% url 'asset-allocation-individual-view' previous %}?allocations_ids={{allocations_ids}}"
|
||||
hx-target="#singleAllocate"
|
||||
class="oh-modal__diaglog-nav oh-modal__nav-prev"
|
||||
>
|
||||
<ion-icon
|
||||
name="chevron-back-outline"
|
||||
class="md hydrated"
|
||||
role="img"
|
||||
aria-label="chevron back outline"
|
||||
></ion-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
hx-get="{% url 'asset-allocation-individual-view' next %}?allocations_ids={{allocations_ids}}"
|
||||
hx-target="#singleAllocate"
|
||||
class="oh-modal__diaglog-nav oh-modal__nav-next"
|
||||
>
|
||||
<ion-icon
|
||||
name="chevron-forward-outline"
|
||||
class="md hydrated"
|
||||
role="img"
|
||||
aria-label="chevron forward outline"
|
||||
></ion-icon>
|
||||
</button>
|
||||
</div> {% endcomment %}
|
||||
|
||||
<a class="oh-timeoff-modal__profile-content pt-4" style="text-decoration:none;"
|
||||
href ="">
|
||||
<div class="oh-profile mb-2">
|
||||
<div class="oh-profile__avatar">
|
||||
<img
|
||||
src="{{asset_assignment.assigned_to_employee_id.get_avatar}}"
|
||||
class="oh-profile__image me-2"
|
||||
alt="Mary Magdalene"
|
||||
/>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__profile-info">
|
||||
<span class="oh-timeoff-modal__user fw-bold m-0"
|
||||
>{{asset_assignment.asset_id}}</span
|
||||
>
|
||||
<span
|
||||
class="oh-timeoff-modal__user m-0"
|
||||
style="font-size: 18px; color: #4d4a4a"
|
||||
>
|
||||
{{asset_assignment.asset_id.asset_category_id}} </span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="oh-timeoff-modal__stats-container">
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Allocated User" %}</span
|
||||
>
|
||||
<span class="oh-timeoff-modal__stat-count"
|
||||
>{{asset_assignment.assigned_to_employee_id}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Returned Status" %}
|
||||
</span>
|
||||
<span class="oh-timeoff-modal__stat-count"
|
||||
>{{asset_assignment.return_status}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oh-timeoff-modal__stats-container mt-3">
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Allocated Date" %}
|
||||
</span>
|
||||
<span class="oh-timeoff-modal__stat-count dateformat_changer"
|
||||
>{{asset_assignment.assigned_date}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Returned Date" %}
|
||||
</span>
|
||||
<span class="oh-timeoff-modal__stat-count dateformat_changer"
|
||||
>{{asset_assignment.return_date}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stats-container mt-3">
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title">{% trans "Asset" %}</span>
|
||||
<span class="oh-timeoff-modal__stat-count"
|
||||
>{{asset_assignment.asset_id}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Return Description" %}</span
|
||||
>
|
||||
<div class="oh-timeoff-modal__stat-description">
|
||||
{{asset_assignment.return_condition}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oh-timeoff-modal__stats-container mt-3 ">
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title">{% trans "Assign Condition Images" %}</span>
|
||||
<span class="oh-timeoff-modal__stat-count"
|
||||
>
|
||||
<div class="d-flex mt-2 mb-2">
|
||||
{% for doc in asset_assignment.assign_images.all %}
|
||||
<a
|
||||
href="{{doc.image.url}}"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
><span
|
||||
class="oh-file-icon oh-file-icon--pdf"
|
||||
onmouseover="enlargeImage('{{doc.image.url}}')"
|
||||
style="width:40px;height:40px"
|
||||
></span
|
||||
></a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Return Condition Images" %}</span
|
||||
>
|
||||
<div class="oh-timeoff-modal__stat-description">
|
||||
<div class="d-flex ">
|
||||
{% for doc in asset_assignment.return_images.all %}
|
||||
<a
|
||||
href="{{doc.image.url}}"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
><span
|
||||
class="oh-file-icon oh-file-icon--pdf"
|
||||
onmouseover="enlargeImage('{{doc.image.url}}')"
|
||||
style="width:40px;height:40px"
|
||||
></span
|
||||
></a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-3 " id="enlargeImageContainer"></div>
|
||||
|
||||
13
asset/templates/asset_history/asset_history_view.html
Normal file
13
asset/templates/asset_history/asset_history_view.html
Normal file
@@ -0,0 +1,13 @@
|
||||
{% extends 'index.html' %}{% block content %}
|
||||
{% load static %}{% load i18n %}
|
||||
{% include 'asset_history/asset_history_nav.html' %}
|
||||
|
||||
<div class="oh-checkpoint-badge mb-2" id="selectedInstances" data-ids="[]" data-clicked="" style="display:none;" >
|
||||
{% trans "Selected Assets" %}
|
||||
</div>
|
||||
|
||||
<div class="oh-wrapper">
|
||||
{% include 'asset_history/asset_history_list.html' %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
272
asset/templates/asset_history/group_by.html
Normal file
272
asset/templates/asset_history/group_by.html
Normal file
@@ -0,0 +1,272 @@
|
||||
{% load attendancefilters %} {% load basefilters %} {% load static %}
|
||||
{% load i18n %} {% include 'filter_tags.html' %}
|
||||
<div class="oh-card">
|
||||
{% for asset_history_list in asset_assignments %}
|
||||
<div class="oh-accordion-meta">
|
||||
<div class="oh-accordion-meta__item">
|
||||
<div
|
||||
class="oh-accordion-meta__header"
|
||||
onclick='$(this).toggleClass("oh-accordion-meta__header--show");'
|
||||
>
|
||||
<span class="oh-accordion-meta__title pt-3 pb-3">
|
||||
<div class="oh-tabs__input-badge-container">
|
||||
<span
|
||||
class="oh-badge oh-badge--secondary oh-badge--small oh-badge--round mr-1"
|
||||
>
|
||||
{{asset_history_list.list|length}}
|
||||
</span>
|
||||
{{asset_history_list.grouper}}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="oh-accordion-meta__body d-none">
|
||||
<div class="oh-sticky-table oh-sticky-table--no-overflow mb-5">
|
||||
<div class="oh-sticky-table">
|
||||
<div class="oh-sticky-table__table">
|
||||
<div class="oh-sticky-table__thead">
|
||||
<div class="oh-sticky-table__tr">
|
||||
<div
|
||||
class="oh-sticky-table__th"
|
||||
hx-get=""
|
||||
hx-target="#historyTable"
|
||||
>
|
||||
{% trans "Asset" %}
|
||||
</div>
|
||||
<div
|
||||
class="oh-sticky-table__th {% if request.sort_option.order == '-assigned_to_employee_id__employee_first_name' %}arrow-up {% elif request.sort_option.order == 'assigned_to_employee_id__employee_first_name' %}arrow-down {% else %}arrow-up-down {% endif %}"
|
||||
hx-get=""
|
||||
hx-target="#historyTable"
|
||||
>
|
||||
{% trans "Employee" %}
|
||||
</div>
|
||||
<div
|
||||
class="oh-sticky-table__th"
|
||||
hx-get=""
|
||||
hx-target="#historyTable"
|
||||
>
|
||||
{% trans "Assigned Date" %}
|
||||
</div>
|
||||
<div
|
||||
class="oh-sticky-table__th"
|
||||
hx-get=""
|
||||
hx-target="#historyTable"
|
||||
>
|
||||
{% trans "Returned Date" %}
|
||||
</div>
|
||||
<div
|
||||
class="oh-sticky-table__th"
|
||||
hx-get=""
|
||||
hx-target="#historyTable"
|
||||
>
|
||||
{% trans "Return Status" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__tbody">
|
||||
{% for asset_assignement in asset_history_list.list %}
|
||||
<div
|
||||
class="oh-sticky-table__tr"
|
||||
hx-get='{% url "asset-history-single-view" asset_assignement.id %}'
|
||||
hx-target="#historySingleModalBody"
|
||||
data-toggle="oh-modal-toggle"
|
||||
,
|
||||
data-target="#historySingleModal"
|
||||
>
|
||||
<div class="oh-sticky-table__sd">
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div
|
||||
class="oh-profile__avatar mr-1"
|
||||
>
|
||||
<img
|
||||
src="https://ui-avatars.com/api/?name={{asset_assignement.asset_id.asset_name}}&background=random"
|
||||
class="oh-profile__image"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
class="oh-profile__name oh-text--dark"
|
||||
>{{asset_assignement.asset_id}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
{{asset_assignement.assigned_to_employee_id}}
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
{{asset_assignement.assigned_date}}
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
{{asset_assignement.return_date}}
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
{{asset_assignement.return_status}}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oh-pagination">
|
||||
<span class="oh-pagination__page">
|
||||
{% trans "Page" %} {{ asset_history_list.list.number }}
|
||||
{%trans "of" %} {{asset_history_list.list.paginator.num_pages }}.
|
||||
</span>
|
||||
<nav class="oh-pagination__nav">
|
||||
<div class="oh-pagination__input-container me-3">
|
||||
<span class="oh-pagination__label me-1"
|
||||
>{% trans "Page" %}</span
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
name="{{asset_history_list.dynamic_name}}"
|
||||
class="oh-pagination__input"
|
||||
value="{{asset_history_list.list.number}}"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}"
|
||||
hx-target="#historyTable"
|
||||
min="1"
|
||||
/>
|
||||
<span class="oh-pagination__label"
|
||||
>{% trans "of" %}
|
||||
{{asset_history_list.list.paginator.num_pages}}</span
|
||||
>
|
||||
</div>
|
||||
<ul class="oh-pagination__items">
|
||||
{% if asset_history_list.list.has_previous %}
|
||||
<li
|
||||
class="oh-pagination__item oh-pagination__item--wide"
|
||||
>
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&{{asset_history_list.dynamic_name}}=1"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "First" %}</a
|
||||
>
|
||||
</li>
|
||||
<li
|
||||
class="oh-pagination__item oh-pagination__item--wide"
|
||||
>
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&{{asset_history_list.dynamic_name}}={{ asset_history_list.list.previous_page_number }}"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "Previous" %}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %} {% if asset_history_list.list.has_next %}
|
||||
<li
|
||||
class="oh-pagination__item oh-pagination__item--wide"
|
||||
>
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&{{asset_history_list.dynamic_name}}={{ asset_history_list.list.next_page_number }}"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "Next" %}</a
|
||||
>
|
||||
</li>
|
||||
<li
|
||||
class="oh-pagination__item oh-pagination__item--wide"
|
||||
>
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&{{asset_history_list.dynamic_name}}={{ asset_history_list.list.paginator.num_pages }}"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "Last" %}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="oh-pagination">
|
||||
<span class="oh-pagination__page">
|
||||
{% trans "Page" %} {{ asset_assignments.number }} {% trans "of" %}
|
||||
{{ asset_assignments.paginator.num_pages }}.
|
||||
</span>
|
||||
<nav class="oh-pagination__nav">
|
||||
<div class="oh-pagination__input-container me-3">
|
||||
<span class="oh-pagination__label me-1"
|
||||
>{% trans "Page" %}</span
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
name="page"
|
||||
class="oh-pagination__input"
|
||||
value="{{asset_assignments.number}}"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}"
|
||||
hx-target="#historyTable"
|
||||
min="1"
|
||||
/>
|
||||
<span class="oh-pagination__label"
|
||||
>{% trans "of" %}
|
||||
{{asset_assignments.paginator.num_pages}}</span
|
||||
>
|
||||
</div>
|
||||
<ul class="oh-pagination__items">
|
||||
{% if asset_assignments.has_previous %}
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&page=1"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "First" %}</a
|
||||
>
|
||||
</li>
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&page={{ asset_assignments.previous_page_number }}"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "Previous" %}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %} {% if asset_assignments.has_next %}
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&page={{ asset_assignments.next_page_number }}"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "Next" %}</a
|
||||
>
|
||||
</li>
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a
|
||||
hx-target="#historyTable"
|
||||
hx-get="{% url 'asset-history-search' %}?{{pd}}&page={{ asset_assignments.paginator.num_pages }}"
|
||||
class="oh-pagination__link"
|
||||
>{% trans "Last" %}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="historySingleModal"
|
||||
role="dialog"
|
||||
aria-labelledby="historySingleModal"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="oh-modal__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="historySingleModalLabel">
|
||||
{% trans "Asset Details" %}
|
||||
</h2>
|
||||
<button class="oh-modal__close" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
<div
|
||||
class="oh-modal__dialog-body p-0 pt-2"
|
||||
id="historySingleModalBody"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
<h5 >{% trans "Asset Allocation" %}</h5>
|
||||
<form hx-post="{%url 'asset-allocate-creation' %}" hx-target="#asset-request-allocation-modal-target">
|
||||
<form hx-post="{%url 'asset-allocate-creation' %}" hx-target="#asset-request-allocation-modal-target" hx-encoding="multipart/form-data" >
|
||||
{% csrf_token %}
|
||||
<div class=" m-3">
|
||||
<div class="oh-input__group ">
|
||||
@@ -18,6 +18,11 @@
|
||||
{{asset_allocation_form.assigned_by_employee_id}}
|
||||
{{asset_allocation_form.assigned_by_employee_id.errors}}
|
||||
</div>
|
||||
<div class="oh-input__group ">
|
||||
<label class="oh-input__label" for="{{asset_allocation_form.assign_images.id_for_label}}">{% trans "Assign condition images" %}</label>
|
||||
{{asset_allocation_form.assign_images}}
|
||||
{{asset_allocation_form.assign_images.errors}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-footer">
|
||||
<button type="submit" class="oh-btn oh-btn--secondary oh-btn--shadow">
|
||||
|
||||
@@ -152,4 +152,19 @@ urlpatterns = [
|
||||
path(
|
||||
"asset-category-chart/", views.asset_category_chart, name="asset-category-chart"
|
||||
),
|
||||
path(
|
||||
"asset-history",
|
||||
views.asset_history,
|
||||
name="asset-history",
|
||||
),
|
||||
path(
|
||||
"asset-history-single-view/<int:asset_id>",
|
||||
views.asset_history_single_view,
|
||||
name="asset-history-single-view",
|
||||
),
|
||||
path(
|
||||
"asset-history-search",
|
||||
views.asset_history_search,
|
||||
name="asset-history-search",
|
||||
),
|
||||
]
|
||||
|
||||
106
asset/views.py
106
asset/views.py
@@ -2,19 +2,22 @@
|
||||
asset.py
|
||||
|
||||
This module is used to """
|
||||
|
||||
from datetime import date, datetime
|
||||
import json
|
||||
from django.db.models import Q
|
||||
from urllib.parse import parse_qs
|
||||
import pandas as pd
|
||||
from django.db.models import ProtectedError
|
||||
from django.shortcuts import render, redirect
|
||||
from django.shortcuts import get_object_or_404, render, redirect
|
||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||
from django.contrib import messages
|
||||
from django.core.paginator import Paginator
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from base.methods import closest_numbers, get_key_instances, get_pagination
|
||||
from attendance.methods.group_by import group_by_queryset
|
||||
from base.methods import closest_numbers, get_key_instances, get_pagination, sortby
|
||||
from base.models import Company
|
||||
from base.views import paginator_qry
|
||||
from employee.models import EmployeeWorkInformation
|
||||
from notifications.signals import notify
|
||||
from horilla.decorators import login_required, hx_request_required, manager_can_enter
|
||||
@@ -26,6 +29,7 @@ from asset.models import (
|
||||
AssetAssignment,
|
||||
AssetCategory,
|
||||
AssetLot,
|
||||
ReturnImages,
|
||||
)
|
||||
from asset.forms import (
|
||||
AssetBatchForm,
|
||||
@@ -40,6 +44,8 @@ from asset.forms import (
|
||||
from asset.filters import (
|
||||
AssetAllocationFilter,
|
||||
AssetAllocationReGroup,
|
||||
AssetHistoryFilter,
|
||||
AssetHistoryReGroup,
|
||||
AssetRequestFilter,
|
||||
AssetRequestReGroup,
|
||||
CustomAssetFilter,
|
||||
@@ -614,7 +620,9 @@ def asset_allocate_creation(request):
|
||||
- to allocated view.
|
||||
"""
|
||||
|
||||
form = AssetAllocationForm()
|
||||
form = AssetAllocationForm(
|
||||
initial={"assigned_by_employee_id": request.user.employee_get}
|
||||
)
|
||||
context = {"asset_allocation_form": form}
|
||||
if request.method == "POST":
|
||||
form = AssetAllocationForm(request.POST)
|
||||
@@ -623,20 +631,31 @@ def asset_allocate_creation(request):
|
||||
asset = Asset.objects.filter(id=asset).first()
|
||||
asset.asset_status = "In use"
|
||||
asset.save()
|
||||
form.save()
|
||||
instance = form.save()
|
||||
files = request.FILES.getlist("assign_images")
|
||||
attachments = []
|
||||
if request.FILES:
|
||||
for file in files:
|
||||
attachment = ReturnImages()
|
||||
attachment.image = file
|
||||
attachment.save()
|
||||
attachments.append(attachment)
|
||||
instance.assign_images.add(*attachments)
|
||||
messages.success(request, _("Asset allocated successfully!."))
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
context["asset_allocation_form"] = form
|
||||
|
||||
return render(request, "request_allocation/asset_allocation_creation.html", context)
|
||||
|
||||
|
||||
def asset_allocate_return_request(request, asset_id):
|
||||
asset_assign = AssetAssignment.objects.get(id=asset_id)
|
||||
asset_assign.return_request = True
|
||||
asset_assign.save()
|
||||
message = _("Return request for {} initiated.").format(asset_assign.asset_id)
|
||||
messages.info(request, message)
|
||||
return redirect('asset-request-allocation-view')
|
||||
return redirect("asset-request-allocation-view")
|
||||
|
||||
|
||||
@login_required
|
||||
def asset_allocate_return(request, asset_id):
|
||||
@@ -660,6 +679,8 @@ def asset_allocate_return(request, asset_id):
|
||||
asset_return_status = request.POST.get("return_status")
|
||||
asset_return_date = request.POST.get("return_date")
|
||||
asset_return_condition = request.POST.get("return_condition")
|
||||
files = request.FILES.getlist("return_images")
|
||||
attachments = []
|
||||
context = {"asset_return_form": asset_return_form, "asset_id": asset_id}
|
||||
response = render(request, "asset/asset_return_form.html", context)
|
||||
if asset_return_status == "Healthy":
|
||||
@@ -671,6 +692,13 @@ def asset_allocate_return(request, asset_id):
|
||||
asset_allocation.return_condition = asset_return_condition
|
||||
asset_allocation.return_request = False
|
||||
asset_allocation.save()
|
||||
if request.FILES:
|
||||
for file in files:
|
||||
attachment = ReturnImages()
|
||||
attachment.image = file
|
||||
attachment.save()
|
||||
attachments.append(attachment)
|
||||
asset_allocation.return_images.add(*attachments)
|
||||
asset.asset_status = "Available"
|
||||
asset.save()
|
||||
messages.info(request, _("Asset Return Successful !."))
|
||||
@@ -687,6 +715,13 @@ def asset_allocate_return(request, asset_id):
|
||||
asset_allocation.return_status = asset_return_status
|
||||
asset_allocation.return_condition = asset_return_condition
|
||||
asset_allocation.save()
|
||||
if request.FILES:
|
||||
for file in files:
|
||||
attachment = ReturnImages()
|
||||
attachment.image = file
|
||||
attachment.save()
|
||||
attachments.append(attachment)
|
||||
asset_allocation.return_images.add(*attachments)
|
||||
messages.info(request, _("Asset Return Successful!."))
|
||||
return HttpResponse(
|
||||
response.content.decode("utf-8") + "<script>location.reload();</script>"
|
||||
@@ -910,7 +945,10 @@ def asset_request_alloaction_view_search_filter(request):
|
||||
|
||||
def asset_request_individual_view(request, id):
|
||||
asset_request = AssetRequest.objects.get(id=id)
|
||||
context = {"asset_request": asset_request,'dashboard': request.GET.get('dashboard'),}
|
||||
context = {
|
||||
"asset_request": asset_request,
|
||||
"dashboard": request.GET.get("dashboard"),
|
||||
}
|
||||
requests_ids_json = request.GET.get("requests_ids")
|
||||
if requests_ids_json:
|
||||
requests_ids = json.loads(requests_ids_json)
|
||||
@@ -1352,7 +1390,7 @@ def asset_available_chart(request):
|
||||
"labels": labels,
|
||||
"dataset": dataset,
|
||||
"message": _("Oops!! No Asset found..."),
|
||||
"emptyImageSrc":"/static/images/ui/asset.png",
|
||||
"emptyImageSrc": "/static/images/ui/asset.png",
|
||||
}
|
||||
return JsonResponse(response)
|
||||
|
||||
@@ -1382,6 +1420,58 @@ def asset_category_chart(request):
|
||||
"labels": labels,
|
||||
"dataset": dataset,
|
||||
"message": _("Oops!! No Asset found..."),
|
||||
"emptyImageSrc":"/static/images/ui/asset.png",
|
||||
"emptyImageSrc": "/static/images/ui/asset.png",
|
||||
}
|
||||
return JsonResponse(response)
|
||||
|
||||
|
||||
@login_required
|
||||
def asset_history(request):
|
||||
previous_data = request.GET.urlencode() + "&returned_assets=True"
|
||||
asset_assignments = AssetHistoryFilter({"returned_assets": "True"}).qs.order_by("-id")
|
||||
data_dict = parse_qs(previous_data)
|
||||
get_key_instances(AssetAssignment, data_dict)
|
||||
asset_assignments= paginator_qry(asset_assignments,request.GET.get("page"))
|
||||
context = {
|
||||
"asset_assignments": asset_assignments,
|
||||
"f": AssetHistoryFilter(),
|
||||
"filter_dict": data_dict,
|
||||
"gp_fields": AssetHistoryReGroup().fields,
|
||||
"pd":previous_data,
|
||||
}
|
||||
return render(request, "asset_history/asset_history_view.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
def asset_history_single_view(request, asset_id):
|
||||
asset_assignment = get_object_or_404(AssetAssignment, id=asset_id)
|
||||
return render(
|
||||
request,
|
||||
"asset_history/asset_history_single_view.html",
|
||||
{"asset_assignment": asset_assignment},
|
||||
)
|
||||
|
||||
@login_required
|
||||
def asset_history_search(request):
|
||||
previous_data = request.GET.urlencode()
|
||||
asset_assignments = AssetHistoryFilter(request.GET).qs.order_by("-id")
|
||||
asset_assignments = sortby(request, asset_assignments, "sortby")
|
||||
template = "asset_history/asset_history_list.html"
|
||||
field = request.GET.get("field")
|
||||
if field != "" and field is not None:
|
||||
asset_assignments = group_by_queryset(asset_assignments, field, request.GET.get("page"), "page")
|
||||
template = "asset_history/group_by.html"
|
||||
asset_assignments= paginator_qry(asset_assignments,request.GET.get("page"))
|
||||
data_dict = parse_qs(previous_data)
|
||||
get_key_instances(AssetAssignment, data_dict)
|
||||
|
||||
return render(
|
||||
request,
|
||||
template,
|
||||
{
|
||||
"asset_assignments": asset_assignments,
|
||||
"filter_dict": data_dict,
|
||||
"field": field,
|
||||
"pd":previous_data,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -857,6 +857,15 @@
|
||||
>{% trans "Request and Allocation" %}</a
|
||||
>
|
||||
</li>
|
||||
{% if perms.asset.view_assetcategory %}
|
||||
<li class="oh-sidebar__submenu-item">
|
||||
<a
|
||||
href="{% url 'asset-history' %}"
|
||||
class="oh-sidebar__submenu-link"
|
||||
>{% trans "Asset History" %}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user