-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension.ts
98 lines (81 loc) · 2.74 KB
/
extension.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import * as Yup from 'yup';
declare module 'yup' {
export interface NumberSchema {
abn(): NumberSchema;
}
export interface StringSchema {
acn(): StringSchema;
arbn(): StringSchema;
arsn(): StringSchema;
}
}
const ABN_METHOD_NAME = 'abn';
const ABN_IDX_WEIGHTING = [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
const ACN_METHOD_NAME = 'acn';
const ARBN_METHOD_NAME = 'arbn';
const ARSN_METHOD_NAME = 'arsn';
const ACN_IDX_WEIGHTING = [8, 7, 6, 5, 4, 3, 2, 1];
/**
* @see https://abr.business.gov.au/Help/AbnFormat
*/
function parseABN() {
return this.test(
ABN_METHOD_NAME,
({ value }) => `${value} is not a valid ABN`,
function (value: number) {
const valueArray = Array.from(String(value));
const firstDigit = parseInt(valueArray[0]);
// ABN length must be 11
if (valueArray.length !== 11) {
return false; // Msg too short
}
if (firstDigit <= 0) {
return false; // Too small
}
// Decrement the first digit by 1
const valueArrayReplaceFirstDigit: string[] = valueArray.map((value, idx) => {
if (idx === 0) {
return String(firstDigit - 1);
}
return value;
});
// Multiply values based on their positional weighting
const valueSum = valueArrayReplaceFirstDigit.reduce(
(acc, val, idx) => acc + parseInt(val) * ABN_IDX_WEIGHTING[idx],
0
);
return valueSum % 89 === 0;
}
);
}
/**
* @see https://asic.gov.au/for-business/registering-a-company/steps-to-register-a-company/australian-company-numbers/australian-company-number-digit-check/
*/
function parseACN() {
return this.test(
ACN_METHOD_NAME,
({ value }) => `${value} is not a valid ACN, ARSN or ARBN`,
function (value: string) {
const valueArray = value.split('').filter((val) => Number.isInteger(parseInt(val)));
const lastDigitCheck = parseInt(valueArray.at(-1) || '0');
const valueArrayAsInt = valueArray.map((value) => parseInt(value)).slice(0, 8);
// ACN length must be 9
if (valueArray.length !== 9) {
return false; // Msg too short
}
const numberSum = valueArrayAsInt.reduce((acc, val, idx) => {
return acc + val * ACN_IDX_WEIGHTING[idx];
}, 0);
const valueRemainder = numberSum % 10;
const remainderCompliment = 10 - valueRemainder;
if (remainderCompliment === 10) {
return 0 === lastDigitCheck;
}
return remainderCompliment === lastDigitCheck;
}
);
}
Yup.addMethod(Yup.number, ABN_METHOD_NAME, parseABN);
Yup.addMethod(Yup.string, ACN_METHOD_NAME, parseACN);
Yup.addMethod(Yup.string, ARBN_METHOD_NAME, parseACN); // Same formula as ACN
Yup.addMethod(Yup.string, ARSN_METHOD_NAME, parseACN); // Same formula as ACN