Importer works. Doesn't yet compensate for crap data quality.

This commit is contained in:
2021-10-27 16:42:52 +01:00
parent e78decdf92
commit 522837c64e
4 changed files with 149 additions and 127 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.13 on 2021-10-27 14:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0042_auto_20211007_2338'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='initials',
field=models.CharField(max_length=5, null=True),
),
]

View File

@@ -21,7 +21,7 @@ from reversion.models import Version
@reversion.register @reversion.register
class Profile(AbstractUser): # TODO move to versioning - currently get import errors with that class Profile(AbstractUser): # TODO move to versioning - currently get import errors with that
initials = models.CharField(max_length=5, unique=True, null=True, blank=False) initials = models.CharField(max_length=5, null=True, blank=False)
phone = models.CharField(max_length=13, blank=True, default='') phone = models.CharField(max_length=13, blank=True, default='')
api_key = models.CharField(max_length=40, blank=True, editable=False, default='') api_key = models.CharField(max_length=40, blank=True, editable=False, default='')
is_approved = models.BooleanField(default=False) is_approved = models.BooleanField(default=False)

View File

@@ -1,22 +1,26 @@
import os import os
import datetime import datetime
import re
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.conf import settings from django.conf import settings
from django.db.utils import IntegrityError
from training import models from training import models
#from RIGS import models.Profile from RIGS.models import Profile
class Command(BaseCommand): class Command(BaseCommand):
epoch = datetime.date(1970, 1, 1) epoch = datetime.date(1970, 1, 1)
id_map = {}
def handle(self, *args, **options): def handle(self, *args, **options):
self.import_Trainees()
self.import_TrainingCatagory() self.import_TrainingCatagory()
self.import_TrainingItem() self.import_TrainingItem()
self.import_TrainingItemQualification() self.import_TrainingItemQualification()
self.import_TrainingLevel() self.import_TrainingLevel()
self.import_TrainingLevelQualification() self.import_TrainingLevelQualification()
@staticmethod @staticmethod
def xml_path(file): def xml_path(file):
return os.path.join(settings.BASE_DIR, 'data/{}'.format(file)) return os.path.join(settings.BASE_DIR, 'data/{}'.format(file))
@@ -27,30 +31,60 @@ class Command(BaseCommand):
return tree.getroot() return tree.getroot()
def import_Trainees(self):
tally = [0, 0]
root = self.parse_xml(self.xml_path('Members.xml'))
for child in root:
try:
name = child.find('Member_x0020_Name').text
first_name = name.split()[0]
last_name = " ".join(name.split()[1:])
profile = Profile.objects.filter(first_name=first_name, last_name=last_name).first()
if profile:
self.id_map[child.find('ID').text] = profile.pk
tally[0] += 1
else:
# PYTHONIC, BABY
initials = first_name[0] + "".join([name_section[0] for name_section in re.split("\s*-", last_name.replace("(", ""))])
# print(initials)
new_profile = Profile.objects.create(username=name.replace(" ", ""),
first_name=first_name,
last_name=last_name,
initials=initials)
self.id_map[child.find('ID').text] = new_profile.pk
tally[1] += 1
except AttributeError: # W.T.F
print("Trainee #{} is FUBAR".format(child.find('ID').text))
print('Trainees - Updated: {}, Created: {}'.format(tally[0], tally[1]))
def import_TrainingCatagory(self): def import_TrainingCatagory(self):
tally = [0, 0] tally = [0, 0]
root = self.parse_xml(self.xml_path('Categories.xml')) root = self.parse_xml(self.xml_path('Categories.xml'))
for child in root: for child in root:
obj, created = models.TrainingCategory.objects.update_or_create( obj, created = models.TrainingCategory.objects.update_or_create(
pk=int(child.find('ID').text), pk=int(child.find('ID').text),
reference_number = int(child.find('Category_x0020_Number').text), reference_number = int(child.find('Category_x0020_Number').text),
name=child.find('Category_x0020_Name').text name=child.find('Category_x0020_Name').text
) )
if created: if created:
tally[1] += 1 tally[1] += 1
else: else:
tally[0] += 1 tally[0] += 1
print('Categories - Updated: {}, Created: {}'.format(tally[0], tally[1])) print('Categories - Updated: {}, Created: {}'.format(tally[0], tally[1]))
def import_TrainingItem(self): def import_TrainingItem(self):
tally = [0, 0] tally = [0, 0]
root = self.parse_xml(self.xml_path('Training Items.xml')) root = self.parse_xml(self.xml_path('Training Items.xml'))
for child in root: for child in root:
if child.find('active').text == '0': active = False if child.find('active').text == '0': active = False
else: active = True else: active = True
@@ -61,155 +95,126 @@ class Command(BaseCommand):
category = models.TrainingCategory.objects.get(pk=int(child.find('Category_x0020_ID').text)), category = models.TrainingCategory.objects.get(pk=int(child.find('Category_x0020_ID').text)),
active = active active = active
) )
if created: if created:
tally[1] += 1 tally[1] += 1
else: else:
tally[0] += 1 tally[0] += 1
print('Training Items - Updated: {}, Created: {}'.format(tally[0], tally[1])) print('Training Items - Updated: {}, Created: {}'.format(tally[0], tally[1]))
def import_TrainingItemQualification(self): def import_TrainingItemQualification(self):
tally = [0, 0] tally = [0, 0, 0]
root = self.parse_xml(self.xml_path('Training Records.xml')) root = self.parse_xml(self.xml_path('Training Records.xml'))
for child in root: for child in root:
if child.find('Traning_Started_Date').text != '': depths = [("Training_Started", models.TrainingItemQualification.STARTED),
obj, created = models.TrainingItemQualification.objects.update_or_create( ("Training_Complete", models.TrainingItemQualification.COMPLETE),
pk=int(child.find('ID').text), ("Competency_Assessed", models.TrainingItemQualification.PASSED_OUT)]
item = int(child.find('Training_Item_ID').text), for depth, depth_index in depths:
trainee = int(child.find('Member_ID').text), if child.find('{}_Date'.format(depth)) is not None:
depth = 0, if child.find('{}_Assessor_ID'.format(depth)) is None:
date = child.find('Traning_Started_Date').text, print("Training Record #{} had no supervisor. Hmm.".format(child.find('ID').text))
supervisor = int(child.find('Training_Started_Assessor_ID').text), tally[2] += 1
notes = child.find('Training_Started_Notes').text # TODO Assign God/Satan/Unknown here.
) continue
if child.find('Traning_Complete_Date').text != '': supervisor = Profile.objects.get(pk=self.id_map[child.find('{}_Assessor_ID'.format(depth)).text])
obj, created = models.TrainingItemQualification.objects.update_or_create( if child.find('Member_ID') is None:
pk=int(child.find('ID').text), print("Training Record #{} didn't train anybody and has been ignored. Dammit {}".format(child.find('ID').text, supervisor.name))
item = int(child.find('Training_Item_ID').text), tally[2] += 1
trainee = int(child.find('Member_ID').text), continue
depth = 1, try:
date = child.find('Traning_Complete_Date').text, obj, created = models.TrainingItemQualification.objects.update_or_create(
supervisor = int(child.find('Training_Complete_Assessor_ID'),text), pk=int(child.find('ID').text),
notes = child.find('Training_Complete_Notes').text item = models.TrainingItem.objects.get(pk=int(child.find('Training_Item_ID').text)),
) trainee = Profile.objects.get(pk=self.id_map[child.find('Member_ID').text]),
if child.find('Competency_Assessed_Date').text != '': depth = depth_index,
obj, created = models.TrainingItemQualification.objects.update_or_create( date = child.find('{}_Date'.format(depth)).text[:-9], # Stored as datetime with time as midnight because fuck you I guess
pk=int(child.find('ID').text), supervisor = supervisor
item = int(child.find('Training_Item_ID').text), )
trainee = int(child.find('Member_ID').text), notes = child.find('{}_Notes'.format(depth))
depth = 2, if notes:
date = child.find('Competency_Assessed_Date').text, obj.notes = notes.text
supervisor = int(child.find('Competency_Assessed_Assessor_ID'),text), obj.save()
notes = child.find('Competency_Assessed_Notes').text if created:
) tally[1] += 1
else:
if created: tally[0] += 1
tally[1] += 1 except IntegrityError: # Eh?
else: print("Training Record #{} is duplicate. ಠ_ಠ".format(child.find('ID').text))
tally[0] += 1 except AttributeError:
print(child.find('ID').text)
print('Training Item Qualifications - Updated: {}, Created: {}'.format(tally[0], tally[1]))
print('Training Item Qualifications - Updated: {}, Created: {}, Broken: {}'.format(tally[0], tally[1], tally[2]))
def import_TrainingLevel(self): def import_TrainingLevel(self):
tally = [0, 0] tally = [0, 0]
root = self.parse_xml(self.xml_path('Training Levels')) root = self.parse_xml(self.xml_path('Training Levels.xml'))
for child in root: for child in root:
name = child.find('Level_x0020_Name').text name = child.find('Level_x0020_Name').text
if name != "Technical Assistant": if name != "Technical Assistant":
depString = name.split()[-1] depString = name.split()[-1]
levelString = name.split()[0] levelString = name.split()[0]
if levelString == "Technician":
level = models.TrainingLevel.TECHNICIAN
elif levelString == "Supervisor":
level = models.TrainingLevel.SUPERVISOR
else:
print(levelString)
continue
for dep in models.TrainingLevel.DEPARTMENTS:
if dep[1] == depString:
department = dep[0]
else: else:
levelString = name level = models.TrainingLevel.TA
depString = None depString = None
obj, created = models.TrainingLevel.objects.update_or_create( obj, created = models.TrainingLevel.objects.update_or_create(
pk=int(child.find('ID').text), pk=int(child.find('ID').text),
description = name, description = name,
department = depString, level = level
level = levelString
) )
if depString is not None:
obj.department = department
obj.save()
if created: if created:
tally[1] += 1 tally[1] += 1
else: else:
tally[0] += 1 tally[0] += 1
print('Training Levels - Updated: {}, Created: {}'.format(tally[0], tally[1])) print('Training Levels - Updated: {}, Created: {}'.format(tally[0], tally[1]))
def import_TrainingLevelQualification(self): def import_TrainingLevelQualification(self):
tally = [0, 0] tally = [0, 0]
root = self.parse_xml(self.xml_path('Training Level Record')) root = self.parse_xml(self.xml_path('Training Level Records.xml'))
for child in root: for child in root:
obj, created = models.TrainingLevelQualification.objects.update_or_create( try:
pk = int(child.find('ID').text), if child.find('Training_x0020_Level_x0020_ID') is None:
trainee = int(child.find('Member_x0020_ID').text), print('Training Level Qualification #{} does not qualify in any level. How?'.format(child.find('ID').text))
level = int(child.find('Training_x0020_Level_x0020_ID').text), continue
confirmed_on = child.find('Date_x0020_Level_x0020_Awarded').text if child.find('Member_x0020_ID') is None:
#confirmed by? print('Training Level Qualification #{} does not qualify anyone. How?!'.format(child.find('ID').text))
) continue
obj, created = models.TrainingLevelQualification.objects.update_or_create(
if created: pk = int(child.find('ID').text),
tally[1] += 1 trainee = Profile.objects.get(pk=self.id_map[child.find('Member_x0020_ID').text]),
else: level = models.TrainingLevel.objects.get(pk=int(child.find('Training_x0020_Level_x0020_ID').text)),
tally[0] += 1 # FIXME
#confirmed_on = child.find('Date_x0020_Level_x0020_Awarded').text
#confirmed by?
)
if created:
tally[1] += 1
else:
tally[0] += 1
except IntegrityError: # Eh?
print("Training Level Qualification #{} is duplicate. ಠ_ಠ".format(child.find('ID').text))
print('TrainingLevelQualifications - Updated: {}, Created: {}'.format(tally[0], tally[1])) print('TrainingLevelQualifications - Updated: {}, Created: {}'.format(tally[0], tally[1]))

