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

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 +1042 -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 +43 -7
  16. package/components/Input/DynamicInput.vue +23 -0
  17. package/components/Input/FileInput.vue +25 -5
  18. package/components/Input/FormInput.vue +7 -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 +18 -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 +50 -9
  33. package/components/Pages/ContragentForm.vue +124 -50
  34. package/components/Pages/Documents.vue +179 -29
  35. package/components/Pages/InvoiceInfo.vue +1 -1
  36. package/components/Pages/MemberForm.vue +605 -116
  37. package/components/Pages/ProductAgreement.vue +1 -8
  38. package/components/Pages/ProductConditions.vue +1055 -183
  39. package/components/Panel/PanelHandler.vue +583 -46
  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 +456 -8
  46. package/composables/constants.ts +114 -2
  47. package/composables/fields.ts +328 -0
  48. package/composables/index.ts +270 -19
  49. package/composables/styles.ts +29 -16
  50. package/layouts/default.vue +48 -3
  51. package/locales/ru.json +547 -14
  52. package/package.json +28 -24
  53. package/pages/Token.vue +1 -12
  54. package/plugins/vuetifyPlugin.ts +2 -0
  55. package/store/data.store.ts +1463 -275
  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 +83 -5
  60. package/types/enum.ts +61 -0
  61. package/types/env.d.ts +1 -0
  62. package/types/form.ts +94 -0
  63. package/types/index.ts +259 -23
@@ -17,56 +17,168 @@
17
17
  >{{ `Запрашиваемая страховая сумма: ` }} <b>{{ `${requestedSumInsured}₸` }}</b>
18
18
  </span>
19
19
  </base-content-block>
20
- <base-btn :text="$dataStore.t('confirm.yes')" @click="handleTask" />
21
- <base-btn :btn="$styles.blueLightBtn" :text="$dataStore.t('confirm.no')" @click="closePanel" />
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>
25
+ <div class="flex flex-col gap-3" v-if="hasConditionsAction">
26
+ <base-btn :text="$dataStore.t('confirm.yes')" @click="handleTask" />
27
+ <base-btn :btn="$styles.blueLightBtn" :text="$dataStore.t('confirm.no')" @click="closePanel" />
28
+ </div>
22
29
  </div>
23
30
  </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 />
31
+ <section v-if="chooseSignActions">
32
+ <div v-if="!isElectronicContract && !isPaperContract && !isScansDocuments && !isQr" :class="[$styles.flexColNav]">
33
+ <base-btn :text="$dataStore.t('buttons.sendOnPaper')" :disabled="isPaperDisabled" :loading="loading" @click="handleSignAction('paper')" />
34
+ <base-btn :text="$dataStore.t('buttons.sendElectronically')" :disabled="isElectronicDisabled" :loading="loading" @click="handleSignAction('electronic')" />
35
+ <base-btn :text="$dataStore.t('buttons.generatePrintedForms')" :disabled="isScansDisabled" :loading="loading" @click="handleSignAction('scans')" />
36
+ <base-btn :text="$dataStore.t('buttons.sendEgovMob')" :disabled="isQrDisabled" :loading="loading" @click="handleSignAction('qr')" />
37
+ <base-btn v-if="$dataStore.isPension" text="Подписать Согласие через Egov QrXML" :disabled="isQrXmlDisabled" :loading="loading" @click="handleSignAction('qrXml')" />
38
+ <base-btn v-if="$dataStore.isPension" :text="$dataStore.t('buttons.signWithSignature')" :disabled="consentGiven" :loading="loading" @click="handleSignAction('signature')" />
39
+ </div>
40
+ <div v-if="isPaperContract" :class="[$styles.flexColNav]">
41
+ <base-btn :text="$dataStore.t('buttons.downloadContract')" :loading="$dataStore.isButtonsLoading" @click="generateDocument" />
42
+ </div>
43
+ <div v-if="isScansDocuments" :class="[$styles.flexColNav]">
44
+ <div v-if="$dataStore.isPension">
45
+ <div v-if="processCode == 1">
46
+ <div v-if="formStore.applicationData.statusCode === 'ContractSignedByAuthorizedPerson' || formStore.applicationData.statusCode === 'ContractSignedFrom'">
47
+ <base-btn :text="$dataStore.t('buttons.downloadContract')" :loading="$dataStore.isButtonsLoading" @click="$dataStore.generatePDFDocument('PA_Contract', '38')" />
48
+ <base-form-section class="mt-4 flex flex-col !gap-2" :title="$dataStore.t('clients.attachScansSignDocs')">
49
+ <base-file-input :label="$dataStore.t('labels.attachContract')" @input.prevent="onFileChangeScans($event, 'pa_contract')" @onClear="onClearFile('pa_contract')" />
50
+ </base-form-section>
51
+ </div>
52
+ <div v-else>
53
+ <base-btn :text="$dataStore.t('buttons.downloadStatement')" :loading="$dataStore.isButtonsLoading" @click="$dataStore.generatePDFDocument('PA_Statement', '37')" />
54
+ <base-form-section class="mt-4 flex flex-col !gap-2" :title="$dataStore.t('clients.attachScansSignDocs')">
55
+ <base-file-input :label="$dataStore.t('labels.attachStatement')" @input.prevent="onFileChangeScans($event, 'pa_statement')" @onClear="onClearFile('pa_statement')" />
56
+ </base-form-section>
41
57
  </div>
