Coverage for app/logic/certification.py: 100%
49 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-10-02 17:57 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-10-02 17:57 +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.certification_id == certId, CertificationRequirement.id.not_in(saveIds)).execute()
85 # update existing and add new requirements
86 requirements = []
87 for order, requirementData in enumerate(newRequirements):
88 try:
89 newRequirement = CertificationRequirement.get_by_id(requirementData['id'])
90 except DoesNotExist:
91 newRequirement = CertificationRequirement()
93 newRequirement.certification = certId
94 newRequirement.isRequired = bool(requirementData['required'])
95 newRequirement.frequency = requirementData['frequency']
96 newRequirement.name = requirementData['name']
97 newRequirement.order = order
98 newRequirement.save()
100 requirements.append(newRequirement)
102 return requirements
104def updateCertRequirementForEvent(event, requirement):
105 """
106 Add a certification requirement to an event.
107 Replaces the requirement for an event if the event already exists.
109 Arguments:
110 event - an Event object or id
111 requirement - a CertificationRequirement object or id
112 """
113 # delete existing matches for our event
114 for match in RequirementMatch.select().where(RequirementMatch.event == event):
115 match.delete_instance()
117 RequirementMatch.create(event=event, requirement=requirement)