hl-core 0.0.9-beta.5 → 0.0.9-beta.50

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 (63) hide show
  1. package/api/base.api.ts +935 -0
  2. package/api/index.ts +2 -620
  3. package/api/interceptors.ts +53 -14
  4. package/components/Button/Btn.vue +2 -2
  5. package/components/Complex/MessageBlock.vue +2 -2
  6. package/components/Complex/Page.vue +1 -1
  7. package/components/Dialog/Dialog.vue +60 -15
  8. package/components/Form/DynamicForm.vue +100 -0
  9. package/components/Form/FormBlock.vue +12 -3
  10. package/components/Form/FormData.vue +110 -0
  11. package/components/Form/FormSection.vue +3 -3
  12. package/components/Form/FormToggle.vue +25 -5
  13. package/components/Form/ManagerAttachment.vue +150 -86
  14. package/components/Form/ProductConditionsBlock.vue +59 -6
  15. package/components/Input/Datepicker.vue +39 -8
  16. package/components/Input/DynamicInput.vue +23 -0
  17. package/components/Input/FileInput.vue +25 -5
  18. package/components/Input/FormInput.vue +2 -4
  19. package/components/Input/Monthpicker.vue +34 -0
  20. package/components/Input/PanelInput.vue +5 -1
  21. package/components/Input/RoundedEmptyField.vue +5 -0
  22. package/components/Input/RoundedSelect.vue +13 -0
  23. package/components/Input/SwitchInput.vue +64 -0
  24. package/components/Input/TextInput.vue +160 -0
  25. package/components/Layout/Drawer.vue +17 -4
  26. package/components/Layout/Header.vue +23 -2
  27. package/components/Layout/Loader.vue +1 -1
  28. package/components/Layout/SettingsPanel.vue +13 -7
  29. package/components/Menu/InfoMenu.vue +35 -0
  30. package/components/Menu/MenuNav.vue +17 -2
  31. package/components/Pages/Anketa.vue +140 -52
  32. package/components/Pages/Auth.vue +42 -7
  33. package/components/Pages/ContragentForm.vue +124 -50
  34. package/components/Pages/Documents.vue +72 -7
  35. package/components/Pages/InvoiceInfo.vue +1 -1
  36. package/components/Pages/MemberForm.vue +369 -100
  37. package/components/Pages/ProductAgreement.vue +1 -8
  38. package/components/Pages/ProductConditions.vue +888 -181
  39. package/components/Panel/PanelHandler.vue +414 -45
  40. package/components/Panel/PanelSelectItem.vue +17 -2
  41. package/components/Panel/RightPanelCloser.vue +7 -0
  42. package/components/Transitions/Animation.vue +28 -0
  43. package/components/Utilities/Qr.vue +44 -0
  44. package/composables/axios.ts +1 -0
  45. package/composables/classes.ts +433 -8
  46. package/composables/constants.ts +102 -2
  47. package/composables/fields.ts +328 -0
  48. package/composables/index.ts +257 -12
  49. package/composables/styles.ts +29 -16
  50. package/layouts/default.vue +48 -3
  51. package/locales/ru.json +480 -14
  52. package/package.json +27 -24
  53. package/pages/Token.vue +1 -12
  54. package/plugins/vuetifyPlugin.ts +2 -0
  55. package/store/data.store.ts +1190 -248
  56. package/store/extractStore.ts +17 -0
  57. package/store/form.store.ts +13 -1
  58. package/store/member.store.ts +1 -1
  59. package/store/rules.ts +66 -5
  60. package/types/enum.ts +43 -0
  61. package/types/env.d.ts +1 -0
  62. package/types/form.ts +94 -0
  63. package/types/index.ts +254 -21
@@ -17,56 +17,101 @@
17
17
  >{{ `Запрашиваемая страховая сумма: ` }} <b>{{ `${requestedSumInsured}₸` }}</b>
18
18
  </span>
19
19
  </base-content-block>
20
+ <base-content-block v-if="$dataStore.isLifetrip" class="flex flex-col gap-3">
21
+ <span
22
+ >{{ `Стоимость на страховую сумму ${insuredAmount}:` }} <b>{{ `${price}₸` }}</b></span
23
+ >
24
+ </base-content-block>
20
25
  <base-btn :text="$dataStore.t('confirm.yes')" @click="handleTask" />