42
58
  </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>
59
+ <div v-if="processCode == 2">
60
+ <base-btn
61
+ :text="$dataStore.t('buttons.downloadPARefundStatement')"
62
+ :loading="$dataStore.isButtonsLoading"
63
+ @click="$dataStore.generatePDFDocument('PA_RefundStatement', '41')"
64
+ />
65
+ <base-btn
66
+ :text="$dataStore.t('buttons.downloadPARefundAgreement')"
67
+ :loading="$dataStore.isButtonsLoading"
68
+ @click="$dataStore.generatePDFDocument('PA_RefundAgreement', '42')"
69
+ />
70
+
71
+ <base-form-section class="mt-4 flex flex-col !gap-2" :title="$dataStore.t('clients.attachScansSignDocs')">
72
+ <base-file-input
73
+ :label="$dataStore.t('buttons.downloadPARefundStatement')"
74
+ @input.prevent="onFileChangeScans($event, 'pa_refundstatement')"
75
+ @onClear="onClearFile('pa_refundstatement')"
76
+ />
77
+ <base-file-input
78
+ :label="$dataStore.t('buttons.downloadPARefundAgreement')"
79
+ @input.prevent="onFileChangeScans($event, 'pa_refundagreement')"
80
+ @onClear="onClearFile('pa_refundagreement')"
81
+ />
82
+ </base-form-section>
60
83
  </div>
61
- </base-fade-transition>
84
+ </div>
85
+ <div v-else>
86
+ <base-btn :text="$dataStore.t('buttons.downloadStatement')" @click="downloadTemplate(constants.documentTypes.statement, 'docx')" />
87
+ <base-btn :text="$dataStore.t('buttons.downloadContract')" @click="downloadTemplate(constants.documentTypes.contract, 'doc')" />
88
+ <base-btn :text="$dataStore.t('buttons.downloadApplication')" @click="downloadTemplate(constants.documentTypes.application1, 'vnd.ms-excel')" />
89
+ <base-form-section class="mt-4 flex flex-col !gap-2" :title="$dataStore.t('clients.attachScansSignDocs')">
90
+ <base-file-input :label="$dataStore.t('labels.attachStatement')" @input.prevent="onFileChangeScans($event, 'statement')" @onClear="onClearFile('statement')" />
91
+ <base-file-input :label="$dataStore.t('labels.attachContract')" @input.prevent="onFileChangeScans($event, 'contract')" @onClear="onClearFile('contract')" />
92
+ <base-file-input :label="$dataStore.t('labels.attachApplication')" @input.prevent="onFileChangeScans($event, 'app')" @onClear="onClearFile('app')" />
93
+ <base-file-input :label="$dataStore.t('labels.attachPowerOfAttorney')" @input.prevent="onFileChangeScans($event, 'attorney')" @onClear="onClearFile('attorney')" />
94
+ </base-form-section>
95
+ </div>
96
+ <base-btn :text="$dataStore.t('buttons.sign')" :loading="$dataStore.isButtonsLoading" @click="sendFiles" />
97
+ <base-btn :text="$dataStore.t('buttons.cancel')" :btn="$styles.whiteBtn" @click="isScansDocuments = false" />
98
+ </div>
99
+ <div v-if="isQr" :class="[$styles.flexColNav]">
100
+ <base-form-section :title="''">
101
+ <base-loader v-if="isQrLoading" class="self-center m-5 opacity-70" />
102
+ <div v-if="qrUrl && !isQrLoading">
103
+ <base-qr :value="qrUrl" :size="200" class="ma-auto rounded" />
104
+ <span :class="[$styles.textSimple]" class="mt-3 text-center d-block">{{ $dataStore.t('sign.scanQrCode') }}</span>
105
+ </div>
106
+ <base-btn class="mt-10" :loading="loading" :text="$dataStore.t('sign.copyEgov')" @click="$dataStore.copyToClipboard(urlCopy)" />
107
+ <base-btn :text="$dataStore.t('buttons.cancel')" :btn="$styles.whiteBtn" @click="closeQrPanel" />
108
+ </base-form-section>
62
109
  </div>
63
110
  </section>
