@infrab4a/connect-angular 5.0.0-beta.8 → 5.0.0-beta.90

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 (77) hide show
  1. package/angular-connect.module.d.ts +17 -9
  2. package/angular-firestore.module.d.ts +1 -2
  3. package/angular-hasura-graphql.module.d.ts +1 -1
  4. package/angular-vertex-search.module.d.ts +9 -0
  5. package/consts/firebase-const.d.ts +1 -0
  6. package/consts/index.d.ts +2 -0
  7. package/consts/persistence.const.d.ts +1 -0
  8. package/consts/vertex-config.const.d.ts +1 -0
  9. package/esm2022/angular-connect.module.mjs +87 -13
  10. package/esm2022/angular-elastic-search.module.mjs +1 -1
  11. package/esm2022/angular-firebase-auth.module.mjs +30 -4
  12. package/esm2022/angular-firestore.module.mjs +53 -28
  13. package/esm2022/angular-hasura-graphql.module.mjs +74 -8
  14. package/esm2022/angular-vertex-search.module.mjs +34 -0
  15. package/esm2022/consts/category-structure.mjs +1 -1
  16. package/esm2022/consts/default-shop.const.mjs +1 -1
  17. package/esm2022/consts/es-config.const.mjs +1 -1
  18. package/esm2022/consts/firebase-const.mjs +2 -1
  19. package/esm2022/consts/hasura-options.const.mjs +1 -1
  20. package/esm2022/consts/index.mjs +3 -1
  21. package/esm2022/consts/persistence.const.mjs +2 -0
  22. package/esm2022/consts/storage-base-url.const.mjs +1 -1
  23. package/esm2022/consts/vertex-config.const.mjs +2 -0
  24. package/esm2022/helpers/index.mjs +1 -1
  25. package/esm2022/helpers/mobile-operation-system-checker.helper.mjs +1 -1
  26. package/esm2022/index.mjs +2 -1
  27. package/esm2022/persistence/cookie-data-persistence.mjs +22 -0
  28. package/esm2022/persistence/data-persistence.mjs +2 -0
  29. package/esm2022/persistence/index.mjs +3 -0
  30. package/esm2022/services/auth.service.mjs +1 -1
  31. package/esm2022/services/cart.service.mjs +42 -237
  32. package/esm2022/services/catalog/adapters/category-structure.adapter.mjs +1 -1
  33. package/esm2022/services/catalog/adapters/index.mjs +1 -1
  34. package/esm2022/services/catalog/adapters/new-category-structure.adapter.mjs +6 -4
  35. package/esm2022/services/catalog/adapters/old-category-structure.adapter.mjs +1 -1
  36. package/esm2022/services/catalog/catalog.service.mjs +158 -48
  37. package/esm2022/services/catalog/category.service.mjs +4 -4
  38. package/esm2022/services/catalog/enums/index.mjs +1 -1
  39. package/esm2022/services/catalog/enums/product-sorts.enum.mjs +1 -1
  40. package/esm2022/services/catalog/index.mjs +1 -1
  41. package/esm2022/services/catalog/models/category-with-tree.model.mjs +1 -1
  42. package/esm2022/services/catalog/models/index.mjs +1 -1
  43. package/esm2022/services/catalog/types/index.mjs +1 -1
  44. package/esm2022/services/catalog/types/product-sort.type.mjs +1 -1
  45. package/esm2022/services/catalog/wishlist.service.mjs +142 -22
  46. package/esm2022/services/checkout-subscription.service.mjs +18 -21
  47. package/esm2022/services/checkout.service.mjs +78 -27
  48. package/esm2022/services/coupon.service.mjs +38 -45
  49. package/esm2022/services/helpers/index.mjs +1 -1
  50. package/esm2022/services/helpers/util.helper.mjs +1 -1
  51. package/esm2022/services/home-shop.service.mjs +4 -4
  52. package/esm2022/services/index.mjs +1 -2
  53. package/esm2022/services/order.service.mjs +1 -1
  54. package/esm2022/services/types/index.mjs +1 -1
  55. package/esm2022/services/types/required-checkout-data.type.mjs +1 -1
  56. package/esm2022/services/types/required-checkout-subscription-data.type.mjs +1 -1
  57. package/esm2022/types/firebase-app-config.type.mjs +1 -1
  58. package/esm2022/types/index.mjs +1 -1
  59. package/fesm2022/infrab4a-connect-angular.mjs +953 -719
  60. package/fesm2022/infrab4a-connect-angular.mjs.map +1 -1
  61. package/index.d.ts +1 -0
  62. package/package.json +6 -6
  63. package/persistence/cookie-data-persistence.d.ts +10 -0
  64. package/persistence/data-persistence.d.ts +6 -0
  65. package/persistence/index.d.ts +2 -0
  66. package/services/cart.service.d.ts +8 -19
  67. package/services/catalog/catalog.service.d.ts +11 -4
  68. package/services/catalog/category.service.d.ts +6 -1
  69. package/services/catalog/wishlist.service.d.ts +16 -4
  70. package/services/checkout-subscription.service.d.ts +5 -4
  71. package/services/checkout.service.d.ts +18 -7
  72. package/services/coupon.service.d.ts +0 -2
  73. package/services/index.d.ts +0 -1
  74. package/esm2022/services/shipping.service.mjs +0 -96
  75. package/esm2022/services/types/shipping-methods.type.mjs +0 -2
  76. package/services/shipping.service.d.ts +0 -19
  77. package/services/types/shipping-methods.type.d.ts +0 -12
@@ -2,21 +2,23 @@ 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 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';
5
+ import * as i2 from '@angular/fire/app-check';
6
+ import { provideAppCheck, initializeAppCheck } from '@angular/fire/app-check';
7
+ import * as i3 from '@angular/fire/storage';
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, HomeFirestoreRepository, LeadFirestoreRepository, LegacyOrderFirestoreRepository, ShopMenuFirestoreRepository, OrderFirestoreRepository, PaymentFirestoreRepository, ProductFirestoreRepository, ShopSettingsFirestoreRepository, SubscriptionPaymentFirestoreRepository, SubscriptionPlanFirestoreRepository, SubscriptionProductFirestoreRepository, SubscriptionFirestoreRepository, UserFirestoreRepository, UserAddressFirestoreRepository, UserPaymentMethodFirestoreRepository, SubscriptionMaterializationFirestoreRepository, SubscriptionSummaryFirestoreRepository, ProductVariantFirestoreRepository, OrderBlockedFirestoreRepository, LogFirestoreRepository, SequenceFirestoreRepository, CategoryHasuraGraphQLRepository, ProductHasuraGraphQLRepository, CategoryFilterHasuraGraphQLRepository, ProductReviewsHasuraGraphQLRepository, 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';
7
11
  import * as i1 from '@angular/fire/auth';
8
- import { Auth, provideAuth, getAuth, getIdToken, authState } from '@angular/fire/auth';
12
+ import { Auth, provideAuth, initializeAuth, indexedDBLocalPersistence, browserLocalPersistence, getAuth, getIdToken, authState } from '@angular/fire/auth';
9
13
  import { isPlatformBrowser, isPlatformServer } from '@angular/common';
10
14
  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';
15
+ import { Firestore, provideFirestore, initializeFirestore, memoryLocalCache, docSnapshots, doc } from '@angular/fire/firestore';
16
16
  import cookie from 'js-cookie';
17
+ import { of, from, combineLatest, throwError, Subject, forkJoin } from 'rxjs';
18
+ import { map, mergeMap, catchError, concatMap, tap } from 'rxjs/operators';
19
+ import * as i1$2 from '@angular/common/http';
17
20
  import { __decorate, __metadata } from 'tslib';
18
21
  import { Type } from 'class-transformer';
19
- import * as i1$3 from '@angular/common/http';
20
22
 
21
23
  const ES_CONFIG = 'ES_CONFIG';
22
24
 
@@ -58,9 +60,14 @@ const DEFAULT_SHOP = 'DEFAULT_SHOP';
58
60
 
59
61
  const FIREBASE_APP_NAME = new InjectionToken('firebaseAppName');
60
62
  const FIREBASE_OPTIONS = new InjectionToken('firebaseOptions');
63
+ const APP_CHECK_PROVIDER = new InjectionToken('appCheckProvider');
61
64
 
62
65
  const HASURA_OPTIONS = 'HASURA_OPTIONS';
63
66
 
67
+ const PERSISTENCE_PROVIDER = 'PERSISTENCE_PROVIDER';
68
+
69
+ const VERTEX_CONFIG = 'VERTEX_CONFIG';
70
+
64
71
  class AngularFirebaseAuthModule {
65
72
  static initializeApp(options, nameOrConfig) {
66
73
  return {
@@ -116,12 +123,38 @@ class AngularFirebaseAuthModule {
116
123
  },
117
124
  deps: ['AuthenticationService'],
118
125
  },
119
- ], imports: [provideAuth((injector) => getAuth(injector.get(FirebaseApp)))] }); }
126
+ ], imports: [provideAuth((injector) => {
127
+ const app = injector.get(FirebaseApp);
128
+ try {
129
+ return initializeAuth(app, {
130
+ persistence: [indexedDBLocalPersistence, browserLocalPersistence],
131
+ });
132
+ }
133
+ catch (error) {
134
+ if (error instanceof Error)
135
+ console.error('Error initializing auth', error.message);
136
+ return getAuth(app);
137
+ }
138
+ })] }); }
120
139
  }
121
140
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularFirebaseAuthModule, decorators: [{
122
141
  type: NgModule,
123
142
  args: [{
124
- imports: [provideAuth((injector) => getAuth(injector.get(FirebaseApp)))],
143
+ imports: [
144
+ provideAuth((injector) => {
145
+ const app = injector.get(FirebaseApp);
146
+ try {
147
+ return initializeAuth(app, {
148
+ persistence: [indexedDBLocalPersistence, browserLocalPersistence],
149
+ });
150
+ }
151
+ catch (error) {
152
+ if (error instanceof Error)
153
+ console.error('Error initializing auth', error.message);
154
+ return getAuth(app);
155
+ }
156
+ }),
157
+ ],
125
158
  providers: [
126
159
  {
127
160
  provide: 'Authentication',
@@ -169,8 +202,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
169
202
  }]
170
203
  }] });
171
204
 
172
- const STORAGE_BASE_URL = 'STORAGE_BASE_URL';
173
-
174
205
  class MobileOperationSystemCheckerHelper {
175
206
  static isAppleDevice() {
176
207
  return (['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(navigator?.platform) ||
@@ -190,12 +221,12 @@ class AngularFirestoreModule {
190
221
  };
191
222
  }
192
223
  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] }); }
224
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, imports: [AngularElasticSeachModule, i1$1.FirestoreModule] }); }
194
225
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, providers: [
195
226
  {
196
227
  provide: 'FirestoreOptions',
197
228
  useFactory: (firestore, platformId) => ({
198
- firestore,
229
+ firestore: new ConnectFirestoreService(firestore),
199
230
  interceptors: {
200
231
  request: (request) => {
201
232
  if (isPlatformBrowser(platformId))
@@ -404,26 +435,40 @@ class AngularFirestoreModule {
404
435
  deps: ['FirestoreOptions', ProductFirestoreRepository],
405
436
  },
406
437
  {
407
- provide: 'FileUploaderService',
408
- useFactory: (storage, baseUrl) => {
409
- return new FirebaseFileUploaderService(storage, baseUrl);
438
+ provide: 'OrderBlockedRepository',
439
+ useFactory: (options) => {
440
+ return new OrderBlockedFirestoreRepository(options);
410
441
  },
411
- deps: [Storage, STORAGE_BASE_URL],
442
+ deps: ['FirestoreOptions'],
443
+ },
444
+ {
445
+ provide: 'LogRepository',
446
+ useFactory: (options) => {
447
+ return new LogFirestoreRepository(options);
448
+ },
449
+ deps: ['FirestoreOptions'],
450
+ },
451
+ {
452
+ provide: 'SequenceRepository',
453
+ useFactory: (options) => {
454
+ return new SequenceFirestoreRepository(options);
455
+ },
456
+ deps: ['FirestoreOptions'],
412
457
  },
413
458
  ], imports: [AngularElasticSeachModule,
414
459
  provideFirestore((injector) => {
415
460
  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));
461
+ if (isPlatformServer(platformId) || !MobileOperationSystemCheckerHelper.isAppleDevice())
462
+ return initializeFirestore(injector.get(FirebaseApp), {
463
+ ignoreUndefinedProperties: true,
464
+ });
420
465
  const firestore = initializeFirestore(injector.get(FirebaseApp), {
421
466
  experimentalForceLongPolling: true,
467
+ ignoreUndefinedProperties: true,
422
468
  localCache: memoryLocalCache(),
423
469
  });
424
470
  return firestore;
425
- }),
426
- provideStorage(() => getStorage())] }); }
471
+ })] }); }
427
472
  }
428
473
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularFirestoreModule, decorators: [{
429
474
  type: NgModule,
@@ -432,23 +477,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
432
477
  AngularElasticSeachModule,
433
478
  provideFirestore((injector) => {
434
479
  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));
480
+ if (isPlatformServer(platformId) || !MobileOperationSystemCheckerHelper.isAppleDevice())
481
+ return initializeFirestore(injector.get(FirebaseApp), {
482
+ ignoreUndefinedProperties: true,
483
+ });
439
484
  const firestore = initializeFirestore(injector.get(FirebaseApp), {
440
485
  experimentalForceLongPolling: true,
486
+ ignoreUndefinedProperties: true,
441
487
  localCache: memoryLocalCache(),
442
488
  });
443
489
  return firestore;
444
490
  }),
445
- provideStorage(() => getStorage()),
446
491
  ],
