@infrab4a/connect-angular 4.21.0 → 4.21.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/angular-connect.module.d.ts +4 -0
  2. package/esm2020/angular-connect.module.mjs +119 -17
  3. package/esm2020/angular-hasura-graphql.module.mjs +1 -1
  4. package/esm2020/consts/backend-url.const.mjs +1 -1
  5. package/esm2020/interfaces/catalog-strategies.interface.mjs +2 -0
  6. package/esm2020/interfaces/category-facades.interface.mjs +2 -0
  7. package/esm2020/interfaces/index.mjs +3 -0
  8. package/esm2020/persistence/cookie-data-persistence.mjs +1 -1
  9. package/esm2020/services/cart/cart-services.facade.mjs +21 -0
  10. package/esm2020/services/cart/index.mjs +2 -0
  11. package/esm2020/services/cart.service.mjs +25 -38
  12. package/esm2020/services/catalog/adapters/new-category-structure.adapter.mjs +1 -1
  13. package/esm2020/services/catalog/adapters/old-category-structure.adapter.mjs +1 -1
  14. package/esm2020/services/catalog/catalog.service.mjs +80 -294
  15. package/esm2020/services/catalog/category.service.mjs +15 -27
  16. package/esm2020/services/catalog/context/catalog-search.context.mjs +40 -0
  17. package/esm2020/services/catalog/facades/catalog-service.facade.mjs +32 -0
  18. package/esm2020/services/catalog/facades/catalog-strategies.facade.mjs +17 -0
  19. package/esm2020/services/catalog/facades/category-repository.facade.mjs +20 -0
  20. package/esm2020/services/catalog/facades/category-service.facade.mjs +30 -0
  21. package/esm2020/services/catalog/facades/index.mjs +6 -0
  22. package/esm2020/services/catalog/facades/product-catalog.facade.mjs +21 -0
  23. package/esm2020/services/catalog/helpers/brand-manager.helper.mjs +57 -0
  24. package/esm2020/services/catalog/helpers/catalog-filter.helper.mjs +44 -0
  25. package/esm2020/services/catalog/helpers/catalog-sort.helper.mjs +52 -0
  26. package/esm2020/services/catalog/helpers/index.mjs +5 -0
  27. package/esm2020/services/catalog/helpers/product-fields.helper.mjs +39 -0
  28. package/esm2020/services/catalog/models/category-with-tree.model.mjs +1 -1
  29. package/esm2020/services/catalog/services/catalog-helpers.service.mjs +33 -0
  30. package/esm2020/services/catalog/services/catalog-operations.facade.mjs +26 -0
  31. package/esm2020/services/catalog/services/catalog-repository.service.mjs +25 -0
  32. package/esm2020/services/catalog/services/index.mjs +5 -0
  33. package/esm2020/services/catalog/services/product-management.facade.mjs +25 -0
  34. package/esm2020/services/catalog/strategies/category-search.strategy.mjs +133 -0
  35. package/esm2020/services/catalog/strategies/index.mjs +4 -0
  36. package/esm2020/services/catalog/strategies/profile-search.strategy.mjs +42 -0
  37. package/esm2020/services/catalog/strategies/term-search.strategy.mjs +126 -0
  38. package/esm2020/services/catalog/strategies/types/strategy-params.type.mjs +2 -0
  39. package/esm2020/services/catalog/types/fetch-products-options.type.mjs +2 -0
  40. package/esm2020/services/catalog/types/fetch-products-params.type.mjs +2 -0
  41. package/esm2020/services/catalog/types/fetch-products-response.type.mjs +2 -0
  42. package/esm2020/services/catalog/types/index.mjs +5 -1
  43. package/esm2020/services/catalog/types/method-params.type.mjs +2 -0
  44. package/esm2020/services/catalog/wishlist.service.mjs +92 -72
  45. package/esm2020/services/checkout/checkout-dependencies.facade.mjs +20 -0
  46. package/esm2020/services/checkout/checkout-repositories.facade.mjs +20 -0
  47. package/esm2020/services/checkout/index.mjs +3 -0
  48. package/esm2020/services/checkout-subscription.service.mjs +8 -3
  49. package/esm2020/services/checkout.service.mjs +34 -50
  50. package/esm2020/services/coupon/coupon-repositories.facade.mjs +24 -0
  51. package/esm2020/services/coupon/index.mjs +2 -0
  52. package/esm2020/services/coupon/types/coupon-params.type.mjs +2 -0
  53. package/esm2020/services/coupon.service.mjs +79 -59
  54. package/esm2020/services/helpers/util.helper.mjs +12 -12
  55. package/esm2020/services/home-shop/home-shop-repositories.facade.mjs +24 -0
  56. package/esm2020/services/home-shop/index.mjs +2 -0
  57. package/esm2020/services/home-shop.service.mjs +27 -33
  58. package/esm2020/services/shared/configuration.facade.mjs +29 -0
  59. package/esm2020/services/shared/index.mjs +2 -0
  60. package/fesm2015/infrab4a-connect-angular.mjs +1287 -566
  61. package/fesm2015/infrab4a-connect-angular.mjs.map +1 -1
  62. package/fesm2020/infrab4a-connect-angular.mjs +1207 -533
  63. package/fesm2020/infrab4a-connect-angular.mjs.map +1 -1
  64. package/interfaces/catalog-strategies.interface.d.ts +31 -0
  65. package/interfaces/category-facades.interface.d.ts +6 -0
  66. package/interfaces/index.d.ts +2 -0
  67. package/package.json +5 -3
  68. package/services/cart/cart-services.facade.d.ts +12 -0
  69. package/services/cart/index.d.ts +1 -0
  70. package/services/cart.service.d.ts +6 -11
  71. package/services/catalog/catalog.service.d.ts +11 -83
  72. package/services/catalog/category.service.d.ts +5 -7
  73. package/services/catalog/context/catalog-search.context.d.ts +14 -0
  74. package/services/catalog/facades/catalog-service.facade.d.ts +15 -0
  75. package/services/catalog/facades/catalog-strategies.facade.d.ts +10 -0
  76. package/services/catalog/facades/category-repository.facade.d.ts +9 -0
  77. package/services/catalog/facades/category-service.facade.d.ts +15 -0
  78. package/services/catalog/facades/index.d.ts +5 -0
  79. package/services/catalog/facades/product-catalog.facade.d.ts +10 -0
  80. package/services/catalog/helpers/brand-manager.helper.d.ts +14 -0
  81. package/services/catalog/helpers/catalog-filter.helper.d.ts +8 -0
  82. package/services/catalog/helpers/catalog-sort.helper.d.ts +7 -0
  83. package/services/catalog/helpers/index.d.ts +4 -0
  84. package/services/catalog/helpers/product-fields.helper.d.ts +7 -0
  85. package/services/catalog/services/catalog-helpers.service.d.ts +17 -0
  86. package/services/catalog/services/catalog-operations.facade.d.ts +13 -0
  87. package/services/catalog/services/catalog-repository.service.d.ts +12 -0
  88. package/services/catalog/services/index.d.ts +4 -0
  89. package/services/catalog/services/product-management.facade.d.ts +12 -0
  90. package/services/catalog/strategies/category-search.strategy.d.ts +19 -0
  91. package/services/catalog/strategies/index.d.ts +3 -0
  92. package/services/catalog/strategies/profile-search.strategy.d.ts +14 -0
  93. package/services/catalog/strategies/term-search.strategy.d.ts +20 -0
  94. package/services/catalog/strategies/types/strategy-params.type.d.ts +58 -0
  95. package/services/catalog/types/fetch-products-options.type.d.ts +8 -0
  96. package/services/catalog/types/fetch-products-params.type.d.ts +25 -0
  97. package/services/catalog/types/fetch-products-response.type.d.ts +19 -0
  98. package/services/catalog/types/index.d.ts +4 -0
  99. package/services/catalog/types/method-params.type.d.ts +17 -0
  100. package/services/catalog/wishlist.service.d.ts +12 -4
  101. package/services/checkout/checkout-dependencies.facade.d.ts +10 -0
  102. package/services/checkout/checkout-repositories.facade.d.ts +9 -0
  103. package/services/checkout/index.d.ts +2 -0
  104. package/services/checkout-subscription.service.d.ts +2 -2
  105. package/services/checkout.service.d.ts +7 -11
  106. package/services/coupon/coupon-repositories.facade.d.ts +10 -0
  107. package/services/coupon/index.d.ts +1 -0
  108. package/services/coupon/types/coupon-params.type.d.ts +13 -0
  109. package/services/coupon.service.d.ts +16 -7
  110. package/services/home-shop/home-shop-repositories.facade.d.ts +10 -0
  111. package/services/home-shop/index.d.ts +1 -0
  112. package/services/home-shop.service.d.ts +6 -6
  113. package/services/shared/configuration.facade.d.ts +12 -0
  114. package/services/shared/index.d.ts +1 -0
@@ -1,13 +1,13 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { NgModule, InjectionToken, PLATFORM_ID, Injectable, Inject } from '@angular/core';
3
- import * as i1$4 from '@angular/fire/app';
3
+ import * as i1$3 from '@angular/fire/app';
4
4
  import { FirebaseApp, provideFirebaseApp, getApp, initializeApp } from '@angular/fire/app';
5
5
  import * as i2 from '@angular/fire/app-check';
6
6
  import { provideAppCheck, initializeAppCheck } from '@angular/fire/app-check';
7
- import * as i3 from '@angular/fire/storage';
7
+ import * as i3$1 from '@angular/fire/storage';
8
8
  import { Storage, provideStorage, getStorage } from '@angular/fire/storage';
9
- import * as i1$3 from '@infrab4a/connect';
10
- import { ProductsIndex, AxiosAdapter, Authentication, AuthenticationFirebaseAuthService, Register, RegisterFirebaseAuthService, SignOut, RecoveryPassword, ConnectFirestoreService, UserBeautyProfileFirestoreRepository, Buy2WinFirestoreRepository, CategoryFirestoreRepository, CheckoutFirestoreRepository, CheckoutSubscriptionFirestoreRepository, CouponFirestoreRepository, CampaignHashtagFirestoreRepository, CampaignDashboardFirestoreRepository, SubscriptionEditionFirestoreRepository, GroupFirestoreRepository, HomeFirestoreRepository, LeadFirestoreRepository, LegacyOrderFirestoreRepository, ShopMenuFirestoreRepository, OrderFirestoreRepository, PaymentFirestoreRepository, ProductFirestoreRepository, ShopSettingsFirestoreRepository, SubscriptionPaymentFirestoreRepository, SubscriptionPlanFirestoreRepository, SubscriptionProductFirestoreRepository, SubscriptionFirestoreRepository, UserFirestoreRepository, UserAddressFirestoreRepository, UserPaymentMethodFirestoreRepository, SubscriptionMaterializationFirestoreRepository, SubscriptionSummaryFirestoreRepository, ProductVariantFirestoreRepository, OrderBlockedFirestoreRepository, LogFirestoreRepository, SequenceFirestoreRepository, CategoryHasuraGraphQLRepository, ProductHasuraGraphQLRepository, CategoryFilterHasuraGraphQLRepository, ProductReviewHasuraGraphQLRepository, VariantHasuraGraphQLRepository, ProductStockNotificationHasuraGraphQLRepository, FilterOptionHasuraGraphQLRepository, FilterHasuraGraphQLRepository, CategoryCollectionChildrenHasuraGraphQLRepository, CategoryProductHasuraGraphQLRepository, WishlistHasuraGraphQLRepository, ProductErrorsHasuraGraphQLRepository, ProductsVertexSearch, VertexAxiosAdapter, isNil, NotFoundError, Checkout, pick, LineItem, Where, set, InvalidArgumentError, RoundProductPricesHelper, isEmpty, Shops, Category, PersonTypes, WishlistLogType, Wishlist, CheckoutTypes, CouponTypes, Exclusivities, OrderStatus, CheckoutSubscription, Product, RequiredArgumentError, add, Order, UpdateUserImage, FirebaseFileUploaderService } from '@infrab4a/connect';
9
+ import * as i3 from '@infrab4a/connect';
10
+ import { ProductsIndex, AxiosAdapter, Authentication, AuthenticationFirebaseAuthService, Register, RegisterFirebaseAuthService, SignOut, RecoveryPassword, ConnectFirestoreService, UserBeautyProfileFirestoreRepository, Buy2WinFirestoreRepository, CategoryFirestoreRepository, CheckoutFirestoreRepository, CheckoutSubscriptionFirestoreRepository, CouponFirestoreRepository, CampaignHashtagFirestoreRepository, CampaignDashboardFirestoreRepository, SubscriptionEditionFirestoreRepository, GroupFirestoreRepository, HomeFirestoreRepository, LeadFirestoreRepository, LegacyOrderFirestoreRepository, ShopMenuFirestoreRepository, OrderFirestoreRepository, PaymentFirestoreRepository, ProductFirestoreRepository, ShopSettingsFirestoreRepository, SubscriptionPaymentFirestoreRepository, SubscriptionPlanFirestoreRepository, SubscriptionProductFirestoreRepository, SubscriptionFirestoreRepository, UserFirestoreRepository, UserAddressFirestoreRepository, UserPaymentMethodFirestoreRepository, SubscriptionMaterializationFirestoreRepository, SubscriptionSummaryFirestoreRepository, ProductVariantFirestoreRepository, OrderBlockedFirestoreRepository, LogFirestoreRepository, SequenceFirestoreRepository, CategoryHasuraGraphQLRepository, ProductHasuraGraphQLRepository, CategoryFilterHasuraGraphQLRepository, ProductReviewHasuraGraphQLRepository, VariantHasuraGraphQLRepository, ProductStockNotificationHasuraGraphQLRepository, FilterOptionHasuraGraphQLRepository, FilterHasuraGraphQLRepository, CategoryCollectionChildrenHasuraGraphQLRepository, CategoryProductHasuraGraphQLRepository, WishlistHasuraGraphQLRepository, ProductErrorsHasuraGraphQLRepository, ProductsVertexSearch, VertexAxiosAdapter, isNil, NotFoundError, Checkout, pick, LineItem, Where, Shops, isEmpty, set, InvalidArgumentError, RoundProductPricesHelper, Category, WishlistLogType, PersonTypes, Wishlist, CheckoutTypes, CouponTypes, Exclusivities, OrderStatus, CheckoutSubscription, Product, RequiredArgumentError, add, Order, UpdateUserImage, FirebaseFileUploaderService } from '@infrab4a/connect';
11
11
  import * as i1 from '@angular/fire/auth';
12
12
  import { Auth, provideAuth, initializeAuth, indexedDBLocalPersistence, browserLocalPersistence, browserSessionPersistence, getAuth, getIdToken, authState } from '@angular/fire/auth';
13
13
  import { isPlatformBrowser, isPlatformServer } from '@angular/common';
@@ -1148,81 +1148,137 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImpor
1148
1148
  args: ['UserRepository']
1149
1149
  }] }]; } });
1150
1150
 
