@zenky/storefront-vue 0.9.40 → 0.9.43

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/dist/esm/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { ref, computed, watch, unref, inject } from 'vue';
2
+ import { getApiError, getApiErrorMessage, getStore, getAddressSuggestions, getCategoriesTree, Visibility, getProductsCollections, getCategoryFeatures, getCategoryFeaturesGroups, getArticle, getArticles, getArticleCategories, getAuthenticationStatus, setAxiosToken, getCustomerProfile, login, requestPasswordResetCode, resetPassword, register, resendConfirmationCode, confirm, getApiErrorCode, getCustomerAddresses, deleteAddress, updateAddress, getOrder, getCustomerOrders, getCustomerPaymentMethods, deleteCustomerPaymentMethod, ImageType, getOffer, getOffers, setOrderCheckoutCustomer, getOrderSettings, createOrder, addOrderProductVariant, removeOrderProductVariant, confirmOrder, resendOrderConfirmationCode, setOrderCheckoutDelivery, setOrderCheckoutPayment, getOrderBonusesPaymentPreview, checkoutOrder, getOrderCheckoutTotal, getProductVariantPrice, getProduct, getProductsPricesRange, getProducts, checkCompletedPromotions } from '@zenky/api';
2
3
  import { debounce, isBoolean, cloneDeep } from 'lodash-es';
3
- import { getStore, getAddressSuggestions, getCategoriesTree, Visibility, getProductsCollections, getApiErrorMessage, getCategoryFeatures, getCategoryFeaturesGroups, getArticle, getArticles, getArticleCategories, getAuthenticationStatus, setAxiosToken, getCustomerProfile, login, requestPasswordResetCode, resetPassword, register, resendConfirmationCode, confirm, getApiErrorCode, getCustomerAddresses, deleteAddress, updateAddress, getOrder, getCustomerOrders, getCustomerPaymentMethods, deleteCustomerPaymentMethod, ImageType, getOffer, getOffers, setOrderCheckoutCustomer, getOrderSettings, createOrder, addOrderProductVariant, removeOrderProductVariant, confirmOrder, resendOrderConfirmationCode, setOrderCheckoutDelivery, setOrderCheckoutPayment, getOrderBonusesPaymentPreview, checkoutOrder, getOrderCheckoutTotal, getProductVariantPrice, getProduct, getProductsPricesRange, getProducts, checkCompletedPromotions } from '@zenky/api';
4
4
  import { defineStore, storeToRefs } from 'pinia';
5
- import { useNotification } from '@zenky/ui';
6
- import { useCustomerLoaded, useCustomerAuthenticated, useCustomerLoggedOut, useOrderLoaded, useProductQuantityIncreased, useProductQuantityDecreased, usePromotionsCheckerStarted, usePromotionsCheckerCompleted, useDisplayOrderPromotionRewardSelection, useOrderPromotionsNotFound, useOrderPriceRecalculated, useOrderShouldBeReloaded, useOrderPromotionRewardsShouldBeReloaded, useOrderSubmitted } from '@zenky/events';
5
+ import { useCustomerLoaded, useCustomerAuthenticated, useCustomerLoggedOut, useOrderLoaded, useOrderInitializationFailed, useProductQuantityIncreased, useProductQuantityIncreaseFailed, useProductQuantityDecreased, useProductQuantityDecreaseFailed, usePromotionsCheckerStarted, usePromotionsCheckerCompleted, useDisplayOrderPromotionRewardSelection, useOrderPromotionsNotFound, useOrderPriceRecalculated, useOrderShouldBeReloaded, useOrderPromotionRewardsShouldBeReloaded, useOrderSubmitted } from '@zenky/events';
7
6
  import { format } from 'date-fns';
8
7
  import Pusher from 'pusher-js';
9
8
 
@@ -19,7 +18,11 @@ function useDataDestroyer(destroyer, errorHandler) {
19
18
  return true;
20
19
  }
21
20
  catch (e) {
22
- errorHandler(e);
21
+ errorHandler({
22
+ e,
23
+ error: getApiError(e),
24
+ message: getApiErrorMessage(e),
25
+ });
23
26
  }
24
27
  finally {
25
28
  destroying.value = false;
@@ -32,8 +35,18 @@ function useDataDestroyer(destroyer, errorHandler) {
32
35
  };
33
36
  }
34
37
 
35
- function getApiErrorHandler(providedHandler, defaultHandler) {
36
- return providedHandler ? providedHandler : defaultHandler;
38
+ function getApiErrorHandler(providedHandler, composableName, defaultMessage) {
39
+ if (typeof providedHandler === 'function') {
40
+ return providedHandler;
41
+ }
42
+ return function ({ e, error, message }) {
43
+ console.error(`[${composableName}] ${defaultMessage}`, {
44
+ message,
45
+ error,
46
+ e,
47
+ });
48
+ console.info(`[@zenky/storefront] Pass errorHandler argument to the ${composableName}() composable to properly handle this error.`);
49
+ };
37
50
  }
38
51
 
39
52
  var ZenkyInjection;
@@ -106,7 +119,11 @@ function usePaginatedLoader(provider, errorHandler) {
106
119
  }
107
120
  }
108
121
  catch (e) {
109
- errorHandler(e);
122
+ errorHandler({
123
+ e,
124
+ error: getApiError(e),
125
+ message: getApiErrorMessage(e),
126
+ });
110
127
  }
