@infrab4a/connect-angular 5.0.0-beta.7 → 5.0.0-beta.71

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 (40) hide show
  1. package/angular-connect.module.d.ts +13 -8
  2. package/angular-firestore.module.d.ts +1 -2
  3. package/angular-vertex-search.module.d.ts +9 -0
  4. package/consts/index.d.ts +2 -0
  5. package/consts/persistence.const.d.ts +1 -0
  6. package/consts/vertex-config.const.d.ts +1 -0
  7. package/esm2022/angular-connect.module.mjs +38 -5
  8. package/esm2022/angular-firestore.module.mjs +39 -28
  9. package/esm2022/angular-hasura-graphql.module.mjs +52 -8
  10. package/esm2022/angular-vertex-search.module.mjs +34 -0
  11. package/esm2022/consts/index.mjs +3 -1
  12. package/esm2022/consts/persistence.const.mjs +2 -0
  13. package/esm2022/consts/vertex-config.const.mjs +2 -0
  14. package/esm2022/index.mjs +2 -1
  15. package/esm2022/persistence/cookie-data-persistence.mjs +22 -0
  16. package/esm2022/persistence/data-persistence.mjs +2 -0
  17. package/esm2022/persistence/index.mjs +3 -0
  18. package/esm2022/services/cart.service.mjs +44 -32
  19. package/esm2022/services/catalog/adapters/new-category-structure.adapter.mjs +6 -4
  20. package/esm2022/services/catalog/catalog.service.mjs +158 -48
  21. package/esm2022/services/catalog/category.service.mjs +4 -4
  22. package/esm2022/services/catalog/wishlist.service.mjs +142 -22
  23. package/esm2022/services/checkout-subscription.service.mjs +18 -21
  24. package/esm2022/services/checkout.service.mjs +13 -16
  25. package/esm2022/services/coupon.service.mjs +74 -29
  26. package/esm2022/services/home-shop.service.mjs +4 -4
  27. package/fesm2022/infrab4a-connect-angular.mjs +624 -201
  28. package/fesm2022/infrab4a-connect-angular.mjs.map +1 -1
  29. package/index.d.ts +1 -0
  30. package/package.json +6 -6
  31. package/persistence/cookie-data-persistence.d.ts +10 -0
  32. package/persistence/data-persistence.d.ts +6 -0
  33. package/persistence/index.d.ts +2 -0
  34. package/services/cart.service.d.ts +1 -0
  35. package/services/catalog/catalog.service.d.ts +11 -4
  36. package/services/catalog/category.service.d.ts +6 -1
  37. package/services/catalog/wishlist.service.d.ts +16 -4
  38. package/services/checkout-subscription.service.d.ts +5 -4
  39. package/services/checkout.service.d.ts +8 -4
  40. package/services/coupon.service.d.ts +6 -2
@@ -2,18 +2,18 @@ import * as i0 from '@angular/core';
2
2
  import { NgModule, InjectionToken, PLATFORM_ID, Injectable, Inject } from '@angular/core';
3
3
  import * as i1$4 from '@angular/fire/app';
4
4
  import { FirebaseApp, provideFirebaseApp, getApp, initializeApp } from '@angular/fire/app';
5
+ import * as i2 from '@angular/fire/storage';
6
+ import { Storage, provideStorage, getStorage } from '@angular/fire/storage';
5
7
  import * as i1$2 from '@infrab4a/connect';
6
- import { ProductsIndex, AxiosAdapter, Authentication, AuthenticationFirebaseAuthService, Register, RegisterFirebaseAuthService, SignOut, RecoveryPassword, UserBeautyProfileFirestoreRepository, Buy2WinFirestoreRepository, CategoryFirestoreRepository, CheckoutFirestoreRepository, CheckoutSubscriptionFirestoreRepository, CouponFirestoreRepository, CampaignHashtagFirestoreRepository, CampaignDashboardFirestoreRepository, SubscriptionEditionFirestoreRepository, HomeFirestoreRepository, LeadFirestoreRepository, LegacyOrderFirestoreRepository, ShopMenuFirestoreRepository, OrderFirestoreRepository, PaymentFirestoreRepository, ProductFirestoreRepository, ShopSettingsFirestoreRepository, SubscriptionPaymentFirestoreRepository, SubscriptionPlanFirestoreRepository, SubscriptionProductFirestoreRepository, SubscriptionFirestoreRepository, UserFirestoreRepository, UserAddressFirestoreRepository, UserPaymentMethodFirestoreRepository, SubscriptionMaterializationFirestoreRepository, SubscriptionSummaryFirestoreRepository, ProductVariantFirestoreRepository, FirebaseFileUploaderService, CategoryHasuraGraphQLRepository, ProductHasuraGraphQLRepository, CategoryFilterHasuraGraphQLRepository, ProductReviewsHasuraGraphQLRepository, VariantHasuraGraphQLRepository, FilterOptionHasuraGraphQLRepository, FilterHasuraGraphQLRepository, CategoryCollectionChildrenHasuraGraphQLRepository, WishlistHasuraGraphQLRepository, Where, Shops, CheckoutTypes, CouponTypes, Exclusivities, isNil, NotFoundError, Checkout, pick, LineItem, RoundProductPricesHelper, set, InvalidArgumentError, Category, Wishlist, CheckoutSubscription, Product, RequiredArgumentError, add, Order, UpdateUserImage } from '@infrab4a/connect';
8
+ import { ProductsIndex, AxiosAdapter, Authentication, AuthenticationFirebaseAuthService, Register, RegisterFirebaseAuthService, SignOut, RecoveryPassword, ConnectFirestoreService, UserBeautyProfileFirestoreRepository, Buy2WinFirestoreRepository, CategoryFirestoreRepository, CheckoutFirestoreRepository, CheckoutSubscriptionFirestoreRepository, CouponFirestoreRepository, CampaignHashtagFirestoreRepository, CampaignDashboardFirestoreRepository, SubscriptionEditionFirestoreRepository, HomeFirestoreRepository, LeadFirestoreRepository, LegacyOrderFirestoreRepository, ShopMenuFirestoreRepository, OrderFirestoreRepository, PaymentFirestoreRepository, ProductFirestoreRepository, ShopSettingsFirestoreRepository, SubscriptionPaymentFirestoreRepository, SubscriptionPlanFirestoreRepository, SubscriptionProductFirestoreRepository, SubscriptionFirestoreRepository, UserFirestoreRepository, UserAddressFirestoreRepository, UserPaymentMethodFirestoreRepository, SubscriptionMaterializationFirestoreRepository, SubscriptionSummaryFirestoreRepository, ProductVariantFirestoreRepository, OrderBlockedFirestoreRepository, LogFirestoreRepository, CategoryHasuraGraphQLRepository, ProductHasuraGraphQLRepository, CategoryFilterHasuraGraphQLRepository, ProductReviewsHasuraGraphQLRepository, VariantHasuraGraphQLRepository, ProductStockNotificationHasuraGraphQLRepository, FilterOptionHasuraGraphQLRepository, FilterHasuraGraphQLRepository, CategoryCollectionChildrenHasuraGraphQLRepository, CategoryProductHasuraGraphQLRepository, WishlistHasuraGraphQLRepository, ProductsVertexSearch, VertexAxiosAdapter, Where, Shops, CheckoutTypes, CouponTypes, Exclusivities, OrderStatus, isNil, NotFoundError, Checkout, pick, LineItem, RoundProductPricesHelper, set, InvalidArgumentError, isEmpty, Category, PersonTypes, WishlistLogType, Wishlist, CheckoutSubscription, Product, RequiredArgumentError, add, Order, UpdateUserImage, FirebaseFileUploaderService } from '@infrab4a/connect';
7
9
  import * as i1 from '@angular/fire/auth';
8
10
  import { Auth, provideAuth, getAuth, getIdToken, authState } from '@angular/fire/auth';
9
11
  import { isPlatformBrowser, isPlatformServer } from '@angular/common';
10
12
  import * as i1$1 from '@angular/fire/firestore';
11
- import { Firestore, provideFirestore, getFirestore, initializeFirestore, memoryLocalCache, docSnapshots, doc } from '@angular/fire/firestore';
12
- import * as i2 from '@angular/fire/storage';
13
- import { Storage, provideStorage, getStorage } from '@angular/fire/storage';
14
- import { combineLatest, from, of, throwError, Subject, iif, forkJoin } from 'rxjs';
15
- import { map, mergeMap, catchError, concatMap, tap } from 'rxjs/operators';
13
+ import { Firestore, provideFirestore, initializeFirestore, memoryLocalCache, docSnapshots, doc } from '@angular/fire/firestore';
16
14
  import cookie from 'js-cookie';
15
+ import { of, from, combineLatest, throwError, Subject, iif, forkJoin } from 'rxjs';
16
+ import { map, mergeMap, catchError, concatMap, tap } from 'rxjs/operators';
17
17
  import { __decorate, __metadata } from 'tslib';
18
18
  import { Type } from 'class-transformer';
19
19
  import * as i1$3 from '@angular/common/http';
@@ -61,6 +61,10 @@ const FIREBASE_OPTIONS = new InjectionToken('firebaseOptions');
61
61
 
62
62
  const HASURA_OPTIONS = 'HASURA_OPTIONS';
63
63
 
64
+ const PERSISTENCE_PROVIDER = 'PERSISTENCE_PROVIDER';
65
+
66
+ const VERTEX_CONFIG = 'VERTEX_CONFIG';
67
+
64
68
  class AngularFirebaseAuthModule {
65
69
  static initializeApp(options, nameOrConfig) {
66
70
  return {
@@ -169,8 +173,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
169
173
  }]
170
174
  }] });
171
175
 