447
492
  providers: [
448
493
  {
449
494
  provide: 'FirestoreOptions',
450
495
  useFactory: (firestore, platformId) => ({
451
- firestore,
496
+ firestore: new ConnectFirestoreService(firestore),
452
497
  interceptors: {
453
498
  request: (request) => {
454
499
  if (isPlatformBrowser(platformId))
@@ -657,11 +702,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
657
702
  deps: ['FirestoreOptions', ProductFirestoreRepository],
658
703
  },
659
704
  {
660
- provide: 'FileUploaderService',
661
- useFactory: (storage, baseUrl) => {
662
- return new FirebaseFileUploaderService(storage, baseUrl);
705
+ provide: 'OrderBlockedRepository',
706
+ useFactory: (options) => {
707
+ return new OrderBlockedFirestoreRepository(options);
663
708
  },
664
- deps: [Storage, STORAGE_BASE_URL],
709
+ deps: ['FirestoreOptions'],
710
+ },
711
+ {
712
+ provide: 'LogRepository',
713
+ useFactory: (options) => {
714
+ return new LogFirestoreRepository(options);
715
+ },
716
+ deps: ['FirestoreOptions'],
717
+ },
718
+ {
719
+ provide: 'SequenceRepository',
720
+ useFactory: (options) => {
721
+ return new SequenceFirestoreRepository(options);
722
+ },
723
+ deps: ['FirestoreOptions'],
665
724
  },
666
725
  ],
667
726
  }]
@@ -744,6 +803,17 @@ class AngularHasuraGraphQLModule {
744
803
  },
745
804
  deps: ['HasuraConfig'],
746
805
  },
806
+ {
807
+ provide: 'ProductStockNotificationRepository',
808
+ useExisting: ProductStockNotificationHasuraGraphQLRepository,
809
+ },
810
+ {
811
+ provide: ProductStockNotificationHasuraGraphQLRepository,
812
+ useFactory: (hasuraConfig) => {
813
+ return new ProductStockNotificationHasuraGraphQLRepository(hasuraConfig);
814
+ },
815
+ deps: ['HasuraConfig'],
816
+ },
747
817
  {
748
818
  provide: 'CategoryFilterRepository',
749
819
  useExisting: CategoryFilterHasuraGraphQLRepository,
@@ -786,17 +856,39 @@ class AngularHasuraGraphQLModule {
786
856
  provide: 'CategoryCollectionChildrenRepository',
787
857
  useExisting: CategoryCollectionChildrenHasuraGraphQLRepository,
788
858
  },
859
+ {
860
+ provide: CategoryProductHasuraGraphQLRepository,
861
+ useFactory: (options) => {
862
+ return new CategoryProductHasuraGraphQLRepository(options);
863
+ },
864
+ deps: ['HasuraConfig'],
865
+ },
866
+ {
867
+ provide: 'CategoryProductRepository',
868
+ useExisting: CategoryProductHasuraGraphQLRepository,
869
+ },
789
870
  {
790
871
  provide: WishlistHasuraGraphQLRepository,
791
- useFactory: (options, categoryFilterRepository) => {
792
- return new WishlistHasuraGraphQLRepository(options, categoryFilterRepository);
872
+ useFactory: (options, categoryProductRepository) => {
873
+ return new WishlistHasuraGraphQLRepository(options, categoryProductRepository);
793
874
  },
794
- deps: ['HasuraConfig', CategoryFilterHasuraGraphQLRepository],
875
+ deps: ['HasuraConfig', CategoryProductHasuraGraphQLRepository],
795
876
  },
796
877
  {
797
878
  provide: 'WishlistRepository',
798
879
  useExisting: WishlistHasuraGraphQLRepository,
799
880
  },
881
+ {
882
+ provide: ProductErrorsHasuraGraphQLRepository,
883
+ useFactory: (options, productRepository) => {
884
+ return new ProductErrorsHasuraGraphQLRepository(options, productRepository);
885
+ },
886
+ deps: ['HasuraConfig', ProductHasuraGraphQLRepository],
887
+ },
888
+ {
889
+ provide: 'ProductErrorsRepository',
890
+ useExisting: ProductErrorsHasuraGraphQLRepository,
891
+ },
800
892
  ] }); }
801
893
  }
802
894
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularHasuraGraphQLModule, decorators: [{
@@ -870,6 +962,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
870
962
  },
871
963
  deps: ['HasuraConfig'],
872
964
  },
965
+ {
966
+ provide: 'ProductStockNotificationRepository',
967
+ useExisting: ProductStockNotificationHasuraGraphQLRepository,
968
+ },
969
+ {
970
+ provide: ProductStockNotificationHasuraGraphQLRepository,
971
+ useFactory: (hasuraConfig) => {
972
+ return new ProductStockNotificationHasuraGraphQLRepository(hasuraConfig);
973
+ },
974
+ deps: ['HasuraConfig'],
975
+ },
873
976
  {
874
977
  provide: 'CategoryFilterRepository',
875
978
  useExisting: CategoryFilterHasuraGraphQLRepository,
@@ -912,21 +1015,92 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
912
1015
  provide: 'CategoryCollectionChildrenRepository',
913
1016
  useExisting: CategoryCollectionChildrenHasuraGraphQLRepository,
914
1017
  },
1018
+ {
1019
+ provide: CategoryProductHasuraGraphQLRepository,
1020
+ useFactory: (options) => {
1021
+ return new CategoryProductHasuraGraphQLRepository(options);
1022
+ },
1023
+ deps: ['HasuraConfig'],
1024
+ },
1025
+ {
1026
+ provide: 'CategoryProductRepository',
1027
+ useExisting: CategoryProductHasuraGraphQLRepository,
1028
+ },
915
1029
  {
916
1030
  provide: WishlistHasuraGraphQLRepository,
917
- useFactory: (options, categoryFilterRepository) => {
918
- return new WishlistHasuraGraphQLRepository(options, categoryFilterRepository);
1031
+ useFactory: (options, categoryProductRepository) => {
1032
+ return new WishlistHasuraGraphQLRepository(options, categoryProductRepository);
919
1033
  },
920
- deps: ['HasuraConfig', CategoryFilterHasuraGraphQLRepository],
1034
+ deps: ['HasuraConfig', CategoryProductHasuraGraphQLRepository],
921
1035
  },
922
1036
  {
923
1037
  provide: 'WishlistRepository',
924
1038
  useExisting: WishlistHasuraGraphQLRepository,
925
1039
  },
1040
+ {
1041
+ provide: ProductErrorsHasuraGraphQLRepository,
1042
+ useFactory: (options, productRepository) => {
1043
+ return new ProductErrorsHasuraGraphQLRepository(options, productRepository);
1044
+ },
1045
+ deps: ['HasuraConfig', ProductHasuraGraphQLRepository],
1046
+ },
1047
+ {
1048
+ provide: 'ProductErrorsRepository',
1049
+ useExisting: ProductErrorsHasuraGraphQLRepository,
1050
+ },
1051
+ ],
1052
+ }]
1053
+ }] });
1054
+
1055
+ class AngularVertexSeachModule {
1056
+ static initializeApp(options) {
1057
+ return {
1058
+ ngModule: AngularVertexSeachModule,
1059
+ providers: [{ provide: VERTEX_CONFIG, useValue: options }],
1060
+ };
1061
+ }
1062
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1063
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule }); }
1064
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule, providers: [
1065
+ {
1066
+ provide: ProductsVertexSearch,
1067
+ useFactory: (configuration) => new ProductsVertexSearch(new VertexAxiosAdapter(configuration)),
1068
+ deps: [VERTEX_CONFIG],
1069
+ },
1070
+ ] }); }
1071
+ }
1072
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: AngularVertexSeachModule, decorators: [{
1073
+ type: NgModule,
1074
+ args: [{
1075
+ providers: [
1076
+ {
1077
+ provide: ProductsVertexSearch,
1078
+ useFactory: (configuration) => new ProductsVertexSearch(new VertexAxiosAdapter(configuration)),
1079
+ deps: [VERTEX_CONFIG],
1080
+ },
926
1081
  ],
927
1082
  }]
928
1083
  }] });
929
1084
 
1085
+ const STORAGE_BASE_URL = 'STORAGE_BASE_URL';
1086
+
1087
+ class CookieDataPersistence {
1088
+ get(key) {
1089
+ return of(cookie.get(key));
1090
+ }
1091
+ remove(key) {
1092
+ return of(cookie.remove(key));
1093
+ }
1094
+ set(key, value) {
1095
+ return from(cookie.set(key, value)).pipe(map(() => { }));
1096
+ }
1097
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CookieDataPersistence, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1098
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CookieDataPersistence }); }
1099
+ }
1100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CookieDataPersistence, decorators: [{
1101
+ type: Injectable
1102
+ }] });
1103
+
930
1104
  class AuthService {
931
1105
  constructor(angularFireAuth, userRepository) {
932
1106
  this.angularFireAuth = angularFireAuth;
@@ -958,266 +1132,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
958
1132
  args: ['UserRepository']
959
1133
  }] }] });
960
1134
 
961
- class CouponService {
962
- constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
963
- this.couponRepository = couponRepository;
1135
+ class CheckoutService {
1136
+ constructor(checkoutRepository, userRepository, defaultShop, dataPersistence, firebaseOptions, http) {
1137
+ this.checkoutRepository = checkoutRepository;
1138
+ this.userRepository = userRepository;
964
1139
  this.defaultShop = defaultShop;
965
- this.orderRepository = orderRepository;
966
- this.categoryRepository = categoryRepository;
967
- this.emailIsFromCollaborator = (userEmail) => !!userEmail?.match(/@b4a.com.br/g);
968
- }
969
- checkCoupon(nickname, checkoutType, checkout, plan) {
970
- return from(this.couponRepository
971
- .find({
972
- filters: {
973
- nickname: { operator: Where.EQUALS, value: nickname },
974
- active: { operator: Where.EQUALS, value: true },
975
- },
976
- })
977
- .then((result) => result.data[0])).pipe(concatMap((coupon) => this.couponValidation(coupon, checkoutType)), concatMap((couponValid) => this.couponRulesValidation(couponValid, checkoutType, checkout, plan)), map((couponValidated) => couponValidated));
1140
+ this.dataPersistence = dataPersistence;
1141
+ this.firebaseOptions = firebaseOptions;
1142
+ this.http = http;
1143
+ this.checkoutUrl = null;
1144
+ this.checkoutUrl = `https://southamerica-east1-${this.firebaseOptions.projectId}.cloudfunctions.net`;
978
1145
  }
979
- async couponValidation(coupon, checkoutType) {
980
- if (!coupon)
981
- throw 'Cupom inválido.';
982
- if (coupon?.beginAt && coupon?.beginAt.getTime() > new Date().getTime())
983
- throw 'Cupom inválido.';
984
- if (coupon?.expiresIn && coupon?.expiresIn.getTime() < new Date().getTime())
985
- throw 'Cupom expirado.';
986
- const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
987
- if (!isInShop)
988
- throw 'Cupom inválido para loja.';
989
- const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
990
- if (!isCheckoutType)
991
- throw 'Cupom inválido. Erro de checkout.';
992
- return coupon;
1146
+ getCheckout(checkoutData) {
1147
+ return this.dataPersistence
1148
+ .get('checkoutId')
1149
+ .pipe(concatMap((id) => (!isNil(id) ? this.checkoutRepository.get({ id }) : this.createCheckout(checkoutData))));
993
1150
  }
994
- async couponRulesValidation(coupon, checkoutType, checkout, plan) {
995
- if (checkoutType == CheckoutTypes.SUBSCRIPTION) {
996
- if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
997
- throw 'Cupom inválido para sua assinatura.';
998
- return coupon;
999
- }
1000
- const validUser = this.coupomUserValidation(coupon, checkout?.user);
1001
- if (!validUser)
1002
- throw 'Usuário não elegível.';
1003
- const couponUseLimits = this.getCouponUseLimits(coupon, checkoutType, checkout.user);
1004
- if (couponUseLimits.firstOrder) {
1005
- const ordersUser = await this.getOrdersFromUser(checkout.user.email.toLocaleLowerCase());
1006
- if (couponUseLimits.firstOrder && ordersUser.length >= 1)
1007
- throw 'Limite de uso atingido';
1008
- }
1009
- if (!couponUseLimits.unlimited || couponUseLimits.limitedPerUser) {
1010
- const orders = await this.getOrdersWithCoupon(coupon);
1011
- if (!couponUseLimits.unlimited && couponUseLimits.total && orders.length >= couponUseLimits.total)
1012
- throw 'Limite de uso atingido.';
1013
- if (couponUseLimits.limitedPerUser) {
1014
- const ordersWithUser = this.countOrdersWithUser(orders, checkout.user.email);
1015
- if (ordersWithUser > 0)
1016
- throw 'Limite de uso por usuário atingido.';
1017
- }
1018
- }
1019
- const hasProductCategories = await this.hasProductCategories(coupon, checkout);
1020
- if (!hasProductCategories)
1021
- throw 'Seu carrinho não possui produtos elegíveis para desconto.';
1022
- 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`;
1025
- return coupon;
1151
+ getUserByCheckout(checkoutId) {
1152
+ 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'))));
1026
1153
  }
1027
- calcDiscountSubscription(coupon, checkout) {
1028
- let discount = 0;
1029
- if (coupon.discount.subscription.type == CouponTypes.ABSOLUTE)
1030
- discount = coupon.discount.subscription.value;
1031
- else
1032
- discount = checkout.subscriptionPlan.recurrencePrice * (coupon.discount.subscription.value / 100);
1033
- return of(discount);
1154
+ updateCheckoutLineItems(checkout) {
1155
+ return from(this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, lineItems: checkout.lineItems })));
1034
1156
  }
1035
- async calcDiscountShopping(coupon, checkout) {
1036
- let discount = 0;
1037
- if (checkout.user.isSubscriber && coupon.discount.subscriber.value) {
1038
- discount = await this.calcDiscountByType(coupon.discount.subscriber.type, coupon.discount.subscriber.value, coupon.productsCategories, checkout);
1039
- }
1040
- else {
1041
- discount = await this.calcDiscountByType(coupon.discount.non_subscriber.type, coupon.discount.non_subscriber.value, coupon.productsCategories, checkout);
1042
- }
1043
- return discount;
1157
+ updateCheckoutUser(checkout) {
1158
+ return from(this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, user: checkout.user })));
1044
1159
  }
1045
- async calcDiscountByType(type, value, categories, checkout) {
1046
- let discount = 0;
1047
- let lineItensDiscount = await this.getLineItensEligebleForDiscount(categories, checkout);
1048
- const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
1049
- if (type == CouponTypes.ABSOLUTE) {
1050
- discount = value > subTotal ? subTotal : value;
1051
- }
1052
- else {
1053
- discount = subTotal * (value / 100);
1054
- }
1055
- return discount;
1160
+ clearCheckoutFromSession() {
1161
+ return this.dataPersistence.remove('checkoutId');
1162
+ }
1163
+ resetCheckoutValues() {
1164
+ return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutResetValues`, {
1165
+ checkoutId: checkout.id,
1166
+ })), concatMap(() => this.getCheckout()));
1167
+ }
1168
+ applyCouponDiscount(nickname, checkoutType) {
1169
+ return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutApplyDiscount`, {
1170
+ checkoutId: checkout.id,
1171
+ coupon: nickname,
1172
+ checkoutType,
1173
+ })), concatMap(() => this.getCheckout()), map((checkout) => checkout.coupon));
1174
+ }
1175
+ removeCouponDiscount() {
1176
+ return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutRemoveDiscount`, {
1177
+ checkoutId: checkout.id,
1178
+ })), concatMap(() => this.getCheckout()));
1179
+ }
1180
+ validateStockProducts() {
1181
+ return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutValidateProductStock`, {
1182
+ checkoutId: checkout.id,
1183
+ })));
1056
1184
  }
1057
- async hasMinSubTotal(coupon, checkout) {
1058
- if (!coupon.minSubTotalValue)
1059
- return true;
1060
- let lineItensDiscount = await this.getLineItensEligebleForDiscount(coupon.productsCategories, checkout);
1061
- const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user, checkout.shop);
1062
- if (coupon.minSubTotalValue <= subTotal)
1063
- return true;
1064
- return false;
1185
+ selectShippingAddress(address) {
1186
+ return this.getCheckout().pipe(concatMap((checkout) => {
1187
+ return this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, shippingAddress: address, billingAddress: address }));
1188
+ }));
1065
1189
  }
1066
- async hasProductCategories(coupon, checkout) {
1067
- if (!coupon.productsCategories || !coupon.productsCategories.length) {
1068
- return true;
1069
- }
1070
- const couponCategories = await this.getCouponCategoriesId(coupon.productsCategories);
1071
- const hasCategories = checkout.lineItems?.filter((i) => {
1072
- if (!i.categories || !i.categories?.length)
1073
- return true;
1074
- return i.categories.some((c) => couponCategories.some((cat) => cat == c));
1190
+ getAvailableShippingForProduct(productShipping) {
1191
+ return this.http.post(`${this.checkoutUrl}/checkoutGetAvailableShipping`, {
1192
+ checkoutId: null,
1193
+ productShipping,
1075
1194
  });
1076
- return hasCategories.length ? true : false;
1077
1195
  }
1078
- coupomUserValidation(coupon, user) {
1079
- if (!user || coupon.exclusivityType.includes(Exclusivities.ALL_USERS))
1080
- return true;
1081
- let userTypes = [];
1082
- if (coupon.exclusivityType.includes(Exclusivities.COLLABORATORS) &&
1083
- this.emailIsFromCollaborator(user.email.toLocaleLowerCase()))
1084
- userTypes.push(Exclusivities.COLLABORATORS);
1085
- if (coupon.exclusivityType.includes(Exclusivities.SPECIFIC_USER) &&
1086
- coupon.userExclusiveEmail.includes(user.email.toLocaleLowerCase()))
1087
- userTypes.push(Exclusivities.SPECIFIC_USER);
1088
- if (coupon.exclusivityType.includes(Exclusivities.ACTIVE_SUBSCRIBER) &&
1089
- user.isSubscriber &&
1090
- user.subscriptionPlan != '')
1091
- userTypes.push(Exclusivities.ACTIVE_SUBSCRIBER);
1092
- if (user.isSubscriber &&
1093
- user.subscriptionPlan == '' &&
1094
- coupon.exclusivityType.includes(Exclusivities.INACTIVE_SUBSCRIBER))
1095
- userTypes.push(Exclusivities.INACTIVE_SUBSCRIBER);
1096
- if (coupon.exclusivityType.includes(Exclusivities.NON_SUBSCRIBER) && !user.isSubscriber)
1097
- userTypes.push(Exclusivities.NON_SUBSCRIBER);
1098
- return coupon.exclusivityType.some((r) => userTypes.includes(r));
1196
+ getAvailableShippingForCheckout() {
1197
+ return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutGetAvailableShipping`, {
1198
+ checkoutId: checkout.id,
1199
+ productShipping: null,
1200
+ })));
1099
1201
  }