21
26
  <base-btn :btn="$styles.blueLightBtn" :text="$dataStore.t('confirm.no')" @click="closePanel" />
22
27
  </div>
23
28
  </section>
24
- <section v-if="signingActions" class="relative">
25
- <div>
26
- <base-fade-transition>
27
- <div v-if="!isSendNumberOpen" :class="[$styles.flexColNav]">
28
- <div :class="[$styles.blueBgLight]" class="rounded-lg p-4">
29
- <v-expansion-panels v-if="formStore.signUrls && formStore.signUrls.length" variant="accordion" multiple>
30
- <v-expansion-panel v-for="signUrl of formStore.signUrls" :key="signUrl.iin!" class="border-[1px]" elevation="0" bg-color="#FFF">
31
- <v-expansion-panel-title class="h-[80px]" :class="$styles.textTitle">{{ `${signUrl.longName} - ${signUrl.iin}` }}</v-expansion-panel-title>
32
- <v-expansion-panel-text class="border-t-[1px]">
33
- <section class="flex flex-col gap-4 py-3" :class="$styles.textSimple">
34
- <base-btn :loading="loading" :text="$dataStore.t('sign.copyCloud')" @click="$dataStore.copyToClipboard(signUrl.uri)" />
35
- <base-btn :loading="loading" :btn="$styles.blueLightBtn" :text="$dataStore.t('sign.recipientNumber')" @click="openSmsPanel(signUrl)" />
36
- </section>
37
- </v-expansion-panel-text>
38
- </v-expansion-panel>
39
- </v-expansion-panels>
40
- <base-list-empty v-else />
41
- </div>
42
- </div>
43
- <div v-if="isSendNumberOpen" :class="[$styles.flexColNav]">
44
- <i
45
- class="mdi mdi-arrow-left cursor-pointer absolute text-xl left-0 top-0 rounded-br-full bg-white border-[1px] pb-3 pt-1 pl-1 pr-3"
46
- @click="isSendNumberOpen = false"
47
- ></i>
48
- <base-form-section :title="selectedClient && selectedClient.longName ? selectedClient.longName : ''">
49
- <v-form ref="vForm">
50
- <base-rounded-input
51
- v-model="phoneNumber"
52
- :maska="$maska.phone"
53
- :rules="$rules.required.concat($rules.phoneFormat)"
54
- :label="$dataStore.t('form.phoneNumber')"
55
- placeholder="+7 7"
56
- />
57
- </v-form>
58
- <base-btn :text="$dataStore.t('buttons.sendSMS')" :loading="loading" @click="submitForm"
59
- /></base-form-section>
29
+ <section v-if="chooseSignActions">
30
+ <div v-if="!isElectronicContract && !isPaperContract && !isScansDocuments && !isQr" :class="[$styles.flexColNav]">
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
+ </div>
36
+ <div v-if="isPaperContract" :class="[$styles.flexColNav]">
37
+ <base-btn :text="$dataStore.t('buttons.downloadContract')" :loading="$dataStore.isButtonsLoading" @click="generateDocument" />
38
+ </div>
39
+ <div v-if="isScansDocuments" :class="[$styles.flexColNav]">
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')" />
43
+ <base-form-section class="mt-4 flex flex-col !gap-2" :title="$dataStore.t('clients.attachScansSignDocs')">
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')" />
48
+ </base-form-section>
49
+ <base-btn :text="$dataStore.t('buttons.sign')" :loading="$dataStore.isButtonsLoading" @click="sendFiles" />
50
+ <base-btn :text="$dataStore.t('buttons.cancel')" :btn="$styles.whiteBtn" @click="isScansDocuments = false" />
51
+ </div>
52
+ <div v-if="isQr" :class="[$styles.flexColNav]">
53
+ <base-form-section :title="''">
54
+ <base-loader v-if="isQrLoading" class="self-center m-5 opacity-70" />
55
+ <div v-if="qrUrl && !isQrLoading">
56
+ <base-qr :value="qrUrl" :size="200" class="ma-auto rounded" />
57
+ <span :class="[$styles.textSimple]" class="mt-3 text-center d-block">{{ $dataStore.t('sign.scanQrCode') }}</span>
60
58
  </div>
