Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #8: Health card number validation for QC #12

Merged
merged 1 commit into from
Oct 21, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Issue #8: Health card number validation for QC
  • Loading branch information
marta- committed Oct 20, 2020
commit 55e3dfc74a8ccc4ea3685b0fd4c12d90ce309a55
45 changes: 42 additions & 3 deletions guids-generator.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@
return MOD_10_check_digit(value) ? value : {"error" : "Health card number " + value + " is invalid for the province of ON. Please check the number and try again."};
},
QC: function (value, dob) {
console.log(dob);
let disableValidateChecksum = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we introduce it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For convenience in case we want to disable it easily.

// Expected: 4 letters and 8 digits, possibly grouped as XXXX #### #### with a space separator
let RAMQ_NB_REGEXP = /^\s*[a-zA-Z]{4}\s?\d{4}\s?\d{4}\s*$/;
if (!RAMQ_NB_REGEXP.exec(value)) {
return {"error" : "Health card number " + value + " is invalid for the province of QC. A 4 letter word followed by 8 digits number is expected."};
return {"error" : "Health card number " + value + " is invalid for the province of QC. A 4 letter word followed by 8 digits is expected."};
}
// Extract the meaningful characters as a string
value = value.replace(/\W+/g, '').toUpperCase();
Expand All @@ -130,7 +130,46 @@
if (dobDigits != hcDobSexDigits && dobDigits + 5000 != hcDobSexDigits) {
return {"error" : "Health card number " + value + " is invalid for the province of QC. The digits do not match the provided date of birth."};
}
return value;
// Checksum validation
// Source of the validation method used: https://github.com/petalmd/health_card/blob/master/spec/validators/canada/quebec_validator_spec.rb
// Step 1 : letter to code
let letterToCode = (letter) => {
// A is 1, B is 2...
var code = letter.charCodeAt(0) - "A".charCodeAt(0) + 1;
// ?!!! There's an imaginary letter between `R` and `S`
if (code > 18) code += 1;
return (code+"").padStart(2,0);
}
// Step 2: augment the hc number: coded letters + full dob + 11th digit
let hcToDigits = (value) => {
let hcCode = "";
// Coded letters:
for (let i = 0; i < 4; ++i) {
hcCode += letterToCode(value.charAt(i));
}
// Full DOB
hcCode += dob.replace(/-/g, '');
// 11th digit:
hcCode += value.charAt(10);
return hcCode;
}
// Step 3: compute checksum
let validateChecksum = (value) => {
// 50 is added to the month group of the HC number for females
let isFemale = (+value.charAt(6) > 1);
let hcCode = hcToDigits(value);
let checksum = 0
// Mystery checksum algorithm:
Array(7, 1, 1, 3, 9, 7, 3, 9, 5, 3, 1, 3, 5, 7, 6, 9, 1).map ( (factor, index) => {
checksum += factor * (+hcCode.charAt(index))
} );
if (isFemale) checksum += 4;
// compare to the last digit of the health card number
return (checksum %= 10) == +value.charAt(value.length - 1) ;
}
return disableValidateChecksum || validateChecksum(value) ?
value :
{"error" : "Health card number " + value + " is invalid for the province of QC. Please check the number and try again."};
},
CA: function (value) {
// Generic sanitizer to use when specific province validators are unavailable:
Expand Down