1100
- async getCouponCategoriesId(productsCategories) {
1101
- const couponCategories = [];
1102
- for (let index = 0; index < productsCategories.length; index++) {
1103
- const category = await this.categoryRepository.get({
1104
- id: productsCategories[index],
1105
- });
1106
- if (category) {
1107
- const children = await this.categoryRepository.getChildren(parseInt(productsCategories[index]));
1108
- couponCategories.push(category.id, ...children.map((c) => c.id.toString()));
1109
- }
1110
- }
1111
- return [...new Set(couponCategories)];
1202
+ selectShipping(option) {
1203
+ return this.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutSelectShipping`, {
1204
+ checkoutId: checkout.id,
1205
+ shippingOption: option,
1206
+ })), concatMap(() => this.getCheckout()));
1112
1207
  }
1113
- async getLineItensEligebleForDiscount(productsCategories, checkout) {
1114
- let lineItensDiscount = [];
1115
- const couponCategories = await this.getCouponCategoriesId(productsCategories);
1116
- 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));
1120
- }
1121
- return true;
1122
- });
1123
- }
1124
- else {
1125
- lineItensDiscount = checkout.lineItems;
1126
- }
1127
- return lineItensDiscount;
1128
- }
1129
- calcCheckoutSubtotal(lineItens, user, shop) {
1130
- return (lineItens?.reduce((acc, curr) => user?.isSubscriber && curr.price.subscriberPrice
1131
- ? acc + curr.price?.subscriberPrice * curr.quantity
1132
- : acc + curr.pricePaid * curr.quantity, 0) || 0);
1133
- }
1134
- async getOrdersWithCoupon(coupon) {
1135
- return await this.orderRepository
1136
- .find({
1137
- filters: {
1138
- coupon: { id: coupon.id },
1139
- payment: { status: 'paid' },
1208
+ createOrder(checkoutPayload, paymentProvider, applicationVersion) {
1209
+ return this.http.post(`${this.checkoutUrl}/checkout`, {
1210
+ data: {
1211
+ ...checkoutPayload,
1212
+ applicationVersion,
1213
+ paymentProvider,
1140
1214
  },
1141
- })
1142
- .then((result) => result.data);
1143
- }
1144
- async getOrdersFromUser(email) {
1145
- return await this.orderRepository
1146
- .find({
1147
- filters: {
1148
- user: { email: { operator: Where.EQUALS, value: email } },
1149
- payment: { status: 'paid' },
1150
- },
1151
- })
1152
- .then((result) => result.data);
1153
- }
1154
- countOrdersWithUser(orders, email) {
1155
- return orders.filter((o) => o.user.email == email).length;
1156
- }
1157
- getCouponUseLimits(coupon, checkoutType, user) {
1158
- let couponUseLimits;
1159
- if (checkoutType == CheckoutTypes.ECOMMERCE || checkoutType == CheckoutTypes.ALL) {
1160
- couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
1161
- }
1162
- else {
1163
- couponUseLimits = coupon.useLimits.subscription;
1164
- }
1165
- return couponUseLimits;
1166
- }
1167
- 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
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, providedIn: 'root' }); }
1169
- }
1170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, decorators: [{
1171
- type: Injectable,
1172
- args: [{
1173
- providedIn: 'root',
1174
- }]
1175
- }], ctorParameters: () => [{ type: undefined, decorators: [{
1176
- type: Inject,
1177
- args: ['CouponRepository']
1178
- }] }, { type: i1$2.Shops, decorators: [{
1179
- type: Inject,
1180
- args: [DEFAULT_SHOP]
1181
- }] }, { type: undefined, decorators: [{
1182
- type: Inject,
1183
- args: ['OrderRepository']
1184
- }] }, { type: undefined, decorators: [{
1185
- type: Inject,
1186
- args: ['CategoryRepository']
1187
- }] }] });
1188
-
1189
- class CheckoutService {
1190
- constructor(couponService, checkoutRepository, orderRepository, userRepository, defaultShop) {
1191
- this.couponService = couponService;
1192
- this.checkoutRepository = checkoutRepository;
1193
- this.orderRepository = orderRepository;
1194
- this.userRepository = userRepository;
1195
- this.defaultShop = defaultShop;
1196
- }
1197
- 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));
1202
- }
1203
- getUserByCheckout(checkoutId) {
1204
- 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'))));
1205
- }
1206
- updateCheckoutLineItems(checkout) {
1207
- return from(this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, lineItems: checkout.lineItems })));
1208
- }
1209
- updateCheckoutUser(checkout) {
1210
- return from(this.checkoutRepository.update(Checkout.toInstance({ id: checkout.id, user: checkout.user })));
1211
- }
1212
- clearCheckoutFromSession() {
1213
- cookie.remove('checkoutId');
1214
- return of();
1215
- }
1216
- calcDiscount(coupon) {
1217
- return this.getCheckout().pipe(concatMap(async (checkout) => await this.couponService.calcDiscountShopping(coupon, checkout)));
1218
- }
1219
- checkCoupon(nickname, checkoutType) {
1220
- return this.getCheckout().pipe(concatMap((checkout) => this.couponService.checkCoupon(nickname, CheckoutTypes.ECOMMERCE, checkout, null).pipe()));
1215
+ });
1221
1216
  }
1222
1217
  async createCheckout(checkoutData) {
1223
1218
  const checkout = await this.checkoutRepository.create({
@@ -1225,51 +1220,40 @@ class CheckoutService {
1225
1220
  ...Checkout.toInstance(pick(checkoutData, ['user', 'shop'])).toPlain(),
1226
1221
  shop: checkoutData?.shop || this.defaultShop,
1227
1222
  });
1228
- cookie.set('checkoutId', checkout.id);
1223
+ await this.dataPersistence.set('checkoutId', checkout.id).toPromise();
1229
1224
  return checkout;
1230
1225
  }
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 }); }
1226
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", 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 }); }
1232
1227
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutService }); }
1233
1228
  }
1234
1229
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutService, decorators: [{
1235
1230
  type: Injectable
1236
- }], ctorParameters: () => [{ type: CouponService }, { type: undefined, decorators: [{
1231
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1237
1232
  type: Inject,
1238
1233
  args: ['CheckoutRepository']
1239
- }] }, { type: undefined, decorators: [{
1240
- type: Inject,
1241
- args: ['OrderRepository']
1242
1234
  }] }, { type: undefined, decorators: [{
1243
1235
  type: Inject,
1244
1236
  args: ['UserRepository']
1245
- }] }, { type: i1$2.Shops, decorators: [{
1237
+ }] }, { type: i1$3.Shops, decorators: [{
1246
1238
  type: Inject,
1247
1239
  args: [DEFAULT_SHOP]
1248
- }] }] });
1240
+ }] }, { type: undefined, decorators: [{
1241
+ type: Inject,
1242
+ args: [PERSISTENCE_PROVIDER]
1243
+ }] }, { type: undefined, decorators: [{
1244
+ type: Inject,
1245
+ args: [FIREBASE_OPTIONS]
1246
+ }] }, { type: i1$2.HttpClient }] });
1249
1247
 
1250
1248
  class CartService {
1251
- constructor(authService, checkoutService, defaultShop, productRepository, categoryRepository, variantRepository, buy2WinRepository) {
1249
+ constructor(authService, checkoutService, defaultShop, firebaseOptions, http) {
1252
1250
  this.authService = authService;
1253
1251
  this.checkoutService = checkoutService;
1254
1252
  this.defaultShop = defaultShop;
1255
- this.productRepository = productRepository;
1256
- this.categoryRepository = categoryRepository;
1257
- this.variantRepository = variantRepository;
1258
- this.buy2WinRepository = buy2WinRepository;
1253
+ this.firebaseOptions = firebaseOptions;
1254
+ this.http = http;
1259
1255
  this.cartSubject = new Subject();
1260
- this.updateLineItemInCart = (lineItem, quantity, checkout) => (isNil(checkout) ? this.checkoutService.getCheckout() : of(checkout)).pipe(concatMap((checkoutLoaded) => {
1261
- const items = [];
1262
- const index = checkoutLoaded.lineItems?.map((checkoutItem) => checkoutItem.id).indexOf(lineItem.id);
1263
- if (index > -1) {
1264
- checkoutLoaded.lineItems[index].quantity += quantity;
1265
- checkoutLoaded.lineItems[index].pricePaid = lineItem.pricePaid;
1266
- }
1267
- else
1268
- checkoutLoaded.lineItems = items.concat(checkoutLoaded.lineItems ? checkoutLoaded.lineItems.concat([lineItem]) : [lineItem]);
1269
- return this.checkoutService
1270
- .updateCheckoutLineItems(checkoutLoaded)
1271
- .pipe(map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)));
1272
- }));
1256
+ this.checkoutUrl = null;
1273
1257
  this.generateCartObject = (items) => items?.reduce((cart, item) => ({
1274
1258
  ...cart,
1275
1259
  [item.id]: LineItem.toInstance({
@@ -1277,94 +1261,40 @@ class CartService {
1277
1261
  quantity: (cart[item.id]?.quantity || 0) + (item.quantity ? item.quantity : 1),
1278
1262
  }),
1279
1263
  }), {}) || {};
1280
- this.buildLineItem = async ({ checkout, item, quantity, }) => {
1281
- const product = await this.getProductData(item.id);
1282
- 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.');
1285
- 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
- });
1293
- RoundProductPricesHelper.roundProductPrices(item);
1294
- return {
1295
- checkout,
1296
- lineItem: LineItem.toInstance({
1297
- id,
1298
- name: name ?? product.name,
1299
- EAN: EAN ?? product.EAN,
1300
- brand: product.brand,
1301
- slug: slug ?? product.slug,
1302
- sku: sku ?? product.sku,
1303
- stock,
1304
- price: this.roundPrice(price),
1305
- image,
1306
- weight: weight ?? product.weight,
1307
- quantity: (item.quantity || 0) + (quantity || 0),
1308
- pricePaid,
1309
- categories: product.categories ?? [],
1310
- isGift: isGift ?? null,
1311
- costPrice: product.costPrice ?? 0,
1312
- type,
1313
- }),
1314
- };
1315
- };
1316
- this.getProductPrice = ({ product, isSubscriber, }) => {
1317
- const info = product.price;
1318
- if (product.isGift)
1319
- return 0;
1320
- return isSubscriber && info.subscriberPrice > 0
1321
- ? Number(info.subscriberPrice.toFixed(2))
1322
- : Number(info.price.toFixed(2));
1323
- };
1324
- this.checkMaxStock = (item, quantity) => {
1325
- const maxStock = item.stock?.quantity || 0;
1326
- const currentItemAmount = item.quantity || 0;
1327
- return currentItemAmount + quantity > maxStock;
1328
- };
1264
+ this.checkoutUrl = `https://southamerica-east1-${this.firebaseOptions.projectId}.cloudfunctions.net`;
1329
1265
  }
1330
1266
  addItem(item, quantity = 1) {
1331
- return from(this.checkoutService.getCheckout()).pipe(concatMap(async (checkout) => await this.buildLineItem({ checkout, item, quantity: quantity || 1 })), mergeMap(({ checkout, lineItem }) => this.updateLineItemInCart(lineItem, quantity || 1, checkout)), tap((cart) => this.cartSubject.next(cart)));
1267
+ return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutAddItemToCart`, {
1268
+ checkoutId: checkout.id,
1269
+ productId: item.id,
1270
+ quantity,
1271
+ })), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1332
1272
  }
1333
1273
  decreaseItem(item) {
1334
- return this.checkoutService.getCheckout().pipe(map((checkout) => {
1335
- const checkoutItem = checkout.lineItems?.find((lineItem) => lineItem.id === item.id);
1336
- if (!isNil(checkoutItem))
1337
- checkoutItem.quantity -= checkoutItem.quantity > 1 ? 1 : 0;
1338
- return checkout;
1339
- }), concatMap((checkout) => this.checkoutService.updateCheckoutLineItems(checkout)), map((checkout) => this.generateCartObject(checkout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1340
- }
1341
- getCart(checkout) {
1342
- this.buildCartFromCheckout(checkout).subscribe((cart) => this.cartSubject.next(cart));
1343
- return this.cartSubject;
1344
- }
1345
- /**
1346
- * @deprecated The method should not be used
1347
- */
1348
- getVariantPriceDiscount(item) {
1349
- return this.authService.getUser().pipe(concatMap((user) => iif(() => user.isSubscriber && !!item.price.subscriberPrice, of(item.price.subscriberPrice), of(item.price.price))), catchError(() => of(item.price.price)));
1274
+ return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutDecreaseProductFromCart`, {
1275
+ checkoutId: checkout.id,
1276
+ productId: item.id,
1277
+ quantity: 1,
1278
+ })), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1350
1279
  }