1151
- class CheckoutService {
1152
- constructor(checkoutRepository, userRepository, defaultShop, dataPersistence, firebaseOptions, http) {
1151
+ class CheckoutRepositoriesFacade {
1152
+ constructor(checkoutRepository, userRepository) {
1153
1153
  this.checkoutRepository = checkoutRepository;
1154
1154
  this.userRepository = userRepository;
1155
- this.defaultShop = defaultShop;
1155
+ }
1156
+ }
1157
+ CheckoutRepositoriesFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutRepositoriesFacade, deps: [{ token: 'CheckoutRepository' }, { token: 'UserRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
1158
+ CheckoutRepositoriesFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutRepositoriesFacade });
1159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutRepositoriesFacade, decorators: [{
1160
+ type: Injectable
1161
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1162
+ type: Inject,
1163
+ args: ['CheckoutRepository']
1164
+ }] }, { type: undefined, decorators: [{
1165
+ type: Inject,
1166
+ args: ['UserRepository']
1167
+ }] }]; } });
1168
+
1169
+ class CheckoutDependenciesFacade {
1170
+ constructor(dataPersistence, httpClient) {
1156
1171
  this.dataPersistence = dataPersistence;
1172
+ this.httpClient = httpClient;
1173
+ }
1174
+ }
1175
+ CheckoutDependenciesFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutDependenciesFacade, deps: [{ token: PERSISTENCE_PROVIDER }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1176
+ CheckoutDependenciesFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutDependenciesFacade });
1177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutDependenciesFacade, decorators: [{
1178
+ type: Injectable
1179
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1180
+ type: Inject,
1181
+ args: [PERSISTENCE_PROVIDER]
1182
+ }] }, { type: i1$2.HttpClient }]; } });
1183
+
1184
+ class ConfigurationFacade {
1185
+ constructor(defaultShop, firebaseOptions) {
1186
+ this.defaultShop = defaultShop;
1157
1187
  this.firebaseOptions = firebaseOptions;
1158
- this.http = http;
1188
+ }
1189
+ getCheckoutUrl() {
1190
+ return `https://southamerica-east1-${this.firebaseOptions.projectId}.cloudfunctions.net`;
1191
+ }
1192
+ getProjectId() {
1193
+ return this.firebaseOptions.projectId;
1194
+ }
1195
+ }
1196
+ ConfigurationFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ConfigurationFacade, deps: [{ token: DEFAULT_SHOP }, { token: FIREBASE_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable });
1197
+ ConfigurationFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ConfigurationFacade });
1198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ConfigurationFacade, decorators: [{
1199
+ type: Injectable
1200
+ }], ctorParameters: function () { return [{ type: i3.Shops, decorators: [{
1201
+ type: Inject,
1202
+ args: [DEFAULT_SHOP]
1203
+ }] }, { type: undefined, decorators: [{
1204
+ type: Inject,
1205
+ args: [FIREBASE_OPTIONS]
1206
+ }] }]; } });
1207
+
1208
+ class CheckoutService {
1209
+ constructor(repositoriesFacade, dependenciesFacade, configurationFacade) {
1210
+ this.repositoriesFacade = repositoriesFacade;
1211
+ this.dependenciesFacade = dependenciesFacade;
1212
+ this.configurationFacade = configurationFacade;
1159
1213
  this.checkoutUrl = null;
1160
- this.checkoutUrl = `https://southamerica-east1-${this.firebaseOptions.projectId}.cloudfunctions.net`;
1214
+ this.checkoutUrl = this.configurationFacade.getCheckoutUrl();
1161
1215
  }
1162
1216
  getCheckout(checkoutData) {
1163
- return this.dataPersistence
1217
+ return this.dependenciesFacade.dataPersistence
1164
1218
  .get('checkoutId')
1165
- .pipe(concatMap((id) => (!isNil(id) ? this.checkoutRepository.get({ id }) : this.createCheckout(checkoutData))));
1219
+ .pipe(concatMap((id) => !isNil(id) ? this.repositoriesFacade.checkoutRepository.get({ id }) : this.createCheckout(checkoutData)));
1166
1220
  }
1167
1221
  getUserByCheckout(checkoutId) {
1168
- return from(this.checkoutRepository.get({ id: checkoutId })).pipe(concatMap((checkout) => checkout?.user?.id ? of(checkout.user) : from(this.userRepository.get({ id: checkout.user.id }))), concatMap((user) => of(user) || throwError(() => new NotFoundError('User is not found'))));
1222
+ return from(this.repositoriesFacade.checkoutRepository.get({ id: checkoutId })).pipe(concatMap((checkout) => checkout?.user?.id
1223
+ ? of(checkout.user)
1224
+ : from(this.repositoriesFacade.userRepository.get({ id: checkout.user.id }))), concatMap((user) => of(user) || throwError(() => new NotFoundError('User is not found'))));
1169
1225
  }
1170
1226
  updateCheckoutLineItems(checkout) {
1171
- return from(this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, lineItems: checkout.lineItems })));
1227
+ return from(this.repositoriesFacade.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, lineItems: checkout.lineItems })));
1172
1228
  }
1173
1229
  updateCheckoutUser(checkout) {
1174
- return from(this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, user: checkout.user })));
1230
+ return from(this.repositoriesFacade.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, user: checkout.user })));
1175
1231
  }
1176
1232
  clearCheckoutFromSession() {
1177
- return this.dataPersistence.remove('checkoutId');
1233
+ return this.dependenciesFacade.dataPersistence.remove('checkoutId');
1178
1234
  }
1179
1235
  resetCheckoutValues() {
1180
- return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutResetValues`, {
1236
+ return this.getCheckout().pipe(concatMap((checkout) => this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkoutResetValues`, {
1181
1237
  checkoutId: checkout.id,
1182
1238
  })), concatMap(() => this.getCheckout()));
1183
1239
  }
1184
1240
  applyCouponDiscount(nickname, checkoutType) {
1185
- return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutApplyDiscount`, {
1241
+ return this.getCheckout().pipe(concatMap((checkout) => this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkoutApplyDiscount`, {
1186
1242
  checkoutId: checkout.id,
1187
1243
  coupon: nickname,
1188
1244
  checkoutType,
1189
1245
  })), concatMap(() => this.getCheckout()), map((checkout) => checkout.coupon));
1190
1246
  }
1191
1247
  removeCouponDiscount() {
1192
- return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutRemoveDiscount`, {
1248
+ return this.getCheckout().pipe(concatMap((checkout) => this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkoutRemoveDiscount`, {
1193
1249
  checkoutId: checkout.id,
1194
1250
  })), concatMap(() => this.getCheckout()));
1195
1251
  }
1196
1252
  validateStockProducts() {
1197
- return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutValidateProductStock`, {
1253
+ return this.getCheckout().pipe(concatMap((checkout) => this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkoutValidateProductStock`, {
1198
1254
  checkoutId: checkout.id,
1199
1255
  })));
1200
1256
  }
1201
1257
  selectShippingAddress(address) {
1202
1258
  return this.getCheckout().pipe(concatMap((checkout) => {
1203
- return this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, shippingAddress: address, billingAddress: address }));
1259
+ return this.repositoriesFacade.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, shippingAddress: address, billingAddress: address }));
1204
1260
  }));
1205
1261
  }
1206
1262
  getAvailableShippingForProduct(productShipping) {
1207
- return this.http.post(`${this.checkoutUrl}/checkoutGetAvailableShipping`, {
1263
+ return this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkoutGetAvailableShipping`, {
1208
1264
  checkoutId: null,
1209
1265
  productShipping,
1210
1266
  });
1211
1267
  }
1212
1268
  getAvailableShippingForCheckout() {
1213
- return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutGetAvailableShipping`, {
1269
+ return this.getCheckout().pipe(concatMap((checkout) => this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkoutGetAvailableShipping`, {
1214
1270
  checkoutId: checkout.id,
1215
1271
  productShipping: null,
1216
1272
  })));
1217
1273
  }
1218
1274
  selectShipping(option) {
1219
- return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutSelectShipping`, {
1275
+ return this.getCheckout().pipe(concatMap((checkout) => this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkoutSelectShipping`, {
1220
1276
  checkoutId: checkout.id,
1221
1277
  shippingOption: option,
1222
1278
  })), concatMap(() => this.getCheckout()));
1223
1279
  }
1224
1280
  createOrder(checkoutPayload, paymentProvider, applicationVersion) {
1225
- return this.http.post(`${this.checkoutUrl}/checkout`, {
1281
+ return this.dependenciesFacade.httpClient.post(`${this.checkoutUrl}/checkout`, {
1226
1282
  data: {
1227
1283
  ...checkoutPayload,
1228
1284
  applicationVersion,
@@ -1231,43 +1287,38 @@ class CheckoutService {
1231
1287
  });
1232
1288
  }
1233
1289
  async createCheckout(checkoutData) {
1234
- const checkout = await this.checkoutRepository.create({
1290
+ const checkout = await this.repositoriesFacade.checkoutRepository.create({
1235
1291
  createdAt: new Date(),
1236
1292
  ...Checkout.toInstance(pick(checkoutData, ['user', 'shop'])).toPlain(),
1237
- shop: checkoutData?.shop || this.defaultShop,
1293
+ shop: checkoutData?.shop || this.configurationFacade.defaultShop,
1238
1294
  });
1239
- await this.dataPersistence.set('checkoutId', checkout.id).toPromise();
1295
+ await this.dependenciesFacade.dataPersistence.set('checkoutId', checkout.id).toPromise();
1240
1296
  return checkout;
1241
1297
  }
1242
1298
  }
1243
- CheckoutService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutService, deps: [{ token: 'CheckoutRepository' }, { token: 'UserRepository' }, { token: DEFAULT_SHOP }, { token: PERSISTENCE_PROVIDER }, { token: FIREBASE_OPTIONS }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1299
+ CheckoutService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutService, deps: [{ token: CheckoutRepositoriesFacade }, { token: CheckoutDependenciesFacade }, { token: ConfigurationFacade }], target: i0.ɵɵFactoryTarget.Injectable });
1244
1300
  CheckoutService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutService });
1245
1301
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CheckoutService, decorators: [{
1246
1302
  type: Injectable
1247
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1248
- type: Inject,
1249
- args: ['CheckoutRepository']
1250
- }] }, { type: undefined, decorators: [{
1251
- type: Inject,
1252
- args: ['UserRepository']
1253
- }] }, { type: i1$3.Shops, decorators: [{
1254
- type: Inject,
1255
- args: [DEFAULT_SHOP]
1256
- }] }, { type: undefined, decorators: [{
1257
- type: Inject,
1258
- args: [PERSISTENCE_PROVIDER]
1259
- }] }, { type: undefined, decorators: [{
1260
- type: Inject,
1261
- args: [FIREBASE_OPTIONS]
1262
- }] }, { type: i1$2.HttpClient }]; } });
1303
+ }], ctorParameters: function () { return [{ type: CheckoutRepositoriesFacade }, { type: CheckoutDependenciesFacade }, { type: ConfigurationFacade }]; } });
1263
1304
 
1264
- class CartService {
1265
- constructor(authService, checkoutService, defaultShop, firebaseOptions, http) {
1305
+ class CartServicesFacade {
1306
+ constructor(authService, checkoutService, httpClient) {
1266
1307
  this.authService = authService;
1267
1308
  this.checkoutService = checkoutService;
1268
- this.defaultShop = defaultShop;
1269
- this.firebaseOptions = firebaseOptions;
1270
- this.http = http;
1309
+ this.httpClient = httpClient;
1310
+ }
1311
+ }
1312
+ CartServicesFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CartServicesFacade, deps: [{ token: AuthService }, { token: CheckoutService }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1313
+ CartServicesFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CartServicesFacade });
1314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CartServicesFacade, decorators: [{
1315
+ type: Injectable
1316
+ }], ctorParameters: function () { return [{ type: AuthService }, { type: CheckoutService }, { type: i1$2.HttpClient }]; } });
1317
+
1318
+ class CartService {
1319
+ constructor(servicesFacade, configurationFacade) {
1320
+ this.servicesFacade = servicesFacade;
1321
+ this.configurationFacade = configurationFacade;
1271
1322
  this.cartSubject = new Subject();
1272
1323
  this.checkoutUrl = null;
1273
1324
  this.generateCartObject = (items) => items?.reduce((cart, item) => ({
@@ -1277,34 +1328,34 @@ class CartService {
1277
1328
  quantity: (cart[item.id]?.quantity || 0) + (item.quantity ? item.quantity : 1),
1278
1329
  }),
1279
1330
  }), {}) || {};
1280
- this.checkoutUrl = `https://southamerica-east1-${this.firebaseOptions.projectId}.cloudfunctions.net`;
1331
+ this.checkoutUrl = this.configurationFacade.getCheckoutUrl();
1281
1332
  }
1282
1333
  addItem(item, quantity = 1) {
1283
- return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutAddItemToCart`, {
1334
+ return this.servicesFacade.checkoutService.getCheckout().pipe(concatMap((checkout) => this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutAddItemToCart`, {
1284
1335
  checkoutId: checkout.id,
1285
1336
  productId: item.id,
1286
1337
  quantity,
1287
- })), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1338
+ })), concatMap(() => this.servicesFacade.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1288
1339
  }
1289
1340
  decreaseItem(item) {
1290
- return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutDecreaseProductFromCart`, {
1341
+ return this.servicesFacade.checkoutService.getCheckout().pipe(concatMap((checkout) => this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutDecreaseProductFromCart`, {
1291
1342
  checkoutId: checkout.id,
1292
1343
  productId: item.id,
1293
1344
  quantity: 1,
1294
- })), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1345
+ })), concatMap(() => this.servicesFacade.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1295
1346
  }
1296
1347
  removeItem(item) {
1297
- return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutRemoveProductFromCart`, {
1348
+ return this.servicesFacade.checkoutService.getCheckout().pipe(concatMap((checkout) => this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutRemoveProductFromCart`, {
1298
1349
  checkoutId: checkout.id,
1299
1350
  productId: item.id,
1300
- })), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1351
+ })), concatMap(() => this.servicesFacade.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1301
1352
  }
1302
1353
  updateUserCart(user) {
1303
- return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.checkoutService.updateCheckoutUser(Checkout.toInstance({ ...checkout.toPlain(), user }))), concatMap((checkout) => {
1304
- return this.http.post(`${this.checkoutUrl}/checkoutUpdateUserCart`, {
1354
+ return this.servicesFacade.checkoutService.getCheckout().pipe(concatMap((checkout) => this.servicesFacade.checkoutService.updateCheckoutUser(Checkout.toInstance({ ...checkout.toPlain(), user }))), concatMap((checkout) => {
1355
+ return this.servicesFacade.httpClient.post(`${this.checkoutUrl}/checkoutUpdateUserCart`, {
1305
1356
  checkoutId: checkout.id,
1306
1357
  });
1307
- }), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => {
1358
+ }), concatMap(() => this.servicesFacade.checkoutService.getCheckout()), map((updatedCheckout) => {
1308
1359
  return this.generateCartObject(updatedCheckout.lineItems);
1309
1360
  }), tap((cart) => this.cartSubject.next(cart)));
1310
1361
  }
@@ -1313,26 +1364,20 @@ class CartService {
1313
1364
  return this.cartSubject;
1314
1365
  }
1315
1366
  clearCart() {
1316
- return this.checkoutService.getCheckout().pipe(map((checkout) => {
1317
- this.checkoutService.clearCheckoutFromSession();
1367
+ return this.servicesFacade.checkoutService.getCheckout().pipe(map((checkout) => {
1368
+ this.servicesFacade.checkoutService.clearCheckoutFromSession();
1318
1369
  return checkout;
1319
1370
  }), concatMap((oldCheckout) => this.buildCartFromCheckout(oldCheckout)), tap((cart) => this.cartSubject.next(cart)));
1320
1371
  }
1321
1372
  buildCartFromCheckout(checkoutData) {
1322
- return this.checkoutService.getCheckout(checkoutData).pipe(map((checkout) => checkout.lineItems), concatMap((lineItems) => of(this.generateCartObject(lineItems))));
1373
+ return this.servicesFacade.checkoutService.getCheckout(checkoutData).pipe(map((checkout) => checkout.lineItems), concatMap((lineItems) => of(this.generateCartObject(lineItems))));
1323
1374
  }
1324
1375
  }
1325
- CartService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CartService, deps: [{ token: AuthService }, { token: CheckoutService }, { token: DEFAULT_SHOP }, { token: FIREBASE_OPTIONS }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1376
+ CartService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CartService, deps: [{ token: CartServicesFacade }, { token: ConfigurationFacade }], target: i0.ɵɵFactoryTarget.Injectable });
1326
1377
  CartService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CartService });
1327
1378
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CartService, decorators: [{
1328
1379
  type: Injectable
1329
- }], ctorParameters: function () { return [{ type: AuthService }, { type: CheckoutService }, { type: i1$3.Shops, decorators: [{
1330
- type: Inject,
1331
- args: [DEFAULT_SHOP]
1332
- }] }, { type: undefined, decorators: [{
1333
- type: Inject,
1334
- args: [FIREBASE_OPTIONS]
1335
- }] }, { type: i1$2.HttpClient }]; } });
1380
+ }], ctorParameters: function () { return [{ type: CartServicesFacade }, { type: ConfigurationFacade }]; } });
1336
1381
 
1337
1382
  class NewCategoryStructureAdapter {
1338
1383
  constructor(categoryRepository) {
@@ -1394,237 +1439,288 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImpor
1394
1439
  args: ['CategoryRepository']
1395
1440
  }] }]; } });
