hl-core 0.0.10-beta.2 → 0.0.10-beta.20

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.
Files changed (42) hide show
  1. package/api/base.api.ts +89 -69
  2. package/components/Complex/TextBlock.vue +2 -0
  3. package/components/Dialog/Dialog.vue +2 -0
  4. package/components/Dialog/FamilyDialog.vue +2 -0
  5. package/components/Form/DigitalDocument.vue +52 -0
  6. package/components/Form/DynamicForm.vue +1 -0
  7. package/components/Form/FormData.vue +1 -0
  8. package/components/Form/ManagerAttachment.vue +1 -0
  9. package/components/Input/DynamicInput.vue +2 -0
  10. package/components/Input/FormInput.vue +2 -0
  11. package/components/Input/OtpInput.vue +25 -0
  12. package/components/Input/PanelInput.vue +1 -0
  13. package/components/Input/RoundedInput.vue +2 -0
  14. package/components/Input/RoundedSelect.vue +2 -0
  15. package/components/Input/SwitchInput.vue +2 -0
  16. package/components/Input/TextInput.vue +2 -0
  17. package/components/Layout/Drawer.vue +2 -0
  18. package/components/Pages/Anketa.vue +1 -0
  19. package/components/Pages/Auth.vue +2 -0
  20. package/components/Pages/ContragentForm.vue +1 -0
  21. package/components/Pages/Documents.vue +236 -5
  22. package/components/Pages/MemberForm.vue +39 -29
  23. package/components/Pages/ProductConditions.vue +10 -2
  24. package/components/Panel/PanelHandler.vue +8 -1
  25. package/components/Transitions/Animation.vue +2 -0
  26. package/components/Utilities/Chip.vue +2 -0
  27. package/components/Utilities/JsonViewer.vue +1 -2
  28. package/composables/classes.ts +74 -41
  29. package/composables/fields.ts +6 -4
  30. package/composables/index.ts +220 -7
  31. package/composables/styles.ts +5 -16
  32. package/configs/pwa.ts +1 -7
  33. package/locales/ru.json +3 -2
  34. package/nuxt.config.ts +10 -13
  35. package/package.json +13 -12
  36. package/plugins/head.ts +1 -1
  37. package/store/data.store.ts +125 -255
  38. package/store/member.store.ts +3 -2
  39. package/tsconfig.json +3 -0
  40. package/types/enum.ts +5 -2
  41. package/types/form.ts +71 -75
  42. package/types/index.ts +852 -882
@@ -34,6 +34,8 @@
34
34
  </template>
35
35
 
36
36
  <script lang="ts">
