hl-core 0.0.10-beta.64 → 0.0.10-beta.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/base.api.ts +27 -1
- package/api/interceptors.ts +166 -60
- package/components/Form/ManagerAttachment.vue +29 -4
- package/components/Input/TextHint.vue +13 -0
- package/components/Pages/Auth.vue +2 -5
- package/components/Pages/ContragentForm.vue +23 -17
- package/components/Pages/MemberForm.vue +177 -45
- package/components/Pages/ProductConditions.vue +214 -61
- package/composables/classes.ts +17 -0
- package/composables/index.ts +36 -9
- package/layouts/default.vue +1 -1
- package/locales/ru.json +17 -4
- package/package.json +1 -1
- package/store/data.store.ts +52 -15
- package/store/rules.ts +8 -0
- package/types/enum.ts +3 -0
- package/types/index.ts +3 -0
package/api/base.api.ts
CHANGED
|
@@ -503,7 +503,7 @@ export class ApiClass {
|
|
|
503
503
|
}
|
|
504
504
|
|
|
505
505
|
async availableToAccureStartEducationalCapital(id: string | number) {
|
|
506
|
-
return await this.axiosCall<
|
|
506
|
+
return await this.axiosCall<any>({
|
|
507
507
|
method: Methods.GET,
|
|
508
508
|
url: `/${this.productUrl}/api/Application/AvailableToAccureStartEducationalCapital?processInstanceId=${id}`,
|
|
509
509
|
});
|
|
@@ -617,6 +617,14 @@ export class ApiClass {
|
|
|
617
617
|
});
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
+
async checkExistProcess(iin: string, processCode: number) {
|
|
621
|
+
return await this.axiosCall<string>({
|
|
622
|
+
method: Methods.GET,
|
|
623
|
+
url: '/Arm/api/Bpm/CheckExistProcess',
|
|
624
|
+
params: { iin, processCode },
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
|
|
620
628
|
async getContragentFromGBDFL(data: Types.Api.GBD.Request) {
|
|
621
629
|
return await this.axiosCall<Types.Api.GBD.Response>({
|
|
622
630
|
method: Methods.POST,
|
|
@@ -1104,6 +1112,16 @@ export class ApiClass {
|
|
|
1104
1112
|
});
|
|
1105
1113
|
}
|
|
1106
1114
|
|
|
1115
|
+
async setIsNotCalculated(processInstanceId: string | number) {
|
|
1116
|
+
return await this.axiosCall<boolean>({
|
|
1117
|
+
method: Methods.POST,
|
|
1118
|
+
url: `/${this.productUrl}/api/Application/SetIsNotCalculated`,
|
|
1119
|
+
params: {
|
|
1120
|
+
processInstanceId,
|
|
1121
|
+
},
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1107
1125
|
async checkProActiveService(processInstanceId: string | number, iin: string) {
|
|
1108
1126
|
return await this.axiosCall({
|
|
1109
1127
|
method: Methods.GET,
|
|
@@ -1180,6 +1198,14 @@ export class ApiClass {
|
|
|
1180
1198
|
data: data,
|
|
1181
1199
|
});
|
|
1182
1200
|
},
|
|
1201
|
+
resetApplicationData: async (processInstanceId: string | number) => {
|
|
1202
|
+
return await this.axiosCall<void>({
|
|
1203
|
+
method: Methods.POST,
|
|
1204
|
+
baseURL: getStrValuePerEnv('efoBaseApi'),
|
|
1205
|
+
url: `${this.pensionannuityNew.base}/ResetApplicationData`,
|
|
1206
|
+
params: { processInstanceId },
|
|
1207
|
+
});
|
|
1208
|
+
},
|
|
1183
1209
|
};
|
|
1184
1210
|
|
|
1185
1211
|
externalServices = {
|
package/api/interceptors.ts
CHANGED
|
@@ -1,46 +1,107 @@
|
|
|
1
|
-
import { AxiosError, type AxiosInstance } from 'axios';
|
|
1
|
+
import { AxiosError, type AxiosInstance, type InternalAxiosRequestConfig, isAxiosError } from 'axios';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Обновляет baseURL в зависимости от текущего хоста
|
|
5
|
+
*/
|
|
6
|
+
function updateBaseUrlForEnvironment(request: InternalAxiosRequestConfig): void {
|
|
7
|
+
if (!request.url || !request.baseURL) return;
|
|
8
|
+
|
|
9
|
+
const host = window.location.hostname;
|
|
10
|
+
|
|
11
|
+
if (host.startsWith('bpmsrv02') || host.startsWith('vega')) {
|
|
12
|
+
if (request.baseURL === getStrValuePerEnv('baseApi')) {
|
|
13
|
+
request.baseURL = getStrValuePerEnv('baseApiLocal');
|
|
14
|
+
}
|
|
15
|
+
if (request.baseURL === getStrValuePerEnv('efoBaseApi')) {
|
|
16
|
+
request.baseURL = getStrValuePerEnv('efoBaseApiLocal');
|
|
17
|
+
}
|
|
18
|
+
if (request.baseURL === getStrValuePerEnv('amlBaseApi')) {
|
|
19
|
+
request.baseURL = getStrValuePerEnv('amlBaseApiLocal');
|
|
20
|
+
}
|
|
21
|
+
if (request.baseURL === getStrValuePerEnv('gatewayApiUrl')) {
|
|
22
|
+
request.baseURL = getStrValuePerEnv('gatewayApiUrlLocal');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Обрабатывает специальную логику для нового API
|
|
29
|
+
*/
|
|
30
|
+
function handleNewApiLogic(request: InternalAxiosRequestConfig): void {
|
|
31
|
+
if (!request.url || !request.baseURL) return;
|
|
32
|
+
|
|
33
|
+
if (import.meta.env.VITE_ON_NEW_API === 'true' && request.url.includes('api/Application')) {
|
|
34
|
+
if (request.baseURL === 'http://vega:84') {
|
|
35
|
+
request.baseURL = 'http://efo-dev.halyklife.nb/api';
|
|
36
|
+
}
|
|
37
|
+
if (request.baseURL === 'http://bpmsrv02.halyklife.nb') {
|
|
38
|
+
request.baseURL = 'http://efo-prod.halyklife.nb/api';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
request.url = request.url.replace('/api/Application', '');
|
|
42
|
+
|
|
43
|
+
if (request.baseURL.includes('api/v1/insis')) {
|
|
44
|
+
request.baseURL = request.baseURL.replace('api/v1/insis', 'efo/api');
|
|
45
|
+
}
|
|
46
|
+
if (request.baseURL.includes('api/v1/test/insis')) {
|
|
47
|
+
request.baseURL = request.baseURL.replace('api/v1/test/insis', 'test/efo/api');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Извлекает полезное сообщение об ошибке из ответа
|
|
54
|
+
*/
|
|
55
|
+
function extractErrorMessage(data: any, status: number, dataStore: any): string {
|
|
56
|
+
// .NET ProblemDetails
|
|
57
|
+
if (data && typeof data === 'object') {
|
|
58
|
+
if (data.title || data.detail) {
|
|
59
|
+
return data.title || data.detail;
|
|
60
|
+
}
|
|
61
|
+
// Распространённые поля
|
|
62
|
+
if (data.message || data.status || data.statusName) {
|
|
63
|
+
return data.message || data.status || data.statusName;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Если строка/HTML
|
|
68
|
+
if (typeof data === 'string') {
|
|
69
|
+
return data.slice(0, 200);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Фолбэк
|
|
73
|
+
return status === 500 ? dataStore.t('toaster.serverError') : `HTTP ${status}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Настраивает interceptors для axios instance
|
|
78
|
+
*
|
|
79
|
+
* @param axios - Экземпляр axios для настройки
|
|
80
|
+
*
|
|
81
|
+
* Включает:
|
|
82
|
+
* - Автоматическое добавление токена авторизации
|
|
83
|
+
* - Обработку различных окружений (dev/prod)
|
|
84
|
+
* - Комплексную обработку ошибок с информативными сообщениями
|
|
85
|
+
* - Мягкую обработку 401 ошибок с сохранением redirect URL
|
|
86
|
+
* - Защиту от дублирования 401 ошибок
|
|
87
|
+
*/
|
|
88
|
+
export default function setupInterceptors(axios: AxiosInstance): void {
|
|
4
89
|
axios.interceptors.request.use(
|
|
5
|
-
request => {
|
|
90
|
+
(request: InternalAxiosRequestConfig) => {
|
|
6
91
|
const dataStore = useDataStore();
|
|
92
|
+
|
|
93
|
+
// Добавляем токен авторизации
|
|
7
94
|
if (dataStore.accessToken) {
|
|
95
|
+
request.headers = request.headers || {};
|
|
8
96
|
request.headers.Authorization = `Bearer ${dataStore.accessToken}`;
|
|
9
97
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
request.baseURL = getStrValuePerEnv('efoBaseApiLocal');
|
|
18
|
-
}
|
|
19
|
-
if (request.baseURL === getStrValuePerEnv('amlBaseApi')) {
|
|
20
|
-
request.baseURL = getStrValuePerEnv('amlBaseApiLocal');
|
|
21
|
-
}
|
|
22
|
-
if (request.baseURL === getStrValuePerEnv('gatewayApiUrl')) {
|
|
23
|
-
request.baseURL = getStrValuePerEnv('gatewayApiUrlLocal');
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (import.meta.env.VITE_ON_NEW_API === 'true') {
|
|
27
|
-
if (request.url.includes('api/Application')) {
|
|
28
|
-
if (request.baseURL === 'http://vega:84') {
|
|
29
|
-
request.baseURL = 'http://efo-dev.halyklife.nb/api';
|
|
30
|
-
}
|
|
31
|
-
if (request.baseURL === 'http://bpmsrv02.halyklife.nb') {
|
|
32
|
-
request.baseURL = 'http://efo-prod.halyklife.nb/api';
|
|
33
|
-
}
|
|
34
|
-
request.url = request.url.replace('/api/Application', '');
|
|
35
|
-
if (request.baseURL.includes('api/v1/insis')) {
|
|
36
|
-
request.baseURL = request.baseURL.replace('api/v1/insis', 'efo/api');
|
|
37
|
-
}
|
|
38
|
-
if (request.baseURL.includes('api/v1/test/insis')) {
|
|
39
|
-
request.baseURL = request.baseURL.replace('api/v1/test/insis', 'test/efo/api');
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
98
|
+
|
|
99
|
+
// Обновляем baseURL для разных окружений
|
|
100
|
+
updateBaseUrlForEnvironment(request);
|
|
101
|
+
|
|
102
|
+
// Обрабатываем логику нового API
|
|
103
|
+
handleNewApiLogic(request);
|
|
104
|
+
|
|
44
105
|
return request;
|
|
45
106
|
},
|
|
46
107
|
(error: AxiosError) => {
|
|
@@ -48,32 +109,77 @@ export default function (axios: AxiosInstance) {
|
|
|
48
109
|
},
|
|
49
110
|
);
|
|
50
111
|
axios.interceptors.response.use(
|
|
51
|
-
response =>
|
|
52
|
-
|
|
53
|
-
},
|
|
54
|
-
(error: AxiosError) => {
|
|
112
|
+
response => response,
|
|
113
|
+
(err: unknown) => {
|
|
55
114
|
const dataStore = useDataStore();
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
115
|
+
|
|
116
|
+
// если калькулятор, выходим (твоя логика)
|
|
117
|
+
if (dataStore.isCalculator) {
|
|
118
|
+
return Promise.reject(err);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 1) Не-Axios ошибка (например, thrown Error)
|
|
122
|
+
if (!isAxiosError(err)) {
|
|
123
|
+
dataStore.showToaster('error', dataStore.t('toaster.unknownError'), 5000);
|
|
124
|
+
return Promise.reject(err);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const { response, request, code, message, config } = err;
|
|
128
|
+
|
|
129
|
+
// 2) Нет ответа вообще (timeout, сеть, CORS)
|
|
130
|
+
if (!response) {
|
|
131
|
+
const isTimeout = code === 'ECONNABORTED' || /timeout/i.test(String(message));
|
|
132
|
+
dataStore.showToaster('error', isTimeout ? dataStore.t('toaster.timeout') : dataStore.t('toaster.networkError'), 5000);
|
|
133
|
+
return Promise.reject(err);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const status = response.status;
|
|
137
|
+
const data = response.data;
|
|
138
|
+
|
|
139
|
+
// 3) 401 — простая обработка, показываем ошибку
|
|
140
|
+
if (status === 401) {
|
|
141
|
+
dataStore.showToaster('error', dataStore.t('error.401'), 5000);
|
|
142
|
+
return Promise.reject(err);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// 4) 403 — вытаскиваем только path без query/hash
|
|
146
|
+
if (status === 403) {
|
|
147
|
+
try {
|
|
148
|
+
const rawUrl = response.config?.url ?? '';
|
|
149
|
+
const urlObj = new URL(rawUrl, window.location.origin);
|
|
150
|
+
const pathSegment = urlObj.pathname.split('/').filter(Boolean).pop() ?? 'resource';
|
|
151
|
+
dataStore.showToaster('error', dataStore.t('error.403', { text: pathSegment }), 5000);
|
|
152
|
+
} catch (urlError) {
|
|
153
|
+
console.warn('Error parsing URL for 403 response:', urlError);
|
|
154
|
+
dataStore.showToaster('error', dataStore.t('error.403'), 5000);
|
|
74
155
|
}
|
|
156
|
+
return Promise.reject(err);
|
|
75
157
|
}
|
|
76
|
-
|
|
158
|
+
|
|
159
|
+
// 5) 404
|
|
160
|
+
if (status === 404) {
|
|
161
|
+
dataStore.showToaster('error', dataStore.t('error.404'), 5000);
|
|
162
|
+
return Promise.reject(err);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 6) 413
|
|
166
|
+
if (status === 413) {
|
|
167
|
+
dataStore.showToaster('error', dataStore.t('error.exceedUploadLimitFile'), 5000);
|
|
168
|
+
return Promise.reject(err);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 7) 500 — явная обработка
|
|
172
|
+
if (status === 500) {
|
|
173
|
+
const errorMessage = extractErrorMessage(data, status, dataStore);
|
|
174
|
+
dataStore.showToaster('error', String(errorMessage), 5000);
|
|
175
|
+
return Promise.reject(err);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 8) Прочие коды — показываем полезное сообщение
|
|
179
|
+
const errorMessage = extractErrorMessage(data, status, dataStore);
|
|
180
|
+
dataStore.showToaster('error', String(errorMessage), 5000);
|
|
181
|
+
|
|
182
|
+
return Promise.reject(err);
|
|
77
183
|
},
|
|
78
184
|
);
|
|
79
185
|
}
|
|
@@ -156,29 +156,54 @@ export default defineComponent({
|
|
|
156
156
|
const isSaleChanellReadonly = computed(() => {
|
|
157
157
|
if (!isReadonly.value) {
|
|
158
158
|
if (dataStore.isTravelAgent()) return true;
|
|
159
|
-
if (dataStore.isGons)
|
|
159
|
+
if (dataStore.isGons) {
|
|
160
|
+
return !dataStore.isServiceManager() &&
|
|
161
|
+
!dataStore.isChiefManagerNSZH() &&
|
|
162
|
+
!dataStore.isChiefSalesManager() &&
|
|
163
|
+
!dataStore.isSalesManager() &&
|
|
164
|
+
!dataStore.isManager();
|
|
165
|
+
}
|
|
160
166
|
}
|
|
161
167
|
return isReadonly.value;
|
|
162
168
|
});
|
|
163
169
|
const isRegionReadonly = computed(() => {
|
|
164
170
|
if (!isReadonly.value) {
|
|
165
171
|
if (dataStore.isTravelAgent()) return true;
|
|
166
|
-
if (dataStore.isGons)
|
|
172
|
+
if (dataStore.isGons) {
|
|
173
|
+
return !dataStore.isServiceManager() &&
|
|
174
|
+
!dataStore.isAgent() &&
|
|
175
|
+
!dataStore.isChiefManagerNSZH() &&
|
|
176
|
+
!dataStore.isChiefSalesManager() &&
|
|
177
|
+
!dataStore.isSalesManager() &&
|
|
178
|
+
!dataStore.isManager();
|
|
179
|
+
}
|
|
167
180
|
}
|
|
168
181
|
return isReadonly.value;
|
|
169
182
|
});
|
|
170
183
|
const isManagerReadonly = computed(() => {
|
|
171
184
|
if (!isReadonly.value) {
|
|
172
185
|
if (dataStore.isTravelAgent()) return true;
|
|
173
|
-
if (dataStore.isGons)
|
|
186
|
+
if (dataStore.isGons) {
|
|
187
|
+
return !dataStore.isServiceManager() &&
|
|
188
|
+
!dataStore.isChiefManagerNSZH() &&
|
|
189
|
+
!dataStore.isChiefSalesManager() &&
|
|
190
|
+
!dataStore.isSalesManager() &&
|
|
191
|
+
!dataStore.isManager();
|
|
192
|
+
}
|
|
174
193
|
}
|
|
175
194
|
return isReadonly.value;
|
|
176
195
|
});
|
|
177
196
|
const isAgentReadonly = computed(() => {
|
|
178
197
|
if (!isReadonly.value) {
|
|
179
198
|
if (dataStore.isTravelAgent()) return true;
|
|
180
|
-
if (dataStore.isGons) return !dataStore.isServiceManager();
|
|
181
199
|
if (dataStore.isPension) return true;
|
|
200
|
+
if (dataStore.isGons) {
|
|
201
|
+
return !dataStore.isServiceManager() &&
|
|
202
|
+
!dataStore.isChiefManagerNSZH() &&
|
|
203
|
+
!dataStore.isChiefSalesManager() &&
|
|
204
|
+
!dataStore.isSalesManager() &&
|
|
205
|
+
!dataStore.isManager();
|
|
206
|
+
}
|
|
182
207
|
}
|
|
183
208
|
return isReadonly.value;
|
|
184
209
|
});
|
|
@@ -126,6 +126,7 @@
|
|
|
126
126
|
|
|
127
127
|
<script lang="ts">
|
|
128
128
|
import type { InputTypes } from '../../types';
|
|
129
|
+
import { handleSuccessfulLogin } from '../../utils/auth-helpers';
|
|
129
130
|
|
|
130
131
|
export default defineComponent({
|
|
131
132
|
setup() {
|
|
@@ -182,11 +183,7 @@ export default defineComponent({
|
|
|
182
183
|
await dataStore.loginUser(login.value, password.value, numAttempts.value);
|
|
183
184
|
numAttempts.value++;
|
|
184
185
|
authLoading.value = false;
|
|
185
|
-
|
|
186
|
-
await router.push({ name: 'index' });
|
|
187
|
-
}
|
|
188
|
-
} else {
|
|
189
|
-
// TODO Reset password
|
|
186
|
+
await handleSuccessfulLogin(router);
|
|
190
187
|
}
|
|
191
188
|
}
|
|
192
189
|
});
|
|
@@ -373,6 +373,10 @@ export default defineComponent({
|
|
|
373
373
|
};
|
|
374
374
|
|
|
375
375
|
const validateESBD = async (docTypeNumber: number) => {
|
|
376
|
+
if (!dataStore.checkWithESBD) {
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
|
|
376
380
|
const data: ESBDValidationType = {
|
|
377
381
|
personType: 1,
|
|
378
382
|
iin: props.member.iin!.replaceAll('-', ''),
|
|
@@ -390,7 +394,20 @@ export default defineComponent({
|
|
|
390
394
|
resident: props.member.signOfResidency.ids === '500011.2' || props.member.signOfResidency.ids === null ? 0 : 1,
|
|
391
395
|
countryId: Number((props.member.countryOfTaxResidency.ids! as string).at(-1)),
|
|
392
396
|
};
|
|
393
|
-
|
|
397
|
+
const ESBDResponse = await dataStore.getValidateClientESBD(data);
|
|
398
|
+
if (!ESBDResponse) {
|
|
399
|
+
dataStore.isLoading = false;
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
const initialPoint = `${props.member.iin!.replaceAll('-', '')}.`;
|
|
403
|
+
const RESPONSE = ESBDMessage(ESBDResponse, initialPoint);
|
|
404
|
+
let errorMessage = RESPONSE !== false ? RESPONSE : 'Что-то произошло не так';
|
|
405
|
+
if (typeof ESBDResponse !== 'object' || ESBDResponse.errorCode !== 0) {
|
|
406
|
+
dataStore.isLoading = false;
|
|
407
|
+
dataStore.showToaster('error', errorMessage, 5000);
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
return true;
|
|
394
411
|
};
|
|
395
412
|
|
|
396
413
|
const saveMember = async () => {
|
|
@@ -411,22 +428,11 @@ export default defineComponent({
|
|
|
411
428
|
const docType = props.member.documentType.ids;
|
|
412
429
|
if (props.member.gotFromInsis === true && (docType === '1UDL' || docType === 'SBI')) {
|
|
413
430
|
dataStore.isLoading = true;
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
const initialPoint = `${props.member.iin!.replaceAll('-', '')}.`;
|
|
420
|
-
const RESPONSE = ESBDMessage(ESBDResponse, initialPoint);
|
|
421
|
-
let errorMessage = RESPONSE !== false ? RESPONSE : 'Что-то произошло не так';
|
|
422
|
-
if (typeof ESBDResponse === 'object' && ESBDResponse.errorCode === 0) {
|
|
423
|
-
props.member.verifyType = 'ESBD';
|
|
424
|
-
props.member.verifyDate = ESBDResponse.verifiedDate;
|
|
425
|
-
const hasMemberSaved = await saveMember();
|
|
426
|
-
} else {
|
|
427
|
-
dataStore.isLoading = false;
|
|
428
|
-
dataStore.showToaster('error', errorMessage, 5000);
|
|
429
|
-
}
|
|
431
|
+
|
|
432
|
+
const isESBDValid = await validateESBD(docType === '1UDL' ? 1 : 3);
|
|
433
|
+
if (isESBDValid === false) return;
|
|
434
|
+
|
|
435
|
+
const hasMemberSaved = await saveMember();
|
|
430
436
|
} else {
|
|
431
437
|
const hasMemberSaved = await saveMember();
|
|
432
438
|
}
|