1351
1280
  removeItem(item) {
1352
- return this.checkoutService.getCheckout().pipe(map((checkout) => {
1353
- const index = checkout.lineItems.findIndex((lineItem) => lineItem.id === item.id);
1354
- if (index >= 0)
1355
- checkout.lineItems.splice(index, 1);
1356
- return checkout;
1357
- }), concatMap((checkout) => this.checkoutService.updateCheckoutLineItems(checkout)), map((checkout) => this.generateCartObject(checkout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1281
+ return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.http.post(`${this.checkoutUrl}/checkoutRemoveProductFromCart`, {
1282
+ checkoutId: checkout.id,
1283
+ productId: item.id,
1284
+ })), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => this.generateCartObject(updatedCheckout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1358
1285
  }
1359
1286
  updateUserCart(user) {
1360
- return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.checkoutService.updateCheckoutUser(Checkout.toInstance({ ...checkout.toPlain(), user }))), concatMap(async (checkout) => this.checkoutService
1361
- .updateCheckoutLineItems(Checkout.toInstance({
1362
- ...checkout.toPlain(),
1363
- lineItems: checkout.lineItems?.length
1364
- ? await Promise.all(checkout.lineItems?.map(async (item) => (await this.buildLineItem({ checkout, item })).lineItem))
1365
- : [],
1366
- }))
1367
- .toPromise()), map((checkout) => this.generateCartObject(checkout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1287
+ return this.checkoutService.getCheckout().pipe(concatMap((checkout) => this.checkoutService.updateCheckoutUser(Checkout.toInstance({ ...checkout.toPlain(), user }))), concatMap((checkout) => {
1288
+ return this.http.post(`${this.checkoutUrl}/checkoutUpdateUserCart`, {
1289
+ checkoutId: checkout.id,
1290
+ });
1291
+ }), concatMap(() => this.checkoutService.getCheckout()), map((updatedCheckout) => {
1292
+ return this.generateCartObject(updatedCheckout.lineItems);
1293
+ }), tap((cart) => this.cartSubject.next(cart)));
1294
+ }
1295
+ getCart(checkout) {
1296
+ this.buildCartFromCheckout(checkout).subscribe((cart) => this.cartSubject.next(cart));
1297
+ return this.cartSubject;
1368
1298
  }
1369
1299
  clearCart() {
1370
1300
  return this.checkoutService.getCheckout().pipe(map((checkout) => {
@@ -1375,147 +1305,18 @@ class CartService {
1375
1305
  buildCartFromCheckout(checkoutData) {
1376
1306
  return this.checkoutService.getCheckout(checkoutData).pipe(map((checkout) => checkout.lineItems), concatMap((lineItems) => of(this.generateCartObject(lineItems))));
1377
1307
  }
1378
- roundPrice(productPrice) {
1379
- const { price, fullPrice, subscriberPrice } = productPrice;
1380
- return {
1381
- ...productPrice,
1382
- price: Number(price.toFixed(2)),
1383
- fullPrice: Number(fullPrice.toFixed(2)),
1384
- ...(subscriberPrice && { subscriberPrice: Number(subscriberPrice.toFixed(2)) }),
1385
- };
1386
- }
1387
- async getProductData(productId) {
1388
- let product;
1389
- let variant;
1390
- try {
1391
- product = await this.productRepository.get({ id: productId });
1392
- }
1393
- catch (error) {
1394
- if (!(error instanceof NotFoundError))
1395
- throw error;
1396
- const { data: variants } = await this.variantRepository.find({ filters: { id: productId } });
1397
- variant = variants.shift();
1398
- if (!variant)
1399
- throw error;
1400
- product = await this.productRepository.get({ id: variant.productId });
1401
- }
1402
- return {
1403
- ...product.toPlain(),
1404
- ...(variant && { ...variant.toPlain() }),
1405
- };
1406
- }
1407
- getGifts() {
1408
- return this.checkoutService.getCheckout().pipe(mergeMap(async (checkout) => {
1409
- const notGiftItems = checkout.lineItems ? checkout.lineItems.filter((item) => !item.isGift) : [];
1410
- if (!notGiftItems.length)
1411
- return { ...checkout, lineItems: [] };
1412
- const cartTotal = notGiftItems.reduce((a, b) => a + b.pricePaid * b.quantity, 0);
1413
- const campaigns = await this.buy2WinRepository
1414
- .find({
1415
- filters: {
1416
- active: { operator: Where.EQUALS, value: true },
1417
- shop: { operator: Where.EQUALS, value: this.defaultShop },
1418
- },
1419
- })
1420
- .then((data) => data.data);
1421
- if (!campaigns.length)
1422
- return { ...checkout, lineItems: notGiftItems };
1423
- const elegibleCampaigns = [];
1424
- for (const campaign of campaigns) {
1425
- const today = new Date().getTime();
1426
- if (!(campaign.startDate.getTime() <= today) && !(campaign.endDate.getTime() >= today))
1427
- continue;
1428
- if (campaign.activeCategory) {
1429
- const categoriesCampaing = campaign.categories.map((c) => c.id.toString());
1430
- const categoriesCampaingFullTree = [];
1431
- for (const id of categoriesCampaing) {
1432
- const children = await this.categoryRepository.getChildren(parseInt(id));
1433
- categoriesCampaingFullTree.push(id, ...children.map((c) => c.id.toString()));
1434
- }
1435
- const categoriesCampaingTree = [...new Set(categoriesCampaingFullTree)];
1436
- const filterProductsCategories = checkout.lineItems.filter((l) => {
1437
- if (!l.categories || !l.categories?.length)
1438
- return true;
1439
- return l.categories.some((c) => categoriesCampaingTree.some((cat) => cat == c));
1440
- });
1441
- if (filterProductsCategories.length) {
1442
- const cartTotalCategories = filterProductsCategories.reduce((a, b) => a + b.pricePaid * b.quantity, 0);
1443
- if (cartTotalCategories >= campaign.cartValueMin)
1444
- elegibleCampaigns.push(campaign);
1445
- }
1446
- }
1447
- else {
1448
- if (campaign.cartValue && campaign.cartValue > 0) {
1449
- if (campaign.cartValue <= cartTotal)
1450
- elegibleCampaigns.push(campaign);
1451
- }
1452
- }
1453
- }
1454
- if (!elegibleCampaigns.length)
1455
- return { ...checkout, lineItems: notGiftItems };
1456
- const campaingnProducts = [];
1457
- for (const campaign of elegibleCampaigns) {
1458
- let elegibleProducts = [];
1459
- for (const product of campaign.products) {
1460
- const { data: productData } = await this.productRepository.find({ filters: { sku: product } });
1461
- if (!productData.length)
1462
- continue;
1463
- const gift = productData.shift();
1464
- if (gift.stock.quantity < 1)
1465
- continue;
1466
- elegibleProducts.push(gift);
1467
- }
1468
- campaingnProducts.push(elegibleProducts);
1469
- }
1470
- if (!campaingnProducts.length)
1471
- return { ...checkout, lineItems: notGiftItems };
1472
- const gifts = this.giftToLineItems([].concat(...campaingnProducts));
1473
- return { ...checkout, lineItems: notGiftItems.concat(gifts) };
1474
- }), concatMap((checkout) => this.checkoutService.updateCheckoutLineItems(checkout)), map((checkout) => this.generateCartObject(checkout.lineItems)), tap((cart) => this.cartSubject.next(cart)));
1475
- }
1476
- giftToLineItems(items) {
1477
- return items.map((item) => {
1478
- const { brand, categories, id, name, price, sku, slug, stock, weight, EAN } = item;
1479
- const image = item?.miniatures?.length ? item.miniatures[0] : item.images[0];
1480
- return LineItem.toInstance({
1481
- brand,
1482
- categories,
1483
- id: id.toString(),
1484
- name,
1485
- price,
1486
- sku,
1487
- slug,
1488
- stock,
1489
- weight,
1490
- EAN,
1491
- image,
1492
- pricePaid: 0,
1493
- quantity: 1,
1494
- isGift: true,
1495
- });
1496
- });
1497
- }
1498
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CartService, deps: [{ token: AuthService }, { token: CheckoutService }, { token: DEFAULT_SHOP }, { token: 'ProductRepository' }, { token: 'CategoryRepository' }, { token: 'VariantRepository' }, { token: 'Buy2WinRepository' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1308
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CartService, deps: [{ token: AuthService }, { token: CheckoutService }, { token: DEFAULT_SHOP }, { token: FIREBASE_OPTIONS }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
1499
1309
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CartService }); }
1500
1310
  }
1501
1311
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CartService, decorators: [{
1502
1312
  type: Injectable
1503
- }], ctorParameters: () => [{ type: AuthService }, { type: CheckoutService }, { type: i1$2.Shops, decorators: [{
1313
+ }], ctorParameters: () => [{ type: AuthService }, { type: CheckoutService }, { type: i1$3.Shops, decorators: [{
1504
1314
  type: Inject,
1505
1315
  args: [DEFAULT_SHOP]
1506
1316
  }] }, { type: undefined, decorators: [{
1507
1317
  type: Inject,
1508
- args: ['ProductRepository']
1509
- }] }, { type: undefined, decorators: [{
1510
- type: Inject,
1511
- args: ['CategoryRepository']
1512
- }] }, { type: undefined, decorators: [{
1513
- type: Inject,
1514
- args: ['VariantRepository']
1515
- }] }, { type: i1$2.Buy2WinFirestoreRepository, decorators: [{
1516
- type: Inject,
1517
- args: ['Buy2WinRepository']
1518
- }] }] });
1318
+ args: [FIREBASE_OPTIONS]
1319
+ }] }, { type: i1$2.HttpClient }] });
1519
1320
 
1520
1321
  class NewCategoryStructureAdapter {
1521
1322
  constructor(categoryRepository) {
@@ -1541,9 +1342,11 @@ class NewCategoryStructureAdapter {
1541
1342
  .then((categories) => categories.map((category) => category.id.toString()));
1542
1343
  }
1543
1344
  async getCategory(category) {
1544
- return isNil(category.isCollection) || (category.isCollection && !category.products?.length)
1545
- ? this.categoryRepository.get({ id: category.id })
1546
- : category;
1345
+ const collectionCategory = category.isCollection ||
1346
+ (isNil(category.isCollection) && !category.products?.length) ||
1347
+ category.isWishlist ||
1348
+ category.brandCategory;
1349
+ return collectionCategory ? this.categoryRepository.get({ id: category.id }) : category;
1547
1350
  }
1548
1351
  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
1352
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NewCategoryStructureAdapter }); }
@@ -1576,13 +1379,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1576
1379
  }] }] });
1577
1380
 