172
- const STORAGE_BASE_URL = 'STORAGE_BASE_URL';
173
-
174
176
  class MobileOperationSystemCheckerHelper {
175
177
  static isAppleDevice() {
176
178
  return (['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(navigator?.platform) ||
@@ -190,12 +192,12 @@ class AngularFirestoreModule {
190
192
  };
191
193
  }
192
194
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
193
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, imports: [AngularElasticSeachModule, i1$1.FirestoreModule, i2.StorageModule] }); }
195
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, imports: [AngularElasticSeachModule, i1$1.FirestoreModule] }); }
194
196
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, providers: [
195
197
  {
196
198
  provide: 'FirestoreOptions',
197
199
  useFactory: (firestore, platformId) => ({
198
- firestore,
200
+ firestore: new ConnectFirestoreService(firestore),
199
201
  interceptors: {
200
202
  request: (request) => {
201
203
  if (isPlatformBrowser(platformId))
@@ -404,26 +406,33 @@ class AngularFirestoreModule {
404
406
  deps: ['FirestoreOptions', ProductFirestoreRepository],
405
407
  },
406
408
  {
407
- provide: 'FileUploaderService',
408
- useFactory: (storage, baseUrl) => {
409
- return new FirebaseFileUploaderService(storage, baseUrl);
409
+ provide: 'OrderBlockedRepository',
410
+ useFactory: (options) => {
411
+ return new OrderBlockedFirestoreRepository(options);
410
412
  },
411
- deps: [Storage, STORAGE_BASE_URL],
413
+ deps: ['FirestoreOptions'],
414
+ },
415
+ {
416
+ provide: 'LogRepository',
417
+ useFactory: (options) => {
418
+ return new LogFirestoreRepository(options);
419
+ },
420
+ deps: ['FirestoreOptions'],
412
421
  },
413
422
  ], imports: [AngularElasticSeachModule,
414
423
  provideFirestore((injector) => {
415
424
  const platformId = injector.get(PLATFORM_ID);
416
- if (isPlatformServer(platformId))
417
- return getFirestore(injector.get(FirebaseApp));
418
- if (!MobileOperationSystemCheckerHelper.isAppleDevice())
419
- return getFirestore(injector.get(FirebaseApp));
425
+ if (isPlatformServer(platformId) || !MobileOperationSystemCheckerHelper.isAppleDevice())
426
+ return initializeFirestore(injector.get(FirebaseApp), {
427
+ ignoreUndefinedProperties: true,
428
+ });
420
429
  const firestore = initializeFirestore(injector.get(FirebaseApp), {
421
430
  experimentalForceLongPolling: true,
431
+ ignoreUndefinedProperties: true,
422
432
  localCache: memoryLocalCache(),
423
433
  });
424
434
  return firestore;
425
- }),
426
- provideStorage(() => getStorage())] }); }
435
+ })] }); }
427
436
  }
428
437
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, decorators: [{
429
438
  type: NgModule,
@@ -432,23 +441,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
432
441
  AngularElasticSeachModule,
433
442
  provideFirestore((injector) => {
434
443
  const platformId = injector.get(PLATFORM_ID);
435
- if (isPlatformServer(platformId))
436
- return getFirestore(injector.get(FirebaseApp));
437
- if (!MobileOperationSystemCheckerHelper.isAppleDevice())
438
- return getFirestore(injector.get(FirebaseApp));
444
+ if (isPlatformServer(platformId) || !MobileOperationSystemCheckerHelper.isAppleDevice())
445
+ return initializeFirestore(injector.get(FirebaseApp), {
446
+ ignoreUndefinedProperties: true,
447
+ });
439
448
  const firestore = initializeFirestore(injector.get(FirebaseApp), {
440
449
  experimentalForceLongPolling: true,
450
+ ignoreUndefinedProperties: true,
441
451
  localCache: memoryLocalCache(),
442
452
  });
443
453
  return firestore;
444
454
  }),
445
- provideStorage(() => getStorage()),
446
455
  ],
447
456
  providers: [
448
457
  {
449
458
  provide: 'FirestoreOptions',
450
459
  useFactory: (firestore, platformId) => ({
451
- firestore,
460
+ firestore: new ConnectFirestoreService(firestore),
452
461
  interceptors: {
453
462
  request: (request) => {
454
463
  if (isPlatformBrowser(platformId))
@@ -657,11 +666,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
657
666
  deps: ['FirestoreOptions', ProductFirestoreRepository],
658
667
  },
659
668
  {
660
- provide: 'FileUploaderService',
661
- useFactory: (storage, baseUrl) => {
662
- return new FirebaseFileUploaderService(storage, baseUrl);
669
+ provide: 'OrderBlockedRepository',
670
+ useFactory: (options) => {
671
+ return new OrderBlockedFirestoreRepository(options);
663
672
  },
664
- deps: [Storage, STORAGE_BASE_URL],
673
+ deps: ['FirestoreOptions'],
674
+ },
675
+ {
676
+ provide: 'LogRepository',
677
+ useFactory: (options) => {
678
+ return new LogFirestoreRepository(options);
679
+ },
680
+ deps: ['FirestoreOptions'],
665
681
  },
666
682
  ],
667
683
  }]
@@ -744,6 +760,17 @@ class AngularHasuraGraphQLModule {
744
760
  },
745
761
  deps: ['HasuraConfig'],
746
762
  },
763
+ {
764
+ provide: 'ProductStockNotificationRepository',
765
+ useExisting: ProductStockNotificationHasuraGraphQLRepository,
766
+ },
767
+ {
768
+ provide: ProductStockNotificationHasuraGraphQLRepository,
769
+ useFactory: (hasuraConfig) => {
770
+ return new ProductStockNotificationHasuraGraphQLRepository(hasuraConfig);
771
+ },
772
+ deps: ['HasuraConfig'],
773
+ },
747
774
  {
748
775
  provide: 'CategoryFilterRepository',
749
776
  useExisting: CategoryFilterHasuraGraphQLRepository,
@@ -786,12 +813,23 @@ class AngularHasuraGraphQLModule {
786
813
  provide: 'CategoryCollectionChildrenRepository',
787
814
  useExisting: CategoryCollectionChildrenHasuraGraphQLRepository,
788
815
  },
816
+ {
817
+ provide: CategoryProductHasuraGraphQLRepository,
818
+ useFactory: (options) => {
819
+ return new CategoryProductHasuraGraphQLRepository(options);
820
+ },
821
+ deps: ['HasuraConfig'],
822
+ },
823
+ {
824
+ provide: 'CategoryProductRepository',
825
+ useExisting: CategoryProductHasuraGraphQLRepository,
826
+ },
789
827
  {
790
828
  provide: WishlistHasuraGraphQLRepository,
791
- useFactory: (options, categoryFilterRepository) => {
792
- return new WishlistHasuraGraphQLRepository(options, categoryFilterRepository);
829
+ useFactory: (options, categoryProductRepository) => {
830
+ return new WishlistHasuraGraphQLRepository(options, categoryProductRepository);
793
831
  },
794
- deps: ['HasuraConfig', CategoryFilterHasuraGraphQLRepository],
832
+ deps: ['HasuraConfig', CategoryProductHasuraGraphQLRepository],
795
833
  },
796
834
  {
797
835
  provide: 'WishlistRepository',
@@ -870,6 +908,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
870
908
  },
871
909
  deps: ['HasuraConfig'],
872
910
  },
911
+ {
912
+ provide: 'ProductStockNotificationRepository',
913
+ useExisting: ProductStockNotificationHasuraGraphQLRepository,
914
+ },
915
+ {
916
+ provide: ProductStockNotificationHasuraGraphQLRepository,
917
+ useFactory: (hasuraConfig) => {
918
+ return new ProductStockNotificationHasuraGraphQLRepository(hasuraConfig);
919
+ },
920
+ deps: ['HasuraConfig'],
921
+ },
873
922
  {
874
923
  provide: 'CategoryFilterRepository',
875
924
  useExisting: CategoryFilterHasuraGraphQLRepository,
@@ -912,12 +961,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
912
961
  provide: 'CategoryCollectionChildrenRepository',
913
962
  useExisting: CategoryCollectionChildrenHasuraGraphQLRepository,
914
963
  },
964
+ {
965
+ provide: CategoryProductHasuraGraphQLRepository,
966
+ useFactory: (options) => {
967
+ return new CategoryProductHasuraGraphQLRepository(options);
968
+ },
969
+ deps: ['HasuraConfig'],
970
+ },
971
+ {
972
+ provide: 'CategoryProductRepository',
973
+ useExisting: CategoryProductHasuraGraphQLRepository,
974
+ },
915
975
  {
916
976
  provide: WishlistHasuraGraphQLRepository,
917
- useFactory: (options, categoryFilterRepository) => {
918
- return new WishlistHasuraGraphQLRepository(options, categoryFilterRepository);
977
+ useFactory: (options, categoryProductRepository) => {
978
+ return new WishlistHasuraGraphQLRepository(options, categoryProductRepository);
919
979
  },
920
- deps: ['HasuraConfig', CategoryFilterHasuraGraphQLRepository],
980
+ deps: ['HasuraConfig', CategoryProductHasuraGraphQLRepository],
921
981
  },
922
982
  {
923
983
  provide: 'WishlistRepository',
@@ -927,6 +987,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
927
987
  }]
928
988
  }] });
929
989
 
