diff --git a/RIGS/templates/RIGS/event_detail.html b/RIGS/templates/RIGS/event_detail.html
index 176756dc..8668bbac 100644
--- a/RIGS/templates/RIGS/event_detail.html
+++ b/RIGS/templates/RIGS/event_detail.html
@@ -245,7 +245,7 @@
diff --git a/RIGS/templates/RIGS/index.html b/RIGS/templates/RIGS/index.html
index 826839e6..acd1a707 100644
--- a/RIGS/templates/RIGS/index.html
+++ b/RIGS/templates/RIGS/index.html
@@ -72,9 +72,8 @@
{% if perms.RIGS.view_event %}
-
+
{% include 'RIGS/activity_feed.html' %}
-
{% endif %}
diff --git a/RIGS/versioning.py b/RIGS/versioning.py
index d7b423c2..795ea9fe 100644
--- a/RIGS/versioning.py
+++ b/RIGS/versioning.py
@@ -206,17 +206,14 @@ class VersionHistory(generic.ListView):
paginate_by = 25
def get_queryset(self, **kwargs):
- thisModel = self.kwargs['model']
+ return RIGSVersion.objects.get_for_object(self.get_object()).select_related("revision", "revision__user").all()
- versions = RIGSVersion.objects.get_for_object_reference(thisModel, self.kwargs['pk']).select_related("revision", "revision__user").all()
-
- return versions
+ def get_object(self, **kwargs):
+ return get_object_or_404(self.kwargs['model'], pk=self.kwargs['pk'])
def get_context_data(self, **kwargs):
- thisModel = self.kwargs['model']
context = super(VersionHistory, self).get_context_data(**kwargs)
- thisObject = get_object_or_404(thisModel, pk=self.kwargs['pk'])
- context['object'] = thisObject
+ context['object'] = self.get_object()
return context
diff --git a/assets/models.py b/assets/models.py
index 993c8c34..2398a563 100644
--- a/assets/models.py
+++ b/assets/models.py
@@ -6,6 +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:
@@ -24,13 +29,15 @@ class AssetStatus(models.Model):
verbose_name_plural = 'Asset Statuses'
name = models.CharField(max_length=80)
- should_show = models.BooleanField(default=True, help_text="Should this be shown by default in the asset 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
-class Supplier(models.Model):
+@reversion.register
+class Supplier(models.Model, RevisionMixin):
name = models.CharField(max_length=80)
class Meta:
@@ -55,7 +62,8 @@ class Connector(models.Model):
return self.description
-class Asset(models.Model):
+@reversion.register
+class Asset(models.Model, RevisionMixin):
class Meta:
ordering = ['asset_id_prefix', 'asset_id_number']
permissions = (
@@ -63,7 +71,8 @@ class Asset(models.Model):
('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)
@@ -79,10 +88,14 @@ class Asset(models.Model):
# 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)
@@ -125,7 +138,8 @@ class Asset(models.Model):
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"]
diff --git a/assets/templates/asset_activity_table.html b/assets/templates/asset_activity_table.html
new file mode 100644
index 00000000..aca6142c
--- /dev/null
+++ b/assets/templates/asset_activity_table.html
@@ -0,0 +1,92 @@
+{% 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 %}
+
+
+
+
+{% endblock %}
+
+{% block content %}
+
+
+
+
Asset Activity Stream
+
+
{% paginator %}
+
+
+
+
+
+
+ | Date |
+ Object |
+ Version ID |
+ User |
+ Changes |
+ Comment |
+
+
+
+ {% for version in object_list %}
+
+
+ | {{ version.revision.date_created }} |
+ {{version.changes.new|to_class_name}} {{ version.changes.new.asset_id|default:version.changes.new.pk }} |
+ {{ version.pk }}|{{ version.revision.pk }} |
+ {{ version.revision.user.name }} |
+
+ {% if version.changes.old == None %}
+ {{version.changes.new|to_class_name}} Created
+ {% else %}
+ {% include 'RIGS/version_changes.html' %}
+ {% endif %} |
+ {{ version.changes.revision.comment }} |
+
+
+ {% endfor %}
+
+
+
+
+
+
{% paginator %}
+
+{% endblock %}
diff --git a/assets/templates/asset_update.html b/assets/templates/asset_update.html
index faee7662..9987e4fe 100644
--- a/assets/templates/asset_update.html
+++ b/assets/templates/asset_update.html
@@ -45,6 +45,16 @@
+{% if not edit %}
+
+{% endif %}
+
{% endblock %}
{% block js%}
diff --git a/assets/templates/asset_version_history.html b/assets/templates/asset_version_history.html
new file mode 100644
index 00000000..89223294
--- /dev/null
+++ b/assets/templates/asset_version_history.html
@@ -0,0 +1,68 @@
+{% 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 %}
+
+
+
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+ | Date |
+ Version ID |
+ User |
+ Changes |
+ Comment |
+
+
+
+ {% for version in object_list %}
+
+
+ | {{ version.revision.date_created }} |
+ {{ version.pk }}|{{ version.revision.pk }} |
+ {{ version.revision.user.name }} |
+
+ {% if version.changes.old is None %}
+ {{object|to_class_name}} Created
+ {% else %}
+ {% include 'RIGS/version_changes.html' %}
+ {% endif %}
+ |
+
+ {{ version.revision.comment }}
+ |
+
+
+
+ {% endfor %}
+
+
+
+
+
{% paginator %}
+
+{% endblock %}
diff --git a/assets/templates/supplier_list.html b/assets/templates/supplier_list.html
index 71ceb78c..4de91bbc 100644
--- a/assets/templates/supplier_list.html
+++ b/assets/templates/supplier_list.html
@@ -31,6 +31,7 @@
{{ item.name }} |
Edit
+ History
|
{% endfor %}
diff --git a/assets/urls.py b/assets/urls.py
index 0a8ff599..3acac945 100644
--- a/assets/urls.py
+++ b/assets/urls.py
@@ -1,5 +1,7 @@
+from django.conf.urls import url
from django.urls import path
-from assets import views
+from assets import views, models
+from RIGS import versioning
from PyRIGS.decorators import permission_required_with_403
@@ -7,16 +9,27 @@ urlpatterns = [
path('', views.AssetList.as_view(), name='asset_index'),
path('asset/list/', views.AssetList.as_view(), name='asset_list'),
path('asset/id//', 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//edit/', permission_required_with_403('assets.change_asset')(views.AssetEdit.as_view()), name='asset_update'),
- path('asset/id//duplicate/', permission_required_with_403('assets.add_asset')(views.AssetDuplicate.as_view()), name='asset_duplicate'),
+ path('asset/create/', permission_required_with_403('assets.add_asset')
+ (views.AssetCreate.as_view()), name='asset_create'),
+ path('asset/id//edit/', permission_required_with_403('assets.change_asset')
+ (views.AssetEdit.as_view()), name='asset_update'),
+ path('asset/id//duplicate/', permission_required_with_403('assets.add_asset')
+ (views.AssetDuplicate.as_view()), name='asset_duplicate'),
+ path('asset/id//history/', 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/search/', views.AssetSearch.as_view(), name='asset_search_json'),
path('supplier/list', views.SupplierList.as_view(), name='supplier_list'),
path('supplier/', 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//edit', permission_required_with_403('assets.change_supplier')(views.SupplierUpdate.as_view()), name='supplier_update'),
+ path('supplier/create', permission_required_with_403('assets.add_supplier')
+ (views.SupplierCreate.as_view()), name='supplier_create'),
+ path('supplier//edit', permission_required_with_403('assets.change_supplier')
+ (views.SupplierUpdate.as_view()), name='supplier_update'),
+ path('supplier//history/', views.SupplierVersionHistory.as_view(),
+ name='supplier_history', kwargs={'model': models.Supplier}),
path('supplier/search/', views.SupplierSearch.as_view(), name='supplier_search_json'),
]
diff --git a/assets/views.py b/assets/views.py
index 06449cdb..1acc28fb 100644
--- a/assets/views.py
+++ b/assets/views.py
@@ -5,7 +5,9 @@ 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')
@@ -36,7 +38,8 @@ 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))
+ 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))
@@ -46,7 +49,8 @@ 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
@@ -203,3 +207,24 @@ 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"
+
+
+# TODO: Reduce SQL queries
+class AssetVersionHistory(versioning.VersionHistory):
+ 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
diff --git a/templates/base_assets.html b/templates/base_assets.html
index 7dd53034..288d7dc9 100644
--- a/templates/base_assets.html
+++ b/templates/base_assets.html
@@ -5,7 +5,7 @@
{% endblock %}
{% block titleelements %}
- {% if perms.assets.view_asset%}
+ {% if perms.assets.view_asset %}
Assets
{% endif %}
- {% if perms.assets.view_supplier%}
+ {% if perms.assets.view_supplier %}
Suppliers
{% endif %}
+ {% if perms.assets.view_asset %}
+ Recent Changes
+ {% endif %}
{% endblock %}