1578
1381
  class CatalogService {
1579
- constructor(productRepository, categoryRepository, categoryStructureAdapter, shop, productIndex) {
1382
+ constructor(productRepository, productStockNotificationRepository, categoryRepository, categoryStructureAdapter, shop, productSearch) {
1580
1383
  this.productRepository = productRepository;
1384
+ this.productStockNotificationRepository = productStockNotificationRepository;
1581
1385
  this.categoryRepository = categoryRepository;
1582
1386
  this.categoryStructureAdapter = categoryStructureAdapter;
1583
1387
  this.shop = shop;
1584
- this.productIndex = productIndex;
1388
+ this.productSearch = productSearch;
1585
1389
  this.productsByTerm = {};
1390
+ this.brandsList = {};
1586
1391
  this.buildFilterQuery = ({ clubDiscount, brands, prices, gender, tags, rate, customOptions, }) => {
1587
1392
  const filters = {};
1588
1393
  if (clubDiscount?.length)
@@ -1593,7 +1398,7 @@ class CatalogService {
1593
1398
  filters.gender = { operator: Where.IN, value: gender };
1594
1399
  if (prices?.min || prices?.max)
1595
1400
  set(filters, prices.subscriberPrice ? 'price.subscriberPrice' : 'price.price', [
1596
- ...(prices.min ? [{ operator: Where.GTE, value: Math.round(prices.min) }] : []),
1401
+ ...(prices.min ? [{ operator: Where.GTE, value: Math.floor(prices.min) }] : []),
1597
1402
  ...(prices.max ? [{ operator: Where.LTE, value: Math.ceil(prices.max) }] : []),
1598
1403
  ]);
1599
1404
  if (rate)
@@ -1608,17 +1413,22 @@ class CatalogService {
1608
1413
  if (!sort || sort === 'most-relevant')
1609
1414
  return {};
1610
1415
  if (sort === 'best-sellers')
1611
- return { shoppingCount: 'desc' };
1416
+ return {
1417
+ shoppingCount: 'desc',
1418
+ rate: 'desc',
1419
+ stock: 'desc',
1420
+ name: 'asc',
1421
+ };
1612
1422
  if (sort === 'biggest-price')
1613
- return { subscriberPrice: 'desc' };
1423
+ return { subscriberPrice: 'desc', rate: 'desc', shoppingCount: 'desc' };
1614
1424
  if (sort === 'lowest-price')
1615
- return { subscriberPrice: 'asc' };
1425
+ return { subscriberPrice: 'asc', rate: 'desc', shoppingCount: 'desc' };
1616
1426
  if (sort === 'best-rating')
1617
- return { rate: 'desc' };
1427
+ return { rate: 'desc', shoppingCount: 'desc', stock: 'desc', name: 'asc' };
1618
1428
  if (sort === 'news')
1619
1429
  return { createdAt: 'desc' };
1620
1430
  if (sort === 'biggest-discount')
1621
- return { subscriberDiscountPercentage: 'desc' };
1431
+ return { subscriberDiscountPercentage: 'desc', rate: 'desc', shoppingCount: 'desc' };
1622
1432
  };
1623
1433
  this.buildLimitQuery = (options) => {
1624
1434
  const limit = options?.perPage || 20;
@@ -1630,6 +1440,15 @@ class CatalogService {
1630
1440
  this.hasProfile = (options) => 'profile' in options;
1631
1441
  this.hasTerm = (options) => 'term' in options;
1632
1442
  this.hasCategory = (options) => 'category' in options;
1443
+ this.buildIndexBrands = (options) => {
1444
+ if (this.hasCategory(options))
1445
+ return `category-${options.category.id}`;
1446
+ if (this.hasTerm(options))
1447
+ return `term-${options.term}`;
1448
+ if (this.hasProfile(options))
1449
+ return `profile-${options.profile.join(',')}`;
1450
+ return '';
1451
+ };
1633
1452
  }
1634
1453
  async fetchProducts(options) {
1635
1454
  const limits = this.buildLimitQuery(options);
@@ -1639,29 +1458,42 @@ class CatalogService {
1639
1458
  throw new InvalidArgumentError(`It couldn't filled tags when profile is given`);
1640
1459
  if (this.hasTerm(options) && options.filters?.customOptions)
1641
1460
  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),
1461
+ return await this.findCatalog(options, limits).then(async ({ data, count: total, maximum, minimal, distinct }) => {
1462
+ await this.setBrandsList(options, distinct?.brand);
1463
+ return {
1464
+ products: { data: data.map((product) => RoundProductPricesHelper.roundProductPrices(product)), total },
1465
+ pages: Math.ceil(total / limits.limit),
1466
+ prices: {
1467
+ price: { min: +minimal?.price?.price?.toFixed(2), max: +maximum?.price?.price?.toFixed(2) },
1468
+ subscriberPrice: {
1469
+ min: +minimal?.price?.subscriberPrice?.toFixed(2),
1470
+ max: +maximum?.price?.subscriberPrice?.toFixed(2),
1471
+ },
1650
1472
  },
1651
- },
1652
- brands: distinct?.brand,
1653
- }));
1473
+ brands: this.brandsList[this.buildIndexBrands(options)],
1474
+ };
1475
+ });
1476
+ }
1477
+ async addCustomerToStockNotification(shop, productId, name, email) {
1478
+ return this.productStockNotificationRepository.addCustomerEmail(shop, productId, name, email);
1654
1479
  }
1655
1480
  async findCatalog(options, limits) {
1656
1481
  if (this.hasTerm(options) && options.sort === 'most-relevant') {
1657
- const productsIds = await this.findCatalogIdsByElasticSearch(options.term);
1658
- return this.findCatalogAndSortByMostRevelant(productsIds, options, limits);
1482
+ const productsIds = await this.findCatalogIdsBySearch(options.term);
1483
+ return this.findCatalogAndSortByMostRevelantByTerm(productsIds, options, limits);
1659
1484
  }
1660
1485
  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);
1486
+ const mostRelevant = options.category.isWishlist ? [] : options.category.getMostRelevantByShop(this.shop);
1487
+ const productsIds = await this.productRepository
1488
+ .findCatalog({
1489
+ fields: ['id'],
1490
+ filters: {
1491
+ ...(await this.buildMainFilter(options)),
1492
+ ...this.buildFilterQuery(options?.filters || {}),
1493
+ },
1494
+ })
1495
+ .then((products) => products.data.map((product) => product.id));
1496
+ return this.findCatalogAndSortByMostRevelant(mostRelevant, productsIds, options, limits);
1665
1497
  }
1666
1498
  const repoParams = {
1667
1499
  filters: {
@@ -1673,7 +1505,9 @@ class CatalogService {
1673
1505
  options: {
1674
1506
  minimal: ['price'],
1675
1507
  maximum: ['price'],
1676
- ...(!this.hasCategory(options) ? { distinct: ['brand'] } : {}),
1508
+ ...(!this.brandsList[this.buildIndexBrands(options)] && isEmpty(options.filters?.brands)
1509
+ ? { distinct: ['brand'] }
1510
+ : {}),
1677
1511
  },
1678
1512
  };
1679
1513
  if (['biggest-price', 'lowest-price', 'biggest-discount', 'best-rating'].includes(options.sort))
@@ -1686,27 +1520,72 @@ class CatalogService {
1686
1520
  if (profile)
1687
1521
  return { tags: { operator: Where.LIKE, value: profile } };
1688
1522
  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) } }));
1523
+ return this.productSearch
1524
+ .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
1525
+ .then((data) => ({ id: { operator: Where.IN, value: data.map((_source) => _source.id) } }));
1526
+ }
1527
+ async findCatalogAndSortByMostRevelant(mostRelevants, productIds, options, limits) {
1528
+ const brandsList = this.brandsList[this.buildIndexBrands(options)];
1529
+ const mostRelevantProductsIds = [...new Set(mostRelevants.concat(productIds))];
1530
+ const totalResult = await this.productRepository.findCatalog({
1531
+ filters: {
1532
+ id: { operator: Where.IN, value: mostRelevantProductsIds },
1533
+ ...this.buildFilterQuery(options?.filters || {}),
1534
+ },
1535
+ orderBy: this.buildSortQuery('best-sellers'),
1536
+ options: {
1537
+ minimal: ['price'],
1538
+ maximum: ['price'],
1539
+ ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
1540
+ },
1541
+ }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
1542
+ const mostRelevantWithouyStock = totalResult.data.filter((product) => mostRelevants.includes(product.id) && product.stock.quantity <= 0);
1543
+ const firstProducts = totalResult.data
1544
+ .filter((product) => mostRelevants.includes(product.id) && product.stock.quantity > 0)
1545
+ .sort((a, b) => mostRelevants.indexOf(a.id) - mostRelevants.indexOf(b.id));
1546
+ const lastProducts = totalResult.data
1547
+ .filter((product) => !mostRelevants.includes(product.id))
1548
+ .concat(mostRelevantWithouyStock);
1549
+ const categoryMostRelevants = firstProducts.concat(lastProducts);
1550
+ const resultFinal = categoryMostRelevants.slice(limits.offset, limits.offset + limits.limit);
1551
+ await this.setBrandsList(options, totalResult.distinct?.brand);
1552
+ return {
1553
+ data: resultFinal,
1554
+ count: totalResult.count,
1555
+ maximum: totalResult.maximum,
1556
+ minimal: totalResult.minimal,
1557
+ distinct: {
1558
+ ...totalResult.distinct,
1559
+ brand: this.brandsList[this.buildIndexBrands(options)],
1560
+ },
1561
+ };
1692
1562
  }
1693
- async findCatalogAndSortByMostRevelant(productIds, options, limits) {
1563
+ async findCatalogAndSortByMostRevelantByTerm(productIds, options, limits) {
1564
+ const brandsList = this.brandsList[this.buildIndexBrands(options)];
1694
1565
  const totalResult = await this.productRepository.findCatalog({
1695
- fields: ['id', 'stock'],
1566
+ fields: ['id', 'stock', 'gender'],
1696
1567
  filters: {
1697
1568
  id: { operator: Where.IN, value: productIds },
1569
+ published: { operator: Where.EQUALS, value: true },
1698
1570
  ...this.buildFilterQuery(options?.filters || {}),
1699
1571
  },
1700
1572
  options: {
1701
1573
  minimal: ['price'],
1702
1574
  maximum: ['price'],
1703
- distinct: ['brand'],
1575
+ ...(!brandsList && isEmpty(options.filters?.brands) ? { distinct: ['brand'] } : {}),
1704
1576
  },
1705
1577
  }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female');
1578
+ const defaultGender = options?.filters?.gender
1579
+ ? options?.filters?.gender.at(0)
1580
+ : this.shop === Shops.GLAMSHOP
1581
+ ? 'female'
1582
+ : 'male';
1706
1583
  const stockData = totalResult.data.filter((product) => product.stock.quantity > 0);
1707
1584
  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));
1585
+ const productIdsStockGender = productIds.filter((product) => stockData.some((result) => result.id === product && (result.gender?.includes(defaultGender) || result.gender?.includes('unisex'))));
1586
+ const productIdsStockNotGender = productIds.filter((product) => stockData.some((result) => result.id === product && !result.gender?.includes(defaultGender) && !result.gender?.includes('unisex')));
1587
+ const productIdsStock = productIdsStockGender.concat(productIdsStockNotGender);
1588
+ const productIdsStockOut = productIds.filter((product) => stockOut.some((result) => result.id === product));
1710
1589
  const limitedProductId = productIdsStock
1711
1590
  .concat(productIdsStockOut)
1712
1591
  .slice(limits.offset, limits.offset + limits.limit);
@@ -1716,27 +1595,55 @@ class CatalogService {
1716
1595
  id: { operator: Where.IN, value: orderedId },
1717
1596
  },
1718
1597
  });
1598
+ await this.setBrandsList(options, totalResult.distinct?.brand);
1719
1599
  return {
1720
1600
  data: limitedProductId.map((id) => productResult.data.find((product) => product.id === id)).filter(Boolean),
1721
1601
  count: totalResult.count,
1722
1602
  maximum: totalResult.maximum,
1723
1603
  minimal: totalResult.minimal,
1724
- distinct: totalResult.distinct,
1604
+ distinct: {
1605
+ ...totalResult.distinct,
1606
+ brand: this.brandsList[this.buildIndexBrands(options)],
1607
+ },
1725
1608
  };
1726
1609
  }
1727
- async findCatalogIdsByElasticSearch(term) {
1610
+ async findCatalogIdsBySearch(term, preview = false) {
1728
1611
  if (this.productsByTerm[term])
1729
1612
  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
- }));
1613
+ return (this.productsByTerm[term] = await this.productSearch
1614
+ .search(term, 999, this.shop == Shops.GLAMSHOP ? 'female' : 'male')
1615
+ .then((products) => [...new Set(products.map((product) => product.id))]));
1738
1616
  }
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 }); }
1617
+ async fetchBrandsOnly(options, productIds = []) {
1618
+ return this.productRepository
1619
+ .findCatalog({
1620
+ fields: ['id'],
1621
+ filters: {
1622
+ ...(!isEmpty(productIds) ? { id: { operator: Where.IN, value: productIds } } : {}),
1623
+ published: { operator: Where.EQUALS, value: true },
1624
+ ...this.buildFilterQuery(options?.filters || {}),
1625
+ },
1626
+ options: {
1627
+ distinct: ['brand'],
1628
+ },
1629
+ }, options?.mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female')
1630
+ .then((result) => {
1631
+ return result.distinct.brand;
1632
+ });
1633
+ }
1634
+ async setBrandsList(options, brands) {
1635
+ const filterBrands = options.filters?.brands;
1636
+ if (isEmpty(brands))
1637
+ delete options.filters?.brands;
1638
+ this.brandsList[this.buildIndexBrands(options)] =
1639
+ this.brandsList[this.buildIndexBrands(options)] || brands || (await this.fetchBrandsOnly(options));
1640
+ this.brandsList[this.buildIndexBrands(options)] = this.brandsList[this.buildIndexBrands(options)].filter(Boolean);
1641
+ options.filters = {
1642
+ ...options.filters,
1643
+ brands: filterBrands,
1644
+ };
1645
+ }
1646
+ 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
1647
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService }); }
1741
1648
  }