990
+ class AngularVertexSeachModule {
991
+ static initializeApp(options) {
992
+ return {
993
+ ngModule: AngularVertexSeachModule,
994
+ providers: [{ provide: VERTEX_CONFIG, useValue: options }],
995
+ };
996
+ }
997
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
998
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule }); }
999
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule, providers: [
1000
+ {
1001
+ provide: ProductsVertexSearch,
1002
+ useFactory: (configuration) => new ProductsVertexSearch(new VertexAxiosAdapter(configuration)),
1003
+ deps: [VERTEX_CONFIG],
1004
+ },
1005
+ ] }); }
1006
+ }
1007
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule, decorators: [{
1008
+ type: NgModule,
1009
+ args: [{
1010
+ providers: [
1011
+ {
1012
+ provide: ProductsVertexSearch,
1013
+ useFactory: (configuration) => new ProductsVertexSearch(new VertexAxiosAdapter(configuration)),
1014
+ deps: [VERTEX_CONFIG],
1015
+ },
1016
+ ],
1017
+ }]
1018
+ }] });
1019
+
1020
+ const STORAGE_BASE_URL = 'STORAGE_BASE_URL';
1021
+
1022
+ class CookieDataPersistence {
1023
+ get(key) {
1024
+ return of(cookie.get(key));
1025
+ }
1026
+ remove(key) {
1027
+ return of(cookie.remove(key));
1028
+ }
1029
+ set(key, value) {
1030
+ return from(cookie.set(key, value)).pipe(map(() => { }));
1031
+ }
1032
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CookieDataPersistence, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1033
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CookieDataPersistence }); }
1034
+ }
1035
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CookieDataPersistence, decorators: [{
1036
+ type: Injectable
1037
+ }] });
1038
+
930
1039
  class AuthService {
931
1040
  constructor(angularFireAuth, userRepository) {
932
1041
  this.angularFireAuth = angularFireAuth;
@@ -1007,11 +1116,11 @@ class CouponService {
1007
1116
  throw 'Limite de uso atingido';
1008
1117
  }
1009
1118
  if (!couponUseLimits.unlimited || couponUseLimits.limitedPerUser) {
1010
- const orders = await this.getOrdersWithCoupon(coupon);
1011
- if (!couponUseLimits.unlimited && couponUseLimits.total && orders.length >= couponUseLimits.total)
1119
+ const ordersCoupon = await this.getOrdersWithCoupon(coupon);
1120
+ if (!couponUseLimits.unlimited && couponUseLimits.total && ordersCoupon.length >= couponUseLimits.total)
1012
1121
  throw 'Limite de uso atingido.';
1013
1122
  if (couponUseLimits.limitedPerUser) {
1014
- const ordersWithUser = this.countOrdersWithUser(orders, checkout.user.email);
1123
+ const ordersWithUser = this.countOrdersWithUser(ordersCoupon, checkout.user.email);
1015
1124
  if (ordersWithUser > 0)
1016
1125
  throw 'Limite de uso por usuário atingido.';
1017
1126
  }
@@ -1020,8 +1129,12 @@ class CouponService {
1020
1129
  if (!hasProductCategories)
1021
1130
  throw 'Seu carrinho não possui produtos elegíveis para desconto.';
1022
1131
  const hasMinSubTotal = await this.hasMinSubTotal(coupon, checkout);
1023
- if (!hasMinSubTotal)
1024
- throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido`;
1132
+ if (!hasMinSubTotal) {
1133
+ if (coupon.productsCategories?.length) {
1134
+ 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.`;
1135
+ }
1136
+ throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido.`;
1137
+ }
1025
1138
  return coupon;
1026
1139
  }
1027
1140
  calcDiscountSubscription(coupon, checkout) {
@@ -1033,45 +1146,53 @@ class CouponService {
1033
1146
  return of(discount);
1034
1147
  }
1035
1148
  async calcDiscountShopping(coupon, checkout) {
1036
- let discount = 0;
1149
+ let discountInfo = null;
1037
1150
  if (checkout.user.isSubscriber && coupon.discount.subscriber.value) {
1038
- discount = await this.calcDiscountByType(coupon.discount.subscriber.type, coupon.discount.subscriber.value, coupon.productsCategories, checkout);
1151
+ discountInfo = await this.calcDiscountByType(coupon.discount.subscriber.type, coupon.discount.subscriber.value, coupon.productsCategories, checkout);
1039
1152
  }
1040
1153
  else {
1041
- discount = await this.calcDiscountByType(coupon.discount.non_subscriber.type, coupon.discount.non_subscriber.value, coupon.productsCategories, checkout);
1154
+ discountInfo = await this.calcDiscountByType(coupon.discount.non_subscriber.type, coupon.discount.non_subscriber.value, coupon.productsCategories, checkout);
1042
1155
  }
1043
- return discount;
1156
+ return { discount: discountInfo.discount, lineItems: discountInfo.lineItems };
1044
1157
  }
1045
1158
  async calcDiscountByType(type, value, categories, checkout) {
1046
1159
  let discount = 0;
1047
- let lineItensDiscount = await this.getLineItensEligebleForDiscount(categories, checkout);
1048
- const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
1160
+ if (type == CouponTypes.SHIPPING) {
1161
+ const subTotal = checkout.shipping.ShippingPrice;
1162
+ const discount = +(subTotal * ((value > 100 ? 100 : value) / 100)).toFixed(2);
1163
+ return { discount, lineItems: checkout.lineItems };
1164
+ }
1165
+ let lineItensElegibleForDiscount = await this.getLineItensEligebleForDiscount(categories, checkout);
1166
+ const subTotal = this.calcCheckoutSubtotal(lineItensElegibleForDiscount, checkout.user);
1049
1167
  if (type == CouponTypes.ABSOLUTE) {
1050
1168
  discount = value > subTotal ? subTotal : value;
1051
1169
  }
1052
1170
  else {
1053
- discount = subTotal * (value / 100);
1171
+ discount = +(subTotal * ((value > 100 ? 100 : value) / 100)).toFixed(2);
1054
1172
  }
1055
- return discount;
1173
+ const lineItems = this.calcLineItenDiscount(type, lineItensElegibleForDiscount, value, subTotal);
1174
+ return { discount, lineItems };
1056
1175
  }
1057
1176
  async hasMinSubTotal(coupon, checkout) {
1058
1177
  if (!coupon.minSubTotalValue)
1059
1178
  return true;
1060
1179
  let lineItensDiscount = await this.getLineItensEligebleForDiscount(coupon.productsCategories, checkout);
1061
- const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
1180
+ const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user);
1062
1181
  if (coupon.minSubTotalValue <= subTotal)
1063
1182
  return true;
1064
1183
  return false;
1065
1184
  }
1066
1185
  async hasProductCategories(coupon, checkout) {
1067
- if (!coupon.productsCategories || !coupon.productsCategories.length) {
1186
+ if (!coupon.productsCategories || !coupon.productsCategories?.length) {
1068
1187
  return true;
1069
1188
  }
1070
1189
  const couponCategories = await this.getCouponCategoriesId(coupon.productsCategories);
1071
- const hasCategories = checkout.lineItems?.filter((i) => {
1072
- if (!i.categories || !i.categories?.length)
1190
+ const hasCategories = checkout.lineItems?.filter((item) => {
1191
+ if (item.isGift)
1192
+ return false;
1193
+ if (!item.categories || !item.categories?.length)
1073
1194
  return true;
1074
- return i.categories.some((c) => couponCategories.some((cat) => cat == c));
1195
+ return item.categories.some((c) => couponCategories.some((cat) => cat == c));
1075
1196
  });
1076
1197
  return hasCategories.length ? true : false;
1077
1198
  }
@@ -1114,20 +1235,24 @@ class CouponService {
1114
1235
  let lineItensDiscount = [];
1115
1236
  const couponCategories = await this.getCouponCategoriesId(productsCategories);
1116
1237
  if (productsCategories && productsCategories.length) {
1117
- lineItensDiscount = checkout.lineItems?.filter((i) => {
1118
- if (i.categories?.length) {
1119
- return i.categories.some((c) => couponCategories.some((cat) => cat == c));
1238
+ lineItensDiscount = checkout.lineItems?.filter((item) => {
1239
+ if (item.isGift)
1240
+ return false;
1241
+ if (item.categories?.length) {
1242
+ return item.categories.some((c) => couponCategories.some((cat) => cat == c));
1120
1243
  }
1121
1244
  return true;
1122
1245
  });
1123
1246
  }
1124
1247
  else {
1125
- lineItensDiscount = checkout.lineItems;
1248
+ lineItensDiscount = checkout.lineItems.filter((item) => !item.isGift);
1126
1249
  }
1127
1250
  return lineItensDiscount;
1128
1251
  }
1129
- calcCheckoutSubtotal(lineItens, user, shop) {
1130
- return (lineItens?.reduce((acc, curr) => user?.isSubscriber && curr.price.subscriberPrice
1252
+ calcCheckoutSubtotal(lineItens, user) {
1253
+ return (lineItens
1254
+ ?.filter((item) => !item.isGift)
1255
+ .reduce((acc, curr) => user?.isSubscriber && curr.price.subscriberPrice
1131
1256
  ? acc + curr.price?.subscriberPrice * curr.quantity
1132
1257
  : acc + curr.pricePaid * curr.quantity, 0) || 0);
1133
1258
  }
@@ -1136,7 +1261,7 @@ class CouponService {
1136
1261
  .find({
1137
1262
  filters: {
1138
1263
  coupon: { id: coupon.id },
1139
- payment: { status: 'paid' },
1264
+ status: { operator: Where.NOTEQUALS, value: OrderStatus.CANCELADO },
1140
1265
  },
1141
1266
  })
1142
1267
  .then((result) => result.data);
@@ -1146,7 +1271,7 @@ class CouponService {
1146
1271
  .find({
1147
1272
  filters: {
1148
1273
  user: { email: { operator: Where.EQUALS, value: email } },
1149
- payment: { status: 'paid' },
1274
+ status: { operator: Where.NOTEQUALS, value: OrderStatus.CANCELADO },
1150
1275
  },
1151
1276
  })
1152
1277
  .then((result) => result.data);
@@ -1157,13 +1282,42 @@ class CouponService {
1157
1282
  getCouponUseLimits(coupon, checkoutType, user) {
1158
1283
  let couponUseLimits;
1159
1284
  if (checkoutType == CheckoutTypes.ECOMMERCE || checkoutType == CheckoutTypes.ALL) {
1160
- couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
1285
+ if (coupon.exclusivityType.length === 1 &&
1286
+ (coupon.exclusivityType.at(0) === Exclusivities.SPECIFIC_USER ||
1287
+ coupon.exclusivityType.at(0) === Exclusivities.COLLABORATORS))
1288
+ couponUseLimits = coupon.useLimits.non_subscriber;
1289
+ else
1290
+ couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
1161
1291
  }
1162
1292
  else {
1163
1293
  couponUseLimits = coupon.useLimits.subscription;
1164
1294
  }
1165
1295
  return couponUseLimits;
1166
1296
  }
1297
+ calcLineItenDiscount(type, lineItems, couponDiscount, subTotal) {
1298
+ let lineItemsDiscount = [];
1299
+ if (type === CouponTypes.ABSOLUTE) {
1300
+ const couponDiscountMax = couponDiscount > subTotal ? subTotal : couponDiscount;
1301
+ lineItemsDiscount = lineItems.map((item) => {
1302
+ const totalItemPercentage = item.pricePaid / subTotal;
1303
+ const discountItem = couponDiscountMax * totalItemPercentage;
1304
+ return {
1305
+ ...item,
1306
+ discount: Number(discountItem.toFixed(2)),
1307
+ };
1308
+ });
1309
+ }
1310
+ else {
1311
+ lineItemsDiscount = lineItems.map((item) => {
1312
+ const discountItem = item.pricePaid * (couponDiscount / 100);
1313
+ return {
1314
+ ...item,
1315
+ discount: Number(discountItem.toFixed(2)),
1316
+ };
1317
+ });
1318
+ }
1319
+ return lineItemsDiscount;
1320
+ }
1167
1321
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, deps: [{ token: 'CouponRepository' }, { token: DEFAULT_SHOP }, { token: 'OrderRepository' }, { token: 'CategoryRepository' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1168
1322
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, providedIn: 'root' }); }
1169
1323
  }
@@ -1187,18 +1341,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1187
1341
  }] }] });
1188
1342
 
1189
1343
  class CheckoutService {
1190
- constructor(couponService, checkoutRepository, orderRepository, userRepository, defaultShop) {
1344
+ constructor(couponService, checkoutRepository, userRepository, defaultShop, dataPersistence) {
1191
1345
  this.couponService = couponService;
1192
1346
  this.checkoutRepository = checkoutRepository;
1193
- this.orderRepository = orderRepository;
1194
1347
  this.userRepository = userRepository;
1195
1348
  this.defaultShop = defaultShop;
1349
+ this.dataPersistence = dataPersistence;
1196
1350
  }
1197
1351
  getCheckout(checkoutData) {
1198
- const checkoutId = cookie.get('checkoutId');
1199
- if (!isNil(checkoutId))
1200
- return from(this.checkoutRepository.get({ id: checkoutId }));
1201
- return from(this.createCheckout(checkoutData));
1352
+ return this.dataPersistence
1353
+ .get('checkoutId')
1354
+ .pipe(concatMap((id) => (!isNil(id) ? this.checkoutRepository.get({ id }) : this.createCheckout(checkoutData))));
1202
1355
  }
1203
1356
  getUserByCheckout(checkoutId) {
1204
1357
  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'))));
@@ -1210,8 +1363,7 @@ class CheckoutService {
1210
1363
  return from(this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, user: checkout.user })));
1211
1364
  }
1212
1365
  clearCheckoutFromSession() {
1213
- cookie.remove('checkoutId');
1214
- return of();
1366
+ return this.dataPersistence.remove('checkoutId');
1215
1367
  }
1216
1368
  calcDiscount(coupon) {
1217
1369
  return this.getCheckout().pipe(concatMap(async (checkout) => await this.couponService.calcDiscountShopping(coupon, checkout)));
@@ -1225,10 +1377,10 @@ class CheckoutService {
1225
1377
  ...Checkout.toInstance(pick(checkoutData, ['user', 'shop'])).toPlain(),
1226
1378
  shop: checkoutData?.shop || this.defaultShop,
1227
1379
  });
1228
- cookie.set('checkoutId', checkout.id);
1380
+ await this.dataPersistence.set('checkoutId', checkout.id).toPromise();
1229
1381
  return checkout;
1230
1382
  }
1231
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutService, deps: [{ token: CouponService }, { token: 'CheckoutRepository' }, { token: 'OrderRepository' }, { token: 'UserRepository' }, { token: DEFAULT_SHOP }], target: i0.ɵɵFactoryTarget.Injectable }); }
1383
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutService, deps: [{ token: CouponService }, { token: 'CheckoutRepository' }, { token: 'UserRepository' }, { token: DEFAULT_SHOP }, { token: PERSISTENCE_PROVIDER }], target: i0.ɵɵFactoryTarget.Injectable }); }
1232
1384
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutService }); }
1233
1385
  }
1234
1386
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutService, decorators: [{
@@ -1236,15 +1388,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1236
1388
  }], ctorParameters: () => [{ type: CouponService }, { type: undefined, decorators: [{
1237
1389
  type: Inject,
1238
1390
  args: ['CheckoutRepository']
1239
- }] }, { type: undefined, decorators: [{
1240
- type: Inject,
1241
- args: ['OrderRepository']
1242
1391
  }] }, { type: undefined, decorators: [{
1243
1392
  type: Inject,
1244
1393
  args: ['UserRepository']
1245
1394
  }] }, { type: i1$2.Shops, decorators: [{
1246
1395
  type: Inject,
1247
1396
  args: [DEFAULT_SHOP]
1397
+ }] }, { type: undefined, decorators: [{
1398
+ type: Inject,
1399
+ args: [PERSISTENCE_PROVIDER]
1248
1400
  }] }] });
1249
1401
 
1250
1402
  class CartService {
@@ -1260,9 +1412,11 @@ class CartService {
1260
1412
  this.updateLineItemInCart = (lineItem, quantity, checkout) => (isNil(checkout) ? this.checkoutService.getCheckout() : of(checkout)).pipe(concatMap((checkoutLoaded) => {
1261
1413
  const items = [];
1262
1414
  const index = checkoutLoaded.lineItems?.map((checkoutItem) => checkoutItem.id).indexOf(lineItem.id);
1415
+ const isGift = checkoutLoaded.lineItems?.[index]?.isGift;
1263
1416
  if (index > -1) {
1264
1417
  checkoutLoaded.lineItems[index].quantity += quantity;
1265
- checkoutLoaded.lineItems[index].pricePaid = lineItem.pricePaid;
1418
+ checkoutLoaded.lineItems[index].pricePaid = isGift ? 0 : lineItem.pricePaid;
1419
+ checkoutLoaded.lineItems[index].price = lineItem.price;
1266
1420
  }
1267
1421
  else
1268
1422
  checkoutLoaded.lineItems = items.concat(checkoutLoaded.lineItems ? checkoutLoaded.lineItems.concat([lineItem]) : [lineItem]);
@@ -1280,17 +1434,20 @@ class CartService {
1280
1434
  this.buildLineItem = async ({ checkout, item, quantity, }) => {
1281
1435
  const product = await this.getProductData(item.id);
1282
1436
  item.quantity = item?.quantity || checkout?.lineItems?.find((lineItem) => lineItem.id === item.id)?.quantity || 0;
1283
- if (this.checkMaxStock(item, quantity || 0))
1284
- throw new Error('Desculpe! Temos apenas ' + item.stock?.quantity + ' em estoque.');
1437
+ if (this.checkMaxStock(product.stock.quantity, item.quantity || 0, quantity || 0))
1438
+ throw new Error('Desculpe! Temos apenas ' + product.stock?.quantity + ' em estoque.');
1285
1439
  const image = item.image || item.images?.shift();
1286
- const { id, name, EAN, slug, stock, price, weight, sku, type } = item;
1287
- const isGift = item.isGift || null;
1288
- const pricePaid = this.getProductPrice({
1289
- product: item,
1290
- shop: checkout.shop || this.defaultShop,
1291
- isSubscriber: checkout.user?.isSubscriber,
1292
- });
1440
+ const { id, name, EAN, slug, weight, sku, type } = item;
1441
+ const isGift = item?.isGift || null;
1442
+ const pricePaid = isGift
1443
+ ? 0
1444
+ : this.getProductPrice({
1445
+ product: LineItem.toInstance(product),
1446
+ shop: checkout.shop || this.defaultShop,
1447
+ isSubscriber: checkout.user?.isSubscriber,
1448
+ });
1293
1449
  RoundProductPricesHelper.roundProductPrices(item);
1450
+ RoundProductPricesHelper.roundProductPrices(product);
1294
1451
  return {
1295
1452
  checkout,
1296
1453
  lineItem: LineItem.toInstance({
@@ -1300,16 +1457,19 @@ class CartService {
1300
1457
  brand: product.brand,
1301
1458
  slug: slug ?? product.slug,
1302
1459
  sku: sku ?? product.sku,
1303
- stock,
1304
- price: this.roundPrice(price),
1460
+ stock: product.stock,
1461
+ price: this.roundPrice(product.price),
1305
1462
  image,
1306
1463
  weight: weight ?? product.weight,
1307
1464
  quantity: (item.quantity || 0) + (quantity || 0),
1308
1465
  pricePaid,
1309
- categories: product.categories ?? [],
1466
+ discount: 0,
1467
+ categories: product.categories || product.category?.id ? [product.category?.id, ...product.categories] : [],
1468
+ category: product.category,
1310
1469
  isGift: isGift ?? null,
1311
- costPrice: product.costPrice ?? 0,
1470
+ costPrice: isGift ? 0 : product.costPrice ?? 0,
1312
1471
  type,
1472
+ label: product.label,
1313
1473
  }),
1314
1474
  };
1315
1475
  };
@@ -1321,10 +1481,10 @@ class CartService {
1321
1481
  ? Number(info.subscriberPrice.toFixed(2))
1322
1482
  : Number(info.price.toFixed(2));
1323
1483
  };
1324
- this.checkMaxStock = (item, quantity) => {
1325
- const maxStock = item.stock?.quantity || 0;
1326
- const currentItemAmount = item.quantity || 0;
1327
- return currentItemAmount + quantity > maxStock;
1484
+ this.checkMaxStock = (currentStock, currentItemQtd, quantityToAdd) => {
1485
+ const maxStock = currentStock || 0;
1486
+ const currentItemAmount = currentItemQtd || 0;
1487
+ return currentItemAmount + quantityToAdd > maxStock;
1328
1488
  };
1329
1489
  }
1330
1490
  addItem(item, quantity = 1) {
@@ -1357,14 +1517,14 @@ class CartService {
1357
1517
  }), concatMap((checkout) => this.checkoutService.updateCheckoutLineItems(checkout)), map((checkout) => this.generateCartObject(checkout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1358
1518
  }
1359
1519
  updateUserCart(user) {
1360
- return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.checkoutService.updateCheckoutUser(Checkout.toInstance({ ...checkout.toPlain(), user }))), concatMap(async (checkout) => this.checkoutService
1520
+ return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.checkoutService.updateCheckoutUser(Checkout.toInstance({ ...checkout.toPlain(), user }))), concatMap(async (checkout) => await this.checkoutService
1361
1521
  .updateCheckoutLineItems(Checkout.toInstance({
1362
1522
  ...checkout.toPlain(),
1363
1523
  lineItems: checkout.lineItems?.length
1364
1524
  ? await Promise.all(checkout.lineItems?.map(async (item) => (await this.buildLineItem({ checkout, item })).lineItem))
1365
1525
  : [],
1366
1526
  }))
1367
- .toPromise()), map((checkout) => this.generateCartObject(checkout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1527
+ .toPromise()), map((checkout) => this.generateCartObject(checkout.lineItems)), tap((cart) => (this.user = user)), tap((cart) => this.cartSubject.next(cart)));
1368
1528
  }
1369
1529
  clearCart() {
1370
1530
  return this.checkoutService.getCheckout().pipe(map((checkout) => {
@@ -1409,15 +1569,13 @@ class CartService {
1409
1569
  const notGiftItems = checkout.lineItems ? checkout.lineItems.filter((item) => !item.isGift) : [];
1410
1570
  if (!notGiftItems.length)
1411
1571
  return { ...checkout, lineItems: [] };
1412
- const cartTotal = notGiftItems.reduce((a, b) => a + b.pricePaid * b.quantity, 0);
1413
1572
  const campaigns = await this.buy2WinRepository
1414
1573
  .find({
1415
1574
  filters: {
1416
1575
  active: { operator: Where.EQUALS, value: true },
1417
- shop: { operator: Where.EQUALS, value: this.defaultShop },
1418
1576
  },
1419
1577
  })
1420
- .then((data) => data.data);
1578
+ .then((data) => data.data.filter((campaign) => campaign.shop === Shops.ALL || campaign.shop === this.defaultShop));
1421
1579
  if (!campaigns.length)
1422
1580
  return { ...checkout, lineItems: notGiftItems };
1423
1581
  const elegibleCampaigns = [];
@@ -1433,22 +1591,27 @@ class CartService {
1433
1591
  categoriesCampaingFullTree.push(id, ...children.map((c) => c.id.toString()));
1434
1592
  }
1435
1593
  const categoriesCampaingTree = [...new Set(categoriesCampaingFullTree)];
1436
- const filterProductsCategories = checkout.lineItems.filter((l) => {
1594
+ const filterProductsCategories = notGiftItems.filter((l) => {
1437
1595
  if (!l.categories || !l.categories?.length)
1438
1596
  return true;
1439
1597
  return l.categories.some((c) => categoriesCampaingTree.some((cat) => cat == c));
1440
1598
  });
1441
1599
  if (filterProductsCategories.length) {
1442
- const cartTotalCategories = filterProductsCategories.reduce((a, b) => a + b.pricePaid * b.quantity, 0);
1443
- if (cartTotalCategories >= campaign.cartValueMin)
1600
+ const cartValuelWithCategories = filterProductsCategories.reduce((a, b) => a + b.pricePaid * b.quantity, 0);
1601
+ const cartItensQuantityWithCategories = filterProductsCategories.reduce((a, b) => a + b.quantity, 0);
1602
+ const hasMinValue = campaign.cartValueMin && cartValuelWithCategories >= campaign.cartValueMin;
1603
+ const hasMinQuantity = campaign.cartItensQuantityMin && cartItensQuantityWithCategories >= campaign.cartItensQuantityMin;
1604
+ if (hasMinQuantity || hasMinValue)
1444
1605
  elegibleCampaigns.push(campaign);
1445
1606
  }
1446
1607
  }
1447
1608
  else {
1448
- if (campaign.cartValue && campaign.cartValue > 0) {
1449
- if (campaign.cartValue <= cartTotal)
1450
- elegibleCampaigns.push(campaign);
1451
- }
1609
+ const cartTotal = notGiftItems.reduce((a, b) => a + b.pricePaid * b.quantity, 0);
1610
+ const cartItensQuantity = notGiftItems.reduce((a, b) => a + b.quantity, 0);
1611
+ const hasMinValue = campaign.cartValue && campaign.cartValue > 0 && campaign.cartValue <= cartTotal;
1612
+ const hasMinQuantity = campaign.cartItensQuantityMin && cartItensQuantity >= campaign.cartItensQuantityMin;
1613
+ if (hasMinQuantity || hasMinValue)
1614
+ elegibleCampaigns.push(campaign);
1452
1615
  }
1453
1616
  }
1454
1617
  if (!elegibleCampaigns.length)
@@ -1475,11 +1638,12 @@ class CartService {
1475
1638
  }
1476
1639
  giftToLineItems(items) {
1477
1640
  return items.map((item) => {
1478
- const { brand, categories, id, name, price, sku, slug, stock, weight, EAN } = item;
1641
+ const { brand, categories, category, id, name, price, sku, slug, stock, weight, EAN } = item;
1479
1642
  const image = item?.miniatures?.length ? item.miniatures[0] : item.images[0];
1480
1643
  return LineItem.toInstance({
1481
1644
  brand,
1482
1645
  categories,
1646
+ category,
1483
1647
  id: id.toString(),
1484
1648
  name,
1485
1649
  price,
@@ -1541,9 +1705,11 @@ class NewCategoryStructureAdapter {
1541
1705
  .then((categories) => categories.map((category) => category.id.toString()));
1542
1706
  }
1543
1707
  async getCategory(category) {
1544
- return isNil(category.isCollection) || (category.isCollection && !category.products?.length)
1545
- ? this.categoryRepository.get({ id: category.id })
1546
- : category;
1708
+ const collectionCategory = category.isCollection ||
1709
+ (isNil(category.isCollection) && !category.products?.length) ||
1710
+ category.isWishlist ||
1711
+ category.brandCategory;
1712
+ return collectionCategory ? this.categoryRepository.get({ id: category.id }) : category;
1547
1713
  }
1548
1714
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NewCategoryStructureAdapter, deps: [{ token: 'CategoryRepository' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1549
1715
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NewCategoryStructureAdapter }); }
@@ -1576,13 +1742,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1576
1742
  }] }] });
1577
1743
 
1578
1744
  class CatalogService {
1579
- constructor(productRepository, categoryRepository, categoryStructureAdapter, shop, productIndex) {
1745
+ constructor(productRepository, productStockNotificationRepository, categoryRepository, categoryStructureAdapter, shop, productSearch) {
1580
1746
  this.productRepository = productRepository;
1747
+ this.productStockNotificationRepository = productStockNotificationRepository;
1581
1748
  this.categoryRepository = categoryRepository;
1582
1749
  this.categoryStructureAdapter = categoryStructureAdapter;
1583
1750
  this.shop = shop;
1584
- this.productIndex = productIndex;
1751
+ this.productSearch = productSearch;
1585
1752
  this.productsByTerm = {};
1753
+ this.brandsList = {};
1586
1754
  this.buildFilterQuery = ({ clubDiscount, brands, prices, gender, tags, rate, customOptions, }) => {
1587
1755
  const filters = {};
1588
1756
  if (clubDiscount?.length)
@@ -1593,7 +1761,7 @@ class CatalogService {
1593
1761
  filters.gender = { operator: Where.IN, value: gender };
1594
1762
  if (prices?.min || prices?.max)
1595
1763
  set(filters, prices.subscriberPrice ? 'price.subscriberPrice' : 'price.price', [
1596
- ...(prices.min ? [{ operator: Where.GTE, value: Math.round(prices.min) }] : []),
1764
+ ...(prices.min ? [{ operator: Where.GTE, value: Math.floor(prices.min) }] : []),
1597
1765
  ...(prices.max ? [{ operator: Where.LTE, value: Math.ceil(prices.max) }] : []),
1598
1766
  ]);
1599
1767
  if (rate)
@@ -1608,17 +1776,22 @@ class CatalogService {
1608
1776
  if (!sort || sort === 'most-relevant')
1609
1777
  return {};
1610
1778
  if (sort === 'best-sellers')
1611
- return { shoppingCount: 'desc' };
1779
+ return {
1780
+ shoppingCount: 'desc',
1781
+ rate: 'desc',
1782
+ stock: 'desc',
1783
+ name: 'asc',
1784
+ };
1612
1785
  if (sort === 'biggest-price')
1613
- return { subscriberPrice: 'desc' };
1786
+ return { subscriberPrice: 'desc', rate: 'desc', shoppingCount: 'desc' };
1614
1787
  if (sort === 'lowest-price')
1615
- return { subscriberPrice: 'asc' };
1788
+ return { subscriberPrice: 'asc', rate: 'desc', shoppingCount: 'desc' };
1616
1789
  if (sort === 'best-rating')
1617
- return { rate: 'desc' };
1790
+ return { rate: 'desc', shoppingCount: 'desc', stock: 'desc', name: 'asc' };
1618
1791
  if (sort === 'news')
1619
1792
  return { createdAt: 'desc' };
1620
1793
  if (sort === 'biggest-discount')
1621
- return { subscriberDiscountPercentage: 'desc' };
1794
+ return { subscriberDiscountPercentage: 'desc', rate: 'desc', shoppingCount: 'desc' };
1622
1795
  };
1623
1796
  this.buildLimitQuery = (options) => {
1624
1797
  const limit = options?.perPage || 20;
@@ -1630,6 +1803,15 @@ class CatalogService {
1630
1803
  this.hasProfile = (options) => 'profile' in options;
1631
1804
  this.hasTerm = (options) => 'term' in options;
1632
1805
  this.hasCategory = (options) => 'category' in options;
1806
+ this.buildIndexBrands = (options) => {
1807
+ if (this.hasCategory(options))
1808
+ return `category-${options.category.id}`;
1809
+ if (this.hasTerm(options))
1810
+ return `term-${options.term}`;
1811
+ if (this.hasProfile(options))
1812
+ return `profile-${options.profile.join(',')}`;
1813
+ return '';
1814
+ };
1633
1815
  }
1634
1816
  async fetchProducts(options) {
1635
1817
  const limits = this.buildLimitQuery(options);
@@ -1639,29 +1821,42 @@ class CatalogService {
1639
1821
  throw new InvalidArgumentError(`It couldn't filled tags when profile is given`);
1640
1822
  if (this.hasTerm(options) && options.filters?.customOptions)
1641
1823
  throw new InvalidArgumentError(`It couldn't filled customOptions when term is given`);
1642
- return await this.findCatalog(options, limits).then(({ data, count: total, maximum, minimal, distinct }) => ({
1643
- products: { data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)), total },
1644
- pages: Math.ceil(total / limits.limit),
1645
- prices: {
1646
- price: { min: +minimal?.price?.price?.toFixed(2), max: +maximum?.price?.price?.toFixed(2) },
1647
- subscriberPrice: {
1648
- min: +minimal?.price?.subscriberPrice?.toFixed(2),
1649
- max: +maximum?.price?.subscriberPrice?.toFixed(2),
1824
+ return await this.findCatalog(options, limits).then(async ({ data, count: total, maximum, minimal, distinct }) => {
1825
+ await this.setBrandsList(options, distinct?.brand);
1826
+ return {
1827
+ products: { data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)), total },
1828
+ pages: Math.ceil(total / limits.limit),
1829
+ prices: {
1830
+ price: { min: +minimal?.price?.price?.toFixed(2), max: +maximum?.price?.price?.toFixed(2) },
1831
+ subscriberPrice: {
1832
+ min: +minimal?.price?.subscriberPrice?.toFixed(2),
1833
+ max: +maximum?.price?.subscriberPrice?.toFixed(2),
1834
+ },
1650
1835
  },
1651
- },
1652
- brands: distinct?.brand,
1653
- }));
1836
+ brands: this.brandsList[this.buildIndexBrands(options)],
1837
+ };
1838
+ });
1839
+ }
1840
+ async addCustomerToStockNotification(shop, productId, name, email) {
1841
+ return this.productStockNotificationRepository.addCustomerEmail(shop, productId, name, email);
1654
1842
  }
