WIP: Basic work on audit

This commit is contained in:
2020-02-09 00:04:54 +00:00
parent ae151ed45e
commit e9a9250027
12 changed files with 192 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
<div class="modal fade" id="itemModal" role="dialog" aria-labelledby="itemModal" aria-hidded="true">
<div class="modal fade" id="itemModal" role="dialog" aria-labelledby="itemModal" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
@@ -71,4 +71,4 @@
</form>
</div>
</div>
</div>
</div>

View File

@@ -12,7 +12,7 @@ class AssetForm(forms.ModelForm):
class Meta:
model = models.Asset
fields = '__all__'
exclude = ['asset_id_prefix', 'asset_id_number']
exclude = ['asset_id_prefix', 'asset_id_number', 'last_audited_at', 'last_audited_by']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

View File

@@ -0,0 +1,26 @@
# Generated by Django 2.0.13 on 2020-02-08 23:04
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('assets', '0010_auto_20200207_1737'),
]
operations = [
migrations.AddField(
model_name='asset',
name='last_audited_at',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='asset',
name='last_audited_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='audited_by', to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -9,7 +9,7 @@ from django.dispatch.dispatcher import receiver
from reversion import revisions as reversion
from reversion.models import Version
from RIGS.models import RevisionMixin
from RIGS.models import RevisionMixin, Profile
class AssetCategory(models.Model):
@@ -88,8 +88,13 @@ class Asset(models.Model, RevisionMixin):
purchase_price = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=10)
salvage_value = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=10)
comments = models.TextField(blank=True)
# TODO Remove
next_sched_maint = models.DateField(blank=True, null=True)
# Audit
last_audited_at = models.DateTimeField(blank=True, null=True)
last_audited_by = models.ForeignKey(Profile, on_delete=models.SET_NULL, related_name='audited_by', blank=True, null=True)
# Cable assets
is_cable = models.BooleanField(default=False)
plug = models.ForeignKey(Connector, on_delete=models.SET_NULL,

View File

@@ -0,0 +1,82 @@
{% extends 'base_assets.html' %}
{% load widget_tweaks %}
{% block title %}Audit Asset {{ object.asset_id }}{% endblock %}
{% block content %}
<div class="page-header">
<h1>
Audit Asset: {{ object.asset_id }}
</h1>
</div>
<form class="form-horizontal" method="post" id="asset_update_form" action="{% url 'asset_audit' pk=object.asset_id%}">
{% include 'form_errors.html' %}
{% csrf_token %}
<input type="hidden" name="id" value="{{ object.id|default:0 }}" hidden=true>
<div class="col-sm-12">
<div class="form-group">
<label for="{{ form.asset_id.id_for_label }}" class="col-sm-2 control-label">Asset ID</label>
<div class="col-sm-10">
{% render_field form.asset_id|add_class:'form-control' value=object.asset_id %}
</div>
</div>
<div class="form-group">
<label for="{{ form.description.id_for_label }}" class="col-sm-2 control-label">Description</label>
<div class="col-sm-10">
{% render_field form.description|add_class:'form-control' value=object.description %}
</div>
</div>
<div class="form-group">
<label for="{{ form.category.id_for_label }}" class="col-sm-2 control-label">Category</label>
<div class="col-sm-10">
{% render_field form.category|add_class:'form-control'%}
</div>
</div>
<div class="form-group">
<label for="{{ form.status.id_for_label }}" class="col-sm-2 control-label">Status</label>
<div class="col-sm-10">
{% render_field form.status|add_class:'form-control'%}
</div>
</div>
<div class="form-group">
<label for="{{ form.serial_number.id_for_label }}" class="col-sm-2 control-label">Serial Number</label>
<div class="col-sm-10">
{% render_field form.serial_number|add_class:'form-control' value=object.serial_number %}
</div>
</div>
<div class="form-group">
<label for="{{ form.date_acquired.id_for_label }}" class="col-sm-2 control-label">Date Acquired</label>
<div class="col-sm-10">
{% render_field form.date_acquired|add_class:'form-control' value=object.date_acquired %}
</div>
<!--- TODO Add buttons for 'today' and 'unknown' (sets to beginning of time)--->
</div>
<div class="form-group">
<label for="{{ form.is_cable.id_for_label }}" class="col-sm-2 control-label">Cable?</label>
<div class="col-sm-10">
{% render_field form.is_cable|attr:'onchange=checkIfCableHidden()' %}
</div>
</div>
<div class="row">
<div class="col-md-10 pull-right">
<button type="submit" class="btn btn-success"><i class="glyphicon glyphicon-floppy-disk"></i> Audit</button>
<br>
<button type="reset" class="btn btn-link" onclick="history.back()">Cancel</button>
</div>
</div>
</form>
{% endblock %}
{% block js%}
{% if edit %}
<script>
function checkIfCableHidden() {
if (document.getElementById("id_is_cable").checked) {
document.getElementById("cable-table").hidden = false;
} else {
document.getElementById("cable-table").hidden = true;
}
}
checkIfCableHidden();
</script>
{% endif %}
{% endblock %}

View File

@@ -9,26 +9,7 @@
<h1 class="text-center">Asset List</h1>
</div>
<form id="asset-search-form" method="get" class="form-inline pull-right">
<div class="input-group pull-right" style="width: auto;">
{% render_field form.query|add_class:'form-control' placeholder='Search by Asset ID/Desc/Serial' style="width: 250px"%}
<label for="query" class="sr-only">Asset ID/Description/Serial Number:</label>
<span class="input-group-btn"><button type="submit" class="btn btn-default">Search</button></span>
</div>
<br>
<div style="margin-top: 1em;" class="pull-right">
<div id="category-group" class="form-group">
<label for="category" class="sr-only">Category</label>
{% render_field form.category|attr:'multiple'|add_class:'form-control selectpicker' data-none-selected-text="Categories" data-header="Categories" data-actions-box="true" %}
</div>
<div id="status-group" class="form-group">
<label for="status" class="sr-only">Status</label>
{% render_field form.status|attr:'multiple'|add_class:'form-control selectpicker' data-none-selected-text="Statuses" data-header="Statuses" data-actions-box="true" %}
</div>
<!---TODO: Auto filter whenever an option is selected, instead of using a button -->
<button id="filter-submit" type="submit" class="btn btn-default">Filter</button>
</div>
</form>
{% include 'partials/asset_search.html' %}
<table class="table">
<thead>

View File

@@ -35,6 +35,11 @@
<div class="col-md-4">
{% include 'partials/parent_form.html' %}
</div>
{% if not edit %}
<div class="col-md-4">
{% include 'partials/audit_details.html' %}
</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-12">

View File

@@ -0,0 +1,28 @@
{% extends request.is_ajax|yesno:'base_ajax.html,base_assets.html' %}
{% load widget_tweaks %}
{% block title %}Asset Search{% endblock %}
{% block content %}
<form id="asset-search-form" method="get" class="form-inline pull-right">
<div class="input-group pull-right" style="width: auto;">
{% render_field form.query|add_class:'form-control' placeholder='Search by Asset ID/Desc/Serial' style="width: 250px"%}
<label for="query" class="sr-only">Asset ID/Description/Serial Number:</label>
<span class="input-group-btn"><button type="submit" class="btn btn-default">Search</button></span>
</div>
<br>
<div style="margin-top: 1em;" class="pull-right">
<div id="category-group" class="form-group">
<label for="category" class="sr-only">Category</label>
{% render_field form.category|attr:'multiple'|add_class:'form-control selectpicker' data-none-selected-text="Categories" data-header="Categories" data-actions-box="true" %}
</div>
<div id="status-group" class="form-group">
<label for="status" class="sr-only">Status</label>
{% render_field form.status|attr:'multiple'|add_class:'form-control selectpicker' data-none-selected-text="Statuses" data-header="Statuses" data-actions-box="true" %}
</div>
<!---TODO: Auto filter whenever an option is selected, instead of using a button -->
<button id="filter-submit" type="submit" class="btn btn-default">Filter</button>
</div>
</form>
{% endblock %}

View File

@@ -0,0 +1,8 @@
<div class="panel {% if object.last_audited_at is not None %} panel-success {% else %} panel-default {% endif %}">
<div class="panel-heading">
Audit Details
</div>
<div class="panel-body">
<p>Audited at <span class="label label-default">{{ object.last_audited_at|default_if_none:'-' }}</span> by <span class="label label-info">{{ object.last_audited_by|default_if_none:'-' }}</span></p>
</div>
</div>

View File

@@ -31,6 +31,9 @@ urlpatterns = [
views.AssetOembed.as_view(),
name='asset_oembed'),
path('asset/audit/', permission_required_with_403('assets.view_asset')(views.AssetAuditList.as_view()), name='asset_audit_list'),
path('asset/id/<str:pk>/audit/', permission_required_with_403('assets.view_asset')(views.AssetAudit.as_view()), name='asset_audit'),
path('supplier/list', views.SupplierList.as_view(), name='supplier_list'),
path('supplier/<int:pk>', views.SupplierDetail.as_view(), name='supplier_detail'),
path('supplier/create', permission_required_with_403('assets.add_supplier')

View File

@@ -11,6 +11,7 @@ from assets import models, forms
from RIGS import versioning
import simplejson
import datetime
@method_decorator(csrf_exempt, name='dispatch')
@@ -173,6 +174,34 @@ class AssetEmbed(AssetDetail):
template_name = 'asset_embed.html'
class AssetAuditList(LoginRequiredMixin, generic.ListView):
model = models.Asset
template_name = 'asset_list.html'
paginate_by = 40
ordering = ['-pk']
class AssetAudit(LoginRequiredMixin, AssetIDUrlMixin, generic.UpdateView):
template_name = 'asset_audit.html'
model = models.Asset
form_class = forms.AssetForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['edit'] = True
context['connectors'] = models.Connector.objects.all()
return context
def get_success_url(self):
# TODO For some reason this doesn't stick when done in form_valid??
asset = self.get_object()
asset.last_audited_by = self.request.user
asset.last_audited_at = datetime.datetime.now()
asset.save()
return reverse("asset_audit_list")
class SupplierList(generic.ListView):
model = models.Supplier
template_name = 'supplier_list.html'

View File

@@ -35,5 +35,6 @@
{# % endif % #}
{% if perms.assets.view_asset %}
<li><a href="{% url 'asset_activity_table' %}">Recent Changes</a></li>
<li><a href="{% url 'asset_audit_list' %}">Audit</a></li>
{% endif %}
{% endblock %}