61
- </base-fade-transition>
59
+ <base-btn class="mt-10" :loading="loading" :text="$dataStore.t('sign.copyEgov')" @click="$dataStore.copyToClipboard(urlCopy)" />
60
+ <base-btn :text="$dataStore.t('buttons.cancel')" :btn="$styles.whiteBtn" @click="closeQrPanel" />
61
+ </base-form-section>
62
+ </div>
63
+ </section>
64
+ <section v-if="choosePayActions">
65
+ <div v-if="!isEpayPay && !isOfflinePay" :class="[$styles.flexColNav]">
66
+ <base-btn :text="$dataStore.t('buttons.payEpay')" :loading="loading" @click="handlePayAction('epay')" />
67
+ <base-btn :text="$dataStore.t('buttons.payOffline')" :loading="loading" @click="handlePayAction('offline')" />
62
68
  </div>
63
69
  </section>
70
+ <section v-if="signingActions" class="relative">
71
+ <base-fade-transition>
72
+ <div v-if="!isSendNumberOpen" :class="[$styles.flexColNav]">
73
+ <div :class="[$styles.blueBgLight]" class="rounded-lg p-4">
74
+ <v-expansion-panels v-if="formStore.signUrls && formStore.signUrls.length" variant="accordion" multiple>
75
+ <v-expansion-panel v-for="signUrl of formStore.signUrls" :key="signUrl.iin!" class="border-[1px]" elevation="0" bg-color="#FFF">
76
+ <v-expansion-panel-title class="h-[80px]" :class="$styles.textTitle">
77
+ {{ `${signUrl.longName} - ${signUrl.iin}` }}
78
+ </v-expansion-panel-title>
79
+ <v-expansion-panel-text class="border-t-[1px]">
80
+ <section class="flex flex-col gap-4 py-3" :class="$styles.textSimple">
81
+ <base-btn :loading="loading" :text="$dataStore.t('sign.copyCloud')" @click="$dataStore.copyToClipboard(signUrl.uri)" />
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)" />
84
+ </section>
85
+ </v-expansion-panel-text>
86
+ </v-expansion-panel>
87
+ </v-expansion-panels>
88
+ <base-list-empty v-else />
89
+ </div>
90
+ </div>
91
+ <div v-if="isSendNumberOpen" :class="[$styles.flexColNav]">
92
+ <i class="mdi mdi-arrow-left cursor-pointer absolute text-xl left-0 top-0 rounded-br-full bg-white border-[1px] pb-3 pt-1 pl-1 pr-3" @click="isSendNumberOpen = false"></i>
93
+ <base-form-section :title="selectedClient && selectedClient.longName ? selectedClient.longName : ''">
94
+ <v-form ref="vForm">
95
+ <base-rounded-input
96
+ v-model="phoneNumber"
97
+ :maska="$maska.phone"
98
+ :rules="$rules.required.concat($rules.phoneFormat)"
99
+ :label="$dataStore.t('form.phoneNumber')"
100
+ placeholder="+7 7"
101
+ />
102
+ </v-form>
103
+ <base-btn :text="$dataStore.t('buttons.sendSMS')" :loading="loading" @click="submitForm" />
104
+ </base-form-section>
105
+ </div>
106
+ </base-fade-transition>
107
+ </section>
64
108
  <section v-if="payingActions" class="relative">
65
109
  <div>
66
110
  <base-fade-transition>
67
111
  <div v-if="!isSendNumberOpen" :class="[$styles.flexColNav]">
68
112
  <base-btn :loading="loading" :text="$dataStore.t('payment.copyUrl')" @click="$dataStore.copyToClipboard(formStore.epayLink)" />
69
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)" />
70
115
  </div>
71
116
  <div v-if="isSendNumberOpen" :class="[$styles.flexColNav]">
72
117
  <i
@@ -99,27 +144,52 @@
99
144
  :maska="$maska.date"
100
145
  :rules="$rules.required"
101
146
  :label="$dataStore.t('form.date')"
102
- append-inner-icon="mdi mdi-calendar-blank-outline" />
147
+ append-inner-icon="mdi mdi-calendar-blank-outline"
148
+ />
103
149
  <base-file-input v-if="!affiliationDocument" @input.prevent="onFileChange($event)" />
104
150
  <base-empty-form-field v-if="affiliationDocument" class="justify-between">
105
151
  {{ `${affiliationDocument.fileTypeName} - ${affiliationDocument.fileName}` }}
