headless_lms_models/library/credit_registration/
config_validation.rs1use crate::course_module_suotar_configurations::{SuotarConfigCheck, SuotarModuleConfigFacts};
9
10use super::grade_mapping::{GradeScaleFamily, grade_scale_family};
11
12const NO_COURSE_CODE: &str = "No uh_course_code, so nothing can be submitted.";
15const COURSE_CODE_NOT_FOUND: &str = "The study registry does not know this uh_course_code.";
16const NO_REALISATION: &str = "No active course unit realisation, so the roster is never listed.";
17const NO_ECTS: &str = "No ects_credits, so there is nothing to register.";
18const NO_PRODUCT_ID: &str =
19 "No open_university_product_id, so the re-enrol guidance has no working link.";
20const NO_PRODUCT_TOKEN: &str =
21 "No product access token has been resolved, so the re-enrol guidance has no working link.";
22const UNKNOWN_GRADE_SCALE: &str =
23 "The grade scale override is not a scale the study registry accepts.";
24const NUMERIC_SCALE_ON_UNGRADED_COMPLETIONS: &str =
25 "The grade scale override is numeric but the module has passed completions with no grade.";
26const OLD_FLOW_ALSO_ENABLED: &str = "enable_registering_completion_to_uh_open_university is on as well, which would register the same completion twice.";
27
28pub fn check_module_config(facts: &SuotarModuleConfigFacts) -> SuotarConfigCheck {
33 let mut problems: Vec<&str> = Vec::new();
34
35 let has_course_code = facts
36 .uh_course_code
37 .as_deref()
38 .is_some_and(|code| !code.trim().is_empty());
39 let course_code_resolves = if !has_course_code {
40 problems.push(NO_COURSE_CODE);
41 Some(false)
42 } else if facts.course_code_not_found {
43 problems.push(COURSE_CODE_NOT_FOUND);
44 Some(false)
45 } else if facts.listed_successfully {
46 Some(true)
47 } else {
48 None
49 };
50 if facts.active_realisation_count == 0 {
51 problems.push(NO_REALISATION);
52 }
53 if facts.ects_credits.is_none() {
54 problems.push(NO_ECTS);
55 }
56
57 let has_product_id = facts
58 .open_university_product_id
59 .as_deref()
60 .is_some_and(|id| !id.trim().is_empty());
61 if !has_product_id {
62 problems.push(NO_PRODUCT_ID);
63 } else if !facts.product_token_found {
64 problems.push(NO_PRODUCT_TOKEN);
65 }
66
67 match facts.grade_scale_id.as_deref().map(grade_scale_family) {
68 Some(None) => problems.push(UNKNOWN_GRADE_SCALE),
69 Some(Some(GradeScaleFamily::Numeric)) if facts.has_passed_completions_without_a_grade => {
70 problems.push(NUMERIC_SCALE_ON_UNGRADED_COMPLETIONS)
71 }
72 _ => {}
73 }
74 if facts.old_flow_also_enabled {
75 problems.push(OLD_FLOW_ALSO_ENABLED);
76 }
77
78 SuotarConfigCheck {
79 course_code_resolves,
80 product_token_found: Some(has_product_id && facts.product_token_found),
83 message: (!problems.is_empty()).then(|| problems.join(" ")),
84 }
85}