1655
1843
  async findCatalog(options, limits) {
1656
1844
  if (this.hasTerm(options) && options.sort === 'most-relevant') {
1657
- const productsIds = await this.findCatalogIdsByElasticSearch(options.term);
1658
- return this.findCatalogAndSortByMostRevelant(productsIds, options, limits);
1845
+ const productsIds = await this.findCatalogIdsBySearch(options.term);
1846
+ return this.findCatalogAndSortByMostRevelantByTerm(productsIds, options, limits);
1659
1847
  }
1660
1848
  if (this.hasCategory(options) && options.sort === 'most-relevant') {
1661
- const productsIds = options.category.products?.length
1662
- ? options.category.products
1663
- : await this.categoryRepository.get({ id: options.category.id }).then((categoryFound) => categoryFound.products);
1664
- return this.findCatalogAndSortByMostRevelant(productsIds, options, limits);
1849
+ const mostRelevant = options.category.isWishlist ? [] : options.category.getMostRelevantByShop(this.shop);
1850
+ const productsIds = await this.productRepository
1851
+ .findCatalog({
1852
+ fields: ['id'],
1853
+ filters: {
1854
+ ...(await this.buildMainFilter(options)),
1855
+ ...this.buildFilterQuery(options?.filters || {}),
1856
+ },
1857
+ })
1858
+ .then((products) => products.data.map((product) => product.id));
1859
+ return this.findCatalogAndSortByMostRevelant(mostRelevant, productsIds, options, limits);
1665
1860
  }
1666
1861
  const repoParams = {
1667
1862
  filters: {
@@ -1673,7 +1868,9 @@ class CatalogService {
1673
1868
  options: {
1674
1869
  minimal: ['price'],
1675
1870
  maximum: ['price'],
1676
- ...(!this.hasCategory(options) ? { distinct: ['brand'] } : {}),
1871
+ ...(!this.brandsList[this.buildIndexBrands(options)] && isEmpty(options.filters?.brands)
1872
+ ? { distinct: ['brand'] }
1873
+ : {}),
1677
1874
  },
1678
1875
  };
1679
1876
  if (['biggest-price', 'lowest-price', 'biggest-discount', 'best-rating'].includes(options.sort))
@@ -1686,27 +1883,72 @@ class CatalogService {
1686
1883
  if (profile)
1687
1884
  return { tags: { operator: Where.LIKE, value: profile } };
1688
1885
  if (term)
1689
- return this.productIndex
1690
- .search(term, 999, this.shop)
1691
- .then((data) => ({ id: { operator: Where.IN, value: data.hits.map(({ _source }) => _source.id) } }));
1886
+ return this.productSearch
1887
+ .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
1888
+ .then((data) => ({ id: { operator: Where.IN, value: data.map((_source) => _source.id) } }));
1889
+ }
1890
+ async findCatalogAndSortByMostRevelant(mostRelevants, productIds, options, limits) {
1891
+ const brandsList = this.brandsList[this.buildIndexBrands(options)];
1892
+ const mostRelevantProductsIds = [...new Set(mostRelevants.concat(productIds))];
1893
+ const totalResult = await this.productRepository.findCatalog({
1894
+ filters: {
1895
+ id: { operator: Where.IN, value: mostRelevantProductsIds },
1896
+ ...this.buildFilterQuery(options?.filters || {}),
1897
+ },
1898
+ orderBy: this.buildSortQuery('best-sellers'),
1899
+ options: {
1900
+ minimal: ['price'],
1901
+ maximum: ['price'],
1902
+ ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
1903
+ },
1904
+ }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
1905
+ const mostRelevantWithouyStock = totalResult.data.filter((product) => mostRelevants.includes(product.id) && product.stock.quantity <= 0);
1906
+ const firstProducts = totalResult.data
1907
+ .filter((product) => mostRelevants.includes(product.id) && product.stock.quantity > 0)
1908
+ .sort((a, b) => mostRelevants.indexOf(a.id) - mostRelevants.indexOf(b.id));
1909
+ const lastProducts = totalResult.data
1910
+ .filter((product) => !mostRelevants.includes(product.id))
1911
+ .concat(mostRelevantWithouyStock);
1912
+ const categoryMostRelevants = firstProducts.concat(lastProducts);
1913
+ const resultFinal = categoryMostRelevants.slice(limits.offset, limits.offset + limits.limit);
1914
+ await this.setBrandsList(options, totalResult.distinct?.brand);
1915
+ return {
1916
+ data: resultFinal,
1917
+ count: totalResult.count,
1918
+ maximum: totalResult.maximum,
1919
+ minimal: totalResult.minimal,
1920
+ distinct: {
1921
+ ...totalResult.distinct,
1922
+ brand: this.brandsList[this.buildIndexBrands(options)],
1923
+ },
1924
+ };
1692
1925
  }
1693
- async findCatalogAndSortByMostRevelant(productIds, options, limits) {
1926
+ async findCatalogAndSortByMostRevelantByTerm(productIds, options, limits) {
1927
+ const brandsList = this.brandsList[this.buildIndexBrands(options)];
1694
1928
  const totalResult = await this.productRepository.findCatalog({
1695
- fields: ['id', 'stock'],
1929
+ fields: ['id', 'stock', 'gender'],
1696
1930
  filters: {
1697
1931
  id: { operator: Where.IN, value: productIds },
1932
+ published: { operator: Where.EQUALS, value: true },
1698
1933
  ...this.buildFilterQuery(options?.filters || {}),
1699
1934
  },
1700
1935
  options: {
1701
1936
  minimal: ['price'],
1702
1937
  maximum: ['price'],
1703
- distinct: ['brand'],
1938
+ ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
1704
1939
  },
1705
1940
  }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
1941
+ const defaultGender = options?.filters?.gender
1942
+ ? options?.filters?.gender.at(0)
1943
+ : this.shop === Shops.GLAMSHOP
1944
+ ? 'female'
1945
+ : 'male';
1706
1946
  const stockData = totalResult.data.filter((product) => product.stock.quantity > 0);
1707
1947
  const stockOut = totalResult.data.filter((product) => product.stock.quantity <= 0);
1708
- const productIdsStock = productIds.filter((product) => stockData.some((result) => result.id == product));
1709
- const productIdsStockOut = productIds.filter((product) => stockOut.some((result) => result.id == product));
1948
+ const productIdsStockGender = productIds.filter((product) => stockData.some((result) => result.id === product && (result.gender?.includes(defaultGender) || result.gender?.includes('unisex'))));
1949
+ const productIdsStockNotGender = productIds.filter((product) => stockData.some((result) => result.id === product && !result.gender?.includes(defaultGender) && !result.gender?.includes('unisex')));
1950
+ const productIdsStock = productIdsStockGender.concat(productIdsStockNotGender);
1951
+ const productIdsStockOut = productIds.filter((product) => stockOut.some((result) => result.id === product));
1710
1952
  const limitedProductId = productIdsStock
1711
1953
  .concat(productIdsStockOut)
1712
1954
  .slice(limits.offset, limits.offset + limits.limit);
@@ -1716,27 +1958,55 @@ class CatalogService {
1716
1958
  id: { operator: Where.IN, value: orderedId },
1717
1959
  },
1718
1960
  });
1961
+ await this.setBrandsList(options, totalResult.distinct?.brand);
1719
1962
  return {
1720
1963
  data: limitedProductId.map((id) => productResult.data.find((product) => product.id === id)).filter(Boolean),
1721
1964
  count: totalResult.count,
1722
1965
  maximum: totalResult.maximum,
1723
1966
  minimal: totalResult.minimal,
1724
- distinct: totalResult.distinct,
1967
+ distinct: {
1968
+ ...totalResult.distinct,
1969
+ brand: this.brandsList[this.buildIndexBrands(options)],
1970
+ },
1725
1971
  };
1726
1972
  }
1727
- async findCatalogIdsByElasticSearch(term) {
1973
+ async findCatalogIdsBySearch(term, preview = false) {
1728
1974
  if (this.productsByTerm[term])
1729
1975
  return this.productsByTerm[term];
1730
- return (this.productsByTerm[term] = await this.productIndex
1731
- .search(term, 999, this.shop)
1732
- .then(({ hits: products }) => {
1733
- const withStock = products.filter(({ _source }) => _source.stock.quantity > 0);
1734
- const withOutStock = products.filter(({ _source }) => _source.stock.quantity <= 0);
1735
- const sorted = [...withStock, ...withOutStock];
1736
- return [...new Set(sorted.map(({ _source }) => _source.id))];
1737
- }));
1976
+ return (this.productsByTerm[term] = await this.productSearch
1977
+ .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
1978
+ .then((products) => [...new Set(products.map((product) => product.id))]));
1979
+ }
1980
+ async fetchBrandsOnly(options, productIds = []) {
1981
+ return this.productRepository
1982
+ .findCatalog({
1983
+ fields: ['id'],
1984
+ filters: {
1985
+ ...(!isEmpty(productIds) ? { id: { operator: Where.IN, value: productIds } } : {}),
1986
+ published: { operator: Where.EQUALS, value: true },
1987
+ ...this.buildFilterQuery(options?.filters || {}),
1988
+ },
1989
+ options: {
1990
+ distinct: ['brand'],
1991
+ },
1992
+ }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female')
1993
+ .then((result) => {
1994
+ return result.distinct.brand;
1995
+ });
1738
1996
  }
1739
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService, deps: [{ token: 'ProductRepository' }, { token: 'CategoryRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }, { token: i1$2.ProductsIndex }], target: i0.ɵɵFactoryTarget.Injectable }); }
1997
+ async setBrandsList(options, brands) {
1998
+ const filterBrands = options.filters?.brands;
1999
+ if (isEmpty(brands))
2000
+ delete options.filters?.brands;
2001
+ this.brandsList[this.buildIndexBrands(options)] =
2002
+ this.brandsList[this.buildIndexBrands(options)] || brands || (await this.fetchBrandsOnly(options));
2003
+ this.brandsList[this.buildIndexBrands(options)] = this.brandsList[this.buildIndexBrands(options)].filter(Boolean);
2004
+ options.filters = {
2005
+ ...options.filters,
2006
+ brands: filterBrands,
2007
+ };
2008
+ }
2009
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService, deps: [{ token: 'ProductRepository' }, { token: 'ProductStockNotificationRepository' }, { token: 'CategoryRepository' }, { token: CATEGORY_STRUCTURE }, { token: DEFAULT_SHOP }, { token: 'ProductSearch' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1740
2010
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService }); }
1741
2011
  }
1742
2012
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService, decorators: [{
@@ -1744,6 +2014,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1744
2014
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1745
2015
  type: Inject,
1746
2016
  args: ['ProductRepository']
2017
+ }] }, { type: undefined, decorators: [{
2018
+ type: Inject,
2019
+ args: ['ProductStockNotificationRepository']
1747
2020
  }] }, { type: undefined, decorators: [{
1748
2021
  type: Inject,
1749
2022
  args: ['CategoryRepository']
@@ -1753,7 +2026,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1753
2026
  }] }, { type: i1$2.Shops, decorators: [{
1754
2027
  type: Inject,
1755
2028
  args: [DEFAULT_SHOP]
1756
- }] }, { type: i1$2.ProductsIndex }] });
2029
+ }] }, { type: undefined, decorators: [{
2030
+ type: Inject,
2031
+ args: ['ProductSearch']
2032
+ }] }] });
1757
2033
 