111
+ <section v-if="choosePayActions">
112
+ <div v-if="!isEpayPay && !isOfflinePay" :class="[$styles.flexColNav]">
113
+ <base-btn :text="$dataStore.t('buttons.payEpay')" :loading="loading" @click="handlePayAction('epay')" />
114
+ <base-btn :text="$dataStore.t('buttons.payOffline')" :loading="loading" @click="handlePayAction('offline')" />
115
+ </div>
116
+ <div v-if="isOfflinePay" :class="[$styles.flexColNav]">
117
+ <base-form-section class="!gap-3 p-3" :title="''">
118
+ <v-form ref="vForm">
119
+ <base-form-input v-model="email" :rules="$rules.required.concat($rules.email)" :label="$dataStore.t('form.email')" />
120
+ </v-form>
121
+ <base-panel-item class="cursor-pointer bg-white border-b-0 rounded" @click="downloadTemplate(constants.documentTypes.invoicePayment, 'pdf')">
122
+ Счет на оплату.pdf
123
+ <i class="mdi mdi-download text-2xl text-[#A0B3D8]"></i
124
+ ></base-panel-item>
125
+ </base-form-section>
126
+ <base-btn :text="$dataStore.t('buttons.send')" :loading="$dataStore.isButtonsLoading" @click="sendInvoiceToEmail" />
127
+ </div>
128
+ </section>
129
+ <section v-if="signingActions" class="relative">
130
+ <base-fade-transition>
131
+ <div v-if="!isSendNumberOpen" :class="[$styles.flexColNav]">
132
+ <div :class="[$styles.blueBgLight]" class="rounded-lg p-4">
133
+ <v-expansion-panels v-if="formStore.signUrls && formStore.signUrls.length" variant="accordion" multiple>
134
+ <v-expansion-panel v-for="signUrl of formStore.signUrls" :key="signUrl.iin!" class="border-[1px]" elevation="0" bg-color="#FFF">
135
+ <v-expansion-panel-title class="h-[80px]" :class="$styles.textTitle">
136
+ {{ `${signUrl.longName} - ${signUrl.iin}` }}
137
+ </v-expansion-panel-title>
138
+ <v-expansion-panel-text class="border-t-[1px]">
139
+ <section class="flex flex-col gap-4 py-3" :class="$styles.textSimple">
140
+ <base-btn :loading="loading" :text="$dataStore.t('sign.copyCloud')" @click="$dataStore.copyToClipboard(signUrl.uri)" />
141
+ <base-btn :loading="loading" :btn="$styles.blueLightBtn" :text="$dataStore.t('sign.recipientNumber')" @click="openSmsPanel(signUrl)" />
142
+ <base-btn :loading="loading" :text="$dataStore.t('sign.convertQr')" @click="convertQr(signUrl.uri)" />
143
+ </section>
144
+ </v-expansion-panel-text>
145
+ </v-expansion-panel>
146
+ </v-expansion-panels>
147
+ <base-list-empty v-else />
148
+ </div>
149
+ </div>
150
+ <div v-if="isSendNumberOpen" :class="[$styles.flexColNav]">
151
+ <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>
152
+ <base-form-section :title="selectedClient && selectedClient.longName ? selectedClient.longName : ''">
153
+ <v-form ref="vForm">
154
+ <base-rounded-input
155
+ v-model="phoneNumber"
156
+ :maska="$maska.phone"
157
+ :rules="$rules.required.concat($rules.phoneFormat)"
158
+ :label="$dataStore.t('form.phoneNumber')"
159
+ placeholder="+7 7"
160
+ />
161
+ </v-form>
162
+ <base-btn :text="$dataStore.t('buttons.sendSMS')" :loading="loading" @click="submitForm" />
163
+ </base-form-section>
164
+ </div>
165
+ </base-fade-transition>
166
+ <base-btn
167
+ :text="$dataStore.t('buttons.cancel')"
168
+ :btn="$styles.whiteBtn"
169
+ @click="
170
+ $dataStore.panelAction = constants.actions.chooseSign;
171
+ isElectronicContract = false;
172
+ "
173
+ />
174
+ </section>
64
175
  <section v-if="payingActions" class="relative">
65
176
  <div>
66
177
  <base-fade-transition>
67
178
  <div v-if="!isSendNumberOpen" :class="[$styles.flexColNav]">
68
179
  <base-btn :loading="loading" :text="$dataStore.t('payment.copyUrl')" @click="$dataStore.copyToClipboard(formStore.epayLink)" />
69
180
  <base-btn :loading="loading" :btn="$styles.blueLightBtn" :text="$dataStore.t('payment.recipientNumber')" @click="openEpayPanel" />
181
+ <base-btn :loading="loading" :text="$dataStore.t('sign.convertQr')" @click="convertQr(formStore.epayLink)" />
70
182
  </div>
71
183
  <div v-if="isSendNumberOpen" :class="[$styles.flexColNav]">
72
184
  <i
@@ -99,32 +211,59 @@
99
211
  :maska="$maska.date"
100
212
  :rules="$rules.required"
101
213
  :label="$dataStore.t('form.date')"
102
- append-inner-icon="mdi mdi-calendar-blank-outline" />
214
+ append-inner-icon="mdi mdi-calendar-blank-outline"
215
+ />
103
216
  <base-file-input v-if="!affiliationDocument" @input.prevent="onFileChange($event)" />
