mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 05:22:16 +00:00
Cables are now a thing, unfortunately by making a monolithic Asset model
Co-authored-by: Arona Jones <aj@aronajones.com>
This commit is contained in:
@@ -32,11 +32,6 @@ class ConnectorAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', '__str__', 'current_rating', 'voltage_rating', 'num_pins']
|
||||
|
||||
|
||||
@admin.register(assets.Cable)
|
||||
class CableAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
admin.AdminSite.site_header = 'PyAssets - TEC\'s Asset System'
|
||||
admin.AdminSite.site_title = 'PyAssets Admin'
|
||||
admin.AdminSite.index_title = 'System Administration'
|
||||
|
||||
@@ -1,74 +1,14 @@
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
import re
|
||||
|
||||
from assets import models
|
||||
|
||||
|
||||
class AssetForm(forms.ModelForm):
|
||||
|
||||
|
||||
class Meta:
|
||||
model = models.Asset
|
||||
fields = '__all__'
|
||||
widgets = {
|
||||
'is_cable' : forms.CheckboxInput()
|
||||
}
|
||||
|
||||
def clean_date_sold(self):
|
||||
if self.cleaned_data["date_sold"] and self.cleaned_data["date_acquired"] > self.cleaned_data["date_sold"]:
|
||||
raise ValidationError("Cannot sell an item before it is acquired")
|
||||
return self.cleaned_data["date_sold"]
|
||||
|
||||
def clean_asset_id(self):
|
||||
# If the asset ID has been changed
|
||||
if self.instance.asset_id and self.instance.asset_id == self.cleaned_data["asset_id"]: #If the item was not changed
|
||||
return self.cleaned_data["asset_id"]
|
||||
else:
|
||||
if re.search("^[a-zA-Z0-9]+$", self.cleaned_data["asset_id"]) == None:
|
||||
raise ValidationError("An Asset ID can only consist of letters and numbers")
|
||||
return self.cleaned_data["asset_id"]
|
||||
|
||||
def clean_purchase_price(self):
|
||||
purchase_price = self.cleaned_data["purchase_price"]
|
||||
if purchase_price and purchase_price < 0:
|
||||
raise ValidationError("A price cannot be negative")
|
||||
return purchase_price
|
||||
|
||||
def clean_salvage_value(self):
|
||||
salvage_value = self.cleaned_data["salvage_value"]
|
||||
if salvage_value and salvage_value < 0:
|
||||
raise ValidationError("A price cannot be negative")
|
||||
return salvage_value
|
||||
|
||||
|
||||
class CableForm(AssetForm):
|
||||
class Meta(AssetForm.Meta):
|
||||
model = models.Cable
|
||||
|
||||
def clean_length(self):
|
||||
length = self.cleaned_data["length"]
|
||||
if length <= 0:
|
||||
raise ValidationError("The length of a cable must be more than 0")
|
||||
return length
|
||||
|
||||
def clean_csa(self):
|
||||
csa = self.cleaned_data["csa"]
|
||||
if csa <= 0:
|
||||
raise ValidationError("The CSA of a cable must be more than 0")
|
||||
return csa
|
||||
|
||||
def clean_circuits(self):
|
||||
circuits = self.cleaned_data["circuits"]
|
||||
if circuits <= 0:
|
||||
raise ValidationError("There must be at least one circuit")
|
||||
return circuits
|
||||
|
||||
def clean_cores(self):
|
||||
cores = self.cleaned_data["cores"]
|
||||
if cores <= 0:
|
||||
raise ValidationError("There must be at least one core")
|
||||
return cores
|
||||
|
||||
class SupplierForm(forms.Form):
|
||||
class Meta:
|
||||
|
||||
67
assets/migrations/0010_auto_20191013_2123.py
Normal file
67
assets/migrations/0010_auto_20191013_2123.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# Generated by Django 2.0.13 on 2019-10-13 20:23
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0009_auto_20191008_2148'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='cable',
|
||||
name='asset_ptr',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='cable',
|
||||
name='plug',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='cable',
|
||||
name='socket',
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='asset',
|
||||
options={},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='asset',
|
||||
name='polymorphic_ctype',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='asset',
|
||||
name='circuits',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='asset',
|
||||
name='cores',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='asset',
|
||||
name='csa',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, help_text='mm^2', max_digits=10, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='asset',
|
||||
name='length',
|
||||
field=models.DecimalField(blank=True, decimal_places=1, help_text='m', max_digits=10, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='asset',
|
||||
name='plug',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plug', to='assets.Connector'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='asset',
|
||||
name='socket',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='socket', to='assets.Connector'),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Cable',
|
||||
),
|
||||
]
|
||||
24
assets/migrations/0011_auto_20191013_2247.py
Normal file
24
assets/migrations/0011_auto_20191013_2247.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 2.0.13 on 2019-10-13 21:47
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0010_auto_20191013_2123'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='asset',
|
||||
name='plug',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plug', to='assets.Connector'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='asset',
|
||||
name='socket',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='socket', to='assets.Connector'),
|
||||
),
|
||||
]
|
||||
@@ -1,9 +1,10 @@
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from polymorphic.models import PolymorphicModel
|
||||
|
||||
import datetime
|
||||
|
||||
import re
|
||||
|
||||
class AssetCategory(models.Model):
|
||||
class Meta:
|
||||
@@ -37,7 +38,17 @@ class Supplier(models.Model):
|
||||
return self.name
|
||||
|
||||
|
||||
class Asset(PolymorphicModel):
|
||||
class Connector(models.Model):
|
||||
description = models.CharField(max_length=80)
|
||||
current_rating = models.DecimalField(decimal_places=2, max_digits=10, help_text='Amps')
|
||||
voltage_rating = models.IntegerField(help_text='Volts')
|
||||
num_pins = models.IntegerField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.description
|
||||
|
||||
|
||||
class Asset(models.Model):
|
||||
|
||||
parent = models.ForeignKey(to='self', related_name='asset_parent', blank=True, null=True, on_delete=models.SET_NULL)
|
||||
asset_id = models.CharField(max_length=10, unique=True)
|
||||
@@ -55,34 +66,56 @@ class Asset(PolymorphicModel):
|
||||
|
||||
# Cable assets
|
||||
is_cable = models.BooleanField(default=False)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('asset_detail', kwargs={'pk': self.pk})
|
||||
|
||||
def __str__(self):
|
||||
return str(self.asset_id) + ' - ' + self.description
|
||||
|
||||
class Connector(models.Model):
|
||||
description = models.CharField(max_length=80)
|
||||
current_rating = models.DecimalField(decimal_places=2, max_digits=10, help_text='Amps')
|
||||
voltage_rating = models.IntegerField(help_text='Volts')
|
||||
num_pins = models.IntegerField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.description
|
||||
|
||||
|
||||
class Cable(Asset):
|
||||
plug = models.ForeignKey(Connector, on_delete=models.SET_NULL, related_name='plug', null=True)
|
||||
socket = models.ForeignKey(Connector, on_delete=models.SET_NULL, related_name='socket', null=True)
|
||||
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)
|
||||
|
||||
def cable_resistance(self):
|
||||
rho = 0.0000000168
|
||||
return (rho * self.length) / (self.csa * 1000000)
|
||||
def get_absolute_url(self):
|
||||
return reverse('asset_detail', kwargs={'pk': self.pk})
|
||||
|
||||
def __str__(self):
|
||||
return '{} - {}m - {}'.format(self.plug, self.length, self.socket)
|
||||
out = str(self.asset_id) + ' - ' + self.description
|
||||
if self.is_cable:
|
||||
out += '{} - {}m - {}'.format(self.plug, self.length, self.socket)
|
||||
return out
|
||||
|
||||
def clean(self):
|
||||
if self.date_sold and self.date_acquired > self.date_sold:
|
||||
raise ValidationError({"date_sold": "Cannot sell an item before it is acquired"})
|
||||
|
||||
self.asset_id = self.asset_id.upper()
|
||||
if re.search("^[a-zA-Z0-9]+$", self.asset_id) is None:
|
||||
raise ValidationError({"asset_id": "An Asset ID can only consist of letters and numbers"})
|
||||
|
||||
if self.purchase_price and self.purchase_price < 0:
|
||||
raise ValidationError({"purchase_price": "A price cannot be negative"})
|
||||
|
||||
if self.salvage_value and self.salvage_value < 0:
|
||||
raise ValidationError({"purchase_price": "A price cannot be negative"})
|
||||
|
||||
if self.is_cable:
|
||||
if self.length is None:
|
||||
raise ValidationError({"length": "The length of a cable must be a number"})
|
||||
elif self.csa is None:
|
||||
raise ValidationError({"csa": "The csa of a cable must be a number"})
|
||||
elif self.circuits is None:
|
||||
raise ValidationError({"circuits": "The number of circuits in a cable must be a number"})
|
||||
elif self.cores is None:
|
||||
raise ValidationError({"cores": "The number of cores in a cable must be a number"})
|
||||
elif self.socket is None:
|
||||
raise ValidationError({"plug": "A cable must have a plug"})
|
||||
elif self.plug is None:
|
||||
raise ValidationError({"socket": "A cable must have a socket"})
|
||||
|
||||
if self.length <= 0:
|
||||
raise ValidationError({"length": "The length of a cable must be more than 0"})
|
||||
elif self.csa <= 0:
|
||||
raise ValidationError({"csa": "The CSA of a cable must be more than 0"})
|
||||
elif self.circuits <= 0:
|
||||
raise ValidationError({"circuits": "There must be at least one circuit in a cable"})
|
||||
elif self.cores <= 0:
|
||||
raise ValidationError({"cores": "There must be at least one core in a cable"})
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
<div class="col-md-6">
|
||||
{% include 'partials/purchasedetails_form.html' %}
|
||||
</div>
|
||||
<div class="col-md-6" hidden="true" id="cable-table">
|
||||
<div class="col-md-6"
|
||||
{% if not object.is_cable %} hidden="true" {% endif %} id="cable-table">
|
||||
{% include 'partials/cable_form.html' %}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
@@ -54,6 +55,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block js%}
|
||||
{% if edit %}
|
||||
<script>
|
||||
function checkIfCableHidden() {
|
||||
if (document.getElementById("id_is_cable").checked) {
|
||||
@@ -64,4 +66,5 @@
|
||||
}
|
||||
checkIfCableHidden();
|
||||
</script>
|
||||
{%endblock%}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% if edit and object %}
|
||||
<!--edit-->
|
||||
<button type="submit" class="btn btn-success"><i class="glyphicon glyphicon-floppy-disk"></i> Save</button>
|
||||
<a class="btn btn-default" href="{% url 'asset_detail' previous_asset_pk %}"><i class="glyphicon glyphicon-duplicate"></i> Duplicate</a>
|
||||
<a class="btn btn-default" href="{% url 'asset_duplicate' object.pk %}"><i class="glyphicon glyphicon-duplicate"></i> Duplicate</a>
|
||||
<a class="btn btn-danger" data-toggle="modal" data-target="#confirm_delete_modal"><i class="glyphicon glyphicon-trash"></i> Delete</a>
|
||||
{% elif duplicate %}
|
||||
<!--duplicate-->
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="form-group">
|
||||
<label for="{{ form.plug.id_for_label }}">Plug</label>
|
||||
<select name="{{ form.plug.name }}" id="{{ form.plug.id_for_label }}" class="form-control">
|
||||
<option value="None">
|
||||
<option value="">
|
||||
{% for connector in connectors %}
|
||||
<option value="{{ connector.pk }}">
|
||||
{{ connector.description }}
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="form-group">
|
||||
<label for="{{ form.socket.id_for_label }}">Socket</label>
|
||||
<select name="{{ form.socket.name }}" id="{{ form.socket.id_for_label }}" class="form-control">
|
||||
<option value="None">
|
||||
<option value="">
|
||||
{% for connector in connectors %}
|
||||
<option value="{{ connector.pk }}">
|
||||
{{ connector.description }}
|
||||
|
||||
@@ -47,7 +47,7 @@ class AssetList(LoginRequiredMixin, generic.ListView):
|
||||
|
||||
context["statuses"] = models.AssetStatus.objects.all()
|
||||
context["status_select"] = self.request.GET.get('status', "")
|
||||
return context;
|
||||
return context
|
||||
|
||||
class AssetSearch(AssetList):
|
||||
def render_to_response(self, context, **response_kwargs):
|
||||
@@ -62,30 +62,18 @@ class AssetDetail(LoginRequiredMixin, generic.DetailView):
|
||||
model = models.Asset
|
||||
template_name = 'asset_update.html'
|
||||
|
||||
|
||||
# class AssetCreate(LoginRequiredMixin, generic.TemplateView):
|
||||
# fields = '__all__'
|
||||
# template_name = 'asset_update.html'
|
||||
# # success_url = reverse_lazy('asset_list')
|
||||
|
||||
class AssetEdit(LoginRequiredMixin, generic.UpdateView):
|
||||
template_name = 'asset_update.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_form_class(self):
|
||||
if self.object.is_cable:
|
||||
return forms.CableForm
|
||||
return forms.AssetForm
|
||||
|
||||
def form_invalid(self, form):
|
||||
return super().form_invalid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse("asset_detail", kwargs={"pk":self.object.id})
|
||||
|
||||
@@ -99,16 +87,9 @@ class AssetCreate(LoginRequiredMixin, generic.CreateView):
|
||||
|
||||
context["create"] = True
|
||||
context["connectors"] = models.Connector.objects.all()
|
||||
|
||||
return context
|
||||
|
||||
def get_form_class(self):
|
||||
if self.request.method == "POST":
|
||||
if 'is_cable' in self.request.POST:
|
||||
return forms.CableForm
|
||||
return forms.AssetForm
|
||||
else:
|
||||
return forms.CableForm #For GET, so that all form fields can be placed
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse("asset_detail", kwargs={"pk":self.object.id})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user