1758
2034
  class CategoryService {
1759
2035
  constructor(productRepository, categoryRepository, categoryFilterRepository, categoryStructureAdapter, shop) {
@@ -1763,15 +2039,15 @@ class CategoryService {
1763
2039
  this.categoryStructureAdapter = categoryStructureAdapter;
1764
2040
  this.shop = shop;
1765
2041
  }
1766
- async fetchBrands(category, mainGender) {
2042
+ async fetchBrands(category, options) {
1767
2043
  const brands = await this.productRepository
1768
2044
  .findCatalog({
1769
2045
  filters: await this.categoryStructureAdapter.buildProductFilterByCategory(category),
1770
2046
  fields: ['brand'],
1771
- }, mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female')
2047
+ }, options?.mainGender ? options?.mainGender : this.shop === Shops.MENSMARKET ? 'male' : 'female')
1772
2048
  .then(({ data }) => Object.keys(data.map((product) => product.brand).reduce((brands, brand) => ({ ...brands, [brand]: true }), {})));
1773
2049
  return this.categoryRepository
1774
- .find({ filters: { brandCategory: true, shop: this.shop }, orderBy: { name: 'asc' } })
2050
+ .find({ filters: { brandCategory: true, shop: options?.shop || this.shop }, orderBy: { name: 'asc' } })
1775
2051
  .then(({ data }) => data.filter((category) => brands.includes(category.conditions.brand)));
1776
2052
  }
1777
2053
  async fetchFilterOptions(category) {
@@ -1820,11 +2096,14 @@ __decorate([
1820
2096
  ], CategoryWithTree.prototype, "children", void 0);
1821
2097
 
1822
2098
  class WishlistService {
1823
- constructor(wishlistRepository, shop, productRepository, categoryFilterRepository, categoryRepository, productIndex) {
2099
+ constructor(wishlistRepository, shop, productRepository, categoryFilterRepository, categoryRepository, productStockNotificationRepository, productSearch, logRepository) {
1824
2100
  this.wishlistRepository = wishlistRepository;
1825
2101
  this.shop = shop;
2102
+ this.productRepository = productRepository;
2103
+ this.productSearch = productSearch;
2104
+ this.logRepository = logRepository;
1826
2105
  const categoryStructureAdapter = new NewCategoryStructureAdapter(wishlistRepository);
1827
- this.catalogService = new CatalogService(productRepository, categoryRepository, categoryStructureAdapter, shop, productIndex);
2106
+ this.catalogService = new CatalogService(productRepository, productStockNotificationRepository, categoryRepository, categoryStructureAdapter, shop, productSearch);
1828
2107
  this.categoryService = new CategoryService(productRepository, categoryRepository, categoryFilterRepository, categoryStructureAdapter, shop);
1829
2108
  }
1830
2109
  getCatalogService() {
@@ -1833,46 +2112,76 @@ class WishlistService {
1833
2112
  getCategoryService() {
1834
2113
  return this.categoryService;
1835
2114
  }
1836
- async create({ personId, title, description, userFullName, userPhoto, theme, bannerUrl, }) {
2115
+ async create({ personId, title, description, published, userFullName, userPhoto, theme, bannerUrl, personType, personIsSubscriber, }) {
1837
2116
  const data = {
1838
2117
  slug: '',
1839
2118
  name: title,
1840
2119
  description,
1841
- metadata: {
1842
- title: `${userFullName} - ${title}`,
1843
- description: `${userFullName} - ${description}`,
1844
- },
2120
+ metadatas: [
2121
+ {
2122
+ shop: this.shop,
2123
+ title: `${userFullName} - ${title}`,
2124
+ description: `${userFullName} - ${description}`,
2125
+ },
2126
+ ],
1845
2127
  shop: this.shop,
1846
2128
  shops: [this.shop],
1847
2129
  personId,
1848
2130
  personName: userFullName,
1849
2131
  personPhoto: userPhoto,
1850
2132
  brandCategory: false,
1851
- published: true,
2133
+ published,
1852
2134
  theme,
1853
2135
  bannerUrl,
2136
+ personType: personType ?? PersonTypes.NONE,
2137
+ personIsSubscriber: personIsSubscriber ?? false,
1854
2138
  };
2139
+ const hasWishlist = await this.wishlistRepository
2140
+ .find({
2141
+ filters: {
2142
+ personId,
2143
+ },
2144
+ options: {
2145
+ enableCount: false,
2146
+ },
2147
+ orderBy: {
2148
+ id: 'asc',
2149
+ },
2150
+ })
2151
+ .then((res) => res.data);
2152
+ await this.createWishlistLog(WishlistLogType.CREATE, data);
2153
+ if (hasWishlist.length)
2154
+ return hasWishlist.at(0);
1855
2155
  const newWishlist = await this.wishlistRepository.create(data);
1856
2156
  await this.wishlistRepository.update({ id: newWishlist.id, slug: newWishlist.id });
1857
2157
  return Wishlist.toInstance({ ...newWishlist.toPlain(), slug: newWishlist.id });
1858
2158
  }
1859
- update({ id, title, description, userFullName, userPhoto, theme, bannerUrl, }) {
2159
+ async update({ id, title, description, published, userFullName, userPhoto, theme, bannerUrl, personType, personIsSubscriber, }) {
1860
2160
  const data = {
1861
2161
  id,
1862
2162
  name: title,
1863
2163
  description,
1864
- metadata: {
1865
- title: `${userFullName} - ${title}`,
1866
- description: `${userFullName} - ${description}`,
1867
- },
2164
+ published,
2165
+ metadatas: [
2166
+ {
2167
+ shop: this.shop,
2168
+ title: `${userFullName} - ${title}`,
2169
+ description: `${userFullName} - ${description}`,
2170
+ },
2171
+ ],
1868
2172
  personName: userFullName,
1869
2173
  personPhoto: userPhoto,
1870
2174
  theme,
1871
2175
  bannerUrl,
2176
+ personType: personType ?? PersonTypes.NONE,
2177
+ personIsSubscriber: personIsSubscriber ?? false,
1872
2178
  };
2179
+ await this.createWishlistLog(WishlistLogType.UPDATE, data);
1873
2180
  return this.wishlistRepository.update(data);
1874
2181
  }
1875
- delete(wishlistId) {
2182
+ async delete(wishlistId) {
2183
+ const wishlist = await this.findById(wishlistId);
2184
+ await this.createWishlistLog(WishlistLogType.DELETE, wishlist);
1876
2185
  return this.wishlistRepository.delete({ id: wishlistId });
1877
2186
  }
1878
2187
  getWishlistBySlug(slug) {
@@ -1887,9 +2196,12 @@ class WishlistService {
1887
2196
  async addProduct(wishlistId, productId) {
1888
2197
  const wishlist = await this.wishlistRepository.get({ id: wishlistId });
1889
2198
  const hasProduct = wishlist.products.some((p) => p == productId);
2199
+ const wishlistData = await this.findById(wishlistId);
2200
+ const productData = await this.findProductById(productId);
2201
+ await this.createWishlistLog(WishlistLogType.ADD_PRODUCT, wishlistData, productData);
1890
2202
  if (!hasProduct) {
1891
2203
  wishlist.products = [...wishlist.products, productId];
1892
- return this.wishlistRepository.update({ id: wishlistId, products: wishlist.products });
2204
+ await this.wishlistRepository.addProduct(wishlistId, productId);
1893
2205
  }
1894
2206
  return wishlist;
1895
2207
  }
@@ -1898,13 +2210,88 @@ class WishlistService {
1898
2210
  const productIndex = wishlist.products.findIndex((p) => p == productId);
1899
2211
  if (productIndex != -1) {
1900
2212
  wishlist.products.splice(productIndex, 1);
1901
- if (!wishlist.products.length)
1902
- return this.wishlistRepository.update({ id: wishlistId, products: { action: 'remove' } });
1903
- return this.wishlistRepository.update({ id: wishlistId, products: wishlist.products });
2213
+ const wishlistData = await this.findById(wishlistId);
2214
+ const productData = await this.findProductById(productId);
2215
+ await this.createWishlistLog(WishlistLogType.REMOVE_PRODUCT, wishlistData, productData);
2216
+ await this.wishlistRepository.removeProduct(wishlistId, productId);
1904
2217
  }
1905
2218
  return wishlist;
1906
2219
  }
1907
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: WishlistService, deps: [{ token: 'WishlistRepository' }, { token: DEFAULT_SHOP }, { token: 'ProductRepository' }, { token: 'CategoryFilterRepository' }, { token: 'CategoryRepository' }, { token: i1$2.ProductsIndex }], target: i0.ɵɵFactoryTarget.Injectable }); }
2220
+ async findById(id) {
2221
+ return this.wishlistRepository
2222
+ .find({
2223
+ fields: ['id', 'name', 'description', 'personId', 'personIsSubscriber', 'personType', 'personName'],
2224
+ filters: {
2225
+ id,
2226
+ },
2227
+ })
2228
+ .then((res) => res.data.at(0));
2229
+ }
2230
+ async findProductById(id) {
2231
+ return this.productRepository
2232
+ .find({
2233
+ fields: ['id', 'sku', 'EAN', 'name', 'brand'],
2234
+ filters: {
2235
+ id,
2236
+ },
2237
+ })
2238
+ .then((res) => res.data.at(0));
2239
+ }
2240
+ async createWishlistLog(type, wishlist, product) {
2241
+ switch (type) {
2242
+ case WishlistLogType.CREATE:
2243
+ case WishlistLogType.UPDATE:
2244
+ case WishlistLogType.DELETE:
2245
+ await this.logRepository.create({
2246
+ collection: 'wishlist',
2247
+ date: new Date(),
2248
+ operation: WishlistLogType.CREATE ? 'CREATE' : WishlistLogType.UPDATE ? 'UPDATE' : 'DELETE',
2249
+ documentId: wishlist.id,
2250
+ document: {
2251
+ id: wishlist.id,
2252
+ shop: this.shop,
2253
+ name: wishlist.name,
2254
+ description: wishlist.description,
2255
+ published: wishlist.published,
2256
+ type: type,
2257
+ personType: wishlist.personType,
2258
+ personId: wishlist.personId,
2259
+ personName: wishlist.personName,
2260
+ personIsSubscriber: wishlist.personIsSubscriber,
2261
+ },
2262
+ });
2263
+ break;
2264
+ case WishlistLogType.ADD_PRODUCT:
2265
+ case WishlistLogType.REMOVE_PRODUCT:
2266
+ await this.logRepository.create({
2267
+ collection: 'wishlist',
2268
+ date: new Date(),
2269
+ operation: 'UPDATE',
2270
+ documentId: wishlist.id,
2271
+ document: {
2272
+ id: wishlist.id,
2273
+ shop: this.shop,
2274
+ name: wishlist.name,
2275
+ description: wishlist.description,
2276
+ published: wishlist.published,
2277
+ type: type,
2278
+ personType: wishlist.personType,
2279
+ personId: wishlist.personId,
2280
+ personName: wishlist.personName,
2281
+ personIsSubscriber: wishlist.personIsSubscriber,
2282
+ productId: product.id,
2283
+ productEAN: product.EAN,
2284
+ productSKU: product.sku,
2285
+ productName: product.name,
2286
+ productBrand: product.brand,
2287
+ },
2288
+ });
2289
+ break;
2290
+ default:
2291
+ break;
2292
+ }
2293
+ }
2294
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", 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 }); }
1908
2295
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: WishlistService }); }
1909
2296
  }
1910
2297
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: WishlistService, decorators: [{
@@ -1924,31 +2311,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1924
2311
  }] }, { type: undefined, decorators: [{
1925
2312
  type: Inject,
1926
2313
  args: ['CategoryRepository']
1927
- }] }, { type: i1$2.ProductsIndex }] });
2314
+ }] }, { type: undefined, decorators: [{
2315
+ type: Inject,
2316
+ args: ['ProductStockNotificationRepository']
2317
+ }] }, { type: undefined, decorators: [{
2318
+ type: Inject,
2319
+ args: ['ProductSearch']
2320
+ }] }, { type: undefined, decorators: [{
2321
+ type: Inject,
2322
+ args: ['LogRepository']
2323
+ }] }] });
1928
2324
 
