Data migration to initially update serial number fields for all stock items

- Also automatically updates serial_int field when saving StockItem
This commit is contained in:
Oliver 2021-11-10 10:59:48 +11:00
parent 257be18d79
commit 738ba4eddf
2 changed files with 81 additions and 0 deletions

View File

@ -0,0 +1,55 @@
# Generated by Django 3.2.5 on 2021-11-09 23:47
import re
from django.db import migrations
def update_serials(apps, schema_editor):
"""
Rebuild the integer serial number field for existing StockItem objects
"""
StockItem = apps.get_model('stock', 'stockitem')
for item in StockItem.objects.all():
if item.serial is None:
# Skip items without existing serial numbers
continue
serial = 0
result = re.match(r"^(\d+)", item.serial or "")
if result and len(result.groups()) == 1:
try:
serial = int(result.groups()[0])
except:
serial = 0
item.serial_int = serial
print(item, item.serial, '->', item.serial_int)
item.save()
def nupdate_serials(apps, schema_editor):
"""
Provided only for reverse migration compatibility
"""
pass
class Migration(migrations.Migration):
dependencies = [
('stock', '0068_stockitem_serial_int'),
]
operations = [
migrations.RunPython(
update_serials,
reverse_code=nupdate_serials,
)
]

View File

@ -7,6 +7,7 @@ Stock database model definitions
from __future__ import unicode_literals
import os
import re
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError, FieldError
@ -223,6 +224,29 @@ class StockItem(MPTTModel):
self.scheduled_for_deletion = True
self.save()
def update_serial_number(self):
"""
Update the 'serial_int' field, to be an integer representation of the serial number.
This is used for efficient numerical sorting
"""
serial = getattr(self, 'serial', '')
# Default value if we cannot convert to an integer
serial_int = 0
# Look at the start of the string - can it be "integerized"?
result = re.match(r'^(\d+)', serial or "")
if result and len(result.groups()) == 1:
try:
serial_int = int(result.groups()[0])
except:
serial_int = 0
self.serial_int = serial_int
def save(self, *args, **kwargs):
"""
Save this StockItem to the database. Performs a number of checks:
@ -234,6 +258,8 @@ class StockItem(MPTTModel):
self.validate_unique()
self.clean()
self.update_serial_number()
user = kwargs.pop('user', None)
# If 'add_note = False' specified, then no tracking note will be added for item creation