Coverage for app/logic/certification.py: 100%
49 statements
« prev ^ index » next coverage.py v7.2.5, created at 2023-05-24 14:13 +0000
« prev ^ index » next coverage.py v7.2.5, created at 2023-05-24 14:13 +0000
1from peewee import JOIN, DoesNotExist, Case
3from app.models.certification import Certification
4from app.models.certificationRequirement import CertificationRequirement
5from app.models.requirementMatch import RequirementMatch
6from app.models.eventParticipant import EventParticipant
8def getCertRequirementsWithCompletion(*, certification, username):
9 """
10 Function to differentiate between simple requirements and requirements completion checking.
11 See: `getCertRequirements`
12 """
13 return getCertRequirements(certification, username)
15def getCertRequirements(certification=None, username=None):
16 """
17 Return the requirements for all certifications, or for one if requested.
19 Keyword arguments:
20 certification -- The id or object for a certification to request
21 username -- The username to check for completion
23 Returns:
24 A list of dictionaries with all certification data and requirements. If `certification`
25 is given, returns only a list of requirement objects for the given certification. If
26 `username` is given, the requirement objects have a `completed` attribute.
27 """
28 reqList = (Certification.select(Certification, CertificationRequirement)
29 .join(CertificationRequirement, JOIN.LEFT_OUTER, attr="requirement")
30 .order_by(Certification.id, CertificationRequirement.order.asc(nulls="LAST")))
32 if certification:
33 if username:
34 # I don't know how to add something to a select, so we have to recreate the whole query :(
35 completedCase = Case(None, ((EventParticipant.user_id.is_null(True), 0),), 1)
36 reqList = (Certification
37 .select(Certification, CertificationRequirement, completedCase.alias("completed"))
38 .join(CertificationRequirement, JOIN.LEFT_OUTER, attr="requirement")
39 .join(RequirementMatch, JOIN.LEFT_OUTER)
40 .join(EventParticipant, JOIN.LEFT_OUTER, on=(RequirementMatch.event == EventParticipant.event))
41 .where(EventParticipant.user.is_null(True) | (EventParticipant.user == username))
42 .order_by(Certification.id, CertificationRequirement.order.asc(nulls="LAST")))
44 # we have to add the is not null check so that `cert.requirement` always exists
45 reqList = reqList.where(Certification.id == certification, CertificationRequirement.id.is_null(False))
46 reqList = reqList.distinct()
48 certs = []
49 for cert in reqList:
50 if username:
51 cert.requirement.completed = bool(cert.__dict__['completed'])
52 certs.append(cert.requirement)
53 return certs
55 #return [cert.requirement for cert in reqList]
57 certs = {}
58 for cert in reqList:
59 if cert.id not in certs.keys():
60 certs[cert.id] = {"data": cert, "requirements": []}
62 if getattr(cert, 'requirement', None):
63 certs[cert.id]["requirements"].append(cert.requirement)
65 return certs
67def updateCertRequirements(certId, newRequirements):
68 """
69 Update the certification requirements in the database to match the provided list of requirement data.
71 The order of the list matters. Any ids that are in the database and not in `newRequirements` will be
72 removed. IDs that do not exist in the database will be created (and given a new, auto-generated ID).
74 Arguments:
75 certId - The id of the certification whose requirements we are updating
76 newRequirements - a list of dictionaries. Each dictionary needs 'id', 'required', 'frequency', and 'name'.
78 Returns:
79 A list of CertificationRequirement objects corresponding to the given `newRequirements` list.
80 """
81 # check for missing ids to remove
82 saveIds = [requirementData['id'] for requirementData in newRequirements]
83 CertificationRequirement.delete().where(CertificationRequirement.id.not_in(saveIds)).execute()
86 # update existing and add new requirements
87 requirements = []
88 for order, requirementData in enumerate(newRequirements):
89 try:
90 newRequirement = CertificationRequirement.get_by_id(requirementData['id'])
91 except DoesNotExist:
92 newRequirement = CertificationRequirement()
94 newRequirement.certification = certId
95 newRequirement.isRequired = bool(requirementData['required'])
96 newRequirement.frequency = requirementData['frequency']
97 newRequirement.name = requirementData['name']
98 newRequirement.order = order
99 newRequirement.save()
101 requirements.append(newRequirement)
103 return requirements
105def updateCertRequirementForEvent(event, requirement):
106 """
107 Add a certification requirement to an event.
108 Replaces the requirement for an event if the event already exists.
110 Arguments:
111 event - an Event object or id
112 requirement - a CertificationRequirement object or id
113 """
114 # delete existing matches for our event
115 for match in RequirementMatch.select().where(RequirementMatch.event == event):
116 match.delete_instance()
118 RequirementMatch.create(event=event, requirement=requirement)