hl-core 0.0.9-beta.9 → 0.0.10-beta.10

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