hl-core 0.0.10-beta.5 → 0.0.10-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.
- package/README.md +0 -2
- package/api/base.api.ts +345 -137
- package/api/interceptors.ts +3 -5
- package/components/Dialog/Dialog.vue +5 -1
- package/components/Dialog/FamilyDialog.vue +15 -4
- package/components/Form/DigitalDocument.vue +52 -0
- package/components/Form/FormSource.vue +30 -0
- package/components/Form/ManagerAttachment.vue +60 -11
- package/components/Form/ProductConditionsBlock.vue +12 -6
- package/components/Input/Datepicker.vue +5 -0
- package/components/Input/FileInput.vue +1 -1
- package/components/Input/FormInput.vue +5 -0
- package/components/Input/OtpInput.vue +25 -0
- package/components/Input/RoundedInput.vue +2 -0
- package/components/Input/RoundedSelect.vue +2 -0
- package/components/Input/TextAreaField.vue +71 -0
- package/components/Menu/MenuNav.vue +1 -1
- package/components/Pages/Anketa.vue +207 -176
- package/components/Pages/ContragentForm.vue +1 -1
- package/components/Pages/Documents.vue +452 -64
- package/components/Pages/MemberForm.vue +416 -180
- package/components/Pages/ProductConditions.vue +1021 -243
- package/components/Panel/PanelHandler.vue +297 -124
- package/components/Utilities/Chip.vue +1 -1
- package/components/Utilities/JsonViewer.vue +1 -2
- package/composables/classes.ts +124 -20
- package/composables/constants.ts +46 -1
- package/composables/index.ts +336 -8
- package/composables/styles.ts +8 -24
- package/configs/pwa.ts +1 -7
- package/layouts/clear.vue +1 -1
- package/layouts/default.vue +1 -1
- package/layouts/full.vue +1 -1
- package/locales/ru.json +90 -19
- package/nuxt.config.ts +10 -12
- package/package.json +12 -12
- package/plugins/head.ts +7 -1
- package/store/data.store.ts +966 -575
- package/store/member.store.ts +17 -6
- package/store/rules.ts +23 -3
- package/types/enum.ts +42 -2
- package/types/index.ts +111 -56
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
<div :class="[$styles.flexColNav]">
|
|
12
12
|
<base-content-block v-if="hasConditionsInfo" class="flex flex-col gap-3">
|
|
13
13
|
<span
|
|
14
|
-
>{{ `Сумма страховой премии ${paymentPeriod}:` }} <b>{{ `${insurancePremiumPerMonth}
|
|
14
|
+
>{{ `Сумма страховой премии ${paymentPeriod}:` }} <b>{{ `${insurancePremiumPerMonth}` }}</b></span
|
|
15
15
|
>
|
|
16
16
|
<span
|
|
17
|
-
>{{ `Запрашиваемая страховая сумма: ` }} <b>{{ `${requestedSumInsured}
|
|
17
|
+
>{{ `Запрашиваемая страховая сумма: ` }} <b>{{ `${requestedSumInsured}` }}</b>
|
|
18
18
|
</span>
|
|
19
19
|
</base-content-block>
|
|
20
20
|
<base-content-block v-if="$dataStore.isLifetrip" class="flex flex-col gap-3">
|
|
@@ -23,80 +23,31 @@
|
|
|
23
23
|
>
|
|
24
24
|
</base-content-block>
|
|
25
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" />
|
|
26
|
+
<base-btn :text="$dataStore.t('confirm.yes')" :loading="$dataStore.isButtonsLoading" @click="handleTask" />
|
|
27
|
+
<base-btn :btn="$styles.blueLightBtn" :loading="$dataStore.isButtonsLoading" :text="$dataStore.t('confirm.no')" @click="closePanel" />
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
30
30
|
</section>
|
|
31
31
|
<section v-if="chooseSignActions">
|
|
32
|
-
<div v-if="!isElectronicContract && !isPaperContract && !isScansDocuments && !isQr" :class="[$styles.flexColNav]">
|
|
32
|
+
<div v-if="!isElectronicContract && !isPaperContract && !isScansDocuments && !isQr && formStore.signatories.length === 0" :class="[$styles.flexColNav]">
|
|
33
33
|
<base-btn :text="$dataStore.t('buttons.sendOnPaper')" :disabled="isPaperDisabled" :loading="loading" @click="handleSignAction('paper')" />
|
|
34
34
|
<base-btn :text="$dataStore.t('buttons.sendElectronically')" :disabled="isElectronicDisabled" :loading="loading" @click="handleSignAction('electronic')" />
|
|
35
35
|
<base-btn :text="$dataStore.t('buttons.generatePrintedForms')" :disabled="isScansDisabled" :loading="loading" @click="handleSignAction('scans')" />
|
|
36
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
37
|
</div>
|
|
52
38
|
<div v-if="isPaperContract" :class="[$styles.flexColNav]">
|
|
53
39
|
<base-btn :text="$dataStore.t('buttons.downloadContract')" :loading="$dataStore.isButtonsLoading" @click="generateDocument" />
|
|
54
40
|
</div>
|
|
55
41
|
<div v-if="isScansDocuments" :class="[$styles.flexColNav]">
|
|
56
|
-
<div v-if="
|
|
57
|
-
<div
|
|
58
|
-
<
|
|
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>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
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
|
-
|
|
42
|
+
<div v-if="isNewSign">
|
|
43
|
+
<div class="flex flex-col gap-2">
|
|
44
|
+
<base-btn v-for="file in getFilesDownloadButtons" :text="`Скачать ${file.fileName}`" :loading="$dataStore.isButtonsLoading" @click="getDocNew(file)" />
|
|
85
45
|
<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
|
-
/>
|
|
46
|
+
<base-file-input v-for="file in signingFiles" :label="`Вложить ${file.fileName}`" @input.prevent="onFileChangeScansNew($event, file)" @onClear="onClearFileNew(file)" />
|
|
96
47
|
</base-form-section>
|
|
97
48
|
</div>
|
|
98
49
|
</div>
|
|
99
|
-
<div :class="[$styles.flexColNav]"
|
|
50
|
+
<div v-else :class="[$styles.flexColNav]">
|
|
100
51
|
<base-btn :text="$dataStore.t('buttons.downloadStatement')" @click="downloadTemplate(constants.documentTypes.statement, 'docx')" />
|
|
101
52
|
<base-btn :text="$dataStore.t('buttons.downloadContract')" @click="downloadTemplate(constants.documentTypes.contract, 'doc')" />
|
|
102
53
|
<base-btn :text="$dataStore.t('buttons.downloadApplication')" @click="downloadTemplate(constants.documentTypes.application1, 'vnd.ms-excel')" />
|
|
@@ -107,8 +58,15 @@
|
|
|
107
58
|
<base-file-input :label="$dataStore.t('labels.attachPowerOfAttorney')" @input.prevent="onFileChangeScans($event, 'attorney')" @onClear="onClearFile('attorney')" />
|
|
108
59
|
</base-form-section>
|
|
109
60
|
</div>
|
|
110
|
-
<base-btn :text="$dataStore.t('buttons.sign')" :loading="$dataStore.isButtonsLoading" @click="sendFiles" />
|
|
61
|
+
<base-btn :text="$dataStore.t('buttons.sign')" :loading="$dataStore.isButtonsLoading || loading" @click="isNewSign ? sendFilesNew() : sendFiles()" />
|
|
111
62
|
<base-btn :text="$dataStore.t('buttons.cancel')" :btn="$styles.whiteBtn" @click="isScansDocuments = false" />
|
|
63
|
+
<base-btn
|
|
64
|
+
v-if="isOnlineEnpf === false && $dataStore.isPension && formStore.applicationData.statusCode === 'AttachAppContractForm'"
|
|
65
|
+
class="mt-[2rem]"
|
|
66
|
+
:text="$dataStore.t('buttons.send')"
|
|
67
|
+
:loading="loading"
|
|
68
|
+
@click="$dataStore.panelAction = constants.actions.signed"
|
|
69
|
+
/>
|
|
112
70
|
</div>
|
|
113
71
|
<div v-if="isQr" :class="[$styles.flexColNav]">
|
|
114
72
|
<base-form-section :title="''">
|
|
@@ -121,10 +79,58 @@
|
|
|
121
79
|
<base-btn :text="$dataStore.t('buttons.cancel')" :btn="$styles.whiteBtn" @click="closeQrPanel" />
|
|
122
80
|
</base-form-section>
|
|
123
81
|
</div>
|
|
82
|
+
<div v-if="!(formStore.signatories.length === 0) && !isQr && !isScansDocuments" :class="[$styles.flexColNav]">
|
|
83
|
+
<div
|
|
84
|
+
v-if="(processCode === 19 || processCode === 25) && formStore.applicationData.statusCode === 'AttachAppContractForm'"
|
|
85
|
+
:class="[$styles.blueBgLight]"
|
|
86
|
+
class="rounded-lg p-4"
|
|
87
|
+
>
|
|
88
|
+
<base-form-toggle v-model="isOnlineEnpf" title="Онлайн подписание согласия для ЕНПФ" :has-border="false" @clicked="setActualEnpf" />
|
|
89
|
+
</div>
|
|
90
|
+
<div :class="[$styles.blueBgLight]" class="rounded-lg p-4">
|
|
91
|
+
<v-expansion-panels v-if="formStore.signatories.length" variant="accordion" :multiple="false">
|
|
92
|
+
<v-expansion-panel v-for="(person, index) of formStore.signatories" :key="person.personId!" class="border-[1px]" elevation="0" bg-color="#FFF">
|
|
93
|
+
<v-expansion-panel-title class="h-[80px]" :class="$styles.textTitle">
|
|
94
|
+
{{ person.longName }}
|
|
95
|
+
</v-expansion-panel-title>
|
|
96
|
+
<v-expansion-panel-text class="border-t-[1px]">
|
|
97
|
+
<section class="flex flex-col" :class="$styles.textSimple">
|
|
98
|
+
<v-expansion-panels v-if="person.fileDatas.length" v-model="currentFilePanel" :multiple="false">
|
|
99
|
+
<v-expansion-panel
|
|
100
|
+
v-for="(file, fileIndex) in groupBy(person.fileDatas, 'orderFile')"
|
|
101
|
+
:value="`${index} - ${fileIndex}`"
|
|
102
|
+
:disabled="inSigningOrder(person.fileDatas, fileIndex) || file.every((f: any) => f.isSigned === true)"
|
|
103
|
+
>
|
|
104
|
+
<v-expansion-panel-title v-for="name in file" class="h-[80px]" :class="$styles.textTitle">
|
|
105
|
+
{{ name.fileName }}
|
|
106
|
+
</v-expansion-panel-title>
|
|
107
|
+
<v-expansion-panel-text class="border-t-[1px]">
|
|
108
|
+
<section class="flex flex-col gap-4 py-3" :class="$styles.textSimple">
|
|
109
|
+
<base-btn
|
|
110
|
+
v-for="signtype in file[0].signTypes"
|
|
111
|
+
:text="signtype.documentSignTypeName"
|
|
112
|
+
:btn="$styles.greenBtn"
|
|
113
|
+
@click="newSign(signtype.documentSignTypeValue, file, index)"
|
|
114
|
+
:loading="loading"
|
|
115
|
+
/>
|
|
116
|
+
</section>
|
|
117
|
+
</v-expansion-panel-text>
|
|
118
|
+
</v-expansion-panel>
|
|
119
|
+
</v-expansion-panels>
|
|
120
|
+
</section>
|
|
121
|
+
</v-expansion-panel-text>
|
|
122
|
+
</v-expansion-panel>
|
|
123
|
+
</v-expansion-panels>
|
|
124
|
+
<base-list-empty v-else />
|
|
125
|
+
</div>
|
|
126
|
+
<base-animation>
|
|
127
|
+
<base-btn v-if="isAllPaperSigned" :text="$dataStore.t('buttons.send')" :loading="loading" @click="$dataStore.panelAction = constants.actions.signed" />
|
|
128
|
+
</base-animation>
|
|
129
|
+
</div>
|
|
124
130
|
</section>
|
|
125
131
|
<section v-if="choosePayActions">
|
|
126
132
|
<div v-if="!isEpayPay && !isOfflinePay" :class="[$styles.flexColNav]">
|
|
127
|
-
<base-btn :text="$dataStore.t('buttons.payEpay')" :loading="loading" @click="handlePayAction('epay')" />
|
|
133
|
+
<base-btn v-if="hasEpayPay" :text="$dataStore.t('buttons.payEpay')" :loading="loading" @click="handlePayAction('epay')" />
|
|
128
134
|
<base-btn :text="$dataStore.t('buttons.payOffline')" :loading="loading" @click="handlePayAction('offline')" />
|
|
129
135
|
</div>
|
|
130
136
|
<div v-if="isOfflinePay" :class="[$styles.flexColNav]">
|
|
@@ -178,7 +184,7 @@
|
|
|
178
184
|
</div>
|
|
179
185
|
</base-fade-transition>
|
|
180
186
|
<base-btn
|
|
181
|
-
v-if="
|
|
187
|
+
v-if="isElectronicContract"
|
|
182
188
|
:text="$dataStore.t('buttons.cancel')"
|
|
183
189
|
:btn="$styles.whiteBtn"
|
|
184
190
|
@click="
|
|
@@ -254,7 +260,8 @@
|
|
|
254
260
|
import { DocumentItem, Value } from '../../composables/classes';
|
|
255
261
|
import { HubConnectionBuilder } from '@microsoft/signalr';
|
|
256
262
|
import { uuid } from 'vue-uuid';
|
|
257
|
-
import type
|
|
263
|
+
import type * as Types from '../../types';
|
|
264
|
+
import { CoreEnums } from '../../types/enum';
|
|
258
265
|
|
|
259
266
|
export default defineComponent({
|
|
260
267
|
emits: ['task'],
|
|
@@ -276,14 +283,16 @@ export default defineComponent({
|
|
|
276
283
|
const isOfflinePay = ref<boolean>(false);
|
|
277
284
|
const isQrDialog = ref<boolean>(false);
|
|
278
285
|
const email = ref<string>('');
|
|
286
|
+
const signOptions = ref<Types.Api.Sign.New.Response>();
|
|
287
|
+
const signingFiles = ref<Types.Api.Sign.New.FileDatas[]>([]);
|
|
288
|
+
const isOnlineEnpf = ref<boolean>(true);
|
|
289
|
+
const currentFilePanel = ref<string[]>([]);
|
|
279
290
|
|
|
280
291
|
const vForm = ref<any>();
|
|
281
292
|
const isSendNumberOpen = ref<boolean>(false);
|
|
282
293
|
const phoneNumber = ref<string | null>(formStore.policyholderForm.phoneNumber ?? '');
|
|
283
|
-
const selectedClient = ref<SignUrlType>();
|
|
294
|
+
const selectedClient = ref<Types.SignUrlType>();
|
|
284
295
|
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));
|
|
287
296
|
const affiliationDocument = computed(() => formStore.signedDocumentList.find((file: DocumentItem) => file.fileTypeName === 'Решение АС'));
|
|
288
297
|
const affiliationData = ref<{
|
|
289
298
|
processInstanceId: string | number;
|
|
@@ -298,9 +307,17 @@ export default defineComponent({
|
|
|
298
307
|
const affiliationFormData = ref(new FormData());
|
|
299
308
|
const scansFormData = ref(new FormData());
|
|
300
309
|
const scansFiles = ref<any[]>([]);
|
|
310
|
+
const isAllPaperSigned = computed(() => formStore.signatories.every((person: any) => person.fileDatas.every((file: any) => file.isSigned === true && file.signedType === 2)));
|
|
301
311
|
const processCode = formStore.applicationData.processCode;
|
|
312
|
+
const getFilesDownloadButtons = computed(() => {
|
|
313
|
+
if (isOnlineEnpf.value === false && dataStore.isPension && formStore.applicationData.statusCode === 'ContractSignedFrom') {
|
|
314
|
+
return signingFiles.value.filter(i => i.fileType === 6);
|
|
315
|
+
} else {
|
|
316
|
+
return signingFiles.value;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
302
319
|
|
|
303
|
-
const openSmsPanel = (signInfo: SignUrlType) => {
|
|
320
|
+
const openSmsPanel = (signInfo: Types.SignUrlType) => {
|
|
304
321
|
if (signInfo) {
|
|
305
322
|
isSendNumberOpen.value = true;
|
|
306
323
|
selectedClient.value = signInfo;
|
|
@@ -328,10 +345,53 @@ export default defineComponent({
|
|
|
328
345
|
}
|
|
329
346
|
};
|
|
330
347
|
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
348
|
+
const inSigningOrder = (files: any, index: number) => {
|
|
349
|
+
for (
|
|
350
|
+
let i = 0;
|
|
351
|
+
i <
|
|
352
|
+
files.sort(function (a: any, b: any) {
|
|
353
|
+
return a.orderFile > b.orderFile ? 1 : b.orderFile > a.orderFile ? -1 : 0;
|
|
354
|
+
}).length;
|
|
355
|
+
i++
|
|
356
|
+
) {
|
|
357
|
+
if (!files[i].isSigned) {
|
|
358
|
+
return files[i].orderFile != index;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const getDocNew = async (file: any) => {
|
|
364
|
+
const newFile = signOptions.value?.signIds.find((i: any) => i.fileType == file.fileType);
|
|
365
|
+
if (newFile) await dataStore.getDocNew(newFile.id, 2, false, file.fileName);
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
const onFileChangeScansNew = async (event: InputEvent, file: any) => {
|
|
369
|
+
if (event.target) {
|
|
370
|
+
const files = (event.target as HTMLInputElement).files;
|
|
371
|
+
if (files && files.length) {
|
|
372
|
+
if (files[0].type !== 'application/pdf') return dataStore.showToaster('error', dataStore.t('toaster.onlyPDF'), 6000);
|
|
373
|
+
const { execute: getBase64 } = useBase64(files[0]);
|
|
374
|
+
const base64 = (await getBase64()).slice(28);
|
|
375
|
+
const data = {
|
|
376
|
+
FileBytes: base64,
|
|
377
|
+
FileName: file.fileName,
|
|
378
|
+
FileTypeCode: file.fileType,
|
|
379
|
+
};
|
|
380
|
+
if (!signOptions.value) return dataStore.showToaster('error', dataStore.t('pension.fileError'), 6000);
|
|
381
|
+
scansFiles.value.push({
|
|
382
|
+
groupId: signOptions.value.signIds.find((i: any) => i.fileType == data.FileTypeCode)?.id,
|
|
383
|
+
data: data,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
const onClearFileNew = async (file: any) => {
|
|
390
|
+
const result = scansFiles.value.filter(i => i.data.FileTypeCode !== file.fileType);
|
|
391
|
+
scansFiles.value = result;
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
const onFileChangeScans = async (event: InputEvent, type: 'statement' | 'contract' | 'pa_refundstatement' | 'pa_refundagreement' | 'app' | 'attorney' | 'agreement') => {
|
|
335
395
|
if (event.target) {
|
|
336
396
|
const files = (event.target as HTMLInputElement).files;
|
|
337
397
|
if (files && files.length) {
|
|
@@ -353,31 +413,20 @@ export default defineComponent({
|
|
|
353
413
|
}
|
|
354
414
|
};
|
|
355
415
|
|
|
356
|
-
const onClearFile = async (
|
|
357
|
-
type: 'statement' | 'pa_statement' | 'pa_refundstatement' | 'contract' | 'pa_contract' | 'pa_refundagreement' | 'app' | 'attorney' | 'agreement',
|
|
358
|
-
) => {
|
|
416
|
+
const onClearFile = async (type: 'statement' | 'contract' | 'pa_refundstatement' | 'pa_refundagreement' | 'app' | 'attorney' | 'agreement') => {
|
|
359
417
|
const doc = await selectedDocument(type);
|
|
360
418
|
const result = scansFiles.value.filter(i => JSON.parse(i.fileData)[0].fileTypeCode !== doc.code);
|
|
361
419
|
scansFiles.value = result;
|
|
362
420
|
};
|
|
363
421
|
|
|
364
|
-
const selectedDocument = (type: 'statement' | '
|
|
422
|
+
const selectedDocument = (type: 'statement' | 'contract' | 'pa_refundstatement' | 'pa_refundagreement' | 'app' | 'attorney' | 'agreement') => {
|
|
365
423
|
let selectedDocument: any;
|
|
366
424
|
if (type === 'statement') {
|
|
367
425
|
selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '32');
|
|
368
426
|
}
|
|
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
427
|
if (type === 'contract') {
|
|
376
428
|
selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '6');
|
|
377
429
|
}
|
|
378
|
-
if (type === 'pa_contract') {
|
|
379
|
-
selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '38');
|
|
380
|
-
}
|
|
381
430
|
if (type === 'pa_refundagreement') {
|
|
382
431
|
selectedDocument = dataStore.dicFileTypeList.find((i: Value) => i.code === '42');
|
|
383
432
|
}
|
|
@@ -393,14 +442,29 @@ export default defineComponent({
|
|
|
393
442
|
return selectedDocument;
|
|
394
443
|
};
|
|
395
444
|
|
|
445
|
+
const sendFilesNew = async () => {
|
|
446
|
+
if (scansFiles.value.length !== signingFiles.value.length) {
|
|
447
|
+
dataStore.showToaster('warning', dataStore.t('toaster.notAllDocumentsAttached'));
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
try {
|
|
451
|
+
await Promise.allSettled(
|
|
452
|
+
Object.values(scansFiles.value).map(async f => {
|
|
453
|
+
await dataStore.api.file.uploadFilesNew(f.groupId, f.data);
|
|
454
|
+
}),
|
|
455
|
+
);
|
|
456
|
+
await checkIfAllSigned(true);
|
|
457
|
+
scansFiles.value = [];
|
|
458
|
+
isScansDocuments.value = false;
|
|
459
|
+
dataStore.showToaster('info', 'Документы загружены успешно');
|
|
460
|
+
} catch (err) {
|
|
461
|
+
return ErrorHandler(err);
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
396
465
|
const sendFiles = async () => {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
? formStore.applicationData.statusCode === 'ContractSignedFrom'
|
|
400
|
-
? scansFiles.value.length !== 1
|
|
401
|
-
: scansFiles.value.length !== 2
|
|
402
|
-
: scansFiles.value.length !== 4
|
|
403
|
-
) {
|
|
466
|
+
loading.value = true;
|
|
467
|
+
if (scansFiles.value.length !== 4) {
|
|
404
468
|
dataStore.showToaster('warning', dataStore.t('toaster.notAllDocumentsAttached'));
|
|
405
469
|
return;
|
|
406
470
|
}
|
|
@@ -412,7 +476,8 @@ export default defineComponent({
|
|
|
412
476
|
}
|
|
413
477
|
closePanel();
|
|
414
478
|
dataStore.showToaster('success', dataStore.t('toaster.successOperation'));
|
|
415
|
-
await dataStore.handleTask(
|
|
479
|
+
await dataStore.handleTask(constants.actions.signed, route.params.taskId as string, 'scans');
|
|
480
|
+
loading.value = false;
|
|
416
481
|
};
|
|
417
482
|
const submitForm = async () => {
|
|
418
483
|
await vForm.value.validate().then(async (v: { valid: Boolean; errors: any }) => {
|
|
@@ -452,7 +517,7 @@ export default defineComponent({
|
|
|
452
517
|
// loading.value = false;
|
|
453
518
|
// return;
|
|
454
519
|
// }
|
|
455
|
-
if (dataStore.isAML || dataStore.isCheckContract || dataStore.isCheckContragent || dataStore.isDas || dataStore.isPrePension || dataStore.isUU) {
|
|
520
|
+
if (dataStore.isAML || dataStore.isCheckContract || dataStore.isCheckContragent || dataStore.isDas || dataStore.isPrePension || dataStore.isCritical || dataStore.isUU) {
|
|
456
521
|
emit('task', [dataStore.panelAction, route.params.taskId as string, actionCause.value]);
|
|
457
522
|
} else {
|
|
458
523
|
await dataStore.handleTask(dataStore.panelAction, route.params.taskId as string, actionCause.value);
|
|
@@ -462,12 +527,16 @@ export default defineComponent({
|
|
|
462
527
|
|
|
463
528
|
const onInit = async () => {
|
|
464
529
|
if (dataStore.controls.hasChooseSign) {
|
|
465
|
-
if (dataStore.isGons || dataStore.isLifeBusiness || dataStore.isPension || dataStore.isGns) {
|
|
530
|
+
if (dataStore.isBaiterek || dataStore.isGons || dataStore.isLifeBusiness || dataStore.isPension || dataStore.isGns) {
|
|
466
531
|
isElectronicContract.value = false;
|
|
467
532
|
}
|
|
468
533
|
}
|
|
469
534
|
if (dataStore.isPension) {
|
|
470
|
-
|
|
535
|
+
if (formStore.applicationData.pensionApp) {
|
|
536
|
+
const isOnlineEnpfAgreement = formStore.applicationData.pensionApp.isOnlineEnpfAgreement;
|
|
537
|
+
isOnlineEnpf.value = isOnlineEnpfAgreement === null ? true : isOnlineEnpfAgreement;
|
|
538
|
+
await dataStore.getSignedDocList(formStore.applicationData.processInstanceId);
|
|
539
|
+
}
|
|
471
540
|
}
|
|
472
541
|
};
|
|
473
542
|
|
|
@@ -523,25 +592,34 @@ export default defineComponent({
|
|
|
523
592
|
dataStore.panelAction === constants.actions.return ||
|
|
524
593
|
dataStore.panelAction === constants.actions.rejectclient,
|
|
525
594
|
);
|
|
526
|
-
const acceptAction = computed(() => dataStore.panelAction === constants.actions.accept);
|
|
595
|
+
const acceptAction = computed(() => dataStore.panelAction === constants.actions.accept || (dataStore.isPension && dataStore.panelAction === constants.actions.signed));
|
|
527
596
|
const signingActions = computed(() => dataStore.panelAction === constants.actions.sign);
|
|
528
597
|
const payingActions = computed(() => dataStore.panelAction === constants.actions.pay);
|
|
529
598
|
const affiliateActions = computed(() => dataStore.panelAction === constants.actions.affiliate);
|
|
530
599
|
const chooseSignActions = computed(() => dataStore.controls.hasChooseSign && dataStore.panelAction === constants.actions.chooseSign);
|
|
531
600
|
const choosePayActions = computed(() => dataStore.controls.hasChoosePay && dataStore.panelAction === constants.actions.choosePay);
|
|
532
|
-
|
|
601
|
+
// TODO на все продукты новое подписание
|
|
602
|
+
const isNewSign = computed(() => dataStore.isPension || dataStore.isGons || dataStore.isBaiterek);
|
|
533
603
|
const paymentPeriod = computed(() => formStore.productConditionsForm.paymentPeriod.nameRu);
|
|
534
|
-
const insurancePremiumPerMonth = computed(() =>
|
|
604
|
+
const insurancePremiumPerMonth = computed(() => {
|
|
605
|
+
if (dataStore.isGons && formStore.productConditionsForm.currency.code === 'USD') {
|
|
606
|
+
return `${formStore.productConditionsForm.insurancePremiumPerMonthInDollar}$`;
|
|
607
|
+
}
|
|
608
|
+
return `${formStore.productConditionsForm.insurancePremiumPerMonth}₸`;
|
|
609
|
+
});
|
|
535
610
|
const requestedSumInsured = computed(() => {
|
|
536
611
|
if ((dataStore.isLifeBusiness || dataStore.isGns) && formStore.productConditionsForm.requestedSumInsured === null) {
|
|
537
612
|
return dataStore.getNumberWithSpaces(formStore.applicationData.policyAppDto!.mainInsSum);
|
|
538
613
|
}
|
|
539
|
-
|
|
614
|
+
if (dataStore.isGons && formStore.productConditionsForm.currency.code === 'USD') {
|
|
615
|
+
return `${formStore.productConditionsForm.requestedSumInsuredInDollar}$`;
|
|
616
|
+
}
|
|
617
|
+
return `${formStore.productConditionsForm.requestedSumInsured}₸`;
|
|
540
618
|
});
|
|
541
619
|
const price = computed(() => dataStore.getNumberWithSpaces(formStore.productConditionsForm.calculatorForm.price));
|
|
542
620
|
const insuredAmount = computed(() => formStore.productConditionsForm.calculatorForm.amount!.nameRu! + dataStore.currency);
|
|
543
621
|
const hasConditionsInfo = computed(() => {
|
|
544
|
-
if (dataStore.isLifetrip || dataStore.isDas || dataStore.isUU || dataStore.isPrePension) {
|
|
622
|
+
if (dataStore.isLifetrip || dataStore.isDas || dataStore.isUU || dataStore.isPrePension || dataStore.isCritical || dataStore.isPension) {
|
|
545
623
|
return false;
|
|
546
624
|
}
|
|
547
625
|
if (dataStore.isFinCenter()) {
|
|
@@ -550,7 +628,7 @@ export default defineComponent({
|
|
|
550
628
|
return true;
|
|
551
629
|
});
|
|
552
630
|
const hasConditionsAction = computed(() => {
|
|
553
|
-
if (dataStore.isPrePension) {
|
|
631
|
+
if (dataStore.isPrePension || dataStore.isCritical) {
|
|
554
632
|
return false;
|
|
555
633
|
}
|
|
556
634
|
return true;
|
|
@@ -562,7 +640,7 @@ export default defineComponent({
|
|
|
562
640
|
return true;
|
|
563
641
|
});
|
|
564
642
|
const isElectronicDisabled = computed(() => {
|
|
565
|
-
if (dataStore.isGons || dataStore.isLifeBusiness || dataStore.isGns
|
|
643
|
+
if (dataStore.isGons || dataStore.isLifeBusiness || dataStore.isGns) {
|
|
566
644
|
return true;
|
|
567
645
|
}
|
|
568
646
|
return false;
|
|
@@ -571,28 +649,22 @@ export default defineComponent({
|
|
|
571
649
|
if (dataStore.isGons) {
|
|
572
650
|
return true;
|
|
573
651
|
}
|
|
574
|
-
if ((!consentGiven.value || formStore.applicationData.statusCode === 'HeadManagerForm') && dataStore.isPension && processCode !== 2) {
|
|
575
|
-
return true;
|
|
576
|
-
}
|
|
577
652
|
return false;
|
|
578
653
|
});
|
|
579
654
|
const isQrDisabled = computed(() => {
|
|
580
|
-
if (consentGiven.value && dataStore.isPension && processCode !== 2) {
|
|
581
|
-
return false;
|
|
582
|
-
}
|
|
583
655
|
return true;
|
|
584
656
|
});
|
|
585
657
|
const isQrXmlDisabled = computed(() => {
|
|
586
|
-
if (!consentGiven.value && dataStore.isPension && processCode !== 2) {
|
|
587
|
-
return false;
|
|
588
|
-
}
|
|
589
658
|
if (dataStore.isLifeBusiness || dataStore.isGns) {
|
|
590
659
|
return false;
|
|
591
660
|
}
|
|
592
661
|
return true;
|
|
593
662
|
});
|
|
594
663
|
const isSignatureDisabled = computed(() => {
|
|
595
|
-
|
|
664
|
+
return true;
|
|
665
|
+
});
|
|
666
|
+
const hasEpayPay = computed(() => {
|
|
667
|
+
if (dataStore.isLifeBusiness || dataStore.isGns) {
|
|
596
668
|
return false;
|
|
597
669
|
}
|
|
598
670
|
return true;
|
|
@@ -601,7 +673,7 @@ export default defineComponent({
|
|
|
601
673
|
await dataStore.downloadTemplate(documentType, fileType, formStore.applicationData.processInstanceId);
|
|
602
674
|
};
|
|
603
675
|
|
|
604
|
-
const handleSignAction = async (type: 'paper' | 'electronic' | 'scans' | 'qr' | 'qrXml'
|
|
676
|
+
const handleSignAction = async (type: 'paper' | 'electronic' | 'scans' | 'qr' | 'qrXml') => {
|
|
605
677
|
loading.value = true;
|
|
606
678
|
if (type === 'electronic') {
|
|
607
679
|
await dataStore.signDocument();
|
|
@@ -630,9 +702,6 @@ export default defineComponent({
|
|
|
630
702
|
isQr.value = true;
|
|
631
703
|
}
|
|
632
704
|
}
|
|
633
|
-
if (type === 'signature') {
|
|
634
|
-
await dataStore.signDocument('signature');
|
|
635
|
-
}
|
|
636
705
|
loading.value = false;
|
|
637
706
|
};
|
|
638
707
|
|
|
@@ -680,11 +749,7 @@ export default defineComponent({
|
|
|
680
749
|
isQrLoading.value = true;
|
|
681
750
|
} else if (message === 'Signed') {
|
|
682
751
|
isQrLoading.value = false;
|
|
683
|
-
|
|
684
|
-
dataStore.showToaster('info', dataStore.t('pension.signInProcess'));
|
|
685
|
-
} else {
|
|
686
|
-
dataStore.showToaster('success', dataStore.t('sign.successQrSigned'));
|
|
687
|
-
}
|
|
752
|
+
dataStore.showToaster('success', dataStore.isPension ? 'Подписание прошло успешно' : dataStore.t('sign.successQrSigned'));
|
|
688
753
|
qrUrl.value = '';
|
|
689
754
|
isQr.value = false;
|
|
690
755
|
dataStore.panel.open = false;
|
|
@@ -706,7 +771,7 @@ export default defineComponent({
|
|
|
706
771
|
data.append('name', 'PAEnpf_Agreement');
|
|
707
772
|
data.append('format', 'xml');
|
|
708
773
|
data.append('EdsXmlId', groupId ?? '');
|
|
709
|
-
await dataStore.api.uploadXml(data);
|
|
774
|
+
await dataStore.api.file.uploadXml(data);
|
|
710
775
|
await dataStore.getSignedDocList(dataStore.formStore.applicationData.processInstanceId);
|
|
711
776
|
dataStore.showToaster('success', dataStore.t('pension.consentGiven'), 3000);
|
|
712
777
|
}
|
|
@@ -742,7 +807,7 @@ export default defineComponent({
|
|
|
742
807
|
await dataStore.generateDocument();
|
|
743
808
|
};
|
|
744
809
|
|
|
745
|
-
const convertQr = async (url: string | null, template?: Api.GenerateShortLink.Templates) => {
|
|
810
|
+
const convertQr = async (url: string | null, template?: Types.Api.GenerateShortLink.Templates) => {
|
|
746
811
|
if (url) {
|
|
747
812
|
const shortedUrl = await dataStore.generateShortLink(url, template);
|
|
748
813
|
qrUrl.value = typeof shortedUrl === 'string' && !!shortedUrl ? shortedUrl : url;
|
|
@@ -793,6 +858,99 @@ export default defineComponent({
|
|
|
793
858
|
dataStore.panelAction = constants.actions.pay;
|
|
794
859
|
};
|
|
795
860
|
|
|
861
|
+
const groupBy = (data: any, key: string) => {
|
|
862
|
+
return data.reduce((results: any, item: any) => {
|
|
863
|
+
results[item[key]] = results[item[key]] || [];
|
|
864
|
+
results[item[key]].push(item);
|
|
865
|
+
return results;
|
|
866
|
+
}, {});
|
|
867
|
+
};
|
|
868
|
+
|
|
869
|
+
const checkIfAllSigned = async (sendTask: boolean = false) => {
|
|
870
|
+
await dataStore.generateSign(route.params.taskId as string);
|
|
871
|
+
formStore.signatories.find(async (person: any) => {
|
|
872
|
+
if (person.fileDatas.find((file: any) => file.isSigned === false) === undefined) {
|
|
873
|
+
if (formStore.applicationData.statusCode !== 'ContractSignedFrom') {
|
|
874
|
+
// TODO better if condition
|
|
875
|
+
// dataStore.showToaster(
|
|
876
|
+
// 'success',
|
|
877
|
+
// dataStore.t(`pension.${formStore.applicationData.statusCode === 'HeadManagerForm' ? 'signInProcessManager' : 'signInProcess'}`),
|
|
878
|
+
// 30000,
|
|
879
|
+
// );
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
const newSign = async (signType: number, file: any, index: number) => {
|
|
886
|
+
loading.value = true;
|
|
887
|
+
const data = {
|
|
888
|
+
...formStore.signatories[index],
|
|
889
|
+
signType: signType,
|
|
890
|
+
fileDatas: file,
|
|
891
|
+
} as Types.Api.Sign.New.GeneralResponse;
|
|
892
|
+
try {
|
|
893
|
+
signOptions.value = await dataStore.generalSign(data);
|
|
894
|
+
if (signOptions.value) {
|
|
895
|
+
switch (signType) {
|
|
896
|
+
case CoreEnums.Sign.Types.electronic:
|
|
897
|
+
// @ts-ignore
|
|
898
|
+
formStore.signUrls = [signOptions.value];
|
|
899
|
+
isElectronicContract.value = true;
|
|
900
|
+
dataStore.panelAction = constants.actions.sign;
|
|
901
|
+
break;
|
|
902
|
+
case CoreEnums.Sign.Types.scans:
|
|
903
|
+
isScansDocuments.value = true;
|
|
904
|
+
signingFiles.value = data.fileDatas && Array.isArray(data.fileDatas) ? data.fileDatas.filter(i => i.isSigned !== true) : [];
|
|
905
|
+
break;
|
|
906
|
+
case CoreEnums.Sign.Types.qr:
|
|
907
|
+
if (!signOptions.value.signatureDocumentGroupId) return dataStore.showToaster('error', 'Ошибка при подписании документов через eGov mobile', 10000);
|
|
908
|
+
await generateQR(signOptions.value.signatureDocumentGroupId);
|
|
909
|
+
isQr.value = true;
|
|
910
|
+
break;
|
|
911
|
+
case CoreEnums.Sign.Types.qrXml:
|
|
912
|
+
if (!signOptions.value.edsXmlId) return dataStore.showToaster('error', 'Ошибка при подписании документов через eGov mobile для ENPF', 10000);
|
|
913
|
+
await generateQR(signOptions.value.edsXmlId, 'xml');
|
|
914
|
+
isQr.value = true;
|
|
915
|
+
break;
|
|
916
|
+
case CoreEnums.Sign.Types.nclayer:
|
|
917
|
+
for (let each of file.filter((i: any) => i.isSigned !== true)) {
|
|
918
|
+
const signingFile = signOptions.value.signIds.find((i: any) => Number(i.fileType) === Number(each.fileType));
|
|
919
|
+
if (signingFile) {
|
|
920
|
+
const response = await dataStore.nclayerSign(signingFile.id, signType, Number(each.fileType) === 43);
|
|
921
|
+
if (response === null) {
|
|
922
|
+
dataStore.showToaster('error', 'Ошибка при подключении к приложению «NCALayer». Убедитесь, что запустили приложение «NCALayer»', 10000);
|
|
923
|
+
break;
|
|
924
|
+
}
|
|
925
|
+
if (!response) break;
|
|
926
|
+
if (response === true) dataStore.showToaster('success', 'Подписание прошло успешно');
|
|
927
|
+
} else {
|
|
928
|
+
dataStore.showToaster('error', 'Не найдены данные для подписания файла');
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
break;
|
|
932
|
+
default:
|
|
933
|
+
break;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
await checkIfAllSigned();
|
|
937
|
+
currentFilePanel.value = [];
|
|
938
|
+
} catch (err) {
|
|
939
|
+
ErrorHandler(err);
|
|
940
|
+
}
|
|
941
|
+
loading.value = false;
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
const setActualEnpf = useDebounceFn(async () => {
|
|
945
|
+
try {
|
|
946
|
+
await dataStore.api.file.setActualEnpf({ processId: String(formStore.applicationData.processInstanceId), isOnlineEnpfAgreement: isOnlineEnpf.value });
|
|
947
|
+
await dataStore.generateSign(String(route.params.taskId));
|
|
948
|
+
} catch (err) {
|
|
949
|
+
ErrorHandler(err);
|
|
950
|
+
}
|
|
951
|
+
currentFilePanel.value = [];
|
|
952
|
+
}, 1000);
|
|
953
|
+
|
|
796
954
|
return {
|
|
797
955
|
// State
|
|
798
956
|
formStore,
|
|
@@ -814,6 +972,10 @@ export default defineComponent({
|
|
|
814
972
|
processCode,
|
|
815
973
|
isQrDialog,
|
|
816
974
|
email,
|
|
975
|
+
signOptions,
|
|
976
|
+
signingFiles,
|
|
977
|
+
isOnlineEnpf,
|
|
978
|
+
currentFilePanel,
|
|
817
979
|
|
|
818
980
|
// Functions
|
|
819
981
|
closePanel,
|
|
@@ -825,11 +987,13 @@ export default defineComponent({
|
|
|
825
987
|
downloadTemplate,
|
|
826
988
|
onFileChangeScans,
|
|
827
989
|
sendFiles,
|
|
990
|
+
sendFilesNew,
|
|
828
991
|
onClearFile,
|
|
829
992
|
closeQrPanel,
|
|
830
993
|
handlePayAction,
|
|
831
994
|
payEpay,
|
|
832
995
|
convertQr,
|
|
996
|
+
setActualEnpf,
|
|
833
997
|
sendInvoiceToEmail,
|
|
834
998
|
hasConditionsAction,
|
|
835
999
|
|
|
@@ -842,6 +1006,7 @@ export default defineComponent({
|
|
|
842
1006
|
affiliateActions,
|
|
843
1007
|
chooseSignActions,
|
|
844
1008
|
paymentPeriod,
|
|
1009
|
+
isAllPaperSigned,
|
|
845
1010
|
insurancePremiumPerMonth,
|
|
846
1011
|
requestedSumInsured,
|
|
847
1012
|
affiliationDocument,
|
|
@@ -858,7 +1023,15 @@ export default defineComponent({
|
|
|
858
1023
|
isQrXmlDisabled,
|
|
859
1024
|
isSignatureDisabled,
|
|
860
1025
|
choosePayActions,
|
|
861
|
-
|
|
1026
|
+
groupBy,
|
|
1027
|
+
newSign,
|
|
1028
|
+
onFileChangeScansNew,
|
|
1029
|
+
onClearFileNew,
|
|
1030
|
+
getDocNew,
|
|
1031
|
+
inSigningOrder,
|
|
1032
|
+
isNewSign,
|
|
1033
|
+
hasEpayPay,
|
|
1034
|
+
getFilesDownloadButtons,
|
|
862
1035
|
};
|
|
863
1036
|
},
|
|
864
1037
|
});
|