1929
2325
  class CheckoutSubscriptionService {
1930
- constructor(checkoutSubscriptionRepository, subscriptionRepository, couponService) {
2326
+ constructor(checkoutSubscriptionRepository, dataPersistence, couponService) {
1931
2327
  this.checkoutSubscriptionRepository = checkoutSubscriptionRepository;
1932
- this.subscriptionRepository = subscriptionRepository;
2328
+ this.dataPersistence = dataPersistence;
1933
2329
  this.couponService = couponService;
1934
2330
  }
1935
2331
  getCheckoutSubscription(checkoutData) {
1936
- const checkoutId = cookie.get('checkoutSubscriptionId');
1937
- if (!isNil(checkoutId))
1938
- return from(this.checkoutSubscriptionRepository.get({ id: checkoutId }));
1939
- return from(this.createCheckoutSubscription(checkoutData));
1940
- }
1941
- async createCheckoutSubscription(checkoutData) {
1942
- const checkout = await this.checkoutSubscriptionRepository.create({
1943
- createdAt: new Date(),
1944
- ...CheckoutSubscription.toInstance(pick(checkoutData, ['user', 'shop'])).toPlain(),
1945
- });
1946
- cookie.set('checkoutSubscriptionId', checkout.id);
1947
- return checkout;
2332
+ return this.dataPersistence
2333
+ .get('checkoutSubscriptionId')
2334
+ .pipe(concatMap((id) => !isNil(id) ? this.checkoutSubscriptionRepository.get({ id }) : this.createCheckoutSubscription(checkoutData)));
1948
2335
  }
1949
2336
  clearCheckoutSubscriptionFromSession() {
1950
- cookie.remove('checkoutSubscriptionId');
1951
- return of();
2337
+ return this.dataPersistence.remove('checkoutSubscriptionId');
1952
2338
  }
1953
2339
  checkCoupon(nickname, userEmail) {
1954
2340
  return this.getCheckoutSubscription().pipe(concatMap((checkout) => this.couponService
@@ -1958,7 +2344,15 @@ class CheckoutSubscriptionService {
1958
2344
  calcDiscountSubscription(coupon) {
1959
2345
  return this.getCheckoutSubscription().pipe(concatMap((checkout) => this.couponService.calcDiscountSubscription(coupon, checkout).pipe()));
1960
2346
  }
1961
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutSubscriptionService, deps: [{ token: 'CheckoutSubscriptionRepository' }, { token: 'SubscriptionRepository' }, { token: CouponService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2347
+ async createCheckoutSubscription(checkoutData) {
2348
+ const checkout = await this.checkoutSubscriptionRepository.create({
2349
+ createdAt: new Date(),
2350
+ ...CheckoutSubscription.toInstance(pick(checkoutData, ['user', 'shop'])).toPlain(),
2351
+ });
2352
+ await this.dataPersistence.set('checkoutSubscriptionId', checkout.id).toPromise();
2353
+ return checkout;
2354
+ }
2355
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutSubscriptionService, deps: [{ token: 'CheckoutSubscriptionRepository' }, { token: PERSISTENCE_PROVIDER }, { token: CouponService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1962
2356
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutSubscriptionService }); }
1963
2357
  }
1964
2358
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutSubscriptionService, decorators: [{
@@ -1968,7 +2362,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1968
2362
  args: ['CheckoutSubscriptionRepository']
1969
2363
  }] }, { type: undefined, decorators: [{
1970
2364
  type: Inject,
1971
- args: ['SubscriptionRepository']
2365
+ args: [PERSISTENCE_PROVIDER]
1972
2366
  }] }, { type: CouponService }] });
1973
2367
 
1974
2368
  class UtilHelper {
@@ -2053,10 +2447,10 @@ class HomeShopService {
2053
2447
  return this.getHomeConfiguration().pipe(map((home) => home.minValueForFreeShipping));
2054
2448
  }
2055
2449
  getDiscoverProducts(gender) {
2056
- return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.discoverCategories, undefined, gender)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2450
+ return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.discoverCategories, this.defaultShop)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2057
2451
  }
2058
2452
  getFeaturedProducts(gender) {
2059
- return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.featuredCategories, undefined, gender)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2453
+ return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.featuredCategories, this.defaultShop)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2060
2454
  }