37
+ import type { InputTypes, InputVariants } from '../../types';
38
+
37
39
  export default defineComponent({
38
40
  name: 'BaseRoundedInput',
39
41
  props: {
@@ -35,6 +35,8 @@
35
35
  </template>
36
36
 
37
37
  <script lang="ts">
38
+ import type { InputVariants } from '../../types';
39
+
38
40
  export default defineComponent({
39
41
  name: 'BaseRoundedSelect',
40
42
  props: {
@@ -5,6 +5,8 @@
5
5
  </template>
6
6
 
7
7
  <script lang="ts">
8
+ import type { SwitchInput } from '../../types/form';
9
+
8
10
  export default defineComponent({
9
11
  name: 'asSwitchInput',
10
12
  props: {
@@ -16,6 +16,8 @@
16
16
  </template>
17
17
 
18
18
  <script lang="ts">
19
+ import type { InputType } from '../../types/form';
20
+
19
21
  const iconsList: { [key: string]: string } = {
20
22
  arrowRight: 'mdi-chevron-right',
21
23
  search: 'mdi-magnify',
@@ -26,6 +26,8 @@
26
26
  </template>
27
27
 
28
28
  <script lang="ts">
29
+ import type { PanelTypes } from '../../types';
30
+
29
31
  export default defineComponent({
30
32
  name: 'BasePanel',
31
33
  props: {
@@ -239,6 +239,7 @@
239
239
 
240
240
  <script lang="ts">
241
241
  import { Value } from '../../composables/classes';
242
+ import type { AnketaBody, AnketaSecond, AnswerName } from '../../types';
242
243
 
243
244
  export default defineComponent({
244
245
  setup() {
@@ -125,6 +125,8 @@
125
125
  </template>
126
126
 
127
127
  <script lang="ts">
128
+ import type { InputTypes } from '../../types';
129
+
128
130
  export default defineComponent({
129
131
  setup() {
130
132
  const route = useRoute();
@@ -289,6 +289,7 @@
289
289
  <script lang="ts">
290
290
  import { StoreMembers } from '../../types/enum';
291
291
  import { Member, Value } from '../../composables/classes';
292
+ import type { ESBDValidationType } from '../../types';
292
293
 
293
294
  export default defineComponent({
294
295
  props: {
@@ -17,7 +17,7 @@
17
17
  <base-form-input v-model="formStore.contractDate" :label="$dataStore.t('form.date')" :readonly="true" append-inner-icon="mdi mdi-calendar-blank-outline" />
18
18
  <base-file-input :readonly="isDisabled" @input.prevent="onFileChange($event)" />
19
19
  </base-content-block>
20
- <base-content-block v-for="document of formStore.signedDocumentList" :key="document.id" :class="[$styles.textSimple]">
20
+ <base-content-block v-for="document of documentListFiltered" :key="document.id" :class="[$styles.textSimple]">
21
21
  <h5 class="text-center font-medium mb-4">
22
22
  {{ document.fileTypeName }}
23
23
  </h5>
@@ -31,6 +31,40 @@
31
31
  </div>
32
32
  </base-content-block>
33
33
  </section>
34
+ <section v-if="hasDigitalDocuments">
35
+ <base-digital-document
36
+ v-if="$route.params.taskId !== '0'"
37
+ :member="policyholderForm"
38
+ :title="$dataStore.t('policyholderForm')"
39
+ :disabled="isDigitalDocDisabled"
40
+ @openDigitalDocPanel="openDigitalDocPanel($event, 'Страхователя')"
41
+ @openPanel="openPanel"
42
+ />
43
+ <div v-if="insuredFiltered.length !== 0">
44
+ <base-digital-document
45
+ v-for="(member, index) in insuredFiltered"
46
+ :key="index"
47
+ :member="member"
48
+ :number="index + 1"
49
+ :title="$dataStore.t('insuredForm')"
50
+ :disabled="isDigitalDocDisabled"
51
+ @openDigitalDocPanel="openDigitalDocPanel($event, 'Застрахованного')"
52
+ @openPanel="openPanel"
53
+ />
54
+ </div>
55
+ <div v-if="beneficiaryFiltered.length !== 0">
56
+ <base-digital-document
57
+ v-for="(member, index) in beneficiaryFiltered"
58
+ :key="index"
59
+ :member="member"
60
+ :number="index + 1"
61
+ :title="$dataStore.t('beneficiaryForm')"
62
+ :disabled="isDigitalDocDisabled"
63
+ @openDigitalDocPanel="openDigitalDocPanel($event, 'Выгодоприобретателя')"
64
+ @openPanel="openPanel"
65
+ />
66
+ </div>
67
+ </section>
34
68
  <div v-if="noDocuments" class="h-[calc(90vh-70px)] flex flex-col items-center justify-center gap-6">
35
69
  <svg xmlns="http://www.w3.org/2000/svg" width="125" height="131" viewBox="0 0 125 131" fill="none" class="cursor-help">
36
70
  <path
@@ -97,7 +131,7 @@
97
131
  </div>
98
132
  </base-content-block>
99
133
  </section>
100
- <Teleport v-if="$dataStore.panelAction === null" to="#right-panel-actions">
134
+ <Teleport v-if="isPanelOpen" to="#right-panel-actions">
101
135
  <base-fade-transition>
102
136
  <div :class="[$styles.flexColNav]">
103
137
  <base-btn :disabled="documentLoading" :loading="documentLoading" text="Открыть" @click="getFile('view')" />
@@ -108,6 +142,46 @@
108
142
  </div>
109
143
  </base-fade-transition>
110
144
  </Teleport>
145
+ <Teleport v-if="isDigitalDocOpen" to="#right-panel-actions">
146
+ <div :class="[$styles.flexColNav]">
147
+ <base-form-section class="!mt-0">
148
+ <v-expansion-panels :flat="true">
149
+ <v-expansion-panel class="digital-doc-info !rounded-[8px]">
150
+ <v-expansion-panel-title class="!text-[12px]"> Как получить цифровой документ: </v-expansion-panel-title>
151
+ <v-expansion-panel-text class="text-[12px] text-[#464f60]">
152
+ 1. Выберите тип документа.<br /><br />
153
+ 2. Через приложение eGov mobile и другие приложения: <br />
154
+ • Откройте раздел "Цифровые документы". <br />
155
+ • Выберите нужный документ и откройте доступ. <br />
156
+ • Введите 6-значный код в поле «Код подтверждения». <br />
157
+ • Нажмите "Получить документ".<br /><br />
158
+ 3. Через SMS: <br />
159
+ • Нажмите "Отправить код". <br />
160
+ • Введите полученный SMS-код. <br />
161
+ • Нажмите "Получить документ".<br />
162
+ </v-expansion-panel-text>
163
+ </v-expansion-panel>
164
+ </v-expansion-panels>
165
+ </base-form-section>
166
+ <div class="p-4 d-flex flex-col gap-0.5" :class="[$styles.blueBgLight, $styles.rounded]">
167
+ <base-rounded-select v-model="documentType" class="document-type-select" :items="documentItems" :label="$dataStore.t('form.documentType')" hide-details />
168
+ <div class="digital-document-otp flex flex-col">
169
+ <base-otp-input
170
+ v-model="otpCode"
171
+ @keyup.enter.prevent="otpCode.length === useMask().otpSixDigit.length && getCode()"
172
+ @input="otpCode.length === useMask().otpSixDigit.length && getDigitalDocument()"
173
+ />
174
+ <base-animation>
175
+ <span v-if="!documentLoading" class="text-center cursor-pointer" :class="[$styles.mutedText]" @click="getCode"
176
+ >Не получили код? <span class="underline underline-offset-2">Отправить код заново</span></span
177
+ >
178
+ </base-animation>
179
+ </div>
180
+ </div>
181
+ <base-btn :disabled="documentLoading" :loading="documentLoading" :btn="$styles.greenLightBtn" text="Отправить SMS-код" @click="getCode" />
182
+ <base-btn :disabled="documentLoading" :loading="documentLoading" text="Получить документ" @click="getDigitalDocument" />
183
+ </div>
184
+ </Teleport>
111
185
  <base-dialog
112
186
  v-model="deletionDialog"
113
187
  :title="$dataStore.t('dialog.confirmDelete')"
@@ -122,18 +196,39 @@
122
196
 
123
197
  <script lang="ts">
124
198
  import { DocumentItem } from '../../composables/classes';
199
+ import type { IDocument } from '../../composables/classes';
125
200
  import { uuid } from 'vue-uuid';
201
+ import type { Base, FileActions } from '../../types';
126
202
 
127
203
  export default defineComponent({
128
204
  setup() {
205
+ type DigitalDocNames = 'Удостоверение личности' | 'Паспорт';
206
+ type DigitalDocTypes = 'IdentityCard' | 'Passport';
207
+
208
+ const route = useRoute();
129
209
  const dataStore = useDataStore();
130
210
  const formStore = useFormStore();
131
211
  const currentDocument = ref<DocumentItem>(new DocumentItem());
132
212
  const documentLoading = ref<boolean>(false);
133
213
  const deletionDialog = ref<boolean>(false);
214
+ const isPanelOpen = ref<boolean>(false);
215
+ const isDigitalDocOpen = ref<boolean>(false);
134
216
  const isDisabled = computed(() => !dataStore.isTask());
135
217
  const contractDict = computed(() => dataStore.dicFileTypeList.find(i => i.nameRu === 'Договор страхования' || i.nameRu === 'Договор'));
136
218
  const processCode = formStore.applicationData.processCode;
219
+
220
+ const hasDigitalDocuments = computed(() => dataStore.isEfoParent && !dataStore.isGns && !dataStore.isLifeBusiness && !!formStore.applicationData);
221
+ const isDigitalDocDisabled = computed(
222
+ () => !dataStore.isTask() || route.params.taskId === '0' || !dataStore.isInitiator() || !dataStore.isProcessEditable(formStore.applicationData.statusCode),
223
+ );
224
+ const documentType = ref<DigitalDocNames | null>(null);
225
+ const otpCode = ref<string>('');
226
+ const currentIin = ref<string>('');
227
+ const deleteFilesId = ['1', '2', '46'];
228
+ const documentItems: Array<{ title: DigitalDocNames; value: DigitalDocTypes }> = [
229
+ { title: 'Удостоверение личности', value: 'IdentityCard' },
230
+ { title: 'Паспорт', value: 'Passport' },
231
+ ];
137
232
  const signedContract = reactive<{
138
233
  processInstanceId: string | number;
139
234
  fileTypeId: string | number | null;
@@ -189,16 +284,24 @@ export default defineComponent({
189
284
  const canDeleteFiles = computed(() => {
190
285
  const baseCondition = dataStore.isTask() && dataStore.isInitiator() && dataStore.isProcessEditable(formStore.applicationData.statusCode);
191
286
  if (dataStore.isBaiterek || dataStore.isBolashak || dataStore.isLiferenta || dataStore.isKazyna || dataStore.isAmulet || dataStore.isGons) {
192
- return baseCondition && (currentDocument.value ? currentDocument.value.fileTypeCode === '46' : false);
287
+ return baseCondition && (currentDocument.value ? deleteFilesId.includes(String(currentDocument.value.fileTypeCode)) : false);
193
288
  }
194
289
  if (dataStore.isPension) return baseCondition;
195
290
  return false;
196
291
  });
197
292
 
293
+ const policyholderForm = computed(() => formStore.policyholderForm as Base.Document.Digital);
294
+ const insuredFiltered = computed(() => formStore.insuredForm.filter(i => i.iin !== formStore.policyholderForm.iin) as Base.Document.Digital[]);
295
+ const beneficiaryFiltered = computed(() => formStore.beneficiaryForm.filter(i => i.iin !== formStore.policyholderForm.iin) as Base.Document.Digital[]);
296
+ const documentListFiltered = computed(() => formStore.signedDocumentList.filter(i => !['1', '2'].includes(String(i.fileTypeCode))));
297
+
198
298
  const openPanel = async (document: DocumentItem) => {
199
299
  dataStore.rightPanel.title = document.fileTypeName!;
200
300
  currentDocument.value = document;
201
301
  dataStore.rightPanel.open = true;
302
+ isDigitalDocOpen.value = false;
303
+ isPanelOpen.value = true;
304
+ dataStore.panelAction = null;
202
305
  };
203
306
 
204
307
  const onFileChange = async (event: InputEvent) => {
@@ -263,6 +366,17 @@ export default defineComponent({
263
366
  }
264
367
  };
265
368
 
369
+ const openDigitalDocPanel = async (iin: string, title: string) => {
370
+ isPanelOpen.value = false;
371
+ isDigitalDocOpen.value = true;
372
+ dataStore.panelAction = null;
373
+ dataStore.rightPanel.open = true;
374
+ dataStore.rightPanel.title = `Получить ЦД ${title}`;
375
+ documentType.value = null;
376
+ otpCode.value = '';
377
+ currentIin.value = iin;
378
+ };
379
+
266
380
  watch(
267
381
  () => document_list.value,
268
382
  () => {
@@ -293,18 +407,93 @@ export default defineComponent({
293
407
  const data = {
294
408
  id: currentDocument.value.id,
295
409
  processInstanceId: currentDocument.value.processInstanceId,
410
+ iin: currentDocument.value.iin ?? '',
296
411
  };
297
412
  await dataStore.deleteFile(data);
298
413
  deletionDialog.value = false;
299
414
  dataStore.rightPanel.open = false;
300
415
  dataStore.panelAction = null;
301
416
  await dataStore.getSignedDocList(formStore.applicationData.processInstanceId);
417
+ if (hasDigitalDocuments.value && (currentDocument.value.fileTypeCode === '1' || currentDocument.value.fileTypeCode === '2')) {
418
+ getDigitalDocs();
419
+ }
420
+ }
421
+ };
422
+
423
+ const getCode = async () => {
424
+ if (!documentType.value) {
425
+ dataStore.showToaster('error', 'Выберите тип документа', 3000);
426
+ return;
427
+ }
428
+ documentLoading.value = true;
429
+ const response = await dataStore.onlineAccess(currentIin.value, String(documentType.value));
430
+ if (response) {
431
+ dataStore.showToaster('success', dataStore.t('toaster.successOtp'), 3000);
432
+ }
433
+ documentLoading.value = false;
434
+ };
435
+
436
+ const getDigitalDocument = async () => {
437
+ if (!otpCode.value) {
438
+ dataStore.showToaster('error', 'Введите код подтверждения', 3000);
439
+ return;
440
+ }
441
+ documentLoading.value = true;
442
+ const response = await dataStore.digitalDocuments(currentIin.value, String(formStore.applicationData.processInstanceId), otpCode.value);
443
+ if (response) {
444
+ await dataStore.getSignedDocList(formStore.applicationData.processInstanceId);
445
+ getDigitalDocs();
446
+ isDigitalDocOpen.value = false;
447
+ dataStore.panelAction = null;
448
+ dataStore.rightPanel.open = false;
449
+ documentType.value = null;
450
+ otpCode.value = '';
451
+ }
452
+ documentLoading.value = false;
453
+ };
454
+
455
+ const findCommonDocs = (members: Base.Document.Digital[]) => {
456
+ let commonDocs: IDocument[] = [];
457
+ for (let member of members) {
458
+ const matchingDoc = formStore.signedDocumentList.find(doc => doc.iin === String(member.iin).replaceAll('-', '') && (doc.fileTypeCode === '1' || doc.fileTypeCode === '2'));
459
+ if (matchingDoc) commonDocs.push(matchingDoc);
460
+ }
461
+ return commonDocs;
462
+ };
463
+
464
+ const setDigitalDocuments = (members: Base.Document.Digital[]) => {
465
+ const commonDocs = findCommonDocs(members);
466
+ if (commonDocs.length !== 0) {
467
+ for (let member of members) {
468
+ const matchingDoc = commonDocs.find(doc => doc.iin === String(member.iin).replaceAll('-', ''));
469
+ if (matchingDoc) member.digitalDocument = matchingDoc;
470
+ }
471
+ }
472
+ };
473
+
474
+ const clearDigitalDocuments = (members: Base.Document.Digital[]) => {
475
+ for (let member of members) member.digitalDocument = null;
476
+ };
477
+
478
+ const getDigitalDocs = () => {
479
+ if (route.params.taskId !== '0') {
480
+ clearDigitalDocuments([formStore.policyholderForm as Base.Document.Digital]);
481
+ setDigitalDocuments([formStore.policyholderForm as Base.Document.Digital]);
482
+ if (insuredFiltered.value.length !== 0) {
483
+ clearDigitalDocuments(insuredFiltered.value);
484
+ setDigitalDocuments(insuredFiltered.value);
485
+ }
486
+ if (beneficiaryFiltered.value.length !== 0) {
487
+ clearDigitalDocuments(beneficiaryFiltered.value);
488
+ setDigitalDocuments(beneficiaryFiltered.value);
489
+ }
302
490
  }
303
491
  };
304
492
 
305
493
  const onInit = async () => {
306
494
  await dataStore.getDicFileTypeList();
307
495
  await dataStore.getSignedDocList(formStore.applicationData.processInstanceId);
496
+ if (hasDigitalDocuments.value) getDigitalDocs();
308
497
  };
309
498
 
310
499
  onInit();
@@ -315,12 +504,17 @@ export default defineComponent({
315
504
 
316
505
  return {
317
506
  // State
507
+ otpCode,
318
508
  formStore,
319
- documentLoading,
509
+ processCode,
510
+ isPanelOpen,
320
511
  DocumentItem,
512
+ documentType,
513
+ documentItems,
321
514
  signedContract,
322
515
  deletionDialog,
323
- processCode,
516
+ documentLoading,
517
+ isDigitalDocOpen,
324
518
  underDocumentsList,
325
519
 
326
520
  // Computed
@@ -328,17 +522,54 @@ export default defineComponent({
328
522
  showContract,
329
523
  noDocuments,
330
524
  canDeleteFiles,
525
+ insuredFiltered,
526
+ policyholderForm,
527
+ beneficiaryFiltered,
528
+ hasDigitalDocuments,
529
+ documentListFiltered,
530
+ isDigitalDocDisabled,
331
531
  isUnderwriterDocuments,
332
532
 
333
533
  // Functions
534
+ getCode,
334
535
  getFile,
335
536
  openPanel,
336
537
  deleteFile,
538
+ getDigitalDocument,
337
539
  onFileChange,
338
540
  onUnderFiles,
541
+ openDigitalDocPanel,
339
542
  uploadUnderFiles,
340
543
  onClearUnderFiles,
341
544
  };
342
545
  },
343
546
  });
344
547
  </script>
548
+
549
+ <style>
550
+ .document-type-select .v-field {
551
+ border: none !important;
552
+ border-radius: 4px;
553
+ height: 56px;
554
+ }
555
+ .digital-document-otp .base-otp-input .v-otp-input__content {
556
+ gap: 8px;
557
+ padding-right: 0px !important;
558
+ padding-left: 0px !important;
559
+ }
560
+ .digital-doc-info .v-expansion-panel-text__wrapper {
561
+ padding: 8px 14px !important;
562
+ }
563
+ .digital-doc-info .v-expansion-panel-title {
564
+ max-height: 40px !important;
565
+ min-height: 39px !important;
566
+ padding: 0px 14px !important;
567
+ color: #464f60 !important;
568
+ }
569
+ .document-type-select .v-field-label--floating {
570
+ top: 5px !important;
571
+ }
572
+ .document-type-select .v-field__input {
573
+ padding-top: 21px;
574
+ }
575
+ </style>
@@ -347,7 +347,7 @@
347
347
  />
348
348
  <base-form-input v-model.trim="member.jobPlace" :label="$dataStore.t('form.jobPlace')" :readonly="isDisabled" :clearable="!isDisabled" :rules="$rules.required" />
349
349
  </base-form-section>
350
- <base-form-section :title="$dataStore.t('form.placeRegistration')" v-if="$dataStore.hasPlaceSection(whichForm)">
350
+ <base-form-section :title="$dataStore.t('form.placeRegistration')">
351
351
  <base-form-toggle v-if="hasSameAddressToggle" v-model="sameAddress" :disabled="isDisabled" :has-border="false" :title="$dataStore.t('form.sameAddress')" />
352
352
  <base-panel-input
353
353
  v-model="member.registrationCountry"
@@ -447,7 +447,7 @@
447
447
  @append="openPanel($dataStore.t('form.Region'), [], 'birthRegion', $dataStore.getRegions)"
448
448
  /> -->
449
449
  </base-form-section>
450
- <base-form-section :title="$dataStore.t('form.documentData')" v-if="$dataStore.hasDocumentSection(whichForm)">
450
+ <base-form-section :title="$dataStore.t('form.documentData')">
451
451
  <base-panel-input
452
452
  v-if="gbdDocuments && gbdDocuments.length"
453
453
  value="Список документов из ГБДФЛ"
@@ -702,18 +702,16 @@
702
702
  </Teleport>
703
703
  <Teleport v-if="isOtpPanelOpen && !member.hasAgreement" to="#right-panel-actions">
704
704
  <div :class="[$styles.flexColNav]">
705
- <base-fade-transition>
706
- <base-rounded-input
707
- v-if="otpCondition && member.otpTokenId"
708
- v-model="member.otpCode"
709
- :label="$dataStore.t('form.otpCode')"
710
- :maska="$maska.otp"
711
- :append-inner-icon="hasOtp ? 'mdi-cellphone-message text-[17px]' : ''"
712
- hide-details
713
- @keyup.enter.prevent="hasOtp ? checkOtp() : null"
714
- @input="onOtpCodeInput"
715
- />
716
- </base-fade-transition>
705
+ <base-animation>
706
+ <div v-if="otpCondition && member.otpTokenId" class="flex flex-col">
707
+ <base-form-section class="mt-0 py-2">
708
+ <base-otp-input v-model="member.otpCode" :length="4" @keyup.enter.prevent="hasOtp && checkOtp()" @input="onOtpCodeInput" />
709
+ </base-form-section>
710
+ <span class="text-center cursor-pointer mt-2" :class="[$styles.mutedText]" @click="sendOtp(false)"
711
+ >Не получили код? <span class="underline underline-offset-2">Отправить код заново</span></span
712
+ >
713
+ </div>
714
+ </base-animation>
717
715
  <base-btn v-if="!member.otpTokenId" :disabled="otpSending" :loading="otpSending" :text="$dataStore.t('buttons.sendOtp')" @click="sendOtp(false)" />
718
716
  <base-btn v-if="member.otpTokenId" :disabled="otpSending" :loading="otpSending" :text="$dataStore.t('buttons.check')" @click="checkOtp()" />
719
717
  </div>
@@ -721,12 +719,12 @@
721
719
  <Teleport v-if="isPositionPanelOpen" to="#right-panel-actions">
722
720
  <div :class="[$styles.scrollPage]" class="flex flex-col items-center">
723
721
  <base-rounded-input
724
- v-model="searchQuery"
725
- :label="$dataStore.t('labels.search')"
722
+ v-model.trim="searchQuery"
723
+ label="Выполните поиск должностей"
726
724
  class="w-full p-2"
727
725
  :hide-details="searchQuery.length >= 4"
728
- :rules="[searchQuery.length < 4 ? $dataStore.t('rules.searchQueryLen', { len: '4' }) : true]"
729
- :append-inner-icon="searchQuery.length < 4 ? '' : 'mdi mdi-magnify'"
726
+ :rules="[searchQuery.length < 4 ? $dataStore.t('rules.searchQueryLen', { len: 4 }) : true]"
727
+ append-inner-icon="mdi mdi-magnify"
730
728
  @append="searchPositions"
731
729
  />
732
730
  <base-animation>
@@ -790,7 +788,8 @@
790
788
  <script lang="ts">
791
789
  import { Value, DocumentItem, Member } from '../../composables/classes';
792
790
  import { uuid } from 'vue-uuid';
793
- import { StoreMembers, Enums } from '../../types/enum';
791
+ import { StoreMembers, CoreEnums } from '../../types/enum';
792
+ import type { Api, Dicts, ESBDValidationType, FileActions, MultipleMember } from '../../types';
794
793
 
795
794
  export default {
796
795
  setup() {
@@ -972,7 +971,7 @@ export default {
972
971
  (whichForm.value === formStore.beneficiaryFormKey && member.value.iin !== formStore.policyholderForm.iin) ||
973
972
  (dataStore.isLifetrip && whichForm.value === formStore.insuredFormKey && member.value.isInsuredUnderage),
974
973
  );
975
- const hasWorkPositionDict = !useEnv().isProduction && dataStore.isBaiterek && dataStore.isEfoParent;
974
+ const hasWorkPositionDict = dataStore.isBaiterek && dataStore.isEfoParent;
976
975
 
977
976
  const birthDateRule = computed(() => {
978
977
  const baseDateRule = dataStore.rules.required.concat(dataStore.rules.birthDate);
@@ -1084,6 +1083,10 @@ export default {
1084
1083
  };
1085
1084
 
1086
1085
  const searchPositions = async () => {
1086
+ if (searchQuery.value.length < 4) {
1087
+ dataStore.showToaster('error', dataStore.t('rules.searchQueryLen', { len: 4 }));
1088
+ return;
1089
+ }
1087
1090
  if (!isDisabled.value) {
1088
1091
  isPanelLoading.value = true;
1089
1092
  positionsList.value = await dataStore.getWorkPosition(searchQuery.value);
@@ -1122,6 +1125,7 @@ export default {
1122
1125
  isPositionPanelOpen.value = false;
1123
1126
  }
1124
1127
  if (type === 'workPosition') {
1128
+ dataStore.rightPanel.title = dataStore.t('form.jobPosition');
1125
1129
  isPositionPanelOpen.value = true;
1126
1130
  isOtpPanelOpen.value = false;
1127
1131
  isDocumentOpen.value = false;
@@ -1325,7 +1329,7 @@ export default {
1325
1329
  if (parsedDocument.middleName) member.value.middleName = parsedDocument.middleName;
1326
1330
  if (parsedDocument.fullName) member.value.longName = parsedDocument.fullName;
1327
1331
  if (parsedDocument.documentName && parsedDocument.documentName.startsWith('Kazakhstan - Id Card')) {
1328
- const documentType = dataStore.documentTypes.find((i: Value) => i.ids === Enums.Insis.DocTypes['1UDL']);
1332
+ const documentType = dataStore.documentTypes.find((i: Value) => i.ids === CoreEnums.Insis.DocTypes['1UDL']);
1329
1333
  if (documentType) member.value.documentType = documentType;
1330
1334
  }
1331
1335
  if (!!parsedDocument.documentIssuer) {
@@ -1429,7 +1433,9 @@ export default {
1429
1433
 
1430
1434
  const selectGbdDocument = (document: Api.GBD.Document) => {
1431
1435
  if (document) {
1432
- const documentType = dataStore.documentTypes.find((i: Value) => i.ids === Object.keys(Enums.GBD.DocTypes)[Object.values(Enums.GBD.DocTypes).indexOf(document.type.code)]);
1436
+ const documentType = dataStore.documentTypes.find(
1437
+ (i: Value) => i.ids === Object.keys(CoreEnums.GBD.DocTypes)[Object.values(CoreEnums.GBD.DocTypes).indexOf(document.type.code)],
1438
+ );
1433
1439
  if (documentType) member.value.documentType = documentType;
1434
1440
  const documentNumber = document.number;
1435
1441
  if (documentNumber) member.value.documentNumber = documentNumber;
@@ -1623,7 +1629,10 @@ export default {
1623
1629
  const docType = member.value.documentType.ids;
1624
1630
  if (
1625
1631
  member.value.gotFromInsis === true &&
1626
- (docType === Enums.Insis.DocTypes['1UDL'] || docType === Enums.Insis.DocTypes.SBI || docType === Enums.Insis.DocTypes.PS || docType === Enums.Insis.DocTypes.VNZ)
1632
+ (docType === CoreEnums.Insis.DocTypes['1UDL'] ||
1633
+ docType === CoreEnums.Insis.DocTypes.SBI ||
1634
+ docType === CoreEnums.Insis.DocTypes.PS ||
1635
+ docType === CoreEnums.Insis.DocTypes.VNZ)
1627
1636
  ) {
1628
1637
  dataStore.isLoading = true;
1629
1638
  const docTypeCodes = {
@@ -1823,9 +1832,9 @@ export default {
1823
1832
  if (dataStore.isLifetrip) {
1824
1833
  const documentByPriority = (() => {
1825
1834
  if (whichForm.value !== formStore.policyholderFormKey || formStore.isPolicyholderInsured === true) {
1826
- return member.value.documentsList.find(i => i.type === Enums.Insis.DocTypes.PS);
1835
+ return member.value.documentsList.find(i => i.type === CoreEnums.Insis.DocTypes.PS);
1827
1836
  }
1828
- return member.value.documentsList.find(i => i.type === Enums.Insis.DocTypes['1UDL']);
1837
+ return member.value.documentsList.find(i => i.type === CoreEnums.Insis.DocTypes['1UDL']);
1829
1838
  })();
1830
1839
  const userDocument = documentByPriority ? documentByPriority : member.value.documentsList[0];
1831
1840
  const documentType = dataStore.documentTypes.find((i: Value) => i.ids === userDocument.type);
@@ -1932,13 +1941,14 @@ export default {
1932
1941
  watch(
1933
1942
  () => member.value.age,
1934
1943
  val => {
1935
- if (val && Number(val) >= 18) {
1936
- if (member.value.hasAgreement !== true) {
1944
+ if (val) {
1945
+ if (Number(val) >= 18 && member.value.hasAgreement !== true) {
1937
1946
  member.value.hasAgreement = false;
1947
+ } else {
1948
+ member.value.hasAgreement = true;
1938
1949
  }
1939
- } else {
1940
- member.value.hasAgreement = true;
1941
1950
  }
1951
+
1942
1952
  member.value.isInsuredUnderage = Number(val) >= 18 ? false : true;
1943
1953
  },
1944
1954
  { immediate: true },
@@ -36,7 +36,14 @@
36
36
  <base-form-input v-model="formStore.policyholderForm.gender.nameRu" class="mb-4" :label="$dataStore.t('form.gender')" :readonly="true" />
37
37
  </base-form-section>
38
38
  <base-form-section
39
- v-if="isUnderwriterRole && $dataStore.members.insuredApp.has === true && whichProduct !== 'lifebusiness' && whichProduct !== 'gns' && whichProduct !== 'pensionannuitynew'"
39
+ v-if="
40
+ isUnderwriterRole &&
41
+ $dataStore.members.insuredApp.has === true &&
42
+ whichProduct !== 'lifebusiness' &&
43
+ whichProduct !== 'gns' &&
44
+ whichProduct !== 'pensionannuitynew' &&
45
+ whichProduct !== 'lifetrip'
46
+ "
40
47
  :title="$dataStore.t('insuredForm')"
41
48
  >
42
49
  <div v-for="(insured, index) of formStore.insuredForm" :key="index">
@@ -696,6 +703,7 @@
696
703
 
697
704
  <script lang="ts">
698
705
  import { Member, Value, CountryValue, CalculatorForm } from '../../composables/classes';
706
+ import type { Projects, AddCover, AddCoverAnswer } from '../../types';
699
707
 
700
708
  export default defineComponent({
701
709
  props: {
@@ -1444,7 +1452,7 @@ export default defineComponent({
1444
1452
  if (calculatorForm.type.code === 'Single' && calculatorForm.startDate && calculatorForm.endDate) {
1445
1453
  const formattedStartDate = formatDate(calculatorForm.startDate);
1446
1454
  const formattedEndDate = formatDate(calculatorForm.endDate);
1447
- if (formattedStartDate && formattedEndDate && formattedStartDate.getTime() > formattedEndDate.getTime()) {
1455
+ if (formattedStartDate && formattedEndDate && formattedStartDate.getTime() >= formattedEndDate.getTime()) {
1448
1456
  return dataStore.showToaster('error', dataStore.t('toaster.startMoreEnd'));
1449
1457
  }
1450
1458
  }
@@ -195,7 +195,13 @@
195
195
  <base-btn :loading="loading" :text="$dataStore.t('payment.copyUrl')" @click="$dataStore.copyToClipboard(formStore.epayLink)" />
196
196
  <base-btn :loading="loading" :text="$dataStore.t('payment.recipientNumber')" @click="openEpayPanel" />
197
197
  <base-btn :loading="loading" :text="$dataStore.t('sign.convertQr')" @click="convertQr(formStore.epayLink)" />
198
- <base-btn :loading="loading" :btn="$styles.greenBtn" :text="$dataStore.t('payment.halykLink')" @click="convertQr(formStore.epayLink, 'halyk_pay_link_template')" />
198
+ <base-btn
199
+ v-if="!useEnv().isProduction"
200
+ :loading="loading"
201
+ :btn="$styles.greenBtn"
202
+ :text="$dataStore.t('payment.halykLink')"
203
+ @click="convertQr(formStore.epayLink, 'halyk_pay_link_template')"
204
+ />
199
205
  </div>
200
206
  </base-form-section>
201
207
  <div v-if="isSendNumberOpen" :class="[$styles.flexColNav]">
@@ -254,6 +260,7 @@
254
260
  import { DocumentItem, Value } from '../../composables/classes';
255
261
  import { HubConnectionBuilder } from '@microsoft/signalr';
256
262
  import { uuid } from 'vue-uuid';
263
+ import type { Api, SignUrlType } from '../../types';
257
264
 
258
265
  export default defineComponent({
259
266
  emits: ['task'],
@@ -6,6 +6,8 @@
6
6
  </template>
7
7
 
8
8
  <script setup lang="ts">
9
+ import type { Utils } from '../../types';
10
+
9
11
  defineProps({
10
12
  type: {
11
13
  type: String as PropType<Utils.VuetifyAnimations>,