1396
1441
 
1397
- class CatalogService {
1398
- constructor(productRepository, productStockNotificationRepository, categoryRepository, categoryStructureAdapter, shop, productSearch) {
1399
- this.productRepository = productRepository;
1400
- this.productStockNotificationRepository = productStockNotificationRepository;
1401
- this.categoryRepository = categoryRepository;
1402
- this.categoryStructureAdapter = categoryStructureAdapter;
1403
- this.shop = shop;
1404
- this.productSearch = productSearch;
1405
- this.productsByTerm = {};
1406
- this.brandsList = {};
1407
- this.fields = [
1408
- 'id',
1409
- 'name',
1410
- 'slug',
1411
- 'images',
1412
- 'miniatures',
1413
- 'price',
1414
- 'stock',
1415
- 'published',
1416
- 'CEST',
1417
- 'EAN',
1418
- 'NCM',
1419
- 'brand',
1420
- 'costPrice',
1421
- 'hasVariants',
1422
- 'isKit',
1423
- 'sku',
1424
- 'rate',
1425
- 'tags',
1426
- 'type',
1427
- 'shoppingCount',
1428
- 'gender',
1429
- 'createdAt',
1430
- 'label',
1431
- 'outlet',
1432
- 'group',
1433
- ];
1434
- this.buildFilterQuery = ({ clubDiscount, brands, prices, gender, tags, rate, customOptions, }) => {
1435
- const filters = {};
1436
- if (clubDiscount?.length)
1437
- set(filters, 'price.subscriberDiscountPercentage', { operator: Where.IN, value: clubDiscount });
1438
- if (brands?.length)
1439
- filters.brand = { operator: Where.IN, value: brands };
1440
- if (gender?.length)
1441
- filters.gender = { operator: Where.IN, value: gender };
1442
- if (prices?.min || prices?.max)
1443
- set(filters, prices.subscriberPrice ? 'price.subscriberPrice' : 'price.price', [
1444
- ...(prices.min ? [{ operator: Where.GTE, value: Math.floor(prices.min) }] : []),
1445
- ...(prices.max ? [{ operator: Where.LTE, value: Math.ceil(prices.max) }] : []),
1446
- ]);
1447
- if (rate)
1448
- filters.rate = { operator: Where.GTE, value: rate };
1449
- if (tags?.length)
1450
- filters.tags = { operator: Where.LIKE, value: tags };
1451
- if (customOptions?.length)
1452
- filters.filters = { operator: Where.LIKE, value: customOptions };
1453
- return filters;
1454
- };
1455
- this.buildSortQuery = (sort) => {
1456
- if (!sort || sort === 'most-relevant')
1457
- return {};
1458
- if (sort === 'best-sellers')
1459
- return {
1460
- shoppingCount: 'desc',
1461
- rate: 'desc',
1462
- stock: 'desc',
1463
- name: 'asc',
1464
- };
1465
- if (sort === 'biggest-price')
1466
- return { subscriberPrice: 'desc', rate: 'desc', shoppingCount: 'desc' };
1467
- if (sort === 'lowest-price')
1468
- return { subscriberPrice: 'asc', rate: 'desc', shoppingCount: 'desc' };
1469
- if (sort === 'best-rating')
1470
- return { rate: 'desc', shoppingCount: 'desc', stock: 'desc', name: 'asc' };
1471
- if (sort === 'news')
1472
- return { createdAt: 'desc' };
1473
- if (sort === 'biggest-discount')
1474
- return { subscriberDiscountPercentage: 'desc', rate: 'desc', shoppingCount: 'desc' };
1475
- };
1476
- this.buildLimitQuery = (options) => {
1477
- const limit = options?.perPage || 20;
1478
- return {
1479
- limit,
1480
- offset: ((options?.page || 1) - 1) * limit,
1481
- };
1482
- };
1483
- this.hasProfile = (options) => 'profile' in options;
1484
- this.hasTerm = (options) => 'term' in options;
1485
- this.hasCategory = (options) => 'category' in options;
1486
- this.buildIndexBrands = (options) => {
1487
- if (this.hasCategory(options))
1488
- return `category-${options.category.id}`;
1489
- if (this.hasTerm(options))
1490
- return `term-${options.term}`;
1491
- if (this.hasProfile(options))
1492
- return `profile-${options.profile.join(',')}`;
1493
- return '';
1494
- };
1442
+ class CatalogSearchContext {
1443
+ constructor(categoryStrategy, termStrategy, profileStrategy) {
1444
+ this.categoryStrategy = categoryStrategy;
1445
+ this.termStrategy = termStrategy;
1446
+ this.profileStrategy = profileStrategy;
1447
+ this.strategies = new Map();
1448
+ this.initializeStrategies();
1449
+ }
1450
+ async executeSearch(params, shop, optionsCache) {
1451
+ const strategy = this.selectStrategy(params);
1452
+ return strategy.search(params, shop, optionsCache);
1453
+ }
1454
+ initializeStrategies() {
1455
+ this.strategies.set('category', this.categoryStrategy);
1456
+ this.strategies.set('term', this.termStrategy);
1457
+ this.strategies.set('profile', this.profileStrategy);
1458
+ }
1459
+ selectStrategy(params) {
1460
+ if (params.category) {
1461
+ const strategy = this.strategies.get('category');
1462
+ if (!strategy)
1463
+ throw new Error('Category strategy not found');
1464
+ return strategy;
1465
+ }
1466
+ if (params.term) {
1467
+ const strategy = this.strategies.get('term');
1468
+ if (!strategy)
1469
+ throw new Error('Term strategy not found');
1470
+ return strategy;
1471
+ }
1472
+ if (params.profile?.length) {
1473
+ const strategy = this.strategies.get('profile');
1474
+ if (!strategy)
1475
+ throw new Error('Profile strategy not found');
1476
+ return strategy;
1477
+ }
1478
+ throw new Error('No valid search strategy found for the given parameters');
1495
1479
  }
1496
- async fetchProducts(options, optionsCache) {
1497
- const limits = this.buildLimitQuery(options);
1498
- if (this.hasProfile(options) && options.filters?.customOptions)
1499
- throw new InvalidArgumentError(`It couldn't filled customOptions when profile is given`);
1500
- if (this.hasProfile(options) && options.filters?.tags)
1501
- throw new InvalidArgumentError(`It couldn't filled tags when profile is given`);
1502
- if (this.hasTerm(options) && options.filters?.customOptions)
1503
- throw new InvalidArgumentError(`It couldn't filled customOptions when term is given`);
1504
- return await this.findCatalog(options, limits, optionsCache).then(async ({ data, count: total, maximum, minimal, distinct }) => {
1505
- await this.setBrandsList(options, distinct?.brand);
1506
- return {
1507
- products: { data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)), total },
1508
- pages: Math.ceil(total / limits.limit),
1509
- prices: {
1510
- price: { min: +minimal?.price?.price?.toFixed(2), max: +maximum?.price?.price?.toFixed(2) },
1511
- subscriberPrice: {
1512
- min: +minimal?.price?.subscriberPrice?.toFixed(2),
1513
- max: +maximum?.price?.subscriberPrice?.toFixed(2),
1514
- },
1515
- },
1516
- brands: this.brandsList[this.buildIndexBrands(options)],
1517
- };
1480
+ }
1481
+
1482
+ class CategorySearchStrategy {
1483
+ constructor(repositoryService, helpersService) {
1484
+ this.repositoryService = repositoryService;
1485
+ this.helpersService = helpersService;
1486
+ }
1487
+ async search(params, shop, optionsCache) {
1488
+ const { category, filters, limits, sort, mainGender } = params;
1489
+ if (!category) {
1490
+ throw new Error('Category is required for CategorySearchStrategy');
1491
+ }
1492
+ const fields = this.helpersService.getFieldsHelper().getStandardFields();
1493
+ if (sort === 'most-relevant') {
1494
+ return this.searchWithMostRelevant({
1495
+ category,
1496
+ filters,
1497
+ limits,
1498
+ shop,
1499
+ mainGender,
1500
+ optionsCache,
1501
+ fields,
1502
+ });
1503
+ }
1504
+ return this.searchDefault({
1505
+ category,
1506
+ filters,
1507
+ limits,
1508
+ shop,
1509
+ mainGender,
1510
+ sort,
1511
+ optionsCache,
1512
+ fields,
1518
1513
  });
1519
1514
  }
1520
- async addCustomerToStockNotification(shop, productId, name, email) {
1521
- return this.productStockNotificationRepository.addCustomerEmail(shop, productId, name, email);
1515
+ async searchWithMostRelevant(params) {
1516
+ const { category, filters, shop, optionsCache } = params;
1517
+ const mostRelevant = category.isWishlist ? [] : category.getMostRelevantByShop(shop);
1518
+ const productsIds = await this.getProductIds(category, filters, optionsCache);
1519
+ return this.findAndSortByMostRelevant({
1520
+ mostRelevants: mostRelevant,
1521
+ productIds: productsIds,
1522
+ filters: params.filters,
1523
+ limits: params.limits,
1524
+ shop: params.shop,
1525
+ mainGender: params.mainGender,
1526
+ optionsCache: params.optionsCache,
1527
+ fields: params.fields,
1528
+ });
1522
1529
  }
1523
- async findCatalog(options, limits, optionsCache) {
1524
- if (this.hasTerm(options) && options.sort === 'most-relevant') {
1525
- const productsIds = await this.findCatalogIdsBySearch(options.term);
1526
- return this.findCatalogAndSortByMostRevelantByTerm(productsIds, options, limits);
1527
- }
1528
- if (this.hasCategory(options) && options.sort === 'most-relevant') {
1529
- const mostRelevant = options.category.isWishlist ? [] : options.category.getMostRelevantByShop(this.shop);
1530
- const productsIds = await this.productRepository
1531
- .findCatalog({
1532
- fields: ['id'],
1533
- filters: {
1534
- ...(await this.buildMainFilter(options)),
1535
- ...this.buildFilterQuery(options?.filters || {}),
1536
- },
1537
- }, undefined, optionsCache)
1538
- .then((products) => products.data.map((product) => product.id));
1539
- return this.findCatalogAndSortByMostRevelant(mostRelevant, productsIds, options, limits, optionsCache);
1540
- }
1530
+ async searchDefault(params) {
1531
+ const { category, filters, limits, shop, mainGender, sort, optionsCache, fields } = params;
1532
+ const productCatalog = this.repositoryService.getProductCatalog();
1533
+ const filterHelper = this.helpersService.getFilterHelper();
1534
+ const sortHelper = this.helpersService.getSortHelper();
1541
1535
  const repoParams = {
1542
- fields: this.fields,
1536
+ fields,
1543
1537
  filters: {
1544
- ...(await this.buildMainFilter(options)),
1545
- ...this.buildFilterQuery(options?.filters || {}),
1538
+ ...(await productCatalog.categoryStructureAdapter.buildProductFilterByCategory(category)),
1539
+ ...filterHelper.buildFilterQuery(filters || {}),
1546
1540
  },
1547
- ...(options?.sort ? { orderBy: this.buildSortQuery(options?.sort) } : {}),
1541
+ ...(sort ? { orderBy: sortHelper.buildSortQuery(sort) } : {}),
1548
1542
  limits,
1549
1543
  options: {
1550
1544
  minimal: ['price'],
1551
1545
  maximum: ['price'],
1552
- ...(!this.brandsList[this.buildIndexBrands(options)] && isEmpty(options.filters?.brands)
1553
- ? { distinct: ['brand'] }
1554
- : {}),
1546
+ distinct: ['brand'],
1555
1547
  },
1556
1548
  };
1557
- if (['biggest-price', 'lowest-price', 'biggest-discount', 'best-rating'].includes(options.sort))
1558
- return this.productRepository.findCatalog(repoParams, undefined, optionsCache);
1559
- return this.productRepository.findCatalog(repoParams, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female', optionsCache);
1560
- }
1561
- async buildMainFilter({ category, profile, term, }) {
1562
- if (category)
1563
- return this.categoryStructureAdapter.buildProductFilterByCategory(category);
1564
- if (profile)
1565
- return { tags: { operator: Where.LIKE, value: profile } };
1566
- if (term)
1567
- return this.productSearch
1568
- .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
1569
- .then((data) => ({ id: { operator: Where.IN, value: data.map((_source) => _source.id) } }));
1570
- }
1571
- async findCatalogAndSortByMostRevelant(mostRelevants, productIds, options, limits, optionsCache) {
1572
- const brandsList = this.brandsList[this.buildIndexBrands(options)];
1549
+ return productCatalog.productRepository.findCatalog(repoParams, mainGender || (shop === Shops.MENSMARKET ? 'male' : 'female'), optionsCache);
1550
+ }
1551
+ async getProductIds(category, filters, optionsCache) {
1552
+ const productCatalog = this.repositoryService.getProductCatalog();
1553
+ const filterHelper = this.helpersService.getFilterHelper();
1554
+ return productCatalog.productRepository
1555
+ .findCatalog({
1556
+ fields: ['id'],
1557
+ filters: {
1558
+ ...(await productCatalog.categoryStructureAdapter.buildProductFilterByCategory(category)),
1559
+ ...filterHelper.buildFilterQuery(filters || {}),
1560
+ },
1561
+ }, undefined, optionsCache)
1562
+ .then((products) => products.data.map((product) => product.id));
1563
+ }
1564
+ async findAndSortByMostRelevant(params) {
1565
+ const { mostRelevants, productIds, filters, shop, mainGender, optionsCache, fields, limits } = params;
1566
+ const productCatalog = this.repositoryService.getProductCatalog();
1567
+ const filterHelper = this.helpersService.getFilterHelper();
1568
+ const sortHelper = this.helpersService.getSortHelper();
1573
1569
  const mostRelevantProductsIds = [...new Set(mostRelevants.concat(productIds))];
1574
- const totalResult = await this.productRepository.findCatalog({
1575
- fields: this.fields,
1570
+ const totalResult = await productCatalog.productRepository.findCatalog({
1571
+ fields,
1576
1572
  filters: {
1577
1573
  id: { operator: Where.IN, value: mostRelevantProductsIds },
1578
- ...this.buildFilterQuery(options?.filters || {}),
1574
+ ...filterHelper.buildFilterQuery(filters || {}),
1579
1575
  },
1580
- orderBy: this.buildSortQuery('best-sellers'),
1576
+ orderBy: sortHelper.buildSortQuery('best-sellers'),
1581
1577
  options: {
1582
1578
  minimal: ['price'],
1583
1579
  maximum: ['price'],
1584
- ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
1580
+ ...(isEmpty(filters?.brands) ? { distinct: ['brand'] } : {}),
1585
1581
  },
1586
- }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female', optionsCache);
1587
- const mostRelevantWithouyStock = totalResult.data.filter((product) => mostRelevants.includes(product.id) && product.stock.quantity <= 0);
1582
+ }, mainGender || (shop === Shops.MENSMARKET ? 'male' : 'female'), optionsCache);
1583
+ return this.sortProductsByRelevance(totalResult, mostRelevants, limits);
1584
+ }
1585
+ sortProductsByRelevance(totalResult, mostRelevants, limits) {
1586
+ const mostRelevantWithoutStock = totalResult.data.filter((product) => mostRelevants.includes(product.id) && product.stock.quantity <= 0);
1588
1587
  const firstProducts = totalResult.data
1589
1588
  .filter((product) => mostRelevants.includes(product.id) && product.stock.quantity > 0)
1590
1589
  .sort((a, b) => mostRelevants.indexOf(a.id) - mostRelevants.indexOf(b.id));
1591
1590
  const lastProducts = totalResult.data
1592
1591
  .filter((product) => !mostRelevants.includes(product.id))
1593
- .concat(mostRelevantWithouyStock);
1592
+ .concat(mostRelevantWithoutStock);
1594
1593
  const categoryMostRelevants = firstProducts.concat(lastProducts);
1595
1594
  const resultFinal = categoryMostRelevants.slice(limits.offset, limits.offset + limits.limit);
1596
- await this.setBrandsList(options, totalResult.distinct?.brand);
1597
1595
  return {
1598
1596
  data: resultFinal,
1599
1597
  count: totalResult.count,
1600
1598
  maximum: totalResult.maximum,
1601
1599
  minimal: totalResult.minimal,
1602
- distinct: {
1603
- ...totalResult.distinct,
1604
- brand: this.brandsList[this.buildIndexBrands(options)],
1600
+ distinct: totalResult.distinct,
1601
+ };
1602
+ }
1603
+ }
1604
+ CategorySearchStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategorySearchStrategy, deps: [{ token: CatalogRepositoryService }, { token: CatalogHelpersService }], target: i0.ɵɵFactoryTarget.Injectable });
1605
+ CategorySearchStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategorySearchStrategy });
1606
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategorySearchStrategy, decorators: [{
1607
+ type: Injectable
1608
+ }], ctorParameters: function () { return [{ type: CatalogRepositoryService }, { type: CatalogHelpersService }]; } });
1609
+
1610
+ class ProfileSearchStrategy {
1611
+ constructor(repositoryService, helpersService) {
1612
+ this.repositoryService = repositoryService;
1613
+ this.helpersService = helpersService;
1614
+ }
1615
+ async search(params, shop, optionsCache) {
1616
+ const { profile, filters, limits, sort, mainGender } = params;
1617
+ if (!profile) {
1618
+ throw new Error('Profile is required for ProfileSearchStrategy');
1619
+ }
1620
+ const productCatalog = this.repositoryService.getProductCatalog();
1621
+ const filterHelper = this.helpersService.getFilterHelper();
1622
+ const sortHelper = this.helpersService.getSortHelper();
1623
+ const fieldsHelper = this.helpersService.getFieldsHelper();
1624
+ const repoParams = {
1625
+ fields: fieldsHelper.getStandardFields(),
1626
+ filters: {
1627
+ tags: { operator: Where.LIKE, value: profile },
1628
+ ...filterHelper.buildFilterQuery(filters || {}),
1629
+ },
1630
+ ...(sort ? { orderBy: sortHelper.buildSortQuery(sort) } : {}),
1631
+ limits,
1632
+ options: {
1633
+ minimal: ['price'],
1634
+ maximum: ['price'],
1635
+ distinct: ['brand'],
1605
1636
  },
1606
1637
  };
1638
+ return productCatalog.productRepository.findCatalog(repoParams, mainGender || (shop === Shops.MENSMARKET ? 'male' : 'female'), optionsCache);
1639
+ }
1640
+ }
1641
+ ProfileSearchStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProfileSearchStrategy, deps: [{ token: CatalogRepositoryService }, { token: CatalogHelpersService }], target: i0.ɵɵFactoryTarget.Injectable });
1642
+ ProfileSearchStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProfileSearchStrategy });
1643
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProfileSearchStrategy, decorators: [{
1644
+ type: Injectable
1645
+ }], ctorParameters: function () { return [{ type: CatalogRepositoryService }, { type: CatalogHelpersService }]; } });
1646
+
1647
+ class TermSearchStrategy {
1648
+ constructor(repositoryService, helpersService) {
1649
+ this.repositoryService = repositoryService;
1650
+ this.helpersService = helpersService;
1651
+ this.productsByTerm = {};
1607
1652
  }
1608
- async findCatalogAndSortByMostRevelantByTerm(productIds, options, limits) {
1609
- const brandsList = this.brandsList[this.buildIndexBrands(options)];
1610
- const totalResult = await this.productRepository.findCatalog({
1653
+ async search(params, shop, _optionsCache) {
1654
+ const { term, filters, limits, sort, mainGender } = params;
1655
+ if (!term) {
1656
+ throw new Error('Term is required for TermSearchStrategy');
1657
+ }
1658
+ const productIds = await this.findCatalogIdsBySearch(term, shop);
1659
+ if (sort === 'most-relevant') {
1660
+ return this.searchWithMostRelevant({
1661
+ productIds,
1662
+ filters,
1663
+ limits,
1664
+ shop,
1665
+ mainGender,
1666
+ });
1667
+ }
1668
+ return this.searchDefault({
1669
+ productIds,
1670
+ filters,
1671
+ limits,
1672
+ shop,
1673
+ mainGender,
1674
+ fields: this.helpersService.getFieldsHelper().getStandardFields(),
1675
+ });
1676
+ }
1677
+ async searchWithMostRelevant(params) {
1678
+ const { productIds, filters, shop, mainGender } = params;
1679
+ const productCatalog = this.repositoryService.getProductCatalog();
1680
+ const filterHelper = this.helpersService.getFilterHelper();
1681
+ const totalResult = await productCatalog.productRepository.findCatalog({
1611
1682
  fields: ['id', 'stock', 'gender'],
1612
1683
  filters: {
1613
1684
  id: { operator: Where.IN, value: productIds },
1614
1685
  published: { operator: Where.EQUALS, value: true },
1615
- ...this.buildFilterQuery(options?.filters || {}),
1686
+ ...filterHelper.buildFilterQuery(filters || {}),
1687
+ },
1688
+ options: {
1689
+ minimal: ['price'],
1690
+ maximum: ['price'],
1691
+ ...(isEmpty(filters?.brands) ? { distinct: ['brand'] } : {}),
1692
+ },
1693
+ }, mainGender || (shop === Shops.MENSMARKET ? 'male' : 'female'));
1694
+ return this.sortByTermRelevance({
1695
+ productIds,
1696
+ totalResult,
1697
+ limits: params.limits,
1698
+ filters,
1699
+ fieldsHelper: this.helpersService.getFieldsHelper(),
1700
+ });
1701
+ }
1702
+ async searchDefault(params) {
1703
+ const { productIds, filters, limits, shop, mainGender, fields } = params;
1704
+ const productCatalog = this.repositoryService.getProductCatalog();
1705
+ const filterHelper = this.helpersService.getFilterHelper();
1706
+ return productCatalog.productRepository.findCatalog({
1707
+ fields,
1708
+ filters: {
1709
+ id: { operator: Where.IN, value: productIds },
1710
+ published: { operator: Where.EQUALS, value: true },
1711
+ ...filterHelper.buildFilterQuery(filters || {}),
1616
1712
  },
1713
+ limits,
1617
1714
  options: {
1618
1715
  minimal: ['price'],
1619
1716
  maximum: ['price'],
1620
- ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
1621
- },
1622
- }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
1623
- const defaultGender = options?.filters?.gender
1624
- ? options?.filters?.gender.at(0)
1625
- : this.shop === Shops.GLAMSHOP
1626
- ? 'female'
1627
- : 'male';
1717
+ distinct: ['brand'],
1718
+ },
1719
+ }, mainGender || (shop === Shops.MENSMARKET ? 'male' : 'female'));
1720
+ }
1721
+ sortByTermRelevance(params) {
1722
+ const { productIds, totalResult, limits, filters, fieldsHelper } = params;
1723
+ const defaultGender = filters?.gender?.at(0) || 'male';
1628
1724
  const stockData = totalResult.data.filter((product) => product.stock.quantity > 0);
1629
1725
  const stockOut = totalResult.data.filter((product) => product.stock.quantity <= 0);
1630
1726
  const productIdsStockGender = productIds.filter((product) => stockData.some((result) => result.id === product && (result.gender?.includes(defaultGender) || result.gender?.includes('unisex'))));
@@ -1635,127 +1731,531 @@ class CatalogService {
1635
1731
  .concat(productIdsStockOut)
1636
1732
  .slice(limits.offset, limits.offset + limits.limit);
1637
1733
  const orderedId = productIds.filter((product) => limitedProductId.includes(product));
1638
- const productResult = await this.productRepository.findCatalog({
1734
+ return this.getDetailedProducts(orderedId, totalResult, fieldsHelper);
1735
+ }
1736
+ async getDetailedProducts(orderedId, totalResult, fieldsHelper) {
1737
+ const productCatalog = this.repositoryService.getProductCatalog();
1738
+ const fields = fieldsHelper.getStandardFields();
1739
+ const productResult = await productCatalog.productRepository.findCatalog({
1639
1740
  filters: {
1640
1741
  id: { operator: Where.IN, value: orderedId },
1641
1742
  },
1642
- fields: this.fields,
1743
+ fields,
1643
1744
  });
1644
- await this.setBrandsList(options, totalResult.distinct?.brand);
1645
1745
  return {
1646
- data: limitedProductId.map((id) => productResult.data.find((product) => product.id === id)).filter(Boolean),
1746
+ data: orderedId.map((id) => productResult.data.find((product) => product.id === id)).filter(Boolean),
1647
1747
  count: totalResult.count,
1648
1748
  maximum: totalResult.maximum,
1649
1749
  minimal: totalResult.minimal,
1650
- distinct: {
1651
- ...totalResult.distinct,
1652
- brand: this.brandsList[this.buildIndexBrands(options)],
1653
- },
1750
+ distinct: totalResult.distinct,
1654
1751
  };
1655
1752
  }
1656
- async findCatalogIdsBySearch(term, preview = false) {
1657
- if (this.productsByTerm[term])
1658
- return this.productsByTerm[term];
1659
- return (this.productsByTerm[term] = await this.productSearch
1660
- .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
1661
- .then((products) => [...new Set(products.map((product) => product.id))]));
1753
+ async findCatalogIdsBySearch(term, shop) {
1754
+ if (this.productsByTerm[term])
1755
+ return this.productsByTerm[term];
1756
+ const productServices = this.repositoryService.getProductServices();
1757
+ return (this.productsByTerm[term] = await productServices.productSearch
1758
+ .search(term, 999, shop === Shops.GLAMSHOP ? 'female' : 'male')
1759
+ .then((products) => [...new Set(products.map((product) => product.id))]));
1760
+ }
1761
+ }
1762
+ TermSearchStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: TermSearchStrategy, deps: [{ token: CatalogRepositoryService }, { token: CatalogHelpersService }], target: i0.ɵɵFactoryTarget.Injectable });
1763
+ TermSearchStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: TermSearchStrategy });
1764
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: TermSearchStrategy, decorators: [{
1765
+ type: Injectable
1766
+ }], ctorParameters: function () { return [{ type: CatalogRepositoryService }, { type: CatalogHelpersService }]; } });
1767
+
1768
+ class CatalogStrategiesFacade {
1769
+ constructor(categoryStrategy, termStrategy, profileStrategy) {
1770
+ this.categoryStrategy = categoryStrategy;
1771
+ this.termStrategy = termStrategy;
1772
+ this.profileStrategy = profileStrategy;
1773
+ }
1774
+ }
1775
+ CatalogStrategiesFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogStrategiesFacade, deps: [{ token: CategorySearchStrategy }, { token: TermSearchStrategy }, { token: ProfileSearchStrategy }], target: i0.ɵɵFactoryTarget.Injectable });
1776
+ CatalogStrategiesFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogStrategiesFacade });
1777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogStrategiesFacade, decorators: [{
1778
+ type: Injectable
1779
+ }], ctorParameters: function () { return [{ type: CategorySearchStrategy }, { type: TermSearchStrategy }, { type: ProfileSearchStrategy }]; } });
1780
+
1781
+ class CatalogServiceFacade {
1782
+ constructor(helpersService, strategiesFacade, shop) {
1783
+ this.helpersService = helpersService;
1784
+ this.strategiesFacade = strategiesFacade;
1785
+ this.shop = shop;
1786
+ const searchContext = new CatalogSearchContext(this.strategiesFacade.categoryStrategy, this.strategiesFacade.termStrategy, this.strategiesFacade.profileStrategy);
1787
+ this.catalogService = new CatalogService(searchContext, this.helpersService, this.shop);
1788
+ }
1789
+ getCatalogService() {
1790
+ return this.catalogService;
1791
+ }
1792
+ }
1793
+ CatalogServiceFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogServiceFacade, deps: [{ token: CatalogHelpersService }, { token: CatalogStrategiesFacade }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable });
1794
+ CatalogServiceFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogServiceFacade });
1795
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogServiceFacade, decorators: [{
1796
+ type: Injectable
1797
+ }], ctorParameters: function () { return [{ type: CatalogHelpersService }, { type: CatalogStrategiesFacade }, { type: i3.Shops, decorators: [{
1798
+ type: Inject,
1799
+ args: [DEFAULT_SHOP]
1800
+ }] }]; } });
1801
+
1802
+ class CategoryRepositoryFacade {
1803
+ constructor(categoryRepository, categoryFilterRepository) {
1804
+ this.categoryRepository = categoryRepository;
1805
+ this.categoryFilterRepository = categoryFilterRepository;
1806
+ }
1807
+ }
1808
+ CategoryRepositoryFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryRepositoryFacade, deps: [{ token: 'CategoryRepository' }, { token: 'CategoryFilterRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
1809
+ CategoryRepositoryFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryRepositoryFacade });
1810
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryRepositoryFacade, decorators: [{
1811
+ type: Injectable
1812
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1813
+ type: Inject,
1814
+ args: ['CategoryRepository']
1815
+ }] }, { type: undefined, decorators: [{
1816
+ type: Inject,
1817
+ args: ['CategoryFilterRepository']
1818
+ }] }]; } });
1819
+
1820
+ class CategoryService {
1821
+ constructor(categoryFacade, productCatalog, shop) {
1822
+ this.categoryFacade = categoryFacade;
1823
+ this.productCatalog = productCatalog;
1824
+ this.shop = shop;
1825
+ }
1826
+ async fetchBrands(category, options, optionsCache) {
1827
+ const brands = await this.productCatalog.productRepository
1828
+ .findCatalog({
1829
+ filters: await this.productCatalog.categoryStructureAdapter.buildProductFilterByCategory(category),
1830
+ fields: ['brand'],
1831
+ }, options?.mainGender ? options?.mainGender : this.shop === Shops.MENSMARKET ? 'male' : 'female', optionsCache)
1832
+ .then(({ data }) => Object.keys(data.map((product) => product.brand).reduce((brands, brand) => ({ ...brands, [brand]: true }), {})));
1833
+ return this.categoryFacade.categoryRepository
1834
+ .find({ filters: { brandCategory: true, shop: options?.shop || this.shop }, orderBy: { name: 'asc' } }, optionsCache)
1835
+ .then(({ data }) => data.filter((category) => brands.includes(category.conditions.brand)));
1836
+ }
1837
+ async fetchFilterOptions(category, optionsCache) {
1838
+ return await this.categoryFacade.categoryFilterRepository
1839
+ .find({ filters: { categoryId: +category.id } }, optionsCache)
1840
+ .then(({ data }) => data.map((categoryFilter) => categoryFilter.filter));
1841
+ }
1842
+ }
1843
+ CategoryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryService, deps: [{ token: CategoryRepositoryFacade }, { token: ProductCatalogFacade }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable });
1844
+ CategoryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryService });
1845
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryService, decorators: [{
1846
+ type: Injectable
1847
+ }], ctorParameters: function () { return [{ type: CategoryRepositoryFacade }, { type: ProductCatalogFacade }, { type: i3.Shops, decorators: [{
1848
+ type: Inject,
1849
+ args: [DEFAULT_SHOP]
1850
+ }] }]; } });
1851
+
1852
+ class ProductCatalogFacade {
1853
+ constructor(productRepository, categoryStructureAdapter) {
1854
+ this.productRepository = productRepository;
1855
+ this.categoryStructureAdapter = categoryStructureAdapter;
1856
+ }
1857
+ }
1858
+ ProductCatalogFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductCatalogFacade, deps: [{ token: 'ProductRepository' }, { token: CATEGORY_STRUCTURE }], target: i0.ɵɵFactoryTarget.Injectable });
1859
+ ProductCatalogFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductCatalogFacade });
1860
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductCatalogFacade, decorators: [{
1861
+ type: Injectable
1862
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1863
+ type: Inject,
1864
+ args: ['ProductRepository']
1865
+ }] }, { type: undefined, decorators: [{
1866
+ type: Inject,
1867
+ args: [CATEGORY_STRUCTURE]
1868
+ }] }]; } });
1869
+
1870
+ class CategoryServiceFacade {
1871
+ constructor(categoryRepositoryFacade, productCatalogFacade, shop) {
1872
+ this.categoryRepositoryFacade = categoryRepositoryFacade;
1873
+ this.productCatalogFacade = productCatalogFacade;
1874
+ this.shop = shop;
1875
+ this.categoryService = new CategoryService(this.categoryRepositoryFacade, this.productCatalogFacade, this.shop);
1876
+ }
1877
+ getCategoryService() {
1878
+ return this.categoryService;
1879
+ }
1880
+ }
1881
+ CategoryServiceFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryServiceFacade, deps: [{ token: CategoryRepositoryFacade }, { token: ProductCatalogFacade }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable });
1882
+ CategoryServiceFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryServiceFacade });
1883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryServiceFacade, decorators: [{
1884
+ type: Injectable
1885
+ }], ctorParameters: function () { return [{ type: CategoryRepositoryFacade }, { type: ProductCatalogFacade }, { type: i3.Shops, decorators: [{
1886
+ type: Inject,
1887
+ args: [DEFAULT_SHOP]
1888
+ }] }]; } });
1889
+
1890
+ class BrandManagerHelper {
1891
+ constructor(productCatalog) {
1892
+ this.productCatalog = productCatalog;
1893
+ this.brandsList = {};
1894
+ }
1895
+ async setBrandsList(options, brands) {
1896
+ const filterBrands = options.filters?.brands;
1897
+ const indexKey = this.buildIndexBrands(options);
1898
+ if (isEmpty(brands) && options.filters) {
1899
+ delete options.filters.brands;
1900
+ }
1901
+ this.brandsList[indexKey] = this.brandsList[indexKey] || brands || (await this.fetchBrandsOnly(options));
1902
+ this.brandsList[indexKey] = this.brandsList[indexKey].filter(Boolean);
1903
+ if (options.filters) {
1904
+ options.filters = {
1905
+ ...options.filters,
1906
+ brands: filterBrands,
1907
+ };
1908
+ }
1909
+ }
1910
+ getBrandsList(indexKey) {
1911
+ return this.brandsList[indexKey];
1912
+ }
1913
+ buildIndexBrands(options) {
1914
+ if (options.category)
1915
+ return `category-${options.category.id}`;
1916
+ if (options.term)
1917
+ return `term-${options.term}`;
1918
+ if (options.profile)
1919
+ return `profile-${options.profile.join(',')}`;
1920
+ return '';
1921
+ }
1922
+ async fetchBrandsOnly(options) {
1923
+ return this.productCatalog.productRepository
1924
+ .findCatalog({
1925
+ fields: ['id'],
1926
+ filters: {
1927
+ published: { operator: Where.EQUALS, value: true },
1928
+ },
1929
+ options: {
1930
+ distinct: ['brand'],
1931
+ },
1932
+ }, options.mainGender)
1933
+ .then((result) => result.distinct.brand);
1934
+ }
1935
+ }
1936
+ BrandManagerHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: BrandManagerHelper, deps: [{ token: ProductCatalogFacade }], target: i0.ɵɵFactoryTarget.Injectable });
1937
+ BrandManagerHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: BrandManagerHelper });
1938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: BrandManagerHelper, decorators: [{
1939
+ type: Injectable
1940
+ }], ctorParameters: function () { return [{ type: ProductCatalogFacade }]; } });
1941
+
1942
+ class CatalogFilterHelper {
1943
+ buildFilterQuery(filters) {
1944
+ const filterQuery = {};
1945
+ if (filters.clubDiscount?.length) {
1946
+ set(filterQuery, 'price.subscriberDiscountPercentage', {
1947
+ operator: Where.IN,
1948
+ value: filters.clubDiscount,
1949
+ });
1950
+ }
1951
+ if (filters.brands?.length) {
1952
+ filterQuery.brand = { operator: Where.IN, value: filters.brands };
1953
+ }
1954
+ if (filters.gender?.length) {
1955
+ filterQuery.gender = { operator: Where.IN, value: filters.gender };
1956
+ }
1957
+ if (filters.prices?.min || filters.prices?.max) {
1958
+ const priceField = filters.prices.subscriberPrice ? 'price.subscriberPrice' : 'price.price';
1959
+ const priceFilters = [
1960
+ ...(filters.prices.min ? [{ operator: Where.GTE, value: Math.floor(filters.prices.min) }] : []),
1961
+ ...(filters.prices.max ? [{ operator: Where.LTE, value: Math.ceil(filters.prices.max) }] : []),
1962
+ ];
1963
+ set(filterQuery, priceField, priceFilters);
1964
+ }
1965
+ if (filters.rate) {
1966
+ filterQuery.rate = { operator: Where.GTE, value: filters.rate };
1967
+ }
1968
+ if (filters.tags?.length) {
1969
+ filterQuery.tags = { operator: Where.LIKE, value: filters.tags };
1970
+ }
1971
+ if (filters.customOptions?.length) {
1972
+ filterQuery.filters = { operator: Where.LIKE, value: filters.customOptions };
1973
+ }
1974
+ return filterQuery;
1975
+ }
1976
+ }
1977
+ CatalogFilterHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogFilterHelper, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1978
+ CatalogFilterHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogFilterHelper });
1979
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogFilterHelper, decorators: [{
1980
+ type: Injectable
1981
+ }] });
1982
+
1983
+ class CatalogSortHelper {
1984
+ buildSortQuery(sort) {
1985
+ if (!sort || sort === 'most-relevant')
1986
+ return {};
1987
+ switch (sort) {
1988
+ case 'best-sellers':
1989
+ return {
1990
+ shoppingCount: 'desc',
1991
+ rate: 'desc',
1992
+ stock: 'desc',
1993
+ name: 'asc',
1994
+ };
1995
+ case 'biggest-price':
1996
+ return {
1997
+ subscriberPrice: 'desc',
1998
+ rate: 'desc',
1999
+ shoppingCount: 'desc',
2000
+ };
2001
+ case 'lowest-price':
2002
+ return {
2003
+ subscriberPrice: 'asc',
2004
+ rate: 'desc',
2005
+ shoppingCount: 'desc',
2006
+ };
2007
+ case 'best-rating':
2008
+ return {
2009
+ rate: 'desc',
2010
+ shoppingCount: 'desc',
2011
+ stock: 'desc',
2012
+ name: 'asc',
2013
+ };
2014
+ case 'news':
2015
+ return { createdAt: 'desc' };
2016
+ case 'biggest-discount':
2017
+ return {
2018
+ subscriberDiscountPercentage: 'desc',
2019
+ rate: 'desc',
2020
+ shoppingCount: 'desc',
2021
+ };
2022
+ default:
2023
+ return {};
2024
+ }
2025
+ }
2026
+ }
2027
+ CatalogSortHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogSortHelper, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2028
+ CatalogSortHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogSortHelper });
2029
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogSortHelper, decorators: [{
2030
+ type: Injectable
2031
+ }] });
2032
+
2033
+ class ProductFieldsHelper {
2034
+ getStandardFields() {
2035
+ return [
2036
+ 'id',
2037
+ 'name',
2038
+ 'slug',
2039
+ 'images',
2040
+ 'miniatures',
2041
+ 'price',
2042
+ 'stock',
2043
+ 'published',
2044
+ 'CEST',
2045
+ 'EAN',
2046
+ 'NCM',
2047
+ 'brand',
2048
+ 'costPrice',
2049
+ 'hasVariants',
2050
+ 'isKit',
2051
+ 'sku',
2052
+ 'rate',
2053
+ 'tags',
2054
+ 'type',
2055
+ 'shoppingCount',
2056
+ 'gender',
2057
+ 'createdAt',
2058
+ 'label',
2059
+ 'outlet',
2060
+ 'group',
2061
+ ];
2062
+ }
2063
+ }
2064
+ ProductFieldsHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductFieldsHelper, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2065
+ ProductFieldsHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductFieldsHelper });
2066
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductFieldsHelper, decorators: [{
2067
+ type: Injectable
2068
+ }] });
2069
+
2070
+ class CatalogOperationsFacade {
2071
+ constructor(filterHelper, sortHelper, fieldsHelper) {
2072
+ this.filterHelper = filterHelper;
2073
+ this.sortHelper = sortHelper;
2074
+ this.fieldsHelper = fieldsHelper;
1662
2075
  }
1663
- async fetchBrandsOnly(options, productIds = []) {
1664
- return this.productRepository
1665
- .findCatalog({
1666
- fields: ['id'],
1667
- filters: {
1668
- ...(!isEmpty(productIds) ? { id: { operator: Where.IN, value: productIds } } : {}),
1669
- published: { operator: Where.EQUALS, value: true },
1670
- ...this.buildFilterQuery(options?.filters || {}),
1671
- },
1672
- options: {
1673
- distinct: ['brand'],
1674
- },
1675
- }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female')
1676
- .then((result) => {
1677
- return result.distinct.brand;
1678
- });
2076
+ getFilterHelper() {
2077
+ return this.filterHelper;
1679
2078
  }
1680
- async setBrandsList(options, brands) {
1681
- const filterBrands = options.filters?.brands;
1682
- if (isEmpty(brands))
1683
- delete options.filters?.brands;
1684
- this.brandsList[this.buildIndexBrands(options)] =
1685
- this.brandsList[this.buildIndexBrands(options)] || brands || (await this.fetchBrandsOnly(options));
1686
- this.brandsList[this.buildIndexBrands(options)] = this.brandsList[this.buildIndexBrands(options)].filter(Boolean);
1687
- options.filters = {
1688
- ...options.filters,
1689
- brands: filterBrands,
1690
- };
2079
+ getSortHelper() {
2080
+ return this.sortHelper;
2081
+ }
2082
+ getFieldsHelper() {
2083
+ return this.fieldsHelper;
1691
2084
  }
1692
2085
  }
1693
- CatalogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, deps: [{ token: 'ProductRepository' }, { token: 'ProductStockNotificationRepository' }, { token: 'CategoryRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }, { token: 'ProductSearch' }], target: i0.ɵɵFactoryTarget.Injectable });
1694
- CatalogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService });
1695
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, decorators: [{
2086
+ CatalogOperationsFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogOperationsFacade, deps: [{ token: CatalogFilterHelper }, { token: CatalogSortHelper }, { token: ProductFieldsHelper }], target: i0.ɵɵFactoryTarget.Injectable });
2087
+ CatalogOperationsFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogOperationsFacade });
2088
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogOperationsFacade, decorators: [{
1696
2089
  type: Injectable
1697
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1698
- type: Inject,
1699
- args: ['ProductRepository']
1700
- }] }, { type: undefined, decorators: [{
1701
- type: Inject,
1702
- args: ['ProductStockNotificationRepository']
1703
- }] }, { type: undefined, decorators: [{
1704
- type: Inject,
1705
- args: ['CategoryRepository']
1706
- }] }, { type: undefined, decorators: [{
1707
- type: Inject,
1708
- args: [CATEGORY_STRUCTURE]
1709
- }] }, { type: i1$3.Shops, decorators: [{
2090
+ }], ctorParameters: function () { return [{ type: CatalogFilterHelper }, { type: CatalogSortHelper }, { type: ProductFieldsHelper }]; } });
2091
+
2092
+ class ProductManagementFacade {
2093
+ constructor(brandManager, productServices) {
2094
+ this.brandManager = brandManager;
2095
+ this.productServices = productServices;
2096
+ }
2097
+ getBrandManager() {
2098
+ return this.brandManager;
2099
+ }
2100
+ getProductServices() {
2101
+ return this.productServices;
2102
+ }
2103
+ }
2104
+ ProductManagementFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductManagementFacade, deps: [{ token: BrandManagerHelper }, { token: 'ProductServicesFacade' }], target: i0.ɵɵFactoryTarget.Injectable });
2105
+ ProductManagementFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductManagementFacade });
2106
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: ProductManagementFacade, decorators: [{
2107
+ type: Injectable
2108
+ }], ctorParameters: function () { return [{ type: BrandManagerHelper }, { type: undefined, decorators: [{
1710
2109
  type: Inject,
1711
- args: [DEFAULT_SHOP]
1712
- }] }, { type: undefined, decorators: [{
2110
+ args: ['ProductServicesFacade']
2111
+ }] }]; } });
2112
+
2113
+ class CatalogHelpersService {
2114
+ constructor(catalogOperations, productManagement) {
2115
+ this.catalogOperations = catalogOperations;
2116
+ this.productManagement = productManagement;
2117
+ }
2118
+ getFilterHelper() {
2119
+ return this.catalogOperations.getFilterHelper();
2120
+ }
2121
+ getSortHelper() {
2122
+ return this.catalogOperations.getSortHelper();
2123
+ }
2124
+ getFieldsHelper() {
2125
+ return this.catalogOperations.getFieldsHelper();
2126
+ }
2127
+ getBrandManager() {
2128
+ return this.productManagement.getBrandManager();
2129
+ }
2130
+ getProductServices() {
2131
+ return this.productManagement.getProductServices();
2132
+ }
2133
+ }
2134
+ CatalogHelpersService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogHelpersService, deps: [{ token: CatalogOperationsFacade }, { token: ProductManagementFacade }], target: i0.ɵɵFactoryTarget.Injectable });
2135
+ CatalogHelpersService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogHelpersService });
2136
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogHelpersService, decorators: [{
2137
+ type: Injectable
2138
+ }], ctorParameters: function () { return [{ type: CatalogOperationsFacade }, { type: ProductManagementFacade }]; } });
2139
+
2140
+ class CatalogRepositoryService {
2141
+ constructor(productCatalog, productServices) {
2142
+ this.productCatalog = productCatalog;
2143
+ this.productServices = productServices;
2144
+ }
2145
+ getProductCatalog() {
2146
+ return this.productCatalog;
2147
+ }
2148
+ getProductServices() {
2149
+ return this.productServices;
2150
+ }
2151
+ }
2152
+ CatalogRepositoryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogRepositoryService, deps: [{ token: ProductCatalogFacade }, { token: 'ProductServicesFacade' }], target: i0.ɵɵFactoryTarget.Injectable });
2153
+ CatalogRepositoryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogRepositoryService });
2154
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogRepositoryService, decorators: [{
2155
+ type: Injectable
2156
+ }], ctorParameters: function () { return [{ type: ProductCatalogFacade }, { type: undefined, decorators: [{
1713
2157
  type: Inject,
1714
- args: ['ProductSearch']
2158
+ args: ['ProductServicesFacade']
1715
2159
  }] }]; } });
