validateMrzLineVisa function

OcrMrzValidation validateMrzLineVisa({
  1. required String line1,
  2. required String line2,
  3. required OcrMrzSetting setting,
  4. required List<String> otherLines,
  5. required String firstName,
  6. required String lastName,
  7. required String country,
  8. required String nationality,
  9. required String issuing,
  10. required String personalNumber,
  11. required List<NameValidationData>? nameValidations,
})

Implementation

OcrMrzValidation validateMrzLineVisa({
  required String line1,
  required String line2,
  required OcrMrzSetting setting,
  required List<String> otherLines,
  required String firstName,
  required String lastName,
  required String country,
  required String nationality,
  required String issuing,
  required String personalNumber,
  required List<NameValidationData>? nameValidations,
}) {
  OcrMrzValidation validation = OcrMrzValidation();
  try {
    final docNumber = line2.substring(0, 9);
    final docCode = line1.substring(0, 2);
    final docCheck = line2.substring(9, 10);
    final nationality =fixAlphaOnlyField(line2.substring(10, 13));
    final birth = line2.substring(13, 19);
    final birthCheck = line2.substring(19, 20);
    final sex = line2.substring(20, 21);
    final expiry = line2.substring(21, 27);
    final expiryCheck = line2.substring(27, 28);
    final optional = line2.substring(28, line2.length); // no final composite check for visas

    // Validate check digits (no composite)
    final validDoc = _computeMrzCheckDigit(docNumber) == docCheck;
    final validBirth = RegExp(r'^\d{6}$').hasMatch(birth) && _computeMrzCheckDigit(birth) == birthCheck;
    final validExpiry = RegExp(r'^\d{6}$').hasMatch(expiry) && _computeMrzCheckDigit(expiry) == expiryCheck;

    // Name/country validations (reuse your switches)
    var namesOk =
    validation.nameValid
        ? (validateNames(firstName, lastName, otherLines) || (nameValidations?.any((a) => a.firstName.toLowerCase() == firstName.toLowerCase() && a.lastName.toLowerCase() == lastName.toLowerCase()) ?? false))
        : true;

    final issuingOk = validation.countryValid ? isValidMrzCountry(issuing) : true;
    final nationalityOk = validation.nationalityValid ? isValidMrzCountry(nationality) : true;
    final birthOk = !validation.birthDateValid || validBirth;
    final expiryOk = !validation.expiryDateValid || validExpiry;
    final docOk = !validation.docNumberValid || validDoc;

    validation.docCodeValid = DocumentCodeHelper.isValid(docCode);
    validation.docNumberValid = docOk;
    validation.birthDateValid = birthOk;
    validation.expiryDateValid = expiryOk;

    // String personalNumber = personalNumber;
    String personalCheck = line2[42];
    final isPersonalValid = personalNumber.replaceAll('<', '').isEmpty
        ? (personalCheck == '0' || personalCheck == '<')
        : (_computeMrzCheckDigit(personalNumber) == personalCheck);
    validation.personalNumberValid = isPersonalValid;


    // bool isFinalCheckValid = _computeMrzCheckDigit(docNumber + docCheck + birth + birthCheck + expiry + expiryCheck + personalNumber + personalCheck) == finalCheck;
    validation.finalCheckValid = true;

    validation.nameValid = namesOk;
    if(!namesOk && nameValidations!=null){
      if(nameValidations.any((a)=>a.firstName.toLowerCase() == firstName.toLowerCase() && a.lastName.toLowerCase()==lastName.toLowerCase())){
        namesOk = true;
        validation.nameValid = true;
      }
    }


    validation.countryValid = issuingOk;

    validation.nationalityValid = nationalityOk;

    return validation;
  } catch (e) {
    return validation;
  }
}