hl-core 0.0.10-beta.81 → 0.0.10-beta.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/base.api.ts +8 -0
- package/components/Dialog/Dialog.vue +33 -0
- package/components/Form/FormTextSection.vue +2 -2
- package/components/Layout/Header.vue +31 -1
- package/components/Menu/MenuHover.vue +2 -2
- package/components/Pages/Anketa.vue +92 -21
- package/components/Pages/ContragentForm.vue +1 -1
- package/components/Pages/Documents.vue +37 -14
- package/components/Pages/MemberForm.vue +44 -13
- package/components/Pages/ProductConditions.vue +45 -5
- package/composables/classes.ts +662 -1108
- package/composables/index.ts +64 -38
- package/layouts/default.vue +1 -1
- package/nuxt.config.ts +19 -2
- package/package.json +6 -14
- package/store/form.store.ts +2 -2
- package/store/legalEntity.store.ts +4 -5
- package/store/member.store.ts +3 -1
- package/types/enum.ts +1 -0
- package/types/index.ts +14 -1
package/api/base.api.ts
CHANGED
|
@@ -1227,6 +1227,14 @@ export class ApiClass {
|
|
|
1227
1227
|
params: { processInstanceId },
|
|
1228
1228
|
});
|
|
1229
1229
|
},
|
|
1230
|
+
checkContractDsPension: async (processInstanceId: string | number) => {
|
|
1231
|
+
return await this.axiosCall<Types.CheckContractDsPensionResponse>({
|
|
1232
|
+
method: Methods.GET,
|
|
1233
|
+
baseURL: getStrValuePerEnv('efoBaseApi'),
|
|
1234
|
+
url: `${this.pensionannuityNew.base}/SetContractDsPensionAsync`,
|
|
1235
|
+
params: { processInstanceId },
|
|
1236
|
+
});
|
|
1237
|
+
},
|
|
1230
1238
|
};
|
|
1231
1239
|
|
|
1232
1240
|
externalServices = {
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-dialog class="base-dialog" :model-value="Boolean(modelValue)" @update:modelValue="$emit('update:modelValue', $event)" :persistent="persistent">
|
|
3
3
|
<v-card class="self-center w-full sm:w-4/4 md:w-2/3 lg:w-[35%] xl:w-[500px] rounded-lg !px-[15px] !py-[30px] sm:!p-[36px]" :class="innerClass">
|
|
4
|
+
<v-btn
|
|
5
|
+
v-if="showCloseButton"
|
|
6
|
+
icon="mdi-close"
|
|
7
|
+
variant="text"
|
|
8
|
+
rounded="0"
|
|
9
|
+
:size="smAndDown ? 'small' : 'default'"
|
|
10
|
+
:ripple="false"
|
|
11
|
+
class="no-hover position-absolute right-0 top-0"
|
|
12
|
+
@click="$emit('update:modelValue', false)"
|
|
13
|
+
/>
|
|
4
14
|
<div class="flex sm:flex-row flex-col place-items-center sm:place-items-start">
|
|
5
15
|
<div class="h-20 w-20 place-items-start pt-1">
|
|
6
16
|
<div class="bg-[#F7F7F7] h-24 w-24 sm:h-16 sm:w-16 rounded grid place-items-center invisible sm:visible">
|
|
@@ -79,8 +89,23 @@ export default defineComponent({
|
|
|
79
89
|
type: String,
|
|
80
90
|
default: '',
|
|
81
91
|
},
|
|
92
|
+
showCloseButton: {
|
|
93
|
+
type: Boolean,
|
|
94
|
+
default: false,
|
|
95
|
+
},
|
|
82
96
|
},
|
|
83
97
|
emits: ['update:modelValue', 'yes', 'no'],
|
|
98
|
+
setup() {
|
|
99
|
+
const display = useDisplayInfo();
|
|
100
|
+
|
|
101
|
+
const smAndDown = computed(() => {
|
|
102
|
+
return display.smAndDown.value;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
smAndDown,
|
|
107
|
+
};
|
|
108
|
+
},
|
|
84
109
|
});
|
|
85
110
|
</script>
|
|
86
111
|
<style>
|
|
@@ -90,6 +115,14 @@ export default defineComponent({
|
|
|
90
115
|
.base-dialog .v-card-subtitle {
|
|
91
116
|
font-size: 14px;
|
|
92
117
|
}
|
|
118
|
+
|
|
119
|
+
.no-hover:hover {
|
|
120
|
+
background: transparent !important;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.no-hover .v-btn__overlay {
|
|
124
|
+
opacity: 0 !important;
|
|
125
|
+
}
|
|
93
126
|
@media (max-width: 640px) {
|
|
94
127
|
.base-dialog .v-card-title {
|
|
95
128
|
margin-top: 10px;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="flex flex-col justify-between rounded-lg transition-all" :class="[$styles.whiteBg]">
|
|
3
|
-
<span v-if="title" class="p-4" :class="[titleClass ?? $styles.textTitle]">{{ title }}</span>
|
|
4
|
-
<span v-if="subtitle" class="p-4 text-[#99A3B3] border-t-[1px]" :class="[subtitleClass ?? $styles.textSimple]">{{ subtitle }}</span>
|
|
3
|
+
<span v-if="title" class="p-4 text-section-label" :class="[titleClass ?? $styles.textTitle]">{{ title }}</span>
|
|
4
|
+
<span v-if="subtitle" class="p-4 text-[#99A3B3] border-t-[1px] text-section-label" :class="[subtitleClass ?? $styles.textSimple]">{{ subtitle }}</span>
|
|
5
5
|
<slot></slot>
|
|
6
6
|
</div>
|
|
7
7
|
</template>
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<header class="relative w-full min-h-[70px] text-center font-medium align-middle flex items-center border-b-[1px]" :class="[$styles.blueBgLight, $styles.textSimple]">
|
|
3
3
|
<i v-if="hasBack" @click="$emit('onBack')" class="absolute left-5 mdi text-xl cursor-pointer transition-all" :class="[backIcon, backIconAnim]"></i>
|
|
4
|
-
<span class="mx-10">
|
|
4
|
+
<span class="mx-10">
|
|
5
|
+
<v-tooltip v-if="hasMore" :text="$dataStore.isSupport() ? `Нажатий: ${homeClickCount}` : ''" :disabled="!$dataStore.isSupport()">
|
|
6
|
+
<template #activator="{ props: tooltipProps }">
|
|
7
|
+
<v-btn v-bind="tooltipProps" variant="text" size="32" :ripple="false" class="absolute z-10" @click="onHomeClick" @mouseenter="onHomeHover">
|
|
8
|
+
<img src="../../../efo/public/favicon.svg" class="w-6 h-6" alt="home" />
|
|
9
|
+
</v-btn>
|
|
10
|
+
</template>
|
|
11
|
+
</v-tooltip>
|
|
12
|
+
{{ title }}
|
|
13
|
+
</span>
|
|
5
14
|
<i
|
|
6
15
|
v-if="hasInfo && infoItems && infoItems.length && infoItems.filter(i => (typeof i.show === 'boolean' ? i.show : true)).length"
|
|
7
16
|
class="mdi text-xl cursor-pointer transition-all opacity-70"
|
|
@@ -65,6 +74,22 @@ export default defineComponent({
|
|
|
65
74
|
setup(props) {
|
|
66
75
|
const dataStore = useDataStore();
|
|
67
76
|
|
|
77
|
+
const homeClickCount = ref(0);
|
|
78
|
+
const COUNTER_URL = `${import.meta.env.VITE_COUNTER_URL ?? 'http://localhost:3001'}/counter`;
|
|
79
|
+
|
|
80
|
+
const onHomeClick = async () => {
|
|
81
|
+
// umTrackEvent('click-logo', {
|
|
82
|
+
// user: dataStore.user.fullName,
|
|
83
|
+
// branch: dataStore.user.branchCode,
|
|
84
|
+
// });
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const onHomeHover = async () => {
|
|
88
|
+
if (!dataStore.isSupport()) return;
|
|
89
|
+
try {
|
|
90
|
+
} catch {}
|
|
91
|
+
};
|
|
92
|
+
|
|
68
93
|
const onClickOutside = () => {
|
|
69
94
|
dataStore.settings.open = false;
|
|
70
95
|
};
|
|
@@ -97,7 +122,12 @@ export default defineComponent({
|
|
|
97
122
|
backIconAnim,
|
|
98
123
|
moreIconAnim,
|
|
99
124
|
|
|
125
|
+
// Counter
|
|
126
|
+
homeClickCount,
|
|
127
|
+
|
|
100
128
|
// Functions
|
|
129
|
+
onHomeClick,
|
|
130
|
+
onHomeHover,
|
|
101
131
|
onClickOutside,
|
|
102
132
|
};
|
|
103
133
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-menu v-if="items.length" :activator="activator" location="bottom center" :offset="top" transition="scale-transition">
|
|
3
3
|
<base-form-text-section class="p-4 border-[1px] flex flex-col gap-3 elevation-3 w-[250px]">
|
|
4
|
-
<div v-for="item of items.filter(i => $dataStore.filters.show(i))" :key="item.id">
|
|
5
|
-
<base-menu-nav-item :class="[$styles.textSimple]" :menu-item="item" @click="$emit(item.id)" />
|
|
4
|
+
<div v-for="item of items.filter(i => $dataStore.filters.show(i))" :key="(item as any).id">
|
|
5
|
+
<base-menu-nav-item :class="[$styles.textSimple]" :menu-item="item" @click="$emit((item as any).id)" />
|
|
6
6
|
</div>
|
|
7
7
|
</base-form-text-section>
|
|
8
8
|
</v-menu>
|
|
@@ -18,15 +18,25 @@
|
|
|
18
18
|
:class="[$styles.blueBgLight, $styles.rounded]"
|
|
19
19
|
class="mx-[10px] p-4 flex flex-col gap-4"
|
|
20
20
|
>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
<div v-for="(question, index) in firstQuestionList.filter(i => i.first.definedAnswers === 'N')" :key="index">
|
|
22
|
+
<base-form-input
|
|
23
|
+
v-if="question.first.answerType === 'N'"
|
|
24
|
+
v-model="question.first.answerText"
|
|
25
|
+
:label="getQuestionLabel(question)"
|
|
26
|
+
:maska="$maska.threeDigit"
|
|
27
|
+
:readonly="formStore.isDisabled[whichSurvey] || !$dataStore.isTask()"
|
|
28
|
+
:rules="$rules.required"
|
|
29
|
+
/>
|
|
30
|
+
<base-form-input
|
|
31
|
+
v-if="question.first.answerType === 'T'"
|
|
32
|
+
v-model="question.first.answerText"
|
|
33
|
+
:label="getQuestionLabel(question)"
|
|
34
|
+
:readonly="formStore.isDisabled[whichSurvey] || !$dataStore.isTask()"
|
|
35
|
+
:rules="$rules.required"
|
|
36
|
+
@input="question.first.answerText = formatPressure($event)"
|
|
37
|
+
placeholder="###/##"
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
30
40
|
</section>
|
|
31
41
|
<section
|
|
32
42
|
v-if="surveyType === 'critical' && ($appContextStore.isBaiterek || $appContextStore.isMycar || $appContextStore.isBolashak || $appContextStore.isLiferenta)"
|
|
@@ -170,7 +180,7 @@
|
|
|
170
180
|
ref="vSecondaryForm"
|
|
171
181
|
@submit="submitSecondaryForm"
|
|
172
182
|
>
|
|
173
|
-
<base-form-text-section v-for="question in currentQuestion.second" :title="question.name" :key="question.name">
|
|
183
|
+
<base-form-text-section class="text-section" v-for="question in currentQuestion.second" :title="question.name" :key="question.name">
|
|
174
184
|
<div v-if="question.definedAnswers === 'N'">
|
|
175
185
|
<base-form-input
|
|
176
186
|
v-if="question.answerType === 'T' || question.answerType === 'N'"
|
|
@@ -311,6 +321,53 @@ export default defineComponent({
|
|
|
311
321
|
const firstQuestions = computed(() =>
|
|
312
322
|
filterType.value !== null ? firstQuestionList.value.filter(i => i.first.answerName?.includes(filterType.value === 'Иә/Да' ? 'Да' : 'Нет')) : firstQuestionList.value,
|
|
313
323
|
);
|
|
324
|
+
|
|
325
|
+
function formatPressure(event: any) {
|
|
326
|
+
const raw = event.target.value;
|
|
327
|
+
const isDeleting = event.inputType?.startsWith('delete');
|
|
328
|
+
|
|
329
|
+
let cleaned = raw.replace(/[^\d/]/g, '');
|
|
330
|
+
|
|
331
|
+
if ((cleaned.match(/\//g) || []).length > 1) {
|
|
332
|
+
const idx = cleaned.indexOf('/');
|
|
333
|
+
const noSlash = cleaned.replace(/\//g, '');
|
|
334
|
+
cleaned = noSlash.slice(0, idx) + '/' + noSlash.slice(idx);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const hasSlash = cleaned.includes('/');
|
|
338
|
+
|
|
339
|
+
if (hasSlash) {
|
|
340
|
+
const slashIdx = cleaned.indexOf('/');
|
|
341
|
+
const left = cleaned.slice(0, slashIdx);
|
|
342
|
+
const right = cleaned.slice(slashIdx + 1);
|
|
343
|
+
|
|
344
|
+
const leftPart = left.slice(0, 3);
|
|
345
|
+
|
|
346
|
+
if (leftPart.length < 2) {
|
|
347
|
+
return leftPart;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const maxRight = leftPart.length === 2 ? 2 : 3;
|
|
351
|
+
const rightPart = right.slice(0, maxRight);
|
|
352
|
+
|
|
353
|
+
return `${leftPart}/${rightPart}`;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (cleaned.length > 3 && !isDeleting) {
|
|
357
|
+
const leftPart = cleaned.slice(0, 3);
|
|
358
|
+
const rightPart = cleaned.slice(3, 6);
|
|
359
|
+
return `${leftPart}/${rightPart}`;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const digits = cleaned.slice(0, 3);
|
|
363
|
+
|
|
364
|
+
if (digits.length === 3 && !isDeleting) {
|
|
365
|
+
return `${digits}/`;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return digits;
|
|
369
|
+
}
|
|
370
|
+
|
|
314
371
|
const scrollForm = (direction: 'up' | 'down') => {
|
|
315
372
|
const scrollObject = { top: direction === 'up' ? 0 : screen.height * 10, behavior: 'smooth' };
|
|
316
373
|
if (firstPanel.value) {
|
|
@@ -320,6 +377,13 @@ export default defineComponent({
|
|
|
320
377
|
}
|
|
321
378
|
};
|
|
322
379
|
|
|
380
|
+
const getQuestionLabel = (question: AnketaBody) => {
|
|
381
|
+
if (question.first.unitOfMeasurement) {
|
|
382
|
+
return `${question.first.name} (${question.first.unitOfMeasurement})`;
|
|
383
|
+
}
|
|
384
|
+
return question.first.name;
|
|
385
|
+
};
|
|
386
|
+
|
|
323
387
|
const submitForm = async () => {
|
|
324
388
|
await vForm.value.validate().then(async (v: { valid: Boolean; errors: any }) => {
|
|
325
389
|
if (v.valid) {
|
|
@@ -399,18 +463,23 @@ export default defineComponent({
|
|
|
399
463
|
firstPanel.value = false;
|
|
400
464
|
secondPanel.value = false;
|
|
401
465
|
} else {
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
showToaster('error', appContextStore.t('toaster.errorFormField', { text: errorText?.replace(/[-<>!//.]/g, '') }));
|
|
407
|
-
}
|
|
408
|
-
errors.scrollIntoView({
|
|
409
|
-
behavior: 'smooth',
|
|
410
|
-
block: 'center',
|
|
411
|
-
inline: 'nearest',
|
|
412
|
-
});
|
|
466
|
+
const errorElement = document.querySelector<HTMLElement>('.v-input--error');
|
|
467
|
+
|
|
468
|
+
if (!errorElement) {
|
|
469
|
+
return;
|
|
413
470
|
}
|
|
471
|
+
|
|
472
|
+
const section = errorElement.closest<HTMLElement>('.text-section');
|
|
473
|
+
const label = section?.querySelector<HTMLElement>('.text-section-label');
|
|
474
|
+
const errorText = label?.textContent?.replace(/[-<>!/.]/g, '');
|
|
475
|
+
|
|
476
|
+
showToaster('error', errorText ? appContextStore.t('toaster.errorFormField', { text: errorText }) : 'Заполните все необходимые поля');
|
|
477
|
+
|
|
478
|
+
errorElement.scrollIntoView({
|
|
479
|
+
behavior: 'smooth',
|
|
480
|
+
block: 'center',
|
|
481
|
+
inline: 'nearest',
|
|
482
|
+
});
|
|
414
483
|
}
|
|
415
484
|
});
|
|
416
485
|
};
|
|
@@ -564,6 +633,8 @@ export default defineComponent({
|
|
|
564
633
|
openFirstPanel,
|
|
565
634
|
openSecondPanel,
|
|
566
635
|
closeSecondPanel,
|
|
636
|
+
getQuestionLabel,
|
|
637
|
+
formatPressure,
|
|
567
638
|
};
|
|
568
639
|
},
|
|
569
640
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section v-show="showForm" class="flex flex-col gap-4 px-[10px]">
|
|
3
|
-
<v-form v-if="member" ref="vForm" @submit="submitForm"
|
|
3
|
+
<v-form v-if="member" ref="vForm" @submit="submitForm">
|
|
4
4
|
<base-form-section :title="$appContextStore.t('form.personalData')" class="mt-[14px]">
|
|
5
5
|
<base-form-input
|
|
6
6
|
v-model="member.phoneNumber"
|
|
@@ -118,19 +118,27 @@
|
|
|
118
118
|
<base-form-input v-model="formStore.contractDate" :label="$appContextStore.t('form.date')" :readonly="true" append-inner-icon="mdi mdi-calendar-blank-outline" />
|
|
119
119
|
<base-file-input :readonly="isDisabled" @input.prevent="onFileChange($event)" />
|
|
120
120
|
</base-content-block>
|
|
121
|
-
<
|
|
122
|
-
<
|
|
123
|
-
{{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
class="
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
121
|
+
<template v-for="group of documentListGrouped" :key="group.name">
|
|
122
|
+
<base-content-block :class="[$styles.textSimple]">
|
|
123
|
+
<h5 class="text-center font-medium mb-4">{{ group.name }}</h5>
|
|
124
|
+
<div
|
|
125
|
+
v-for="document of group.items"
|
|
126
|
+
:key="document.id"
|
|
127
|
+
:class="[$styles.whiteBg, $styles.rounded]"
|
|
128
|
+
class="p-2 h-12 flex items-center relative mb-2 last:mb-0"
|
|
129
|
+
>
|
|
130
|
+
<div class="flex justify-between w-full items-center">
|
|
131
|
+
<span class="ml-2 block">{{ document.fileName }}</span>
|
|
132
|
+
<p class="mr-12">{{ reformatDateWithHours(document.createdDate!, true) }}</p>
|
|
133
|
+
</div>
|
|
134
|
+
<i
|
|
135
|
+
class="transition-all cursor-pointer mdi mdi-dots-vertical pl-2 mr-3 border-l-[1px] text-xl absolute right-0"
|
|
136
|
+
:class="[$styles.greenTextHover]"
|
|
137
|
+
@click="openPanel(document)"
|
|
138
|
+
></i>
|
|
139
|
+
</div>
|
|
140
|
+
</base-content-block>
|
|
141
|
+
</template>
|
|
134
142
|
</section>
|
|
135
143
|
<section class="w-full px-[10px] pt-[14px]" v-if="$appContextStore.isPension && formStore.hasRepresentative">
|
|
136
144
|
<base-form-section
|
|
@@ -281,7 +289,12 @@
|
|
|
281
289
|
@click="getDoc('view')"
|
|
282
290
|
/>
|
|
283
291
|
</base-animation>
|
|
284
|
-
<base-btn
|
|
292
|
+
<base-btn
|
|
293
|
+
:disabled="documentLoading"
|
|
294
|
+
:loading="documentLoading"
|
|
295
|
+
:text="$appContextStore.t('download')"
|
|
296
|
+
@click="getDoc('download', $dataStore.isSupport() ? downloadType : undefined)"
|
|
297
|
+
/>
|
|
285
298
|
<base-animation>
|
|
286
299
|
<base-btn v-if="canDeleteFiles" :disabled="documentLoading" :loading="documentLoading" :text="$appContextStore.t('buttons.delete')" @click="deletionDialog = true" />
|
|
287
300
|
</base-animation>
|
|
@@ -547,6 +560,15 @@ export default defineComponent({
|
|
|
547
560
|
const beneficiaryFiltered = computed(() => formStore.beneficiaryForm.filter(i => i.iin !== formStore.policyholderForm.iin) as Base.Document.Digital[]);
|
|
548
561
|
const slaveInsuredForm = computed(() => formStore.slaveInsuredForm as Base.Document.Digital);
|
|
549
562
|
const documentListFiltered = computed(() => formStore.signedDocumentList.filter(i => !['1', '2', '3', '4'].includes(String(i.fileTypeCode))));
|
|
563
|
+
const documentListGrouped = computed(() => {
|
|
564
|
+
const groups = new Map<string, typeof documentListFiltered.value>();
|
|
565
|
+
for (const doc of documentListFiltered.value) {
|
|
566
|
+
const key = doc.fileTypeNameRu || 'Без категории';
|
|
567
|
+
if (!groups.has(key)) groups.set(key, []);
|
|
568
|
+
groups.get(key)!.push(doc);
|
|
569
|
+
}
|
|
570
|
+
return Array.from(groups.entries()).map(([name, items]) => ({ name, items }));
|
|
571
|
+
});
|
|
550
572
|
const jointMembers = ref<Member[]>([formStore.insuredForm[0]]);
|
|
551
573
|
|
|
552
574
|
const openPanel = async (document: DocumentItem) => {
|
|
@@ -968,6 +990,7 @@ export default defineComponent({
|
|
|
968
990
|
beneficiaryFiltered,
|
|
969
991
|
hasDigitalDocuments,
|
|
970
992
|
documentListFiltered,
|
|
993
|
+
documentListGrouped,
|
|
971
994
|
isDigitalDocDisabled,
|
|
972
995
|
isUnderwriterDocuments,
|
|
973
996
|
|
|
@@ -252,6 +252,7 @@
|
|
|
252
252
|
</base-animation>
|
|
253
253
|
</base-form-section>
|
|
254
254
|
<base-form-section :title="$appContextStore.t('policyholdersRepresentative.PowerOfAttorney')" v-if="whichForm === formStore.policyholdersRepresentativeFormKey">
|
|
255
|
+
<h2 :class="[$styles.textTitle]" class="pt-[14px] pb-3 pl-4 font-medium text-[#071222]">{{ $appContextStore.t('policyholdersRepresentative.mainData') }}</h2>
|
|
255
256
|
<base-form-input
|
|
256
257
|
v-model.trim="member.fullNameRod"
|
|
257
258
|
:label="$appContextStore.t('policyholdersRepresentative.NameParentCase')"
|
|
@@ -280,6 +281,7 @@
|
|
|
280
281
|
:clearable="!isDisabled"
|
|
281
282
|
:rules="$rules.required"
|
|
282
283
|
/>
|
|
284
|
+
<h2 :class="[$styles.textTitle]" class="pt-[14px] pb-3 pl-4 font-medium text-[#071222]">{{ $appContextStore.t('policyholdersRepresentative.doc') }}</h2>
|
|
283
285
|
<base-form-input
|
|
284
286
|
v-model.trim="member.confirmDocNumber"
|
|
285
287
|
:label="$appContextStore.t('policyholdersRepresentative.numberDoc')"
|
|
@@ -289,7 +291,7 @@
|
|
|
289
291
|
/>
|
|
290
292
|
<base-form-input
|
|
291
293
|
v-model="member.confirmDocIssueDate"
|
|
292
|
-
:label="$appContextStore.t('
|
|
294
|
+
:label="$appContextStore.t('policyholdersRepresentative.issueDateDoc')"
|
|
293
295
|
:readonly="isDisabled"
|
|
294
296
|
:clearable="!isDisabled"
|
|
295
297
|
:rules="$rules.date.concat($rules.checkPastOrToday)"
|
|
@@ -299,7 +301,7 @@
|
|
|
299
301
|
/>
|
|
300
302
|
<base-form-input
|
|
301
303
|
v-model="member.confirmDocExpireDate"
|
|
302
|
-
:label="$appContextStore.t('
|
|
304
|
+
:label="$appContextStore.t('policyholdersRepresentative.expiryDateDoc')"
|
|
303
305
|
:readonly="isDisabled"
|
|
304
306
|
:clearable="!isDisabled"
|
|
305
307
|
:rules="$rules.date.concat($rules.checkTodayOrFuture)"
|
|
@@ -307,25 +309,27 @@
|
|
|
307
309
|
:min-date="getToday()"
|
|
308
310
|
append-inner-icon="mdi mdi-calendar-blank-outline"
|
|
309
311
|
/>
|
|
312
|
+
<h2 :class="[$styles.textTitle]" class="pt-[14px] pb-3 pl-4 font-medium text-[#071222]">{{ $appContextStore.t('policyholdersRepresentative.visa') }}</h2>
|
|
310
313
|
<base-form-input v-model.trim="member.migrationCard" :label="$appContextStore.t('policyholdersRepresentative.numberVisa')" />
|
|
311
314
|
<base-form-input
|
|
312
315
|
v-model="member.migrationCardIssueDate"
|
|
313
|
-
:label="$appContextStore.t('
|
|
316
|
+
:label="$appContextStore.t('policyholdersRepresentative.issueDateVisa')"
|
|
314
317
|
:readonly="isDisabled"
|
|
315
318
|
:clearable="!isDisabled"
|
|
316
|
-
:rules="$rules.date"
|
|
319
|
+
:rules="member.migrationCard ? $rules.required.concat($rules.date) : $rules.date"
|
|
317
320
|
:maska="$maska.date"
|
|
318
321
|
append-inner-icon="mdi mdi-calendar-blank-outline"
|
|
319
322
|
/>
|
|
320
323
|
<base-form-input
|
|
321
324
|
v-model="member.migrationCardExpireDate"
|
|
322
|
-
:label="$appContextStore.t('
|
|
325
|
+
:label="$appContextStore.t('policyholdersRepresentative.expiryDateVisa')"
|
|
323
326
|
:readonly="isDisabled"
|
|
324
327
|
:clearable="!isDisabled"
|
|
325
|
-
:rules="$rules.date"
|
|
328
|
+
:rules="member.migrationCard ? $rules.required.concat($rules.date) : $rules.date"
|
|
326
329
|
:maska="$maska.date"
|
|
327
330
|
append-inner-icon="mdi mdi-calendar-blank-outline"
|
|
328
331
|
/>
|
|
332
|
+
<h2 :class="[$styles.textTitle]" class="pt-[14px] pb-3 pl-4 font-medium text-[#071222]">{{ $appContextStore.t('policyholdersRepresentative.notary') }}</h2>
|
|
329
333
|
<base-form-toggle
|
|
330
334
|
v-model="formStore.policyholdersRepresentativeForm.isNotary"
|
|
331
335
|
:disabled="isDisabled"
|
|
@@ -2267,6 +2271,17 @@ export default {
|
|
|
2267
2271
|
}
|
|
2268
2272
|
};
|
|
2269
2273
|
|
|
2274
|
+
const norm = (s?: string) => s?.trim().toLowerCase().replace(/ё/g, 'е').replace(/\s+/g, ' ') ?? '';
|
|
2275
|
+
|
|
2276
|
+
const normalizeDate = (d?: string) => d?.slice(0, 10) ?? '';
|
|
2277
|
+
|
|
2278
|
+
const containsAllWords = (source: string, target: string) => {
|
|
2279
|
+
const sourceWords = source.split(' ');
|
|
2280
|
+
const targetWords = target.split(' ');
|
|
2281
|
+
|
|
2282
|
+
return targetWords.every(w => sourceWords.includes(w));
|
|
2283
|
+
};
|
|
2284
|
+
|
|
2270
2285
|
const getDigitalDocument = async (otpCode: string) => {
|
|
2271
2286
|
if (!digitalDocumentOwnerType.value) return;
|
|
2272
2287
|
let iin = '';
|
|
@@ -2301,15 +2316,23 @@ export default {
|
|
|
2301
2316
|
if (digitalDocumentOwnerType.value === 'child' && selectedChild.value && responseData) {
|
|
2302
2317
|
const { firstName, lastName, birthDate } = selectedChild.value;
|
|
2303
2318
|
|
|
2304
|
-
const
|
|
2305
|
-
const
|
|
2319
|
+
const first = norm(firstName);
|
|
2320
|
+
const last = norm(lastName);
|
|
2321
|
+
|
|
2322
|
+
const respFirst = norm(responseData.firstName);
|
|
2323
|
+
const respLast = norm(responseData.lastName);
|
|
2324
|
+
const respFull = norm(responseData.fullName);
|
|
2306
2325
|
|
|
2307
|
-
const firstNameMatch = norm(firstName) === norm(responseData.firstName);
|
|
2308
|
-
const lastNameMatch = norm(lastName) === norm(responseData.lastName);
|
|
2309
2326
|
const birthDateMatch =
|
|
2310
2327
|
normalizeDate(birthDate) !== '' && normalizeDate(responseData.birthDate) !== '' && normalizeDate(birthDate) === normalizeDate(responseData.birthDate);
|
|
2311
2328
|
|
|
2312
|
-
|
|
2329
|
+
const strictMatch = first === respFirst && last === respLast;
|
|
2330
|
+
|
|
2331
|
+
const fullNameMatch = containsAllWords(respFull, `${first} ${last}`);
|
|
2332
|
+
|
|
2333
|
+
const nameMatch = strictMatch || fullNameMatch;
|
|
2334
|
+
|
|
2335
|
+
if (!nameMatch) {
|
|
2313
2336
|
let message;
|
|
2314
2337
|
if (currentLocale.value === 'kz') {
|
|
2315
2338
|
message = `Таңдалған бала (${lastName} ${firstName}) мен алынған деректер (${responseData.lastName} ${responseData.firstName}) өзара сәйкес келмейді.`;
|
|
@@ -2319,6 +2342,9 @@ export default {
|
|
|
2319
2342
|
showToaster('error', message);
|
|
2320
2343
|
return;
|
|
2321
2344
|
}
|
|
2345
|
+
if (!birthDateMatch) {
|
|
2346
|
+
showToaster('warning', 'Проверьте дату рождения');
|
|
2347
|
+
}
|
|
2322
2348
|
}
|
|
2323
2349
|
|
|
2324
2350
|
if (appContextStore.isLifetrip) {
|
|
@@ -2336,8 +2362,13 @@ export default {
|
|
|
2336
2362
|
member.value.chooseChild = `${responseData.lastName} ${responseData.firstName} ${responseData.middleName ? responseData.middleName : ''}`;
|
|
2337
2363
|
}
|
|
2338
2364
|
if (responseData.iin) member.value.iin = reformatIin(responseData.iin);
|
|
2339
|
-
if (
|
|
2340
|
-
|
|
2365
|
+
if (digitalDocumentOwnerType.value === 'child' && selectedChild.value) {
|
|
2366
|
+
if (selectedChild.value.firstName) member.value.firstName = selectedChild.value.firstName;
|
|
2367
|
+
if (selectedChild.value.lastName) member.value.lastName = selectedChild.value.lastName;
|
|
2368
|
+
} else {
|
|
2369
|
+
if (responseData.firstName) member.value.firstName = responseData.firstName;
|
|
2370
|
+
if (responseData.lastName) member.value.lastName = responseData.lastName;
|
|
2371
|
+
}
|
|
2341
2372
|
if (responseData.firstNameLatin && appContextStore.isLifetrip) member.value.firstNameLat = responseData.firstNameLatin;
|
|
2342
2373
|
if (responseData.lastNameLatin && appContextStore.isLifetrip) member.value.lastNameLat = responseData.lastNameLatin;
|
|
2343
2374
|
if (responseData.middleName) member.value.middleName = responseData.middleName;
|
|
@@ -485,9 +485,10 @@
|
|
|
485
485
|
:title="$appContextStore.t('pension.ownFundsAmount')"
|
|
486
486
|
:class="[formStore.applicationData.processCode === 25 ? 'mt-0 rounded-tl-none' : '']"
|
|
487
487
|
>
|
|
488
|
+
<!--Временно сделали поле readonly, по запросу бизнеса-->
|
|
488
489
|
<base-form-input
|
|
489
490
|
v-model="pensionForm.ownFundsRaisAmount"
|
|
490
|
-
:readonly="isDisabled"
|
|
491
|
+
:readonly="isDisabled || true"
|
|
491
492
|
:clearable="!isDisabled"
|
|
492
493
|
:label="$appContextStore.t('pension.ownFundsRaisAmount')"
|
|
493
494
|
:rules="$dataStore.rules.sums"
|
|
@@ -1010,7 +1011,7 @@
|
|
|
1010
1011
|
<div v-if="panelList && isPanelLoading === false" class="w-full flex flex-col gap-2 p-2">
|
|
1011
1012
|
<base-panel-select-item :text="$appContextStore.t('form.notChosen')" :selected="panelValue.nameRu === null" @click="pickPanelValue(new Value())" />
|
|
1012
1013
|
<base-panel-select-item
|
|
1013
|
-
v-for="(item, index) of panelList.filter(i => i.nameRu && (i.nameRu as string).match(new RegExp(searchQuery, 'i')))"
|
|
1014
|
+
v-for="(item, index) of panelList.filter(i => i.nameRu && (i.nameRu as string).match(new RegExp(searchQuery || '', 'i')))"
|
|
1014
1015
|
:key="index"
|
|
1015
1016
|
:text="currentLocale === 'ru' ? String(item.nameRu) : String(item.nameKz)"
|
|
1016
1017
|
:selected="item.nameRu === panelValue.nameRu"
|
|
@@ -1031,7 +1032,7 @@
|
|
|
1031
1032
|
<div v-if="multiplePanelList && isPanelLoading === false" class="w-full flex flex-col gap-2 p-2">
|
|
1032
1033
|
<base-panel-select-item :text="$appContextStore.t('buttons.clearOrReset')" @click="calculatorForm.countries = []" false-icon="mdi-close-circle-outline" />
|
|
1033
1034
|
<base-panel-select-item
|
|
1034
|
-
v-for="(item, index) of multiplePanelList.filter(i => i.nameRu && (i.nameRu as string).match(new RegExp(searchQuery, 'i')))"
|
|
1035
|
+
v-for="(item, index) of multiplePanelList.filter(i => i.nameRu && (i.nameRu as string).match(new RegExp(searchQuery || '', 'i')))"
|
|
1035
1036
|
:key="index"
|
|
1036
1037
|
:text="String(item.nameRu)"
|
|
1037
1038
|
:selected="calculatorForm.countries && calculatorForm.countries.some(option => option.id === item.id)"
|
|
@@ -1047,7 +1048,7 @@
|
|
|
1047
1048
|
<div :class="[$styles.scrollPage]" class="flex flex-col items-center">
|
|
1048
1049
|
<base-rounded-input v-model.trim="searchQuery" :label="$appContextStore.t('labels.search')" class="w-full p-2" :hide-details="true" />
|
|
1049
1050
|
<div v-if="panelList && isPanelLoading === false" class="w-full flex flex-col gap-2 p-2">
|
|
1050
|
-
<div v-for="(item, index) of panelList.filter(i => i.nameRu && (i.nameRu as string).match(new RegExp(searchQuery, 'i')))">
|
|
1051
|
+
<div v-for="(item, index) of panelList.filter(i => i.nameRu && (i.nameRu as string).match(new RegExp(searchQuery || '', 'i')))">
|
|
1051
1052
|
<v-expansion-panels v-if="panelCodeList.includes(String(item.code)) && (whichProduct === 'lifebusiness' || whichProduct === 'gns')" variant="accordion">
|
|
1052
1053
|
<v-expansion-panel class="hover:bg-[#f5f8fd]" elevation="0" bg-color="#F3F6FC">
|
|
1053
1054
|
<v-expansion-panel-title @click="pickTermValue(item)">
|
|
@@ -1104,7 +1105,7 @@
|
|
|
1104
1105
|
|
|
1105
1106
|
<script lang="ts">
|
|
1106
1107
|
import { Member, Value, CountryValue, CalculatorForm, TransferContract, DocumentItem, TransferContractCompany } from '../../composables/classes';
|
|
1107
|
-
import type { Projects, AddCover, AddCoverAnswer, FileActions } from '../../types';
|
|
1108
|
+
import type { Projects, AddCover, AddCoverAnswer, FileActions, CheckContractDsPensionResponse } from '../../types';
|
|
1108
1109
|
import { getNumber, parseAmount } from '../../composables';
|
|
1109
1110
|
import { uuid } from 'vue-uuid';
|
|
1110
1111
|
|
|
@@ -2250,6 +2251,39 @@ export default defineComponent({
|
|
|
2250
2251
|
return Number(target ?? 0);
|
|
2251
2252
|
};
|
|
2252
2253
|
|
|
2254
|
+
const checkContractDsPension = async () => {
|
|
2255
|
+
try {
|
|
2256
|
+
const promises: Promise<CheckContractDsPensionResponse>[] = [];
|
|
2257
|
+
|
|
2258
|
+
if (formStore.pensionApp.transferContracts?.length) {
|
|
2259
|
+
promises.push(dataStore.api.pensionannuityNew.checkContractDsPension(formStore.applicationData.processInstanceId));
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
if (formStore.pensionApp.slave?.transferContracts?.length) {
|
|
2263
|
+
promises.push(dataStore.api.pensionannuityNew.checkContractDsPension(formStore.applicationData.slave?.processInstanceId));
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
if (!promises.length) return true;
|
|
2267
|
+
|
|
2268
|
+
const results = await Promise.all(promises);
|
|
2269
|
+
|
|
2270
|
+
const failed = results.filter(res => !res?.isSuccess);
|
|
2271
|
+
|
|
2272
|
+
if (failed.length) {
|
|
2273
|
+
failed.forEach(res => {
|
|
2274
|
+
if (res.error?.message) {
|
|
2275
|
+
showToaster('warning', res.error.message);
|
|
2276
|
+
}
|
|
2277
|
+
});
|
|
2278
|
+
return false;
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
return true;
|
|
2282
|
+
} catch (err) {
|
|
2283
|
+
ErrorHandler(err);
|
|
2284
|
+
}
|
|
2285
|
+
};
|
|
2286
|
+
|
|
2253
2287
|
const submitForm = async () => {
|
|
2254
2288
|
if (whichProduct.value === 'pensionannuitynew') {
|
|
2255
2289
|
const needsEnpfNoteFile = doesNeedEnpfNoteFile();
|
|
@@ -2397,7 +2431,13 @@ export default defineComponent({
|
|
|
2397
2431
|
const isApplicationSaved = await formStore.setApplication(data, true);
|
|
2398
2432
|
if (isApplicationSaved === false) return;
|
|
2399
2433
|
}
|
|
2434
|
+
await checkContractDsPension();
|
|
2400
2435
|
await dataStore.getApplicationData(String(route.params.taskId), false, false, false, true);
|
|
2436
|
+
if (appContextStore.isPension) {
|
|
2437
|
+
if (pensionForm.value.ownAmountFromDividend) {
|
|
2438
|
+
showToaster('info', `Использовано ${getNumberWithSpaces(pensionForm.value.ownAmountFromDividend)} ₸ из дивидендов для формирования выкупной суммы.`, 5000);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2401
2441
|
dateOfBegin.value = reformatDate(formStore.applicationData.pensionApp.dateOfBegin);
|
|
2402
2442
|
dividendSchedules.value = await formStore.getDividendSchedule();
|
|
2403
2443
|
} else {
|