1742
1649
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CatalogService, decorators: [{
@@ -1744,16 +1651,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1744
1651
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1745
1652
  type: Inject,
1746
1653
  args: ['ProductRepository']
1654
+ }] }, { type: undefined, decorators: [{
1655
+ type: Inject,
1656
+ args: ['ProductStockNotificationRepository']
1747
1657
  }] }, { type: undefined, decorators: [{
1748
1658
  type: Inject,
1749
1659
  args: ['CategoryRepository']
1750
1660
  }] }, { type: undefined, decorators: [{
1751
1661
  type: Inject,
1752
1662
  args: [CATEGORY_STRUCTURE]
1753
- }] }, { type: i1$2.Shops, decorators: [{
1663
+ }] }, { type: i1$3.Shops, decorators: [{
1754
1664
  type: Inject,
1755
1665
  args: [DEFAULT_SHOP]
1756
- }] }, { type: i1$2.ProductsIndex }] });
1666
+ }] }, { type: undefined, decorators: [{
1667
+ type: Inject,
1668
+ args: ['ProductSearch']
1669
+ }] }] });
1757
1670
 
1758
1671
  class CategoryService {
1759
1672
  constructor(productRepository, categoryRepository, categoryFilterRepository, categoryStructureAdapter, shop) {
@@ -1763,15 +1676,15 @@ class CategoryService {
1763
1676
  this.categoryStructureAdapter = categoryStructureAdapter;
1764
1677
  this.shop = shop;
1765
1678
  }
1766
- async fetchBrands(category, mainGender) {
1679
+ async fetchBrands(category, options) {
1767
1680
  const brands = await this.productRepository
1768
1681
  .findCatalog({
1769
1682
  filters: await this.categoryStructureAdapter.buildProductFilterByCategory(category),
1770
1683
  fields: ['brand'],
1771
- }, mainGender || this.shop === Shops.MENSMARKET ? 'male' : 'female')
1684
+ }, options?.mainGender ? options?.mainGender : this.shop === Shops.MENSMARKET ? 'male' : 'female')
1772
1685
  .then(({ data }) => Object.keys(data.map((product) => product.brand).reduce((brands, brand) => ({ ...brands, [brand]: true }), {})));
1773
1686
  return this.categoryRepository
1774
- .find({ filters: { brandCategory: true, shop: this.shop }, orderBy: { name: 'asc' } })
1687
+ .find({ filters: { brandCategory: true, shop: options?.shop || this.shop }, orderBy: { name: 'asc' } })
1775
1688
  .then(({ data }) => data.filter((category) => brands.includes(category.conditions.brand)));
1776
1689
  }
1777
1690
  async fetchFilterOptions(category) {
@@ -1796,7 +1709,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1796
1709
  }] }, { type: undefined, decorators: [{
1797
1710
  type: Inject,
1798
1711
  args: [CATEGORY_STRUCTURE]
1799
- }] }, { type: i1$2.Shops, decorators: [{
1712
+ }] }, { type: i1$3.Shops, decorators: [{
1800
1713
  type: Inject,
1801
1714
  args: [DEFAULT_SHOP]
1802
1715
  }] }] });
@@ -1820,11 +1733,14 @@ __decorate([
1820
1733
  ], CategoryWithTree.prototype, "children", void 0);
1821
1734
 
1822
1735
  class WishlistService {
1823
- constructor(wishlistRepository, shop, productRepository, categoryFilterRepository, categoryRepository, productIndex) {
1736
+ constructor(wishlistRepository, shop, productRepository, categoryFilterRepository, categoryRepository, productStockNotificationRepository, productSearch, logRepository) {
1824
1737
  this.wishlistRepository = wishlistRepository;
1825
1738
  this.shop = shop;
1739
+ this.productRepository = productRepository;
1740
+ this.productSearch = productSearch;
1741
+ this.logRepository = logRepository;
1826
1742
  const categoryStructureAdapter = new NewCategoryStructureAdapter(wishlistRepository);
1827
- this.catalogService = new CatalogService(productRepository, categoryRepository, categoryStructureAdapter, shop, productIndex);
1743
+ this.catalogService = new CatalogService(productRepository, productStockNotificationRepository, categoryRepository, categoryStructureAdapter, shop, productSearch);
1828
1744
  this.categoryService = new CategoryService(productRepository, categoryRepository, categoryFilterRepository, categoryStructureAdapter, shop);
1829
1745
  }
1830
1746
  getCatalogService() {
@@ -1833,46 +1749,76 @@ class WishlistService {
1833
1749
  getCategoryService() {
1834
1750
  return this.categoryService;
1835
1751
  }
1836
- async create({ personId, title, description, userFullName, userPhoto, theme, bannerUrl, }) {
1752
+ async create({ personId, title, description, published, userFullName, userPhoto, theme, bannerUrl, personType, personIsSubscriber, }) {
1837
1753
  const data = {
1838
1754
  slug: '',
1839
1755
  name: title,
1840
1756
  description,
1841
- metadata: {
1842
- title: `${userFullName} - ${title}`,
1843
- description: `${userFullName} - ${description}`,
1844
- },
1757
+ metadatas: [
1758
+ {
1759
+ shop: this.shop,
1760
+ title: `${userFullName} - ${title}`,
1761
+ description: `${userFullName} - ${description}`,
1762
+ },
1763
+ ],
1845
1764
  shop: this.shop,
1846
1765
  shops: [this.shop],
1847
1766
  personId,
1848
1767
  personName: userFullName,
1849
1768
  personPhoto: userPhoto,
1850
1769
  brandCategory: false,
1851
- published: true,
1770
+ published,
1852
1771
  theme,
1853
1772
  bannerUrl,
1773
+ personType: personType ?? PersonTypes.NONE,
1774
+ personIsSubscriber: personIsSubscriber ?? false,
1854
1775
  };
1776
+ const hasWishlist = await this.wishlistRepository
1777
+ .find({
1778
+ filters: {
1779
+ personId,
1780
+ },
1781
+ options: {
1782
+ enableCount: false,
1783
+ },
1784
+ orderBy: {
1785
+ id: 'asc',
1786
+ },
1787
+ })
1788
+ .then((res) => res.data);
1789
+ await this.createWishlistLog(WishlistLogType.CREATE, data);
1790
+ if (hasWishlist.length)
1791
+ return hasWishlist.at(0);
1855
1792
  const newWishlist = await this.wishlistRepository.create(data);
1856
1793
  await this.wishlistRepository.update({ id: newWishlist.id, slug: newWishlist.id });
1857
1794
  return Wishlist.toInstance({ ...newWishlist.toPlain(), slug: newWishlist.id });
1858
1795
  }
1859
- update({ id, title, description, userFullName, userPhoto, theme, bannerUrl, }) {
1796
+ async update({ id, title, description, published, userFullName, userPhoto, theme, bannerUrl, personType, personIsSubscriber, }) {
1860
1797
  const data = {
1861
1798
  id,
1862
1799
  name: title,
1863
1800
  description,
1864
- metadata: {
1865
- title: `${userFullName} - ${title}`,
1866
- description: `${userFullName} - ${description}`,
1867
- },
1801
+ published,
1802
+ metadatas: [
1803
+ {
1804
+ shop: this.shop,
1805
+ title: `${userFullName} - ${title}`,
1806
+ description: `${userFullName} - ${description}`,
1807
+ },
1808
+ ],
1868
1809
  personName: userFullName,
1869
1810
  personPhoto: userPhoto,
1870
1811
  theme,
1871
1812
  bannerUrl,
1813
+ personType: personType ?? PersonTypes.NONE,
1814
+ personIsSubscriber: personIsSubscriber ?? false,
1872
1815
  };
1816
+ await this.createWishlistLog(WishlistLogType.UPDATE, data);
1873
1817
  return this.wishlistRepository.update(data);
1874
1818
  }
1875
- delete(wishlistId) {
1819
+ async delete(wishlistId) {
1820
+ const wishlist = await this.findById(wishlistId);
1821
+ await this.createWishlistLog(WishlistLogType.DELETE, wishlist);
1876
1822
  return this.wishlistRepository.delete({ id: wishlistId });
1877
1823
  }
1878
1824
  getWishlistBySlug(slug) {
@@ -1887,9 +1833,12 @@ class WishlistService {
1887
1833
  async addProduct(wishlistId, productId) {
1888
1834
  const wishlist = await this.wishlistRepository.get({ id: wishlistId });
1889
1835
  const hasProduct = wishlist.products.some((p) => p == productId);
1836
+ const wishlistData = await this.findById(wishlistId);
1837
+ const productData = await this.findProductById(productId);
1838
+ await this.createWishlistLog(WishlistLogType.ADD_PRODUCT, wishlistData, productData);
1890
1839
  if (!hasProduct) {
1891
1840
  wishlist.products = [...wishlist.products, productId];
1892
- return this.wishlistRepository.update({ id: wishlistId, products: wishlist.products });
1841
+ await this.wishlistRepository.addProduct(wishlistId, productId);
1893
1842
  }
1894
1843
  return wishlist;
1895
1844
  }
@@ -1898,13 +1847,88 @@ class WishlistService {
1898
1847
  const productIndex = wishlist.products.findIndex((p) => p == productId);
1899
1848
  if (productIndex != -1) {
1900
1849
  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 });
1850
+ const wishlistData = await this.findById(wishlistId);
1851
+ const productData = await this.findProductById(productId);
1852
+ await this.createWishlistLog(WishlistLogType.REMOVE_PRODUCT, wishlistData, productData);
1853
+ await this.wishlistRepository.removeProduct(wishlistId, productId);
1904
1854
  }
1905
1855
  return wishlist;
1906
1856
  }
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 }); }
1857
+ async findById(id) {
1858
+ return this.wishlistRepository
1859
+ .find({
1860
+ fields: ['id', 'name', 'description', 'personId', 'personIsSubscriber', 'personType', 'personName'],
1861
+ filters: {
1862
+ id,
1863
+ },
1864
+ })
1865
+ .then((res) => res.data.at(0));
1866
+ }
1867
+ async findProductById(id) {
1868
+ return this.productRepository
1869
+ .find({
1870
+ fields: ['id', 'sku', 'EAN', 'name', 'brand'],
1871
+ filters: {
1872
+ id,
1873
+ },
1874
+ })
1875
+ .then((res) => res.data.at(0));
1876
+ }
1877
+ async createWishlistLog(type, wishlist, product) {
1878
+ switch (type) {
1879
+ case WishlistLogType.CREATE:
1880
+ case WishlistLogType.UPDATE:
1881
+ case WishlistLogType.DELETE:
1882
+ await this.logRepository.create({
1883
+ collection: 'wishlist',
1884
+ date: new Date(),
1885
+ operation: WishlistLogType.CREATE ? 'CREATE' : WishlistLogType.UPDATE ? 'UPDATE' : 'DELETE',
1886
+ documentId: wishlist.id,
1887
+ document: {
1888
+ id: wishlist.id,
1889
+ shop: this.shop,
1890
+ name: wishlist.name,
1891
+ description: wishlist.description,
1892
+ published: wishlist.published,
1893
+ type: type,
1894
+ personType: wishlist.personType,
1895
+ personId: wishlist.personId,
1896
+ personName: wishlist.personName,
1897
+ personIsSubscriber: wishlist.personIsSubscriber,
1898
+ },
1899
+ });
1900
+ break;
1901
+ case WishlistLogType.ADD_PRODUCT:
1902
+ case WishlistLogType.REMOVE_PRODUCT:
1903
+ await this.logRepository.create({
1904
+ collection: 'wishlist',
1905
+ date: new Date(),
1906
+ operation: 'UPDATE',
1907
+ documentId: wishlist.id,
1908
+ document: {
1909
+ id: wishlist.id,
1910
+ shop: this.shop,
1911
+ name: wishlist.name,
1912
+ description: wishlist.description,
1913
+ published: wishlist.published,
1914
+ type: type,
1915
+ personType: wishlist.personType,
1916
+ personId: wishlist.personId,
1917
+ personName: wishlist.personName,
1918
+ personIsSubscriber: wishlist.personIsSubscriber,
1919
+ productId: product.id,
1920
+ productEAN: product.EAN,
1921
+ productSKU: product.sku,
1922
+ productName: product.name,
1923
+ productBrand: product.brand,
1924
+ },
1925
+ });
1926
+ break;
1927
+ default:
1928
+ break;
1929
+ }
1930
+ }
1931
+ 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
1932
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: WishlistService }); }
1909
1933
  }
