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 @@