cmsmanage/paperwork/models.py
Adam Goldsmith 3c73e9fa46 [paperwork] Use semver to determine if if certs are latest or outdated
"Latest" = cert with the highest version number
"Current" = compatible version, so not latest, but still valid
"Outdated" = major version < major version of "latest"
2022-11-07 15:34:44 -05:00

240 lines
7.7 KiB
Python

from django.db import models
import re
import semver
from membershipworks.models import Member
VALID_SEMVER_PATTERN = re.compile(
r"(?P<semver>\d+\.\d+\.\d+) - (?P<approvaldate>\d{4}-\d{2}-\d{2})"
)
class CmsRedRiverVeteransScholarship(models.Model):
serial = models.AutoField(primary_key=True)
program_name = models.CharField(db_column="Program Name", max_length=255)
member_name = models.CharField(
db_column="Member Name", max_length=255, blank=True, null=True
)
discount_percent = models.DecimalField(
db_column="Discount Percent",
max_digits=16,
decimal_places=0,
blank=True,
null=True,
)
discount_code = models.CharField(
db_column="Discount Code", max_length=255, blank=True, null=True
)
membership_code = models.CharField(
db_column="Membership Code", max_length=255, blank=True, null=True
)
start_date = models.DateField(db_column="Start Date", blank=True, null=True)
end_date = models.DateField(db_column="End Date", blank=True, null=True)
program_amount = models.DecimalField(
db_column="Program Amount",
max_digits=16,
decimal_places=0,
blank=True,
null=True,
)
program_status = models.CharField(
db_column="Program Status", max_length=16, blank=True, null=True
)
def __str__(self):
return f"{self.program_name} {self.member_name}"
class Meta:
db_table = "CMS Red River Veterans Scholarship"
class CertificationDefinition(models.Model):
certification_identifier = models.AutoField(
db_column="Certification Identifier", primary_key=True
)
certification_name = models.CharField(
db_column="Certification Name", max_length=255, blank=True, null=True
)
department = models.CharField(
db_column="Department", max_length=255, blank=True, null=True
)
def __str__(self):
return f"{self.certification_name} <{self.department}>"
class Meta:
db_table = "Certification Definitions"
ordering = ("certification_name", "department")
def latest_version(self) -> "CertificationVersion":
all_versions = CertificationVersion.objects.filter(definition=self)
return max(all_versions, key=lambda version: version.semantic_version())
class CertificationVersion(models.Model):
definition = models.ForeignKey(
CertificationDefinition, on_delete=models.PROTECT, db_column="Certification"
)
version = models.CharField(
db_column="Version", max_length=255, blank=True, null=True
)
def __str__(self):
return f"{self.definition} [{self.version}]"
class Meta:
constraints = [
models.UniqueConstraint(
fields=["definition", "version"], name="unique_certification_version"
)
]
def semantic_version(self) -> semver.VersionInfo:
if self.version is None:
return "0.0.0-none"
elif self.version == "MembershipWorks Label":
return semver.parse_version_info("0.0.1-mw-label")
elif match := VALID_SEMVER_PATTERN.match(self.version):
return semver.parse_version_info(
f'{match["semver"]}+{match["approvaldate"]}'
)
else:
return semver.parse_version_info(
"0.0.1-" + re.sub(r"[^.a-zA-Z0-9]", "-", self.version)
)
def is_latest(self) -> bool:
return self.definition.latest_version() == self
is_latest.boolean = True
def is_current(self) -> bool:
"""Returns true if this version compatible with the latest version"""
# TODO: should do a more correct comparison than just major version
return (
self.definition.latest_version().semantic_version().major
== self.semantic_version().major
)
is_current.boolean = True
class Certification(models.Model):
number = models.AutoField(db_column="Number", primary_key=True)
certification_version = models.ForeignKey(
CertificationVersion, on_delete=models.PROTECT
)
name = models.CharField(db_column="Name", max_length=255)
member = models.ForeignKey(
Member,
on_delete=models.PROTECT,
to_field="uid",
db_column="uid",
blank=True,
null=True,
db_constraint=False,
)
certified_by = models.CharField(
db_column="Certified_By", max_length=255, blank=True, null=True
)
date = models.DateField(db_column="Date", blank=True, null=True)
shop_lead_notified = models.DateTimeField(
db_column="Shop Lead Notified", blank=True, null=True
)
notes = models.CharField(db_column="Notes", max_length=255, blank=True, null=True)
def __str__(self):
return f"{self.name} - {self.certification_version}"
class Meta:
db_table = "Certifications"
permissions = [
(
"receive_certification_emails",
"Receives notifications of all new certifications",
),
]
class InstructorOrVendor(models.Model):
serial = models.AutoField(primary_key=True)
name = models.CharField(db_column="Name", max_length=255)
instructor_agreement_date = models.DateField(
db_column="Instructor Agreement Date", blank=True, null=True
)
w9_date = models.DateField(db_column="W9 date", blank=True, null=True)
phone = models.CharField(max_length=255, blank=True, null=True)
email_address = models.CharField(
db_column="email address", max_length=255, blank=True, null=True
)
def __str__(self):
return f"{self.name}"
class Meta:
db_table = "Instructors and Vendors"
class SpecialProgram(models.Model):
program_name = models.CharField(
db_column="Program Name", primary_key=True, max_length=255
)
discount_percent = models.DecimalField(
db_column="Discount Percent",
max_digits=16,
decimal_places=0,
blank=True,
null=True,
)
discount_code = models.CharField(
db_column="Discount Code", max_length=255, blank=True, null=True
)
membership_code = models.CharField(
db_column="Membership Code", max_length=255, blank=True, null=True
)
start_date = models.DateField(db_column="Start Date", blank=True, null=True)
end_date = models.DateField(db_column="End Date", blank=True, null=True)
program_amount = models.DecimalField(
db_column="Program Amount",
max_digits=16,
decimal_places=0,
blank=True,
null=True,
)
program_status = models.CharField(
db_column="Program Status", max_length=16, blank=True, null=True
)
def __str__(self):
return self.program_name
class Meta:
db_table = "Special_Programs"
class Waiver(models.Model):
number = models.AutoField(db_column="Number", primary_key=True)
name = models.CharField(db_column="Name", max_length=255)
date = models.DateField(db_column="Date")
emergency_contact_name = models.CharField(
db_column="Emergency Contact Name", max_length=255, blank=True, null=True
)
emergency_contact_number = models.CharField(
db_column="Emergency Contact Number", max_length=25, blank=True, null=True
)
waiver_version = models.CharField(db_column="Waiver version", max_length=64)
guardian_name = models.CharField(
db_column="Guardian Name", max_length=255, blank=True, null=True
)
guardian_relation = models.CharField(
db_column="Guardian Relation", max_length=255, blank=True, null=True
)
guardian_date = models.DateField(db_column="Guardian Date", blank=True, null=True)
def __str__(self):
return f"{self.name} {self.date}"
class Meta:
db_table = "Waivers"