Repository: validatorjs/validator.js
Pull request #2492 (2024-11-12 13:53:24)

Assign check digit to 0 if remainder is 10
### Title:
feat(isISO6346): improve ISO6346 container ID validation with checksum adjustments

### Description: 
This PR enhances the isISO6346 validator to comply more accurately with the ISO 6346 standard, specifically addressing checksum validation for container IDs where the checksum result is 10. According to the standard, if the checksum is 10, the check digit should be represented as 0. This update improves accuracy in validating container IDs, particularly for freight containers (category 'U') where the checksum is mandatory.

### Changes include:
- Adjusting checksum validation to handle cases where the checksum is 10, setting the check digit to 0 as per the standard.
- Adding tests for container IDs with check digits of 0 (when the checksum is 10) to ensure the validator correctly processes edge cases.

### References:
"If the final difference is 10, then the check digit becomes 0. To ensure that this does not happen the standard recommends that serial numbers should not be used which produce a final difference of 10; however, there are containers in the market which do not follow this recommendation, so handling this case has to be included if a check digit calculator is programmed."
- https://en.wikipedia.org/wiki/ISO_6346

I think this should be considered as I'm currently working for a logistics company and we get container numbers that end with 0 (checksum is 10) very often. Hence, decided to help contribute. Let me know what you think!

### Checklist

- [x] PR contains only changes related; no stray files, etc.
- [ ] README updated (where applicable)
- [x] Tests written (where applicable)
- [x] References provided in PR (where applicable)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/validatorjs/validator.js/pull/2492?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 99.96%. Comparing base [(`f81d857`)](https://app.codecov.io/gh/validatorjs/validator.js/commit/f81d85702b06ba1e0a624d4d345cacdde46ed3e0?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) to head [(`de21f8d`)](https://app.codecov.io/gh/validatorjs/validator.js/commit/de21f8df4e2d9dbd2280de0ceb86ad31b9c729c2?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).
> Report is 12 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##            master    #2492      +/-   ##
===========================================
- Coverage   100.00%   99.96%   -0.04%     
===========================================
  Files          110      111       +1     
  Lines         2510     2523      +13     
  Branches       633      638       +5     
===========================================
+ Hits          2510     2522      +12     
- Partials         0        1       +1     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/validatorjs/validator.js/pull/2492?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).

WikiRik: Failing check is not due to your change, so this all looks good to me. After a second approval we can merge this

Patch:
diff --git a/src/lib/isISO6346.js b/src/lib/isISO6346.js
index 0cb657e..2c28c11 100644
--- a/src/lib/isISO6346.js
+++ b/src/lib/isISO6346.js
@@ -27,7 +27,8 @@ export function isISO6346(str) {
       } else sum += str[i] * (2 ** i);
     }
 
-    const checkSumDigit = sum % 11;
+    let checkSumDigit = sum % 11;
+    if (checkSumDigit === 10) checkSumDigit = 0;
     return Number(str[str.length - 1]) === checkSumDigit;
   }
 


Test patch:
diff --git a/test/validators.test.js b/test/validators.test.js
index 08d76f8..8335477 100644
--- a/test/validators.test.js
+++ b/test/validators.test.js
@@ -13066,6 +13066,55 @@ describe('Validators', () => {
     });
   });
 
+  it('should validate ISO6346 shipping container IDs with checksum digit 10 represented as 0', () => {
+    test({
+      validator: 'isISO6346',
+      valid: [
+        'APZU3789870',
+        'TEMU1002030',
+        'DFSU1704420',
+        'CMAU2221480',
+        'SEGU5060260',
+        'FCIU8939320',
+        'TRHU3495670',
+        'MEDU3871410',
+        'CMAU2184010',
+        'TCLU2265970',
+      ],
+      invalid: [
+        'APZU3789871', // Incorrect check digit
+        'TEMU1002031',
+        'DFSU1704421',
+        'CMAU2221481',
+        'SEGU5060261',
+      ],
+    });
+  });
+  it('should validate ISO6346 shipping container IDs with checksum digit 10 represented as 0', () => {
+    test({
+      validator: 'isFreightContainerID',
+      valid: [
+        'APZU3789870',
+        'TEMU1002030',
+        'DFSU1704420',
+        'CMAU2221480',
+        'SEGU5060260',
+        'FCIU8939320',
+        'TRHU3495670',
+        'MEDU3871410',
+        'CMAU2184010',
+        'TCLU2265970',
+      ],
+      invalid: [
+        'APZU3789871', // Incorrect check digit
+        'TEMU1002031',
+        'DFSU1704421',
+        'CMAU2221481',
+        'SEGU5060261',
+      ],
+    });
+  });
+
   // EU-UK valid numbers sourced from https://ec.europa.eu/taxation_customs/tin/specs/FS-TIN%20Algorithms-Public.docx or constructed by @tplessas.
   it('should validate taxID', () => {
     test({