104
217
  <base-empty-form-field v-if="affiliationDocument" class="justify-between">
105
218
  {{ `${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>
219
+ <i class="cursor-pointer mdi mdi-file-document mr-6 text-[#a0b3d8] text-xl"></i
220
+ ></base-empty-form-field>
221
+ </base-content-block>
108
222
  </v-form>
109
223
  <base-btn :text="buttonText" :loading="loading" @click="submitForm" />
110
224
  </div>
111
225
  </section>
226
+ <v-dialog v-model="isQrDialog" width="auto">
227
+ <v-card>
228
+ <v-card-text class="!p-4">
229
+ <base-qr :value="qrUrl" class="rounded" :size="300" />
230
+ </v-card-text>
231
+ </v-card>
232
+ </v-dialog>
112
233
  </template>
113
234
 
114
235
  <script lang="ts">
115
- import { DocumentItem } from '../../composables/classes';
236
+ import { DocumentItem, Value } from '../../composables/classes';
237
+ import { HubConnectionBuilder } from '@microsoft/signalr';
238
+ import { uuid } from 'vue-uuid';
239
+
116
240
  export default defineComponent({
117
- setup() {
241
+ emits: ['task'],
242
+ setup(props, { emit }) {
118
243
  const route = useRoute();
119
244
  const dataStore = useDataStore();
120
245
  const formStore = useFormStore();
121
246
  const actionCause = ref<string>('');
122
247
  const loading = ref<boolean>(false);
248
+ const isPaperContract = ref<boolean>(false);
249
+ const isScansDocuments = ref<boolean>(false);
250
+ const isQr = ref<boolean>(false);
251
+ const isElectronicContract = ref<boolean>(true);
252
+ const qrUrl = ref<string>('');
253
+ const connection = ref<any>(null);
254
+ const isQrLoading = ref<boolean>(false);
255
+ const urlCopy = ref<string>('');
256
+ const isEpayPay = ref<boolean>(false);
257
+ const isOfflinePay = ref<boolean>(false);
258
+ const isQrDialog = ref<boolean>(false);
259
+ const email = ref<string>('');
260
+
123
261
  const vForm = ref<any>();
124
262
  const isSendNumberOpen = ref<boolean>(false);
125
263
  const phoneNumber = ref<string | null>(formStore.policyholderForm.phoneNumber ?? '');
126
264
  const selectedClient = ref<SignUrlType>();
127
265
  const documentDict = computed(() => dataStore.dicFileTypeList.find(i => i.nameRu === 'Решение АС'));
266
+ const consentGiven = computed(() => !!formStore.signedDocumentList.find(i => i.fileTypeCode === '43')?.signed);
128
267
  const affiliationDocument = computed(() => formStore.signedDocumentList.find((file: DocumentItem) => file.fileTypeName === 'Решение АС'));
129
268
  const affiliationData = ref<{
130
269
  processInstanceId: string | number;
@@ -137,6 +276,9 @@ export default defineComponent({
137
276
  fileTypeCode: documentDict.value ? documentDict.value.code : '',
138
277
  });
139
278
  const affiliationFormData = ref(new FormData());
279
+ const scansFormData = ref(new FormData());
280
+ const scansFiles = ref<any[]>([]);
281
+ const processCode = formStore.applicationData.processCode;
140
282
 
141
283
  const openSmsPanel = (signInfo: SignUrlType) => {
142
284
  if (signInfo) {
@@ -166,6 +308,78 @@ export default defineComponent({
166
308
  }
167
309
  };
168
310
 
311
+ const onFileChangeScans = async (
312
+ event: InputEvent,
313
+ type: 'statement' | 'pa_statement' | 'pa_refundstatement' | 'contract' | 'pa_contract' | 'pa_refundagreement' | 'app' | 'attorney',
314
+ ) => {
315
+ if (event.target) {
316
+ const files = (event.target as HTMLInputElement).files;
317
+ if (files && files.length) {
318
+ const doc = await selectedDocument(type);
319
+ const data = {
320
+ processInstanceId: formStore.applicationData.processInstanceId,
321
+ fileTypeCode: doc ? doc.code : null,
322
+ fileTypeId: doc ? doc.id : null,
323
+ fileName: files[0].name,
324
+ };
325
+ scansFiles.value.push({
326
+ file: files[0],
327
+ fileData: JSON.stringify([data]),
328
+ });
329
+ }
330
+ }
331
+ };
332
+
333
+ const onClearFile = async (type: 'statement' | 'pa_statement' | 'pa_refundstatement' | 'contract' | 'pa_contract' | 'pa_refundagreement' | 'app' | 'attorney') => {
334
+ const doc = await selectedDocument(type);
335
+ const result = scansFiles.value.filter(i => JSON.parse(i.fileData)[0].fileTypeCode !== doc.code);
336
+ scansFiles.value = result;
337
+ };
338
+
339
+ const selectedDocument = (type: 'statement' | 'pa_statement' | 'pa_refundstatement' | 'contract' | 'pa_contract' | 'pa_refundagreement' | 'app' | 'attorney') => {
340
+ let selectedDocument: any;
341
+ if (type === 'statement') {
342
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '32');
343
+ }
344
+ if (type === 'pa_statement') {
345
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '37');
346
+ }
347
+ if (type === 'pa_refundstatement') {
348
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '41');
349
+ }
350
+ if (type === 'contract') {
351
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '6');
352
+ }
353
+ if (type === 'pa_contract') {
354
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '38');
355
+ }
356
+ if (type === 'pa_refundagreement') {
357
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '42');
358
+ }
359
+ if (type === 'app') {
360
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '33');
361
+ }
362
+ if (type === 'attorney') {
363
+ selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '34');
364
+ }
365
+ return selectedDocument;
366
+ };
367
+
368
+ const sendFiles = async () => {
369
+ if (dataStore.isPension ? scansFiles.value.length !== 1 : scansFiles.value.length !== 4) {
370
+ dataStore.showToaster('warning', dataStore.t('toaster.notAllDocumentsAttached'));
371
+ return;
372
+ }
373
+ for (const item of scansFiles.value) {
374
+ scansFormData.value.append('file', item.file);
375
+ scansFormData.value.append('fileData', item.fileData);
376
+ await dataStore.uploadFiles(scansFormData.value);
377
+ scansFormData.value = new FormData();
378
+ }
379
+ closePanel();
380
+ dataStore.showToaster('success', dataStore.t('toaster.successOperation'));
381
+ await dataStore.handleTask(dataStore.isPension ? constants.actions.accept : constants.actions.signed, route.params.taskId as string, 'scans');
382
+ };
169
383
  const submitForm = async () => {
170
384
  await vForm.value.validate().then(async (v: { valid: Boolean; errors: any }) => {
171
385
  if (v.valid) {
@@ -198,12 +412,38 @@ export default defineComponent({
198
412
 
199
413
  const handleTask = async () => {
200
414
  loading.value = true;
201
- await dataStore.handleTask(dataStore.panelAction, route.params.taskId as string, actionCause.value);
415
+ // Пока не нужно, на всякий оставить
416
+ // if (needRecalculation.value) {
417
+ // dataStore.showToaster('info', dataStore.t('toaster.needToRecalculate'));
418
+ // loading.value = false;
419
+ // return;
420
+ // }
421
+ if (dataStore.isAML || dataStore.isCheckContract || dataStore.isCheckContragent || dataStore.isDas || dataStore.isPrePension || dataStore.isUU) {
422
+ emit('task', [dataStore.panelAction, route.params.taskId as string, actionCause.value]);
423
+ } else {
424
+ await dataStore.handleTask(dataStore.panelAction, route.params.taskId as string, actionCause.value);
425
+ }
202
426
  loading.value = false;
203
427
  };
204
428
 
429
+ const onInit = async () => {
430
+ if (dataStore.controls.hasChooseSign) {
431
+ if (dataStore.isGons || dataStore.isLifeBusiness || dataStore.isPension || dataStore.isGns) {
432
+ isElectronicContract.value = false;
433
+ }
434
+ }
435
+ if (dataStore.isPension) {
436
+ await dataStore.getSignedDocList(formStore.applicationData.processInstanceId);
437
+ }
438
+ };
439
+
440
+ onMounted(async () => {
441
+ await onInit();
442
+ });
443
+
205
444
  const buttonText = computed(() => {
206
445
  switch (dataStore.panelAction) {
446
+ case constants.actions.cancel:
207
447
  case constants.actions.reject:
208
448
  case constants.actions.rejectclient:
209
449
  return dataStore.t('buttons.rejectStatement');
@@ -219,6 +459,8 @@ export default defineComponent({
219
459
  return dataStore.t('buttons.register');
220
460
  case constants.actions.affiliate:
221
461
  return dataStore.t('buttons.send');
462
+ default:
463
+ return dataStore.t('buttons.send');
222
464
  }
223
465
  });
224
466
 
@@ -226,28 +468,285 @@ export default defineComponent({
226
468
  () => dataStore.panelAction,
227
469
  val => {
228
470
  if (!!val) {
229
- dataStore.panel.title = buttonText.value!;
471
+ dataStore.panel.title = buttonText.value;
230
472
  dataStore.panel.open = true;
231
473
  }
232
474
  },
233
475
  { immediate: true },
234
476
  );
477
+
478
+ const needRecalculation = computed(
479
+ () =>
480
+ dataStore.isGons &&
481
+ formStore.applicationData.statusCode === 'UnderwriterForm' &&
482
+ dataStore.panelAction === constants.actions.accept &&
483
+ formStore.productConditionsForm.isRecalculated === false,
484
+ );
235
485
  const sendingActions = computed(
236
- () => dataStore.panelAction === constants.actions.reject || dataStore.panelAction === constants.actions.return || dataStore.panelAction === constants.actions.rejectclient,
486
+ () =>
487
+ dataStore.panelAction === constants.actions.reject ||
488
+ dataStore.panelAction === constants.actions.cancel ||
489
+ dataStore.panelAction === constants.actions.return ||
490
+ dataStore.panelAction === constants.actions.rejectclient,
237
491
  );
238
492
  const acceptAction = computed(() => dataStore.panelAction === constants.actions.accept);
239
493
  const signingActions = computed(() => dataStore.panelAction === constants.actions.sign);
240
494
  const payingActions = computed(() => dataStore.panelAction === constants.actions.pay);
241
495
  const affiliateActions = computed(() => dataStore.panelAction === constants.actions.affiliate);
496
+ const chooseSignActions = computed(() => dataStore.controls.hasChooseSign && dataStore.panelAction === constants.actions.chooseSign);
497
+ const choosePayActions = computed(() => dataStore.controls.hasChoosePay && dataStore.panelAction === constants.actions.choosePay);
498
+
242
499
  const paymentPeriod = computed(() => formStore.productConditionsForm.paymentPeriod.nameRu);
243
500
  const insurancePremiumPerMonth = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.insurancePremiumPerMonth));
244
- const requestedSumInsured = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.requestedSumInsured));
501
+ const requestedSumInsured = computed(() => {
502
+ if ((dataStore.isLifeBusiness || dataStore.isGns) && formStore.productConditionsForm.requestedSumInsured === null) {
503
+ return dataStore.getNumberWithSpaces(formStore.applicationData.policyAppDto!.mainInsSum);
504
+ }
505
+ return dataStore.getNumberWithSpaces(formStore.productConditionsForm.requestedSumInsured);
506
+ });
507
+ const price = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.calculatorForm.price));
508
+ const insuredAmount = computed(() => formStore.productConditionsForm.calculatorForm.amount!.nameRu! + dataStore.currency);
245
509
  const hasConditionsInfo = computed(() => {
510
+ if (dataStore.isLifetrip || dataStore.isDas || dataStore.isUU || dataStore.isPrePension) {
511
+ return false;
512
+ }
246
513
  if (dataStore.isFinCenter()) {
247
514
  return false;
248
515
  }
249
516
  return true;
250
517
  });
518
+ const hasConditionsAction = computed(() => {
519
+ if (dataStore.isPrePension) {
520
+ return false;
521
+ }
522
+ return true;
523
+ });
524
+ const isPaperDisabled = computed(() => {
525
+ if (dataStore.isGons || dataStore.isPension) {
526
+ return false;
527
+ }
528
+ return true;
529
+ });
530
+ const isElectronicDisabled = computed(() => {
531
+ if (dataStore.isGons) {
532
+ return true;
533
+ }
534
+ if (!consentGiven.value && dataStore.isPension) {
535
+ return true;
536
+ }
537
+ return false;
538
+ });
539
+ const isScansDisabled = computed(() => {
540
+ if (dataStore.isGons) {
541
+ return true;
542
+ }
543
+ if (formStore.applicationData.statusCode === 'ContractSignedByAuthorizedPerson') {
544
+ return false;
545
+ }
546
+ if (!consentGiven.value && dataStore.isPension) {
547
+ return true;
548
+ }
549
+ return false;
550
+ });
551
+ const isQrDisabled = computed(() => {
552
+ if (!consentGiven.value && dataStore.isPension) {
553
+ return true;
554
+ }
555
+ if (dataStore.isLifeBusiness || dataStore.isPension || dataStore.isGns) {
556
+ return false;
557
+ }
558
+ return true;
559
+ });
560
+ const isQrXmlDisabled = computed(() => {
561
+ if (consentGiven.value && dataStore.isPension) {
562
+ return true;
563
+ }
564
+ return false;
565
+ });
566
+ const downloadTemplate = async (documentType: number, fileType: string) => {
567
+ await dataStore.downloadTemplate(documentType, fileType, formStore.applicationData.processInstanceId);
568
+ };
569
+
570
+ const handleSignAction = async (type: 'paper' | 'electronic' | 'scans' | 'qr' | 'qrXml' | 'signature') => {
571
+ loading.value = true;
572
+ if (type === 'electronic') {
573
+ await dataStore.signDocument();
574
+ isElectronicContract.value = true;
575
+ dataStore.panelAction = constants.actions.sign;
576
+ }
577
+ if (type === 'paper') {
578
+ isPaperContract.value = true;
579
+ }
580
+ if (type === 'scans') {
581
+ isScansDocuments.value = true;
582
+ }
583
+ if (type === 'qr') {
584
+ const result = (await dataStore.signDocument('qr')) as any;
585
+ if (result && result.data) {
586
+ const groupId = result.data[0].signatureDocumentGroupId;
587
+ await generateQR(groupId);
588
+ isQr.value = true;
589
+ }
590
+ }
591
+ if (type === 'qrXml') {
592
+ const result = (await dataStore.signDocument('qrXml')) as any;
593
+ if (result && result.data) {
594
+ const id = result.data;
595
+ await generateQR(id, 'xml');
596
+ isQr.value = true;
597
+ }
598
+ }
599
+ if (type === 'signature') {
600
+ await dataStore.signDocument('signature');
601
+ }
602
+ loading.value = false;
603
+ };
604
+
605
+ const handlePayAction = async (type: 'epay' | 'offline') => {
606
+ loading.value = true;
607
+ if (type === 'epay') {
608
+ await payEpay();
609
+ }
610
+ if (type === 'offline') {
611
+ const result = await dataStore.sendTask(route.params.taskId as string, constants.actions.payed, 'offline');
612
+ if (result) {
613
+ isOfflinePay.value = true;
614
+ }
615
+ }
616
+ loading.value = false;
617
+ };
618
+
619
+ const generateQR = async (groupId: string, type: string = 'cms') => {
620
+ const confName = type === 'cms' ? 'qrGenUrl' : 'qrXmlGenUrl';
621
+ const uuidV4 = uuid.v4();
622
+ const linkToCopy = ref<string>(`${getStrValuePerEnv(confName)}/${uuidV4}/${groupId}`);
623
+ const qrValue = `mobileSign:${linkToCopy.value}`;
624
+ qrUrl.value = qrValue;
625
+ if (dataStore.isLifeBusiness || dataStore.isGns) {
626
+ //для юр лиц
627
+ urlCopy.value = `https://egovbusiness.page.link/?link=${linkToCopy.value}?mgovSign&amp;apn=kz.mobile.mgov.business&amp;isi=1597880144&amp;ibi=kz.mobile.mgov.business`;
628
+ } else {
629
+ //для физ лиц
630
+ urlCopy.value = `https://mgovsign.page.link/?link=${linkToCopy.value}?mgovSign&amp;apn=kz.mobile.mgov&amp;isi=1476128386&amp;ibi=kz.egov.mobile`;
631
+ }
632
+
633
+ await startConnection(uuidV4, groupId);
634
+ };
635
+
636
+ const startConnection = async (uuid: string, groupId?: string) => {
637
+ connection.value = new HubConnectionBuilder().withUrl(`https://test-sign.halyklife.kz/qrhub/${uuid}`).withAutomaticReconnect().build();
638
+ try {
639
+ await connection.value.start();
640
+ console.log('SignalR connection started.');
641
+ connection.value.on('QR', async (message: any) => {
642
+ if (message === 'Opened') {
643
+ isQrLoading.value = true;
644
+ } else if (message === 'Signed') {
645
+ isQrLoading.value = false;
646
+ dataStore.showToaster('success', dataStore.t('sign.successQrSigned'));
647
+ qrUrl.value = '';
648
+ isQr.value = false;
649
+ dataStore.panel.open = false;
650
+ dataStore.panelAction = null;
651
+ await stopConnection();
652
+ } else {
653
+ console.log('message from SignalR', message);
654
+ if (message.signed) {
655
+ isQrLoading.value = false;
656
+ qrUrl.value = '';
657
+ isQr.value = false;
658
+ dataStore.panel.open = false;
659
+ dataStore.panelAction = null;
660
+ if (message.signature) {
661
+ console.log('signature from SignalR', message.signature);
662
+ const data = new FormData();
663
+ data.append('processInstanceId', String(dataStore.formStore.applicationData.processInstanceId));
664
+ data.append('xmlData', message.signature);
665
+ data.append('name', 'PAEnpf_Agreement');
666
+ data.append('format', 'xml');
667
+ data.append('EdsXmlId', groupId ?? '');
668
+ await dataStore.api.uploadXml(data);
669
+ await dataStore.getSignedDocList(dataStore.formStore.applicationData.processInstanceId);
670
+ dataStore.showToaster('success', dataStore.t('pension.consentGiven'), 3000);
671
+ }
672
+ await stopConnection();
673
+ }
674
+ }
675
+ });
676
+ } catch (err) {
677
+ console.error('Error starting SignalR connection:', err);
678
+ }
679
+ };
680
+
681
+ const closeQrPanel = async () => {
682
+ isQr.value = false;
683
+ isQrLoading.value = false;
684
+ await stopConnection();
685
+ };
686
+
687
+ const stopConnection = async () => {
688
+ if (connection.value) {
689
+ await connection.value.stop();
690
+ console.log('SignalR connection stopped.');
691
+ }
692
+ };
693
+
694
+ const generateDocument = async () => {
695
+ dataStore.panel.open = false;
696
+ dataStore.panelAction = null;
697
+ await dataStore.generateDocument();
698
+ };
699
+
700
+ const convertQr = async (url: string | null) => {
701
+ if (url) {
702
+ const shortedUrl = await dataStore.generateShortLink(url);
703
+ qrUrl.value = typeof shortedUrl === 'string' && !!shortedUrl ? shortedUrl : url;
704
+ isQrDialog.value = true;
705
+ } else {
706
+ dataStore.showToaster('error', dataStore.t('toaster.noUrl'));
707
+ }
708
+ };
709
+
710
+ const sendInvoiceToEmail = async () => {
711
+ await vForm.value.validate().then(async (v: { valid: Boolean; errors: any }) => {
712
+ if (v.valid) {
713
+ await dataStore.sendInvoiceToEmail(formStore.applicationData.processInstanceId, email.value);
714
+ email.value = '';
715
+ }
716
+ });
717
+ };
718
+
719
+ const payEpay = async () => {
720
+ const invoiceData = await dataStore.getInvoiceData(formStore.applicationData.processInstanceId);
721
+ if (invoiceData === false || invoiceData.status === 3 || invoiceData.status === 0) {
722
+ if (invoiceData === false || invoiceData.status === 3) {
723
+ const created = await dataStore.createInvoice();
724
+ if (created) {
725
+ const ePayData = await dataStore.sendToEpay();
726
+ if (!ePayData) return;
727
+ formStore.epayLink = dataStore.sanitize(ePayData.link);
728
+ }
729
+ }
730
+ if (!!invoiceData && invoiceData.status === 0) {
731
+ const ePayData = await dataStore.sendToEpay();
732
+ if (!ePayData) return;
733
+ formStore.epayLink = dataStore.sanitize(ePayData.link);
734
+ }
735
+ } else {
736
+ if (invoiceData.paymentLink) {
737
+ formStore.epayLink = dataStore.sanitize(invoiceData.paymentLink);
738
+ } else {
739
+ dataStore.showToaster('error', dataStore.t('toaster.noUrl'));
740
+ }
741
+ }
742
+ if (!formStore.epayLink) {
743
+ dataStore.showToaster('error', dataStore.t('toaster.noUrl'));
744
+ return;
745
+ }
746
+ loading.value = false;
747
+ isEpayPay.value = true;
748
+ dataStore.panelAction = constants.actions.pay;
749
+ };
251
750
 
