Compare commits

..

11 Commits

26 changed files with 129 additions and 421 deletions

View File

@@ -245,7 +245,7 @@
<div class="row">
<div class="col-sm-10 align-left">
<a href="{% url 'event_history' object.pk %}" title="View Revision History">
Last edited at {{ object.last_edited_at|default:'never' }} by {{ object.last_edited_by.name|default:'nobody' }}
Last edited at {{ object.last_edited_at }} by {{ object.last_edited_by.name }}
</a>
</div>
<div class="col-sm-2">

View File

@@ -6,7 +6,7 @@
<p>
Your event <b>N{{ object.event.pk|stringformat:"05d" }}</b> has been successfully authorised
for <b>&pound;{{ object.amount }}</b>
by <b>{{ object.name }}</b> as of <b>{{ object.event.last_edited_at }}</b>.
by <b>{{ object.name }}</b> as of <b>{{ object.last_edited_at }}</b>.
</p>
<p>

View File

@@ -1,6 +1,6 @@
Hi {{ to_name|default_if_none:"there" }},
Hi {{ to_name|default:"there" }},
Your event N{{object.event.pk|stringformat:"05d"}} has been successfully authorised for £{{object.amount}} by {{object.name}} as of {{object.event.last_edited_at}}.
Your event N{{object.event.pk|stringformat:"05d"}} has been successfully authorised for £{{object.amount}} by {{object.name}} as of {{object.last_edited_at}}.
{% if object.event.organisation and object.event.organisation.union_account %}{# internal #}
Your event is now fully booked and payment will be processed by the finance department automatically.

View File

@@ -1,5 +1,5 @@
Hi {{object.event.mic.get_full_name|default_if_none:"somebody"}},
Just to let you know your event N{{object.event.pk|stringformat:"05d"}} has been successfully authorised for £{{object.amount}} by {{object.name}} as of {{object.event.last_edited_at}}.
Just to let you know your event N{{object.event.pk|stringformat:"05d"}} has been successfully authorised for £{{object.amount}} by {{object.name}} as of {{object.last_edited_at}}.
The TEC Rig Information Gathering System

View File

@@ -72,8 +72,9 @@
</div>
</div>
{% if perms.RIGS.view_event %}
<div class="col-sm-6">
<div class="col-sm-6" >
{% include 'RIGS/activity_feed.html' %}
</div>
{% endif %}
</div>

View File

@@ -1,9 +0,0 @@
{% extends 'base_rigs.html' %}
{% block title %}Password Reset Disabled{% endblock %}
{% block content %}
<h1>Password reset is disabled</h1>
<p> We are very sorry for the inconvenience, but due to a security vulnerability, password reset is currently disabled until the vulnerability can be patched.</p>
<p> If you are locked out of your account, please contact an administrator and we can manually perform a reset</p>
{% endblock %}

View File

@@ -19,7 +19,7 @@ urlpatterns = [
url('^user/login/$', views.login, name='login'),
url('^user/login/embed/$', xframe_options_exempt(views.login_embed), name='login_embed'),
url(r'^user/password_reset/$', views.PasswordResetDisabled.as_view()),
url(r'^user/password_reset/$', password_reset, {'password_reset_form': forms.PasswordReset}),
# People
url(r'^people/$', permission_required_with_403('RIGS.view_person')(views.PersonList.as_view()),

View File

@@ -168,7 +168,7 @@ class RIGSVersionManager(VersionQuerySet):
for model in model_array:
content_types.append(ContentType.objects.get_for_model(model))
return self.filter(content_type__in=content_types).select_related("revision").order_by("-revision__date_created")
return self.filter(content_type__in=content_types).select_related("revision").order_by("-pk")
class RIGSVersion(Version):
@@ -206,14 +206,17 @@ class VersionHistory(generic.ListView):
paginate_by = 25
def get_queryset(self, **kwargs):
return RIGSVersion.objects.get_for_object(self.get_object()).select_related("revision", "revision__user").all().order_by("-revision__date_created")
thisModel = self.kwargs['model']
def get_object(self, **kwargs):
return get_object_or_404(self.kwargs['model'], pk=self.kwargs['pk'])
versions = RIGSVersion.objects.get_for_object_reference(thisModel, self.kwargs['pk']).select_related("revision", "revision__user").all()
return versions
def get_context_data(self, **kwargs):
thisModel = self.kwargs['model']
context = super(VersionHistory, self).get_context_data(**kwargs)
context['object'] = self.get_object()
thisObject = get_object_or_404(thisModel, pk=self.kwargs['pk'])
context['object'] = thisObject
return context
@@ -225,7 +228,7 @@ class ActivityTable(generic.ListView):
def get_queryset(self):
versions = RIGSVersion.objects.get_for_multiple_models([models.Event, models.Venue, models.Person, models.Organisation, models.EventAuthorisation])
return versions.order_by("-revision__date_created")
return versions
class ActivityFeed(generic.ListView):
@@ -235,7 +238,7 @@ class ActivityFeed(generic.ListView):
def get_queryset(self):
versions = RIGSVersion.objects.get_for_multiple_models([models.Event, models.Venue, models.Person, models.Organisation, models.EventAuthorisation])
return versions.order_by("-revision__date_created")
return versions
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context

View File

@@ -17,7 +17,6 @@ from django.views.decorators.csrf import csrf_exempt
from RIGS import models, forms
from assets import models as asset_models
from functools import reduce
"""
@@ -249,7 +248,6 @@ class SecureAPIRequest(generic.View):
'organisation': models.Organisation,
'profile': models.Profile,
'event': models.Event,
'supplier': asset_models.Supplier
}
perms = {
@@ -258,7 +256,6 @@ class SecureAPIRequest(generic.View):
'organisation': 'RIGS.view_organisation',
'profile': 'RIGS.view_profile',
'event': None,
'supplier': None
}
'''
@@ -392,7 +389,3 @@ class ResetApiKey(generic.RedirectView):
self.request.user.save()
return reverse_lazy('profile_detail')
class PasswordResetDisabled(generic.TemplateView):
template_name = "RIGS/password_reset_disable.html"

View File

@@ -6,4 +6,4 @@ from assets import models
class AssetFilter(django_filters.FilterSet):
class Meta:
model = models.Asset
fields = ['asset_id', 'description', 'serial_number', 'category', 'status']
fields = ['asset_id', 'description', 'category', 'status']

View File

@@ -4,11 +4,6 @@ from assets import models
class AssetForm(forms.ModelForm):
related_models = {
'asset': models.Asset,
'supplier': models.Supplier
}
class Meta:
model = models.Asset
fields = '__all__'

View File

@@ -1,32 +0,0 @@
# Generated by Django 2.0.13 on 2020-01-03 22:15
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('assets', '0008_auto_20191206_2124'),
]
operations = [
migrations.AlterModelOptions(
name='assetcategory',
options={'ordering': ['name'], 'verbose_name': 'Asset Category', 'verbose_name_plural': 'Asset Categories'},
),
migrations.AlterModelOptions(
name='assetstatus',
options={'ordering': ['name'], 'verbose_name': 'Asset Status', 'verbose_name_plural': 'Asset Statuses'},
),
migrations.AddField(
model_name='assetstatus',
name='display_class',
field=models.CharField(blank=True, help_text='HTML class to be appended to alter display of assets with this status, such as in the list.', max_length=80, null=True),
),
migrations.AlterField(
model_name='asset',
name='purchased_from',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='assets', to='assets.Supplier'),
),
]

View File

@@ -6,17 +6,11 @@ from django.urls import reverse
from django.db.models.signals import pre_save
from django.dispatch.dispatcher import receiver
from reversion import revisions as reversion
from reversion.models import Version
from RIGS.models import RevisionMixin
class AssetCategory(models.Model):
class Meta:
verbose_name = 'Asset Category'
verbose_name_plural = 'Asset Categories'
ordering = ['name']
name = models.CharField(max_length=80)
@@ -28,19 +22,15 @@ class AssetStatus(models.Model):
class Meta:
verbose_name = 'Asset Status'
verbose_name_plural = 'Asset Statuses'
ordering = ['name']
name = models.CharField(max_length=80)
should_show = models.BooleanField(
default=True, help_text="Should this be shown by default in the asset list.")
display_class = models.CharField(max_length=80, blank=True, null=True, help_text="HTML class to be appended to alter display of assets with this status, such as in the list.")
should_show = models.BooleanField(default=True, help_text="Should this be shown by default in the asset list.")
def __str__(self):
return self.name
@reversion.register
class Supplier(models.Model, RevisionMixin):
class Supplier(models.Model):
name = models.CharField(max_length=80)
class Meta:
@@ -65,8 +55,7 @@ class Connector(models.Model):
return self.description
@reversion.register
class Asset(models.Model, RevisionMixin):
class Asset(models.Model):
class Meta:
ordering = ['asset_id_prefix', 'asset_id_number']
permissions = (
@@ -74,14 +63,13 @@ class Asset(models.Model, RevisionMixin):
('view_asset', 'Can view an asset')
)
parent = models.ForeignKey(to='self', related_name='asset_parent',
blank=True, null=True, on_delete=models.SET_NULL)
parent = models.ForeignKey(to='self', related_name='asset_parent', blank=True, null=True, on_delete=models.SET_NULL)
asset_id = models.CharField(max_length=15, unique=True)
description = models.CharField(max_length=120)
category = models.ForeignKey(to=AssetCategory, on_delete=models.CASCADE)
status = models.ForeignKey(to=AssetStatus, on_delete=models.CASCADE)
serial_number = models.CharField(max_length=150, blank=True)
purchased_from = models.ForeignKey(to=Supplier, on_delete=models.CASCADE, blank=True, null=True, related_name="assets")
purchased_from = models.ForeignKey(to=Supplier, on_delete=models.CASCADE, blank=True, null=True)
date_acquired = models.DateField()
date_sold = models.DateField(blank=True, null=True)
purchase_price = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=10)
@@ -91,14 +79,10 @@ class Asset(models.Model, RevisionMixin):
# Cable assets
is_cable = models.BooleanField(default=False)
plug = models.ForeignKey(Connector, on_delete=models.SET_NULL,
related_name='plug', blank=True, null=True)
socket = models.ForeignKey(Connector, on_delete=models.SET_NULL,
related_name='socket', blank=True, null=True)
length = models.DecimalField(decimal_places=1, max_digits=10,
blank=True, null=True, help_text='m')
csa = models.DecimalField(decimal_places=2, max_digits=10,
blank=True, null=True, help_text='mm^2')
plug = models.ForeignKey(Connector, on_delete=models.SET_NULL, related_name='plug', blank=True, null=True)
socket = models.ForeignKey(Connector, on_delete=models.SET_NULL, related_name='socket', blank=True, null=True)
length = models.DecimalField(decimal_places=1, max_digits=10, blank=True, null=True, help_text='m')
csa = models.DecimalField(decimal_places=2, max_digits=10, blank=True, null=True, help_text='mm^2')
circuits = models.IntegerField(blank=True, null=True)
cores = models.IntegerField(blank=True, null=True)
@@ -141,8 +125,7 @@ class Asset(models.Model, RevisionMixin):
self.asset_id = self.asset_id.upper()
asset_search = re.search("^([a-zA-Z0-9]*?[a-zA-Z]?)([0-9]+)$", self.asset_id)
if asset_search is None:
errdict["asset_id"] = [
"An Asset ID can only consist of letters and numbers, with a final number"]
errdict["asset_id"] = ["An Asset ID can only consist of letters and numbers, with a final number"]
if self.purchase_price and self.purchase_price < 0:
errdict["purchase_price"] = ["A price cannot be negative"]

View File

@@ -1,92 +0,0 @@
{% extends request.is_ajax|yesno:"base_ajax.html,base_assets.html" %}
{% load static %}
{% load paginator from filters %}
{% load to_class_name from filters %}
{% block title %}Asset Activity Stream{% endblock %}
{# TODO: Find a way to reduce code duplication...can't just include the content because of the IDs... #}
{% block js %}
<script src="{% static "js/tooltip.js" %}"></script>
<script src="{% static "js/popover.js" %}"></script>
<script src="{% static "js/moment.min.js" %}"></script>
<script>
$(function () {
$('[data-toggle="popover"]').popover().click(function(){
if($(this).attr('href')){
window.location.href = $(this).attr('href');
}
});
// This keeps timeago values correct, but uses an insane amount of resources
// $(function () {
// setInterval(function() {
// $('.date').each(function (index, dateElem) {
// var $dateElem = $(dateElem);
// var formatted = moment($dateElem.attr('data-date')).fromNow();
// $dateElem.text(formatted);
// })
// });
// }, 10000);
$('.date').each(function (index, dateElem) {
var $dateElem = $(dateElem);
var formatted = moment($dateElem.attr('data-date')).fromNow();
$dateElem.text(formatted);
});
})
</script>
{% endblock %}
{% block content %}
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12">
<h3>Asset Activity Stream</h3>
</div>
<div class="text-right col-sm-12">{% paginator %}</div>
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<td>Date</td>
<td>Object</td>
<td>Version ID</td>
<td>User</td>
<td>Changes</td>
<td>Comment</td>
</tr>
</thead>
<tbody>
{% for version in object_list %}
<tr>
<td>{{ version.revision.date_created }}</td>
<td><a href="{{ version.changes.new.get_absolute_url }}">{{version.changes.new|to_class_name}} {{ version.changes.new.asset_id|default:version.changes.new.pk }}</a></td>
<td>{{ version.pk }}|{{ version.revision.pk }}</td>
<td>{{ version.revision.user.name }}</td>
<td>
{% if version.changes.old == None %}
{{version.changes.new|to_class_name}} Created
{% else %}
{% include 'RIGS/version_changes.html' %}
{% endif %} </td>
<td>{{ version.changes.revision.comment }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="align-right">{% paginator %}</div>
</div>
{% endblock %}

View File

@@ -3,6 +3,7 @@
{% load asset_templatetags %}
{% block title %}Asset {{ object.asset_id }}{% endblock %}
{% block content %}
<div class="page-header">

View File

@@ -11,8 +11,8 @@
<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>
{% render_field form.query|add_class:'form-control' placeholder='Search by Asset ID/Description' style="width: 250px"%}
<label for="query" class="sr-only">Asset ID/Description:</label>
<span class="input-group-btn"><button type="submit" class="btn btn-default">Search</button></span>
</div>
<br>

View File

@@ -3,6 +3,7 @@
{% load asset_templatetags %}
{% block title %}Asset {{ object.asset_id }}{% endblock %}
{% block content %}
<div class="page-header">
@@ -44,16 +45,6 @@
</div>
</form>
{% if not edit and perms.assets.view_asset %}
<div class="col-sm-12 text-right">
<div>
<a href="{% url 'asset_history' object.asset_id %}" title="View Revision History">
Last edited at {{ object.last_edited_at|default:'never' }} by {{ object.last_edited_by.name|default:'nobody' }}
</a>
</div>
</div>
{% endif %}
{% endblock %}
{% block js%}

View File

@@ -1,68 +0,0 @@
{% extends request.is_ajax|yesno:"base_ajax.html,base_assets.html" %}
{% load to_class_name from filters %}
{% load paginator from filters %}
{% load static %}
{% block title %}{{object|to_class_name}} {{ object.asset_id }} - Revision History{% endblock %}
{% block js %}
<script src="{% static "js/tooltip.js" %}"></script>
<script src="{% static "js/popover.js" %}"></script>
<script>
$(function () {
$('[data-toggle="popover"]').popover().click(function(){
if($(this).attr('href')){
window.location.href = $(this).attr('href');
}
});
})
</script>
{% endblock %}
{% block content %}
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12">
<h3><a href="{{ object.get_absolute_url }}">{{object|to_class_name}} {{ object.asset_id|default:object.pk }}</a> - Revision History</h3>
</div>
<div class="text-right col-sm-12">{% paginator %}</div>
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<td>Date</td>
<td>Version ID</td>
<td>User</td>
<td>Changes</td>
<td>Comment</td>
</tr>
</thead>
<tbody>
{% for version in object_list %}
<tr>
<td>{{ version.revision.date_created }}</td>
<td>{{ version.pk }}|{{ version.revision.pk }}</td>
<td>{{ version.revision.user.name }}</td>
<td>
{% if version.changes.old is None %}
{{object|to_class_name}} Created
{% else %}
{% include 'RIGS/version_changes.html' %}
{% endif %}
</td>
<td>
{{ version.revision.comment }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="align-right">{% paginator %}</div>
</div>
{% endblock %}

View File

@@ -1,6 +1,20 @@
{% for item in object_list %}
{# <li><a href="{% url 'asset_detail' item.pk %}">{{ item.asset_id }} - {{ item.description }}</a></li>#}
<!---TODO: When the ability to filter the list is added, remove the colours from the filter - specifically, stop greying out sold/binned stuff if it is being searched for--> <tr class={{ item.status.display_class|default:"" }}>
<!---TODO: When the ability to filter the list is added, remove the colours from the filter - specifically, stop greying out sold/binned stuff if it is being searched for--> <tr class="
{% if item.status.name == 'Broken' %}
danger
{% elif item.status.name == 'Scrapped'%}
warning
{% elif item.status.name == 'Sold'%}
warning
{% elif item.status.name == 'Lost'%}
danger
{% elif item.status.name == 'Not Built Yet'%}
info
{% elif item.status.name == 'Active'%}
success
{% endif %}
">
<td style="vertical-align: middle;"><a href="{% url 'asset_detail' item.asset_id %}">{{ item.asset_id }}</a></td>
<td style="vertical-align: middle; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; max-width: 25vw">{{ item.description }}</td>
<td style="vertical-align: middle;">{{ item.category }}</td>

View File

@@ -1,22 +1,5 @@
{% load widget_tweaks %}
{% load asset_templatetags %}
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static "css/bootstrap-select.min.css" %}"/>
<link rel="stylesheet" href="{% static "css/ajax-bootstrap-select.css" %}"/>
{% endblock %}
{% block preload_js %}
<script src="{% static "js/bootstrap-select.js" %}"></script>
<script src="{% static "js/ajax-bootstrap-select.js" %}"></script>
{% endblock %}
{% block js %}
<script src="{% static "js/autocompleter.js" %}"></script>
{% endblock %}
<div class="panel panel-default">
<div class="panel-heading">
Purchase Details
@@ -24,12 +7,8 @@
<div class="panel-body">
{% if create or edit or duplicate %}
<div class="form-group">
<label for="{{ form.purchased_from.id_for_label }}">Supplier</label>
<select id="{{ form.purchased_from.id_for_label }}" name="{{ form.purchased_from.name }}" class="form-control selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='supplier' %}">
{% if object.purchased_from %}
<option value="{{form.purchased_from.value}}" selected="selected" data-update_url="{% url 'supplier_update' form.purchased_from.value %}">{{ object.purchased_from }}</option>
{% endif %}
</select>
<label for="{{ form.purchased_from.id_for_label }}">Purchased From</label>
{% include 'partials/supplier_picker.html' %}
</div>
<div class="form-group">

View File

@@ -0,0 +1,64 @@
<select name="purchased_from" id="supplier_id" class="selectpicker">
{% if object.parent%}
<option value="{{object.parent.pk}}" selected>{{object.parent.name}}</option>
{% endif %}
</select>
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static "css/bootstrap-select.min.css" %}"/>
<link rel="stylesheet" href="{% static "css/ajax-bootstrap-select.css" %}"/>
{% endblock %}
{% block preload_js %}
<script src="{% static "js/bootstrap-select.js" %}"></script>
<script src="{% static "js/ajax-bootstrap-select.js" %}"></script>
{% endblock %}
{% block js %}
{{ js.super }}
<script>
$('#supplier_id')
.selectpicker({
liveSearch: true
})
.ajaxSelectPicker({
ajax: {
url: '{% url 'supplier_search_json'%}',
type: "get",
data: function () {
var params = {
{% verbatim %}query: '{{{q}}}'{% endverbatim %}
};
return params;
}
},
locale: {
emptyTitle: 'Search for supplier...'
},
preprocessData: function(data){
var suppliers = [];
if(data.length){
var len = data.length;
for(var i = 0; i < len; i++){
var curr = data[i];
suppliers.push(
{
'value': curr.id,
'text': curr.name,
'disabled': false
}
);
}
suppliers.push(
{
'value': null,
'text': "(no selection)"
});
}
return suppliers;
},
preserveSelected: false
});
</script>
{% endblock js %}

View File

@@ -1,73 +1,6 @@
{% extends 'base_assets.html' %}
{% block title %}Supplier | {{ object.name }}{% endblock %}
{% block title %}Detail{% endblock %}
{% block content %}
<div class="row">
{% if not request.is_ajax %}
<div class="col-sm-12">
<h1>Supplier | {{ object.name }}</h1>
</div>
<div class="col-sm-12 text-right">
<div class="btn-group btn-page">
<a href="{% url 'supplier_update' object.pk %}" class="btn btn-default"><span
class="glyphicon glyphicon-pencil"></span> Edit</a>
</div>
</div>
{% endif %}
<div class="col-sm-6">
<div class="panel panel-info">
<div class="panel-heading">Supplier Details</div>
<div class="panel-body">
<dl class="dl-horizontal">
<dt>Name</dt>
<dd>{{ object.name }}</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Associated Assets</div>
<div class="panel-body">
<table class="table">
<thead>
<tr>
<th>Asset ID</th>
<th>Description</th>
<th>Category</th>
<th>Status</th>
<th class="hidden-xs">Quick Links</th>
</tr>
</thead>
<tbody id="asset_table_body">
{% with object.assets.all as object_list %}
{% include 'partials/asset_list_table_body.html' %}
{% endwith %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% if not request.is_ajax %}
<div class="row">
<div class="col-sm-12 text-right">
<div class="btn-group btn-page">
<a href="{% url 'supplier_update' object.pk %}" class="btn btn-default"><span
class="glyphicon glyphicon-pencil"></span> Edit</a>
</div>
<div>
<a href="{% url 'supplier_update' object.pk %}" title="View Revision History">
Last edited {{ object.last_edited_at }} by {{ object.last_edited_by.name }}
</a>
</div>
</div>
</div>
{% endif %}
{% endblock %}
{{ object }}
{% endblock %}

View File

@@ -30,7 +30,6 @@
<tr>
<td>{{ item.name }}</td>
<td>
<a href="{% url 'supplier_detail' item.pk %}" class="btn btn-default"><i class="glyphicon glyphicon-eye-open"></i> View</a>
<a href="{% url 'supplier_update' item.pk %}" class="btn btn-default"><i class="glyphicon glyphicon-edit"></i> Edit</a>
</td>
</tr>

View File

@@ -1,7 +1,5 @@
from django.conf.urls import url
from django.urls import path
from assets import views, models
from RIGS import versioning
from assets import views
from PyRIGS.decorators import permission_required_with_403
@@ -9,27 +7,16 @@ urlpatterns = [
path('', views.AssetList.as_view(), name='asset_index'),
path('asset/list/', views.AssetList.as_view(), name='asset_list'),
path('asset/id/<str:pk>/', views.AssetDetail.as_view(), name='asset_detail'),
path('asset/create/', permission_required_with_403('assets.add_asset')
(views.AssetCreate.as_view()), name='asset_create'),
path('asset/id/<str:pk>/edit/', permission_required_with_403('assets.change_asset')
(views.AssetEdit.as_view()), name='asset_update'),
path('asset/id/<str:pk>/duplicate/', permission_required_with_403('assets.add_asset')
(views.AssetDuplicate.as_view()), name='asset_duplicate'),
path('asset/id/<str:pk>/history/', permission_required_with_403('assets.view_asset')(views.AssetVersionHistory.as_view()),
name='asset_history', kwargs={'model': models.Asset}),
path('activity', permission_required_with_403('assets.view_asset')
(views.ActivityTable.as_view()), name='asset_activity_table'),
path('asset/create/', permission_required_with_403('assets.add_asset')(views.AssetCreate.as_view()), name='asset_create'),
path('asset/id/<str:pk>/edit/', permission_required_with_403('assets.change_asset')(views.AssetEdit.as_view()), name='asset_update'),
path('asset/id/<str:pk>/duplicate/', permission_required_with_403('assets.add_asset')(views.AssetDuplicate.as_view()), name='asset_duplicate'),
path('asset/search/', views.AssetSearch.as_view(), name='asset_search_json'),
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')
(views.SupplierCreate.as_view()), name='supplier_create'),
path('supplier/<int:pk>/edit', permission_required_with_403('assets.change_supplier')
(views.SupplierUpdate.as_view()), name='supplier_update'),
path('supplier/<str:pk>/history/', views.SupplierVersionHistory.as_view(),
name='supplier_history', kwargs={'model': models.Supplier}),
path('supplier/create', permission_required_with_403('assets.add_supplier')(views.SupplierCreate.as_view()), name='supplier_create'),
path('supplier/<int:pk>/edit', permission_required_with_403('assets.change_supplier')(views.SupplierUpdate.as_view()), name='supplier_update'),
path('supplier/search/', views.SupplierSearch.as_view(), name='supplier_search_json'),
]

View File

@@ -5,9 +5,7 @@ from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.urls import reverse
from django.db.models import Q
from django.shortcuts import get_object_or_404
from assets import models, forms
from RIGS import versioning
@method_decorator(csrf_exempt, name='dispatch')
@@ -38,8 +36,7 @@ class AssetList(LoginRequiredMixin, generic.ListView):
if len(query_string) == 0:
queryset = self.model.objects.all()
elif len(query_string) >= 3:
queryset = self.model.objects.filter(
Q(asset_id__exact=query_string) | Q(description__icontains=query_string) | Q(serial_number__exact=query_string))
queryset = self.model.objects.filter(Q(asset_id__exact=query_string) | Q(description__icontains=query_string))
else:
queryset = self.model.objects.filter(Q(asset_id__exact=query_string))
@@ -49,8 +46,7 @@ class AssetList(LoginRequiredMixin, generic.ListView):
if len(form.cleaned_data['status']) > 0:
queryset = queryset.filter(status__in=form.cleaned_data['status'])
elif self.hide_hidden_status:
queryset = queryset.filter(
status__in=models.AssetStatus.objects.filter(should_show=True))
queryset = queryset.filter(status__in=models.AssetStatus.objects.filter(should_show=True))
return queryset
@@ -207,25 +203,3 @@ class SupplierUpdate(generic.UpdateView):
model = models.Supplier
form_class = forms.SupplierForm
template_name = 'supplier_update.html'
class SupplierVersionHistory(versioning.VersionHistory):
template_name = "asset_version_history.html"
class AssetVersionHistory(versioning.VersionHistory):
template_name = "asset_version_history.html"
def get_object(self, **kwargs):
return get_object_or_404(models.Asset, asset_id=self.kwargs['pk'])
class ActivityTable(versioning.ActivityTable):
model = versioning.RIGSVersion
template_name = "asset_activity_table.html"
paginate_by = 25
def get_queryset(self):
versions = versioning.RIGSVersion.objects.get_for_multiple_models(
[models.Asset, models.Supplier])
return versions

View File

@@ -1,16 +1,11 @@
{% extends 'base.html' %}
{% block extrahead %}
<meta name="google" content="notranslate">
{% endblock %}
{% block titleheader %}
<a class="nav navbar-brand navbar-left" href="/"><i class="glyphicon glyphicon-circle-arrow-left" style="vertical-align: middle !important;"></i> RIGS</a>
<a class="nav navbar-brand" href="{% url 'asset_index' %}">Assets</a>
{% endblock %}
{% block titleelements %}
{# % if perms.assets.view_asset % #}
{% if perms.assets.view_asset%}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Assets<b class="caret"></b></a>
<ul class="dropdown-menu">
@@ -20,20 +15,17 @@
{% endif %}
</ul>
</li>
{# % endif % #}
{# % if perms.assets.view_supplier % #}
{% endif %}
{% if perms.assets.view_supplier%}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> Suppliers<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="{% url 'supplier_list' %}"><span class="glyphicon glyphicon-list"></span>
List Suppliers</a></li>
{% if perms.assets.add_supplier %}
{% if perms.assets.add_asset %}
<li><a href="{% url 'supplier_create' %}"><span class="glyphicon glyphicon-plus"></span> Create Supplier</a></li>
{% endif %}
</ul>
</li>
{# % endif % #}
{% if perms.assets.view_asset %}
<li><a href="{% url 'asset_activity_table' %}">Recent Changes</a></li>
{% endif %}
{% endblock %}