1716
2160
 
1717
- class CategoryService {
1718
- constructor(productRepository, categoryRepository, categoryFilterRepository, categoryStructureAdapter, shop) {
1719
- this.productRepository = productRepository;
1720
- this.categoryRepository = categoryRepository;
1721
- this.categoryFilterRepository = categoryFilterRepository;
1722
- this.categoryStructureAdapter = categoryStructureAdapter;
2161
+ class CatalogService {
2162
+ constructor(searchContext, helpersService, shop) {
2163
+ this.searchContext = searchContext;
2164
+ this.helpersService = helpersService;
1723
2165
  this.shop = shop;
1724
2166
  }
1725
- async fetchBrands(category, options, optionsCache) {
1726
- const brands = await this.productRepository
1727
- .findCatalog({
1728
- filters: await this.categoryStructureAdapter.buildProductFilterByCategory(category),
1729
- fields: ['brand'],
1730
- }, options?.mainGender ? options?.mainGender : this.shop === Shops.MENSMARKET ? 'male' : 'female', optionsCache)
1731
- .then(({ data }) => Object.keys(data.map((product) => product.brand).reduce((brands, brand) => ({ ...brands, [brand]: true }), {})));
1732
- return this.categoryRepository
1733
- .find({ filters: { brandCategory: true, shop: options?.shop || this.shop }, orderBy: { name: 'asc' } }, optionsCache)
1734
- .then(({ data }) => data.filter((category) => brands.includes(category.conditions.brand)));
2167
+ async fetchProducts(options, optionsCache) {
2168
+ this.validateRequest(options);
2169
+ const searchParams = this.buildSearchParams(options);
2170
+ const { data, count: total, maximum, minimal, distinct, } = await this.searchContext.executeSearch(searchParams, this.shop, optionsCache);
2171
+ await this.helpersService.getBrandManager().setBrandsList(searchParams, distinct?.brand);
2172
+ return this.buildResponse({
2173
+ data,
2174
+ total,
2175
+ maximum,
2176
+ minimal,
2177
+ searchParams,
2178
+ options,
2179
+ });
1735
2180
  }
1736
- async fetchFilterOptions(category, optionsCache) {
1737
- return await this.categoryFilterRepository
1738
- .find({ filters: { categoryId: +category.id } }, optionsCache)
1739
- .then(({ data }) => data.map((categoryFilter) => categoryFilter.filter));
2181
+ async addCustomerToStockNotification(params) {
2182
+ const { shop, productId, name, email } = params;
2183
+ const productServices = this.helpersService.getProductServices();
2184
+ return productServices.productStockNotificationRepository.addCustomerEmail({
2185
+ shop,
2186
+ productId,
2187
+ name,
2188
+ email,
2189
+ });
2190
+ }
2191
+ validateRequest(options) {
2192
+ if (this.hasProfile(options) && options.filters?.customOptions) {
2193
+ throw new InvalidArgumentError(`It couldn't filled customOptions when profile is given`);
2194
+ }
2195
+ if (this.hasProfile(options) && options.filters?.tags) {
2196
+ throw new InvalidArgumentError(`It couldn't filled tags when profile is given`);
2197
+ }
2198
+ if (this.hasTerm(options) && options.filters?.customOptions) {
2199
+ throw new InvalidArgumentError(`It couldn't filled customOptions when term is given`);
2200
+ }
2201
+ }
2202
+ buildSearchParams(options) {
2203
+ const limits = this.buildLimitQuery(options);
2204
+ return {
2205
+ category: this.hasCategory(options) ? options.category : undefined,
2206
+ profile: this.hasProfile(options) ? options.profile : undefined,
2207
+ term: this.hasTerm(options) ? options.term : undefined,
2208
+ filters: options.filters,
2209
+ mainGender: options.mainGender,
2210
+ sort: options.sort,
2211
+ limits,
2212
+ };
2213
+ }
2214
+ buildResponse(params) {
2215
+ const { data, total, maximum, minimal, searchParams } = params;
2216
+ const limits = searchParams.limits;
2217
+ const indexKey = this.helpersService.getBrandManager().buildIndexBrands(searchParams);
2218
+ return {
2219
+ products: {
2220
+ data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)),
2221
+ total,
2222
+ },
2223
+ pages: Math.ceil(total / limits.limit),
2224
+ prices: {
2225
+ price: {
2226
+ min: +(minimal?.price?.price?.toFixed(2) || 0),
2227
+ max: +(maximum?.price?.price?.toFixed(2) || 0),
2228
+ },
2229
+ subscriberPrice: {
2230
+ min: +(minimal?.price?.subscriberPrice?.toFixed(2) || 0),
2231
+ max: +(maximum?.price?.subscriberPrice?.toFixed(2) || 0),
2232
+ },
2233
+ },
2234
+ brands: this.helpersService.getBrandManager().getBrandsList(indexKey),
2235
+ };
2236
+ }
2237
+ buildLimitQuery(options) {
2238
+ const limit = options?.perPage || 20;
2239
+ return {
2240
+ limit,
2241
+ offset: ((options?.page || 1) - 1) * limit,
2242
+ };
2243
+ }
2244
+ hasProfile(options) {
2245
+ return 'profile' in options;
2246
+ }
2247
+ hasTerm(options) {
2248
+ return 'term' in options;
2249
+ }
2250
+ hasCategory(options) {
2251
+ return 'category' in options;
1740
2252
  }
1741
2253
  }
1742
- CategoryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryService, deps: [{ token: 'ProductRepository' }, { token: 'CategoryRepository' }, { token: 'CategoryFilterRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable });
1743
- CategoryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryService });
1744
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CategoryService, decorators: [{
2254
+ CatalogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, deps: [{ token: CatalogSearchContext }, { token: CatalogHelpersService }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable });
2255
+ CatalogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService });
2256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CatalogService, decorators: [{
1745
2257
  type: Injectable
1746
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1747
- type: Inject,
1748
- args: ['ProductRepository']
1749
- }] }, { type: undefined, decorators: [{
1750
- type: Inject,
1751
- args: ['CategoryRepository']
1752
- }] }, { type: undefined, decorators: [{
1753
- type: Inject,
1754
- args: ['CategoryFilterRepository']
1755
- }] }, { type: undefined, decorators: [{
1756
- type: Inject,
1757
- args: [CATEGORY_STRUCTURE]
1758
- }] }, { type: i1$3.Shops, decorators: [{
2258
+ }], ctorParameters: function () { return [{ type: CatalogSearchContext }, { type: CatalogHelpersService }, { type: i3.Shops, decorators: [{
1759
2259
  type: Inject,
1760
2260
  args: [DEFAULT_SHOP]
1761
2261
  }] }]; } });