252
751
  return {
253
752
  // State
@@ -258,6 +757,18 @@ export default defineComponent({
258
757
  isSendNumberOpen,
259
758
  phoneNumber,
260
759
  selectedClient,
760
+ isPaperContract,
761
+ isScansDocuments,
762
+ isQr,
763
+ qrUrl,
764
+ scansFiles,
765
+ isQrLoading,
766
+ urlCopy,
767
+ isEpayPay,
768
+ isOfflinePay,
769
+ processCode,
770
+ isQrDialog,
771
+ email,
261
772
 
262
773
  // Functions
263
774
  closePanel,
@@ -266,6 +777,16 @@ export default defineComponent({
266
777
  openSmsPanel,
267
778
  openEpayPanel,
268
779
  onFileChange,
780
+ downloadTemplate,
781
+ onFileChangeScans,
782
+ sendFiles,
783
+ onClearFile,
784
+ closeQrPanel,
785
+ handlePayAction,
786
+ payEpay,
787
+ convertQr,
788
+ sendInvoiceToEmail,
789
+ hasConditionsAction,
269
790
 
270
791
  // Computed
271
792
  buttonText,
@@ -274,11 +795,24 @@ export default defineComponent({
274
795
  payingActions,
275
796
  acceptAction,
276
797
  affiliateActions,
798
+ chooseSignActions,
277
799
  paymentPeriod,
278
800
  insurancePremiumPerMonth,
279
801
  requestedSumInsured,
280
802
  affiliationDocument,
281
803
  hasConditionsInfo,
804
+ price,
805
+ insuredAmount,
806
+ isElectronicContract,
807
+ handleSignAction,
808
+ generateDocument,
809
+ isPaperDisabled,
810
+ isElectronicDisabled,
811
+ isScansDisabled,
812
+ isQrDisabled,
813
+ isQrXmlDisabled,
814
+ choosePayActions,
815
+ consentGiven,
282
816
  };
283
817
  },
284
818
  });
@@ -288,16 +822,19 @@ export default defineComponent({
288
822
  .v-expansion-panel-title__overlay {
289
823
  background: #ffffff;
290
824
  }
825
+
291
826
  .v-expansion-panel-title {
292
827
  height: 70px !important;
293
828
  padding: 10px 20px !important;
294
829
  }
830
+
295
831
  .v-expansion-panels--variant-accordion > :last-child {
296
832
  border-top-left-radius: 0.5rem !important;
297
833
  border-top-right-radius: 0.5rem !important;
298
834
  border-top-left-radius: 0.5rem !important;
299
835
  border-radius: 0.5rem !important;
300
836
  }
837
+
301
838
  .v-expansion-panel-text__wrapper {
302
839
  padding: 10px 20px !important;
303
840
  }