jws-frontend/src/utils/mrz.ts

234 lines
6.7 KiB
TypeScript
Raw Normal View History

2024-10-02 15:02:12 +07:00
import moment from 'moment';
2024-10-02 13:55:52 +07:00
type MRZ = {
type: 'TD1' | 'TD2' | 'TD3';
zone: string[];
};
type Field = {
field: string;
feat: menu request list (#75) * feat: i18n * feat: request list * refactor: hide stat transition on app.scss * feat: request list i18n * feat: request list => constants and main page * feat: add store * feat: add fetch data * feat: add utilities fn * feat: add store function / types * refactor: request list type * refactor: request list constants * refactor: quotation card => add customData and badge color props * feat: avatar group components * feat: request list group * refactor: request list => remove tab, add table data * feat: send search query * feat: add parameter * refactor: remove unused function * fix: rename component lits to list * feat: show stats from api * chore: cleanup * refactor: make it type safe * refactor: accept rotate flow id as parameter * feat: use page size component * feat: add component, data display & expansion product * feat: i18n * refactor: constants and request list table * refactor: type code, createdAt, updatedAt * refactor: utils function changThemeMode * feat: request list => view page * refactor: use type instead of infer from value * fix: function getEmployeeName att type * refactor: fetch work list * refactor: loop work list * feat: add i18n duty * feat: add form issue component * feat: add form issue section * fix: store error * refactor: edit by value * refactor: accept basic info from outside instead * feat: add status filter support on fetch * refactor: remove delete button * refactor: wording * feat/fix: request list i18n & constant * feat: document type * feat/refactor: request list => document expansion * refactor: doc expansion use FormGroupHead * refactor: fetch data based on id from route param * refactor: text area disable * feat: properties expansion display (mocking) * refactor: add document at product relation * refactor: edit get value product * feat: get workflow step to show on top * refactor: add type * refactor: add get attachment * refactor: add view attachment * refactor: edit file name * refactor: define props get hide icon * refactor: edit align row * refactor: by value table document * refactor: by value row table * feat: add independent ocr dialog * chore: clean up * refactor: accept more props and small adjustment * fix: error withDefault call * feat: accept default metadata when open * fix: typo * feat: add override hook when finish ocr * feat: reset state on open * feat: detect reader result is actually string * fix: variable name conflict * feat: properties to input component * feat: properties input in properties expansion * feat: properties expansion data (temporary) * refactor: add i18n status work * refactor: edit type work status and add step status * refactor: add edit status work * refactor: edit step work * refactor: properties data type * refactor: filter selected product & specific properties * feat: add emit event * refactor: change variable name for better understanding * refactor: hide step that no properties * refactor: work status type to validate * feat: work status color * refactor: key for filename * refactor: close expansion when change step * refactor: responsive meta data * refactor: product expansion responsive * fix: dark mode step text color * fix: document expansion table no data label * refactor: main page body bordered and overflow hidden * refactor: use utils function instead * refactor: add process * refactor: by value name * refactor: add upload file * refactor: upload file * refactor: by value * fix: option worker type * refactor: fetchRequestAttachment after edit * fix: metadata display * refactor: add class full-height * refactor: edit type * refactor: fetch file * refactor: by value visa * refactor: request list attributes type * fix: properties to input props (placeholder, readonly, disable) * feat: request list properties function * fix: error when no workflow * docs: update comment to fix indent * refactor: step type (attributes) * refactor: add attributes payload on editStatusRequestWork function * feat/refactor: functional form expansion/filter worklist * refactor: set attributes properties after submit * refactor: add request work ready status * feat: request list => form employee component * feat/refactor: form expansion select user/layout * fix: properties readonly --------- Co-authored-by: puriphatt <puriphat@frappet.com> Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
2024-11-22 18:02:03 +07:00
format?: (value: string, obj?: Record<string, string>) => string;
feat: menu request list (#75) * feat: i18n * feat: request list * refactor: hide stat transition on app.scss * feat: request list i18n * feat: request list => constants and main page * feat: add store * feat: add fetch data * feat: add utilities fn * feat: add store function / types * refactor: request list type * refactor: request list constants * refactor: quotation card => add customData and badge color props * feat: avatar group components * feat: request list group * refactor: request list => remove tab, add table data * feat: send search query * feat: add parameter * refactor: remove unused function * fix: rename component lits to list * feat: show stats from api * chore: cleanup * refactor: make it type safe * refactor: accept rotate flow id as parameter * feat: use page size component * feat: add component, data display & expansion product * feat: i18n * refactor: constants and request list table * refactor: type code, createdAt, updatedAt * refactor: utils function changThemeMode * feat: request list => view page * refactor: use type instead of infer from value * fix: function getEmployeeName att type * refactor: fetch work list * refactor: loop work list * feat: add i18n duty * feat: add form issue component * feat: add form issue section * fix: store error * refactor: edit by value * refactor: accept basic info from outside instead * feat: add status filter support on fetch * refactor: remove delete button * refactor: wording * feat/fix: request list i18n & constant * feat: document type * feat/refactor: request list => document expansion * refactor: doc expansion use FormGroupHead * refactor: fetch data based on id from route param * refactor: text area disable * feat: properties expansion display (mocking) * refactor: add document at product relation * refactor: edit get value product * feat: get workflow step to show on top * refactor: add type * refactor: add get attachment * refactor: add view attachment * refactor: edit file name * refactor: define props get hide icon * refactor: edit align row * refactor: by value table document * refactor: by value row table * feat: add independent ocr dialog * chore: clean up * refactor: accept more props and small adjustment * fix: error withDefault call * feat: accept default metadata when open * fix: typo * feat: add override hook when finish ocr * feat: reset state on open * feat: detect reader result is actually string * fix: variable name conflict * feat: properties to input component * feat: properties input in properties expansion * feat: properties expansion data (temporary) * refactor: add i18n status work * refactor: edit type work status and add step status * refactor: add edit status work * refactor: edit step work * refactor: properties data type * refactor: filter selected product & specific properties * feat: add emit event * refactor: change variable name for better understanding * refactor: hide step that no properties * refactor: work status type to validate * feat: work status color * refactor: key for filename * refactor: close expansion when change step * refactor: responsive meta data * refactor: product expansion responsive * fix: dark mode step text color * fix: document expansion table no data label * refactor: main page body bordered and overflow hidden * refactor: use utils function instead * refactor: add process * refactor: by value name * refactor: add upload file * refactor: upload file * refactor: by value * fix: option worker type * refactor: fetchRequestAttachment after edit * fix: metadata display * refactor: add class full-height * refactor: edit type * refactor: fetch file * refactor: by value visa * refactor: request list attributes type * fix: properties to input props (placeholder, readonly, disable) * feat: request list properties function * fix: error when no workflow * docs: update comment to fix indent * refactor: step type (attributes) * refactor: add attributes payload on editStatusRequestWork function * feat/refactor: functional form expansion/filter worklist * refactor: set attributes properties after submit * refactor: add request work ready status * feat: request list => form employee component * feat/refactor: form expansion select user/layout * fix: properties readonly --------- Co-authored-by: puriphatt <puriphat@frappet.com> Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
2024-11-22 18:02:03 +07:00
/**
* Post process value after format.
* Useful for extract one field to multiple fields .
*
* @example
* Convert fullname into firstname and lastname
*
* ```ts
* (value) => [
* { field: 'first_name', value: value.split(' ').at(0) || '' },
* { field: 'last_name', value: value.split(' ').slice(1).join(' ') },
* ]
* ```
*/
process?: (value: string) => { field: string; value: string }[];
};
feat: menu request list (#75) * feat: i18n * feat: request list * refactor: hide stat transition on app.scss * feat: request list i18n * feat: request list => constants and main page * feat: add store * feat: add fetch data * feat: add utilities fn * feat: add store function / types * refactor: request list type * refactor: request list constants * refactor: quotation card => add customData and badge color props * feat: avatar group components * feat: request list group * refactor: request list => remove tab, add table data * feat: send search query * feat: add parameter * refactor: remove unused function * fix: rename component lits to list * feat: show stats from api * chore: cleanup * refactor: make it type safe * refactor: accept rotate flow id as parameter * feat: use page size component * feat: add component, data display & expansion product * feat: i18n * refactor: constants and request list table * refactor: type code, createdAt, updatedAt * refactor: utils function changThemeMode * feat: request list => view page * refactor: use type instead of infer from value * fix: function getEmployeeName att type * refactor: fetch work list * refactor: loop work list * feat: add i18n duty * feat: add form issue component * feat: add form issue section * fix: store error * refactor: edit by value * refactor: accept basic info from outside instead * feat: add status filter support on fetch * refactor: remove delete button * refactor: wording * feat/fix: request list i18n & constant * feat: document type * feat/refactor: request list => document expansion * refactor: doc expansion use FormGroupHead * refactor: fetch data based on id from route param * refactor: text area disable * feat: properties expansion display (mocking) * refactor: add document at product relation * refactor: edit get value product * feat: get workflow step to show on top * refactor: add type * refactor: add get attachment * refactor: add view attachment * refactor: edit file name * refactor: define props get hide icon * refactor: edit align row * refactor: by value table document * refactor: by value row table * feat: add independent ocr dialog * chore: clean up * refactor: accept more props and small adjustment * fix: error withDefault call * feat: accept default metadata when open * fix: typo * feat: add override hook when finish ocr * feat: reset state on open * feat: detect reader result is actually string * fix: variable name conflict * feat: properties to input component * feat: properties input in properties expansion * feat: properties expansion data (temporary) * refactor: add i18n status work * refactor: edit type work status and add step status * refactor: add edit status work * refactor: edit step work * refactor: properties data type * refactor: filter selected product & specific properties * feat: add emit event * refactor: change variable name for better understanding * refactor: hide step that no properties * refactor: work status type to validate * feat: work status color * refactor: key for filename * refactor: close expansion when change step * refactor: responsive meta data * refactor: product expansion responsive * fix: dark mode step text color * fix: document expansion table no data label * refactor: main page body bordered and overflow hidden * refactor: use utils function instead * refactor: add process * refactor: by value name * refactor: add upload file * refactor: upload file * refactor: by value * fix: option worker type * refactor: fetchRequestAttachment after edit * fix: metadata display * refactor: add class full-height * refactor: edit type * refactor: fetch file * refactor: by value visa * refactor: request list attributes type * fix: properties to input props (placeholder, readonly, disable) * feat: request list properties function * fix: error when no workflow * docs: update comment to fix indent * refactor: step type (attributes) * refactor: add attributes payload on editStatusRequestWork function * feat/refactor: functional form expansion/filter worklist * refactor: set attributes properties after submit * refactor: add request work ready status * feat: request list => form employee component * feat/refactor: form expansion select user/layout * fix: properties readonly --------- Co-authored-by: puriphatt <puriphat@frappet.com> Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
2024-11-22 18:02:03 +07:00
type FieldList = Record<string, Field | Field[]>;
2024-10-02 15:46:22 +07:00
const DEFAULT_FIELD = {
documentType: { field: 'doc_type' },
documentNo: { field: 'doc_number' },
documentNoCheck: { field: 'doc_number_check' },
2024-10-02 15:02:12 +07:00
name: {
field: 'full_name',
format: (value, _) => value.replace(/0/, 'O'),
feat: menu request list (#75) * feat: i18n * feat: request list * refactor: hide stat transition on app.scss * feat: request list i18n * feat: request list => constants and main page * feat: add store * feat: add fetch data * feat: add utilities fn * feat: add store function / types * refactor: request list type * refactor: request list constants * refactor: quotation card => add customData and badge color props * feat: avatar group components * feat: request list group * refactor: request list => remove tab, add table data * feat: send search query * feat: add parameter * refactor: remove unused function * fix: rename component lits to list * feat: show stats from api * chore: cleanup * refactor: make it type safe * refactor: accept rotate flow id as parameter * feat: use page size component * feat: add component, data display & expansion product * feat: i18n * refactor: constants and request list table * refactor: type code, createdAt, updatedAt * refactor: utils function changThemeMode * feat: request list => view page * refactor: use type instead of infer from value * fix: function getEmployeeName att type * refactor: fetch work list * refactor: loop work list * feat: add i18n duty * feat: add form issue component * feat: add form issue section * fix: store error * refactor: edit by value * refactor: accept basic info from outside instead * feat: add status filter support on fetch * refactor: remove delete button * refactor: wording * feat/fix: request list i18n & constant * feat: document type * feat/refactor: request list => document expansion * refactor: doc expansion use FormGroupHead * refactor: fetch data based on id from route param * refactor: text area disable * feat: properties expansion display (mocking) * refactor: add document at product relation * refactor: edit get value product * feat: get workflow step to show on top * refactor: add type * refactor: add get attachment * refactor: add view attachment * refactor: edit file name * refactor: define props get hide icon * refactor: edit align row * refactor: by value table document * refactor: by value row table * feat: add independent ocr dialog * chore: clean up * refactor: accept more props and small adjustment * fix: error withDefault call * feat: accept default metadata when open * fix: typo * feat: add override hook when finish ocr * feat: reset state on open * feat: detect reader result is actually string * fix: variable name conflict * feat: properties to input component * feat: properties input in properties expansion * feat: properties expansion data (temporary) * refactor: add i18n status work * refactor: edit type work status and add step status * refactor: add edit status work * refactor: edit step work * refactor: properties data type * refactor: filter selected product & specific properties * feat: add emit event * refactor: change variable name for better understanding * refactor: hide step that no properties * refactor: work status type to validate * feat: work status color * refactor: key for filename * refactor: close expansion when change step * refactor: responsive meta data * refactor: product expansion responsive * fix: dark mode step text color * fix: document expansion table no data label * refactor: main page body bordered and overflow hidden * refactor: use utils function instead * refactor: add process * refactor: by value name * refactor: add upload file * refactor: upload file * refactor: by value * fix: option worker type * refactor: fetchRequestAttachment after edit * fix: metadata display * refactor: add class full-height * refactor: edit type * refactor: fetch file * refactor: by value visa * refactor: request list attributes type * fix: properties to input props (placeholder, readonly, disable) * feat: request list properties function * fix: error when no workflow * docs: update comment to fix indent * refactor: step type (attributes) * refactor: add attributes payload on editStatusRequestWork function * feat/refactor: functional form expansion/filter worklist * refactor: set attributes properties after submit * refactor: add request work ready status * feat: request list => form employee component * feat/refactor: form expansion select user/layout * fix: properties readonly --------- Co-authored-by: puriphatt <puriphat@frappet.com> Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
2024-11-22 18:02:03 +07:00
process: (value) => [
{ field: 'first_name', value: value.split(' ').at(0) || '' },
{ field: 'last_name', value: value.split(' ').slice(1).join(' ') },
],
2024-10-02 15:02:12 +07:00
},
country: {
field: 'country',
format: (value, _) => value.replace(/0/, 'O'),
2024-10-02 15:02:12 +07:00
},
2024-10-02 15:46:22 +07:00
nationality: {
2024-10-02 16:17:02 +07:00
field: 'nationality',
format: (value, _) => value.replace(/0/, 'O'),
2024-10-02 15:46:22 +07:00
},
2024-10-15 14:51:12 +07:00
gender: {
field: 'sex',
format: (value, _) => (value === 'M' ? 'male' : 'female'),
},
2024-10-02 15:02:12 +07:00
birthDate: {
field: 'birth_date',
format: (value, _) => moment(value, 'YYMMDD').format('YYYY-MM-DD'),
2024-10-02 15:02:12 +07:00
},
2024-10-02 15:46:22 +07:00
birthDateCheck: { field: 'birth_date_check' },
2024-10-02 15:02:12 +07:00
expireDate: {
2024-10-02 15:12:44 +07:00
field: 'expire_date',
format: (value, _) => moment(value, 'YYMMDD').format('YYYY-MM-DD'),
2024-10-02 15:02:12 +07:00
},
2024-10-02 15:46:22 +07:00
expireDateCheck: { field: 'expire_date_check' },
2024-10-02 16:52:57 +07:00
optionalData: { field: 'optional_data' },
2024-10-02 15:46:22 +07:00
optionalDataCheck: { field: 'optional_data_check' },
lineCheck: { field: 'line_check' },
} satisfies FieldList;
2024-10-02 15:02:12 +07:00
2024-10-02 13:55:52 +07:00
const MRZ_TD_1 = [
new RegExp(
[
2024-10-02 15:58:13 +07:00
`(?<${DEFAULT_FIELD.documentType.field}>[0-9A-Z<]{2})`,
2024-10-02 15:46:22 +07:00
`(?<${DEFAULT_FIELD.country.field}>[0-9A-Z<]{3})`,
`(?<${DEFAULT_FIELD.documentNo.field}>[0-9A-Z<]{9})`,
`(?<${DEFAULT_FIELD.documentNoCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.optionalData.field}>[0-9A-Z<]{15})`,
2024-10-02 13:55:52 +07:00
].join(''),
),
new RegExp(
[
2024-10-02 15:46:22 +07:00
`(?<${DEFAULT_FIELD.birthDate.field}>[0-9A-Z<]{6})`,
`(?<${DEFAULT_FIELD.birthDateCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.gender.field}>[mfMF<]{1})`,
`(?<${DEFAULT_FIELD.expireDate.field}>[0-9A-Z<]{6})`,
`(?<${DEFAULT_FIELD.expireDateCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.nationality.field}>[0-9A-Z<]{3})`,
`(?<${DEFAULT_FIELD.optionalData.field}>[A-Z0-9<]{11})`,
`(?<${DEFAULT_FIELD.lineCheck.field}>[0-9A-Z<]{1})`,
2024-10-02 13:55:52 +07:00
].join(''),
),
2024-10-02 15:46:22 +07:00
new RegExp([`(?<${DEFAULT_FIELD.name.field}>[A-Z<]{30})`].join('')),
2024-10-02 13:55:52 +07:00
];
const MRZ_TD_2 = [
new RegExp(
[
2024-10-02 15:58:13 +07:00
`(?<${DEFAULT_FIELD.documentType.field}>[0-9A-Z<]{2})`,
2024-10-02 15:46:22 +07:00
`(?<${DEFAULT_FIELD.country.field}>[0-9A-Z<]{3})`,
`(?<${DEFAULT_FIELD.name.field}>[A-Z<]{31})`,
2024-10-02 13:55:52 +07:00
].join(''),
),
new RegExp(
[
2024-10-02 15:46:22 +07:00
`(?<${DEFAULT_FIELD.documentNo.field}>[0-9A-Z<]{9})`,
`(?<${DEFAULT_FIELD.documentNoCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.nationality.field}>[0-9A-Z<]{3})`,
`(?<${DEFAULT_FIELD.birthDate.field}>[0-9A-Z<]{6})`,
`(?<${DEFAULT_FIELD.birthDateCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.gender.field}>[mfMF]{1})`,
`(?<${DEFAULT_FIELD.expireDate.field}>[0-9A-Z<]{6})`,
`(?<${DEFAULT_FIELD.expireDateCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.optionalData.field}>[A-Z0-9<]{7})`,
`(?<${DEFAULT_FIELD.lineCheck.field}>[0-9A-Z<]{1})`,
2024-10-02 13:55:52 +07:00
].join(''),
),
];
const MRZ_TD_3 = [
new RegExp(
[
2024-10-02 15:58:13 +07:00
`(?<${DEFAULT_FIELD.documentType.field}>[A-Z0-9<]{2})`,
2024-10-02 15:46:22 +07:00
`(?<${DEFAULT_FIELD.country.field}>[0-9A-Z<]{3})`,
`(?<${DEFAULT_FIELD.name.field}>[A-Z0-9<]{39})`,
2024-10-02 13:55:52 +07:00
].join(''),
),
new RegExp(
[
2024-10-02 15:46:22 +07:00
`(?<${DEFAULT_FIELD.documentNo.field}>[0-9A-Z<]{9})`,
`(?<${DEFAULT_FIELD.documentNoCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.nationality.field}>[0-9A-Z<]{3})`,
`(?<${DEFAULT_FIELD.birthDate.field}>[0-9A-Z<]{6})`,
`(?<${DEFAULT_FIELD.birthDateCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.gender.field}>[mfMF<]{1})`,
`(?<${DEFAULT_FIELD.expireDate.field}>[0-9A-Z<]{6})`,
`(?<${DEFAULT_FIELD.expireDateCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.optionalData.field}>[A-Z0-9<]{14})`,
`(?<${DEFAULT_FIELD.optionalDataCheck.field}>[0-9A-Z<]{1})`,
`(?<${DEFAULT_FIELD.lineCheck.field}>[0-9A-Z<]{1})`,
2024-10-02 13:55:52 +07:00
].join(''),
),
];
function mrzCleanResult(obj: Record<string, string>) {
Object.entries(obj).forEach(([k, v]) => {
obj[k] = v
.replace(/</g, ' ')
.replace(/\s{2,}/, ' ')
.trim();
});
2024-10-02 15:02:12 +07:00
2024-10-02 15:59:25 +07:00
const original = structuredClone(obj);
2024-10-02 15:46:22 +07:00
for (const value of Object.values(DEFAULT_FIELD)) {
feat: menu request list (#75) * feat: i18n * feat: request list * refactor: hide stat transition on app.scss * feat: request list i18n * feat: request list => constants and main page * feat: add store * feat: add fetch data * feat: add utilities fn * feat: add store function / types * refactor: request list type * refactor: request list constants * refactor: quotation card => add customData and badge color props * feat: avatar group components * feat: request list group * refactor: request list => remove tab, add table data * feat: send search query * feat: add parameter * refactor: remove unused function * fix: rename component lits to list * feat: show stats from api * chore: cleanup * refactor: make it type safe * refactor: accept rotate flow id as parameter * feat: use page size component * feat: add component, data display & expansion product * feat: i18n * refactor: constants and request list table * refactor: type code, createdAt, updatedAt * refactor: utils function changThemeMode * feat: request list => view page * refactor: use type instead of infer from value * fix: function getEmployeeName att type * refactor: fetch work list * refactor: loop work list * feat: add i18n duty * feat: add form issue component * feat: add form issue section * fix: store error * refactor: edit by value * refactor: accept basic info from outside instead * feat: add status filter support on fetch * refactor: remove delete button * refactor: wording * feat/fix: request list i18n & constant * feat: document type * feat/refactor: request list => document expansion * refactor: doc expansion use FormGroupHead * refactor: fetch data based on id from route param * refactor: text area disable * feat: properties expansion display (mocking) * refactor: add document at product relation * refactor: edit get value product * feat: get workflow step to show on top * refactor: add type * refactor: add get attachment * refactor: add view attachment * refactor: edit file name * refactor: define props get hide icon * refactor: edit align row * refactor: by value table document * refactor: by value row table * feat: add independent ocr dialog * chore: clean up * refactor: accept more props and small adjustment * fix: error withDefault call * feat: accept default metadata when open * fix: typo * feat: add override hook when finish ocr * feat: reset state on open * feat: detect reader result is actually string * fix: variable name conflict * feat: properties to input component * feat: properties input in properties expansion * feat: properties expansion data (temporary) * refactor: add i18n status work * refactor: edit type work status and add step status * refactor: add edit status work * refactor: edit step work * refactor: properties data type * refactor: filter selected product & specific properties * feat: add emit event * refactor: change variable name for better understanding * refactor: hide step that no properties * refactor: work status type to validate * feat: work status color * refactor: key for filename * refactor: close expansion when change step * refactor: responsive meta data * refactor: product expansion responsive * fix: dark mode step text color * fix: document expansion table no data label * refactor: main page body bordered and overflow hidden * refactor: use utils function instead * refactor: add process * refactor: by value name * refactor: add upload file * refactor: upload file * refactor: by value * fix: option worker type * refactor: fetchRequestAttachment after edit * fix: metadata display * refactor: add class full-height * refactor: edit type * refactor: fetch file * refactor: by value visa * refactor: request list attributes type * fix: properties to input props (placeholder, readonly, disable) * feat: request list properties function * fix: error when no workflow * docs: update comment to fix indent * refactor: step type (attributes) * refactor: add attributes payload on editStatusRequestWork function * feat/refactor: functional form expansion/filter worklist * refactor: set attributes properties after submit * refactor: add request work ready status * feat: request list => form employee component * feat/refactor: form expansion select user/layout * fix: properties readonly --------- Co-authored-by: puriphatt <puriphat@frappet.com> Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
2024-11-22 18:02:03 +07:00
if (obj[value.field]) {
if ('format' in value) {
obj[value.field] = value.format(obj[value.field], original);
}
if ('process' in value) {
value.process(obj[value.field]).forEach((result) => {
obj[result.field] = result.value;
});
delete obj[value.field];
continue;
}
2024-10-02 15:46:22 +07:00
}
2024-10-02 15:02:12 +07:00
}
2024-10-02 13:55:52 +07:00
return obj;
}
2024-10-02 16:50:51 +07:00
function mrzFieldExtract(expression: RegExp, line: string) {
if (expression.test(line)) {
return expression.exec(line)?.groups || {};
}
return {};
}
export function checkSum(data: string) {
2024-10-02 16:25:52 +07:00
if (!/[0-9A-Z<]/.test(data)) return null;
2024-10-02 15:02:12 +07:00
const sum = data.split('').reduce((a, v, i) => {
2024-10-02 16:25:52 +07:00
if (v === '<') return a;
2024-10-02 15:02:12 +07:00
const num = Number(v);
const weight = [7, 3, 1][i % 3];
if (Number.isNaN(num)) {
return a + (v.charCodeAt(0) - 55) * weight;
}
return a + num * weight;
}, 0);
return sum % 10;
2024-10-02 15:02:12 +07:00
}
2024-10-02 13:55:52 +07:00
export function parseType1(mrz: MRZ) {
const result: Record<string, string> = {};
2024-10-02 16:50:51 +07:00
mrz.zone.forEach((line, i) =>
Object.assign(result, mrzFieldExtract(MRZ_TD_1[i], line)),
);
2024-10-02 13:55:52 +07:00
return { mrz, result: mrzCleanResult(result) };
}
export function parseType2(mrz: MRZ) {
const result: Record<string, string> = {};
2024-10-02 16:50:51 +07:00
mrz.zone.forEach((line, i) =>
Object.assign(result, mrzFieldExtract(MRZ_TD_2[i], line)),
);
2024-10-02 13:55:52 +07:00
return { mrz, result: mrzCleanResult(result) };
}
export function parseType3(mrz: MRZ) {
const result: Record<string, string> = {};
2024-10-02 16:50:51 +07:00
mrz.zone.forEach((line, i) =>
Object.assign(result, mrzFieldExtract(MRZ_TD_3[i], line)),
);
2024-10-02 13:55:52 +07:00
return { mrz, result: mrzCleanResult(result) };
}
export function parseMRZ(mrz: MRZ) {
if (mrz.type === 'TD1') return parseType1(mrz);
if (mrz.type === 'TD2') return parseType2(mrz);
if (mrz.type === 'TD3') return parseType3(mrz);
return null;
}