diff --git a/assets/forms.py b/assets/forms.py index 430eef20..7571d28b 100644 --- a/assets/forms.py +++ b/assets/forms.py @@ -7,6 +7,7 @@ class AssetForm(forms.ModelForm): class Meta: model = models.Asset fields = '__all__' + exclude = ['asset_id_prefix', 'asset_id_number'] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/assets/migrations/0008_auto_20191205_1354.py b/assets/migrations/0008_auto_20191205_1354.py new file mode 100644 index 00000000..7f171525 --- /dev/null +++ b/assets/migrations/0008_auto_20191205_1354.py @@ -0,0 +1,42 @@ +# Generated by Django 2.0.13 on 2019-12-05 13:54 +# Edited by Matthew Smith on same date. +import re +from django.db import migrations, models + +def forwards(apps, schema_editor): + AssetModel = apps.get_model('assets', 'Asset') + + for row in AssetModel.objects.all(): + + row.asset_id = row.asset_id.upper() + asset_search = re.search("^([A-Z0-9]*?[A-Z]?)([0-9]+)$", row.asset_id) + if asset_search is None: # If the asset_id doesn't have a number at the end + row.asset_id += "1" + + asset_search = re.search("^([A-Z0-9]*?[A-Z]?)([0-9]+)$", row.asset_id) + row.asset_id_prefix = asset_search.group(1) + row.asset_id_number = int(asset_search.group(2)) + + row.save(update_fields=['asset_id', 'asset_id_prefix', 'asset_id_number']) + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0007_auto_20190108_0202_squashed_0014_auto_20191017_2052'), + ] + + operations = [ + migrations.AddField( + model_name='asset', + name='asset_id_number', + field=models.IntegerField(default=0), + preserve_default=False, + ), + migrations.AddField( + model_name='asset', + name='asset_id_prefix', + field=models.CharField(default=0, max_length=5), + preserve_default=False, + ), + migrations.RunPython(forwards, reverse_code=migrations.RunPython.noop), + ] diff --git a/assets/models.py b/assets/models.py index 7abddfd2..6e54c5e8 100644 --- a/assets/models.py +++ b/assets/models.py @@ -54,7 +54,7 @@ class Connector(models.Model): class Asset(models.Model): class Meta: - ordering = ['asset_id'] + ordering = ['asset_id_prefix', 'asset_id_number'] permissions = ( ('asset_finance', 'Can see financial data for assets'), ('view_asset', 'Can view an asset') @@ -83,13 +83,19 @@ class Asset(models.Model): circuits = models.IntegerField(blank=True, null=True) cores = models.IntegerField(blank=True, null=True) - def get_available_asset_id(): + # Hidden asset_id components + # For example, if asset_id was "C1001" then asset_id_prefix would be "C" and number "1001" + asset_id_prefix = models.CharField(max_length=5) + asset_id_number = models.IntegerField() + + def get_available_asset_id(wanted_prefix=""): sql = """ - SELECT MIN(CAST(a.asset_id AS int))+1 + SELECT a.asset_id_number+1 FROM assets_asset a LEFT OUTER JOIN assets_asset b ON - (CAST(a.asset_id AS int) + 1 = CAST(b.asset_id AS int)) - WHERE b.asset_id IS NULL AND CAST(a.asset_id AS int) >= %s; + (a.asset_id_number + 1 = b.asset_id_number AND + a.asset_id_prefix = b.asset_id_prefix) + WHERE b.asset_id IS NULL AND a.asset_id_number >= %s AND a.asset_id_prefix = ''; """ with connection.cursor() as cursor: cursor.execute(sql, [9000]) @@ -114,8 +120,11 @@ class Asset(models.Model): errdict["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: + asset_search = re.search("^([A-Z0-9]*?[A-Z]?)([0-9]+)$", self.asset_id) + if asset_search is None: errdict["asset_id"] = ["An Asset ID can only consist of letters and numbers"] + self.asset_id_prefix = asset_search.group(1) + self.asset_id_number = int(asset_search.group(2)) if self.purchase_price and self.purchase_price < 0: errdict["purchase_price"] = ["A price cannot be negative"]