1910
1934
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: WishlistService, decorators: [{
@@ -1912,7 +1936,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1912
1936
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1913
1937
  type: Inject,
1914
1938
  args: ['WishlistRepository']
1915
- }] }, { type: i1$2.Shops, decorators: [{
1939
+ }] }, { type: i1$3.Shops, decorators: [{
1916
1940
  type: Inject,
1917
1941
  args: [DEFAULT_SHOP]
1918
1942
  }] }, { type: undefined, decorators: [{
@@ -1924,31 +1948,251 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1924
1948
  }] }, { type: undefined, decorators: [{
1925
1949
  type: Inject,
1926
1950
  args: ['CategoryRepository']
1927
- }] }, { type: i1$2.ProductsIndex }] });
1951
+ }] }, { type: undefined, decorators: [{
1952
+ type: Inject,
1953
+ args: ['ProductStockNotificationRepository']
1954
+ }] }, { type: undefined, decorators: [{
1955
+ type: Inject,
1956
+ args: ['ProductSearch']
1957
+ }] }, { type: undefined, decorators: [{
1958
+ type: Inject,
1959
+ args: ['LogRepository']
1960
+ }] }] });
1961
+
1962
+ class CouponService {
1963
+ constructor(couponRepository, defaultShop, orderRepository, categoryRepository) {
1964
+ this.couponRepository = couponRepository;
1965
+ this.defaultShop = defaultShop;
1966
+ this.orderRepository = orderRepository;
1967
+ this.categoryRepository = categoryRepository;
1968
+ this.emailIsFromCollaborator = (userEmail) => !!userEmail?.match(/@b4a.com.br/g);
1969
+ }
1970
+ checkCoupon(nickname, checkoutType, checkout, plan) {
1971
+ return from(this.couponRepository
1972
+ .find({
1973
+ filters: {
1974
+ nickname: { operator: Where.EQUALS, value: nickname },
1975
+ active: { operator: Where.EQUALS, value: true },
1976
+ },
1977
+ })
1978
+ .then((result) => result.data[0])).pipe(concatMap((coupon) => this.couponValidation(coupon, checkoutType)), concatMap((couponValid) => this.couponRulesValidation(couponValid, checkoutType, checkout, plan)), map((couponValidated) => couponValidated));
1979
+ }
1980
+ async couponValidation(coupon, checkoutType) {
1981
+ if (!coupon)
1982
+ throw 'Cupom inválido.';
1983
+ if (coupon?.beginAt && coupon?.beginAt.getTime() > new Date().getTime())
1984
+ throw 'Cupom inválido.';
1985
+ if (coupon?.expiresIn && (coupon?.expiresIn).getTime() < new Date().getTime())
1986
+ throw 'Cupom expirado.';
1987
+ const isInShop = coupon.shopAvailability === Shops.ALL || coupon.shopAvailability === this.defaultShop;
1988
+ if (!isInShop)
1989
+ throw 'Cupom inválido para loja.';
1990
+ const isCheckoutType = coupon.checkoutType === CheckoutTypes.ALL || coupon.checkoutType === checkoutType;
1991
+ if (!isCheckoutType)
1992
+ throw 'Cupom inválido. Erro de checkout.';
1993
+ return coupon;
1994
+ }
1995
+ async couponRulesValidation(coupon, checkoutType, checkout, plan) {
1996
+ if (checkoutType == CheckoutTypes.SUBSCRIPTION) {
1997
+ if (coupon.plan && coupon.plan.toUpperCase() !== plan.toUpperCase())
1998
+ throw 'Cupom inválido para sua assinatura.';
1999
+ return coupon;
2000
+ }
2001
+ const validUser = this.coupomUserValidation(coupon, checkout?.user);
2002
+ if (!validUser)
2003
+ throw 'Usuário não elegível.';
2004
+ const couponUseLimits = this.getCouponUseLimits(coupon, checkoutType, checkout.user);
2005
+ if (couponUseLimits.firstOrder) {
2006
+ const ordersUser = await this.getOrdersFromUser(checkout.user.email.toLocaleLowerCase());
2007
+ if (couponUseLimits.firstOrder && ordersUser.length >= 1)
2008
+ throw 'Limite de uso atingido';
2009
+ }
2010
+ if (!couponUseLimits.unlimited || couponUseLimits.limitedPerUser) {
2011
+ const ordersCoupon = await this.getOrdersWithCoupon(coupon);
2012
+ if (!couponUseLimits.unlimited && couponUseLimits.total && ordersCoupon.length >= couponUseLimits.total)
2013
+ throw 'Limite de uso atingido.';
2014
+ if (couponUseLimits.limitedPerUser) {
2015
+ const ordersWithUser = this.countOrdersWithUser(ordersCoupon, checkout.user.email);
2016
+ if (ordersWithUser > 0)
2017
+ throw 'Limite de uso por usuário atingido.';
2018
+ }
2019
+ }
2020
+ const hasProductCategories = await this.hasProductCategories(coupon, checkout);
2021
+ if (!hasProductCategories)
2022
+ throw 'Seu carrinho não possui produtos elegíveis para desconto.';
2023
+ const hasMinSubTotal = await this.hasMinSubTotal(coupon, checkout);
2024
+ if (!hasMinSubTotal) {
2025
+ if (coupon.productsCategories?.length) {
2026
+ 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.`;
2027
+ }
2028
+ throw `Valor mínimo de ${Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(coupon.minSubTotalValue)} não atingido.`;
2029
+ }
2030
+ return coupon;
2031
+ }
2032
+ calcDiscountSubscription(coupon, checkout) {
2033
+ let discount = 0;
2034
+ if (coupon.discount.subscription.type == CouponTypes.ABSOLUTE)
2035
+ discount = coupon.discount.subscription.value;
2036
+ else
2037
+ discount = checkout.subscriptionPlan.recurrencePrice * (coupon.discount.subscription.value / 100);
2038
+ return of(discount);
2039
+ }
2040
+ async hasMinSubTotal(coupon, checkout) {
2041
+ if (!coupon.minSubTotalValue)
2042
+ return true;
2043
+ const lineItensDiscount = await this.getLineItensEligebleForDiscount(coupon.productsCategories, checkout);
2044
+ const subTotal = this.calcCheckoutSubtotal(lineItensDiscount, checkout.user);
2045
+ if (coupon.minSubTotalValue <= subTotal)
2046
+ return true;
2047
+ return false;
2048
+ }
2049
+ async hasProductCategories(coupon, checkout) {
2050
+ if (!coupon.productsCategories || !coupon.productsCategories?.length) {
2051
+ return true;
2052
+ }
2053
+ const couponCategories = await this.getCouponCategoriesId(coupon.productsCategories);
2054
+ const hasCategories = checkout.lineItems?.filter((item) => {
2055
+ if (item.isGift)
2056
+ return false;
2057
+ if (!item.categories || !item.categories?.length)
2058
+ return true;
2059
+ return item.categories.some((c) => couponCategories.some((cat) => cat == c));
2060
+ });
2061
+ return hasCategories.length ? true : false;
2062
+ }
2063
+ coupomUserValidation(coupon, user) {
2064
+ if (!user || coupon.exclusivityType.includes(Exclusivities.ALL_USERS))
2065
+ return true;
2066
+ let userTypes = [];
2067
+ if (coupon.exclusivityType.includes(Exclusivities.COLLABORATORS) &&
2068
+ this.emailIsFromCollaborator(user.email.toLocaleLowerCase()))
2069
+ userTypes.push(Exclusivities.COLLABORATORS);
2070
+ if (coupon.exclusivityType.includes(Exclusivities.SPECIFIC_USER) &&
2071
+ coupon.userExclusiveEmail.includes(user.email.toLocaleLowerCase()))
2072
+ userTypes.push(Exclusivities.SPECIFIC_USER);
2073
+ if (coupon.exclusivityType.includes(Exclusivities.ACTIVE_SUBSCRIBER) &&
2074
+ user.isSubscriber &&
2075
+ user.subscriptionPlan != '')
2076
+ userTypes.push(Exclusivities.ACTIVE_SUBSCRIBER);
2077
+ if (user.isSubscriber &&
2078
+ user.subscriptionPlan == '' &&
2079
+ coupon.exclusivityType.includes(Exclusivities.INACTIVE_SUBSCRIBER))
2080
+ userTypes.push(Exclusivities.INACTIVE_SUBSCRIBER);
2081
+ if (coupon.exclusivityType.includes(Exclusivities.NON_SUBSCRIBER) && !user.isSubscriber)
2082
+ userTypes.push(Exclusivities.NON_SUBSCRIBER);
2083
+ return coupon.exclusivityType.some((r) => userTypes.includes(r));
2084
+ }
2085
+ async getCouponCategoriesId(productsCategories) {
2086
+ const couponCategories = [];
2087
+ for (let index = 0; index < productsCategories.length; index++) {
2088
+ const category = await this.categoryRepository.get({
2089
+ id: productsCategories[index],
2090
+ });
2091
+ if (category) {
2092
+ const children = await this.categoryRepository.getChildren(parseInt(productsCategories[index]));
2093
+ couponCategories.push(category.id, ...children.map((c) => c.id.toString()));
2094
+ }
2095
+ }
2096
+ return [...new Set(couponCategories)];
2097
+ }
2098
+ async getLineItensEligebleForDiscount(productsCategories, checkout) {
2099
+ let lineItensDiscount = [];
2100
+ const couponCategories = await this.getCouponCategoriesId(productsCategories);
2101
+ if (productsCategories && productsCategories.length) {
2102
+ lineItensDiscount = checkout.lineItems?.filter((item) => {
2103
+ if (item.isGift)
2104
+ return false;
2105
+ if (item.categories?.length) {
2106
+ return item.categories.some((c) => couponCategories.some((cat) => cat == c));
2107
+ }
2108
+ return true;
2109
+ });
2110
+ }
2111
+ else {
2112
+ lineItensDiscount = checkout.lineItems.filter((item) => !item.isGift);
2113
+ }
2114
+ return lineItensDiscount;
2115
+ }
2116
+ calcCheckoutSubtotal(lineItens, user) {
2117
+ return (lineItens
2118
+ ?.filter((item) => !item.isGift)
2119
+ .reduce((acc, curr) => user?.isSubscriber && curr.price.subscriberPrice
2120
+ ? acc + curr.price?.subscriberPrice * curr.quantity
2121
+ : acc + curr.pricePaid * curr.quantity, 0) || 0);
2122
+ }
2123
+ async getOrdersWithCoupon(coupon) {
2124
+ return await this.orderRepository
2125
+ .find({
2126
+ filters: {
2127
+ coupon: { id: coupon.id },
2128
+ status: { operator: Where.NOTEQUALS, value: OrderStatus.CANCELADO },
2129
+ },
2130
+ })
2131
+ .then((result) => result.data);
2132
+ }
2133
+ async getOrdersFromUser(email) {
2134
+ return await this.orderRepository
2135
+ .find({
2136
+ filters: {
2137
+ user: { email: { operator: Where.EQUALS, value: email } },
2138
+ status: { operator: Where.NOTEQUALS, value: OrderStatus.CANCELADO },
2139
+ },
2140
+ })
2141
+ .then((result) => result.data);
2142
+ }
2143
+ countOrdersWithUser(orders, email) {
2144
+ return orders.filter((o) => o.user.email == email).length;
2145
+ }
2146
+ getCouponUseLimits(coupon, checkoutType, user) {
2147
+ let couponUseLimits;
2148
+ if (checkoutType == CheckoutTypes.ECOMMERCE || checkoutType == CheckoutTypes.ALL) {
2149
+ if (coupon.exclusivityType.length === 1 &&
2150
+ (coupon.exclusivityType.at(0) === Exclusivities.SPECIFIC_USER ||
2151
+ coupon.exclusivityType.at(0) === Exclusivities.COLLABORATORS))
2152
+ couponUseLimits = coupon.useLimits.non_subscriber;
2153
+ else
2154
+ couponUseLimits = user && user.isSubscriber ? coupon.useLimits.subscriber : coupon.useLimits.non_subscriber;
2155
+ }
2156
+ else {
2157
+ couponUseLimits = coupon.useLimits.subscription;
2158
+ }
2159
+ return couponUseLimits;
2160
+ }
2161
+ 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 }); }
2162
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, providedIn: 'root' }); }
2163
+ }
2164
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CouponService, decorators: [{
2165
+ type: Injectable,
2166
+ args: [{
2167
+ providedIn: 'root',
2168
+ }]
2169
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
2170
+ type: Inject,
2171
+ args: ['CouponRepository']
2172
+ }] }, { type: i1$3.Shops, decorators: [{
2173
+ type: Inject,
2174
+ args: [DEFAULT_SHOP]
2175
+ }] }, { type: undefined, decorators: [{
2176
+ type: Inject,
2177
+ args: ['OrderRepository']
2178
+ }] }, { type: undefined, decorators: [{
2179
+ type: Inject,
2180
+ args: ['CategoryRepository']
2181
+ }] }] });
1928
2182
 
1929
2183
  class CheckoutSubscriptionService {
1930
- constructor(checkoutSubscriptionRepository, subscriptionRepository, couponService) {
2184
+ constructor(checkoutSubscriptionRepository, dataPersistence, couponService) {
1931
2185
  this.checkoutSubscriptionRepository = checkoutSubscriptionRepository;
1932
- this.subscriptionRepository = subscriptionRepository;
2186
+ this.dataPersistence = dataPersistence;
1933
2187
  this.couponService = couponService;
1934
2188
  }
1935
2189
  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;
2190
+ return this.dataPersistence
2191
+ .get('checkoutSubscriptionId')
2192
+ .pipe(concatMap((id) => !isNil(id) ? this.checkoutSubscriptionRepository.get({ id }) : this.createCheckoutSubscription(checkoutData)));
1948
2193
  }
1949
2194
  clearCheckoutSubscriptionFromSession() {
1950
- cookie.remove('checkoutSubscriptionId');
1951
- return of();
2195
+ return this.dataPersistence.remove('checkoutSubscriptionId');
1952
2196
  }
1953
2197
  checkCoupon(nickname, userEmail) {
1954
2198
  return this.getCheckoutSubscription().pipe(concatMap((checkout) => this.couponService
@@ -1958,7 +2202,15 @@ class CheckoutSubscriptionService {
1958
2202
  calcDiscountSubscription(coupon) {
1959
2203
  return this.getCheckoutSubscription().pipe(concatMap((checkout) => this.couponService.calcDiscountSubscription(coupon, checkout).pipe()));
1960
2204
  }
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 }); }
2205
+ async createCheckoutSubscription(checkoutData) {
2206
+ const checkout = await this.checkoutSubscriptionRepository.create({
2207
+ createdAt: new Date(),
2208
+ ...CheckoutSubscription.toInstance(pick(checkoutData, ['user', 'shop'])).toPlain(),
2209
+ });
2210
+ await this.dataPersistence.set('checkoutSubscriptionId', checkout.id).toPromise();
2211
+ return checkout;
2212
+ }
2213
+ 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
2214
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutSubscriptionService }); }
1963
2215
  }
1964
2216
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: CheckoutSubscriptionService, decorators: [{
@@ -1968,7 +2220,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
1968
2220
  args: ['CheckoutSubscriptionRepository']
1969
2221
  }] }, { type: undefined, decorators: [{
1970
2222
  type: Inject,
1971
- args: ['SubscriptionRepository']
2223
+ args: [PERSISTENCE_PROVIDER]
1972
2224
  }] }, { type: CouponService }] });
1973
2225
 
1974
2226
  class UtilHelper {
@@ -2053,10 +2305,10 @@ class HomeShopService {
2053
2305
  return this.getHomeConfiguration().pipe(map((home) => home.minValueForFreeShipping));
2054
2306
  }
2055
2307
  getDiscoverProducts(gender) {
2056
- return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.discoverCategories, undefined, gender)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2308
+ return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.discoverCategories, this.defaultShop)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2057
2309
  }
2058
2310
  getFeaturedProducts(gender) {
2059
- return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.featuredCategories, undefined, gender)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2311
+ return this.getHomeConfiguration().pipe(concatMap((home) => from(this.categoryRepository.getCategoriesForHome(home.featuredCategories, this.defaultShop)).pipe(map((groups) => groups.map(this.buildCategoryGroupWithRequiredData)))));
2060
2312
  }
2061
2313
  getVerticalProducts(gender) {
2062
2314
  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({
@@ -2102,7 +2354,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2102
2354
  }] }, { type: undefined, decorators: [{
2103
2355
  type: Inject,
2104
2356
  args: ['ProductRepository']
2105
- }] }, { type: i1$2.Shops, decorators: [{
2357
+ }] }, { type: i1$3.Shops, decorators: [{
2106
2358
  type: Inject,
2107
2359
  args: [DEFAULT_SHOP]
2108
2360
  }] }] });
@@ -2124,112 +2376,29 @@ class OrderService {
2124
2376
  }
2125
2377
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: OrderService, decorators: [{
2126
2378
  type: Injectable
2127
- }], ctorParameters: () => [{ type: i1$1.Firestore }, { type: i1$2.OrderFirestoreRepository, decorators: [{
2379
+ }], ctorParameters: () => [{ type: i1$1.Firestore }, { type: i1$3.OrderFirestoreRepository, decorators: [{
2128
2380
  type: Inject,
2129
2381
  args: ['OrderRepository']
2130
2382
  }] }] });
2131
2383
 
2132
- class ShippingService {
2133
- constructor(http, apiUrl, homeService) {
2134
- this.http = http;
2135
- this.apiUrl = apiUrl;
2136
- this.homeService = homeService;
2137
- }
2138
- getShippingMethods(shop, zip, weightGrams, totalPrice, personId, subscriptionPlan) {
2139
- return combineLatest([
2140
- this.homeService.getHomeData(),
2141
- this.http.get(`${this.apiUrl}open/checkshippingcompany?personId=${personId}&postalCode=${zip}&weightGrams=${weightGrams}`),
2142
- ]).pipe(map(([datas, shippingMethodsResponse]) => {
2143
- let shippingMethods = shippingMethodsResponse.result;
2144
- if (!shippingMethods.length)
2145
- return [];
2146
- shippingMethods = shippingMethods.map((shippingMethod) => {
2147
- if (shippingMethod.ShippingCompanyName == 'Same Day EG')
2148
- shippingMethod.ShippingCompanyName = 'Same Day';
2149
- return shippingMethod;
2150
- });
2151
- const datasSameDayNotAvaliable = datas.sameDayNotAvaliable;
2152
- if (this.isHolidays(datasSameDayNotAvaliable)) {
2153
- shippingMethods = shippingMethods.filter((method) => method.serviceName !== 'Same Day');
2154
- }
2155
- if (totalPrice >= 200) {
2156
- shippingMethods = shippingMethods.map((s) => {
2157
- if (s.serviceName !== 'Same Day')
2158
- return { ...s, totalPrice: 0 };
2159
- else
2160
- return s;
2161
- });
2162
- }
2163
- if (shop == Shops.GLAMSHOP)
2164
- return shippingMethods;
2165
- if (this.isFreeShippingBySubscription(shop, subscriptionPlan)) {
2166
- shippingMethods = shippingMethods.map((s) => {
2167
- if (s.serviceName == 'Same Day')
2168
- return { ...s, totalPrice: s.totalPrice / 2 };
2169
- else
2170
- return { ...s, totalPrice: 0 };
2171
- });
2172
- }
2173
- if (this.isHalfShippingBySubscription(shop, subscriptionPlan)) {
2174
- shippingMethods = shippingMethods.map((s) => {
2175
- return { ...s, totalPrice: s.totalPrice / 2 };
2176
- });
2177
- }
2178
- return shippingMethods;
2179
- }));
2180
- }
2181
- isFreeShippingBySubscription(shop, subscriptionPlan) {
2182
- if (!subscriptionPlan)
2183
- return false;
2184
- if (shop == Shops.MENSMARKET && subscriptionPlan == 'SELECT')
2185
- return true;
2186
- return false;
2187
- }
2188
- isHalfShippingBySubscription(shop, subscriptionPlan) {
2189
- if (!subscriptionPlan)
2190
- return false;
2191
- if (shop == Shops.MENSMARKET && subscriptionPlan == 'PRIME') {
2192
- return true;
2193
- }
2194
- return false;
2195
- }
2196
- isHolidays(datas) {
2197
- const today = new Date();
2198
- for (const key in datas) {
2199
- let start = new Date(`${today.getFullYear()}-${datas[key].beginDate}`);
2200
- let end = new Date(`${today.getFullYear()}-${datas[key].endDate}`);
2201
- if (start > end)
2202
- end = new Date(`${today.getFullYear() + 1}-${datas[key].endDate}`);
2203
- if (today >= start && today <= end)
2204
- return true;
2205
- }
2206
- return false;
2207
- }
2208
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ShippingService, deps: [{ token: i1$3.HttpClient }, { token: BACKEND_URL }, { token: HomeShopService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2209
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ShippingService }); }
2210
- }
2211
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ShippingService, decorators: [{
2212
- type: Injectable
2213
- }], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: undefined, decorators: [{
2214
- type: Inject,
2215
- args: [BACKEND_URL]
2216
- }] }, { type: HomeShopService }] });
2217
-
2218
2384
  class AngularConnectModule {
2219
2385
  static initializeApp(defaultShop, options, nameOrConfig) {
2220
2386
  return {
2221
2387
  ngModule: AngularConnectModule,
2222
2388
  providers: [
2389
+ { provide: FIREBASE_APP_NAME, useValue: nameOrConfig },
2390
+ { provide: APP_CHECK_PROVIDER, useValue: options.appCheckProvider },
2223
2391
  {
2224
2392
  provide: CATEGORY_STRUCTURE,
2225
2393
  useClass: isNil(options?.oldCategoryStructure) || options?.oldCategoryStructure
2226
2394
  ? OldCategoryStructureAdapter
2227
2395
  : NewCategoryStructureAdapter,
2228
2396
  },
2397
+ { provide: PERSISTENCE_PROVIDER, useClass: options?.persistenceProvider || CookieDataPersistence },
2229
2398
  ...(isNil(defaultShop) ? [] : [{ provide: DEFAULT_SHOP, useValue: defaultShop }]),
2230
2399
  ...(isNil(options?.firebase) ? [] : [{ provide: FIREBASE_OPTIONS, useValue: options?.firebase }]),
2231
- ...(isNil(options?.firebase) ? [] : [{ provide: FIREBASE_APP_NAME, useValue: nameOrConfig }]),
2232
2400
  ...(isNil(options?.elasticSearch) ? [] : [{ provide: ES_CONFIG, useValue: options.elasticSearch }]),
2401
+ ...(isNil(options?.vertexConfig) ? [] : [{ provide: VERTEX_CONFIG, useValue: options.vertexConfig }]),
2233
2402
  ...(isNil(options?.hasura) ? [] : [{ provide: HASURA_OPTIONS, useValue: options.hasura }]),
2234
2403
  ...(isNil(options?.backendUrl) ? [] : [{ provide: BACKEND_URL, useValue: options.backendUrl }]),
2235
2404
  ...(isNil(options?.storageBaseUrl) ? [] : [{ provide: STORAGE_BASE_URL, useValue: options.storageBaseUrl }]),
@@ -2237,7 +2406,8 @@ class AngularConnectModule {
2237
2406
  };
2238
2407
  }
2239
2408
  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,
2409
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: AngularConnectModule, imports: [i1$4.FirebaseAppModule, i2.AppCheckModule, i3.StorageModule, AngularElasticSeachModule,
2410
+ AngularVertexSeachModule,
2241
2411
  AngularFirebaseAuthModule,
2242
2412
  AngularFirestoreModule,
2243
2413
  AngularHasuraGraphQLModule] }); }
@@ -2251,7 +2421,6 @@ class AngularConnectModule {
2251
2421
  CouponService,
2252
2422
  HomeShopService,
2253
2423
  OrderService,
2254
- ShippingService,
2255
2424
  WishlistService,
2256
2425
  {
2257
2426
  provide: UpdateUserImage,
@@ -2260,16 +2429,49 @@ class AngularConnectModule {
2260
2429
  },
2261
2430
  deps: ['UserRepository', 'FileUploaderService'],
2262
2431
  },
2432
+ {
2433
+ provide: 'FileUploaderService',
2434
+ useFactory: (storage, baseUrl) => {
2435
+ return new FirebaseFileUploaderService(storage, baseUrl);
2436
+ },
2437
+ deps: [Storage, STORAGE_BASE_URL],
2438
+ },
2439
+ {
2440
+ provide: 'ProductSearch',
2441
+ useExisting: ProductsVertexSearch,
2442
+ },
2263
2443
  ], imports: [provideFirebaseApp((injector) => {
2264
- const appName = injector.get(FIREBASE_APP_NAME) || '[DEFAULT]';
2444
+ const appName = injector.get(FIREBASE_APP_NAME);
2265
2445
  try {
2266
- return getApp(appName);
2446
+ const app = appName ? getApp(appName) : getApp();
2447
+ return app;
2267
2448
  }
2268
2449
  catch (error) {
2450
+ console.warn('Firebase app not found, initializing new app');
2451
+ if (error instanceof Error)
2452
+ console.error(error.message);
2269
2453
  return initializeApp(injector.get(FIREBASE_OPTIONS), appName);
2270
2454
  }
2271
2455
  }),
2456
+ provideAppCheck((injector) => {
2457
+ const app = injector.get(FirebaseApp);
2458
+ try {
2459
+ const provider = injector.get(APP_CHECK_PROVIDER);
2460
+ if (provider)
2461
+ return initializeAppCheck(app, {
2462
+ provider,
2463
+ isTokenAutoRefreshEnabled: true,
2464
+ });
2465
+ }
2466
+ catch (error) {
2467
+ if (error instanceof Error)
2468
+ console.error(error.message);
2469
+ return;
2470
+ }
2471
+ }),
2472
+ provideStorage((injector) => getStorage(injector.get(FirebaseApp))),
2272
2473
  AngularElasticSeachModule,
2474
+ AngularVertexSeachModule,
2273
2475
  AngularFirebaseAuthModule,
2274
2476
  AngularFirestoreModule,
2275
2477
  AngularHasuraGraphQLModule] }); }
@@ -2279,15 +2481,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2279
2481
  args: [{
2280
2482
  imports: [
2281
2483
  provideFirebaseApp((injector) => {
2282
- const appName = injector.get(FIREBASE_APP_NAME) || '[DEFAULT]';
2484
+ const appName = injector.get(FIREBASE_APP_NAME);
2283
2485
  try {
2284
- return getApp(appName);
2486
+ const app = appName ? getApp(appName) : getApp();
2487
+ return app;
2285
2488
  }
2286
2489
  catch (error) {
2490
+ console.warn('Firebase app not found, initializing new app');
2491
+ if (error instanceof Error)
2492
+ console.error(error.message);
2287
2493
  return initializeApp(injector.get(FIREBASE_OPTIONS), appName);
2288
2494
  }
2289
2495
  }),
2496
+ provideAppCheck((injector) => {
2497
+ const app = injector.get(FirebaseApp);
2498
+ try {
2499
+ const provider = injector.get(APP_CHECK_PROVIDER);
2500
+ if (provider)
2501
+ return initializeAppCheck(app, {
2502
+ provider,
2503
+ isTokenAutoRefreshEnabled: true,
2504
+ });
2505
+ }
2506
+ catch (error) {
2507
+ if (error instanceof Error)
2508
+ console.error(error.message);
2509
+ return;
2510
+ }
2511
+ }),
2512
+ provideStorage((injector) => getStorage(injector.get(FirebaseApp))),
2290
2513
  AngularElasticSeachModule,
2514
+ AngularVertexSeachModule,
2291
2515
  AngularFirebaseAuthModule,
2292
2516
  AngularFirestoreModule,
2293
2517
  AngularHasuraGraphQLModule,
@@ -2302,7 +2526,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2302
2526
  CouponService,
2303
2527
  HomeShopService,
2304
2528
  OrderService,
2305
- ShippingService,
2306
2529
  WishlistService,
2307
2530
  {
2308
2531
  provide: UpdateUserImage,
@@ -2311,6 +2534,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2311
2534
  },
2312
2535
  deps: ['UserRepository', 'FileUploaderService'],
2313
2536
  },
2537
+ {
2538
+ provide: 'FileUploaderService',
2539
+ useFactory: (storage, baseUrl) => {
2540
+ return new FirebaseFileUploaderService(storage, baseUrl);
2541
+ },
2542
+ deps: [Storage, STORAGE_BASE_URL],
2543
+ },
2544
+ {
2545
+ provide: 'ProductSearch',
2546
+ useExisting: ProductsVertexSearch,
2547
+ },
2314
2548
  ],
2315
2549
  }]
2316
2550
  }] });
@@ -2319,5 +2553,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImpor
2319
2553
  * Generated bundle index. Do not edit.
2320
2554
  */
2321
2555
 
2322
- export { AngularConnectModule, AngularFirebaseAuthModule, AngularFirestoreModule, AngularHasuraGraphQLModule, AuthService, CartService, CatalogService, CategoryService, CategoryWithTree, CheckoutService, CheckoutSubscriptionService, CouponService, HomeShopService, NewCategoryStructureAdapter, OldCategoryStructureAdapter, OrderService, ProductSorts, ShippingService, UtilHelper, WishlistService };
2556
+ export { AngularConnectModule, AngularFirebaseAuthModule, AngularFirestoreModule, AngularHasuraGraphQLModule, AuthService, CartService, CatalogService, CategoryService, CategoryWithTree, CheckoutService, CheckoutSubscriptionService, CookieDataPersistence, CouponService, HomeShopService, NewCategoryStructureAdapter, OldCategoryStructureAdapter, OrderService, ProductSorts, UtilHelper, WishlistService };
2323
2557
  //# sourceMappingURL=infrab4a-connect-angular.mjs.map