2061
2455
  getVerticalProducts(gender) {
2062
2456
  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({
@@ -2226,10 +2620,12 @@ class AngularConnectModule {
2226
2620
  ? OldCategoryStructureAdapter
2227
2621
  : NewCategoryStructureAdapter,
2228
2622
  },
2623
+ { provide: PERSISTENCE_PROVIDER, useClass: options?.persistenceProvider || CookieDataPersistence },
2229
2624
  ...(isNil(defaultShop) ? [] : [{ provide: DEFAULT_SHOP, useValue: defaultShop }]),
2230
2625
  ...(isNil(options?.firebase) ? [] : [{ provide: FIREBASE_OPTIONS, useValue: options?.firebase }]),
2231
2626
  ...(isNil(options?.firebase) ? [] : [{ provide: FIREBASE_APP_NAME, useValue: nameOrConfig }]),
2232
2627
  ...(isNil(options?.elasticSearch) ? [] : [{ provide: ES_CONFIG, useValue: options.elasticSearch }]),
2628
+ ...(isNil(options?.vertexConfig) ? [] : [{ provide: VERTEX_CONFIG, useValue: options.vertexConfig }]),
2233
2629
  ...(isNil(options?.hasura) ? [] : [{ provide: HASURA_OPTIONS, useValue: options.hasura }]),
2234
2630
  ...(isNil(options?.backendUrl) ? [] : [{ provide: BACKEND_URL, useValue: options.backendUrl }]),
2235
2631
  ...(isNil(options?.storageBaseUrl) ? [] : [{ provide: STORAGE_BASE_URL, useValue: options.storageBaseUrl }]),
@@ -2237,7 +2633,8 @@ class AngularConnectModule {
2237
2633
  };
2238
2634
  }
2239
2635
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularConnectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2240
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularConnectModule, imports: [i1$4.FirebaseAppModule, AngularElasticSeachModule,
2636
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularConnectModule, imports: [i1$4.FirebaseAppModule, i2.StorageModule, AngularElasticSeachModule,
2637
+ AngularVertexSeachModule,
2241
2638
  AngularFirebaseAuthModule,
2242
2639
  AngularFirestoreModule,
2243
2640
  AngularHasuraGraphQLModule] }); }