111
128
  finally {
112
129
  state.value.loading = false;
@@ -136,7 +153,11 @@ function useListLoader(provider, errorHandler) {
136
153
  items.value = await provider(request);
137
154
  }
138
155
  catch (e) {
139
- errorHandler(e);
156
+ errorHandler({
157
+ e,
158
+ error: getApiError(e),
159
+ message: getApiErrorMessage(e),
160
+ });
140
161
  }
141
162
  finally {
142
163
  state.value.loading = false;
@@ -164,7 +185,11 @@ function useItemLoader(provider, errorHandler) {
164
185
  item.value = await provider(id, request);
165
186
  }
166
187
  catch (e) {
167
- errorHandler(e);
188
+ errorHandler({
189
+ e,
190
+ error: getApiError(e),
191
+ message: getApiErrorMessage(e),
192
+ });
168
193
  }
169
194
  finally {
170
195
  state.value.loading = false;
@@ -192,7 +217,11 @@ function useDataLoader(provider, errorHandler) {
192
217
  data.value = await provider();
193
218
  }
194
219
  catch (e) {
195
- errorHandler(e);
220
+ errorHandler({
221
+ e,
222
+ error: getApiError(e),
223
+ message: getApiErrorMessage(e),
224
+ });
196
225
  }
197
226
  finally {
198
227
  state.value.loading = false;
@@ -384,19 +413,19 @@ const useStoreStore = defineStore({
384
413
  });
385
414
 
386
415
  function useDadata() {
387
- const { cityId } = useStoreStore();
416
+ const { cityId } = storeToRefs(useStoreStore());
388
417
  const query = ref(null);
389
418
  const loading = ref(false);
390
419
  const results = ref([]);
391
420
  watch(query, debounce(async () => {
392
- if (loading.value || !query.value || !cityId) {
421
+ if (loading.value || !query.value || !cityId.value) {
393
422
  return;
394
423
  }
395
424
  try {
396
425
  loading.value = true;
397
426
  const { suggestions } = await getAddressSuggestions({
398
427
  query: query.value,
399
- city_id: cityId,
428
+ city_id: cityId.value,
400
429
  });
401
430
  results.value = suggestions;
402
431
  }
@@ -496,6 +525,15 @@ const getAddressForm = () => ({
496
525
  floor: '',
497
526
  has_intercom: true,
498
527
  });
528
+ var AddressFormValueError;
529
+ (function (AddressFormValueError) {
530
+ AddressFormValueError["DaDataSuggestionRequired"] = "dadata.suggestion_required";
531
+ AddressFormValueError["CityRequired"] = "plain.city_required";
532
+ AddressFormValueError["StreetRequired"] = "plain.street_required";
533
+ AddressFormValueError["HouseRequired"] = "plain.house_required";
534
+ AddressFormValueError["StockRequired"] = "stock_required";
535
+ AddressFormValueError["TableRequired"] = "table_required";
536
+ })(AddressFormValueError || (AddressFormValueError = {}));
499
537
  function useAddressFormValue(form, resolver, address) {
500
538
  const errors = [];
501
539
  let data = {};
@@ -523,18 +561,18 @@ function useAddressFormValue(form, resolver, address) {
523
561
  };
524
562
  }
525
563
  else {
526
- errors.push('Нужно выбрать улицу из выпадающего списка.');
564
+ errors.push(AddressFormValueError.DaDataSuggestionRequired);
527
565
  }
528
566
  }
529
567
  else if (resolver === 'plain') {
530
568
  if (!form.city) {
531
- errors.push('Нужно указать город.');
569
+ errors.push(AddressFormValueError.CityRequired);
532
570
  }
533
571
  else if (!form.street) {
534
- errors.push('Нужно указать улицу.');
572
+ errors.push(AddressFormValueError.StreetRequired);
535
573
  }
536
574
  else if (!form.house) {
537
- errors.push('Нужно указать номер дома.');
575
+ errors.push(AddressFormValueError.HouseRequired);
538
576
  }
539
577
  else {
540
578
  data = {
@@ -812,9 +850,7 @@ function useCategoryFeaturesList(categoryId, errorHandler) {
812
850
  return [];
813
851
  }
814
852
  return getCategoryFeatures(categoryId);
815
- }, getApiErrorHandler(errorHandler, function (e) {
816
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить список фильтров.'));
817
- }));
853
+ }, getApiErrorHandler(errorHandler, 'useCategoryFeaturesList', 'Unable to load category features list.'));
818
854
  }
819
855
  function useCategoryFeaturesGroupsList(categoryId, errorHandler) {
820
856
  return useListLoader(async function () {
@@ -822,25 +858,17 @@ function useCategoryFeaturesGroupsList(categoryId, errorHandler) {
822
858
  return [];
823
859
  }
824
860
  return getCategoryFeaturesGroups(categoryId);
825
- }, getApiErrorHandler(errorHandler, function (e) {
826
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить список фильтров.'));
827
- }));
861
+ }, getApiErrorHandler(errorHandler, 'useCategoryFeaturesGroupsList', 'Unable to load category features groups list.'));
828
862
  }
829
863
 
830
864
  function useArticlesList(errorHandler) {
831
- return usePaginatedLoader(getArticles, getApiErrorHandler(errorHandler, function (e) {
832
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить список статей.'));
833
- }));
865
+ return usePaginatedLoader(getArticles, getApiErrorHandler(errorHandler, 'useArticlesList', 'Unable to load articles list.'));
834
866
  }
835
867
  function useArticleCategoriesList(errorHandler) {
836
- return usePaginatedLoader(getArticleCategories, getApiErrorHandler(errorHandler, function (e) {
837
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить список категорий статей.'));
838
- }));
868
+ return usePaginatedLoader(getArticleCategories, getApiErrorHandler(errorHandler, 'useArticleCategoriesList', 'Unable to load article categories list.'));
839
869
  }
840
870
  function useArticleItem(errorHandler) {
841
- return useItemLoader(getArticle, getApiErrorHandler(errorHandler, function (e) {
842
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить статью.'));
843
- }));
871
+ return useItemLoader(getArticle, getApiErrorHandler(errorHandler, 'useArticleItem', 'Unable to load article.'));
844
872
  }
845
873
 
846
874
  var AuthenticationStage;
@@ -857,26 +885,45 @@ var AuthenticationEvent;
857
885
  })(AuthenticationEvent || (AuthenticationEvent = {}));
858
886
  var AuthenticationResultType;
859
887
  (function (AuthenticationResultType) {
860
- AuthenticationResultType["Pending"] = "pending";
861
888
  AuthenticationResultType["Validation"] = "validation";
862
889
  AuthenticationResultType["Failed"] = "failed";
863
890
  AuthenticationResultType["Completed"] = "completed";
864
891
  AuthenticationResultType["Stage"] = "stage";
865
892
  })(AuthenticationResultType || (AuthenticationResultType = {}));
893
+ var AuthenticationFailureReason;
894
+ (function (AuthenticationFailureReason) {
895
+ AuthenticationFailureReason["ApiError"] = "api_error";
896
+ AuthenticationFailureReason["InProgress"] = "in_progress";
897
+ AuthenticationFailureReason["Cooldown"] = "cooldown";
898
+ AuthenticationFailureReason["PhoneRequired"] = "phone_required";
899
+ AuthenticationFailureReason["PasswordRequired"] = "password_required";
900
+ AuthenticationFailureReason["CodeRequired"] = "code_required";
901
+ })(AuthenticationFailureReason || (AuthenticationFailureReason = {}));
902
+ var AddressResultType;
903
+ (function (AddressResultType) {
904
+ AddressResultType["Failed"] = "failed";
905
+ AddressResultType["Completed"] = "completed";
906
+ })(AddressResultType || (AddressResultType = {}));
907
+ var AddressResultReason;
908
+ (function (AddressResultReason) {
909
+ AddressResultReason["InProgress"] = "in_progress";
910
+ AddressResultReason["Validation"] = "validation";
911
+ AddressResultReason["ApiError"] = "api_error";
912
+ })(AddressResultReason || (AddressResultReason = {}));
866
913
 
867
914
  function useAuthenticationStatusChecker(form, emit) {
868
915
  const active = ref(false);
869
916
  const check = async () => {
870
917
  if (active.value) {
871
918
  return {
872
- type: AuthenticationResultType.Pending,
919
+ type: AuthenticationResultType.Failed,
920
+ reason: AuthenticationFailureReason.InProgress,
873
921
  };
874
922
  }
875
923
  else if (!form.value.phone.number || !form.value.phone.country) {
876
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
877
924
  return {
878
925
  type: AuthenticationResultType.Validation,
879
- data: 'phone',
926
+ reason: AuthenticationFailureReason.PhoneRequired,
880
927
  };
881
928
  }
882
929
  active.value = true;
@@ -885,32 +932,33 @@ function useAuthenticationStatusChecker(form, emit) {
885
932
  if (!status.registered) {
886
933
  emit(AuthenticationEvent.Stage, AuthenticationStage.Register);
887
934
  return {
888
- type: AuthenticationResultType.Completed,
935
+ type: AuthenticationResultType.Stage,
889
936
  data: AuthenticationStage.Register,
890
937
  };
891
938
  }
892
939
  else if (!status.confirmed) {
893
940
  emit(AuthenticationEvent.Stage, AuthenticationStage.Confirmation);
894
941
  return {
895
- type: AuthenticationResultType.Completed,
942
+ type: AuthenticationResultType.Stage,
896
943
  data: AuthenticationStage.Confirmation,
897
944
  };
898
945
  }
899
946
  emit(AuthenticationEvent.Stage, AuthenticationStage.Login);
900
947
  return {
901
- type: AuthenticationResultType.Completed,
948
+ type: AuthenticationResultType.Stage,
902
949
  data: AuthenticationStage.Login,
903
950
  };
904
951
  }
905
952
  catch (e) {
906
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось проверить статус регистрации. Повторите попытку.'));
953
+ return {
954
+ type: AuthenticationResultType.Failed,
955
+ reason: AuthenticationFailureReason.ApiError,
956
+ error: getApiError(e),
957
+ };
907
958
  }
908
959
  finally {
909
960
  active.value = false;
910
961
  }
911
- return {
912
- type: AuthenticationResultType.Failed,
913
- };
914
962
  };
915
963
  return {
916
964
  active,
@@ -1007,21 +1055,20 @@ function useLogin(form, emit) {
1007
1055
  const login$1 = async () => {
1008
1056
  if (active.value) {
1009
1057
  return {
1010
- type: AuthenticationResultType.Pending,
1058
+ type: AuthenticationResultType.Failed,
1059
+ reason: AuthenticationFailureReason.InProgress,
1011
1060
  };
1012
1061
  }
1013
1062
  else if (!form.value.phone.number || !form.value.phone.country) {
1014
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
1015
1063
  return {
1016
1064
  type: AuthenticationResultType.Validation,
1017
- data: 'phone',
1065
+ reason: AuthenticationFailureReason.PhoneRequired,
1018
1066
  };
1019
1067
  }
1020
1068
  else if (!form.value.password) {
1021
- useNotification('error', 'Ошибка', 'Нужно указать пароль.');
1022
1069
  return {
1023
1070
  type: AuthenticationResultType.Validation,
1024
- data: 'password',
1071
+ reason: AuthenticationFailureReason.PasswordRequired,
1025
1072
  };
1026
1073
  }
1027
1074
  active.value = true;
@@ -1029,7 +1076,6 @@ function useLogin(form, emit) {
1029
1076
  const { token } = await login({ number: form.value.phone.number, country: form.value.phone.country }, form.value.password);
1030
1077
  const { setToken } = useCustomerStore();
1031
1078
  const customer = await setToken(token);
1032
- useNotification('success', 'Успешный вход', 'Вы успешно вошли в ваш аккаунт!');
1033
1079
  emit(AuthenticationEvent.Completed);
1034
1080
  return {
1035
1081
  type: AuthenticationResultType.Completed,
@@ -1037,14 +1083,15 @@ function useLogin(form, emit) {
1037
1083
  };
1038
1084
  }
1039
1085
  catch (e) {
1040
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Указан неправильный пароль.'));
1086
+ return {
1087
+ type: AuthenticationResultType.Failed,
1088
+ reason: AuthenticationFailureReason.ApiError,
1089
+ error: getApiError(e),
1090
+ };
1041
1091
  }
1042
1092
  finally {
1043
1093
  active.value = false;
1044
1094
  }
1045
- return {
1046
- type: AuthenticationResultType.Failed,
1047
- };
1048
1095
  };
1049
1096
  return {
1050
1097
  active,
@@ -1116,26 +1163,25 @@ function useRequest(form, active) {
1116
1163
  const request = async () => {
1117
1164
  if (active.value) {
1118
1165
  return {
1119
- type: AuthenticationResultType.Pending,
1166
+ type: AuthenticationResultType.Failed,
1167
+ reason: AuthenticationFailureReason.InProgress,
1120
1168
  };
1121
1169
  }
1122
1170
  else if (seconds.value > 0) {
1123
- useNotification('error', 'Ошибка', 'Нужно подождать перед повторной отправкой кода сброса пароля.');
1124
1171
  return {
1125
- type: AuthenticationResultType.Pending,
1172
+ type: AuthenticationResultType.Failed,
1173
+ reason: AuthenticationFailureReason.Cooldown,
1126
1174
  };
1127
1175
  }
1128
1176
  else if (!form.value.phone.number || !form.value.phone.country) {
1129
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
1130
1177
  return {
1131
1178
  type: AuthenticationResultType.Validation,
1132
- data: 'phone',
1179
+ reason: AuthenticationFailureReason.PhoneRequired,
1133
1180
  };
1134
1181
  }
1135
1182
  active.value = true;
1136
1183
  try {
1137
1184
  await requestPasswordResetCode(form.value.phone);
1138
- useNotification('success', 'Код отправлен', 'Код сброса пароля был отправлен на ваш номер.');
1139
1185
  sent.value = true;
1140
1186
  start();
1141
1187
  return {
@@ -1143,14 +1189,15 @@ function useRequest(form, active) {
1143
1189
  };
1144
1190
  }
1145
1191
  catch (e) {
1146
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Нужно подождать перед повторной отправкой кода сброса пароля.'));
1192
+ return {
1193
+ type: AuthenticationResultType.Failed,
1194
+ reason: AuthenticationFailureReason.ApiError,
1195
+ error: getApiError(e),
1196
+ };
1147
1197
  }
1148
1198
  finally {
1149
1199
  active.value = false;
1150
1200
  }
1151
- return {
1152
- type: AuthenticationResultType.Failed,
1153
- };
1154
1201
  };
1155
1202
  return {
1156
1203
  seconds,
@@ -1163,28 +1210,26 @@ function useReset(form, active, emit) {
1163
1210
  const reset = async () => {
1164
1211
  if (active.value) {
1165
1212
  return {
1166
- type: AuthenticationResultType.Pending,
1213
+ type: AuthenticationResultType.Failed,
1214
+ reason: AuthenticationFailureReason.InProgress,
1167
1215
  };
1168
1216
  }
1169
1217
  else if (!form.value.phone.number || !form.value.phone.country) {
1170
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
1171
1218
  return {
1172
1219
  type: AuthenticationResultType.Validation,
1173
- data: 'phone',
1220
+ reason: AuthenticationFailureReason.PhoneRequired,
1174
1221
  };
1175
1222
  }
1176
1223
  else if (!form.value.password) {
1177
- useNotification('error', 'Ошибка', 'Нужно придумать новый пароль.');
1178
1224
  return {
1179
1225
  type: AuthenticationResultType.Validation,
1180
- data: 'password',
1226
+ reason: AuthenticationFailureReason.PasswordRequired,
1181
1227
  };
1182
1228
  }
1183
1229
  else if (!form.value.confirmation_code) {
1184
- useNotification('error', 'Ошибка', 'Нужно указать код из SMS.');
1185
1230
  return {
1186
1231
  type: AuthenticationResultType.Validation,
1187
- data: 'confirmation_code',
1232
+ reason: AuthenticationFailureReason.CodeRequired,
1188
1233
  };
1189
1234
  }
1190
1235
  active.value = true;
@@ -1192,7 +1237,6 @@ function useReset(form, active, emit) {
1192
1237
  const result = await resetPassword(form.value.phone, form.value.confirmation_code, form.value.password);
1193
1238
  const store = useCustomerStore();
1194
1239
  await store.setToken(result.token);
1195
- useNotification('success', 'Пароль изменён', 'Вы успешно изменили пароль и вошли в свой аккаунт.');
1196
1240
  emit(AuthenticationEvent.Completed);
1197
1241
  return {
1198
1242
  type: AuthenticationResultType.Completed,
@@ -1200,14 +1244,15 @@ function useReset(form, active, emit) {
1200
1244
  };
1201
1245
  }
1202
1246
  catch (e) {
1203
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Указан неправильный код сброса пароля.'));
1247
+ return {
1248
+ type: AuthenticationResultType.Failed,
1249
+ reason: AuthenticationFailureReason.ApiError,
1250
+ error: getApiError(e),
1251
+ };
1204
1252
  }
1205
1253
  finally {
1206
1254
  active.value = false;
1207
1255
  }
1208
- return {
1209
- type: AuthenticationResultType.Failed,
1210
- };
1211
1256
  };
1212
1257
  return {
1213
1258
  reset,
@@ -1232,21 +1277,20 @@ function useRegistration(form, emit) {
1232
1277
  const register$1 = async () => {
1233
1278
  if (active.value) {
1234
1279
  return {
1235
- type: AuthenticationResultType.Pending,
1280
+ type: AuthenticationResultType.Failed,
1281
+ reason: AuthenticationFailureReason.InProgress,
1236
1282
  };
1237
1283
  }
1238
1284
  else if (!form.value.phone.number || !form.value.phone.country) {
1239
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
1240
1285
  return {
1241
1286
  type: AuthenticationResultType.Validation,
1242
- data: 'phone',
1287
+ reason: AuthenticationFailureReason.PhoneRequired,
1243
1288
  };
1244
1289
  }
1245
1290
  else if (!form.value.password) {
1246
- useNotification('error', 'Ошибка', 'Нужно придумать пароль.');
1247
1291
  return {
1248
1292
  type: AuthenticationResultType.Validation,
1249
- data: 'password',
1293
+ reason: AuthenticationFailureReason.PasswordRequired,
1250
1294
  };
1251
1295
  }
1252
1296
  active.value = true;
@@ -1254,7 +1298,6 @@ function useRegistration(form, emit) {
1254
1298
  const result = await register(form.value.phone, form.value.password);
1255
1299
  if (!result.confirmation_required) {
1256
1300
  emit(AuthenticationEvent.Completed);
1257
- useNotification('success', 'Успешная регистрация', 'Вы успешно зарегистрировались!');
1258
1301
  return {
1259
1302
  type: AuthenticationResultType.Completed,
1260
1303
  };
@@ -1266,14 +1309,15 @@ function useRegistration(form, emit) {
1266
1309
  };
1267
1310
  }
1268
1311
  catch (e) {
1269
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Этот телефон уже зарегистрирован.'));
1312
+ return {
1313
+ type: AuthenticationResultType.Failed,
1314
+ reason: AuthenticationFailureReason.ApiError,
1315
+ error: getApiError(e),
1316
+ };
1270
1317
  }
1271
1318
  finally {
1272
1319
  active.value = false;
1273
1320
  }
1274
- return {
1275
- type: AuthenticationResultType.Failed,
1276
- };
1277
1321
  };
1278
1322
  return {
1279
1323
  active,
@@ -1286,20 +1330,20 @@ function useResend(form, active) {
1286
1330
  const resend = async () => {
1287
1331
  if (active.value) {
1288
1332
  return {
1289
- type: AuthenticationResultType.Pending,
1333
+ type: AuthenticationResultType.Failed,
1334
+ reason: AuthenticationFailureReason.InProgress,
1290
1335
  };
1291
1336
  }
1292
1337
  else if (seconds.value > 0) {
1293
- useNotification('error', 'Ошибка', 'Нужно подождать перед повторной отправкой кода подтверждения.');
1294
1338
  return {
1295
- type: AuthenticationResultType.Pending,
1339
+ type: AuthenticationResultType.Failed,
1340
+ reason: AuthenticationFailureReason.Cooldown,
1296
1341
  };
1297
1342
  }
1298
1343
  else if (!form.value.phone.number || !form.value.phone.country) {
1299
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
1300
1344
  return {
1301
1345
  type: AuthenticationResultType.Validation,
1302
- data: 'phone',
1346
+ reason: AuthenticationFailureReason.PhoneRequired,
1303
1347
  };
1304
1348
  }
1305
1349
  active.value = true;
@@ -1311,14 +1355,15 @@ function useResend(form, active) {
1311
1355
  };
1312
1356
  }
1313
1357
  catch (e) {
1314
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Нужно подождать перед повторной отправкой кода подтверждения.'));
1358
+ return {
1359
+ type: AuthenticationResultType.Failed,
1360
+ reason: AuthenticationFailureReason.ApiError,
1361
+ error: getApiError(e),
1362
+ };
1315
1363
  }
1316
1364
  finally {
1317
1365
  active.value = false;
1318
1366
  }
1319
- return {
1320
- type: AuthenticationResultType.Failed,
1321
- };
1322
1367
  };
1323
1368
  return {
1324
1369
  seconds,
@@ -1331,28 +1376,26 @@ function useConfirm(form, active, emit) {
1331
1376
  const confirm$1 = async (withPassword = false) => {
1332
1377
  if (active.value) {
1333
1378
  return {
1334
- type: AuthenticationResultType.Pending,
1379
+ type: AuthenticationResultType.Failed,
1380
+ reason: AuthenticationFailureReason.InProgress,
1335
1381
  };
1336
1382
  }
1337
1383
  else if (!form.value.phone.number || !form.value.phone.country) {
1338
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
1339
1384
  return {
1340
1385
  type: AuthenticationResultType.Validation,
1341
- data: 'phone',
1386
+ reason: AuthenticationFailureReason.PhoneRequired,
1342
1387
  };
1343
1388
  }
1344
1389
  else if (!form.value.confirmation_code) {
1345
- useNotification('error', 'Ошибка', 'Нужно указать код из SMS.');
1346
1390
  return {
1347
1391
  type: AuthenticationResultType.Validation,
1348
- data: 'confirmation_code',
1392
+ reason: AuthenticationFailureReason.CodeRequired,
1349
1393
  };
1350
1394
  }
1351
1395
  else if (withPassword && !form.value.password) {
1352
- useNotification('error', 'Ошибка', 'Нужно указать новый пароль.');
1353
1396
  return {
1354
1397
  type: AuthenticationResultType.Validation,
1355
- data: 'password',
1398
+ reason: AuthenticationFailureReason.PasswordRequired,
1356
1399
  };
1357
1400
  }
1358
1401
  active.value = true;
@@ -1360,7 +1403,6 @@ function useConfirm(form, active, emit) {
1360
1403
  const result = await confirm(form.value.phone, form.value.confirmation_code, withPassword ? form.value.password : null);
1361
1404
  const store = useCustomerStore();
1362
1405
  await store.setToken(result.token);
1363
- useNotification('success', 'Успешное подтверждение телефона', 'Вы успешно подтвердили телефон и вошли в свой аккаунт.');
1364
1406
  emit(AuthenticationEvent.Completed);
1365
1407
  return {
1366
1408
  type: AuthenticationResultType.Completed,
@@ -1368,20 +1410,21 @@ function useConfirm(form, active, emit) {
1368
1410
  };
1369
1411
  }
1370
1412
  catch (e) {
1371
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Указан неправильный код подтверждения.'));
1372
1413
  if (getApiErrorCode(e) === 'auth.registration.password_required') {
1373
1414
  return {
1374
1415
  type: AuthenticationResultType.Validation,
1375
- data: 'password',
1416
+ reason: AuthenticationFailureReason.PasswordRequired,
1376
1417
  };
1377
1418
  }
1419
+ return {
1420
+ type: AuthenticationResultType.Failed,
1421
+ reason: AuthenticationFailureReason.ApiError,
1422
+ error: getApiError(e),
1423
+ };
1378
1424
  }
1379
1425
  finally {
1380
1426
  active.value = false;
1381
1427
  }
1382
- return {
1383
- type: AuthenticationResultType.Failed,
1384
- };
1385
1428
  };
1386
1429
  return {
1387
1430
  confirm: confirm$1,
@@ -1402,14 +1445,10 @@ const usePhoneConfirmation = (form, emit) => {
1402
1445
  };
1403
1446
 
1404
1447
  function useDeliveryAddressesList(errorHandler) {
1405
- return usePaginatedLoader(getCustomerAddresses, getApiErrorHandler(errorHandler, function (e) {
1406
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить адреса доставки.'));
1407
- }));
1448
+ return usePaginatedLoader(getCustomerAddresses, getApiErrorHandler(errorHandler, 'useDeliveryAddressesList', 'Unable to load delivery addresses list.'));
1408
1449
  }
1409
1450
  function useDeliveryAddressDestroyer(errorHandler) {
1410
- return useDataDestroyer(deleteAddress, getApiErrorHandler(errorHandler, function (e) {
1411
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось удалить адрес доставки.'));
1412
- }));
1451
+ return useDataDestroyer(deleteAddress, getApiErrorHandler(errorHandler, 'useDeliveryAddressDestroyer', 'Unable to delete delivery address.'));
1413
1452
  }
1414
1453
  function useEditAddressForm(address) {
1415
1454
  var _a, _b;
@@ -1439,12 +1478,18 @@ function useEditAddressForm(address) {
1439
1478
  const form = ref(addressFields);
1440
1479
  const save = async () => {
1441
1480
  if (saving.value) {
1442
- return false;
1481
+ return {
1482
+ type: AddressResultType.Failed,
1483
+ reason: AddressResultReason.InProgress,
1484
+ };
1443
1485
  }
1444
1486
  const { errors, data } = useAddressFormValue(form.value, address.resolver, address);
1445
1487
  if (errors.length > 0) {
1446
- useNotification('error', 'Ошибка', errors[0]);
1447
- return false;
1488
+ return {
1489
+ type: AddressResultType.Failed,
1490
+ reason: AddressResultReason.Validation,
1491
+ data: errors,
1492
+ };
1448
1493
  }
1449
1494
  saving.value = true;
1450
1495
  try {
@@ -1454,16 +1499,20 @@ function useEditAddressForm(address) {
1454
1499
  name: form.value.name,
1455
1500
  },
1456
1501
  });
1457
- useNotification('success', 'Адрес сохранён', 'Адрес был успешно сохранён!');
1458
- return true;
1502
+ return {
1503
+ type: AddressResultType.Completed,
1504
+ };
1459
1505
  }
1460
1506
  catch (e) {
1461
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось сохранить адрес. Повторите попытку.'));
1507
+ return {
1508
+ type: AddressResultType.Failed,
1509
+ reason: AddressResultReason.ApiError,
1510
+ error: getApiError(e),
1511
+ };
1462
1512
  }
1463
1513
  finally {
1464
1514
  saving.value = false;
1465
1515
  }
1466
- return false;
1467
1516
  };
1468
1517
  return {
1469
1518
  form,
@@ -1483,25 +1532,17 @@ function useCustomer() {
1483
1532
  }
1484
1533
 
1485
1534
  function useOrdersList(errorHandler) {
1486
- return usePaginatedLoader(getCustomerOrders, getApiErrorHandler(errorHandler, function (e) {
1487
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить список заказов.'));
1488
- }));
1535
+ return usePaginatedLoader(getCustomerOrders, getApiErrorHandler(errorHandler, 'useOrdersList', 'Unable to load orders list.'));
1489
1536
  }
1490
1537
  function useOrderItem(errorHandler) {
1491
- return useItemLoader(getOrder, getApiErrorHandler(errorHandler, function (e) {
1492
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Заказ не найден.'));
1493
- }));
1538
+ return useItemLoader(getOrder, getApiErrorHandler(errorHandler, 'useOrderItem', 'Unable to load order.'));
1494
1539
  }
1495
1540
 
1496
1541
  function usePaymentMethodsList(errorHandler) {
1497
- return usePaginatedLoader(getCustomerPaymentMethods, getApiErrorHandler(errorHandler, function (e) {
1498
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить способы оплаты.'));
1499
- }));
1542
+ return usePaginatedLoader(getCustomerPaymentMethods, getApiErrorHandler(errorHandler, 'usePaymentMethodsList', 'Unable to load payment methods.'));
1500
1543
  }
1501
1544
  function usePaymentMethodDestroyer(errorHandler) {
1502
- return useDataDestroyer(deleteCustomerPaymentMethod, getApiErrorHandler(errorHandler, function (e) {
1503
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось удалить способ оплаты.'));
1504
- }));
1545
+ return useDataDestroyer(deleteCustomerPaymentMethod, getApiErrorHandler(errorHandler, 'usePaymentMethodDestroyer', 'Unable to delete payment method.'));
1505
1546
  }
1506
1547
 
1507
1548
  function getFirstMedium(media, sizes = ['large', 'medium'], preferWebp = true) {
@@ -1539,15 +1580,35 @@ function getFirstMedium(media, sizes = ['large', 'medium'], preferWebp = true) {
1539
1580
  }
1540
1581
 
1541
1582
  function useOffersList(errorHandler) {
1542
- return usePaginatedLoader(getOffers, getApiErrorHandler(errorHandler, function (e) {
1543
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить список акций.'));
1544
- }));
1583
+ return usePaginatedLoader(getOffers, getApiErrorHandler(errorHandler, 'useOffersList', 'Unable to load offers list.'));
1545
1584
  }
1546
1585
  function useOfferItem(errorHandler) {
1547
- return useItemLoader(getOffer, getApiErrorHandler(errorHandler, function (e) {
1548
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить акцию.'));
1549
- }));
1550
- }
1586
+ return useItemLoader(getOffer, getApiErrorHandler(errorHandler, 'useOfferItem', 'Unable to load offer.'));
1587
+ }
1588
+
1589
+ var OrderCheckoutResultType;
1590
+ (function (OrderCheckoutResultType) {
1591
+ OrderCheckoutResultType["Validation"] = "validation";
1592
+ OrderCheckoutResultType["Completed"] = "completed";
1593
+ OrderCheckoutResultType["Failed"] = "failed";
1594
+ })(OrderCheckoutResultType || (OrderCheckoutResultType = {}));
1595
+ var OrderCheckoutResultReason;
1596
+ (function (OrderCheckoutResultReason) {
1597
+ OrderCheckoutResultReason["InProgress"] = "in_progress";
1598
+ OrderCheckoutResultReason["Cooldown"] = "cooldown";
1599
+ OrderCheckoutResultReason["ApiError"] = "api_error";
1600
+ OrderCheckoutResultReason["OrderNotReady"] = "order_not_ready";
1601
+ OrderCheckoutResultReason["PhoneRequired"] = "phone_required";
1602
+ OrderCheckoutResultReason["FirstNameRequired"] = "first_name_required";
1603
+ OrderCheckoutResultReason["CodeRequired"] = "code_required";
1604
+ OrderCheckoutResultReason["AddressError"] = "address_error";
1605
+ })(OrderCheckoutResultReason || (OrderCheckoutResultReason = {}));
1606
+ var BillSuggestionType;
1607
+ (function (BillSuggestionType) {
1608
+ BillSuggestionType["Bill"] = "bill";
1609
+ BillSuggestionType["NoChange"] = "no_change";
1610
+ BillSuggestionType["Custom"] = "custom";
1611
+ })(BillSuggestionType || (BillSuggestionType = {}));
1551
1612
 
1552
1613
  function getUpdatedVariants(currentOrder, order) {
1553
1614
  var _a, _b;
@@ -1694,7 +1755,9 @@ const useOrderStore = defineStore({
1694
1755
  return await this.load(storeId, cityId, order.id, order.token);
1695
1756
  }
1696
1757
  catch (e) {
1697
- useNotification('error', 'Ошибка инициализации заказа', 'Не удалось инициализировать заказ. Обновите страницу.');
1758
+ useOrderInitializationFailed().publish({
1759
+ error: getApiError(e),
1760
+ });
1698
1761
  }
1699
1762
  return false;
1700
1763
  },
@@ -1729,7 +1792,14 @@ const useOrderStore = defineStore({
1729
1792
  return true;
1730
1793
  }
1731
1794
  catch (e) {
1732
- useNotification('error', 'Товар не добавлен', getApiErrorMessage(e, 'Не удалось добавить товар в корзину. Повторите попытку'));
1795
+ useProductQuantityIncreaseFailed().publish({
1796
+ error: getApiError(e),
1797
+ order: this.order,
1798
+ productVariantId,
1799
+ quantity,
1800
+ modifiers,
1801
+ promotion,
1802
+ });
1733
1803
  }
1734
1804
  return false;
1735
1805
  },
@@ -1759,7 +1829,14 @@ const useOrderStore = defineStore({
1759
1829
  return true;
1760
1830
  }
1761
1831
  catch (e) {
1762
- useNotification('error', 'Товар не удалён', getApiErrorMessage(e, 'Не удалось удалить товар из корзины. Повторите попытку'));
1832
+ useProductQuantityDecreaseFailed().publish({
1833
+ error: getApiError(e),
1834
+ order: this.order,
1835
+ productVariantId,
1836
+ quantity,
1837
+ modifiers,
1838
+ promotion,
1839
+ });
1763
1840
  }
1764
1841
  return false;
1765
1842
  },
@@ -1902,40 +1979,62 @@ function useCheckoutConfirmation(order) {
1902
1979
  }));
1903
1980
  const confirm = async () => {
1904
1981
  if (confirming.value) {
1905
- return null;
1982
+ return {
1983
+ type: OrderCheckoutResultType.Failed,
1984
+ reason: OrderCheckoutResultReason.InProgress,
1985
+ };
1906
1986
  }
1907
1987
  else if (!form.value.code) {
1908
- useNotification('error', 'Ошибка', 'Нужно указать код из SMS.');
1909
- return null;
1988
+ return {
1989
+ type: OrderCheckoutResultType.Validation,
1990
+ reason: OrderCheckoutResultReason.CodeRequired,
1991
+ };
1910
1992
  }
1911
1993
  confirming.value = true;
1912
1994
  try {
1913
- return await confirmOrder(credentials.value, form.value);
1995
+ const response = await confirmOrder(credentials.value, form.value);
1996
+ return {
1997
+ type: OrderCheckoutResultType.Completed,
1998
+ data: response,
1999
+ };
1914
2000
  }
1915
2001
  catch (e) {
1916
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось подтвердить заказ.'));
2002
+ return {
2003
+ type: OrderCheckoutResultType.Failed,
2004
+ reason: OrderCheckoutResultReason.ApiError,
2005
+ error: getApiError(e),
2006
+ };
1917
2007
  }
1918
2008
  finally {
1919
2009
  confirming.value = false;
1920
2010
  }
1921
- return null;
1922
2011
  };
1923
2012
  const resendCode = async () => {
1924
2013
  if (resending.value) {
1925
- return;
2014
+ return {
2015
+ type: OrderCheckoutResultType.Failed,
2016
+ reason: OrderCheckoutResultReason.InProgress,
2017
+ };
1926
2018
  }
1927
2019
  resending.value = true;
1928
2020
  try {
1929
2021
  const result = await resendOrderConfirmationCode(credentials.value);
1930
2022
  if (result.success) {
1931
- useNotification('success', 'Код выслан', 'Код был повторно выслан на ваш телефон.');
1932
- }
1933
- else {
1934
- useNotification('error', 'Ошибка', 'Не удалось выслать код подтверждения. Повторите попытку позднее.');
2023
+ return {
2024
+ type: OrderCheckoutResultType.Completed,
2025
+ };
1935
2026
  }
2027
+ return {
2028
+ type: OrderCheckoutResultType.Failed,
2029
+ reason: OrderCheckoutResultReason.Cooldown,
2030
+ };
1936
2031
  }
1937
2032
  catch (e) {
1938
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось выслать код подтверждения.'));
2033
+ return {
2034
+ type: OrderCheckoutResultType.Failed,
2035
+ reason: OrderCheckoutResultReason.ApiError,
2036
+ error: getApiError(e),
2037
+ };
1939
2038
  }
1940
2039
  finally {
1941
2040
  resending.value = false;
@@ -1978,26 +2077,43 @@ function useCustomerCheckoutForm(emit) {
1978
2077
  }
1979
2078
  const save = async () => {
1980
2079
  if (!credentials.value) {
1981
- return;
2080
+ return {
2081
+ type: OrderCheckoutResultType.Failed,
2082
+ reason: OrderCheckoutResultReason.OrderNotReady,
2083
+ };
1982
2084
  }
1983
2085
  else if (saving.value) {
1984
- return;
2086
+ return {
2087
+ type: OrderCheckoutResultType.Failed,
2088
+ reason: OrderCheckoutResultReason.InProgress,
2089
+ };
1985
2090
  }
1986
2091
  else if (!form.value.phone.number || !form.value.phone.country) {
1987
- useNotification('error', 'Ошибка', 'Нужно указать номер телефона.');
1988
- return;
2092
+ return {
2093
+ type: OrderCheckoutResultType.Validation,
2094
+ reason: OrderCheckoutResultReason.PhoneRequired,
2095
+ };
1989
2096
  }
1990
2097
  else if (!form.value.first_name) {
1991
- useNotification('error', 'Ошибка', 'Нужно указать имя.');
1992
- return;
2098
+ return {
2099
+ type: OrderCheckoutResultType.Validation,
2100
+ reason: OrderCheckoutResultReason.FirstNameRequired,
2101
+ };
1993
2102
  }
1994
2103
  saving.value = true;
1995
2104
  try {
1996
2105
  await setOrderCheckoutCustomer(credentials.value, form.value);
1997
2106
  emit('completed');
2107
+ return {
2108
+ type: OrderCheckoutResultType.Completed,
2109
+ };
1998
2110
  }
1999
2111
  catch (e) {
2000
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось сохранить контактные данные.'));
2112
+ return {
2113
+ type: OrderCheckoutResultType.Failed,
2114
+ reason: OrderCheckoutResultReason.ApiError,
2115
+ error: getApiError(e),
2116
+ };
2001
2117
  }
2002
2118
  finally {
2003
2119
  saving.value = false;
@@ -2049,7 +2165,7 @@ function useOrderVariants() {
2049
2165
  variants,
2050
2166
  };
2051
2167
  }
2052
- const useVariantControls = (variant, modifiers, modifiersHash, promotion) => {
2168
+ const useVariantControls = (variant, modifiers, modifiersHash, promotion, callback) => {
2053
2169
  const { order } = storeToRefs(useOrderStore());
2054
2170
  const { add: addVariant, remove: removeVariant } = useOrderStore();
2055
2171
  const loading = ref(false);
@@ -2083,10 +2199,9 @@ const useVariantControls = (variant, modifiers, modifiersHash, promotion) => {
2083
2199
  }
2084
2200
  else {
2085
2201
  result = await removeVariant(variant.value.id, quantity, modifiers.value, promotion.value);
2086
- useNotification('success', 'Товар удалён', `Товар${variant.value.name ? ` «${variant.value.name}»` : ''} удалён из корзины!`);
2087
2202
  }
2088
- if (result) {
2089
- useNotification('success', `Товар ${type === 'add' ? 'добавлен' : 'удалён'}`, `Товар${variant.value.name ? ` «${variant.value.name}»` : ''} ${type === 'add' ? 'добавлен в корзину' : 'удалён из корзины'}!`);
2203
+ if (typeof callback === 'function') {
2204
+ callback(type, result);
2090
2205
  }
2091
2206
  loading.value = false;
2092
2207
  };
@@ -2171,7 +2286,7 @@ function getDeliveryPayload(form, addressesResolver) {
2171
2286
  data.stock_id = form.pickup.stock_id;
2172
2287
  }
2173
2288
  else {
2174
- errors.push('Нужно выбрать точку самовывоза.');
2289
+ errors.push(AddressFormValueError.StockRequired);
2175
2290
  }
2176
2291
  }
2177
2292
  else if (form.method === 'on_premise') {
@@ -2179,13 +2294,13 @@ function getDeliveryPayload(form, addressesResolver) {
2179
2294
  data.stock_id = form.on_premise.stock_id;
2180
2295
  }
2181
2296
  else {
2182
- errors.push('Нужно выбрать точку самовывоза.');
2297
+ errors.push(AddressFormValueError.StockRequired);
2183
2298
  }
2184
2299
  if (form.on_premise.table) {
2185
2300
  data.on_premise = { table: form.on_premise.table };
2186
2301
  }
2187
2302
  else {
2188
- errors.push('Нужно указать номер стола.');
2303
+ errors.push(AddressFormValueError.TableRequired);
2189
2304
  }
2190
2305
  }
2191
2306
  else if (form.method === 'delivery') {
@@ -2252,23 +2367,39 @@ function useDeliveryCheckoutForm(emit) {
2252
2367
  });
2253
2368
  const save = async () => {
2254
2369
  if (!credentials.value || !addressesResolver.value) {
2255
- return;
2370
+ return {
2371
+ type: OrderCheckoutResultType.Failed,
2372
+ reason: OrderCheckoutResultReason.OrderNotReady,
2373
+ };
2256
2374
  }
2257
2375
  else if (saving.value) {
2258
- return;
2376
+ return {
2377
+ type: OrderCheckoutResultType.Failed,
2378
+ reason: OrderCheckoutResultReason.InProgress,
2379
+ };
2259
2380
  }
2260
2381
  const { data, errors } = getDeliveryPayload(form.value, addressesResolver.value);
2261
2382
  if (errors.length > 0) {
2262
- useNotification('error', 'Ошибка', errors[0]);
2263
- return;
2383
+ return {
2384
+ type: OrderCheckoutResultType.Validation,
2385
+ reason: OrderCheckoutResultReason.AddressError,
2386
+ data: errors,
2387
+ };
2264
2388
  }
2265
2389
  saving.value = true;
2266
2390
  try {
2267
2391
  await setOrderCheckoutDelivery(credentials.value, data);
2268
2392
  emit('completed');
2393
+ return {
2394
+ type: OrderCheckoutResultType.Completed,
2395
+ };
2269
2396
  }
2270
2397
  catch (e) {
2271
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось сохранить способ доставки.'));
2398
+ return {
2399
+ type: OrderCheckoutResultType.Failed,
2400
+ reason: OrderCheckoutResultReason.ApiError,
2401
+ error: getApiError(e),
2402
+ };
2272
2403
  }
2273
2404
  finally {
2274
2405
  saving.value = false;
@@ -2294,7 +2425,6 @@ function getPaymentMethod(settings) {
2294
2425
  return available[0];
2295
2426
  }
2296
2427
  function useBillSuggestions(unpaidAmount, staticAmounts = [10, 50, 200, 5000], availableBills = [100, 500, 1000]) {
2297
- const { totalPrice } = useTotalPrice();
2298
2428
  const getClosestMultipleOf = (price, amount) => Math.ceil(price / amount) * amount;
2299
2429
  const suggestions = computed(() => {
2300
2430
  const items = new Set([
@@ -2305,19 +2435,16 @@ function useBillSuggestions(unpaidAmount, staticAmounts = [10, 50, 200, 5000], a
2305
2435
  const bills = [...items]
2306
2436
  .filter((suggestion) => suggestion > unpaidAmount.value)
2307
2437
  .sort((first, second) => (first - second))
2308
- .map((amount) => {
2309
- var _a, _b;
2310
- return ({
2311
- value: amount,
2312
- label: `${(_a = totalPrice.value) === null || _a === void 0 ? void 0 : _a.currency.prefix}${amount}${(_b = totalPrice.value) === null || _b === void 0 ? void 0 : _b.currency.suffix}`,
2313
- });
2314
- });
2438
+ .map((amount) => ({
2439
+ value: amount,
2440
+ type: BillSuggestionType.Bill,
2441
+ }));
2315
2442
  bills.unshift({
2316
- label: 'Без сдачи',
2443
+ type: BillSuggestionType.NoChange,
2317
2444
  value: '',
2318
2445
  });
2319
2446
  bills.push({
2320
- label: 'Другая',
2447
+ type: BillSuggestionType.Custom,
2321
2448
  value: 'custom',
2322
2449
  });
2323
2450
  return bills;
@@ -2348,7 +2475,6 @@ function useBonusesPreviewChecker(order, credentials, bonuses, setBonuses) {
2348
2475
  unpaidAmount.value = preview.unpaid;
2349
2476
  if (parseFloat(bonuses.value) > parseFloat(preview.bonuses.trimmed)) {
2350
2477
  setBonuses(preview.bonuses.trimmed);
2351
- useNotification('warning', 'Сумма бонусов изменена', 'Вы указали сумму бонусов, превышающую лимит списания. Мы изменили сумму на максимально доступную.');
2352
2478
  }
2353
2479
  }
2354
2480
  catch (e) {
@@ -2401,18 +2527,31 @@ function useDeliveryPaymentsForm(emit) {
2401
2527
  });
2402
2528
  const save = async () => {
2403
2529
  if (!credentials.value) {
2404
- return;
2530
+ return {
2531
+ type: OrderCheckoutResultType.Failed,
2532
+ reason: OrderCheckoutResultReason.OrderNotReady,
2533
+ };
2405
2534
  }
2406
2535
  else if (saving.value) {
2407
- return;
2536
+ return {
2537
+ type: OrderCheckoutResultType.Failed,
2538
+ reason: OrderCheckoutResultReason.InProgress,
2539
+ };
2408
2540
  }
2409
2541
  const payments = getPaymentsPayload(form.value);
2410
2542
  try {
2411
2543
  await setOrderCheckoutPayment(credentials.value, { payments });
2412
2544
  emit('completed');
2545
+ return {
2546
+ type: OrderCheckoutResultType.Completed,
2547
+ };
2413
2548
  }
2414
2549
  catch (e) {
2415
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось сохранить способ оплаты.'));
2550
+ return {
2551
+ type: OrderCheckoutResultType.Failed,
2552
+ reason: OrderCheckoutResultReason.ApiError,
2553
+ error: getApiError(e),
2554
+ };
2416
2555
  }
2417
2556
  finally {
2418
2557
  saving.value = false;
@@ -2445,16 +2584,22 @@ function useCheckoutSummary(emit) {
2445
2584
  const saving = ref(false);
2446
2585
  const save = async () => {
2447
2586
  if (!credentials.value) {
2448
- return;
2587
+ return {
2588
+ type: OrderCheckoutResultType.Failed,
2589
+ reason: OrderCheckoutResultReason.OrderNotReady,
2590
+ };
2449
2591
  }
2450
2592
  else if (saving.value) {
2451
- return;
2593
+ return {
2594
+ type: OrderCheckoutResultType.Failed,
2595
+ reason: OrderCheckoutResultReason.InProgress,
2596
+ };
2452
2597
  }
2453
2598
  const payload = {
2454
2599
  notes: form.value.notes,
2455
2600
  };
2456
2601
  if (hasPersonsCount.value && form.value.persons_count) {
2457
- payload.notes = `Персон: ${form.value.persons_count}\n\n${payload.notes}`.trim();
2602
+ payload.persons_count = form.value.persons_count;
2458
2603
  }
2459
2604
  saving.value = true;
2460
2605
  try {
@@ -2468,9 +2613,16 @@ function useCheckoutSummary(emit) {
2468
2613
  if (store.value && city.value) {
2469
2614
  await orderStore.recreate(store.value.id, city.value.id);
2470
2615
  }
2616
+ return {
2617
+ type: OrderCheckoutResultType.Completed,
2618
+ };
2471
2619
  }
2472
2620
  catch (e) {
2473
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось оформить заказ.'));
2621
+ return {
2622
+ type: OrderCheckoutResultType.Failed,
2623
+ reason: OrderCheckoutResultReason.ApiError,
2624
+ error: getApiError(e),
2625
+ };
2474
2626
  }
2475
2627
  finally {
2476
2628
  saving.value = false;
@@ -2692,11 +2844,7 @@ function useModifiers(product, variant, recalculate) {
2692
2844
  modifiers.value = getModifiers(product, variant);
2693
2845
  });
2694
2846
  watch(selectedModifiers, async () => {
2695
- const hash = await recalculate(selectedModifiers);
2696
- if (hash === null) {
2697
- return;
2698
- }
2699
- modifiersHash.value = hash;
2847
+ modifiersHash.value = await recalculate(selectedModifiers);
2700
2848
  });
2701
2849
  return {
2702
2850
  modifiers,
@@ -2859,9 +3007,7 @@ function useVariant(variants) {
2859
3007
  }
2860
3008
 
2861
3009
  function useProductItem(errorHandler) {
2862
- return useItemLoader(getProduct, getApiErrorHandler(errorHandler, function (e) {
2863
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Товар не найден.'));
2864
- }));
3010
+ return useItemLoader(getProduct, getApiErrorHandler(errorHandler, 'useProductItem', 'Unable to load product.'));
2865
3011
  }
2866
3012
  function useProductCard(item) {
2867
3013
  var _a;
@@ -2896,9 +3042,7 @@ function useProductCard(item) {
2896
3042
  }
2897
3043
 
2898
3044
  function useProductsPricesRange(categoryId, errorHandler) {
2899
- return useDataLoader(async () => getProductsPricesRange(categoryId), getApiErrorHandler(errorHandler, function (e) {
2900
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить диапазон цен.'));
2901
- }));
3045
+ return useDataLoader(async () => getProductsPricesRange(categoryId), getApiErrorHandler(errorHandler, 'useProductsPricesRange', 'Unable to load product prices range.'));
2902
3046
  }
2903
3047
 
2904
3048
  function useFeaturesFilters(categoryId, values) {
@@ -3096,9 +3240,7 @@ function getCategoryIdFromSource(source) {
3096
3240
  return source.id;
3097
3241
  }
3098
3242
  function useProductsList(config, errorHandler) {
3099
- const productsLoader = usePaginatedLoader(getProducts, getApiErrorHandler(errorHandler, function (e) {
3100
- useNotification('error', 'Ошибка', getApiErrorMessage(e, 'Не удалось загрузить товары.'));
3101
- }));
3243
+ const productsLoader = usePaginatedLoader(getProducts, getApiErrorHandler(errorHandler, 'useProductsList', 'Unable to load products list.'));
3102
3244
  const store = useStoreStore();
3103
3245
  const cityId = computed(() => store.cityId);
3104
3246
  const sorting = ref(config.value.sorting || ProductsSorting.Manual);
@@ -3478,4 +3620,4 @@ function subscribeToOrderEvents(order) {
3478
3620
  });
3479
3621
  }
3480
3622
 
3481
- export { AuthenticationEvent, AuthenticationResultType, AuthenticationStage, CheckoutStage, ProductsFiltersType, ProductsSorting, ProductsSourceType, ZenkyInjection, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductVariantsPricesRange, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getUpdatedVariants, getWebsocketsConnection, initializeOrderCustomer, initializePromotions, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useBillSuggestions, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCheckoutConfirmation, useCheckoutSummary, useCheckoutTotal, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerCheckoutForm, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useDeliveryCheckoutForm, useDeliveryPaymentsForm, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useModifiers, useModifiersGroup, useOfferItem, useOffersList, useOrderCheckout, useOrderItem, useOrderStore, useOrderVariants, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductCard, useProductItem, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, usePromotionsStore, useRegistration, useReversedTree, useRewardsSelector, useSingleModifier, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity, useTotalPrice, useTotalQuantity, useVariant, useVariantControls, useVariantPrice };
3623
+ export { AddressFormValueError, AddressResultReason, AddressResultType, AuthenticationEvent, AuthenticationFailureReason, AuthenticationResultType, AuthenticationStage, BillSuggestionType, CheckoutStage, OrderCheckoutResultReason, OrderCheckoutResultType, ProductsFiltersType, ProductsSorting, ProductsSourceType, ZenkyInjection, ZenkyWebsocketEvent, createStorage, createWebsocketsConnection, getAddressForm, getApiErrorHandler, getExistedAddress, getExistedAddressDisplayValue, getFirstMedium, getProductVariantsPricesRange, getProductsListParamsFromQuery, getProductsListQueryParams, getProductsPaginationRequest, getProductsSource, getSelectedAddress, getSelectedAddressDisplayValue, getStockAddress, getStockSchedule, getStorage, getUpdatedVariants, getWebsocketsConnection, initializeOrderCustomer, initializePromotions, subscribeToOrderEvents, useAddressFormValue, useArticleCategoriesList, useArticleItem, useArticlesList, useAuthenticationForm, useAuthenticationStatusChecker, useBillSuggestions, useCategories, useCategoriesStore, useCategoriesTree, useCategory, useCategoryFeaturesGroupsList, useCategoryFeaturesList, useCheckoutConfirmation, useCheckoutSummary, useCheckoutTotal, useCollection, useCollections, useCollectionsStore, useCustomer, useCustomerCheckoutForm, useCustomerStore, useDadata, useDataDestroyer, useDataLoader, useDeliveryAddressDestroyer, useDeliveryAddressesList, useDeliveryCheckoutForm, useDeliveryPaymentsForm, useEditAddressForm, useFeaturesFilters, useFeaturesGroupsFilters, useFlatCategoriesTree, useItemLoader, useListLoader, useLogin, useLogout, useModifiers, useModifiersGroup, useOfferItem, useOffersList, useOrderCheckout, useOrderItem, useOrderStore, useOrderVariants, useOrdersList, usePaginatedLoader, usePasswordReset, usePaymentMethodDestroyer, usePaymentMethodsList, usePhoneConfirmation, useProductCard, useProductItem, useProductsList, useProductsPricesRange, useProductsPricesRangeFilters, usePromotionsStore, useRegistration, useReversedTree, useRewardsSelector, useSingleModifier, useSplittedCategoriesTree, useStateDataLoader, useStoreStore, useSuggestionsRestrictedToCity, useTotalPrice, useTotalQuantity, useVariant, useVariantControls, useVariantPrice };