From 1370881eee9995699bffd5a577fc36a754a312d1 Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Sat, 4 Feb 2023 23:04:15 +0100 Subject: [PATCH] feat: autofill birthdate and sex from CZ personalIdNumber --- frontend/src/lib/utils/personalIdFormat.ts | 17 +-- frontend/src/lib/utils/toast.ts | 12 ++- .../(authenticated)/register/+page.svelte | 100 ++++++------------ frontend/src/translations/cs/index.ts | 4 +- 4 files changed, 56 insertions(+), 77 deletions(-) diff --git a/frontend/src/lib/utils/personalIdFormat.ts b/frontend/src/lib/utils/personalIdFormat.ts index bfd3cdf..91f5f6e 100644 --- a/frontend/src/lib/utils/personalIdFormat.ts +++ b/frontend/src/lib/utils/personalIdFormat.ts @@ -48,25 +48,26 @@ export const isPersonalIdNumberWithBirthdateValid = ( } }; -export const deriveBirthdateFromPersonalId = ( +export const parseBirthdateSexFromPersonalId = ( personalIdNumber: string -): [birthdate: string, sex: 'MUŽ' | 'ŽENA'] => { - const year = Number(personalIdNumber.slice(0, 2)); +): [birthdate: string, sex: 'Muž' | 'Žena'] => { + const yearPadded = Number(personalIdNumber.slice(0, 2)); + const year = yearPadded < 24 ? yearPadded + 2000 : yearPadded + 1900; const idMonth = Number(personalIdNumber.slice(2, 4)); let month; - let sex: 'MUŽ' | 'ŽENA'; + let sex: 'Muž' | 'Žena'; if (idMonth > 12 && idMonth <= 32) { month = idMonth - 20; - sex = 'MUŽ'; + sex = 'Muž'; } else if (idMonth > 50 && idMonth <= 52) { month = idMonth - 50; - sex = 'ŽENA'; + sex = 'Žena'; } else if (idMonth > 70 && idMonth <= 82) { month = idMonth - 70; - sex = 'ŽENA'; + sex = 'Žena'; } else { month = idMonth; - sex = 'MUŽ'; + sex = 'Muž'; } const day = Number(personalIdNumber.slice(4, 6)); diff --git a/frontend/src/lib/utils/toast.ts b/frontend/src/lib/utils/toast.ts index 096af11..dba4777 100644 --- a/frontend/src/lib/utils/toast.ts +++ b/frontend/src/lib/utils/toast.ts @@ -8,4 +8,14 @@ export const pushErrorText = (text: string) => { '--toastBarBackground': '#7f1d1d' } }); -}; \ No newline at end of file +}; + +export const pushSuccessText = (text: string) => { + toast.push(text, { + theme: { + '--toastColor': 'mintcream', + '--toastBackground': '#047857', + '--toastBarBackground': '#064e3b' + } + }); +} \ No newline at end of file diff --git a/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte b/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte index 5e9e96e..e30ba5c 100644 --- a/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte +++ b/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte @@ -23,11 +23,14 @@ import GradesTable from '$lib/components/grades/GradesTable.svelte'; import SchoolSelect from '$lib/components/select/SchoolSelect/SchoolSelect.svelte'; import PersonalIdConfirmCheckBox from '$lib/components/checkbox/PersonalIdConfirmCheckBox.svelte'; - import { isPersonalIdNumberWithBirthdateValid } from '$lib/utils/personalIdFormat'; + import { + parseBirthdateSexFromPersonalId, + isPersonalIdNumberWithBirthdateValid + } from '$lib/utils/personalIdFormat'; import PersonalIdErrorModal from '$lib/components/modal/PersonalIdErrorModal.svelte'; import LinkErrorModal from '$lib/components/modal/LinkErrorModal.svelte'; import type { Writable } from 'svelte/store'; - import { pushErrorText } from '$lib/utils/toast'; + import { pushErrorText, pushSuccessText } from '$lib/utils/toast'; import schoolList from '$lib/assets/list/school.json'; import countriesList from '$lib/assets/list/countries.json'; @@ -73,7 +76,7 @@ city: '', zip: '', citizenship: '', - personalIdNumber: '', + personalIdNumber: 'TODO: remove this', schoolName: '', healthInsurance: '', grades: [], @@ -132,7 +135,7 @@ city: yup.string().required(), zip: yup.string().required(), citizenship: yup.string().required(), - personalIdNumber: yup.string().required(), + personalIdNumber: yup.string(), schoolName: yup.string().required(), healthInsurance: yup.number().required(), grades: yup @@ -243,25 +246,6 @@ personalIdModal: false, linkErrorModal: false }; - const validatePersonalId = () => { - if ($form.candidate.citizenship === 'Česká republika') { - if ( - !isPersonalIdNumberWithBirthdateValid( - $form.candidate.personalIdNumber, - $form.candidate.birthdate - ) - ) { - toast.push('Rodné číslo neodpovídá oficiální specifikaci či datumu narození', { - theme: { - '--toastColor': 'mintcream', - '--toastBackground': '#b91c1c', - '--toastBarBackground': '#7f1d1d' - } - }); - throw new Error('Rodné číslo neodpovídá datumu narození'); - } - } - }; const onSubmit = async (values: CandidateData) => { if (pageIndex === pageCount) { @@ -359,7 +343,7 @@ $typedErrors['candidate']['healthInsurance'] || $typedErrors['candidate']['birthdate'] || $typedErrors['candidate']['birthplace'] || - $typedErrors['candidate']['personalIdNumber'] || + $typedErrors['candidate']['birthSurname'] || $typedErrors['candidate']['testLanguage'] ) { return true; @@ -409,11 +393,19 @@ return '+' + telephone.match(/[0-9]{1,3}/g)!.join(' '); }; - // TODO - /* $form.candidate.personalIdNumber = data.whoami.personalIdNumber; - const [birthdate, sex] = deriveBirthdateFromPersonalId(data.whoami.personalIdNumber); - $form.candidate.birthdate = birthdate; - $form.candidate.sex = sex; */ + $: if ($form.candidate.citizenship === 'Česká republika') { + if ($form.candidate.birthdate === '' && $form.candidate.sex === '') { + let [birthdate, sex] = parseBirthdateSexFromPersonalId(data.whoami.personalIdNumber); + $form.candidate.birthdate = birthdate; + $form.candidate.sex = sex; + pushSuccessText( + `Datum narození a pohlaví bylo vyplněno automaticky podle Vašeho rodného čísla (${data.whoami.personalIdNumber}).` + ); + } + } else { + $form.candidate.birthdate = ''; + $form.candidate.sex = ''; + } if (details !== undefined) { details.candidate.birthdate = details.candidate.birthdate.split('-').reverse().join('.'); @@ -525,24 +517,14 @@

-
- - - - - - -
+ + +
- {#if $form.candidate.citizenship === 'Česká republika' || !$form.candidate.citizenship} - - {:else} - - {/if} +
{ - if (pageIndex === 4) { - validatePersonalId(); - } await handleSubmit(e); if (isPageInvalid(pageIndex)) return; if (pageIndex !== pageCount) { @@ -826,9 +797,6 @@