@@ -2260,6 +2657,17 @@ class AngularConnectModule {
2260
2657
  },
2261
2658
  deps: ['UserRepository', 'FileUploaderService'],
2262
2659
  },
2660
+ {
2661
+ provide: 'FileUploaderService',
2662
+ useFactory: (storage, baseUrl) => {
2663
+ return new FirebaseFileUploaderService(storage, baseUrl);
2664
+ },
2665
+ deps: [Storage, STORAGE_BASE_URL],
2666
+ },
2667
+ {
2668
+ provide: 'ProductSearch',
2669
+ useExisting: ProductsVertexSearch,
2670
+ },
2263
2671
  ], imports: [provideFirebaseApp((injector) => {
2264
2672
  const appName = injector.get(FIREBASE_APP_NAME) || '[DEFAULT]';
2265
2673
  try {
@@ -2269,7 +2677,9 @@ class AngularConnectModule {
2269
2677
  return initializeApp(injector.get(FIREBASE_OPTIONS), appName);
2270
2678
  }
2271
2679
  }),
2680
+ provideStorage((injector) => getStorage(injector.get(FirebaseApp))),
2272
2681
  AngularElasticSeachModule,
2682
+ AngularVertexSeachModule,
2273
2683
  AngularFirebaseAuthModule,
2274
2684
  AngularFirestoreModule,
2275
2685
  AngularHasuraGraphQLModule] }); }
@@ -2287,7 +2697,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2287
2697
  return initializeApp(injector.get(FIREBASE_OPTIONS), appName);
2288
2698
  }
2289
2699
  }),
2700
+ provideStorage((injector) => getStorage(injector.get(FirebaseApp))),
2290
2701
  AngularElasticSeachModule,
2702
+ AngularVertexSeachModule,
2291
2703
  AngularFirebaseAuthModule,
2292
2704
  AngularFirestoreModule,
2293
2705
  AngularHasuraGraphQLModule,
@@ -2311,6 +2723,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2311
2723
  },
2312
2724
  deps: ['UserRepository', 'FileUploaderService'],
2313
2725
  },
2726
+ {
2727
+ provide: 'FileUploaderService',
2728
+ useFactory: (storage, baseUrl) => {
2729
+ return new FirebaseFileUploaderService(storage, baseUrl);
2730
+ },
2731
+ deps: [Storage, STORAGE_BASE_URL],
2732
+ },
2733
+ {
2734
+ provide: 'ProductSearch',
2735
+ useExisting: ProductsVertexSearch,
2736
+ },
2314
2737
  ],
2315
2738
  }]
2316
2739
  }] });
@@ -2319,5 +2742,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2319
2742
  * Generated bundle index. Do not edit.
2320
2743
  */
2321
2744
 
2322
- export { AngularConnectModule, AngularFirebaseAuthModule, AngularFirestoreModule, AngularHasuraGraphQLModule, AuthService, CartService, CatalogService, CategoryService, CategoryWithTree, CheckoutService, CheckoutSubscriptionService, CouponService, HomeShopService, NewCategoryStructureAdapter, OldCategoryStructureAdapter, OrderService, ProductSorts, ShippingService, UtilHelper, WishlistService };
2745
+ export { AngularConnectModule, AngularFirebaseAuthModule, AngularFirestoreModule, AngularHasuraGraphQLModule, AuthService, CartService, CatalogService, CategoryService, CategoryWithTree, CheckoutService, CheckoutSubscriptionService, CookieDataPersistence, CouponService, HomeShopService, NewCategoryStructureAdapter, OldCategoryStructureAdapter, OrderService, ProductSorts, ShippingService, UtilHelper, WishlistService };
2323
2746
  //# sourceMappingURL=infrab4a-connect-angular.mjs.map