View File

@@ -69,7 +69,7 @@
</div> </div>
{% if forloop.last %}</div>{%endif%} {% if forloop.last %}</div>{%endif%}
{% empty %} {% empty %}
<div class="alert alert-warning">No qualifications in any levels yet...did someone forget to fill out the paperwork?</div> <div class="alert alert-warning mx-auto">No qualifications in any levels yet...did someone forget to fill out the paperwork?</div>
{% endfor %} {% endfor %}
<div class="card-columns"> <div class="card-columns">
{% for level in started_levels %} {% for level in started_levels %}
@@ -87,8 +87,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<h2 class="col-10">Training Items</h2> <h2 class="col-12 pb-2">Training Items <small class="bg-light rounded-sm p-2"> Key: <span class="badge badge-warning">Training Started</span> <span class="badge badge-success">Training Complete</span> <span class="badge badge-info">Passed Out</span></small></h2>
<div class="alert alert-info col-12" role="alert"><h3>Key: <span class="badge badge-warning">Training Started</span> <span class="badge badge-success">Training Complete</span> <span class="badge badge-info">Passed Out</span></h3></div>
{% for category in categories %} {% for category in categories %}
{% if forloop.first or forloop.counter|divisibleby:3 %}<div class="card-deck col-12">{% endif %} {% if forloop.first or forloop.counter|divisibleby:3 %}<div class="card-deck col-12">{% endif %}
<div class="card mb-3"> <div class="card mb-3">