106
- <i class="cursor-pointer mdi mdi-file-document mr-6 text-[#a0b3d8] text-xl"></i></base-empty-form-field
107
- ></base-content-block>
152
+ <i class="cursor-pointer mdi mdi-file-document mr-6 text-[#a0b3d8] text-xl"></i
153
+ ></base-empty-form-field>
154
+ </base-content-block>
108
155
  </v-form>
109
156
  <base-btn :text="buttonText" :loading="loading" @click="submitForm" />
110
157
  </div>
111
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>
112
166
  </template>
113
167
 
114
168
  <script lang="ts">
115
- import { DocumentItem } from '../../composables/classes';
169
+ import { DocumentItem, Value } from '../../composables/classes';
170
+ import { HubConnectionBuilder } from '@microsoft/signalr';
171
+ import { uuid } from 'vue-uuid';
172
+
116
173
  export default defineComponent({
117
- setup() {
174
+ emits: ['task'],
175
+ setup(props, { emit }) {
118
176
  const route = useRoute();
119
177
  const dataStore = useDataStore();
120
178
  const formStore = useFormStore();
121
179
  const actionCause = ref<string>('');
122
180
  const loading = ref<boolean>(false);
181
+ const isPaperContract = ref<boolean>(false);
182
+ const isScansDocuments = ref<boolean>(false);
183
+ const isQr = ref<boolean>(false);
184
+ const isElectronicContract = ref<boolean>(true);
185
+ const qrUrl = ref<string>('');
186
+ const connection = ref<any>(null);
187
+ const isQrLoading = ref<boolean>(false);
188
+ const urlCopy = ref<string>('');
189
+ const isEpayPay = ref<boolean>(false);
190
+ const isOfflinePay = ref<boolean>(false);
191
+ const isQrDialog = ref<boolean>(false);
192
+
123
193
  const vForm = ref<any>();
124
194
  const isSendNumberOpen = ref<boolean>(false);
125
195
  const phoneNumber = ref<string | null>(formStore.policyholderForm.phoneNumber ?? '');
@@ -137,6 +207,8 @@ export default defineComponent({
137
207
  fileTypeCode: documentDict.value ? documentDict.value.code : '',
138
208
  });
139
209
  const affiliationFormData = ref(new FormData());
210
+ const scansFormData = ref(new FormData());
211
+ const scansFiles = ref<any[]>([]);
140
212
 
141
213
  const openSmsPanel = (signInfo: SignUrlType) => {
142
214
  if (signInfo) {
@@ -166,6 +238,63 @@ export default defineComponent({
166
238
  }
167
239
  };
168
240
 
241
+ const onFileChangeScans = async (event: InputEvent, type: 'statement' | 'contract' | 'app' | 'attorney') => {
242
+ if (event.target) {
243
+ const files = (event.target as HTMLInputElement).files;
244
+ if (files && files.length) {
245
+ const doc = await selectedDocument(type);
246
+ const data = {
247
+ processInstanceId: formStore.applicationData.processInstanceId,
248
+ fileTypeCode: doc ? doc.code : null,
249
+ fileTypeId: doc ? doc.id : null,
250
+ fileName: files[0].name,
251
+ };
252
+ scansFiles.value.push({
253
+ file: files[0],
254
+ fileData: JSON.stringify([data]),
255
+ });
256
+ }
257
+ }
258
+ };
259
+
260
+ const onClearFile = async (type: 'statement' | 'contract' | 'app' | 'attorney') => {
261
+ const doc = await selectedDocument(type);
262
+ const result = scansFiles.value.filter(i => JSON.parse(i.fileData)[0].fileTypeCode !== doc.code);
263
+ scansFiles.value = result;
264
+ };
265
+
266
+ const selectedDocument = (type: 'statement' | 'contract' | 'app' | 'attorney') => {
267
+ let selectedDocument: any;
268
+ if (type === 'statement') {
269
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '32');
270
+ }
271
+ if (type === 'contract') {
272
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '6');
273
+ }
274
+ if (type === 'app') {
275
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '33');
276
+ }
277
+ if (type === 'attorney') {
278
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '34');
279
+ }
280
+ return selectedDocument;
281
+ };
282
+
283
+ const sendFiles = async () => {
284
+ if (scansFiles.value.length !== 4) {
285
+ dataStore.showToaster('warning', dataStore.t('toaster.notAllDocumentsAttached'));
286
+ return;
287
+ }
288
+ for (const item of scansFiles.value) {
289
+ scansFormData.value.append('file', item.file);
290
+ scansFormData.value.append('fileData', item.fileData);
291
+ await dataStore.uploadFiles(scansFormData.value);
292
+ scansFormData.value = new FormData();
293
+ }
294
+ closePanel();
295
+ dataStore.showToaster('success', dataStore.t('toaster.successOperation'));
296
+ await dataStore.handleTask(constants.actions.signed, route.params.taskId as string, 'scans');
297
+ };
169
298
  const submitForm = async () => {
170
299
  await vForm.value.validate().then(async (v: { valid: Boolean; errors: any }) => {
171
300
  if (v.valid) {
@@ -198,10 +327,32 @@ export default defineComponent({
198
327
 
199
328
  const handleTask = async () => {
200
329
  loading.value = true;
201
- await dataStore.handleTask(dataStore.panelAction, route.params.taskId as string, actionCause.value);
330
+ // Пока не нужно, на всякий оставить
331
+ // if (needRecalculation.value) {
332
+ // dataStore.showToaster('info', dataStore.t('toaster.needToRecalculate'));
333
+ // loading.value = false;
334
+ // return;
335
+ // }
336
+ if (dataStore.isAML || dataStore.isCheckContract || dataStore.isCheckContragent || dataStore.isDas || dataStore.isUU) {
337
+ emit('task', [dataStore.panelAction, route.params.taskId as string, actionCause.value]);
338
+ } else {
339
+ await dataStore.handleTask(dataStore.panelAction, route.params.taskId as string, actionCause.value);
340
+ }
202
341
  loading.value = false;
203
342
  };
204
343
 
344
+ const onInit = async () => {
345
+ if (dataStore.controls.hasChooseSign) {
346
+ if (dataStore.isGons || dataStore.isLifeBusiness || dataStore.isGns) {
347
+ isElectronicContract.value = false;
348
+ }
349
+ }
350
+ };
351
+
352
+ onMounted(async () => {
353
+ await onInit();
354
+ });
355
+
205
356
  const buttonText = computed(() => {
206
357
  switch (dataStore.panelAction) {
207
358
  case constants.actions.reject:
@@ -219,6 +370,8 @@ export default defineComponent({
219
370
  return dataStore.t('buttons.register');
220
371
  case constants.actions.affiliate:
221
372
  return dataStore.t('buttons.send');
373
+ default:
374
+ return dataStore.t('buttons.send');
222
375
  }
223
376
  });
224
377
 
@@ -226,12 +379,20 @@ export default defineComponent({
226
379
  () => dataStore.panelAction,
227
380
  val => {
228
381
  if (!!val) {
229
- dataStore.panel.title = buttonText.value!;
382
+ dataStore.panel.title = buttonText.value;
230
383
  dataStore.panel.open = true;
231
384
  }
232
385
  },
233
386
  { immediate: true },
234
387
  );
388
+
389
+ const needRecalculation = computed(
390
+ () =>
391
+ dataStore.isGons &&
392
+ formStore.applicationData.statusCode === 'UnderwriterForm' &&
393
+ dataStore.panelAction === constants.actions.accept &&
394
+ formStore.productConditionsForm.isRecalculated === false,
395
+ );
235
396
  const sendingActions = computed(
236
397
  () => dataStore.panelAction === constants.actions.reject || dataStore.panelAction === constants.actions.return || dataStore.panelAction === constants.actions.rejectclient,
237
398
  );
@@ -239,15 +400,191 @@ export default defineComponent({
239
400
  const signingActions = computed(() => dataStore.panelAction === constants.actions.sign);
240
401
  const payingActions = computed(() => dataStore.panelAction === constants.actions.pay);
241
402
  const affiliateActions = computed(() => dataStore.panelAction === constants.actions.affiliate);
403
+ const chooseSignActions = computed(() => dataStore.controls.hasChooseSign && dataStore.panelAction === constants.actions.chooseSign);
404
+ const choosePayActions = computed(() => dataStore.controls.hasChoosePay && dataStore.panelAction === constants.actions.choosePay);
405
+
242
406
  const paymentPeriod = computed(() => formStore.productConditionsForm.paymentPeriod.nameRu);
243
407
  const insurancePremiumPerMonth = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.insurancePremiumPerMonth));
244
- const requestedSumInsured = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.requestedSumInsured));
408
+ const requestedSumInsured = computed(() => {
409
+ if ((dataStore.isLifeBusiness || dataStore.isGns) && formStore.productConditionsForm.requestedSumInsured === null) {
410
+ return dataStore.getNumberWithSpaces(formStore.applicationData.policyAppDto!.mainInsSum);
411
+ }
412
+ return dataStore.getNumberWithSpaces(formStore.productConditionsForm.requestedSumInsured);
413
+ });
414
+ const price = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.calculatorForm.price));
415
+ const insuredAmount = computed(() => formStore.productConditionsForm.calculatorForm.amount!.nameRu! + dataStore.currency);
245
416
  const hasConditionsInfo = computed(() => {
417
+ if (dataStore.isLifetrip || dataStore.isDas || dataStore.isUU) {
418
+ return false;
419
+ }
246
420
  if (dataStore.isFinCenter()) {
247
421
  return false;
248
422
  }
249
423
  return true;
250
424
  });
425
+ const isPaperDisabled = computed(() => {
426
+ if (dataStore.isGons) {
427
+ return false;
428
+ }
429
+ return true;
430
+ });
431
+ const isElectronicDisabled = computed(() => {
432
+ if (dataStore.isGons) {
433
+ return true;
434
+ }
435
+ return false;
436
+ });
437
+ const isScansDisabled = computed(() => {
438
+ if (dataStore.isGons) {
439
+ return true;
440
+ }
441
+ return false;
442
+ });
443
+ const isQrDisabled = computed(() => {
444
+ if (dataStore.isLifeBusiness || dataStore.isGns) {
445
+ return false;
446
+ }
447
+ return true;
448
+ });
449
+ const downloadTemplate = async (documentType: number, fileType: string) => {
450
+ await dataStore.downloadTemplate(documentType, fileType, formStore.applicationData.processInstanceId);
451
+ };
452
+
453
+ const handleSignAction = async (type: 'paper' | 'electronic' | 'scans' | 'qr') => {
454
+ loading.value = true;
455
+ if (type === 'electronic') {
456
+ await dataStore.signDocument();
457
+ isElectronicContract.value = true;
458
+ dataStore.panelAction = constants.actions.sign;
459
+ }
460
+ if (type === 'paper') {
461
+ isPaperContract.value = true;
462
+ }
463
+ if (type === 'scans') {
464
+ isScansDocuments.value = true;
465
+ }
466
+ if (type === 'qr') {
467
+ const result = (await dataStore.signDocument('qr')) as any;
468
+ if (result && result.data) {
469
+ const groupId = result.data[0].signatureDocumentGroupId;
470
+ await generateQR(groupId);
471
+ isQr.value = true;
472
+ }
473
+ }
474
+ loading.value = false;
475
+ };
476
+
477
+ const handlePayAction = async (type: 'epay' | 'offline') => {
478
+ loading.value = true;
479
+ if (type === 'epay') {
480
+ await payEpay();
481
+ }
482
+ if (type === 'offline') {
483
+ await dataStore.handleTask(constants.actions.payed, route.params.taskId as string, 'offline');
484
+ isOfflinePay.value = true;
485
+ }
486
+ loading.value = false;
487
+ };
488
+
489
+ const generateQR = async (groupId: string) => {
490
+ const uuidV4 = uuid.v4();
491
+ const qrValue = `${getStrValuePerEnv('qrGenUrl')}/${uuidV4}/${groupId}`;
492
+ qrUrl.value = qrValue;
493
+ if (dataStore.isLifeBusiness || dataStore.isGns) {
494
+ //для юр лиц
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`;
496
+ } else {
497
+ //для физ лиц
498
+ urlCopy.value = `https://mgovsign.page.link/?link=${qrValue}?mgovSign&amp;apn=kz.mobile.mgov&amp;isi=1476128386&amp;ibi=kz.egov.mobile`;
499
+ }
500
+
501
+ await startConnection(uuidV4);
502
+ };
503
+
504
+ const startConnection = async (uuid: string) => {
505
+ connection.value = new HubConnectionBuilder().withUrl(`https://test-sign.halyklife.kz/qrhub/${uuid}`).withAutomaticReconnect().build();
506
+ try {
507
+ await connection.value.start();
508
+ console.log('SignalR connection started.');
509
+ connection.value.on('QR', async (message: any) => {
510
+ if (message === 'Opened') {
511
+ isQrLoading.value = true;
512
+ }
513
+ if (message === 'Signed') {
514
+ isQrLoading.value = false;
515
+ dataStore.showToaster('success', dataStore.t('sign.successQrSigned'));
516
+ qrUrl.value = '';
517
+ isQr.value = false;
518
+ dataStore.panel.open = false;
519
+ dataStore.panelAction = null;
520
+ await stopConnection();
521
+ }
522
+ });
523
+ } catch (err) {
524
+ console.error('Error starting SignalR connection:', err);
525
+ }
526
+ };
527
+
528
+ const closeQrPanel = async () => {
529
+ isQr.value = false;
530
+ isQrLoading.value = false;
531
+ await stopConnection();
532
+ };
533
+
534
+ const stopConnection = async () => {
535
+ if (connection.value) {
536
+ await connection.value.stop();
537
+ console.log('SignalR connection stopped.');
538
+ }
539
+ };
540
+
541
+ const generateDocument = async () => {
542
+ dataStore.panel.open = false;
543
+ dataStore.panelAction = null;
544
+ await dataStore.generateDocument();
545
+ };
546
+
547
+ const convertQr = async (url: string | null) => {
548
+ if (url) {
549
+ const shortedUrl = await dataStore.generateShortLink(url);
550
+ qrUrl.value = typeof shortedUrl === 'string' && !!shortedUrl ? shortedUrl : url;
551
+ isQrDialog.value = true;
552
+ } else {
553
+ dataStore.showToaster('error', dataStore.t('toaster.noUrl'));
554
+ }
555
+ };
556
+
557
+ const payEpay = async () => {
558
+ const invoiceData = await dataStore.getInvoiceData(formStore.applicationData.processInstanceId);
559
+ if (invoiceData === false || invoiceData.status === 3 || invoiceData.status === 0) {
560
+ if (invoiceData === false || invoiceData.status === 3) {
561
+ const created = await dataStore.createInvoice();
562
+ if (created) {
563
+ const ePayData = await dataStore.sendToEpay();
564
+ if (!ePayData) return;
565
+ formStore.epayLink = dataStore.sanitize(ePayData.link);
566
+ }
567
+ }
568
+ if (!!invoiceData && invoiceData.status === 0) {
569
+ const ePayData = await dataStore.sendToEpay();
570
+ if (!ePayData) return;
571
+ formStore.epayLink = dataStore.sanitize(ePayData.link);
572
+ }
573
+ } else {
574
+ if (invoiceData.paymentLink) {
575
+ formStore.epayLink = dataStore.sanitize(invoiceData.paymentLink);
576
+ } else {
577
+ dataStore.showToaster('error', dataStore.t('toaster.noUrl'));
578
+ }
579
+ }
580
+ if (!formStore.epayLink) {
581
+ dataStore.showToaster('error', dataStore.t('toaster.noUrl'));
582
+ return;
583
+ }
584
+ loading.value = false;
585
+ isEpayPay.value = true;
586
+ dataStore.panelAction = constants.actions.pay;
587
+ };
251
588
 
252
589
  return {
253
590
  // State
@@ -258,6 +595,16 @@ export default defineComponent({
258
595
  isSendNumberOpen,
259
596
  phoneNumber,
260
597
  selectedClient,
598
+ isPaperContract,
599
+ isScansDocuments,
600
+ isQr,
601
+ qrUrl,
602
+ scansFiles,
603
+ isQrLoading,
604
+ urlCopy,
605
+ isEpayPay,
606
+ isOfflinePay,
607
+ isQrDialog,
261
608
 
262
609
  // Functions
263
610
  closePanel,
@@ -266,6 +613,14 @@ export default defineComponent({
266
613
  openSmsPanel,
267
614
  openEpayPanel,
268
615
  onFileChange,
616
+ downloadTemplate,
617
+ onFileChangeScans,
618
+ sendFiles,
619
+ onClearFile,
620
+ closeQrPanel,
621
+ handlePayAction,
622
+ payEpay,
623
+ convertQr,
269
624
 
270
625
  // Computed
271
626
  buttonText,
@@ -274,11 +629,22 @@ export default defineComponent({
274
629
  payingActions,
275
630
  acceptAction,
276
631
  affiliateActions,
632
+ chooseSignActions,
277
633
  paymentPeriod,
278
634
  insurancePremiumPerMonth,
279
635
  requestedSumInsured,
280
636
  affiliationDocument,
281
637
  hasConditionsInfo,
638
+ price,
639
+ insuredAmount,
640
+ isElectronicContract,
641
+ handleSignAction,
642
+ generateDocument,
643
+ isPaperDisabled,
644
+ isElectronicDisabled,
645
+ isScansDisabled,
646
+ isQrDisabled,
647
+ choosePayActions,
282
648
  };
283
649
  },
284
650
  });
@@ -288,16 +654,19 @@ export default defineComponent({
288
654
  .v-expansion-panel-title__overlay {
289
655
  background: #ffffff;
290
656
  }
657
+
291
658
  .v-expansion-panel-title {
292
659
  height: 70px !important;
293
660
  padding: 10px 20px !important;
294
661
  }
662
+
295
663
  .v-expansion-panels--variant-accordion > :last-child {
296
664
  border-top-left-radius: 0.5rem !important;
297
665
  border-top-right-radius: 0.5rem !important;
298
666
  border-top-left-radius: 0.5rem !important;
299
667
  border-radius: 0.5rem !important;
300
668
  }
669
+
301
670
  .v-expansion-panel-text__wrapper {
302
671
  padding: 10px 20px !important;
303
672
  }
@@ -1,7 +1,10 @@
1
1
  <template>
2
- <div class="flex justify-between p-4 items-center cursor-pointer" :class="[$styles.rounded, $styles.blueBgLight, $styles.blueBgLightHover]">
2
+ <div
3
+ class="transition-all flex justify-between p-4 items-center cursor-pointer"
4
+ :class="[$styles.rounded, $styles.blueBgLight, $styles.blueBgLightHover, disabled ? $styles.disabled : '']"
5
+ >
3
6
  <span :class="[$styles.textSimple]">{{ text }}</span>
4
- <i class="mdi text-xl" :class="[selected ? `mdi-radiobox-marked ${$styles.greenText}` : 'mdi-radiobox-blank text-[#636363]']"></i>
7
+ <i class="mdi text-xl" :class="[selected ? `${trueIcon} ${$styles.greenText}` : `${falseIcon} text-[#636363]`]"></i>
5
8
  </div>
6
9
  </template>
7
10
 
@@ -15,6 +18,18 @@ export default defineComponent({
15
18
  type: Boolean,
16
19
  default: false,
17
20
  },
21
+ disabled: {
22
+ type: Boolean,
23
+ default: false,
24
+ },
25
+ trueIcon: {
26
+ type: String,
27
+ default: 'mdi-radiobox-marked',
28
+ },
29
+ falseIcon: {
30
+ type: String,
31
+ default: 'mdi-radiobox-blank ',
32
+ },
18
33
  },
19
34
  });
20
35
  </script>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts">
2
+ const dataStore = useDataStore();
3
+
4
+ onUnmounted(() => {
5
+ dataStore.rightPanel.open = false;
6
+ });
7
+ </script>
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <component v-if="!!type && Object.keys(vuetifyAnimations).includes(type)" :is="vuetifyAnimations[type]">
3
+ <slot></slot>
4
+ </component>
5
+ <slot v-else></slot>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ defineProps({
10
+ type: {
11
+ type: String as PropType<VuetifyAnimations>,
12
+ default: 'expand',
13
+ },
14
+ });
15
+
16
+ const vuetifyAnimations: { [key in VuetifyAnimations]: string } = {
17
+ expand: 'v-expand-transition',
18
+ fab: 'v-fab-transition',
19
+ fade: 'v-fade-transition',
20
+ scale: 'v-scale-transition',
21
+ 'scroll-x': 'v-scroll-x-transition',
22
+ 'scroll-y': 'v-scroll-x-transition',
23
+ 'slide-x': 'v-slide-x-transition',
24
+ 'slide-x-r': 'v-slide-x-reverse-transition',
25
+ 'slide-y': 'v-slide-y-transition',
26
+ 'slide-y-r': 'v-slide-y-reverse-transition',
27
+ };
28
+ </script>