@@ -1779,15 +2279,14 @@ __decorate([
1779
2279
  ], CategoryWithTree.prototype, "children", void 0);
1780
2280
 
1781
2281
  class WishlistService {
1782
- constructor(wishlistRepository, shop, productRepository, categoryFilterRepository, categoryRepository, productStockNotificationRepository, productSearch, logRepository) {
2282
+ constructor(wishlistRepository, shop, logRepository) {
1783
2283
  this.wishlistRepository = wishlistRepository;
1784
2284
  this.shop = shop;
1785
- this.productRepository = productRepository;
1786
- this.productSearch = productSearch;
1787
2285
  this.logRepository = logRepository;
1788
- const categoryStructureAdapter = new NewCategoryStructureAdapter(wishlistRepository);
1789
- this.catalogService = new CatalogService(productRepository, productStockNotificationRepository, categoryRepository, categoryStructureAdapter, shop, productSearch);
1790
- this.categoryService = new CategoryService(productRepository, categoryRepository, categoryFilterRepository, categoryStructureAdapter, shop);
2286
+ }
2287
+ initializeServices(catalogServiceFacade, categoryServiceFacade) {
2288
+ this.catalogService = catalogServiceFacade.getCatalogService();
2289
+ this.categoryService = categoryServiceFacade.getCategoryService();
1791
2290
  }
1792
2291
  getCatalogService() {
1793
2292
  return this.catalogService;
@@ -1796,7 +2295,26 @@ class WishlistService {
1796
2295
  return this.categoryService;
1797
2296
  }
1798
2297
  async create({ personId, title, description, published, userFullName, userPhoto, theme, bannerUrl, personType, personIsSubscriber, }) {
1799
- const data = {
2298
+ const wishlistData = this.buildWishlistData({
2299
+ title,
2300
+ description,
2301
+ published,
2302
+ userFullName,
2303
+ userPhoto,
2304
+ theme,
2305
+ bannerUrl,
2306
+ personType,
2307
+ personIsSubscriber,
2308
+ personId,
2309
+ });
2310
+ const existingWishlist = await this.findExistingWishlistByPersonId(personId);
2311
+ await this.createWishlistLog(WishlistLogType.CREATE, wishlistData);
2312
+ if (existingWishlist)
2313
+ return existingWishlist;
2314
+ return this.createNewWishlist(wishlistData);
2315
+ }
2316
+ buildWishlistData({ title, description, published, userFullName, userPhoto, theme, bannerUrl, personType, personIsSubscriber, personId, }) {
2317
+ return {
1800
2318
  slug: '',
1801
2319
  name: title,
1802
2320
  description,
@@ -1819,6 +2337,8 @@ class WishlistService {
1819
2337
  personType: personType ?? PersonTypes.NONE,
1820
2338
  personIsSubscriber: personIsSubscriber ?? false,
1821
2339
  };
2340
+ }
2341
+ async findExistingWishlistByPersonId(personId) {
1822
2342
  const hasWishlist = await this.wishlistRepository
1823
2343
  .find({
1824
2344
  filters: {
@@ -1832,9 +2352,9 @@ class WishlistService {
1832
2352
  },
1833
2353
  })
1834
2354
  .then((res) => res.data);
1835
- await this.createWishlistLog(WishlistLogType.CREATE, data);
1836
- if (hasWishlist.length)
1837
- return hasWishlist.at(0);
2355
+ return hasWishlist.length ? hasWishlist.at(0) : null;
2356
+ }
2357
+ async createNewWishlist(data) {
1838
2358
  const newWishlist = await this.wishlistRepository.create(data);
1839
2359
  await this.wishlistRepository.update({ id: newWishlist.id, slug: newWishlist.id });
1840
2360
  return Wishlist.toInstance({ ...newWishlist.toPlain(), slug: newWishlist.id });
@@ -1911,7 +2431,12 @@ class WishlistService {
1911
2431
  .then((res) => res.data.at(0));
1912
2432
  }
1913
2433
  async findProductById(id) {
1914
- return this.productRepository
2434
+ if (!this.catalogService) {
2435
+ throw new Error('CatalogService not initialized. Call initializeServices first.');
2436
+ }
2437
+ const helpersService = this.catalogService['helpersService'];
2438
+ const productServices = helpersService.getProductServices();
2439
+ return productServices.productRepository
1915
2440
  .find({
1916
2441
  fields: ['id', 'sku', 'EAN', 'name', 'brand'],
1917
2442
  filters: {
@@ -1925,103 +2450,122 @@ class WishlistService {
1925
2450
  case WishlistLogType.CREATE:
1926
2451
  case WishlistLogType.UPDATE:
1927
2452
  case WishlistLogType.DELETE:
1928
- await this.logRepository.create({
1929
- collection: 'wishlist',
1930
- date: new Date(),
1931
- operation: WishlistLogType.CREATE ? 'CREATE' : WishlistLogType.UPDATE ? 'UPDATE' : 'DELETE',
1932
- documentId: wishlist.id,
1933
- document: {
1934
- id: wishlist.id,
1935
- shop: this.shop,
1936
- name: wishlist.name,
1937
- description: wishlist.description,
1938
- published: wishlist.published,
1939
- type: type,
1940
- personType: wishlist.personType,
1941
- personId: wishlist.personId,
1942
- personName: wishlist.personName,
1943
- personIsSubscriber: wishlist.personIsSubscriber,
1944
- },
1945
- });
2453
+ await this.createWishlistOperationLog(type, wishlist);
1946
2454
  break;
1947
2455
  case WishlistLogType.ADD_PRODUCT:
1948
2456
  case WishlistLogType.REMOVE_PRODUCT:
1949
- await this.logRepository.create({
1950
- collection: 'wishlist',
1951
- date: new Date(),
1952
- operation: 'UPDATE',
1953
- documentId: wishlist.id,
1954
- document: {
1955
- id: wishlist.id,
1956
- shop: this.shop,
1957
- name: wishlist.name,
1958
- description: wishlist.description,
1959
- published: wishlist.published,
1960
- type: type,
1961
- personType: wishlist.personType,
1962
- personId: wishlist.personId,
1963
- personName: wishlist.personName,
1964
- personIsSubscriber: wishlist.personIsSubscriber,
1965
- productId: product.id,
1966
- productEAN: product.EAN,
1967
- productSKU: product.sku,
1968
- productName: product.name,
1969
- productBrand: product.brand,
1970
- },
1971
- });
2457
+ await this.createWishlistProductLog(type, wishlist, product);
1972
2458
  break;
1973
2459
  default:
1974
2460
  break;
1975
2461
  }
1976
2462
  }
2463
+ async createWishlistOperationLog(type, wishlist) {
2464
+ const operation = this.getOperationTypeFromWishlistLogType(type);
2465
+ await this.logRepository.create({
2466
+ collection: 'wishlist',
2467
+ date: new Date(),
2468
+ operation,
2469
+ documentId: wishlist.id,
2470
+ document: this.buildWishlistLogDocument(wishlist, type),
2471
+ });
2472
+ }
2473
+ async createWishlistProductLog(type, wishlist, product) {
2474
+ await this.logRepository.create({
2475
+ collection: 'wishlist',
2476
+ date: new Date(),
2477
+ operation: 'UPDATE',
2478
+ documentId: wishlist.id,
2479
+ document: {
2480
+ ...this.buildWishlistLogDocument(wishlist, type),
2481
+ ...this.buildProductLogData(product),
2482
+ },
2483
+ });
2484
+ }
2485
+ getOperationTypeFromWishlistLogType(type) {
2486
+ if (type === WishlistLogType.CREATE)
2487
+ return 'CREATE';
2488
+ if (type === WishlistLogType.UPDATE)
2489
+ return 'UPDATE';
2490
+ return 'DELETE';
2491
+ }
2492
+ buildWishlistLogDocument(wishlist, type) {
2493
+ return {
2494
+ id: wishlist.id,
2495
+ shop: this.shop,
2496
+ name: wishlist.name,
2497
+ description: wishlist.description,
2498
+ published: wishlist.published,
2499
+ type: type,
2500
+ personType: wishlist.personType,
2501
+ personId: wishlist.personId,
2502
+ personName: wishlist.personName,
2503
+ personIsSubscriber: wishlist.personIsSubscriber,
2504
+ };
2505
+ }
2506
+ buildProductLogData(product) {
2507
+ return {
2508
+ productId: product.id,
2509
+ productEAN: product.EAN,
2510
+ productSKU: product.sku,
2511
+ productName: product.name,
2512
+ productBrand: product.brand,
2513
+ };
2514
+ }
1977
2515
  }
1978
- WishlistService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: WishlistService, deps: [{ token: 'WishlistRepository' }, { token: DEFAULT_SHOP }, { token: 'ProductRepository' }, { token: 'CategoryFilterRepository' }, { token: 'CategoryRepository' }, { token: 'ProductStockNotificationRepository' }, { token: 'ProductSearch' }, { token: 'LogRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
2516
+ WishlistService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: WishlistService, deps: [{ token: 'WishlistRepository' }, { token: DEFAULT_SHOP }, { token: 'LogRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
1979
2517
  WishlistService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: WishlistService });
1980
2518
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: WishlistService, decorators: [{
1981
2519
  type: Injectable
1982
2520
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1983
2521
  type: Inject,
1984
2522
  args: ['WishlistRepository']
1985
- }] }, { type: i1$3.Shops, decorators: [{
2523
+ }] }, { type: i3.Shops, decorators: [{
1986
2524
  type: Inject,
1987
2525
  args: [DEFAULT_SHOP]
1988
2526
  }] }, { type: undefined, decorators: [{
1989
2527
  type: Inject,
1990
- args: ['ProductRepository']
1991
- }] }, { type: undefined, decorators: [{
1992
- type: Inject,
1993
- args: ['CategoryFilterRepository']
1994
- }] }, { type: undefined, decorators: [{
1995
- type: Inject,
1996
- args: ['CategoryRepository']
1997
- }] }, { type: undefined, decorators: [{
2528
+ args: ['LogRepository']
2529
+ }] }]; } });
2530
+
2531
+ class CouponRepositoriesFacade {
2532
+ constructor(couponRepository, orderRepository, categoryRepository) {
2533
+ this.couponRepository = couponRepository;
2534
+ this.orderRepository = orderRepository;
2535
+ this.categoryRepository = categoryRepository;
2536
+ }
2537
+ }
2538
+ CouponRepositoriesFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CouponRepositoriesFacade, deps: [{ token: 'CouponRepository' }, { token: 'OrderRepository' }, { token: 'CategoryRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
2539
+ CouponRepositoriesFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CouponRepositoriesFacade });
2540
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CouponRepositoriesFacade, decorators: [{
2541
+ type: Injectable
2542
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1998
2543
  type: Inject,
1999
- args: ['ProductStockNotificationRepository']
2544
+ args: ['CouponRepository']
2000
2545
  }] }, { type: undefined, decorators: [{
2001
2546
  type: Inject,
2002
- args: ['ProductSearch']
2547
+ args: ['OrderRepository']
2003
2548
  }] }, { type: undefined, decorators: [{
2004
2549
  type: Inject,
2005
- args: ['LogRepository']
2550
+ args: ['CategoryRepository']
2006
2551
  }] }]; } });
2007
2552
 
2008
2553
  class CouponService {
2009
- constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
2010
- this.couponRepository = couponRepository;
2011
- this.defaultShop = defaultShop;
2012
- this.orderRepository = orderRepository;
2013
- this.categoryRepository = categoryRepository;
2554
+ constructor(repositoriesFacade, configurationFacade) {
2555
+ this.repositoriesFacade = repositoriesFacade;
2556
+ this.configurationFacade = configurationFacade;
2014
2557
  this.emailIsFromCollaborator = (userEmail) => !!userEmail?.match(/@b4a.com.br/g);
2015
2558
  }
2016
- checkCoupon(nickname, checkoutType, checkout, plan) {
2017
- return from(this.couponRepository
2559
+ checkCoupon(params) {
2560
+ const { nickname, checkoutType, checkout, plan } = params;
2561
+ return from(this.repositoriesFacade.couponRepository
2018
2562
  .find({
2019
2563
  filters: {
2020
2564
  nickname: { operator: Where.EQUALS, value: nickname },
2021
2565
  active: { operator: Where.EQUALS, value: true },
2022
2566
  },
2023
2567
  })
2024
- .then((result) => result.data[0])).pipe(concatMap((coupon) => this.couponValidation(coupon, checkoutType)), concatMap((couponValid) => this.couponRulesValidation(couponValid, checkoutType, checkout, plan)), map((couponValidated) => couponValidated));
2568
+ .then((result) => result.data[0])).pipe(concatMap((coupon) => this.couponValidation(coupon, checkoutType)), concatMap((couponValid) => this.couponRulesValidation({ coupon: couponValid, checkoutType, checkout, plan })), map((couponValidated) => couponValidated));
2025
2569
  }
2026
2570
  async couponValidation(coupon, checkoutType) {
2027
2571
  if (!coupon)
@@ -2030,7 +2574,7 @@ class CouponService {
2030
2574
  throw 'Cupom inválido.';
2031
2575
  if (coupon?.expiresIn && (coupon?.expiresIn).getTime() < new Date().getTime())
2032
2576
  throw 'Cupom expirado.';
2033
- const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
2577
+ const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.configurationFacade.defaultShop;
2034
2578
  if (!isInShop)
2035
2579
  throw 'Cupom inválido para loja.';
2036
2580
  const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
@@ -2038,42 +2582,73 @@ class CouponService {
2038
2582
  throw 'Cupom inválido. Erro de checkout.';
2039
2583
  return coupon;
2040
2584
  }
2041
- async couponRulesValidation(coupon, checkoutType, checkout, plan) {
2585
+ async couponRulesValidation(params) {
2586
+ const { coupon, checkoutType, checkout, plan } = params;
2042
2587
  if (checkoutType == CheckoutTypes.SUBSCRIPTION) {
2043
- if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
2044
- throw 'Cupom inválido para sua assinatura.';
2045
- return coupon;
2588
+ return this.validateSubscriptionCoupon(coupon, plan);
2589
+ }
2590
+ return this.validateEcommerceCoupon(coupon, checkoutType, checkout);
2591
+ }
2592
+ validateSubscriptionCoupon(coupon, plan) {
2593
+ if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase()) {
2594
+ throw 'Cupom inválido para sua assinatura.';
2046
2595
  }
2047
- const validUser = this.coupomUserValidation(coupon, checkout?.user);
2596
+ return coupon;
2597
+ }
2598
+ async validateEcommerceCoupon(coupon, checkoutType, checkout) {
2599
+ this.validateUserEligibility(coupon, checkout?.user);
2600
+ await this.validateUsageLimits(coupon, checkoutType, checkout);
2601
+ await this.validateProductEligibility(coupon, checkout);
2602
+ return coupon;
2603
+ }
2604
+ validateUserEligibility(coupon, user) {
2605
+ const validUser = this.coupomUserValidation(coupon, user);
2048
2606
  if (!validUser)
2049
2607
  throw 'Usuário não elegível.';
2608
+ }
2609
+ async validateUsageLimits(coupon, checkoutType, checkout) {
2050
2610
  const couponUseLimits = this.getCouponUseLimits(coupon, checkoutType, checkout.user);
2051
2611
  if (couponUseLimits.firstOrder) {
2052
- const ordersUser = await this.getOrdersFromUser(checkout.user.email.toLocaleLowerCase());
2053
- if (couponUseLimits.firstOrder && ordersUser.length >= 1)
2054
- throw 'Limite de uso atingido';
2612
+ await this.validateFirstOrderLimit(checkout.user.email);
2055
2613
  }
2056
2614
  if (!couponUseLimits.unlimited || couponUseLimits.limitedPerUser) {
2057
- const ordersCoupon = await this.getOrdersWithCoupon(coupon);
2058
- if (!couponUseLimits.unlimited && couponUseLimits.total && ordersCoupon.length >= couponUseLimits.total)
2059
- throw 'Limite de uso atingido.';
2060
- if (couponUseLimits.limitedPerUser) {
2061
- const ordersWithUser = this.countOrdersWithUser(ordersCoupon, checkout.user.email);
2062
- if (ordersWithUser > 0)
2063
- throw 'Limite de uso por usuário atingido.';
2064
- }
2615
+ await this.validateCouponUsageLimits(coupon, couponUseLimits, checkout.user.email);
2616
+ }
2617
+ }
2618
+ async validateFirstOrderLimit(userEmail) {
2619
+ const ordersUser = await this.getOrdersFromUser(userEmail.toLocaleLowerCase());
2620
+ if (ordersUser.length >= 1)
2621
+ throw 'Limite de uso atingido';
2622
+ }
2623
+ async validateCouponUsageLimits(coupon, couponUseLimits, userEmail) {
2624
+ const ordersCoupon = await this.getOrdersWithCoupon(coupon);
2625
+ if (!couponUseLimits.unlimited && couponUseLimits.total && ordersCoupon.length >= couponUseLimits.total) {
2626
+ throw 'Limite de uso atingido.';
2065
2627
  }
2628
+ if (couponUseLimits.limitedPerUser) {
2629
+ const ordersWithUser = this.countOrdersWithUser(ordersCoupon, userEmail);
2630
+ if (ordersWithUser > 0)
2631
+ throw 'Limite de uso por usuário atingido.';
2632
+ }
2633
+ }
2634
+ async validateProductEligibility(coupon, checkout) {
2066
2635
  const hasProductCategories = await this.hasProductCategories(coupon, checkout);
2067
2636
  if (!hasProductCategories)
2068
2637
  throw 'Seu carrinho não possui produtos elegíveis para desconto.';
2069
2638
  const hasMinSubTotal = await this.hasMinSubTotal(coupon, checkout);
2070
2639
  if (!hasMinSubTotal) {
2071
- if (coupon.productsCategories?.length) {
2072
- throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido na(s) categoria(s) elegíveis para o desconto.`;
2073
- }
2074
- throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido.`;
2640
+ this.throwMinSubTotalError(coupon);
2075
2641
  }
2076
- return coupon;
2642
+ }
2643
+ throwMinSubTotalError(coupon) {
2644
+ const formattedValue = Intl.NumberFormat('pt-BR', {
2645
+ style: 'currency',
2646
+ currency: 'BRL',
2647
+ }).format(coupon.minSubTotalValue);
2648
+ if (coupon.productsCategories?.length) {
2649
+ throw `Valor mínimo de ${formattedValue} não atingido na(s) categoria(s) elegíveis para o desconto.`;
2650
+ }
2651
+ throw `Valor mínimo de ${formattedValue} não atingido.`;
2077
2652
  }
2078
2653
  calcDiscountSubscription(coupon, checkout) {
2079
2654
  let discount = 0;
@@ -2093,23 +2668,23 @@ class CouponService {
2093
2668
  return false;
2094
2669
  }
2095
2670
  async hasProductCategories(coupon, checkout) {
2096
- if (!coupon.productsCategories || !coupon.productsCategories?.length) {
2671
+ if (!coupon.productsCategories?.length) {
2097
2672
  return true;
2098
2673
  }
2099
2674
  const couponCategories = await this.getCouponCategoriesId(coupon.productsCategories);
2100
2675
  const hasCategories = checkout.lineItems?.filter((item) => {
2101
2676
  if (item.isGift)
2102
2677
  return false;
2103
- if (!item.categories || !item.categories?.length)
2678
+ if (!item.categories?.length)
2104
2679
  return true;
2105
2680
  return item.categories.some((c) => couponCategories.some((cat) => cat == c));
2106
2681
  });
2107
- return hasCategories.length ? true : false;
2682
+ return hasCategories?.length ? true : false;
2108
2683
  }
2109
2684
  coupomUserValidation(coupon, user) {
2110
2685
  if (!user || coupon.exclusivityType.includes(Exclusivities.ALL_USERS))
2111
2686
  return true;
2112
- let userTypes = [];
2687
+ const userTypes = [];
2113
2688
  if (coupon.exclusivityType.includes(Exclusivities.COLLABORATORS) &&
2114
2689
  this.emailIsFromCollaborator(user.email.toLocaleLowerCase()))
2115
2690
  userTypes.push(Exclusivities.COLLABORATORS);
@@ -2131,11 +2706,11 @@ class CouponService {
2131
2706
  async getCouponCategoriesId(productsCategories) {
2132
2707
  const couponCategories = [];
2133
2708
  for (let index = 0; index < productsCategories.length; index++) {
2134
- const category = await this.categoryRepository.get({
2709
+ const category = await this.repositoriesFacade.categoryRepository.get({
2135
2710
  id: productsCategories[index],
2136
2711
  });
2137
2712
  if (category) {
2138
- const children = await this.categoryRepository.getChildren(parseInt(productsCategories[index]));
2713
+ const children = await this.repositoriesFacade.categoryRepository.getChildren(parseInt(productsCategories[index]));
2139
2714
  couponCategories.push(category.id, ...children.map((c) => c.id.toString()));
2140
2715
  }
2141
2716
  }
@@ -2144,7 +2719,7 @@ class CouponService {
2144
2719
  async getLineItensEligebleForDiscount(productsCategories, checkout) {
2145
2720
  let lineItensDiscount = [];
2146
2721
  const couponCategories = await this.getCouponCategoriesId(productsCategories);
2147
- if (productsCategories && productsCategories.length) {
2722
+ if (productsCategories?.length) {
2148
2723
  lineItensDiscount = checkout.lineItems?.filter((item) => {
2149
2724
  if (item.isGift)
2150
2725
  return false;
@@ -2162,12 +2737,12 @@ class CouponService {
2162
2737
  calcCheckoutSubtotal(lineItens, user) {
2163
2738
  return (lineItens
2164
2739
  ?.filter((item) => !item.isGift)
2165
- .reduce((acc, curr) => user?.isSubscriber && curr.price.subscriberPrice
2740
+ .reduce((acc, curr) => user?.isSubscriber && curr.price?.subscriberPrice
2166
2741
  ? acc + curr.price?.subscriberPrice * curr.quantity
2167
2742
  : acc + curr.pricePaid * curr.quantity, 0) || 0);
2168
2743
  }
2169
2744
  async getOrdersWithCoupon(coupon) {
2170
- return await this.orderRepository
2745
+ return await this.repositoriesFacade.orderRepository
2171
2746
  .find({
2172
2747
  filters: {
2173
2748
  coupon: { id: coupon.id },
@@ -2177,7 +2752,7 @@ class CouponService {
2177
2752
  .then((result) => result.data);
2178
2753
  }
2179
2754
  async getOrdersFromUser(email) {
2180
- return await this.orderRepository
2755
+ return await this.repositoriesFacade.orderRepository
2181
2756
  .find({
2182
2757
  filters: {
2183
2758
  user: { email: { operator: Where.EQUALS, value: email } },
@@ -2197,7 +2772,7 @@ class CouponService {
2197
2772
  coupon.exclusivityType.at(0) === Exclusivities.COLLABORATORS))
2198
2773
  couponUseLimits = coupon.useLimits.non_subscriber;
2199
2774
  else
2200
- couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
2775
+ couponUseLimits = user?.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
2201
2776
  }
2202
2777
  else {
2203
2778
  couponUseLimits = coupon.useLimits.subscription;
@@ -2205,26 +2780,14 @@ class CouponService {
2205
2780
  return couponUseLimits;
2206
2781
  }
2207
2782
  }
2208
- CouponService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CouponService, deps: [{ token: 'CouponRepository' }, { token: DEFAULT_SHOP }, { token: 'OrderRepository' }, { token: 'CategoryRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
2783
+ CouponService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CouponService, deps: [{ token: CouponRepositoriesFacade }, { token: ConfigurationFacade }], target: i0.ɵɵFactoryTarget.Injectable });
2209
2784
  CouponService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CouponService, providedIn: 'root' });
2210
2785
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: CouponService, decorators: [{
2211
2786
  type: Injectable,
2212
2787
  args: [{
2213
2788
  providedIn: 'root',
2214
2789
  }]
2215
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
2216
- type: Inject,
2217
- args: ['CouponRepository']
2218
- }] }, { type: i1$3.Shops, decorators: [{
2219
- type: Inject,
2220
- args: [DEFAULT_SHOP]
2221
- }] }, { type: undefined, decorators: [{
2222
- type: Inject,
2223
- args: ['OrderRepository']
2224
- }] }, { type: undefined, decorators: [{
2225
- type: Inject,
2226
- args: ['CategoryRepository']
2227
- }] }]; } });
2790
+ }], ctorParameters: function () { return [{ type: CouponRepositoriesFacade }, { type: ConfigurationFacade }]; } });
2228
2791
 
2229
2792
  class CheckoutSubscriptionService {
2230
2793
  constructor(checkoutSubscriptionRepository, dataPersistence, couponService) {
@@ -2240,9 +2803,14 @@ class CheckoutSubscriptionService {
2240
2803
  clearCheckoutSubscriptionFromSession() {
2241
2804
  return this.dataPersistence.remove('checkoutSubscriptionId');
2242
2805
  }
2243
- checkCoupon(nickname, userEmail) {
2806
+ checkCoupon(nickname, _userEmail) {
2244
2807
  return this.getCheckoutSubscription().pipe(concatMap((checkout) => this.couponService
2245
- .checkCoupon(nickname, CheckoutTypes.SUBSCRIPTION, checkout, checkout.subscriptionPlan.name)
2808
+ .checkCoupon({
2809
+ nickname,
2810
+ checkoutType: CheckoutTypes.SUBSCRIPTION,
2811
+ checkout,
2812
+ plan: checkout.subscriptionPlan.name,
2813
+ })
2246
2814
  .pipe()));
2247
2815
  }
2248
2816
  calcDiscountSubscription(coupon) {
@@ -2273,33 +2841,53 @@ class UtilHelper {
2273
2841
  static createSlug(name) {
2274
2842
  return name
2275
2843
  .toLowerCase()
2276
- .replace(/\s+/g, '-') // Replace spaces with -
2277
- .replace(/[ãàáäâ]/g, 'a') // Replace spaces with -
2278
- .replace(/[ẽèéëê]/g, 'e') // Replace spaces with -
2279
- .replace(/[ìíïî]/g, 'i') // Replace spaces with -
2280
- .replace(/[õòóöô]/g, 'o') // Replace spaces with -
2281
- .replace(/[ùúüû]/g, 'u') // Replace spaces with -
2282
- .replace(/[ñ]/g, 'n') // Replace spaces with -
2283
- .replace(/[ç]/g, 'c') // Replace spaces with -
2284
- .replace(/[&]/g, 'and') // Replace spaces with -
2285
- .replace(/[^\w\-]+/g, '') // Remove all non-word chars
2286
- .replace(/\-\-+/g, '-'); // Replace multiple - with single -
2844
+ .replace(/\s+/g, '-')
2845
+ .replace(/[ãàáäâ]/g, 'a')
2846
+ .replace(/[ẽèéëê]/g, 'e')
2847
+ .replace(/[ìíïî]/g, 'i')
2848
+ .replace(/[õòóöô]/g, 'o')
2849
+ .replace(/[ùúüû]/g, 'u')
2850
+ .replace(/[ñ]/g, 'n')
2851
+ .replace(/[ç]/g, 'c')
2852
+ .replace(/[&]/g, 'and')
2853
+ .replace(/[^\w-]+/g, '')
2854
+ .replace(/--+/g, '-');
2855
+ }
2856
+ }
2857
+
2858
+ class HomeShopRepositoriesFacade {
2859
+ constructor(categoryRepository, homeRepository, productRepository) {
2860
+ this.categoryRepository = categoryRepository;
2861
+ this.homeRepository = homeRepository;
2862
+ this.productRepository = productRepository;
2287
2863
  }
2288
2864
  }
2865
+ HomeShopRepositoriesFacade.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: HomeShopRepositoriesFacade, deps: [{ token: 'CategoryRepository' }, { token: 'HomeRepository' }, { token: 'ProductRepository' }], target: i0.ɵɵFactoryTarget.Injectable });
2866
+ HomeShopRepositoriesFacade.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: HomeShopRepositoriesFacade });
2867
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: HomeShopRepositoriesFacade, decorators: [{
2868
+ type: Injectable
2869
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
2870
+ type: Inject,
2871
+ args: ['CategoryRepository']
2872
+ }] }, { type: undefined, decorators: [{
2873
+ type: Inject,
2874
+ args: ['HomeRepository']
2875
+ }] }, { type: undefined, decorators: [{
2876
+ type: Inject,
2877
+ args: ['ProductRepository']
2878
+ }] }]; } });
2289
2879
 
2290
2880
  class HomeShopService {
2291
2881
  get homeId() {
2292
- if (this.defaultShop === Shops.GLAMSHOP)
2882
+ if (this.configurationFacade.defaultShop === Shops.GLAMSHOP)
2293
2883
  return 'glamshop';
2294
- if (this.defaultShop === Shops.MENSMARKET)
2884
+ if (this.configurationFacade.defaultShop === Shops.MENSMARKET)
2295
2885
  return 'mens_market';
2296
2886
  return null;
2297
2887
  }
2298
- constructor(categoryRepository, homeRepository, productRepository, defaultShop) {
2299
- this.categoryRepository = categoryRepository;
2300
- this.homeRepository = homeRepository;
2301
- this.productRepository = productRepository;
2302
- this.defaultShop = defaultShop;
2888
+ constructor(repositoriesFacade, configurationFacade) {
2889
+ this.repositoriesFacade = repositoriesFacade;
2890
+ this.configurationFacade = configurationFacade;
2303
2891
  this.buildCategoryGroupWithRequiredData = (group) => ({
2304
2892
  category: Category.toInstance(pick(group?.category?.toPlain() || {}, ['id', 'name', 'slug', 'conditions'])),
2305
2893
  products: group?.products?.map((product) => Product.toInstance(pick(product?.toPlain() || {}, [
@@ -2350,14 +2938,20 @@ class HomeShopService {
2350
2938
  getMinValueForFreeShipping() {
2351
2939
  return this.getHomeConfiguration().pipe(map((home) => home.minValueForFreeShipping));
2352
2940
  }
2353
- getDiscoverProducts(gender) {
2354
- return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.discoverCategories, this.defaultShop)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2941
+ getDiscoverProducts(_gender) {
2942
+ return this.getHomeConfiguration().pipe(concatMap((home) => from(this.repositoriesFacade.categoryRepository.getCategoriesForHome({
2943
+ categoryIds: home.discoverCategories,
2944
+ shop: this.configurationFacade.defaultShop,
2945
+ })).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2355
2946
  }
2356
- getFeaturedProducts(gender) {
2357
- return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.featuredCategories, this.defaultShop)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2947
+ getFeaturedProducts(_gender) {
2948
+ return this.getHomeConfiguration().pipe(concatMap((home) => from(this.repositoriesFacade.categoryRepository.getCategoriesForHome({
2949
+ categoryIds: home.featuredCategories,
2950
+ shop: this.configurationFacade.defaultShop,
2951
+ })).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2358
2952
  }
2359
2953
  getVerticalProducts(gender) {
2360
- return this.getHomeConfiguration().pipe(concatMap((home) => forkJoin(home.verticalCarousels.filter(Boolean).map((id) => from(this.categoryRepository.get({ id })).pipe(concatMap((category) => from(this.productRepository.find({
2954
+ return this.getHomeConfiguration().pipe(concatMap((home) => forkJoin(home.verticalCarousels.filter(Boolean).map((id) => from(this.repositoriesFacade.categoryRepository.get({ id })).pipe(concatMap((category) => from(this.repositoriesFacade.productRepository.find({
2361
2955
  filters: {
2362
2956
  categories: { operator: Where.IN, value: [category.id] },
2363
2957
  ...(gender ? { tags: { operator: Where.IN, value: [gender] } } : {}),
@@ -2369,8 +2963,8 @@ class HomeShopService {
2369
2963
  return of(this.homeConfiguration).pipe(concatMap((home) => home
2370
2964
  ? of(home)
2371
2965
  : !this.homeId
2372
- ? throwError(new RequiredArgumentError(['homeId']))
2373
- : from(this.homeRepository.get({ id: this.homeId })).pipe(tap((homeLoaded) => (this.homeConfiguration = homeLoaded)))));
2966
+ ? throwError(() => new RequiredArgumentError(['homeId']))
2967
+ : from(this.repositoriesFacade.homeRepository.get({ id: this.homeId })).pipe(tap((homeLoaded) => (this.homeConfiguration = homeLoaded)))));
2374
2968
  }
2375
2969
  saveHomeData(homeData) {
2376
2970
  const data = {
@@ -2378,7 +2972,7 @@ class HomeShopService {
2378
2972
  expiresAt: add(new Date(), { hours: 1 }),
2379
2973
  data: homeData,
2380
2974
  };
2381
- return from(this.homeRepository.update({
2975
+ return from(this.repositoriesFacade.homeRepository.update({
2382
2976
  id: this.homeId,
2383
2977
  data,
2384
2978
  })).pipe(tap(() => (this.homeConfiguration.data = data)), map(() => this.homeConfiguration));
@@ -2387,23 +2981,11 @@ class HomeShopService {
2387
2981
  return this.homeId === 'mens_market' ? 'masculino' : undefined;
2388
2982
  }
2389
2983
  }
2390
- HomeShopService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: HomeShopService, deps: [{ token: 'CategoryRepository' }, { token: 'HomeRepository' }, { token: 'ProductRepository' }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable });
2984
+ HomeShopService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: HomeShopService, deps: [{ token: HomeShopRepositoriesFacade }, { token: ConfigurationFacade }], target: i0.ɵɵFactoryTarget.Injectable });
2391
2985
  HomeShopService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: HomeShopService });
2392
2986
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: HomeShopService, decorators: [{
2393
2987
  type: Injectable
2394
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
2395
- type: Inject,
2396
- args: ['CategoryRepository']
2397
- }] }, { type: undefined, decorators: [{
2398
- type: Inject,
2399
- args: ['HomeRepository']
2400
- }] }, { type: undefined, decorators: [{
2401
- type: Inject,
2402
- args: ['ProductRepository']
2403
- }] }, { type: i1$3.Shops, decorators: [{
2404
- type: Inject,
2405
- args: [DEFAULT_SHOP]
2406
- }] }]; } });
2988
+ }], ctorParameters: function () { return [{ type: HomeShopRepositoriesFacade }, { type: ConfigurationFacade }]; } });
2407
2989
 
2408
2990
  class OrderService {
2409
2991
  constructor(angularFirestore, orderRepository) {
@@ -2422,7 +3004,7 @@ OrderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "1
2422
3004
  OrderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: OrderService });
2423
3005
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: OrderService, decorators: [{
2424
3006
  type: Injectable
2425
- }], ctorParameters: function () { return [{ type: i1$1.Firestore }, { type: i1$3.OrderFirestoreRepository, decorators: [{
3007
+ }], ctorParameters: function () { return [{ type: i1$1.Firestore }, { type: i3.OrderFirestoreRepository, decorators: [{
2426
3008
  type: Inject,
2427
3009
  args: ['OrderRepository']
2428
3010
  }] }]; } });
@@ -2432,28 +3014,44 @@ class AngularConnectModule {
2432
3014
  return {
2433
3015
  ngModule: AngularConnectModule,
2434
3016
  providers: [
2435
- { provide: FIREBASE_APP_NAME, useValue: nameOrConfig },
2436
- { provide: APP_CHECK_PROVIDER, useValue: options.appCheckProvider },
2437
- {
2438
- provide: CATEGORY_STRUCTURE,
2439
- useClass: isNil(options?.oldCategoryStructure) || options?.oldCategoryStructure
2440
- ? OldCategoryStructureAdapter
2441
- : NewCategoryStructureAdapter,
2442
- },
2443
- { provide: PERSISTENCE_PROVIDER, useClass: options?.persistenceProvider || CookieDataPersistence },
2444
- ...(isNil(defaultShop) ? [] : [{ provide: DEFAULT_SHOP, useValue: defaultShop }]),
2445
- ...(isNil(options?.firebase) ? [] : [{ provide: FIREBASE_OPTIONS, useValue: options?.firebase }]),
2446
- ...(isNil(options?.elasticSearch) ? [] : [{ provide: ES_CONFIG, useValue: options.elasticSearch }]),
2447
- ...(isNil(options?.vertexConfig) ? [] : [{ provide: VERTEX_CONFIG, useValue: options.vertexConfig }]),
2448
- ...(isNil(options?.hasura) ? [] : [{ provide: HASURA_OPTIONS, useValue: options.hasura }]),
2449
- ...(isNil(options?.backendUrl) ? [] : [{ provide: BACKEND_URL, useValue: options.backendUrl }]),
2450
- ...(isNil(options?.storageBaseUrl) ? [] : [{ provide: STORAGE_BASE_URL, useValue: options.storageBaseUrl }]),
3017
+ ...this.buildCoreProviders(nameOrConfig, options),
3018
+ ...this.buildConditionalProviders(defaultShop, options),
2451
3019
  ],
2452
3020
  };
2453
3021
  }
3022
+ static buildCoreProviders(nameOrConfig, options) {
3023
+ return [
3024
+ { provide: FIREBASE_APP_NAME, useValue: nameOrConfig },
3025
+ { provide: APP_CHECK_PROVIDER, useValue: options.appCheckProvider },
3026
+ {
3027
+ provide: CATEGORY_STRUCTURE,
3028
+ useClass: this.selectCategoryStructureAdapter(options.oldCategoryStructure),
3029
+ },
3030
+ { provide: PERSISTENCE_PROVIDER, useClass: options?.persistenceProvider || CookieDataPersistence },
3031
+ ];
3032
+ }
3033
+ static buildConditionalProviders(defaultShop, options) {
3034
+ return [
3035
+ ...this.createProviderIfExists(DEFAULT_SHOP, defaultShop),
3036
+ ...this.createProviderIfExists(FIREBASE_OPTIONS, options.firebase),
3037
+ ...this.createProviderIfExists(ES_CONFIG, options.elasticSearch),
3038
+ ...this.createProviderIfExists(VERTEX_CONFIG, options.vertexConfig),
3039
+ ...this.createProviderIfExists(HASURA_OPTIONS, options.hasura),
3040
+ ...this.createProviderIfExists(BACKEND_URL, options.backendUrl),
3041
+ ...this.createProviderIfExists(STORAGE_BASE_URL, options.storageBaseUrl),
3042
+ ];
3043
+ }
3044
+ static selectCategoryStructureAdapter(oldCategoryStructure) {
3045
+ return isNil(oldCategoryStructure) || oldCategoryStructure
3046
+ ? OldCategoryStructureAdapter
3047
+ : NewCategoryStructureAdapter;
3048
+ }
3049
+ static createProviderIfExists(token, value) {
3050
+ return isNil(value) ? [] : [{ provide: token, useValue: value }];
3051
+ }
2454
3052
  }
2455
3053
  AngularConnectModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AngularConnectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2456
- AngularConnectModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.0", ngImport: i0, type: AngularConnectModule, imports: [i1$4.FirebaseAppModule, i2.AppCheckModule, i3.StorageModule, AngularElasticSeachModule,
3054
+ AngularConnectModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.0", ngImport: i0, type: AngularConnectModule, imports: [i1$3.FirebaseAppModule, i2.AppCheckModule, i3$1.StorageModule, AngularElasticSeachModule,
2457
3055
  AngularVertexSeachModule,
2458
3056
  AngularFirebaseAuthModule,
2459
3057
  AngularFirestoreModule,
@@ -2469,6 +3067,42 @@ AngularConnectModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", ve
2469
3067
  HomeShopService,
2470
3068
  OrderService,
2471
3069
  WishlistService,
3070
+ ConfigurationFacade,
3071
+ CartServicesFacade,
3072
+ CheckoutRepositoriesFacade,
3073
+ CheckoutDependenciesFacade,
3074
+ CategoryRepositoryFacade,
3075
+ ProductCatalogFacade,
3076
+ CatalogServiceFacade,
3077
+ CategoryServiceFacade,
3078
+ CatalogStrategiesFacade,
3079
+ CatalogOperationsFacade,
3080
+ ProductManagementFacade,
3081
+ {
3082
+ provide: 'ProductServicesFacade',
3083
+ useFactory: (productStockNotificationRepository, categoryRepository, productSearch) => ({
3084
+ productStockNotificationRepository,
3085
+ categoryRepository,
3086
+ productSearch,
3087
+ }),
3088
+ deps: ['ProductStockNotificationRepository', 'CategoryRepository', 'ProductSearch'],
3089
+ },
3090
+ CatalogFilterHelper,
3091
+ CatalogSortHelper,
3092
+ ProductFieldsHelper,
3093
+ BrandManagerHelper,
3094
+ CatalogRepositoryService,
3095
+ CatalogHelpersService,
3096
+ CategorySearchStrategy,
3097
+ TermSearchStrategy,
3098
+ ProfileSearchStrategy,
3099
+ {
3100
+ provide: CatalogSearchContext,
3101
+ useFactory: (categoryStrategy, termStrategy, profileStrategy) => {
3102
+ return new CatalogSearchContext(categoryStrategy, termStrategy, profileStrategy);
3103
+ },
3104
+ deps: [CategorySearchStrategy, TermSearchStrategy, ProfileSearchStrategy],
3105
+ },
2472
3106
  {
2473
3107
  provide: UpdateUserImage,
2474
3108
  useFactory: (userRepository, fileUploader) => {
@@ -2487,6 +3121,8 @@ AngularConnectModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", ve
2487
3121
  provide: 'ProductSearch',
2488
3122
  useExisting: ProductsVertexSearch,
2489
3123
  },
3124
+ CouponRepositoriesFacade,
3125
+ HomeShopRepositoriesFacade,
2490
3126
  ], imports: [provideFirebaseApp((injector) => {
2491
3127
  const appName = injector.get(FIREBASE_APP_NAME);
2492
3128
  try {
@@ -2573,6 +3209,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImpor
2573
3209
  HomeShopService,
2574
3210
  OrderService,
2575
3211
  WishlistService,
3212
+ ConfigurationFacade,
3213
+ CartServicesFacade,
3214
+ CheckoutRepositoriesFacade,
3215
+ CheckoutDependenciesFacade,
3216
+ CategoryRepositoryFacade,
3217
+ ProductCatalogFacade,
3218
+ CatalogServiceFacade,
3219
+ CategoryServiceFacade,
3220
+ CatalogStrategiesFacade,
3221
+ CatalogOperationsFacade,
3222
+ ProductManagementFacade,
3223
+ {
3224
+ provide: 'ProductServicesFacade',
3225
+ useFactory: (productStockNotificationRepository, categoryRepository, productSearch) => ({
3226
+ productStockNotificationRepository,
3227
+ categoryRepository,
3228
+ productSearch,
3229
+ }),
3230
+ deps: ['ProductStockNotificationRepository', 'CategoryRepository', 'ProductSearch'],
3231
+ },
3232
+ CatalogFilterHelper,
3233
+ CatalogSortHelper,
3234
+ ProductFieldsHelper,
3235
+ BrandManagerHelper,
3236
+ CatalogRepositoryService,
3237
+ CatalogHelpersService,
3238
+ CategorySearchStrategy,
3239
+ TermSearchStrategy,
3240
+ ProfileSearchStrategy,
3241
+ {
3242
+ provide: CatalogSearchContext,
3243
+ useFactory: (categoryStrategy, termStrategy, profileStrategy) => {
3244
+ return new CatalogSearchContext(categoryStrategy, termStrategy, profileStrategy);
3245
+ },
3246
+ deps: [CategorySearchStrategy, TermSearchStrategy, ProfileSearchStrategy],
3247
+ },
2576
3248
  {
2577
3249
  provide: UpdateUserImage,
2578
3250
  useFactory: (userRepository, fileUploader) => {
@@ -2591,6 +3263,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImpor
2591
3263
  provide: 'ProductSearch',
2592
3264
  useExisting: ProductsVertexSearch,
2593
3265
  },
3266
+ CouponRepositoriesFacade,
3267
+ HomeShopRepositoriesFacade,
2594
3268
  ],
2595
3269
  }]
2596
3270
  }] });