hl-core 0.0.9-beta.31 → 0.0.9-beta.32

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 CHANGED
@@ -573,7 +573,7 @@ export class ApiClass {
573
573
  });
574
574
  }
575
575
 
576
- async checkIIN(iin: number) {
576
+ async checkIIN(iin: string) {
577
577
  return await this.axiosCall<boolean>({
578
578
  method: Methods.GET,
579
579
  url: `/Arm/api/Bpm/CheckIIN?iin=${iin}`,
@@ -696,10 +696,11 @@ export class ApiClass {
696
696
  data: data,
697
697
  });
698
698
  }
699
- async downloadTemplate() {
699
+ async downloadTemplate(fileType: number) {
700
700
  return this.axiosCall({
701
701
  method: Methods.GET,
702
- url: `/${this.productUrl}/api/Application/DownloadTemplate`,
702
+ url: `/${this.productUrl}/api/Application/DownloadTemplate?fileType=${fileType}`,
703
+ responseType: 'arraybuffer',
703
704
  });
704
705
  }
705
706
 
@@ -1,48 +1,94 @@
1
1
  <template>
2
- <div class="bg-primary-light-blue rounded-lg mb-2">
3
- <div class="bg-white rounded-lg pa-3 pa-sm-6">
4
- <div class="items-center justify-between">
5
- <p class="text-[#009C73] text-base">{{ props.control.title }}</p>
2
+ <div v-if="block" class="form-data-block rounded-lg border-[1px] relative transition-all" :class="[$styles.whiteBg, block.disabled && $styles.disabled]">
3
+ <div class="py-3 px-6">
4
+ <div class="flex items-center justify-between">
5
+ <p :class="[$styles.textTitle, $styles.greenText]">{{ block.title }}</p>
6
+ <div
7
+ v-if="typeof block.headerBtn === 'object'"
8
+ :class="[$styles.blueBg, $styles.whiteText, $styles.textSimple, block.disabled ? $styles.disabled : 'cursor-pointer']"
9
+ class="hidden lg:flex transition-all rounded-lg h-[36px] items-center font-medium justify-center opacity-50 hover:opacity-90 w-[120px]"
10
+ @click="!block.disabled && block.headerBtn.action()"
11
+ >
12
+ {{ block.headerBtn.text }}
13
+ </div>
6
14
  </div>
7
- <v-row class="mt-1">
8
- <v-col v-for="(label, index) in visibleLabels" :key="index" :cols="label.hideInMobile !== false ? label.size : 11 / visibleLabels.length">
9
- <p class="text-sm font-medium">
10
- {{ label.value }}
15
+ <p v-if="block.subtitle" :class="[$styles.greyText, $styles.textSimple]">{{ block.subtitle }}</p>
16
+ <v-row class="mt-1 max-w-[97%]">
17
+ <v-col v-for="(label, index) in visibleLabels" :key="index" :cols="block.shrinkLabels === true ? false : label.size">
18
+ <p :class="[$styles.textSimple]" class="font-medium">
19
+ {{ label.text }}
11
20
  </p>
12
21
  </v-col>
13
- <v-col cols="1"></v-col>
14
- </v-row>
15
- <v-row v-if="props.control.entries && props.control.entries.length">
16
- <v-col v-for="(label, index) in visibleLabels" :key="index" :cols="label.size ?? 11 / visibleLabels.length" class="flex items-center">
17
- <p class="text-base">{{ props.control.entries[index].value }}</p>
18
- </v-col>
19
- <v-col cols="1" class="flex items-end justify-end">
20
- <button v-if="!props.control.disabled" @click="$emit('onMore', { whichForm: control.key })">
21
- <i class="mdi mdi-dots-vertical text-xl"></i>
22
- </button>
23
- </v-col>
24
- </v-row>
25
- <v-row v-else>
26
- <v-col cols="11" class="flex items-center">
27
- <span class="text-primary-blue text-base">{{ $dataStore.t('clients.necessaryFillForm') }} </span>
28
- </v-col>
29
- <v-col cols="1" class="flex items-end justify-end">
30
- <button v-if="!props.control.disabled" @click="$emit('onMore', { whichForm: control.key })">
31
- <i class="mdi mdi-dots-vertical text-xl"></i>
32
- </button>
33
- </v-col>
34
22
  </v-row>
23
+ <div v-if="hasBlockData(block.data)">
24
+ <v-row v-for="(row, index) in getBlockDataValue(block.data)" :key="index" class="min-h-[65px] max-w-[97%]">
25
+ <v-col
26
+ v-if="row.every((i: any) => !!i)"
27
+ v-for="each of row.filter((_: any, i: number) => $display().lgAndUp.value ? true : block.labels[i].hideOnMobile === false)"
28
+ :key="each"
29
+ >
30
+ <p :class="[$styles.textSimple]">
31
+ {{ each }}
32
+ </p>
33
+ </v-col>
34
+ <v-col v-else :class="[$styles.textSimple, $styles.blueText]">{{ block.noValueText ?? $dataStore.t('clients.necessaryFillForm') }}</v-col>
35
+ <div
36
+ v-if="block.btn"
37
+ class="absolute right-0 rounded-br-lg transition-all h-[70px] w-[60px] place-self-end flex items-center justify-center"
38
+ :class="[$styles.blueBgLight, $styles.blueBgLightHover, block.disabled ? $styles.disabled : 'cursor-pointer']"
39
+ @click="!block.disabled && block.btn.action({ value: row, index: index })"
40
+ >
41
+ <i class="mdi text-xl" :class="[block.btn.icon]"></i>
42
+ </div>
43
+ </v-row>
44
+ </div>
35
45
  </div>
36
46
  </div>
37
47
  </template>
38
- <script setup lang="ts">
39
- const display = useDisplayInfo();
40
- const props = defineProps({
41
- control: {
42
- type: Object as PropType<FormBlock>,
43
- required: true,
48
+
49
+ <script lang="ts">
50
+ import { ComputedRefWithControl } from '@vueuse/core';
51
+ import { FormBlock } from '../../composables/fields';
52
+
53
+ export default defineComponent({
54
+ props: {
55
+ block: {
56
+ type: Object as PropType<FormBlock>,
57
+ required: true,
58
+ },
59
+ },
60
+ setup(props) {
61
+ const display = useDisplayInfo();
62
+ const visibleLabels = computed(() => (display.lgAndUp.value ? props.block.labels : props.block.labels.filter(i => i.hideOnMobile === false)));
63
+
64
+ const hasBlockData = (data: ComputedRefWithControl<any> | string[][]) => {
65
+ if (data) {
66
+ if ('value' in data && data.value && data.value.length) {
67
+ return true;
68
+ }
69
+ if ('value' in data === false && Array.isArray(data) && data.length) {
70
+ return true;
71
+ }
72
+ }
73
+ return false;
74
+ };
75
+ const getBlockDataValue = (data: ComputedRefWithControl<any> | string[][]) => ('value' in data ? data.value : data);
76
+
77
+ return {
78
+ // Computed
79
+ visibleLabels,
80
+
81
+ // Functions
82
+ hasBlockData,
83
+ getBlockDataValue,
84
+ };
44
85
  },
45
86
  });
46
- const isDesktop = computed(() => display.lgAndUp.value);
47
- const visibleLabels = computed(() => (isDesktop.value ? props.control.labels : props.control.labels.filter(l => l.hideInMobile === false)));
48
87
  </script>
88
+
89
+ <style>
90
+ .form-data-block .v-col {
91
+ display: flex;
92
+ align-items: center;
93
+ }
94
+ </style>
@@ -8,11 +8,12 @@
8
8
  variant="solo"
9
9
  show-size
10
10
  multiple
11
- accept=".pdf,.doc,.jpeg,.jpg,.jpg,.xlsx,.xls"
11
+ accept=".pdf,.doc,.docx,.jpeg,.jpg,.jpg,.xlsx,.xls"
12
12
  truncate-length="15"
13
13
  clear-icon="mdi mdi-close"
14
14
  :label="label"
15
15
  @click:append-inner="$emit('append-inner', $event)"
16
+ @click:clear="$emit('on-clear')"
16
17
  />
17
18
  </template>
18
19
 
@@ -34,7 +35,7 @@ export default defineComponent({
34
35
  },
35
36
  },
36
37
  },
37
- emits: ['input', 'append-inner'],
38
+ emits: ['input', 'append-inner', 'on-clear'],
38
39
  });
39
40
  </script>
40
41
 
@@ -8,18 +8,6 @@
8
8
  :text="$dataStore.t('preliminaryCalculation')"
9
9
  icon="mdi-alert text-[#FCB016]"
10
10
  ></base-message-block>
11
- <base-form-section v-if="whichProduct === 'gons'" :title="$dataStore.t('productConditionsForm.requestedProductConditions')" :class="[$styles.textSimple]">
12
- <base-form-text-section
13
- class="mb-4"
14
- title="Инвалидность I или II группы по причине несчастного случая, начиная с третьего года по любой причине, с освобождением от уплаты страховых взносов"
15
- subtitle="Равна страховой сумме по основному покрытию"
16
- />
17
- <base-form-text-section
18
- title="Если лицо, назначенное Выгодоприобретателем, на дату осуществления Страховщиком страховой выплаты не достигло совершеннолетия (восемнадцатилетнего возраста), страховая
19
- выплата подлежит осуществлению:"
20
- subtitle="Если несовершеннолетний не достиг возраста 14 лет - законному представителю в соответствии с законодательством Республики Казахстан"
21
- />
22
- </base-form-section>
23
11
  <base-form-section v-if="isUnderwriterRole && $dataStore.hasClientAnketa && $dataStore.isClientAnketaCondition" :title="$dataStore.t('policyholderForm')">
24
12
  <base-form-input
25
13
  v-model="productConditionsForm.lifeMultiplyClient"
@@ -54,7 +42,7 @@
54
42
  <base-form-input v-model="insured.gender.nameRu" class="mb-4" :label="$dataStore.t('form.gender')" :readonly="true" />
55
43
  </div>
56
44
  </base-form-section>
57
- <base-form-section v-if="isUnderwriterRole" :title="$dataStore.t('recalculationInfo')">
45
+ <base-form-section v-if="isUnderwriterRole && whichProduct !== 'lifebusiness'" :title="$dataStore.t('recalculationInfo')">
58
46
  <base-form-input
59
47
  v-model="productConditionsForm.lifeMultiply"
60
48
  :maska="$maska.numbers"
@@ -461,7 +449,7 @@
461
449
  />
462
450
  <base-form-input v-model="calculatorForm.price" :readonly="true" :label="isCalculator ? $dataStore.t('calculatorForm.premium') : $dataStore.t('calculatorForm.price')" />
463
451
  </base-form-section>
464
- <base-form-section v-if="additionalTerms && additionalTerms.length" :title="$dataStore.t('productConditionsForm.additional')">
452
+ <base-form-section v-if="isShownAdditionalTerms && additionalTerms && additionalTerms.length" :title="$dataStore.t('productConditionsForm.additional')">
465
453
  <div v-for="(term, index) of additionalTerms" :key="index">
466
454
  <base-panel-input
467
455
  v-if="filterTermConditions(term)"
@@ -614,6 +602,14 @@ export default defineComponent({
614
602
  const whichSum = ref<'insurancePremiumPerMonth' | 'requestedSumInsured' | ''>('');
615
603
 
616
604
  const additionalTerms = ref<AddCover[]>([]);
605
+
606
+ const isShownAdditionalTerms = computed(() => {
607
+ if (whichProduct.value === 'gons') {
608
+ return false;
609
+ }
610
+ return true;
611
+ });
612
+
617
613
  const isMultiplePanelOpen = ref<boolean>(false);
618
614
 
619
615
  const multiplePanelValue = ref<CountryValue>(new CountryValue());
@@ -656,7 +652,13 @@ export default defineComponent({
656
652
  return !!productConditionsForm.requestedSumInsured && !!productConditionsForm.insurancePremiumPerMonth;
657
653
  });
658
654
  const hasProcessIndexRate = computed(() => {
659
- if (whichProduct.value === 'gons' || whichProduct.value === 'halykkazyna' || whichProduct.value === 'liferenta' || whichProduct.value === 'lifebusiness') {
655
+ if (
656
+ whichProduct.value === 'gons' ||
657
+ whichProduct.value === 'halykkazyna' ||
658
+ whichProduct.value === 'liferenta' ||
659
+ whichProduct.value === 'lifebusiness' ||
660
+ whichProduct.value === 'amuletlife'
661
+ ) {
660
662
  return false;
661
663
  }
662
664
  return true;
@@ -1525,6 +1527,7 @@ export default defineComponent({
1525
1527
  isDisabledCoverPeriod,
1526
1528
  hasDefault,
1527
1529
  isDisabledProcessGfot,
1530
+ isShownAdditionalTerms,
1528
1531
 
1529
1532
  // Rules
1530
1533
  coverPeriodRule,
@@ -28,25 +28,23 @@
28
28
  </section>
29
29
  <section v-if="chooseSignActions">
30
30
  <div v-if="!isElectronicContract && !isPaperContract && !isScansDocuments && !isQr" :class="[$styles.flexColNav]">
31
- <base-btn :text="$dataStore.t('buttons.sendOnPaper')" :disabled="isPaperDisabled" @click="handleSignAction('paper')" />
32
- <base-btn :text="$dataStore.t('buttons.sendElectronically')" :disabled="isElectronicDisabled" @click="handleSignAction('electronic')" />
33
- <base-btn :text="$dataStore.t('buttons.generatePrintedForms')" :disabled="isScansDisabled" @click="handleSignAction('scans')" />
34
- <base-btn :text="$dataStore.t('buttons.sendEgovMob')" :disabled="isQrDisabled" @click="handleSignAction('qr')" />
31
+ <base-btn :text="$dataStore.t('buttons.sendOnPaper')" :disabled="isPaperDisabled" :loading="loading" @click="handleSignAction('paper')" />
32
+ <base-btn :text="$dataStore.t('buttons.sendElectronically')" :disabled="isElectronicDisabled" :loading="loading" @click="handleSignAction('electronic')" />
33
+ <base-btn :text="$dataStore.t('buttons.generatePrintedForms')" :disabled="isScansDisabled" :loading="loading" @click="handleSignAction('scans')" />
34
+ <base-btn :text="$dataStore.t('buttons.sendEgovMob')" :disabled="isQrDisabled" :loading="loading" @click="handleSignAction('qr')" />
35
35
  </div>
36
36
  <div v-if="isPaperContract" :class="[$styles.flexColNav]">
37
37
  <base-btn :text="$dataStore.t('buttons.downloadContract')" :loading="$dataStore.isButtonsLoading" @click="generateDocument" />
38
38
  </div>
39
39
  <div v-if="isScansDocuments" :class="[$styles.flexColNav]">
40
- <base-btn :text="$dataStore.t('buttons.downloadStatement')" />
41
- <base-btn :text="$dataStore.t('buttons.downloadContract')" />
42
- <base-btn :text="$dataStore.t('buttons.downloadApplication')" />
43
- <base-btn :text="$dataStore.t('buttons.downloadPowerOfAttorney')" />
44
-
40
+ <base-btn :text="$dataStore.t('buttons.downloadStatement')" @click="downloadTemplate(constants.documentTypes.statement, 'docx')" />
41
+ <base-btn :text="$dataStore.t('buttons.downloadContract')" @click="downloadTemplate(constants.documentTypes.contract, 'doc')" />
42
+ <base-btn :text="$dataStore.t('buttons.downloadApplication')" @click="downloadTemplate(constants.documentTypes.application1, 'vnd.ms-excel')" />
45
43
  <base-form-section class="mt-4 flex flex-col !gap-2" :title="$dataStore.t('clients.attachScansSignDocs')">
46
- <base-file-input :label="$dataStore.t('labels.attachStatement')" @input.prevent="onFileChangeScans($event)" />
47
- <base-file-input :label="$dataStore.t('labels.attachContract')" @input.prevent="onFileChangeScans($event)" />
48
- <base-file-input :label="$dataStore.t('labels.attachApplication')" @input.prevent="onFileChangeScans($event)" />
49
- <base-file-input :label="$dataStore.t('labels.attachPowerOfAttorney')" @input.prevent="onFileChangeScans($event)" />
44
+ <base-file-input :label="$dataStore.t('labels.attachStatement')" @input.prevent="onFileChangeScans($event, 'statement')" @onClear="onClearFile('statement')" />
45
+ <base-file-input :label="$dataStore.t('labels.attachContract')" @input.prevent="onFileChangeScans($event, 'contract')" @onClear="onClearFile('contract')" />
46
+ <base-file-input :label="$dataStore.t('labels.attachApplication')" @input.prevent="onFileChangeScans($event, 'app')" @onClear="onClearFile('app')" />
47
+ <base-file-input :label="$dataStore.t('labels.attachPowerOfAttorney')" @input.prevent="onFileChangeScans($event, 'attorney')" @onClear="onClearFile('attorney')" />
50
48
  </base-form-section>
51
49
  <base-btn :text="$dataStore.t('buttons.sign')" :loading="$dataStore.isButtonsLoading" @click="sendFiles" />
52
50
  <base-btn :text="$dataStore.t('buttons.cancel')" :btn="$styles.whiteBtn" @click="isScansDocuments = false" />
@@ -150,7 +148,7 @@
150
148
  <section v-if="templateAction">
151
149
  <div :class="[$styles.flexColNav]">
152
150
  <base-content-block>
153
- <base-panel-item class="cursor-pointer bg-white mb-4 border-b-0 rounded" @click.prevent="downloadTemplate">
151
+ <base-panel-item class="cursor-pointer bg-white mb-4 border-b-0 rounded" @click.prevent="downloadTemplate(constants.documentTypes.insuredsList, 'vnd.ms-excel')">
154
152
  {{ $dataStore.t('downloadTemplate') }}
155
153
  <i class="mdi mdi-download text-2xl text-[#A0B3D8]"></i
156
154
  ></base-panel-item>
@@ -231,16 +229,15 @@ export default defineComponent({
231
229
  }
232
230
  };
233
231
 
234
- const onFileChangeScans = async (event: InputEvent) => {
232
+ const onFileChangeScans = async (event: InputEvent, type: 'statement' | 'contract' | 'app' | 'attorney') => {
235
233
  if (event.target) {
236
234
  const files = (event.target as HTMLInputElement).files;
237
235
  if (files && files.length) {
238
- const name = files[0].name.substring(0, files[0].name.indexOf('.'));
239
- const selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.nameRu === String(name));
236
+ const doc = await selectedDocument(type);
240
237
  const data = {
241
238
  processInstanceId: formStore.applicationData.processInstanceId,
242
- fileTypeCode: selectedDocument ? selectedDocument.code : null,
243
- fileTypeId: selectedDocument ? selectedDocument.id : null,
239
+ fileTypeCode: doc ? doc.code : null,
240
+ fileTypeId: doc ? doc.id : null,
244
241
  fileName: files[0].name,
245
242
  };
246
243
  scansFiles.value.push({
@@ -251,6 +248,29 @@ export default defineComponent({
251
248
  }
252
249
  };
253
250
 
251
+ const onClearFile = async (type: 'statement' | 'contract' | 'app' | 'attorney') => {
252
+ const doc = await selectedDocument(type);
253
+ const result = scansFiles.value.filter(i => JSON.parse(i.fileData)[0].fileTypeCode !== doc.code);
254
+ scansFiles.value = result;
255
+ };
256
+
257
+ const selectedDocument = (type: 'statement' | 'contract' | 'app' | 'attorney') => {
258
+ let selectedDocument: any;
259
+ if (type === 'statement') {
260
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '32');
261
+ }
262
+ if (type === 'contract') {
263
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '6');
264
+ }
265
+ if (type === 'app') {
266
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '33');
267
+ }
268
+ if (type === 'attorney') {
269
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '34');
270
+ }
271
+ return selectedDocument;
272
+ };
273
+
254
274
  const sendFiles = async () => {
255
275
  if (scansFiles.value.length !== 4) {
256
276
  dataStore.showToaster('warning', dataStore.t('toaster.notAllDocumentsAttached'));
@@ -386,7 +406,7 @@ export default defineComponent({
386
406
  const insurancePremiumPerMonth = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.insurancePremiumPerMonth));
387
407
  const requestedSumInsured = computed(() => {
388
408
  if (dataStore.isLifeBusiness && formStore.productConditionsForm.requestedSumInsured === null) {
389
- dataStore.getNumberWithSpaces(formStore.applicationData.policyAppDto!.mainInsSum);
409
+ return dataStore.getNumberWithSpaces(formStore.applicationData.policyAppDto!.mainInsSum);
390
410
  }
391
411
  return dataStore.getNumberWithSpaces(formStore.productConditionsForm.requestedSumInsured);
392
412
  });
@@ -425,10 +445,8 @@ export default defineComponent({
425
445
  }
426
446
  return true;
427
447
  });
428
- const downloadTemplate = async () => {
429
- dataStore.panel.open = false;
430
- dataStore.panelAction = null;
431
- await dataStore.downloadTemplate();
448
+ const downloadTemplate = async (documentType: number, fileType: string) => {
449
+ await dataStore.downloadTemplate(documentType, fileType);
432
450
  };
433
451
 
434
452
  const sendTemplateToEmail = async () => {
@@ -442,6 +460,7 @@ export default defineComponent({
442
460
  };
443
461
 
444
462
  const handleSignAction = async (type: 'paper' | 'electronic' | 'scans' | 'qr') => {
463
+ loading.value = true;
445
464
  if (type === 'electronic') {
446
465
  await dataStore.signDocument();
447
466
  isElectronicContract.value = true;
@@ -456,6 +475,7 @@ export default defineComponent({
456
475
  await generateQR();
457
476
  isQr.value = true;
458
477
  }
478
+ loading.value = false;
459
479
  };
460
480
 
461
481
  // TODO Рефактор QR c npm
@@ -485,6 +505,8 @@ export default defineComponent({
485
505
  email,
486
506
  isQr,
487
507
  qrUrl,
508
+ scansFiles,
509
+
488
510
  // Functions
489
511
  closePanel,
490
512
  submitForm,
@@ -496,6 +518,8 @@ export default defineComponent({
496
518
  sendTemplateToEmail,
497
519
  onFileChangeScans,
498
520
  sendFiles,
521
+ onClearFile,
522
+
499
523
  // Computed
500
524
  buttonText,
501
525
  sendingActions,
@@ -1238,6 +1238,7 @@ export class FormStoreClass {
1238
1238
  beneficialOwnersIndex: number;
1239
1239
  isPolicyholderBeneficialOwner: boolean;
1240
1240
  clientId: string | null;
1241
+ insuredFile: any;
1241
1242
  };
1242
1243
  additionalInsuranceTerms: AddCover[];
1243
1244
  additionalInsuranceTermsWithout: AddCover[];
@@ -1343,6 +1344,7 @@ export class FormStoreClass {
1343
1344
  isPolicyholderBeneficialOwner: false,
1344
1345
  accidentIncidents: [],
1345
1346
  clientId: null,
1347
+ insuredFile: null,
1346
1348
  };
1347
1349
  this.additionalInsuranceTerms = [];
1348
1350
  this.additionalInsuranceTermsWithout = [];
@@ -1454,13 +1456,11 @@ export class MemberV2 {
1454
1456
  bik: string | null;
1455
1457
  kbe: string | null;
1456
1458
  };
1457
- address: Address;
1458
1459
  workDetails: {
1459
1460
  workplace: string | null;
1460
1461
  position: string | null;
1461
1462
  jobDuties: string | null;
1462
1463
  };
1463
- companyAddress: Address;
1464
1464
  authorityDetails: {
1465
1465
  basis: string | null;
1466
1466
  documentNumber: string | null;
@@ -1479,6 +1479,8 @@ export class MemberV2 {
1479
1479
  organizationInternetResource: string | null;
1480
1480
  organizationStartDate: string | null;
1481
1481
  isActualAddressEqualLegalAddres: boolean;
1482
+ organizationLegalAddress: Address;
1483
+ organizationActualAddress: Address;
1482
1484
  activityTypes: {
1483
1485
  activityTypeName: string | null;
1484
1486
  empoloyeeCount: number | null;
@@ -1516,13 +1518,11 @@ export class MemberV2 {
1516
1518
  bik: null,
1517
1519
  kbe: null,
1518
1520
  };
1519
- this.address = new Address();
1520
1521
  this.workDetails = {
1521
1522
  workplace: null,
1522
1523
  position: null,
1523
1524
  jobDuties: null,
1524
1525
  };
1525
- this.companyAddress = new Address();
1526
1526
  this.authorityDetails = {
1527
1527
  basis: null,
1528
1528
  documentNumber: null,
@@ -1541,6 +1541,8 @@ export class MemberV2 {
1541
1541
  organizationInternetResource: null,
1542
1542
  organizationStartDate: null,
1543
1543
  isActualAddressEqualLegalAddres: true,
1544
+ organizationLegalAddress: new Address(),
1545
+ organizationActualAddress: new Address(),
1544
1546
  activityTypes: [
1545
1547
  {
1546
1548
  activityTypeName: null,
@@ -11,6 +11,7 @@ export const constants = Object.freeze({
11
11
  halykkazyna: 11,
12
12
  daskamkorlyk: 13,
13
13
  lifebusiness: 14,
14
+ amuletlife: 15,
14
15
  },
15
16
  amlProducts: {
16
17
  checkcontragent: 1,
@@ -44,6 +45,17 @@ export const constants = Object.freeze({
44
45
  kzt: '₸',
45
46
  usd: '$',
46
47
  },
48
+ documentTypes: {
49
+ statement: 5,
50
+ contract: 6,
51
+ underConclusion: 12,
52
+ complianceFinMonitoring: 14,
53
+ agreement: 19,
54
+ acceptLetter: 22,
55
+ rejectLetter: 23,
56
+ application1: 33,
57
+ insuredsList: 34,
58
+ },
47
59
  fixInsAmount: [
48
60
  {
49
61
  code: '500000',
@@ -1,5 +1,6 @@
1
1
  import { i18n } from '../configs/i18n';
2
2
  import { FieldTypes } from '../types/form';
3
+ import { ComputedRefWithControl } from '@vueuse/core';
3
4
 
4
5
  const t = i18n.t;
5
6
 
@@ -201,3 +202,84 @@ export class BaseFields {
201
202
  return this;
202
203
  }
203
204
  }
205
+
206
+ export class FormBlockLabel {
207
+ text: string;
208
+ size: LabelSize = 1;
209
+ hideOnMobile: boolean = false;
210
+ constructor(options: { text: string; size?: LabelSize; hideOnMobile?: boolean }) {
211
+ this.text = options.text;
212
+ if (typeof options.size === 'number') this.size = options.size;
213
+ if (typeof options.hideOnMobile === 'boolean') this.hideOnMobile = options.hideOnMobile;
214
+ }
215
+ }
216
+
217
+ export class FormBlock {
218
+ title: string;
219
+ subtitle?: string;
220
+ noValueText?: string;
221
+ headerBtn?: {
222
+ text: string;
223
+ action: () => void;
224
+ };
225
+ labels: FormBlockLabel[];
226
+ data: ComputedRefWithControl<any> | string[][];
227
+ shrinkLabels: boolean = true;
228
+ disabled: ComputedRef;
229
+ btn: {
230
+ icon: string;
231
+ action: ({ value, index }: { value: any; index: number }) => void;
232
+ };
233
+ constructor(options: {
234
+ title: string;
235
+ subtitle?: string;
236
+ noValueText?: string;
237
+ headerBtn?: { text: string; action: () => void };
238
+ labels: FormBlockLabel[];
239
+ data: ComputedRefWithControl<any> | string[][];
240
+ shrinkLabels?: boolean;
241
+ disabled: ComputedRef;
242
+ btn?: { icon?: string; action: ({ value, index }: { value: any; index: number }) => void };
243
+ }) {
244
+ this.title = options.title;
245
+ if (typeof options.subtitle === 'string') this.subtitle = options.subtitle;
246
+ if (typeof options.noValueText === 'string') this.noValueText = options.noValueText;
247
+ else this.noValueText = t('clients.necessaryFillForm');
248
+ this.labels = options.labels;
249
+ this.data = options.data;
250
+ if (typeof options.shrinkLabels === 'boolean') this.shrinkLabels = options.shrinkLabels;
251
+ this.disabled = options.disabled;
252
+ if (typeof options.headerBtn === 'object') this.headerBtn = options.headerBtn;
253
+ if (typeof options.btn === 'object') {
254
+ this.btn = { icon: options.btn.icon ?? 'mdi-dots-vertical', action: options.btn.action };
255
+ } else this.btn = { icon: 'mdi-dots-vertical', action: () => {} };
256
+ }
257
+ }
258
+
259
+ export const getFormDataFrom = <T>(
260
+ data: T | T[],
261
+ keys: Array<keyof T>,
262
+ modifiers?: {
263
+ [key in keyof T]?: (val: any) => any;
264
+ },
265
+ ) => {
266
+ const getValuesFromKeys = (member: T) => {
267
+ const each: any[] = [];
268
+ keys.forEach(key => {
269
+ const data = member[key];
270
+ const value = data && typeof data === 'object' && 'nameRu' in data ? (data['nameRu'] as any) : data;
271
+ //@ts-ignore
272
+ each.push(modifiers && modifiers[key] ? modifiers[key](value ?? '') : value);
273
+ });
274
+ return each;
275
+ };
276
+ const getData = () => {
277
+ const result: any[][] = [];
278
+ Array.isArray(data) ? data.forEach(member => result.push(getValuesFromKeys(member))) : result.push(getValuesFromKeys(data));
279
+ return result;
280
+ };
281
+ return computedWithControl(
282
+ () => getData(),
283
+ () => getData(),
284
+ );
285
+ };
@@ -30,7 +30,7 @@ export class Masks {
30
30
  date: string = '##.##.####';
31
31
  post: string = '######';
32
32
  threeDigit: string = '###';
33
- iik: string = 'KZ################';
33
+ iik: string = 'KZ##################';
34
34
  }
35
35
 
36
36
  export const useMask = () => new Masks();
package/locales/ru.json CHANGED
@@ -131,7 +131,11 @@
131
131
  "fileOnlyBelow5mb": "Максимальный размер документа для загрузки - 5 МБ.",
132
132
  "fileOnlyBelow20mb": "Максимальный размер документа для загрузки - 20 МБ.",
133
133
  "onlyPDF": "Загружать документы можно только в формате PDF",
134
- "notAllDocumentsAttached": "Не все документы вложены"
134
+ "notAllDocumentsAttached": "Не все документы вложены",
135
+ "needAttachQuestionnaire": "Нужно вложить анкету для клиентов",
136
+ "notZeroPremium": "Общая страховая премия не должен быть 0",
137
+ "requiredFieldsLB": "Обязательные поля: №, Ф.И.О, Пол, Должность, Дата рождения, ИИН, Страховая сумма",
138
+ "duplicateClient": "В списке присутствуют повторяющиеся клиенты"
135
139
  },
136
140
  "notSignedContract": "Неподписанный Договор",
137
141
  "Contract": "Договор страхования",
@@ -331,6 +335,7 @@
331
335
  "downloadDocument": "Скачать документ",
332
336
  "downloadTemplate": "Скачать шаблон",
333
337
  "countriesLength": "Число выбранных стран",
338
+ "isPolicyholderLegalEntity": "Является ли Страхователь Юридическим лицом?",
334
339
  "productConditionsForm": {
335
340
  "coverPeriod": "Срок страхования",
336
341
  "payPeriod": "Период оплаты страховой премии",
@@ -742,7 +747,8 @@
742
747
  "guaranteedPeriodLimit": "Период гарантированного срока не может быть больше срока аннуитетных выплат",
743
748
  "noResidentOffline": "Обратитесь в филиал для оффлайн оформления нерезидента",
744
749
  "calculationPreliminary": "Расчет предварительный. Требуется заполнить все необходимые данные",
745
- "planDate": "Дата должна превышать сегодняшнюю дату"
750
+ "planDate": "Дата должна превышать сегодняшнюю дату",
751
+ "iik": "ИИК должен состоять из 20 символов"
746
752
  },
747
753
  "code": "КЭС",
748
754
  "fontSize": "Размер шрифта",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hl-core",
3
- "version": "0.0.9-beta.31",
3
+ "version": "0.0.9-beta.32",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "main": "nuxt.config.ts",
@@ -28,8 +28,8 @@
28
28
  "dev": "nuxt dev",
29
29
  "generate": "nuxt generate",
30
30
  "preview": "nuxt preview",
31
- "tk:all": "cd .. && cd baiterek && yarn typecheck && cd .. && cd bolashak && yarn typecheck && cd .. && cd calculator && yarn typecheck && cd .. && cd daskamkorlyk && yarn typecheck && cd .. && cd efo && yarn typecheck && cd .. && cd gons && yarn typecheck && cd .. && cd kazyna && yarn typecheck && cd .. && cd lifebusiness && yarn typecheck && cd .. && cd liferenta && yarn typecheck && cd .. && cd lifetrip && yarn typecheck && cd .. && cd core",
32
- "i:all": "cd .. && cd baiterek && yarn && cd .. && cd bolashak && yarn && cd .. && cd calculator && yarn && cd .. && cd daskamkorlyk && yarn && cd .. && cd efo && yarn && cd .. && cd gons && yarn && cd .. && cd kazyna && yarn && cd .. && cd lifebusiness && yarn && cd .. && cd liferenta && yarn && cd .. && cd lifetrip && yarn && cd .. && cd core",
31
+ "tk:all": "cd .. && cd amuletlife && yarn typecheck && cd .. && cd baiterek && yarn typecheck && cd .. && cd bolashak && yarn typecheck && cd .. && cd calculator && yarn typecheck && cd .. && cd daskamkorlyk && yarn typecheck && cd .. && cd efo && yarn typecheck && cd .. && cd gons && yarn typecheck && cd .. && cd kazyna && yarn typecheck && cd .. && cd lifebusiness && yarn typecheck && cd .. && cd liferenta && yarn typecheck && cd .. && cd lifetrip && yarn typecheck && cd .. && cd core",
32
+ "i:all": "cd .. && cd amuletlife && yarn && cd .. && cd baiterek && yarn && cd .. && cd bolashak && yarn && cd .. && cd calculator && yarn && cd .. && cd daskamkorlyk && yarn && cd .. && cd efo && yarn && cd .. && cd gons && yarn && cd .. && cd kazyna && yarn && cd .. && cd lifebusiness && yarn && cd .. && cd liferenta && yarn && cd .. && cd lifetrip && yarn && cd .. && cd core",
33
33
  "update:core": "git checkout -b %npm_package_version% && git add . && git commit -m \"%npm_package_version%\" && git push && git checkout main",
34
34
  "update:aml": "cd ../../aml/aml && yarn && cd ../checkcontract && yarn && cd ../checkcontragent && yarn && cd.. && git checkout -b %npm_package_version% && git add . && git commit -m \"%npm_package_version%\" && git push && git checkout main && cd ../efo/core",
35
35
  "update:lka": "cd .. && cd lka && yarn && git checkout -b %npm_package_version% && git add . && git commit -m \"%npm_package_version%\" && git push && git checkout main && cd .. && cd core",
@@ -45,6 +45,7 @@ export const useDataStore = defineStore('data', {
45
45
  isGons: state => state.product === 'gons',
46
46
  isKazyna: state => state.product === 'halykkazyna',
47
47
  isDas: state => state.product === 'daskamkorlyk',
48
+ isAmulet: state => state.product === 'amuletlife',
48
49
  isCalculator: state => state.product === 'calculator',
49
50
  isCheckContract: state => state.product === 'checkcontract',
50
51
  isCheckContragent: state => state.product === 'checkcontragent',
@@ -399,6 +400,7 @@ export const useDataStore = defineStore('data', {
399
400
  this.isLoading = false;
400
401
  },
401
402
  async getContragentById(id: number, whichForm: keyof typeof StoreMembers, load: boolean = true, whichIndex: number | null = null) {
403
+ if (Number(id) === 0) return;
402
404
  this.isLoading = load;
403
405
  try {
404
406
  const member = whichIndex === null ? this.formStore[whichForm as SingleMember] : this.formStore[whichForm as MultipleMember][whichIndex];
@@ -2082,7 +2084,7 @@ export const useDataStore = defineStore('data', {
2082
2084
  this.formStore.policyholdersRepresentativeForm.isNotary = spokesmanData.isNotary;
2083
2085
  }
2084
2086
  }
2085
- if (setProductConditions) {
2087
+ if (setProductConditions && !!applicationData.policyAppDto) {
2086
2088
  this.formStore.policyNumber = applicationData.policyAppDto.policyNumber;
2087
2089
  this.formStore.contractDate = reformatDate(applicationData.policyAppDto.contractDate);
2088
2090
  this.formStore.productConditionsForm.coverPeriod = applicationData.policyAppDto.coverPeriod;
@@ -2345,18 +2347,30 @@ export const useDataStore = defineStore('data', {
2345
2347
  ErrorHandler(err);
2346
2348
  }
2347
2349
  },
2348
- async downloadTemplate() {
2350
+ async downloadTemplate(documentType: number, fileType: string = 'pdf') {
2349
2351
  try {
2350
2352
  this.isButtonsLoading = true;
2351
- const response: any = await this.api.downloadTemplate();
2353
+ const response: any = await this.api.downloadTemplate(documentType);
2352
2354
  const blob = new Blob([response], {
2353
- type: `application/pdf`,
2355
+ type: `application/${fileType}`,
2354
2356
  });
2355
- this.showToaster('info', this.t('toaster.needToSignContract'), 100000);
2356
2357
  const url = window.URL.createObjectURL(blob);
2357
2358
  const link = document.createElement('a');
2358
2359
  link.href = url;
2359
- link.setAttribute('download', this.formStore.regNumber + ' Договор страхования');
2360
+ switch (documentType) {
2361
+ case constants.documentTypes.insuredsList:
2362
+ link.setAttribute('download', 'РФ-ДС-028 Список застрахованных ГССЖ_ГНС, изд.1.xls');
2363
+ break;
2364
+ case constants.documentTypes.statement:
2365
+ link.setAttribute('download', 'Заявление.docx');
2366
+ break;
2367
+ case constants.documentTypes.contract:
2368
+ link.setAttribute('download', 'Договор страхования.doc');
2369
+ break;
2370
+ case constants.documentTypes.application1:
2371
+ link.setAttribute('download', 'Приложение №1.xls');
2372
+ break;
2373
+ }
2360
2374
  document.body.appendChild(link);
2361
2375
  link.click();
2362
2376
  } catch (err) {
@@ -2368,7 +2382,7 @@ export const useDataStore = defineStore('data', {
2368
2382
  try {
2369
2383
  this.isButtonsLoading = true;
2370
2384
  await this.api.sendTemplateToEmail(email);
2371
- this.showToaster('info', this.t('toaster.needToSignContract'), 100000);
2385
+ this.showToaster('info', this.t('toaster.successfullyDocSent'), 5000);
2372
2386
  } catch (err) {
2373
2387
  ErrorHandler(err);
2374
2388
  }
@@ -3032,10 +3046,11 @@ export const useDataStore = defineStore('data', {
3032
3046
  const economySectorCode = this.economySectorCode.find((i: Value) => i.ids === '500003.9');
3033
3047
  if (economySectorCode) member.economySectorCode = economySectorCode;
3034
3048
  },
3035
- async startApplicationV2(policyholder: MemberV2) {
3049
+ async startApplicationV2(data: any) {
3050
+ const policyholder = data.clientData as MemberV2;
3036
3051
  if (!policyholder.iin) return false;
3037
3052
  try {
3038
- const response = await this.api.startApplication(policyholder);
3053
+ const response = await this.api.startApplication(data);
3039
3054
  this.sendToParent(constants.postActions.applicationCreated, response.processInstanceId);
3040
3055
  return response.processInstanceId;
3041
3056
  } catch (err) {
@@ -3045,8 +3060,7 @@ export const useDataStore = defineStore('data', {
3045
3060
  async saveClient(policyholder: MemberV2) {
3046
3061
  try {
3047
3062
  this.formStore.applicationData.clientApp.clientData = policyholder;
3048
- const response = await this.api.saveClient(this.formStore.applicationData.processInstanceId, this.formStore.lfb.clientId, this.formStore.applicationData.clientApp);
3049
- return response;
3063
+ await this.api.saveClient(this.formStore.applicationData.processInstanceId, this.formStore.lfb.clientId, this.formStore.applicationData.clientApp);
3050
3064
  } catch (err) {
3051
3065
  return ErrorHandler(err);
3052
3066
  }
@@ -3098,6 +3112,7 @@ export const useDataStore = defineStore('data', {
3098
3112
  this.formStore.lfb.isPolicyholderBeneficialOwner = clientData.iin.replace(/-/g, '') === beneficialOwnerApp[0].beneficialOwnerData.iin ? true : false;
3099
3113
  this.formStore.lfb.beneficialOwners.forEach(beneficial => {
3100
3114
  beneficial.beneficialOwnerData.identityDocument!.validUntil = reformatDate(beneficial.beneficialOwnerData.identityDocument!.validUntil as string);
3115
+ beneficial.beneficialOwnerData.iin = reformatIin(beneficial.beneficialOwnerData.iin as string);
3101
3116
  });
3102
3117
  }
3103
3118
 
@@ -3192,9 +3207,10 @@ export const useDataStore = defineStore('data', {
3192
3207
  gender: client.gender,
3193
3208
  position: item.workDetails?.position,
3194
3209
  birthDate: client.birthDate,
3195
- iin: client.iin,
3210
+ iin: reformatIin(client.iin),
3196
3211
  insSum: client.insuredPolicyData.insSum,
3197
3212
  premium: client.insuredPolicyData.premium,
3213
+ hasAttachedFile: client.hasAttachedFile,
3198
3214
  };
3199
3215
  });
3200
3216
  return clients;
@@ -3254,11 +3270,9 @@ export const useDataStore = defineStore('data', {
3254
3270
  }
3255
3271
  }
3256
3272
 
3257
- if (this.formStore.lfb.policyholderActivities) {
3258
- if (this.formStore.lfb.policyholderActivities.length !== this.formStore.applicationData.clientApp.clientData.organizationInfo.activityTypes.length) {
3259
- this.showToaster('error', this.t('toaster.notSavedMember', { text: 'деятельности Страхователя' }), 3000);
3260
- return false;
3261
- }
3273
+ if (this.formStore.applicationData.clientApp.clientData.organizationInfo.activityTypes === null) {
3274
+ this.showToaster('error', this.t('toaster.notSavedMember', { text: 'деятельности Страхователя' }), 3000);
3275
+ return false;
3262
3276
  }
3263
3277
 
3264
3278
  if (this.formStore.lfb.clients) {
@@ -3272,14 +3286,28 @@ export const useDataStore = defineStore('data', {
3272
3286
  }
3273
3287
  }
3274
3288
 
3289
+ if (this.formStore.lfb.clients && this.formStore.lfb.clients.length <= 10) {
3290
+ for (const client of this.formStore.lfb.clients) {
3291
+ if (client.hasAttachedFile === false) {
3292
+ this.showToaster('error', this.t('toaster.needAttachQuestionnaire'), 3000);
3293
+ return false;
3294
+ }
3295
+ }
3296
+ }
3297
+
3275
3298
  if (this.formStore.productConditionsForm.insurancePremiumPerMonth === null) {
3276
3299
  this.showToaster('error', this.t('toaster.emptyProductConditions'), 3000);
3277
3300
  return false;
3278
3301
  }
3279
3302
 
3303
+ if (this.formStore.productConditionsForm.insurancePremiumPerMonth === '0') {
3304
+ this.showToaster('error', this.t('toaster.notZeroPremium'), 3000);
3305
+ return false;
3306
+ }
3307
+
3280
3308
  return true;
3281
3309
  },
3282
- async checkIIN(iin: number) {
3310
+ async checkIIN(iin: string) {
3283
3311
  try {
3284
3312
  const response = await this.api.checkIIN(iin);
3285
3313
  return response;
package/store/rules.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i18n } from '../configs/i18n';
2
- import { formatDate } from '../composables';
2
+ import { formatDate, useMask } from '../composables';
3
3
 
4
4
  const t = i18n.t;
5
5
 
@@ -8,6 +8,7 @@ export const rules = {
8
8
  recalculationMultiplyBetween: [(v: any) => (v !== null && v !== '' && v >= 100 && v <= 200) || t('toaster.recalculationMultiplyBetween', { floor: '100', ceil: '200' })],
9
9
  recalculationAdditive: [(v: any) => (v !== null && v !== '' && v <= 100 && v >= 0) || t('toaster.valueShouldBeBetween', { floor: '0', ceil: '100' })],
10
10
  required: [(v: any) => !!v || t('rules.required')],
11
+ iik: [(v: any) => v.length === 20 || t('rules.iik')],
11
12
  objectRequired: [
12
13
  (v: any) => {
13
14
  if (!!v && 'nameRu' in v && v.nameRu != null) {
package/types/index.ts CHANGED
@@ -23,6 +23,7 @@ declare global {
23
23
  | 'checkcontract'
24
24
  | 'checkcontragent'
25
25
  | 'daskamkorlyk'
26
+ | 'amuletlife'
26
27
  | 'dso'
27
28
  | 'uu';
28
29
  type MemberKeys = keyof ReturnType<typeof useFormStore>;
@@ -286,6 +287,7 @@ declare global {
286
287
  accidentalLifeAdditive?: number;
287
288
  criticalMultiply?: string;
288
289
  criticalAdditive?: string;
290
+ hasAttachedFile?: boolean;
289
291
  }
290
292
 
291
293
  type RecalculationResponseType = {
@@ -649,24 +651,4 @@ declare global {
649
651
  };
650
652
 
651
653
  type LabelSize = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
652
-
653
- type Label = {
654
- value: string;
655
- hideInMobile: Boolean;
656
- size: LabelSize;
657
- };
658
-
659
- type Entry = {
660
- value: string;
661
- formatType?: 'iin' | 'fullName' | 'phone' | 'digits';
662
- };
663
-
664
- type FormBlock = {
665
- title: string;
666
- redirectPath: string;
667
- key?: string;
668
- disabled: boolean;
669
- labels: Label[];
670
- entries: Entry[];
671
- };
672
654
  }