hl-core 0.0.9-beta.48 → 0.0.9-beta.49

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
@@ -234,6 +234,13 @@ export class ApiClass {
234
234
  });
235
235
  }
236
236
 
237
+ async getProcessCoverTypePeriod(processCode: string | number, questionId: string) {
238
+ return await this.axiosCall<AddCoverAnswer[]>({
239
+ method: Methods.GET,
240
+ url: `/Arm/api/Dictionary/GetProcessCoverTypePeriod/${processCode}/${questionId}`,
241
+ });
242
+ }
243
+
237
244
  async getProcessPaymentPeriod(processCode: string | number) {
238
245
  return await this.axiosCall({
239
246
  method: Methods.GET,
@@ -715,8 +722,12 @@ export class ApiClass {
715
722
  async downloadTemplate(fileType: number, processInstanceId?: string | number) {
716
723
  return await this.axiosCall({
717
724
  method: Methods.GET,
718
- url: `/${this.productUrl}/api/Application/DownloadTemplate?fileType=${fileType}&processInstanceId=${processInstanceId}`,
725
+ url: `/${this.productUrl}/api/Application/DownloadTemplate`,
719
726
  responseType: 'arraybuffer',
727
+ params: {
728
+ fileType,
729
+ processInstanceId: processInstanceId ?? null,
730
+ },
720
731
  });
721
732
  }
722
733
 
@@ -33,7 +33,7 @@
33
33
  <v-icon
34
34
  v-if="appendInnerIcon.includes('mdi-calendar-blank-outline') === false"
35
35
  :icon="appendInnerIcon"
36
- @click="appendInnerIcon.includes('mdi-magnify') ? $emit('append') : !props.readonly && $emit('append')"
36
+ @click="appendInnerIcon.includes('mdi-magnify') || appendInnerIcon.includes('mdi-credit-card-scan') ? $emit('append') : !props.readonly && $emit('append')"
37
37
  />
38
38
  <base-datepicker
39
39
  v-if="appendInnerIcon.includes('mdi-calendar-blank-outline') && !props.readonly"
@@ -59,23 +59,23 @@
59
59
  v-model="member.iin"
60
60
  :label="$dataStore.t('form.iin')"
61
61
  :maska="$maska.iin"
62
- :readonly="!!isDisabled || !!isIinPhoneDisabled"
62
+ :readonly="!!isDisabled || !!isIinPhoneDisabled || !!member.parsedDocument?.iin"
63
63
  :clearable="!isDisabled"
64
- :append-inner-icon="hasMemberSearch ? 'mdi mdi-magnify' : ''"
64
+ :append-inner-icon="hasMemberSearch ? (hasDocumentReader ? 'mdi mdi-credit-card-scan-outline' : 'mdi mdi-magnify') : ''"
65
65
  @append="searchMember"
66
66
  @input="onIinInput"
67
67
  :rules="$rules.required.concat($rules.iinRight)"
68
68
  />
69
69
  <base-form-input
70
70
  v-model.trim="member.lastName"
71
- :readonly="isDisabled || isFromGBD"
71
+ :readonly="isDisabled || isFromGBD || !!member.parsedDocument?.lastName"
72
72
  :clearable="!isDisabled"
73
73
  :label="$dataStore.t('form.lastName')"
74
74
  :rules="$rules.required.concat($rules.cyrillic)"
75
75
  />
76
76
  <base-form-input
77
77
  v-model.trim="member.firstName"
78
- :readonly="isDisabled || isFromGBD"
78
+ :readonly="isDisabled || isFromGBD || !!member.parsedDocument?.firstName"
79
79
  :clearable="!isDisabled"
80
80
  :label="$dataStore.t('form.firstName')"
81
81
  :rules="$rules.required.concat($rules.cyrillic)"
@@ -83,7 +83,7 @@
83
83
  <base-form-input
84
84
  v-if="hasMiddleName"
85
85
  v-model.trim="member.middleName"
86
- :readonly="isDisabled || isFromGBD"
86
+ :readonly="isDisabled || isFromGBD || !!member.parsedDocument?.middleName"
87
87
  :clearable="!isDisabled"
88
88
  :label="$dataStore.t('form.middleName')"
89
89
  :rules="$rules.cyrillicNonRequired"
@@ -108,7 +108,7 @@
108
108
  />
109
109
  <base-form-input
110
110
  v-model="member.birthDate"
111
- :readonly="isDisabled || isFromGBD"
111
+ :readonly="isDisabled || isFromGBD || !!member.parsedDocument?.birthDate"
112
112
  :clearable="!isDisabled"
113
113
  :label="$dataStore.t('form.birthDate')"
114
114
  :rules="birthDateRule"
@@ -386,7 +386,7 @@
386
386
  <base-form-input
387
387
  v-model.trim="member.documentNumber"
388
388
  :label="$dataStore.t('form.documentNumber')"
389
- :readonly="isDisabled"
389
+ :readonly="isDisabled || !!member.parsedDocument?.documentNumber"
390
390
  :clearable="!isDisabled"
391
391
  :rules="$rules.required"
392
392
  />
@@ -399,7 +399,7 @@
399
399
  v-model="member.documentIssuers"
400
400
  :value="member.documentIssuers?.nameRu"
401
401
  :label="$dataStore.t('form.documentIssuers')"
402
- :readonly="isDisabled"
402
+ :readonly="isDisabled || !!member.parsedDocument?.documentIssuer"
403
403
  :clearable="!isDisabled"
404
404
  :rules="$rules.objectRequired"
405
405
  append-inner-icon="mdi mdi-chevron-right"
@@ -408,7 +408,7 @@
408
408
  <base-form-input
409
409
  v-model="member.documentDate"
410
410
  :label="$dataStore.t('form.documentDate')"
411
- :readonly="isDisabled"
411
+ :readonly="isDisabled || !!member.parsedDocument?.documentIssueDate"
412
412
  :clearable="!isDisabled"
413
413
  :rules="$rules.required.concat($rules.date)"
414
414
  :maska="$maska.date"
@@ -419,7 +419,7 @@
419
419
  v-if="member.documentType.ids !== 'SBI' && member.documentType.ids !== 'VNZ'"
420
420
  v-model="member.documentExpire"
421
421
  :label="$dataStore.t('form.documentExpire')"
422
- :readonly="isDisabled"
422
+ :readonly="isDisabled || !!member.parsedDocument?.documentExpireDate"
423
423
  :clearable="!isDisabled"
424
424
  :rules="$rules.required.concat($rules.date)"
425
425
  :maska="$maska.date"
@@ -538,6 +538,20 @@
538
538
  <base-btn v-if="hasGBDFL" :loading="isButtonLoading" :text="$dataStore.t('buttons.fromGBDFL')" @click="getContragentFromGBDFL" />
539
539
  <base-btn v-if="hasInsis" :loading="isButtonLoading" :text="$dataStore.t('buttons.fromInsis')" @click="getContragent" />
540
540
  <base-btn v-if="hasGKB" :loading="isButtonLoading" :text="$dataStore.t('buttons.fromGKB')" @click="getFamilyInfo" />
541
+ <base-form-section v-if="hasDocumentReader" class="!mt-0">
542
+ <base-file-input
543
+ :disabled="isDisabled"
544
+ :clearable="!isDisabled"
545
+ accept="image/*,.pdf"
546
+ append="mdi-credit-card-scan-outline"
547
+ :multiple="true"
548
+ @onClear="imageDataList = []"
549
+ @input="attachDocumentReader($event)"
550
+ />
551
+ </base-form-section>
552
+ <base-animation>
553
+ <base-btn v-if="hasDocumentReader && imageDataList && !!imageDataList.length" :loading="isButtonLoading" text="Получить данные" @click="getDocumentReader" />
554
+ </base-animation>
541
555
  </div>
542
556
  </Teleport>
543
557
  <Teleport v-if="isDocumentOpen" to="#right-panel-actions">
@@ -620,6 +634,7 @@ export default {
620
634
  const currentPanel = ref<keyof typeof member.value>();
621
635
  const searchQuery = ref<string>('');
622
636
  const fileData = ref<{ file: any }>();
637
+ const imageDataList = ref<string[]>([]);
623
638
 
624
639
  const memberSetting = computed(() => dataStore.members[memberStore.getMemberApplicationCode(whichForm.value)!]);
625
640
  const hasOtp = computed(() => member.value.otpCode && member.value.otpCode.length === useMask().otp.length);
@@ -696,7 +711,10 @@ export default {
696
711
  };
697
712
  return dataStore.controls.hasGKB && !!dataStore.isTask() && perMemberCondition();
698
713
  });
699
- const hasMemberSearch = computed(() => showSaveButton.value && (hasGBDFL.value || hasGKB.value || hasInsis.value));
714
+ const hasDocumentReader = computed(() => {
715
+ return !!member.value.hasAgreement && !!isTask.value && (dataStore.isAULETTI || dataStore.isAulettiParent);
716
+ });
717
+ const hasMemberSearch = computed(() => showSaveButton.value && (hasGBDFL.value || hasGKB.value || hasInsis.value || hasDocumentReader.value));
700
718
  const hasMiddleName = computed(() => {
701
719
  if (dataStore.isLifetrip) {
702
720
  return false;
@@ -834,7 +852,7 @@ export default {
834
852
  const searchMember = async () => {
835
853
  if (!isDisabled.value) {
836
854
  dataStore.panelAction = null;
837
- dataStore.rightPanel.title = 'Поиск контрагента';
855
+ dataStore.rightPanel.title = hasDocumentReader.value ? 'Получение данных со скана документа' : 'Поиск контрагента';
838
856
  dataStore.rightPanel.open = true;
839
857
  isSearchOpen.value = true;
840
858
  isDocumentOpen.value = false;
@@ -959,6 +977,68 @@ export default {
959
977
  }
960
978
  };
961
979
 
980
+ const attachDocumentReader = async (event: InputEvent) => {
981
+ if (event.target) {
982
+ const target = event.target as HTMLInputElement;
983
+ if (target.files && !!target.files.length) {
984
+ imageDataList.value = [];
985
+ await Promise.allSettled(
986
+ Object.values(target.files).map(async f => {
987
+ const { execute: getBase64 } = useBase64(f);
988
+ imageDataList.value.push(await getBase64());
989
+ }),
990
+ );
991
+ }
992
+ } else {
993
+ if (event.dataTransfer) {
994
+ const dataTransfer = event.dataTransfer as DataTransfer;
995
+ if (!!dataTransfer.files && !!dataTransfer.files.length) {
996
+ imageDataList.value = [];
997
+ await Promise.allSettled(
998
+ Object.values(dataTransfer.files).map(async f => {
999
+ const { execute: getBase64 } = useBase64(f);
1000
+ imageDataList.value.push(await getBase64());
1001
+ }),
1002
+ );
1003
+ }
1004
+ }
1005
+ }
1006
+ };
1007
+
1008
+ const getDocumentReader = async () => {
1009
+ if (imageDataList.value && !!imageDataList.value.length) {
1010
+ isButtonLoading.value = true;
1011
+ const parsedDocument = await callDocumentReader(imageDataList.value);
1012
+ if (typeof parsedDocument === 'object') {
1013
+ formatDateProperty(parsedDocument, 'front');
1014
+ member.value.parsedDocument = parsedDocument;
1015
+ if (parsedDocument.age) member.value.age = parsedDocument.age;
1016
+ if (parsedDocument.iin) member.value.iin = reformatIin(parsedDocument.iin);
1017
+ if (parsedDocument.birthDate) member.value.birthDate = parsedDocument.birthDate;
1018
+ if (parsedDocument.documentIssueDate) member.value.documentDate = parsedDocument.documentIssueDate;
1019
+ if (parsedDocument.documentExpireDate) member.value.documentExpire = parsedDocument.documentExpireDate;
1020
+ if (parsedDocument.documentNumber) member.value.documentNumber = parsedDocument.documentNumber;
1021
+ if (parsedDocument.lastName) member.value.lastName = parsedDocument.lastName;
1022
+ if (parsedDocument.firstName) member.value.firstName = parsedDocument.firstName;
1023
+ if (parsedDocument.middleName) member.value.middleName = parsedDocument.middleName;
1024
+ if (parsedDocument.fullName) member.value.longName = parsedDocument.fullName;
1025
+ if (!!parsedDocument.documentIssuer) {
1026
+ if (parsedDocument.documentIssuer === 'МИНИСТЕРСТВО ВНУТРЕННИХ ДЕЛ РК' || parsedDocument.documentIssuer === 'ҚР ІШКІ ІСТЕР МИНИСТРЛІГІ') {
1027
+ const documentIssuer = dataStore.documentIssuers.find(i => (i.nameRu as string).match(new RegExp('МВД РК', 'i')));
1028
+ if (documentIssuer) member.value.documentIssuers = documentIssuer;
1029
+ } else {
1030
+ const documentIssuer = dataStore.documentIssuers.find(i => (i.nameRu as string).match(new RegExp(`${parsedDocument.documentIssuer}`, 'i')));
1031
+ if (documentIssuer) member.value.documentIssuers = documentIssuer;
1032
+ }
1033
+ }
1034
+ dataStore.rightPanel.open = false;
1035
+ dataStore.showToaster('success', dataStore.t('toaster.successOperation'));
1036
+ imageDataList.value = [];
1037
+ }
1038
+ isButtonLoading.value = false;
1039
+ }
1040
+ };
1041
+
962
1042
  const getFile = async (type: FileActions) => {
963
1043
  if (memberDocument.value) {
964
1044
  documentLoading.value = true;
@@ -1498,6 +1578,7 @@ export default {
1498
1578
  selectedIndex,
1499
1579
  selectedFamilyMember,
1500
1580
  sameAddress,
1581
+ imageDataList,
1501
1582
 
1502
1583
  // Computed
1503
1584
  whichForm,
@@ -1513,6 +1594,7 @@ export default {
1513
1594
  hasGBDFL,
1514
1595
  hasInsis,
1515
1596
  hasGKB,
1597
+ hasDocumentReader,
1516
1598
  hasMiddleName,
1517
1599
  hasRelationDegree,
1518
1600
  hasFamilyStatus,
@@ -1539,6 +1621,8 @@ export default {
1539
1621
  getContragentFromGBDFL,
1540
1622
  getContragent,
1541
1623
  attachFile,
1624
+ attachDocumentReader,
1625
+ getDocumentReader,
1542
1626
  getFile,
1543
1627
  selectFamilyMember,
1544
1628
  closeFamilyDialog,
@@ -460,7 +460,10 @@
460
460
  <base-form-input v-model="calculatorForm.price" :readonly="true" :label="isCalculator ? $dataStore.t('calculatorForm.premium') : $dataStore.t('calculatorForm.price')" />
461
461
  </base-form-section>
462
462
  <base-form-section v-if="hasDeathInsFromNS" :title="$dataStore.t('generalConditions')">
463
- <base-form-input v-model="deathInsFromNS" :readonly="true" :clearable="false" :label="$dataStore.t('form.deathInsFromNS')" />
463
+ <base-form-input v-model="enabled" :readonly="true" :clearable="false" :label="$dataStore.t('form.deathInsFromNS')" />
464
+ </base-form-section>
465
+ <base-form-section v-if="hasDeathInsAnyReason" :title="$dataStore.t('generalConditions')">
466
+ <base-form-input v-model="enabled" :readonly="true" :clearable="false" :label="$dataStore.t('form.deathInsAnyReason')" />
464
467
  </base-form-section>
465
468
  <base-form-section v-if="isShownAdditionalTerms && additionalTerms && additionalTerms.length" :title="$dataStore.t('productConditionsForm.additional')">
466
469
  <div v-for="(term, index) of additionalTerms" :key="index">
@@ -589,14 +592,14 @@ export default defineComponent({
589
592
  const termValue = ref<AddCover>();
590
593
  const subTermValue = ref<string>('');
591
594
  const panelList = ref<Value[]>([]);
592
- const subPanelList = ref<Value[]>([]);
595
+ const subPanelList = ref<AddCoverAnswer[] | Value[]>([]);
593
596
  const productConditionsForm = formStore.productConditionsForm;
594
597
  const currentPanel = ref<keyof typeof productConditionsForm>();
595
598
  const currentIndex = ref<number>();
596
599
  const searchQuery = ref<string>('');
597
600
  const whichSum = ref<'insurancePremiumPerMonth' | 'requestedSumInsured' | ''>('');
598
601
  const panelCodeList = ['processcovertypesum', 'fixedinssum'];
599
- const deathInsFromNS = 'Включено';
602
+ const enabled = 'включено';
600
603
 
601
604
  const additionalTerms = ref<AddCover[]>([]);
602
605
 
@@ -880,8 +883,14 @@ export default defineComponent({
880
883
  }
881
884
  return false;
882
885
  });
886
+ const hasDeathInsAnyReason = computed(() => {
887
+ if (whichProduct.value === 'lifebusiness') {
888
+ return true;
889
+ }
890
+ return false;
891
+ });
883
892
  const defaultText = computed(() => {
884
- if (whichProduct.value === 'gns') {
893
+ if (whichProduct.value === 'gns' || whichProduct.value === 'lifebusiness') {
885
894
  return dataStore.t('clients.form.calculation');
886
895
  }
887
896
  return dataStore.t('generalConditions');
@@ -985,9 +994,11 @@ export default defineComponent({
985
994
  }
986
995
 
987
996
  if (termValue.value && termValue.value.coverTypeCode === 6 && item.code === 'processcovertypesum') {
988
- const response = await dataStore.getFromApi('DicCoverTypePeriod', 'getArmDicts', 'DicCoverTypePeriod');
989
- subPanelList.value = response;
990
- subTermValue.value = termValue.value.coverPeriodCode as string;
997
+ const response = await dataStore.getProcessCoverTypePeriod(termValue.value.coverTypeId);
998
+ if (response) {
999
+ subPanelList.value = response;
1000
+ subTermValue.value = termValue.value.coverPeriodCode as string;
1001
+ }
991
1002
  }
992
1003
 
993
1004
  if (termValue.value && termValue.value.coverTypeCode === 6 && item.code !== 'processcovertypesum') {
@@ -1107,7 +1118,7 @@ export default defineComponent({
1107
1118
  }
1108
1119
  };
1109
1120
 
1110
- const pickSubTermValue = (item: Value, subItem: Value) => {
1121
+ const pickSubTermValue = (item: any, subItem: any) => {
1111
1122
  dataStore.rightPanel.open = false;
1112
1123
  isTermsPanelOpen.value = false;
1113
1124
  subTermValue.value = item.code as string;
@@ -1554,7 +1565,7 @@ export default defineComponent({
1554
1565
  subPanelList,
1555
1566
  subTermValue,
1556
1567
  panelCodeList,
1557
- deathInsFromNS,
1568
+ enabled,
1558
1569
 
1559
1570
  // Computed
1560
1571
  isTask,
@@ -1601,6 +1612,7 @@ export default defineComponent({
1601
1612
  isDisabledFixInsSum,
1602
1613
  defaultText,
1603
1614
  hasDeathInsFromNS,
1615
+ hasDeathInsAnyReason,
1604
1616
 
1605
1617
  // Rules
1606
1618
  coverPeriodRule,
@@ -53,7 +53,7 @@
53
53
  <base-form-section :title="''">
54
54
  <base-loader v-if="isQrLoading" class="self-center m-5 opacity-70" />
55
55
  <div v-if="qrUrl && !isQrLoading">
56
- <img width="135" height="135" class="ma-auto" :src="qrUrl" alt="" />
56
+ <base-qr :value="qrUrl" :size="200" class="ma-auto rounded" />
57
57
  <span :class="[$styles.textSimple]" class="mt-3 text-center d-block">{{ $dataStore.t('sign.scanQrCode') }}</span>
58
58
  </div>
59
59
  <base-btn class="mt-10" :loading="loading" :text="$dataStore.t('sign.copyEgov')" @click="$dataStore.copyToClipboard(urlCopy)" />
@@ -80,6 +80,7 @@
80
80
  <section class="flex flex-col gap-4 py-3" :class="$styles.textSimple">
81
81
  <base-btn :loading="loading" :text="$dataStore.t('sign.copyCloud')" @click="$dataStore.copyToClipboard(signUrl.uri)" />
82
82
  <base-btn :loading="loading" :btn="$styles.blueLightBtn" :text="$dataStore.t('sign.recipientNumber')" @click="openSmsPanel(signUrl)" />
83
+ <base-btn :loading="loading" :text="$dataStore.t('sign.convertQr')" @click="convertQr(signUrl.uri)" />
83
84
  </section>
84
85
  </v-expansion-panel-text>
85
86
  </v-expansion-panel>
@@ -110,6 +111,7 @@
110
111
  <div v-if="!isSendNumberOpen" :class="[$styles.flexColNav]">
111
112
  <base-btn :loading="loading" :text="$dataStore.t('payment.copyUrl')" @click="$dataStore.copyToClipboard(formStore.epayLink)" />
112
113
  <base-btn :loading="loading" :btn="$styles.blueLightBtn" :text="$dataStore.t('payment.recipientNumber')" @click="openEpayPanel" />
114
+ <base-btn :loading="loading" :text="$dataStore.t('sign.convertQr')" @click="convertQr(formStore.epayLink)" />
113
115
  </div>
114
116
  <div v-if="isSendNumberOpen" :class="[$styles.flexColNav]">
115
117
  <i
@@ -154,6 +156,13 @@
154
156
  <base-btn :text="buttonText" :loading="loading" @click="submitForm" />
155
157
  </div>
156
158
  </section>
159
+ <v-dialog v-model="isQrDialog" width="auto">
160
+ <v-card>
161
+ <v-card-text class="!p-4">
162
+ <base-qr :value="qrUrl" class="rounded" :size="300" />
163
+ </v-card-text>
164
+ </v-card>
165
+ </v-dialog>
157
166
  </template>
158
167
 
159
168
  <script lang="ts">
@@ -179,6 +188,7 @@ export default defineComponent({
179
188
  const urlCopy = ref<string>('');
180
189
  const isEpayPay = ref<boolean>(false);
181
190
  const isOfflinePay = ref<boolean>(false);
191
+ const isQrDialog = ref<boolean>(false);
182
192
 
183
193
  const vForm = ref<any>();
184
194
  const isSendNumberOpen = ref<boolean>(false);
@@ -476,12 +486,10 @@ export default defineComponent({
476
486
  loading.value = false;
477
487
  };
478
488
 
479
- // TODO Рефактор QR c npm
480
489
  const generateQR = async (groupId: string) => {
481
490
  const uuidV4 = uuid.v4();
482
491
  const qrValue = `${getStrValuePerEnv('qrGenUrl')}/${uuidV4}/${groupId}`;
483
- qrUrl.value = `https://api.qrserver.com/v1/create-qr-code/?size=135x135&data=${qrValue}`;
484
-
492
+ qrUrl.value = qrValue;
485
493
  if (dataStore.isLifeBusiness || dataStore.isGns) {
486
494
  //для юр лиц
487
495
  urlCopy.value = `https://egovbusiness.page.link/?link=${qrValue}?mgovSign&amp;apn=kz.mobile.mgov.business&amp;isi=1597880144&amp;ibi=kz.mobile.mgov.business`;
@@ -536,6 +544,15 @@ export default defineComponent({
536
544
  await dataStore.generateDocument();
537
545
  };
538
546
 
547
+ const convertQr = (url: string | null) => {
548
+ if (url) {
549
+ qrUrl.value = url;
550
+ isQrDialog.value = true;
551
+ } else {
552
+ dataStore.showToaster('error', dataStore.t('toaster.noUrl'));
553
+ }
554
+ };
555
+
539
556
  const payEpay = async () => {
540
557
  const invoiceData = await dataStore.getInvoiceData(formStore.applicationData.processInstanceId);
541
558
  if (invoiceData === false || invoiceData.status === 3 || invoiceData.status === 0) {
@@ -586,6 +603,7 @@ export default defineComponent({
586
603
  urlCopy,
587
604
  isEpayPay,
588
605
  isOfflinePay,
606
+ isQrDialog,
589
607
 
590
608
  // Functions
591
609
  closePanel,
@@ -601,6 +619,7 @@ export default defineComponent({
601
619
  closeQrPanel,
602
620
  handlePayAction,
603
621
  payEpay,
622
+ convertQr,
604
623
 
605
624
  // Computed
606
625
  buttonText,
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <qrcode-vue v-if="!!value" :value="value" :size="size" :level="level" :margin="margin" :render-as="renderAs" :background="background" :foreground="foreground" />
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import QrcodeVue from 'qrcode.vue';
7
+
8
+ export default defineComponent({
9
+ components: {
10
+ QrcodeVue,
11
+ },
12
+ props: {
13
+ value: {
14
+ type: String,
15
+ default: '',
16
+ required: true,
17
+ },
18
+ size: {
19
+ type: Number,
20
+ default: 250,
21
+ },
22
+ renderAs: {
23
+ type: String as PropType<'canvas' | 'svg'>,
24
+ default: 'canvas',
25
+ },
26
+ margin: {
27
+ type: Number,
28
+ default: 0,
29
+ },
30
+ level: {
31
+ type: String as PropType<'L' | 'M' | 'Q' | 'H'>,
32
+ default: 'M',
33
+ },
34
+ background: {
35
+ type: String,
36
+ default: '#ffffff',
37
+ },
38
+ foreground: {
39
+ type: String,
40
+ default: '#000000',
41
+ },
42
+ },
43
+ });
44
+ </script>
@@ -447,6 +447,7 @@ export class Member extends Person {
447
447
  _emailPattern: RegExp;
448
448
  gotFromInsis: boolean | null;
449
449
  gosPersonData: any;
450
+ parsedDocument: any;
450
451
  hasAgreement: boolean | null;
451
452
  otpTokenId: string | null;
452
453
  otpCode: string | null;
@@ -582,6 +583,7 @@ export class Member extends Person {
582
583
  this._emailPattern = /.+@.+\..+/;
583
584
  this.gotFromInsis = true;
584
585
  this.gosPersonData = null;
586
+ this.parsedDocument = null;
585
587
  this.hasAgreement = null;
586
588
  }
587
589
 
@@ -625,6 +627,7 @@ export class Member extends Person {
625
627
  this.percentageOfPayoutAmount = null;
626
628
  this.gotFromInsis = true;
627
629
  this.gosPersonData = null;
630
+ this.parsedDocument = null;
628
631
  this.hasAgreement = null;
629
632
  this.insurancePay = new Value();
630
633
  this.migrationCard = null;
@@ -2,6 +2,7 @@ import { useDisplay } from 'vuetify';
2
2
  import jwt_decode from 'jwt-decode';
3
3
  import { XMLParser } from 'fast-xml-parser';
4
4
  import { AxiosError } from 'axios';
5
+ import { DocumentReaderApi, Scenario, TextFieldType } from '@regulaforensics/document-reader-webclient';
5
6
  import { PolicyholderClass } from '../composables/classes';
6
7
 
7
8
  export const getBaseCredentials = () => {
@@ -382,3 +383,76 @@ export const keyDeleter = <T extends object>(data: T, keys: Array<NestedKeyOf<T>
382
383
  });
383
384
  }
384
385
  };
386
+
387
+ export const formatDateProperty = (item: any, to: 'front' | 'back', additionalKeys?: string[]) => {
388
+ try {
389
+ if (item) {
390
+ Object.keys(item).forEach((key: string) => {
391
+ if (item[key] === Object(item[key])) {
392
+ formatDateProperty(item[key], to);
393
+ } else {
394
+ if (Array.isArray(additionalKeys)) {
395
+ additionalKeys.forEach(k => {
396
+ if (String(key).includes(k) && typeof item[key] === 'string' && !!item[key]) {
397
+ item[key] = to === 'front' ? reformatDate(item[key]) : formatDate(item[key])!.toISOString();
398
+ }
399
+ });
400
+ }
401
+ if ((String(key).includes('date') || String(key).includes('Date')) && typeof item[key] === 'string' && !!item[key]) {
402
+ item[key] = to === 'front' ? reformatDate(item[key]) : formatDate(item[key])!.toISOString();
403
+ }
404
+ }
405
+ });
406
+ }
407
+ } catch (err) {
408
+ console.log(err);
409
+ }
410
+ };
411
+
412
+ export const callDocumentReader = async (imageBase64: string | string[]) => {
413
+ if (!imageBase64) return false;
414
+ const dataStore = useDataStore();
415
+ try {
416
+ const api = new DocumentReaderApi({ basePath: 'http://10.176.49.47:8080' });
417
+ const result = await api.process({
418
+ images: Array.isArray(imageBase64) ? imageBase64 : [imageBase64],
419
+ processParam: { scenario: Scenario.FULL_PROCESS, doublePageSpread: true, measureSystem: 0 },
420
+ });
421
+ if (result.text) {
422
+ const iin = result.text.getField(TextFieldType.PERSONAL_NUMBER);
423
+ const lastName = result.text.getField(TextFieldType.SURNAME);
424
+ const firstName = result.text.getField(TextFieldType.GIVEN_NAMES_RUS) ?? result.text.getField(TextFieldType.GIVEN_NAMES);
425
+ const middleName = result.text.getField(TextFieldType.FATHERS_NAME_RUS) ?? result.text.getField(TextFieldType.FATHERS_NAME);
426
+ const fullName = result.text.getField(TextFieldType.SURNAME_AND_GIVEN_NAMES);
427
+ const birthDate = result.text.getField(TextFieldType.DATE_OF_BIRTH);
428
+ const age = result.text.getField(TextFieldType.AGE);
429
+ const documentNumber = result.text.getField(TextFieldType.DOCUMENT_NUMBER);
430
+ const documentIssuer = result.text.getField(TextFieldType.AUTHORITY_RUS) ?? result.text.getField(TextFieldType.AUTHORITY);
431
+ const documentIssueDate = result.text.getField(TextFieldType.DATE_OF_ISSUE);
432
+ const documentExpireDate = result.text.getField(TextFieldType.DATE_OF_EXPIRY);
433
+ const parsedDocument = {
434
+ iin: iin?.value,
435
+ lastName: lastName?.value,
436
+ firstName: firstName?.value,
437
+ middleName: middleName?.value,
438
+ fullName: fullName?.value,
439
+ birthDate: birthDate?.value,
440
+ age: age?.value,
441
+ documentNumber: documentNumber?.value,
442
+ documentIssuer: documentIssuer?.value,
443
+ documentIssueDate: documentIssueDate?.value,
444
+ documentExpireDate: documentExpireDate?.value,
445
+ };
446
+ if (Object.values(parsedDocument).every(i => !i)) {
447
+ dataStore.showToaster('error', dataStore.t('toaster.notParsedDocument'));
448
+ return false;
449
+ }
450
+ return parsedDocument;
451
+ } else {
452
+ dataStore.showToaster('error', dataStore.t('toaster.notParsedDocument'));
453
+ }
454
+ return false;
455
+ } catch (err) {
456
+ return ErrorHandler(err);
457
+ }
458
+ };
package/locales/ru.json CHANGED
@@ -136,7 +136,8 @@
136
136
  "needAttachQuestionnaire": "Нужно вложить анкету для клиентов",
137
137
  "notZeroPremium": "Общая страховая премия не должен быть 0",
138
138
  "requiredFieldsLB": "Обязательные поля: №, Ф.И.О, Пол, Должность, Дата рождения, ИИН, Страховая сумма",
139
- "duplicateClient": "В списке присутствуют повторяющиеся клиенты"
139
+ "duplicateClient": "В списке присутствуют повторяющиеся клиенты",
140
+ "notParsedDocument": "Не удалось получить данные"
140
141
  },
141
142
  "notSignedContract": "Неподписанный Договор",
142
143
  "Contract": "Договор страхования",
@@ -276,7 +277,8 @@
276
277
  "timer": "Вы создали счет на оплату, через 00:59 сек счет станет не активным",
277
278
  "copyEgov": "Скопировать ссылку на подпись через Egov",
278
279
  "scanQrCode": "Отсканируйте этот QR-код в приложении, чтобы осуществить подписание",
279
- "successQrSigned": "Заявление и Договор подписаны Страхователем"
280
+ "successQrSigned": "Заявление и Договор подписаны Страхователем",
281
+ "convertQr": "Преобразовать в QR код"
280
282
  },
281
283
  "questionnaireType": {
282
284
  "byHealth": "Анкета по здоровью Застрахованного",
@@ -382,6 +384,7 @@
382
384
  "totalRequestedSumInsured": "Общая страховая сумма",
383
385
  "totalInsurancePremiumAmount": "Общая страховая премия",
384
386
  "totalInsurancePremiumAmountWithCommission": "Общая страховая премия с комиссией",
387
+ "totalInsurancePremiumAmountWithAgent": "Общая страховая премия с агентской частью",
385
388
  "agencyPart": "Агентская переменная часть, %",
386
389
  "processGfot": "Кратность страховой суммы к ГФОТ-у",
387
390
  "annuiteStartDate": "Дата расчета",
@@ -896,7 +899,8 @@
896
899
  "identityCardOfContactPerson": "Документ удостоверяющий личность Контактного лица Застрахованного",
897
900
  "recipientDocs": "Документы Получателя",
898
901
  "recipientData": "Сведения о Получателе",
899
- "deathInsFromNS": "Страхование от смерти от НС"
902
+ "deathInsFromNS": "Страхование от смерти от НС",
903
+ "deathInsAnyReason": "Смерть Застрахованного по любой причине"
900
904
  },
901
905
  "bankDetailsForm": {
902
906
  "title": "Банковские реквизиты",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hl-core",
3
- "version": "0.0.9-beta.48",
3
+ "version": "0.0.9-beta.49",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "main": "nuxt.config.ts",
@@ -51,9 +51,10 @@
51
51
  "dependencies": {
52
52
  "@intlify/unplugin-vue-i18n": "0.12.2",
53
53
  "@mdi/font": "7.3.67",
54
- "@microsoft/signalr": "^7.0.12",
54
+ "@microsoft/signalr": "7.0.12",
55
55
  "@nuxtjs/tailwindcss": "6.8.0",
56
56
  "@pinia/nuxt": "0.4.11",
57
+ "@regulaforensics/document-reader-webclient": "6.9.5",
57
58
  "@vuepic/vue-datepicker": "7.2.0",
58
59
  "animate.css": "4.1.1",
59
60
  "axios": "1.4.0",
@@ -61,6 +62,7 @@
61
62
  "jwt-decode": "3.1.2",
62
63
  "maska": "1.5.0",
63
64
  "pinia": "2.1.4",
65
+ "qrcode.vue": "3.4.1",
64
66
  "typedoc": "0.24.8",
65
67
  "typescript": "5.0.4",
66
68
  "vue-i18n": "9.2.2",
@@ -237,6 +237,9 @@ export const useDataStore = defineStore('data', {
237
237
  isHeadManager() {
238
238
  return this.isRole(constants.roles.HeadManager);
239
239
  },
240
+ isBranchDirector() {
241
+ return this.isRole(constants.roles.BranchDirector);
242
+ },
240
243
  isProcessEditable(statusCode?: keyof typeof Statuses) {
241
244
  const getEditibleStatuses = () => {
242
245
  const defaultStatuses = constants.editableStatuses;
@@ -1112,6 +1115,16 @@ export const useDataStore = defineStore('data', {
1112
1115
  }
1113
1116
  return null;
1114
1117
  },
1118
+ async getProcessCoverTypePeriod(questionId: string) {
1119
+ if (!this.processCode) return null;
1120
+ try {
1121
+ const answers = await this.api.getProcessCoverTypePeriod(this.processCode, questionId);
1122
+ return answers;
1123
+ } catch (err) {
1124
+ console.log(err);
1125
+ }
1126
+ return null;
1127
+ },
1115
1128
  async definedAnswers(
1116
1129
  filter: string,
1117
1130
  whichSurvey: 'surveyByHealthBase' | 'surveyByHealthBasePolicyholder' | 'surveyByCriticalBase' | 'surveyByCriticalBasePolicyholder',
@@ -1341,20 +1354,6 @@ export const useDataStore = defineStore('data', {
1341
1354
  }
1342
1355
  return this.cities;
1343
1356
  },
1344
- async getCitiesEfo(key?: string, member?: any, parentKey?: string) {
1345
- if (this.isLifeBusiness || this.isGns) {
1346
- await this.getFromApi('cities', 'getCities');
1347
- //@ts-ignore
1348
- if (key && member[parentKey][key] && member[parentKey][key].ids !== null) return this.cities.filter(i => i.code === member[parentKey][key].ids);
1349
- //@ts-ignore
1350
- if (member && member[parentKey].registrationProvince.ids !== null) {
1351
- //@ts-ignore
1352
- return this.cities.filter(i => i.code === member[parentKey].registrationProvince.ids);
1353
- } else {
1354
- return this.cities;
1355
- }
1356
- }
1357
- },
1358
1357
  async getLocalityTypes() {
1359
1358
  return await this.getFromApi('localityTypes', 'getLocalityTypes');
1360
1359
  },
@@ -1453,7 +1452,6 @@ export const useDataStore = defineStore('data', {
1453
1452
  this.getStates(),
1454
1453
  this.getRegions(),
1455
1454
  this.getCities(),
1456
- this.getCitiesEfo(),
1457
1455
  this.getLocalityTypes(),
1458
1456
  this.getDocumentTypes(),
1459
1457
  this.getDocumentIssuers(),
@@ -2249,7 +2247,7 @@ export const useDataStore = defineStore('data', {
2249
2247
  try {
2250
2248
  const data = {
2251
2249
  taskId: taskId,
2252
- decision: decision,
2250
+ decision: decision.replace(/custom/i, '') as keyof typeof constants.actions,
2253
2251
  };
2254
2252
  await this.api.sendTask(comment === null ? data : { ...data, comment: comment });
2255
2253
  this.showToaster('success', this.t('toaster.successOperation'), 3000);
@@ -2443,10 +2441,10 @@ export const useDataStore = defineStore('data', {
2443
2441
  link.setAttribute('download', 'РФ-ДС-028 Список застрахованных ГССЖ_ГНС, изд.1.xls');
2444
2442
  break;
2445
2443
  case constants.documentTypes.statement:
2446
- link.setAttribute('download', 'Заявление.docx');
2444
+ link.setAttribute('download', 'Заявление.pdf');
2447
2445
  break;
2448
2446
  case constants.documentTypes.contract:
2449
- link.setAttribute('download', 'Договор страхования.doc');
2447
+ link.setAttribute('download', 'Договор страхования.pdf');
2450
2448
  break;
2451
2449
  case constants.documentTypes.application1:
2452
2450
  link.setAttribute('download', 'Приложение №1.xls');
@@ -3573,7 +3571,8 @@ export const useDataStore = defineStore('data', {
3573
3571
  this.isFinCenter() ||
3574
3572
  this.isSupervisor() ||
3575
3573
  this.isSupport() ||
3576
- this.isDrn(),
3574
+ this.isDrn() ||
3575
+ this.isBranchDirector(),
3577
3576
  };
3578
3577
  },
3579
3578
  },
package/types/enum.ts CHANGED
@@ -83,6 +83,7 @@ export enum Roles {
83
83
  DRNSJ = 'DRNSJ',
84
84
  HeadManager = 'HeadManager',
85
85
  AgentAuletti = 'AgentAuletti',
86
+ BranchDirector = 'BranchDirector',
86
87
  }
87
88
 
88
89
  export enum Statuses {