diff --git a/.env-cmdrc b/.env-cmdrc index aeb0f17cde2..11046009c0d 100644 --- a/.env-cmdrc +++ b/.env-cmdrc @@ -94,5 +94,9 @@ "CX_BASE_URL": "https://api.cg79x9wuu9-eccommerc1-s8-public.model-t.myhybris.cloud", "CX_S4_SERVICE": "true", "CX_B2B": "true" + }, + "subscription-billing":{ + "CX_BASE_URL": "https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud", + "CX_SUBSCRIPTION_BILLING": "true" } } diff --git a/core-libs/setup/tsconfig.spec.json b/core-libs/setup/tsconfig.spec.json index ce18f34178c..610b06d1319 100644 --- a/core-libs/setup/tsconfig.spec.json +++ b/core-libs/setup/tsconfig.spec.json @@ -720,6 +720,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/extra-webpack.config.js b/extra-webpack.config.js index 00beacece3d..e065056dbbb 100644 --- a/extra-webpack.config.js +++ b/extra-webpack.config.js @@ -74,6 +74,7 @@ module.exports = { '@spartacus/s4om': path.join(__dirname, 'integration-libs/s4om'), '@spartacus/opf': path.join(__dirname, 'integration-libs/opf'), '@spartacus/s4-service': path.join(__dirname, 'integration-libs/s4-service'), + '@spartacus/subscription-billing': path.join(__dirname, 'integration-libs/subscription-billing'), '@spartacus/omf': path.join(__dirname, 'integration-libs/omf'), }, }, diff --git a/feature-libs/asm/tsconfig.schematics.json b/feature-libs/asm/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/asm/tsconfig.schematics.json +++ b/feature-libs/asm/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/cart/base/components/add-to-cart/add-to-cart.component.spec.ts b/feature-libs/cart/base/components/add-to-cart/add-to-cart.component.spec.ts index 7984b4a1b7d..4fe1d8c74b3 100644 --- a/feature-libs/cart/base/components/add-to-cart/add-to-cart.component.spec.ts +++ b/feature-libs/cart/base/components/add-to-cart/add-to-cart.component.spec.ts @@ -98,6 +98,9 @@ class MockCurrentProductService { getProduct(): Observable { return EMPTY; } + showItemCounter(_product: Product): boolean { + return true; + } } class MockProductAvailabilityAdapter {} @@ -414,6 +417,27 @@ describe('AddToCartComponent', () => { const quantityEl = el.query(By.css('.quantity')); expect(quantityEl).toBeNull(); }); + it('should not show quantity (item counter) button if explicitly set to be hidden', () => { + spyOn(currentProductService, 'getProduct').and.returnValue( + of(mockProduct) + ); + spyOn(currentProductService, 'showItemCounter').and.returnValue(false); + addToCartComponent.showQuantity = true; + addToCartComponent.ngOnInit(); + fixture.detectChanges(); + const quantityEl = el.query(By.css('.quantity')); + expect(quantityEl).toBeNull(); + }); + it('should not show quantity (item counter) button if it fails condition, even if explicitly set to show', () => { + spyOn(currentProductService, 'getProduct').and.returnValue( + of(mockProduct) + ); + addToCartComponent.showQuantity = false; + addToCartComponent.ngOnInit(); + fixture.detectChanges(); + const quantityEl = el.query(By.css('.quantity')); + expect(quantityEl).toBeNull(); + }); describe('Inventory Display test', () => { it('should display inventory quantity when enabled', () => { diff --git a/feature-libs/cart/tsconfig.schematics.json b/feature-libs/cart/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/cart/tsconfig.schematics.json +++ b/feature-libs/cart/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/checkout/tsconfig.schematics.json b/feature-libs/checkout/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/checkout/tsconfig.schematics.json +++ b/feature-libs/checkout/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/customer-ticketing/tsconfig.schematics.json b/feature-libs/customer-ticketing/tsconfig.schematics.json index d59474f4a45..0775622db85 100644 --- a/feature-libs/customer-ticketing/tsconfig.schematics.json +++ b/feature-libs/customer-ticketing/tsconfig.schematics.json @@ -730,6 +730,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/estimated-delivery-date/tsconfig.schematics.json b/feature-libs/estimated-delivery-date/tsconfig.schematics.json index d59474f4a45..0775622db85 100644 --- a/feature-libs/estimated-delivery-date/tsconfig.schematics.json +++ b/feature-libs/estimated-delivery-date/tsconfig.schematics.json @@ -730,6 +730,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/order/tsconfig.schematics.json b/feature-libs/order/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/order/tsconfig.schematics.json +++ b/feature-libs/order/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/organization/tsconfig.schematics.json b/feature-libs/organization/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/organization/tsconfig.schematics.json +++ b/feature-libs/organization/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/pdf-invoices/tsconfig.schematics.json b/feature-libs/pdf-invoices/tsconfig.schematics.json index d59474f4a45..0775622db85 100644 --- a/feature-libs/pdf-invoices/tsconfig.schematics.json +++ b/feature-libs/pdf-invoices/tsconfig.schematics.json @@ -730,6 +730,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/pickup-in-store/tsconfig.schematics.json b/feature-libs/pickup-in-store/tsconfig.schematics.json index 20993f2bfd7..01044593ab0 100644 --- a/feature-libs/pickup-in-store/tsconfig.schematics.json +++ b/feature-libs/pickup-in-store/tsconfig.schematics.json @@ -732,6 +732,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/product-configurator/tsconfig.schematics.json b/feature-libs/product-configurator/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/product-configurator/tsconfig.schematics.json +++ b/feature-libs/product-configurator/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/product-multi-dimensional/tsconfig.schematics.json b/feature-libs/product-multi-dimensional/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/product-multi-dimensional/tsconfig.schematics.json +++ b/feature-libs/product-multi-dimensional/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/product/tsconfig.schematics.json b/feature-libs/product/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/product/tsconfig.schematics.json +++ b/feature-libs/product/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/qualtrics/tsconfig.schematics.json b/feature-libs/qualtrics/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/qualtrics/tsconfig.schematics.json +++ b/feature-libs/qualtrics/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/quote/tsconfig.schematics.json b/feature-libs/quote/tsconfig.schematics.json index 20993f2bfd7..01044593ab0 100644 --- a/feature-libs/quote/tsconfig.schematics.json +++ b/feature-libs/quote/tsconfig.schematics.json @@ -732,6 +732,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/requested-delivery-date/tsconfig.schematics.json b/feature-libs/requested-delivery-date/tsconfig.schematics.json index d59474f4a45..0775622db85 100644 --- a/feature-libs/requested-delivery-date/tsconfig.schematics.json +++ b/feature-libs/requested-delivery-date/tsconfig.schematics.json @@ -730,6 +730,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/smartedit/tsconfig.schematics.json b/feature-libs/smartedit/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/smartedit/tsconfig.schematics.json +++ b/feature-libs/smartedit/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/storefinder/tsconfig.schematics.json b/feature-libs/storefinder/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/storefinder/tsconfig.schematics.json +++ b/feature-libs/storefinder/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/tracking/tsconfig.schematics.json b/feature-libs/tracking/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/feature-libs/tracking/tsconfig.schematics.json +++ b/feature-libs/tracking/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/feature-libs/user/tsconfig.schematics.json b/feature-libs/user/tsconfig.schematics.json index 13569c4d50e..7e32b3fcc50 100644 --- a/feature-libs/user/tsconfig.schematics.json +++ b/feature-libs/user/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/cdc/tsconfig.schematics.json b/integration-libs/cdc/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/cdc/tsconfig.schematics.json +++ b/integration-libs/cdc/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/cdp/tsconfig.schematics.json b/integration-libs/cdp/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/cdp/tsconfig.schematics.json +++ b/integration-libs/cdp/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/cds/tsconfig.schematics.json b/integration-libs/cds/tsconfig.schematics.json index 834f71edc84..43f2a5b9182 100644 --- a/integration-libs/cds/tsconfig.schematics.json +++ b/integration-libs/cds/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/cpq-quote/tsconfig.schematics.json b/integration-libs/cpq-quote/tsconfig.schematics.json index d59474f4a45..0775622db85 100644 --- a/integration-libs/cpq-quote/tsconfig.schematics.json +++ b/integration-libs/cpq-quote/tsconfig.schematics.json @@ -730,6 +730,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/digital-payments/tsconfig.schematics.json b/integration-libs/digital-payments/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/digital-payments/tsconfig.schematics.json +++ b/integration-libs/digital-payments/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/epd-visualization/components/visual-picking/visual-picking-tab/product-list/compact-add-to-cart/compact-add-to-cart.component.spec.ts b/integration-libs/epd-visualization/components/visual-picking/visual-picking-tab/product-list/compact-add-to-cart/compact-add-to-cart.component.spec.ts index 99c837884a1..10805de810e 100644 --- a/integration-libs/epd-visualization/components/visual-picking/visual-picking-tab/product-list/compact-add-to-cart/compact-add-to-cart.component.spec.ts +++ b/integration-libs/epd-visualization/components/visual-picking/visual-picking-tab/product-list/compact-add-to-cart/compact-add-to-cart.component.spec.ts @@ -78,6 +78,9 @@ class MockCurrentProductService { getProduct(): Observable { return EMPTY; } + showItemCounter(_product: Product): boolean { + return true; + } } class MockLaunchDialogService implements Partial { diff --git a/integration-libs/epd-visualization/tsconfig.schematics.json b/integration-libs/epd-visualization/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/epd-visualization/tsconfig.schematics.json +++ b/integration-libs/epd-visualization/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/omf/tsconfig.schematics.json b/integration-libs/omf/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/omf/tsconfig.schematics.json +++ b/integration-libs/omf/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/opps/tsconfig.schematics.json b/integration-libs/opps/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/opps/tsconfig.schematics.json +++ b/integration-libs/opps/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/s4-service/tsconfig.schematics.json b/integration-libs/s4-service/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/s4-service/tsconfig.schematics.json +++ b/integration-libs/s4-service/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/s4om/tsconfig.schematics.json b/integration-libs/s4om/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/s4om/tsconfig.schematics.json +++ b/integration-libs/s4om/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/segment-refs/tsconfig.schematics.json b/integration-libs/segment-refs/tsconfig.schematics.json index b10f8a63602..346b8c023df 100644 --- a/integration-libs/segment-refs/tsconfig.schematics.json +++ b/integration-libs/segment-refs/tsconfig.schematics.json @@ -717,6 +717,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/integration-libs/subscription-billing/README.md b/integration-libs/subscription-billing/README.md new file mode 100644 index 00000000000..3a26470d904 --- /dev/null +++ b/integration-libs/subscription-billing/README.md @@ -0,0 +1,7 @@ +# Spartacus Subscription Billing Integration + +Spartacus' Subscription Billing Integration library helps to monetize your subscription and usage-based services, sell them across channels and touch points, bill them, collect and recognize revenue. + +It can be added to the existing Spartacus application by running `ng add @spartacus/subscription-billing`. For more information about Spartacus schematics, visit the [official Spartacus schematics documentation page](https://sap.github.io/spartacus-docs/schematics/). + +For more information, see [Spartacus](https://github.com/SAP/spartacus). diff --git a/integration-libs/subscription-billing/assets/ng-package.json b/integration-libs/subscription-billing/assets/ng-package.json new file mode 100644 index 00000000000..38e01ac17de --- /dev/null +++ b/integration-libs/subscription-billing/assets/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "./public_api.ts" + } +} diff --git a/integration-libs/subscription-billing/assets/public_api.ts b/integration-libs/subscription-billing/assets/public_api.ts new file mode 100644 index 00000000000..47e68cdd621 --- /dev/null +++ b/integration-libs/subscription-billing/assets/public_api.ts @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +export * from './translations/translations'; diff --git a/integration-libs/subscription-billing/assets/translations/en/index.ts b/integration-libs/subscription-billing/assets/translations/en/index.ts new file mode 100644 index 00000000000..5e97cbb5641 --- /dev/null +++ b/integration-libs/subscription-billing/assets/translations/en/index.ts @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import subscriptionBilling from './subscription-billing.json'; + +export const en = { + subscriptionBilling, +}; diff --git a/integration-libs/subscription-billing/assets/translations/en/subscription-billing.json b/integration-libs/subscription-billing/assets/translations/en/subscription-billing.json new file mode 100644 index 00000000000..118e41fe0e6 --- /dev/null +++ b/integration-libs/subscription-billing/assets/translations/en/subscription-billing.json @@ -0,0 +1,17 @@ +{ + "subscriptionProduct": { + "minimumTerm": "Minimum Term: {{ term }}", + "renewalTerm": "Renewal Term: {{ term }}", + "usageCharges": "Usage Charges", + "volumeUsage": "For {{ from }} to {{ to }}: {{ fixed }} plus {{ price }} per {{ usage }}", + "volumeOverageUsage": "For {{ from }} to Unlimited: {{ fixed }} plus {{ price }} per {{ usage }}", + "volumeUsageMessage": "*You will be charged as per the highest applicable tier", + "tierOverageUsage": "From {{ from }} to Unlimited: {{ price }} per {{ usage }}", + "tierUsageMessage": "*You will be charged as per each applicable tier", + "tierUsage": "From {{ from }} to {{ to }}: {{ price }} per {{ usage }}", + "includedQuantity": "Included Quantity: {{ quantity }}", + "oneBlockUsage": " {{ price }} per {{ usage }} ", + "multiBlockUsage": "{{ price }} for every {{ block }}", + "percentageUsage": "Included Ratio {{ ratio }} at {{ price }} per {{ usage }}" + } +} diff --git a/integration-libs/subscription-billing/assets/translations/translations.ts b/integration-libs/subscription-billing/assets/translations/translations.ts new file mode 100644 index 00000000000..0dc10a3cc38 --- /dev/null +++ b/integration-libs/subscription-billing/assets/translations/translations.ts @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { TranslationChunksConfig, TranslationResources } from '@spartacus/core'; +import { en } from './en/index'; + +export const subscriptionBillingTranslations: TranslationResources = { + en, +}; + +export const subscriptionBillingTranslationChunksConfig: TranslationChunksConfig = + { + subscriptionBilling: ['subscriptionProduct'], + }; diff --git a/integration-libs/subscription-billing/jest.schematics.config.js b/integration-libs/subscription-billing/jest.schematics.config.js new file mode 100644 index 00000000000..7ab7899f7c4 --- /dev/null +++ b/integration-libs/subscription-billing/jest.schematics.config.js @@ -0,0 +1,34 @@ +const { pathsToModuleNameMapper } = require('ts-jest'); +const { compilerOptions } = require('./tsconfig.schematics.json'); +const { defaultTransformerOptions } = require('jest-preset-angular/presets'); + +/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */ +module.exports = { + preset: 'jest-preset-angular', + moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths || {}, { + prefix: '/', + }), + setupFilesAfterEnv: ['/setup-jest.ts'], + testMatch: ['**/+(*_)+(spec).+(ts)'], + transform: { + '^.+\\.(ts|js|mjs|html|svg)$': [ + 'jest-preset-angular', + { + ...defaultTransformerOptions, + tsconfig: '/tsconfig.schematics.json', + }, + ], + }, + + collectCoverage: false, + coverageReporters: ['json', 'lcov', 'text', 'clover'], + coverageDirectory: '/../../coverage/segment/schematics', + coverageThreshold: { + global: { + statements: 90, + branches: 90, + functions: 90, + lines: 90, + }, + }, +}; diff --git a/integration-libs/subscription-billing/karma.conf.js b/integration-libs/subscription-billing/karma.conf.js new file mode 100644 index 00000000000..abe147f0081 --- /dev/null +++ b/integration-libs/subscription-billing/karma.conf.js @@ -0,0 +1,49 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-coverage'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('@angular-devkit/build-angular/plugins/karma'), + require('karma-junit-reporter'), + ], + client: { + clearContext: true, // close Jasmine Spec Runner output in browser to avoid 'Some of your tests did a full page reload!' error when '--no-watch' is active + }, + reporters: ['progress', 'kjhtml', 'dots', 'junit'], + junitReporter: { + outputFile: 'unit-test-segment.xml', + outputDir: require('path').join(__dirname, '../../unit-tests-reports'), + useBrowserName: false, + }, + coverageReporter: { + dir: require('path').join(__dirname, '../../coverage/segment'), + reporters: [{ type: 'lcov', subdir: '.' }, { type: 'text-summary' }], + check: { + global: { + statements: 90, + lines: 90, + branches: 75, + functions: 90, + }, + }, + }, + captureTimeout: 210000, + browserDisconnectTolerance: 3, + browserDisconnectTimeout: 210000, + browserNoActivityTimeout: 210000, + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true, + }); +}; diff --git a/integration-libs/subscription-billing/ng-package.json b/integration-libs/subscription-billing/ng-package.json new file mode 100644 index 00000000000..c9fd50c1e19 --- /dev/null +++ b/integration-libs/subscription-billing/ng-package.json @@ -0,0 +1,8 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/subscription-billing", + "lib": { + "entryFile": "./public_api.ts" + }, + "assets": ["**/*.scss", "schematics/**/*.json", "schematics/**/*.js"] +} diff --git a/integration-libs/subscription-billing/package.json b/integration-libs/subscription-billing/package.json new file mode 100644 index 00000000000..ef051c02d86 --- /dev/null +++ b/integration-libs/subscription-billing/package.json @@ -0,0 +1,36 @@ +{ + "name": "@spartacus/subscription-billing", + "version": "2211.29.0", + "description": "subscription-billing", + "keywords": [ + "spartacus", + "framework", + "storefront", + "subscription-billing", + "subscription" + ], + "homepage": "https://github.com/SAP/spartacus", + "repository": "https://github.com/SAP/spartacus", + "license": "Apache-2.0", + "scripts": { + "build:schematics": "npm run clean:schematics && ../../node_modules/.bin/tsc -p ./tsconfig.schematics.json", + "clean:schematics": "../../node_modules/.bin/rimraf --glob \"schematics/**/*.js\" \"schematics/**/*.js.map\" \"schematics/**/*.d.ts\"", + "test:schematics": "npm --prefix ../../projects/schematics/ run clean && npm run clean:schematics && ../../node_modules/.bin/jest --config ./jest.schematics.config.js" + }, + "dependencies": { + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@angular-devkit/schematics": "^17.0.5", + "@angular/common": "^17.0.5", + "@angular/core": "^17.0.5", + "@spartacus/core": "2211.29.0", + "@spartacus/schematics": "2211.29.0", + "@spartacus/storefront": "2211.29.0", + "rxjs": "^7.8.0" + }, + "publishConfig": { + "access": "public" + }, + "schematics": "./schematics/collection.json" +} diff --git a/integration-libs/subscription-billing/project.json b/integration-libs/subscription-billing/project.json new file mode 100644 index 00000000000..f6237b212a4 --- /dev/null +++ b/integration-libs/subscription-billing/project.json @@ -0,0 +1,50 @@ +{ + "name": "subscription-billing", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "sourceRoot": "integration-libs/subscription-billing", + "prefix": "cx", + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:ng-packagr", + "options": { + "project": "integration-libs/subscription-billing/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "integration-libs/subscription-billing/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "integration-libs/subscription-billing/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "executor": "@angular-devkit/build-angular:karma", + "options": { + "main": "integration-libs/subscription-billing/test.ts", + "tsConfig": "integration-libs/subscription-billing/tsconfig.spec.json", + "polyfills": ["zone.js", "zone.js/testing"], + "karmaConfig": "integration-libs/subscription-billing/karma.conf.js" + } + }, + "test-jest": { + "executor": "nx:run-commands", + "options": { + "command": "npm run test:schematics", + "cwd": "integration-libs/subscription-billing" + } + }, + "lint": { + "executor": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "integration-libs/subscription-billing/**/*.ts", + "integration-libs/subscription-billing/**/*.html" + ] + } + } + }, + "tags": ["type:feature", "type:integration"] +} diff --git a/integration-libs/subscription-billing/public_api.ts b/integration-libs/subscription-billing/public_api.ts new file mode 100644 index 00000000000..9d7c777420f --- /dev/null +++ b/integration-libs/subscription-billing/public_api.ts @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Public API Surface of segment + */ +export * from './subscription-billing.module'; diff --git a/integration-libs/subscription-billing/root/feature-name.ts b/integration-libs/subscription-billing/root/feature-name.ts new file mode 100644 index 00000000000..932f77ef6c2 --- /dev/null +++ b/integration-libs/subscription-billing/root/feature-name.ts @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +export const SUBSCRIPTION_BILLING_FEATURE = 'Subscription-Billing'; diff --git a/integration-libs/subscription-billing/root/model/augmented-types.model.ts b/integration-libs/subscription-billing/root/model/augmented-types.model.ts new file mode 100644 index 00000000000..fb129636d63 --- /dev/null +++ b/integration-libs/subscription-billing/root/model/augmented-types.model.ts @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { PricePlan, SubscriptionTerm } from './subscription-product.model'; +import '@spartacus/core'; + +declare module '@spartacus/core' { + interface Product { + sapSubscriptionTerm?: SubscriptionTerm; + sapPricePlan?: PricePlan; + } +} + +declare module '@spartacus/core' { + const enum ProductScope { + SUBSCRIPTION = 'subscription', + } +} diff --git a/integration-libs/subscription-billing/root/model/index.ts b/integration-libs/subscription-billing/root/model/index.ts new file mode 100644 index 00000000000..5511a3b7623 --- /dev/null +++ b/integration-libs/subscription-billing/root/model/index.ts @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import './augmented-types.model'; +export * from './subscription-product.model'; +export * from './augmented-types.model'; diff --git a/integration-libs/subscription-billing/root/model/subscription-product.model.ts b/integration-libs/subscription-billing/root/model/subscription-product.model.ts new file mode 100644 index 00000000000..c02cfc59b1a --- /dev/null +++ b/integration-libs/subscription-billing/root/model/subscription-product.model.ts @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Price } from '@spartacus/core'; + +export interface SubscriptionTerm { + renewalTerm?: TermType; + minimumTerm?: TermType; + billingPlan?: { + billingTime?: BillingTime; + }; +} + +export interface BillingTime { + id?: string; + name?: string; + description?: string; + namePastTense?: string; +} + +export interface TermType { + value?: number; + frequency?: { + id?: string; + name?: string; + }; +} + +export interface PricePlan { + name?: string; + oneTimeCharges?: OneTimeCharge[]; + recurringCharges?: RecurringCharge[]; + perUnitUsageCharges?: PerUnitUsageCharge[]; + volumeUsageCharges?: VolumeUsageCharge[]; + percentageUsageCharges?: PercentageUsageCharge[]; + tierUsageCharges?: TierUsageCharge[]; +} + +export interface OneTimeCharge { + price?: Price; + name?: string; + billingTime?: BillingTime; +} + +export interface RecurringCharge { + price?: Price; +} + +export interface PerUnitUsageCharge { + usageUnit?: UsageUnit; + blockSize?: number; + includedQty?: number; + perUnitUsageChargeEntries?: UsageChargeEntry[]; +} + +export interface VolumeUsageCharge { + usageUnit?: UsageUnit; + tierUsageChargeEntries?: TierUsageChargeEntry[]; + overageUsageChargeEntries?: OverageUsageChargeEntry[]; +} + +export interface PercentageUsageCharge { + ratio?: string; + percentageUsageChargeEntries?: UsageChargeEntry[]; + usageUnit?: UsageUnit; +} + +export interface TierUsageCharge { + usageUnit?: UsageUnit; + minBlocks?: number; + tierUsageChargeEntries?: TierUsageChargeEntry[]; + overageUsageChargeEntries?: OverageUsageChargeEntry[]; +} + +export interface UsageChargeEntry { + price?: Price; +} + +export interface OverageUsageChargeEntry extends UsageChargeEntry { + fixedPrice?: Price; +} + +export interface TierUsageChargeEntry extends UsageChargeEntry { + fixedPrice?: Price; + tierStart?: number; + tierEnd?: number; +} + +export interface UsageUnit { + id?: string; + name?: string; + namePlural?: string; +} diff --git a/integration-libs/subscription-billing/root/ng-package.json b/integration-libs/subscription-billing/root/ng-package.json new file mode 100644 index 00000000000..38e01ac17de --- /dev/null +++ b/integration-libs/subscription-billing/root/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "./public_api.ts" + } +} diff --git a/integration-libs/subscription-billing/root/product/index.ts b/integration-libs/subscription-billing/root/product/index.ts new file mode 100644 index 00000000000..29bfae76cc2 --- /dev/null +++ b/integration-libs/subscription-billing/root/product/index.ts @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +export * from './subscription-product.module'; +export * from './product-price/subscription-product-price.component'; +export * from './product-price/subscription-product-usage-charge.component'; +export * from './services/current-subscription-product.service'; +export * from './services/subscription-product.service'; diff --git a/integration-libs/subscription-billing/root/product/occ/config/default-occ-subscription-billing-config.ts b/integration-libs/subscription-billing/root/product/occ/config/default-occ-subscription-billing-config.ts new file mode 100644 index 00000000000..4e859fc759b --- /dev/null +++ b/integration-libs/subscription-billing/root/product/occ/config/default-occ-subscription-billing-config.ts @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { OccConfig } from '@spartacus/core'; + +export const defaultOccSubscriptionBillingConfig: OccConfig = { + backend: { + occ: { + endpoints: { + product: { + subscription: + 'products/${productCode}?fields=sapPricePlan,sapSubscriptionTerm', + }, + }, + }, + }, +}; diff --git a/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.html b/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.html new file mode 100644 index 00000000000..1c7872e6bc0 --- /dev/null +++ b/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.html @@ -0,0 +1,76 @@ + +
+
{{ product.sapPricePlan?.name }}:
+
+ +
+
+ +
+ + +
+ +
+
+ {{ charge.billingTime?.name }}: {{ charge.price?.formattedValue }} +
+
+
+ + +
+
+ {{ product.sapSubscriptionTerm?.billingPlan?.billingTime?.name }}: + {{ charge.price?.formattedValue }} +
+
+
+ + +
+ {{ + 'subscriptionProduct.minimumTerm' + | cxTranslate + : { + term: + product.sapSubscriptionTerm?.minimumTerm?.value + + ' ' + + product.sapSubscriptionTerm?.minimumTerm?.frequency?.name, + } + }} +
+
+ {{ + 'subscriptionProduct.renewalTerm' + | cxTranslate + : { + term: + product.sapSubscriptionTerm?.renewalTerm?.value + + ' ' + + product.sapSubscriptionTerm?.renewalTerm?.frequency?.name, + } + }} +
+
+ + +
+ {{ product.price?.formattedValue }} +
+
+
diff --git a/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.spec.ts b/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.spec.ts new file mode 100644 index 00000000000..154344188d5 --- /dev/null +++ b/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.spec.ts @@ -0,0 +1,88 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SubscriptionProductPriceComponent } from './subscription-product-price.component'; +import { SubscriptionProductService } from '../services/subscription-product.service'; +import { CurrentProductService } from '@spartacus/storefront'; +import { Pipe, PipeTransform } from '@angular/core'; +import { ProductScope } from '@spartacus/core'; +import { OneTimeCharge, RecurringCharge } from '../../model'; + +class MockSubscriptionProductService { + isSubscription(_product: any) { + return true; + } +} +class MockCurrentProductService { + getProduct(_scopes: any) { + return null; + } +} +@Pipe({ + name: 'cxTranslate', +}) +class MockTranslatePipe implements PipeTransform { + transform(_value: string): any { + return ''; + } +} + +const mockOneTime: OneTimeCharge[] = [{ name: 'one' }, { name: 'two' }]; +const mockRecurring: RecurringCharge[] = [{ price: { value: 1 } }]; +const mockProduct1 = { + sapPricePlan: { + oneTimeCharges: mockOneTime, + recurringCharges: mockRecurring, + }, +}; +const mockProduct2 = { + sapPricePlan: {}, +}; + +describe('SubscriptionProductPriceComponent', () => { + let component: SubscriptionProductPriceComponent; + let fixture: ComponentFixture; + let currentProductService: CurrentProductService; + let productService: SubscriptionProductService; + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [], + declarations: [SubscriptionProductPriceComponent, MockTranslatePipe], + providers: [ + { + provide: SubscriptionProductService, + useClass: MockSubscriptionProductService, + }, + { provide: CurrentProductService, useClass: MockCurrentProductService }, + ], + }).compileComponents(); + + productService = TestBed.inject(SubscriptionProductService); + currentProductService = TestBed.inject(CurrentProductService); + spyOn(currentProductService, 'getProduct').and.returnValue(null); + fixture = TestBed.createComponent(SubscriptionProductPriceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should be created', () => { + expect(component).toBeTruthy(); + expect(currentProductService.getProduct).toHaveBeenCalledWith([ + ProductScope.SUBSCRIPTION, + ]); + }); + + it('should check if product is subscription', () => { + spyOn(productService, 'isSubscription').and.returnValue(true); + let result = component.isCurrentProductSubscription({}); + expect(result).toEqual(true); + expect(productService.isSubscription).toHaveBeenCalled(); + }); + + it('should return one time charges', () => { + expect(component.getOneTimeCharges(mockProduct1)).toEqual(mockOneTime); + expect(component.getOneTimeCharges(mockProduct2)).toEqual([]); + }); + it('should return recurring charges', () => { + expect(component.getRecurringCharges(mockProduct1)).toEqual(mockRecurring); + expect(component.getRecurringCharges(mockProduct2)).toEqual([]); + }); +}); diff --git a/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.ts b/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.ts new file mode 100644 index 00000000000..82c95aca248 --- /dev/null +++ b/integration-libs/subscription-billing/root/product/product-price/subscription-product-price.component.ts @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Component, inject } from '@angular/core'; +import { Product, ProductScope } from '@spartacus/core'; +import { Observable } from 'rxjs'; +import { SubscriptionProductService } from '../services/subscription-product.service'; +import { CurrentProductService } from '@spartacus/storefront'; +import { OneTimeCharge, RecurringCharge } from '../../model'; + +@Component({ + selector: 'cx-subscription-product-price', + templateUrl: './subscription-product-price.component.html', +}) +export class SubscriptionProductPriceComponent { + protected productService = inject(SubscriptionProductService); + protected currentProductService = inject(CurrentProductService); + protected product$: Observable = + this.currentProductService.getProduct([ProductScope.SUBSCRIPTION]); + + isCurrentProductSubscription(product: Product): boolean { + return this.productService.isSubscription(product); + } + + getOneTimeCharges(product: Product): OneTimeCharge[] { + return product.sapPricePlan?.oneTimeCharges ?? []; + } + + getRecurringCharges(product: Product): RecurringCharge[] { + return product.sapPricePlan?.recurringCharges ?? []; + } +} diff --git a/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.html b/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.html new file mode 100644 index 00000000000..981f84217ef --- /dev/null +++ b/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.html @@ -0,0 +1,171 @@ +
+
+ {{ 'subscriptionProduct.usageCharges' | cxTranslate }}: +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + +
+ {{ + 'subscriptionProduct.includedQuantity' + | cxTranslate: { quantity: getIncludedQuantity(usageCharge) } + }} +
+ +
+ + {{ + 'subscriptionProduct.oneBlockUsage' + | cxTranslate + : { + price: usageChargeEntry.price?.formattedValue, + usage: usageCharge.usageUnit?.name, + } + }} + + + {{ + 'subscriptionProduct.multiBlockUsage' + | cxTranslate + : { + price: usageChargeEntry.price?.formattedValue, + block: + usageCharge.blockSize + + ' ' + + usageCharge?.usageUnit?.namePlural, + } + }} + +
+
+
+ + + +
+ {{ + 'subscriptionProduct.volumeUsage' + | cxTranslate + : { + from: + usageChargeEntry.tierStart + + ' ' + + usageCharge.usageUnit?.name, + to: + usageChargeEntry.tierEnd + ' ' + usageCharge.usageUnit?.name, + fixed: usageChargeEntry.fixedPrice?.formattedValue, + price: usageChargeEntry.price?.formattedValue, + usage: usageCharge.usageUnit?.name, + } + }} +
+
+ {{ + 'subscriptionProduct.volumeOverageUsage' + | cxTranslate + : { + from: + getLastTierValue(usageCharge.tierUsageChargeEntries ?? []) + + 1 + + ' ' + + usageCharge.usageUnit?.name, + fixed: usageChargeEntry.fixedPrice?.formattedValue, + price: usageChargeEntry.price?.formattedValue, + usage: usageCharge.usageUnit?.name, + } + }} +
+
+ {{ 'subscriptionProduct.volumeUsageMessage' | cxTranslate }} +
+
+
+ + + +
+ {{ + 'subscriptionProduct.tierUsage' + | cxTranslate + : { + from: + usageChargeEntry.tierStart + + ' ' + + usageCharge.usageUnit?.name, + to: + usageChargeEntry.tierEnd + ' ' + usageCharge.usageUnit?.name, + price: usageChargeEntry.price?.formattedValue, + usage: usageCharge.usageUnit?.name, + } + }} +
+
+ {{ + 'subscriptionProduct.tierOverageUsage' + | cxTranslate + : { + from: + getLastTierValue(usageCharge?.tierUsageChargeEntries || []) + + 1 + + (usageCharge?.usageUnit?.name || ''), + price: usageChargeEntry.price?.formattedValue, + usage: usageCharge.usageUnit?.name, + } + }} +
+
+ {{ 'subscriptionProduct.tierUsageMessage' | cxTranslate }} +
+
+
+ + + +
+ {{ + 'subscriptionProduct.percentageUsage' + | cxTranslate + : { + ratio: usageCharge.ratio, + price: usageChargeEntry.price?.formattedValue, + usage: usageCharge.usageUnit?.name, + } + }} +
+
+
diff --git a/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.spec.ts b/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.spec.ts new file mode 100644 index 00000000000..8e5b3951ade --- /dev/null +++ b/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.spec.ts @@ -0,0 +1,108 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SubscriptionProductUsageChargeComponent } from './subscription-product-usage-charge.component'; +import { Pipe, PipeTransform } from '@angular/core'; +import { TierUsageChargeEntry } from '../../model'; +@Pipe({ + name: 'cxTranslate', +}) +class MockTranslatePipe implements PipeTransform { + transform(_value: string): any { + return ''; + } +} +const mockTierEntries1: TierUsageChargeEntry[] = [ + { tierStart: 0, tierEnd: 10 }, + { tierStart: 10, tierEnd: 20 }, + { tierStart: 20 }, +]; +const mockTierEntries2: TierUsageChargeEntry[] = [ + { tierStart: 0, tierEnd: 10 }, + { tierStart: 10, tierEnd: 20 }, + { tierStart: 20, tierEnd: 30 }, +]; +const mockPerUnit = [ + { + perUnitUsageChargeEntries: [], + includedQty: 10, + usageUnit: { namePlural: 'KGs', name: 'KG' }, + }, + { + perUnitUsageChargeEntries: [], + includedQty: 1, + usageUnit: { namePlural: 'KGs', name: 'KG' }, + }, + { + perUnitUsageChargeEntries: [], + usageUnit: { namePlural: 'KGs', name: 'KG' }, + }, +]; +const mockVolume = [ + { tierUsageChargeEntries: mockTierEntries1, overageUsageChargeEntries: [] }, +]; +const mockPercentage = [{ percentageUsageChargeEntries: [] }]; +const mockTier = [{ tierUsageChargeEntries: mockTierEntries1 }]; + +const mockProduct1 = { + sapPricePlan: { + perUnitUsageCharges: mockPerUnit, + percentageUsageCharges: mockPercentage, + tierUsageCharges: mockTier, + volumeUsageCharges: mockVolume, + }, +}; +const mockProduct2 = { sapPricePlan: {} }; + +describe('SubscriptionProductUsageChargeComponent', () => { + let component: SubscriptionProductUsageChargeComponent; + let fixture: ComponentFixture; + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [], + declarations: [ + SubscriptionProductUsageChargeComponent, + MockTranslatePipe, + ], + providers: [], + }).compileComponents(); + fixture = TestBed.createComponent(SubscriptionProductUsageChargeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should be created', () => { + expect(component).toBeTruthy(); + }); + it('should return per unit usage charges', () => { + component.product = mockProduct1; + expect(component.getPerUnitUsageCharges()).toEqual(mockPerUnit); + component.product = mockProduct2; + expect(component.getPerUnitUsageCharges()).toEqual([]); + }); + it('should return volumne usage charges', () => { + component.product = mockProduct1; + expect(component.getVolumeUsageCharges()).toEqual(mockVolume); + component.product = mockProduct2; + expect(component.getVolumeUsageCharges()).toEqual([]); + }); + it('should return percentage usage charges', () => { + component.product = mockProduct1; + expect(component.getPercentageUsageCharges()).toEqual(mockPercentage); + component.product = mockProduct2; + expect(component.getPercentageUsageCharges()).toEqual([]); + }); + it('should return tier usage charges', () => { + component.product = mockProduct1; + expect(component.getTierUsageCharges()).toEqual(mockTier); + component.product = mockProduct2; + expect(component.getTierUsageCharges()).toEqual([]); + }); + it('should return last tier value', () => { + expect(component.getLastTierValue(mockTierEntries1)).toEqual(0); + expect(component.getLastTierValue(mockTierEntries2)).toEqual(30); + }); + it('should return included quantity', () => { + expect(component.getIncludedQuantity(mockPerUnit[0])).toEqual('10 KGs'); + expect(component.getIncludedQuantity(mockPerUnit[1])).toEqual('1 KG'); + expect(component.getIncludedQuantity(mockPerUnit[2])).toEqual(''); + }); +}); diff --git a/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.ts b/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.ts new file mode 100644 index 00000000000..dabd5d578f9 --- /dev/null +++ b/integration-libs/subscription-billing/root/product/product-price/subscription-product-usage-charge.component.ts @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Component, Input } from '@angular/core'; +import { Product } from '@spartacus/core'; +import { + PercentageUsageCharge, + PerUnitUsageCharge, + TierUsageCharge, + TierUsageChargeEntry, + VolumeUsageCharge, +} from '../../model'; + +@Component({ + selector: 'cx-subscription-product-usage-charge', + templateUrl: './subscription-product-usage-charge.component.html', +}) +export class SubscriptionProductUsageChargeComponent { + @Input() product: Product; + + getPerUnitUsageCharges(): PerUnitUsageCharge[] { + return this.product?.sapPricePlan?.perUnitUsageCharges ?? []; + } + getIncludedQuantity(charge: PerUnitUsageCharge): string { + if (charge.includedQty) { + return ( + charge.includedQty + + ' ' + + (charge.includedQty > 1 + ? charge.usageUnit?.namePlural + : charge.usageUnit?.name) + ); + } + return ''; + } + getPercentageUsageCharges(): PercentageUsageCharge[] { + return this.product?.sapPricePlan?.percentageUsageCharges ?? []; + } + getTierUsageCharges(): TierUsageCharge[] { + return this.product?.sapPricePlan?.tierUsageCharges ?? []; + } + getVolumeUsageCharges(): VolumeUsageCharge[] { + return this.product?.sapPricePlan?.volumeUsageCharges ?? []; + } + getLastTierValue(tierUsageChargeEntries: TierUsageChargeEntry[]): number { + return ( + tierUsageChargeEntries[tierUsageChargeEntries.length - 1].tierEnd ?? 0 + ); + } +} diff --git a/integration-libs/subscription-billing/root/product/services/current-subscription-product.service.spec.ts b/integration-libs/subscription-billing/root/product/services/current-subscription-product.service.spec.ts new file mode 100644 index 00000000000..b9b2e994b4d --- /dev/null +++ b/integration-libs/subscription-billing/root/product/services/current-subscription-product.service.spec.ts @@ -0,0 +1,38 @@ +import { TestBed } from '@angular/core/testing'; +import { CurrentSubscriptionProductService } from './current-subscription-product.service'; +import { SubscriptionProductService } from './subscription-product.service'; +import { StoreModule } from '@ngrx/store'; +class MockSubscriptionProductService { + isSubscription(_product: any): boolean { + return true; + } +} +describe('CurrentSubscriptionProductService', () => { + let service: CurrentSubscriptionProductService; + let subscriptionService: SubscriptionProductService; + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [StoreModule.forRoot({})], + providers: [ + CurrentSubscriptionProductService, + { + provide: SubscriptionProductService, + useClass: MockSubscriptionProductService, + }, + ], + }); + service = TestBed.inject(CurrentSubscriptionProductService); + subscriptionService = TestBed.inject(SubscriptionProductService); + }); + it('should be created', () => { + expect(service).toBeTruthy(); + }); + it('should show item counter for a non-subscription product', () => { + spyOn(subscriptionService, 'isSubscription').and.returnValue(false); + expect(service.showItemCounter({})).toEqual(true); + }); + it('should not show item counter for a subscription product', () => { + spyOn(subscriptionService, 'isSubscription').and.returnValue(true); + expect(service.showItemCounter({})).toEqual(false); + }); +}); diff --git a/integration-libs/subscription-billing/root/product/services/current-subscription-product.service.ts b/integration-libs/subscription-billing/root/product/services/current-subscription-product.service.ts new file mode 100644 index 00000000000..91861e54a7e --- /dev/null +++ b/integration-libs/subscription-billing/root/product/services/current-subscription-product.service.ts @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { inject, Injectable } from '@angular/core'; +import { CurrentProductService } from '@spartacus/storefront'; +import { SubscriptionProductService } from './subscription-product.service'; +import { Product } from '@spartacus/core'; + +@Injectable({ + providedIn: 'root', +}) +export class CurrentSubscriptionProductService extends CurrentProductService { + protected subscriptionProductService = inject(SubscriptionProductService); + + showItemCounter(product: Product): boolean { + if (this.subscriptionProductService.isSubscription(product || {})) { + return false; + } else { + return true; + } + } +} diff --git a/integration-libs/subscription-billing/root/product/services/subscription-product.service.spec.ts b/integration-libs/subscription-billing/root/product/services/subscription-product.service.spec.ts new file mode 100644 index 00000000000..a4cb6581870 --- /dev/null +++ b/integration-libs/subscription-billing/root/product/services/subscription-product.service.spec.ts @@ -0,0 +1,27 @@ +import { TestBed } from '@angular/core/testing'; +import { SubscriptionProductService } from './subscription-product.service'; +import { StoreModule } from '@ngrx/store'; + +describe('SubscriptionProductService', () => { + let service: SubscriptionProductService; + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [StoreModule.forRoot({})], + providers: [SubscriptionProductService], + }); + service = TestBed.inject(SubscriptionProductService); + }); + it('should be created', () => { + expect(service).toBeTruthy(); + }); + it('should return false for a non-subscription product', () => { + expect(service.isSubscription({})).toEqual(false); + expect(service.isSubscription({ sapPricePlan: {} })).toEqual(false); + expect(service.isSubscription({ sapSubscriptionTerm: {} })).toEqual(false); + }); + it('should return true for a subscription product', () => { + expect( + service.isSubscription({ sapSubscriptionTerm: {}, sapPricePlan: {} }) + ).toEqual(true); + }); +}); diff --git a/integration-libs/subscription-billing/root/product/services/subscription-product.service.ts b/integration-libs/subscription-billing/root/product/services/subscription-product.service.ts new file mode 100644 index 00000000000..7b753cea636 --- /dev/null +++ b/integration-libs/subscription-billing/root/product/services/subscription-product.service.ts @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Injectable } from '@angular/core'; +import { Product } from '@spartacus/core'; + +@Injectable({ + providedIn: 'root', +}) +export class SubscriptionProductService { + isSubscription(product: Product): boolean { + return product.sapSubscriptionTerm && product.sapPricePlan ? true : false; + } +} diff --git a/integration-libs/subscription-billing/root/product/subscription-product.module.ts b/integration-libs/subscription-billing/root/product/subscription-product.module.ts new file mode 100644 index 00000000000..7eca28eb6aa --- /dev/null +++ b/integration-libs/subscription-billing/root/product/subscription-product.module.ts @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { NgModule } from '@angular/core'; +import { SubscriptionProductPriceComponent } from './product-price/subscription-product-price.component'; +import { + provideOutlet, + ProductDetailOutlets, + OutletPosition, + CurrentProductService, +} from '@spartacus/storefront'; +import { I18nModule, provideDefaultConfig } from '@spartacus/core'; +import { SubscriptionProductUsageChargeComponent } from './product-price/subscription-product-usage-charge.component'; +import { CommonModule } from '@angular/common'; +import { defaultOccSubscriptionBillingConfig } from './occ/config/default-occ-subscription-billing-config'; +import { CurrentSubscriptionProductService } from './services/current-subscription-product.service'; + +const componentList = [ + SubscriptionProductPriceComponent, + SubscriptionProductUsageChargeComponent, +]; + +@NgModule({ + imports: [CommonModule, I18nModule], + providers: [ + provideDefaultConfig(defaultOccSubscriptionBillingConfig), + provideOutlet({ + id: ProductDetailOutlets.PRICE, + position: OutletPosition.REPLACE, + component: SubscriptionProductPriceComponent, + }), + { + provide: CurrentProductService, + useExisting: CurrentSubscriptionProductService, + }, + ], + exports: componentList, + declarations: componentList, +}) +export class SubscriptionProductModule {} diff --git a/integration-libs/subscription-billing/root/public_api.ts b/integration-libs/subscription-billing/root/public_api.ts new file mode 100644 index 00000000000..07f7893916a --- /dev/null +++ b/integration-libs/subscription-billing/root/public_api.ts @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +export * from './subscription-billing-root.module'; +export * from './feature-name'; +export * from './model/index'; +export * from './product/index'; diff --git a/integration-libs/subscription-billing/root/subscription-billing-root.module.ts b/integration-libs/subscription-billing/root/subscription-billing-root.module.ts new file mode 100644 index 00000000000..156b9992e68 --- /dev/null +++ b/integration-libs/subscription-billing/root/subscription-billing-root.module.ts @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { NgModule } from '@angular/core'; +import { SubscriptionProductModule } from './product/subscription-product.module'; +@NgModule({ + imports: [SubscriptionProductModule], +}) +export class SubscriptionBillingRootModule {} diff --git a/integration-libs/subscription-billing/schematics/.gitignore b/integration-libs/subscription-billing/schematics/.gitignore new file mode 100644 index 00000000000..c88f4d69e15 --- /dev/null +++ b/integration-libs/subscription-billing/schematics/.gitignore @@ -0,0 +1,18 @@ +# Outputs +**/*.js +**/*.js.map +**/*.d.ts + +# IDEs +.idea/ +jsconfig.json +.vscode/ + +# Misc +node_modules/ +npm-debug.log* +yarn-error.log* + +# Mac OSX Finder files. +**/.DS_Store +.DS_Store diff --git a/integration-libs/subscription-billing/schematics/add-subscription-billing/__snapshots__/index_spec.ts.snap b/integration-libs/subscription-billing/schematics/add-subscription-billing/__snapshots__/index_spec.ts.snap new file mode 100644 index 00000000000..c776b4f5397 --- /dev/null +++ b/integration-libs/subscription-billing/schematics/add-subscription-billing/__snapshots__/index_spec.ts.snap @@ -0,0 +1,56 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Spartacus Subscription Billing Schematics: ng-add Subscription Billing feature eager loading should import appropriate modules 1`] = ` +"import { NgModule } from '@angular/core'; +import { I18nConfig, provideConfig } from "@spartacus/core"; +import { SubscriptionBillingModule } from "@spartacus/subscription-billing"; +import { subscriptionBillingTranslationChunksConfig, subscriptionBillingTranslations } from "@spartacus/subscription-billing/assets"; +import { SubscriptionBillingRootModule } from "@spartacus/subscription-billing/root"; + +@NgModule({ + declarations: [], + imports: [ + SubscriptionBillingRootModule, + SubscriptionBillingModule + ], + providers: [provideConfig({ + i18n: { + resources: subscriptionBillingTranslations, + chunks: subscriptionBillingTranslationChunksConfig, + }, + })] +}) +export class SubscriptionBillingFeatureModule { } +" +`; + +exports[`Spartacus Subscription Billing Schematics: ng-add Subscription Billing feature general setup should add the feature using the lazy loading syntax 1`] = ` +"import { NgModule } from '@angular/core'; +import { CmsConfig, I18nConfig, provideConfig } from "@spartacus/core"; +import { subscriptionBillingTranslationChunksConfig, subscriptionBillingTranslations } from "@spartacus/subscription-billing/assets"; +import { SubscriptionBillingRootModule } from "@spartacus/subscription-billing/root"; + +@NgModule({ + declarations: [], + imports: [ + SubscriptionBillingRootModule + ], + providers: [provideConfig({ + featureModules: { + SubscriptionBilling: { + module: () => + import('@spartacus/subscription-billing').then((m) => m.SubscriptionBillingModule), + }, + } + }), + provideConfig({ + i18n: { + resources: subscriptionBillingTranslations, + chunks: subscriptionBillingTranslationChunksConfig, + }, + }) + ] +}) +export class SubscriptionBillingFeatureModule { } +" +`; diff --git a/integration-libs/subscription-billing/schematics/add-subscription-billing/index.ts b/integration-libs/subscription-billing/schematics/add-subscription-billing/index.ts new file mode 100644 index 00000000000..642f18e1a26 --- /dev/null +++ b/integration-libs/subscription-billing/schematics/add-subscription-billing/index.ts @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + chain, + Rule, + SchematicContext, + Tree, +} from '@angular-devkit/schematics'; +import { + addFeatures, + addPackageJsonDependenciesForLibrary, + analyzeApplication, + analyzeCrossFeatureDependencies, + finalizeInstallation, + readPackageJson, + validateSpartacusInstallation, + LibraryOptions as SpartacusSubscriptionBillingOptions, +} from '@spartacus/schematics'; +import { peerDependencies } from '../../package.json'; + +export function addSubscriptionBillingFeature( + options: SpartacusSubscriptionBillingOptions +): Rule { + return (tree: Tree, _context: SchematicContext): Rule => { + const packageJson = readPackageJson(tree); + validateSpartacusInstallation(packageJson); + + const features = analyzeCrossFeatureDependencies( + options.features as string[] + ); + + return chain([ + analyzeApplication(options, features), + + addFeatures(options, features), + addPackageJsonDependenciesForLibrary(peerDependencies, options), + + finalizeInstallation(options, features), + ]); + }; +} diff --git a/integration-libs/subscription-billing/schematics/add-subscription-billing/index_spec.ts b/integration-libs/subscription-billing/schematics/add-subscription-billing/index_spec.ts new file mode 100644 index 00000000000..65b6c7e7e9d --- /dev/null +++ b/integration-libs/subscription-billing/schematics/add-subscription-billing/index_spec.ts @@ -0,0 +1,147 @@ +/// + +import { + SchematicTestRunner, + UnitTestTree, +} from '@angular-devkit/schematics/testing'; +import { + Schema as ApplicationOptions, + Style, +} from '@schematics/angular/application/schema'; +import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; +import { + SPARTACUS_SCHEMATICS, + SPARTACUS_SUBSCRIPTION_BILLING, + SUBSCRIPTION_BILLING_FEATURE_NAME, + SpartacusOptions, + LibraryOptions as SpartacusSubscriptionBillingOptions, + subscriptionBillingFeatureModulePath, +} from '@spartacus/schematics'; +import * as path from 'path'; +import { peerDependencies } from '../../package.json'; + +const collectionPath = path.join(__dirname, '../collection.json'); + +describe('Spartacus Subscription Billing Schematics: ng-add', () => { + const schematicRunner = new SchematicTestRunner( + SPARTACUS_SUBSCRIPTION_BILLING, + collectionPath + ); + let appTree: UnitTestTree; + const workspaceOptions: WorkspaceOptions = { + name: 'workspace', + version: '0.5.0', + }; + const appOptions: ApplicationOptions = { + name: 'schematics-test', + inlineStyle: false, + inlineTemplate: false, + style: Style.Scss, + skipTests: false, + projectRoot: '', + standalone: false, + }; + const spartacusDefaultOptions: SpartacusOptions = { + project: 'schematics-test', + lazy: true, + features: [], + }; + const libraryNoFeaturesOptions: SpartacusSubscriptionBillingOptions = { + project: 'schematics-test', + lazy: true, + features: [], + }; + const subscriptionBillingFeatureOptions: SpartacusSubscriptionBillingOptions = + { + ...libraryNoFeaturesOptions, + features: [SUBSCRIPTION_BILLING_FEATURE_NAME], + }; + beforeEach(async () => { + schematicRunner.registerCollection( + SPARTACUS_SCHEMATICS, + path.join( + __dirname, + '../../../../projects/schematics/src/collection.json' + ) + ); + appTree = await schematicRunner.runExternalSchematic( + '@schematics/angular', + 'workspace', + workspaceOptions + ); + appTree = await schematicRunner.runExternalSchematic( + '@schematics/angular', + 'application', + appOptions, + appTree + ); + appTree = await schematicRunner.runExternalSchematic( + SPARTACUS_SCHEMATICS, + 'ng-add', + { ...spartacusDefaultOptions, name: 'schematics-test' }, + appTree + ); + }); + describe('Without features', () => { + beforeEach(async () => { + appTree = await schematicRunner.runSchematic( + 'ng-add', + libraryNoFeaturesOptions, + appTree + ); + }); + it('should not create any of the feature modules', () => { + expect(appTree.exists(subscriptionBillingFeatureModulePath)).toBeFalsy(); + }); + }); + describe('Subscription Billing feature', () => { + describe('general setup', () => { + beforeEach(async () => { + appTree = await schematicRunner.runSchematic( + 'ng-add', + subscriptionBillingFeatureOptions, + appTree + ); + }); + it('should install necessary Spartacus libraries', () => { + const packageJson = JSON.parse(appTree.readContent('package.json')); + let dependencies: Record = {}; + dependencies = { ...packageJson.dependencies }; + dependencies = { ...dependencies, ...packageJson.devDependencies }; + + for (const toAdd in peerDependencies) { + if ( + !peerDependencies.hasOwnProperty(toAdd) || + toAdd === SPARTACUS_SCHEMATICS + ) { + continue; + } + const expectedDependency = dependencies[toAdd]; + expect(expectedDependency).toBeTruthy(); + } + }); + it('should add the feature using the lazy loading syntax', async () => { + const module = appTree.readContent( + subscriptionBillingFeatureModulePath + ); + expect(module).toMatchSnapshot(); + }); + it('should install the appropriate dependencies', async () => {}); + }); + describe('eager loading', () => { + beforeEach(async () => { + appTree = await schematicRunner.runSchematic( + 'ng-add', + { ...subscriptionBillingFeatureOptions, lazy: false }, + appTree + ); + }); + it('should import appropriate modules', async () => { + const module = appTree.readContent( + subscriptionBillingFeatureModulePath + ); + expect(module).toMatchSnapshot(); + }); + }); + }); +}); diff --git a/integration-libs/subscription-billing/schematics/add-subscription-billing/schema.json b/integration-libs/subscription-billing/schematics/add-subscription-billing/schema.json new file mode 100644 index 00000000000..6a0f3065f7f --- /dev/null +++ b/integration-libs/subscription-billing/schematics/add-subscription-billing/schema.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/schema", + "$id": "SubscriptionBillingSchematics", + "title": "Segment Refs Schematics", + "type": "object", + "properties": { + "project": { + "type": "string", + "description": "The name of the project.", + "$default": { + "$source": "projectName" + } + }, + "debug": { + "description": "Display additional details during the running process.", + "type": "boolean", + "default": false + }, + "features": { + "type": "array", + "uniqueItems": true, + "default": ["Subscription-Billing"] + } + } +} diff --git a/integration-libs/subscription-billing/schematics/collection.json b/integration-libs/subscription-billing/schematics/collection.json new file mode 100644 index 00000000000..2f3c9e133f0 --- /dev/null +++ b/integration-libs/subscription-billing/schematics/collection.json @@ -0,0 +1,18 @@ +{ + "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json", + "schematics": { + "ng-add": { + "factory": "./add-subscription-billing/index#addSubscriptionBillingFeature", + "description": "Add and configure Spartacus' Subscription Billing feature", + "schema": "./add-subscription-billing/schema.json", + "private": true, + "hidden": true, + "aliases": ["install"] + }, + "add": { + "factory": "./add-subscription-billing/index#addSubscriptionBillingFeature", + "description": "Add and configure Spartacus' Subscription Billing feature", + "schema": "./add-subscription-billing/schema.json" + } + } +} diff --git a/integration-libs/subscription-billing/setup-jest.ts b/integration-libs/subscription-billing/setup-jest.ts new file mode 100644 index 00000000000..59d26166bd8 --- /dev/null +++ b/integration-libs/subscription-billing/setup-jest.ts @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import 'jest-preset-angular/setup-jest'; +import 'zone.js'; diff --git a/integration-libs/subscription-billing/subscription-billing.module.ts b/integration-libs/subscription-billing/subscription-billing.module.ts new file mode 100644 index 00000000000..cc47ae1a62a --- /dev/null +++ b/integration-libs/subscription-billing/subscription-billing.module.ts @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { NgModule } from '@angular/core'; + +@NgModule() +export class SubscriptionBillingModule {} diff --git a/integration-libs/subscription-billing/test.ts b/integration-libs/subscription-billing/test.ts new file mode 100644 index 00000000000..da9169725cb --- /dev/null +++ b/integration-libs/subscription-billing/test.ts @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting, +} from '@angular/platform-browser-dynamic/testing'; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), + { + teardown: { destroyAfterEach: false }, + } +); diff --git a/integration-libs/subscription-billing/tsconfig.lib.json b/integration-libs/subscription-billing/tsconfig.lib.json new file mode 100644 index 00000000000..3a32c06b473 --- /dev/null +++ b/integration-libs/subscription-billing/tsconfig.lib.json @@ -0,0 +1,30 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/lib", + "module": "es2022", + "moduleResolution": "node", + "declaration": true, + "sourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "importHelpers": true, + "skipLibCheck": true, + "lib": ["dom", "esnext"], + "paths": { + "@spartacus/core": ["dist/core"], + "@spartacus/storefront": ["dist/storefrontlib"] + }, + "resolveJsonModule": true, + "esModuleInterop": true + }, + "angularCompilerOptions": { + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, + "enableResourceInlining": true + }, + "exclude": ["test.ts", "**/*.spec.ts"] +} diff --git a/integration-libs/subscription-billing/tsconfig.lib.prod.json b/integration-libs/subscription-billing/tsconfig.lib.prod.json new file mode 100644 index 00000000000..2a2faa884cf --- /dev/null +++ b/integration-libs/subscription-billing/tsconfig.lib.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/integration-libs/subscription-billing/tsconfig.schematics.json b/integration-libs/subscription-billing/tsconfig.schematics.json new file mode 100644 index 00000000000..c9b6d2f7032 --- /dev/null +++ b/integration-libs/subscription-billing/tsconfig.schematics.json @@ -0,0 +1,670 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "module": "CommonJs", + "types": ["jest"], + "paths": { + "@spartacus/schematics": ["../../projects/schematics/index"], + "@spartacus/setup": ["../../core-libs/setup/public_api"], + "@spartacus/setup/ssr": ["../../core-libs/setup/ssr/public_api"], + "@spartacus/asm/assets": ["../../feature-libs/asm/assets/public_api"], + "@spartacus/asm/components": [ + "../../feature-libs/asm/components/public_api" + ], + "@spartacus/asm/core": ["../../feature-libs/asm/core/public_api"], + "@spartacus/asm/customer-360/assets": [ + "../../feature-libs/asm/customer-360/assets/public_api" + ], + "@spartacus/asm/customer-360/components": [ + "../../feature-libs/asm/customer-360/components/public_api" + ], + "@spartacus/asm/customer-360/core": [ + "../../feature-libs/asm/customer-360/core/public_api" + ], + "@spartacus/asm/customer-360": [ + "../../feature-libs/asm/customer-360/public_api" + ], + "@spartacus/asm/customer-360/occ": [ + "../../feature-libs/asm/customer-360/occ/public_api" + ], + "@spartacus/asm/customer-360/root": [ + "../../feature-libs/asm/customer-360/root/public_api" + ], + "@spartacus/asm": ["../../feature-libs/asm/public_api"], + "@spartacus/asm/occ": ["../../feature-libs/asm/occ/public_api"], + "@spartacus/asm/root": ["../../feature-libs/asm/root/public_api"], + "@spartacus/cart/base/assets": [ + "../../feature-libs/cart/base/assets/public_api" + ], + "@spartacus/cart/base/components/add-to-cart": [ + "../../feature-libs/cart/base/components/add-to-cart/public_api" + ], + "@spartacus/cart/base/components/mini-cart": [ + "../../feature-libs/cart/base/components/mini-cart/public_api" + ], + "@spartacus/cart/base/components": [ + "../../feature-libs/cart/base/components/public_api" + ], + "@spartacus/cart/base/core": [ + "../../feature-libs/cart/base/core/public_api" + ], + "@spartacus/cart/base": ["../../feature-libs/cart/base/public_api"], + "@spartacus/cart/base/occ": [ + "../../feature-libs/cart/base/occ/public_api" + ], + "@spartacus/cart/base/root": [ + "../../feature-libs/cart/base/root/public_api" + ], + "@spartacus/cart/import-export/assets": [ + "../../feature-libs/cart/import-export/assets/public_api" + ], + "@spartacus/cart/import-export/components": [ + "../../feature-libs/cart/import-export/components/public_api" + ], + "@spartacus/cart/import-export/core": [ + "../../feature-libs/cart/import-export/core/public_api" + ], + "@spartacus/cart/import-export": [ + "../../feature-libs/cart/import-export/public_api" + ], + "@spartacus/cart/import-export/root": [ + "../../feature-libs/cart/import-export/root/public_api" + ], + "@spartacus/cart": ["../../feature-libs/cart/public_api"], + "@spartacus/cart/quick-order/assets": [ + "../../feature-libs/cart/quick-order/assets/public_api" + ], + "@spartacus/cart/quick-order/components": [ + "../../feature-libs/cart/quick-order/components/public_api" + ], + "@spartacus/cart/quick-order/core": [ + "../../feature-libs/cart/quick-order/core/public_api" + ], + "@spartacus/cart/quick-order": [ + "../../feature-libs/cart/quick-order/public_api" + ], + "@spartacus/cart/quick-order/root": [ + "../../feature-libs/cart/quick-order/root/public_api" + ], + "@spartacus/cart/saved-cart/assets": [ + "../../feature-libs/cart/saved-cart/assets/public_api" + ], + "@spartacus/cart/saved-cart/components": [ + "../../feature-libs/cart/saved-cart/components/public_api" + ], + "@spartacus/cart/saved-cart/core": [ + "../../feature-libs/cart/saved-cart/core/public_api" + ], + "@spartacus/cart/saved-cart": [ + "../../feature-libs/cart/saved-cart/public_api" + ], + "@spartacus/cart/saved-cart/occ": [ + "../../feature-libs/cart/saved-cart/occ/public_api" + ], + "@spartacus/cart/saved-cart/root": [ + "../../feature-libs/cart/saved-cart/root/public_api" + ], + "@spartacus/cart/wish-list/assets": [ + "../../feature-libs/cart/wish-list/assets/public_api" + ], + "@spartacus/cart/wish-list/components/add-to-wishlist": [ + "../../feature-libs/cart/wish-list/components/add-to-wishlist/public_api" + ], + "@spartacus/cart/wish-list/components": [ + "../../feature-libs/cart/wish-list/components/public_api" + ], + "@spartacus/cart/wish-list/core": [ + "../../feature-libs/cart/wish-list/core/public_api" + ], + "@spartacus/cart/wish-list": [ + "../../feature-libs/cart/wish-list/public_api" + ], + "@spartacus/cart/wish-list/root": [ + "../../feature-libs/cart/wish-list/root/public_api" + ], + "@spartacus/checkout/b2b/assets": [ + "../../feature-libs/checkout/b2b/assets/public_api" + ], + "@spartacus/checkout/b2b/components": [ + "../../feature-libs/checkout/b2b/components/public_api" + ], + "@spartacus/checkout/b2b/core": [ + "../../feature-libs/checkout/b2b/core/public_api" + ], + "@spartacus/checkout/b2b": ["../../feature-libs/checkout/b2b/public_api"], + "@spartacus/checkout/b2b/occ": [ + "../../feature-libs/checkout/b2b/occ/public_api" + ], + "@spartacus/checkout/b2b/root": [ + "../../feature-libs/checkout/b2b/root/public_api" + ], + "@spartacus/checkout/base/assets": [ + "../../feature-libs/checkout/base/assets/public_api" + ], + "@spartacus/checkout/base/components": [ + "../../feature-libs/checkout/base/components/public_api" + ], + "@spartacus/checkout/base/core": [ + "../../feature-libs/checkout/base/core/public_api" + ], + "@spartacus/checkout/base": [ + "../../feature-libs/checkout/base/public_api" + ], + "@spartacus/checkout/base/occ": [ + "../../feature-libs/checkout/base/occ/public_api" + ], + "@spartacus/checkout/base/root": [ + "../../feature-libs/checkout/base/root/public_api" + ], + "@spartacus/checkout": ["../../feature-libs/checkout/public_api"], + "@spartacus/checkout/scheduled-replenishment/assets": [ + "../../feature-libs/checkout/scheduled-replenishment/assets/public_api" + ], + "@spartacus/checkout/scheduled-replenishment/components": [ + "../../feature-libs/checkout/scheduled-replenishment/components/public_api" + ], + "@spartacus/checkout/scheduled-replenishment": [ + "../../feature-libs/checkout/scheduled-replenishment/public_api" + ], + "@spartacus/checkout/scheduled-replenishment/root": [ + "../../feature-libs/checkout/scheduled-replenishment/root/public_api" + ], + "@spartacus/customer-ticketing/assets": [ + "../../feature-libs/customer-ticketing/assets/public_api" + ], + "@spartacus/customer-ticketing/components": [ + "../../feature-libs/customer-ticketing/components/public_api" + ], + "@spartacus/customer-ticketing/core": [ + "../../feature-libs/customer-ticketing/core/public_api" + ], + "@spartacus/customer-ticketing": [ + "../../feature-libs/customer-ticketing/public_api" + ], + "@spartacus/customer-ticketing/occ": [ + "../../feature-libs/customer-ticketing/occ/public_api" + ], + "@spartacus/customer-ticketing/root": [ + "../../feature-libs/customer-ticketing/root/public_api" + ], + "@spartacus/estimated-delivery-date/assets": [ + "../../feature-libs/estimated-delivery-date/assets/public_api" + ], + "@spartacus/estimated-delivery-date": [ + "../../feature-libs/estimated-delivery-date/public_api" + ], + "@spartacus/estimated-delivery-date/root": [ + "../../feature-libs/estimated-delivery-date/root/public_api" + ], + "@spartacus/estimated-delivery-date/show-estimated-delivery-date": [ + "../../feature-libs/estimated-delivery-date/show-estimated-delivery-date/public_api" + ], + "@spartacus/order/assets": ["../../feature-libs/order/assets/public_api"], + "@spartacus/order/components": [ + "../../feature-libs/order/components/public_api" + ], + "@spartacus/order/core": ["../../feature-libs/order/core/public_api"], + "@spartacus/order": ["../../feature-libs/order/public_api"], + "@spartacus/order/occ": ["../../feature-libs/order/occ/public_api"], + "@spartacus/order/root": ["../../feature-libs/order/root/public_api"], + "@spartacus/organization/account-summary/assets": [ + "../../feature-libs/organization/account-summary/assets/public_api" + ], + "@spartacus/organization/account-summary/components": [ + "../../feature-libs/organization/account-summary/components/public_api" + ], + "@spartacus/organization/account-summary/core": [ + "../../feature-libs/organization/account-summary/core/public_api" + ], + "@spartacus/organization/account-summary": [ + "../../feature-libs/organization/account-summary/public_api" + ], + "@spartacus/organization/account-summary/occ": [ + "../../feature-libs/organization/account-summary/occ/public_api" + ], + "@spartacus/organization/account-summary/root": [ + "../../feature-libs/organization/account-summary/root/public_api" + ], + "@spartacus/organization/administration/assets": [ + "../../feature-libs/organization/administration/assets/public_api" + ], + "@spartacus/organization/administration/components": [ + "../../feature-libs/organization/administration/components/public_api" + ], + "@spartacus/organization/administration/core": [ + "../../feature-libs/organization/administration/core/public_api" + ], + "@spartacus/organization/administration": [ + "../../feature-libs/organization/administration/public_api" + ], + "@spartacus/organization/administration/occ": [ + "../../feature-libs/organization/administration/occ/public_api" + ], + "@spartacus/organization/administration/root": [ + "../../feature-libs/organization/administration/root/public_api" + ], + "@spartacus/organization": ["../../feature-libs/organization/public_api"], + "@spartacus/organization/order-approval/assets": [ + "../../feature-libs/organization/order-approval/assets/public_api" + ], + "@spartacus/organization/order-approval": [ + "../../feature-libs/organization/order-approval/public_api" + ], + "@spartacus/organization/order-approval/root": [ + "../../feature-libs/organization/order-approval/root/public_api" + ], + "@spartacus/organization/unit-order/assets": [ + "../../feature-libs/organization/unit-order/assets/public_api" + ], + "@spartacus/organization/unit-order/components": [ + "../../feature-libs/organization/unit-order/components/public_api" + ], + "@spartacus/organization/unit-order/core": [ + "../../feature-libs/organization/unit-order/core/public_api" + ], + "@spartacus/organization/unit-order": [ + "../../feature-libs/organization/unit-order/public_api" + ], + "@spartacus/organization/unit-order/occ": [ + "../../feature-libs/organization/unit-order/occ/public_api" + ], + "@spartacus/organization/unit-order/root": [ + "../../feature-libs/organization/unit-order/root/public_api" + ], + "@spartacus/organization/user-registration/assets": [ + "../../feature-libs/organization/user-registration/assets/public_api" + ], + "@spartacus/organization/user-registration/components": [ + "../../feature-libs/organization/user-registration/components/public_api" + ], + "@spartacus/organization/user-registration/core": [ + "../../feature-libs/organization/user-registration/core/public_api" + ], + "@spartacus/organization/user-registration": [ + "../../feature-libs/organization/user-registration/public_api" + ], + "@spartacus/organization/user-registration/occ": [ + "../../feature-libs/organization/user-registration/occ/public_api" + ], + "@spartacus/organization/user-registration/root": [ + "../../feature-libs/organization/user-registration/root/public_api" + ], + "@spartacus/pdf-invoices/assets": [ + "../../feature-libs/pdf-invoices/assets/public_api" + ], + "@spartacus/pdf-invoices/components": [ + "../../feature-libs/pdf-invoices/components/public_api" + ], + "@spartacus/pdf-invoices/core": [ + "../../feature-libs/pdf-invoices/core/public_api" + ], + "@spartacus/pdf-invoices": ["../../feature-libs/pdf-invoices/public_api"], + "@spartacus/pdf-invoices/occ": [ + "../../feature-libs/pdf-invoices/occ/public_api" + ], + "@spartacus/pdf-invoices/root": [ + "../../feature-libs/pdf-invoices/root/public_api" + ], + "@spartacus/pickup-in-store/assets": [ + "../../feature-libs/pickup-in-store/assets/public_api" + ], + "@spartacus/pickup-in-store/components": [ + "../../feature-libs/pickup-in-store/components/public_api" + ], + "@spartacus/pickup-in-store/core": [ + "../../feature-libs/pickup-in-store/core/public_api" + ], + "@spartacus/pickup-in-store": [ + "../../feature-libs/pickup-in-store/public_api" + ], + "@spartacus/pickup-in-store/occ": [ + "../../feature-libs/pickup-in-store/occ/public_api" + ], + "@spartacus/pickup-in-store/root": [ + "../../feature-libs/pickup-in-store/root/public_api" + ], + "@spartacus/product-configurator/common/assets": [ + "../../feature-libs/product-configurator/common/assets/public_api" + ], + "@spartacus/product-configurator/common": [ + "../../feature-libs/product-configurator/common/public_api" + ], + "@spartacus/product-configurator": [ + "../../feature-libs/product-configurator/public_api" + ], + "@spartacus/product-configurator/rulebased/cpq": [ + "../../feature-libs/product-configurator/rulebased/cpq/public_api" + ], + "@spartacus/product-configurator/rulebased": [ + "../../feature-libs/product-configurator/rulebased/public_api" + ], + "@spartacus/product-configurator/rulebased/root": [ + "../../feature-libs/product-configurator/rulebased/root/public_api" + ], + "@spartacus/product-configurator/textfield": [ + "../../feature-libs/product-configurator/textfield/public_api" + ], + "@spartacus/product-configurator/textfield/root": [ + "../../feature-libs/product-configurator/textfield/root/public_api" + ], + "@spartacus/product-multi-dimensional/list": [ + "../../feature-libs/product-multi-dimensional/list/public_api" + ], + "@spartacus/product-multi-dimensional/list/root": [ + "../../feature-libs/product-multi-dimensional/list/root/public_api" + ], + "@spartacus/product-multi-dimensional": [ + "../../feature-libs/product-multi-dimensional/public_api" + ], + "@spartacus/product-multi-dimensional/selector/assets": [ + "../../feature-libs/product-multi-dimensional/selector/assets/public_api" + ], + "@spartacus/product-multi-dimensional/selector/components": [ + "../../feature-libs/product-multi-dimensional/selector/components/public_api" + ], + "@spartacus/product-multi-dimensional/selector/core": [ + "../../feature-libs/product-multi-dimensional/selector/core/public_api" + ], + "@spartacus/product-multi-dimensional/selector": [ + "../../feature-libs/product-multi-dimensional/selector/public_api" + ], + "@spartacus/product-multi-dimensional/selector/occ": [ + "../../feature-libs/product-multi-dimensional/selector/occ/public_api" + ], + "@spartacus/product-multi-dimensional/selector/root": [ + "../../feature-libs/product-multi-dimensional/selector/root/public_api" + ], + "@spartacus/product/bulk-pricing/assets": [ + "../../feature-libs/product/bulk-pricing/assets/public_api" + ], + "@spartacus/product/bulk-pricing/components": [ + "../../feature-libs/product/bulk-pricing/components/public_api" + ], + "@spartacus/product/bulk-pricing/core": [ + "../../feature-libs/product/bulk-pricing/core/public_api" + ], + "@spartacus/product/bulk-pricing": [ + "../../feature-libs/product/bulk-pricing/public_api" + ], + "@spartacus/product/bulk-pricing/occ": [ + "../../feature-libs/product/bulk-pricing/occ/public_api" + ], + "@spartacus/product/bulk-pricing/root": [ + "../../feature-libs/product/bulk-pricing/root/public_api" + ], + "@spartacus/product/future-stock/assets": [ + "../../feature-libs/product/future-stock/assets/public_api" + ], + "@spartacus/product/future-stock/components": [ + "../../feature-libs/product/future-stock/components/public_api" + ], + "@spartacus/product/future-stock/core": [ + "../../feature-libs/product/future-stock/core/public_api" + ], + "@spartacus/product/future-stock": [ + "../../feature-libs/product/future-stock/public_api" + ], + "@spartacus/product/future-stock/occ": [ + "../../feature-libs/product/future-stock/occ/public_api" + ], + "@spartacus/product/future-stock/root": [ + "../../feature-libs/product/future-stock/root/public_api" + ], + "@spartacus/product/image-zoom/assets": [ + "../../feature-libs/product/image-zoom/assets/public_api" + ], + "@spartacus/product/image-zoom/components": [ + "../../feature-libs/product/image-zoom/components/public_api" + ], + "@spartacus/product/image-zoom": [ + "../../feature-libs/product/image-zoom/public_api" + ], + "@spartacus/product/image-zoom/root": [ + "../../feature-libs/product/image-zoom/root/public_api" + ], + "@spartacus/product": ["../../feature-libs/product/public_api"], + "@spartacus/product/variants/assets": [ + "../../feature-libs/product/variants/assets/public_api" + ], + "@spartacus/product/variants/components": [ + "../../feature-libs/product/variants/components/public_api" + ], + "@spartacus/product/variants": [ + "../../feature-libs/product/variants/public_api" + ], + "@spartacus/product/variants/occ": [ + "../../feature-libs/product/variants/occ/public_api" + ], + "@spartacus/product/variants/root": [ + "../../feature-libs/product/variants/root/public_api" + ], + "@spartacus/qualtrics/components": [ + "../../feature-libs/qualtrics/components/public_api" + ], + "@spartacus/qualtrics": ["../../feature-libs/qualtrics/public_api"], + "@spartacus/qualtrics/root": [ + "../../feature-libs/qualtrics/root/public_api" + ], + "@spartacus/quote/assets": ["../../feature-libs/quote/assets/public_api"], + "@spartacus/quote/components/cart-guard": [ + "../../feature-libs/quote/components/cart-guard/public_api" + ], + "@spartacus/quote/components": [ + "../../feature-libs/quote/components/public_api" + ], + "@spartacus/quote/components/request-button": [ + "../../feature-libs/quote/components/request-button/public_api" + ], + "@spartacus/quote/core": ["../../feature-libs/quote/core/public_api"], + "@spartacus/quote": ["../../feature-libs/quote/public_api"], + "@spartacus/quote/occ": ["../../feature-libs/quote/occ/public_api"], + "@spartacus/quote/root": ["../../feature-libs/quote/root/public_api"], + "@spartacus/requested-delivery-date/assets": [ + "../../feature-libs/requested-delivery-date/assets/public_api" + ], + "@spartacus/requested-delivery-date/core": [ + "../../feature-libs/requested-delivery-date/core/public_api" + ], + "@spartacus/requested-delivery-date": [ + "../../feature-libs/requested-delivery-date/public_api" + ], + "@spartacus/requested-delivery-date/occ": [ + "../../feature-libs/requested-delivery-date/occ/public_api" + ], + "@spartacus/requested-delivery-date/root": [ + "../../feature-libs/requested-delivery-date/root/public_api" + ], + "@spartacus/smartedit/core": [ + "../../feature-libs/smartedit/core/public_api" + ], + "@spartacus/smartedit": ["../../feature-libs/smartedit/public_api"], + "@spartacus/smartedit/root": [ + "../../feature-libs/smartedit/root/public_api" + ], + "@spartacus/storefinder/assets": [ + "../../feature-libs/storefinder/assets/public_api" + ], + "@spartacus/storefinder/components": [ + "../../feature-libs/storefinder/components/public_api" + ], + "@spartacus/storefinder/core": [ + "../../feature-libs/storefinder/core/public_api" + ], + "@spartacus/storefinder": ["../../feature-libs/storefinder/public_api"], + "@spartacus/storefinder/occ": [ + "../../feature-libs/storefinder/occ/public_api" + ], + "@spartacus/storefinder/root": [ + "../../feature-libs/storefinder/root/public_api" + ], + "@spartacus/tracking": ["../../feature-libs/tracking/public_api"], + "@spartacus/tracking/personalization/core": [ + "../../feature-libs/tracking/personalization/core/public_api" + ], + "@spartacus/tracking/personalization": [ + "../../feature-libs/tracking/personalization/public_api" + ], + "@spartacus/tracking/personalization/root": [ + "../../feature-libs/tracking/personalization/root/public_api" + ], + "@spartacus/tracking/tms/aep": [ + "../../feature-libs/tracking/tms/aep/public_api" + ], + "@spartacus/tracking/tms/core": [ + "../../feature-libs/tracking/tms/core/public_api" + ], + "@spartacus/tracking/tms/gtm": [ + "../../feature-libs/tracking/tms/gtm/public_api" + ], + "@spartacus/tracking/tms": ["../../feature-libs/tracking/tms/public_api"], + "@spartacus/user/account/assets": [ + "../../feature-libs/user/account/assets/public_api" + ], + "@spartacus/user/account/components": [ + "../../feature-libs/user/account/components/public_api" + ], + "@spartacus/user/account/core": [ + "../../feature-libs/user/account/core/public_api" + ], + "@spartacus/user/account": ["../../feature-libs/user/account/public_api"], + "@spartacus/user/account/occ": [ + "../../feature-libs/user/account/occ/public_api" + ], + "@spartacus/user/account/root": [ + "../../feature-libs/user/account/root/public_api" + ], + "@spartacus/user": ["../../feature-libs/user/public_api"], + "@spartacus/user/profile/assets": [ + "../../feature-libs/user/profile/assets/public_api" + ], + "@spartacus/user/profile/components": [ + "../../feature-libs/user/profile/components/public_api" + ], + "@spartacus/user/profile/core": [ + "../../feature-libs/user/profile/core/public_api" + ], + "@spartacus/user/profile": ["../../feature-libs/user/profile/public_api"], + "@spartacus/user/profile/occ": [ + "../../feature-libs/user/profile/occ/public_api" + ], + "@spartacus/user/profile/root": [ + "../../feature-libs/user/profile/root/public_api" + ], + "@spartacus/cdc/assets": ["../../integration-libs/cdc/assets/public_api"], + "@spartacus/cdc/components": [ + "../../integration-libs/cdc/components/public_api" + ], + "@spartacus/cdc/core": ["../../integration-libs/cdc/core/public_api"], + "@spartacus/cdc": ["../../integration-libs/cdc/public_api"], + "@spartacus/cdc/organization/administration": [ + "../../integration-libs/cdc/organization/administration/public_api" + ], + "@spartacus/cdc/organization/user-registration": [ + "../../integration-libs/cdc/organization/user-registration/public_api" + ], + "@spartacus/cdc/root": ["../../integration-libs/cdc/root/public_api"], + "@spartacus/cdc/user-account": [ + "../../integration-libs/cdc/user-account/public_api" + ], + "@spartacus/cdc/user-profile": [ + "../../integration-libs/cdc/user-profile/public_api" + ], + "@spartacus/cdp/customer-ticketing": [ + "../../integration-libs/cdp/customer-ticketing/public_api" + ], + "@spartacus/cdp": ["../../integration-libs/cdp/public_api"], + "@spartacus/cds/assets": ["../../integration-libs/cds/assets/public_api"], + "@spartacus/cds": ["../../integration-libs/cds/public_api"], + "@spartacus/cpq-quote/assets": [ + "../../integration-libs/cpq-quote/assets/public_api" + ], + "@spartacus/cpq-quote/cpq-quote-discount": [ + "../../integration-libs/cpq-quote/cpq-quote-discount/public_api" + ], + "@spartacus/cpq-quote": ["../../integration-libs/cpq-quote/public_api"], + "@spartacus/cpq-quote/root": [ + "../../integration-libs/cpq-quote/root/public_api" + ], + "@spartacus/digital-payments/assets": [ + "../../integration-libs/digital-payments/assets/public_api" + ], + "@spartacus/digital-payments": [ + "../../integration-libs/digital-payments/public_api" + ], + "@spartacus/epd-visualization/assets": [ + "../../integration-libs/epd-visualization/assets/public_api" + ], + "@spartacus/epd-visualization/components": [ + "../../integration-libs/epd-visualization/components/public_api" + ], + "@spartacus/epd-visualization/core": [ + "../../integration-libs/epd-visualization/core/public_api" + ], + "@spartacus/epd-visualization/epd-visualization-api": [ + "../../integration-libs/epd-visualization/epd-visualization-api/public_api" + ], + "@spartacus/epd-visualization": [ + "../../integration-libs/epd-visualization/public_api" + ], + "@spartacus/epd-visualization/root": [ + "../../integration-libs/epd-visualization/root/public_api" + ], + "@spartacus/omf": ["../../integration-libs/omf/public_api"], + "@spartacus/omf/order": ["../../integration-libs/omf/order/public_api"], + "@spartacus/omf/root": ["../../integration-libs/omf/root/public_api"], + "@spartacus/opps": ["../../integration-libs/opps/public_api"], + "@spartacus/opps/root": ["../../integration-libs/opps/root/public_api"], + "@spartacus/s4-service/assets": [ + "../../integration-libs/s4-service/assets/public_api" + ], + "@spartacus/s4-service/checkout": [ + "../../integration-libs/s4-service/checkout/public_api" + ], + "@spartacus/s4-service": ["../../integration-libs/s4-service/public_api"], + "@spartacus/s4-service/order": [ + "../../integration-libs/s4-service/order/public_api" + ], + "@spartacus/s4-service/root": [ + "../../integration-libs/s4-service/root/public_api" + ], + "@spartacus/s4om/assets": [ + "../../integration-libs/s4om/assets/public_api" + ], + "@spartacus/s4om": ["../../integration-libs/s4om/public_api"], + "@spartacus/s4om/root": ["../../integration-libs/s4om/root/public_api"], + "@spartacus/segment-refs": [ + "../../integration-libs/segment-refs/public_api" + ], + "@spartacus/segment-refs/root": [ + "../../integration-libs/segment-refs/root/public_api" + ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], + "@spartacus/assets": ["../../projects/assets/src/public_api"], + "@spartacus/core": ["../../projects/core/public_api"], + "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] + }, + "noEmitOnError": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUnusedParameters": true, + "noUnusedLocals": true, + "skipDefaultLibCheck": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "strictNullChecks": true, + "resolveJsonModule": true, + "esModuleInterop": true + }, + "include": ["schematics/**/*.ts"], + "exclude": ["schematics/*/files/**/*", "schematics/**/*_spec.ts"] +} diff --git a/integration-libs/subscription-billing/tsconfig.spec.json b/integration-libs/subscription-billing/tsconfig.spec.json new file mode 100644 index 00000000000..32e84d9e66c --- /dev/null +++ b/integration-libs/subscription-billing/tsconfig.spec.json @@ -0,0 +1,12 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "strict": false, + "module": "es2022", + "types": ["jasmine", "node"] + }, + "files": ["test.ts"], + "include": ["**/*.spec.ts", "**/*.d.ts"] +} diff --git a/package.json b/package.json index d56f85c4d69..f1b066e4b90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "storefrontapp", - "version": "1.0.0", + "version": "0.0.0", "license": "Apache-2.0", "author": "SAP, Spartacus team", "engines": { @@ -22,10 +22,11 @@ "build:customer-ticketing": "npm --prefix feature-libs/customer-ticketing run build:schematics && nx build customer-ticketing --configuration production", "build:digital-payments": "npm --prefix integration-libs/digital-payments run build:schematics && nx build digital-payments --configuration production", "build:s4-service": "npm --prefix integration-libs/s4-service run build:schematics && nx build s4-service --configuration production", + "build:subscription-billing": "npm --prefix integration-libs/subscription-billing run build:schematics && nx build subscription-billing --configuration production", "build:epd-visualization": "npm --prefix integration-libs/epd-visualization run build:schematics && nx build epd-visualization --configuration production", "build:estimated-delivery-date": "npm --prefix feature-libs/estimated-delivery-date run build:schematics && nx build estimated-delivery-date --configuration production", "build:order": "npm --prefix feature-libs/order run build:schematics && nx build order --configuration production", - "build:libs": "nx build core --configuration production && nx build storefrontlib --configuration production && concurrently --kill-others-on-fail npm:build:schematics npm:build:user && npm run build:cart && npm run build:pdf-invoices && npm run build:order && npm run build:storefinder && concurrently --kill-others-on-fail npm:build:checkout npm:build:asm npm:build:tracking npm:build:customer-ticketing && concurrently --kill-others-on-fail npm:build:organization npm:build:product npm:build:product-configurator npm:build:product-multi-dimensional && concurrently --kill-others-on-fail npm:build:requested-delivery-date && concurrently --kill-others-on-fail npm:build:estimated-delivery-date && concurrently --kill-others-on-fail npm:build:smartedit npm:build:qualtrics npm:build:assets npm:build:cds npm:build:cdc npm:build:cdp npm:build:digital-payments npm:build:epd-visualization npm:build:s4om npm:build:omf npm:build:cpq-quote npm:build:segment-refs npm:build:opf npm:build:opps npm:build:pickup-in-store npm:build:quote && npm run build:setup && npm run build:s4-service", + "build:libs": "nx build core --configuration production && nx build storefrontlib --configuration production && concurrently --kill-others-on-fail npm:build:schematics npm:build:user && npm run build:cart && npm run build:pdf-invoices && npm run build:order && npm run build:storefinder && concurrently --kill-others-on-fail npm:build:checkout npm:build:asm npm:build:tracking npm:build:customer-ticketing && concurrently --kill-others-on-fail npm:build:organization npm:build:product npm:build:product-configurator npm:build:product-multi-dimensional && concurrently --kill-others-on-fail npm:build:requested-delivery-date && concurrently --kill-others-on-fail npm:build:estimated-delivery-date && concurrently --kill-others-on-fail npm:build:smartedit npm:build:qualtrics npm:build:assets npm:build:cds npm:build:cdc npm:build:cdp npm:build:digital-payments npm:build:epd-visualization npm:build:s4om npm:build:omf npm:build:cpq-quote npm:build:segment-refs npm:build:opf npm:build:opps npm:build:pickup-in-store npm:build:quote && npm run build:setup && npm run build:s4-service && npm run build:subscription-billing", "build:organization": "npm --prefix feature-libs/organization run build:schematics && nx build organization --configuration production", "build:pdf-invoices": "npm --prefix feature-libs/pdf-invoices run build:schematics && nx build pdf-invoices --configuration production", "build:pickup-in-store": "npm --prefix feature-libs/pickup-in-store run build:schematics && nx build pickup-in-store --configuration production", @@ -75,8 +76,8 @@ "e2e:run:ci:cdp": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:cdp", "e2e:run:ci:digital-payments": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:digital-payments", "e2e:run:ci:s4-service": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:s4-service", + "e2e:run:ci:subscription-billing": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:subscription-billing", "e2e:run:ci:epd-visualization": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:epd-visualization", - "e2e:run:ci:asm": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:asm", "e2e:run:ci:ccv2": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:ccv2", "e2e:run:ci:ccv2-b2b": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:ccv2-b2b", "e2e:run:ci:ccv2-product-configurator": "npm --prefix ./projects/storefrontapp-e2e-cypress run cy:run:ci:ccv2-product-configurator", @@ -106,7 +107,7 @@ "start:pwa": "cd ./dist/storefrontapp/ && http-server --silent --proxy http://localhost:4200? -p 4200", "test": "nx test", "test:all-schematics": "set -e; npm --prefix ./projects/schematics test -- -u; for dir in feature-libs/* integration-libs/*; do (cd $dir && npm run test:schematics -- -u); done", - "test:libs": "concurrently \"nx test core --code-coverage\" \"nx test storefrontlib --code-coverage\" \"nx test cart --code-coverage\" \"nx test organization --code-coverage\" \"nx test storefinder --code-coverage\" \"nx test smartedit --code-coverage\" \"nx test asm --code-coverage\" \"nx test qualtrics --code-coverage\" \"nx test product --code-coverage\" \"nx test product-configurator --code-coverage\" \"nx test product-multi-dimensional --code-coverage\" \"nx test customer-ticketing --code-coverage\" \"nx test cdc --code-coverage\" \"nx test s4-service --code-coverage\" \"nx test cdp --code-coverage\" \"nx test opps --code-coverage\" \"nx test setup --code-coverage\" \"nx test checkout --code-coverage\" \"nx test order --code-coverage\" \"nx test digital-payments --code-coverage\" \"nx test epd-visualization --code-coverage\" \"nx test pickup-in-store --code-coverage\" \"nx test s4om --code-coverage\" \"nx test cpq-quote --code-coverage\" \"nx test omf --code-coverage\" \"nx test requested-delivery-date --code-coverage\" \"nx test estimated-delivery-date --code-coverage\" \"nx test pdf-invoices --code-coverage\" \"nx test quote --code-coverage\" \"nx test opf --code-coverage\"", + "test:libs": "concurrently \"nx test core --code-coverage\" \"nx test storefrontlib --code-coverage\" \"nx test cart --code-coverage\" \"nx test organization --code-coverage\" \"nx test storefinder --code-coverage\" \"nx test smartedit --code-coverage\" \"nx test asm --code-coverage\" \"nx test qualtrics --code-coverage\" \"nx test product --code-coverage\" \"nx test product-configurator --code-coverage\" \"nx test product-multi-dimensional --code-coverage\" \"nx test customer-ticketing --code-coverage\" \"nx test cdc --code-coverage\" \"nx test s4-service --code-coverage\" \"nx test cdp --code-coverage\" \"nx test opps --code-coverage\" \"nx test setup --code-coverage\" \"nx test checkout --code-coverage\" \"nx test order --code-coverage\" \"nx test digital-payments --code-coverage\" \"nx test epd-visualization --code-coverage\" \"nx test pickup-in-store --code-coverage\" \"nx test s4om --code-coverage\" \"nx test cpq-quote --code-coverage\" \"nx test omf --code-coverage\" \"nx test requested-delivery-date --code-coverage\" \"nx test estimated-delivery-date --code-coverage\" \"nx test pdf-invoices --code-coverage\" \"nx test quote --code-coverage\" \"nx test opf --code-coverage\" \"nx test subscription-billing --code-coverage\"", "test:storefront:lib": "nx test storefrontlib --source-map --code-coverage", "test:opf:lib": "nx test opf --source-map --code-coverage", "dev:ssr": "env-cmd --no-override -e dev,b2c,$SPA_ENV cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 nx run storefrontapp:serve-ssr", diff --git a/projects/schematics/src/add-spartacus/schema.json b/projects/schematics/src/add-spartacus/schema.json index bf7409939c5..fffdde28110 100644 --- a/projects/schematics/src/add-spartacus/schema.json +++ b/projects/schematics/src/add-spartacus/schema.json @@ -75,6 +75,7 @@ "S4HANA-Order-Management", "cpq-quote", "s4-service", + "subscription-billing", "OMF", "SmartEdit", "Store-Finder", @@ -260,6 +261,10 @@ "value": "s4-service", "label": "S/4HANA Service Integration (b2b feature)" }, + { + "value": "subscription-billing", + "label": "Subscription Billing Integration" + }, { "value": "OMF", "label": "SAP Order Management Foundation Integration" diff --git a/projects/schematics/src/dependencies.json b/projects/schematics/src/dependencies.json index b27fa04903a..fcb28c4b74d 100644 --- a/projects/schematics/src/dependencies.json +++ b/projects/schematics/src/dependencies.json @@ -472,6 +472,15 @@ "@spartacus/schematics": "2211.37.0", "rxjs": "^7.8.2" }, + "@spartacus/subscription-billing": { + "@angular-devkit/schematics": "^17.0.5", + "@angular/common": "^17.0.5", + "@angular/core": "^17.0.5", + "@spartacus/core": "2211.29.0", + "@spartacus/schematics": "2211.29.0", + "@spartacus/storefront": "2211.29.0", + "rxjs": "^7.8.0" + }, "storefrontapp": { "@angular/animations": "^19.1.8", "@angular/common": "^19.1.8", diff --git a/projects/schematics/src/shared/lib-configs/integration-libs/index.ts b/projects/schematics/src/shared/lib-configs/integration-libs/index.ts index 203266bfbeb..bb6e2291b0d 100644 --- a/projects/schematics/src/shared/lib-configs/integration-libs/index.ts +++ b/projects/schematics/src/shared/lib-configs/integration-libs/index.ts @@ -16,3 +16,4 @@ export * from './opps-schematics-config'; export * from './cpq-quote-schematics-config'; export * from './s4-service-schematics-config'; export * from './omf-schematics-config'; +export * from './subscription-billing-schematics-config'; diff --git a/projects/schematics/src/shared/lib-configs/integration-libs/subscription-billing-schematics-config.ts b/projects/schematics/src/shared/lib-configs/integration-libs/subscription-billing-schematics-config.ts new file mode 100644 index 00000000000..4508a5a5f61 --- /dev/null +++ b/projects/schematics/src/shared/lib-configs/integration-libs/subscription-billing-schematics-config.ts @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + SUBSCRIPTION_BILLING_FEATURE_NAME, + SPARTACUS_SUBSCRIPTION_BILLING, + SPARTACUS_SUBSCRIPTION_BILLING_ROOT, + SPARTACUS_SUBSCRIPTION_BILLING_ASSETS, +} from '../../libs-constants'; +import { SchematicConfig } from '../../utils/lib-utils'; + +export const SUBSCRIPTION_BILLING_FOLDER_NAME = 'subscription-billing'; +export const SUBSCRIPTION_BILLING_MODULE = 'SubscriptionBillingModule'; +export const SUBSCRIPTION_BILLING_MODULE_NAME = 'SubscriptionBilling'; +export const SUBSCRIPTION_BILLING_ROOT_MODULE = 'SubscriptionBillingRootModule'; +export const SUBSCRIPTION_BILLING_SCSS_FILE_NAME = 'subscription-billing.scss'; +export const SUBSCRIPTION_BILLING_FEATURE_NAME_CONSTANT = + 'SUBSCRIPTION_BILLING_FEATURE'; +export const SUBSCRIPTION_BILLING_TRANSLATIONS = + 'subscriptionBillingTranslations'; +export const SUBSCRIPTION_BILLING_TRANSLATION_CHUNKS_CONFIG = + 'subscriptionBillingTranslationChunksConfig'; + +export const SUBSCRIPTION_BILLING_SCHEMATICS_CONFIG: SchematicConfig = { + library: { + featureName: SUBSCRIPTION_BILLING_FEATURE_NAME, + mainScope: SPARTACUS_SUBSCRIPTION_BILLING, + }, + folderName: SUBSCRIPTION_BILLING_FOLDER_NAME, + moduleName: SUBSCRIPTION_BILLING_MODULE_NAME, + featureModule: [ + { + name: SUBSCRIPTION_BILLING_MODULE, + importPath: SPARTACUS_SUBSCRIPTION_BILLING, + }, + ], + rootModule: { + importPath: SPARTACUS_SUBSCRIPTION_BILLING_ROOT, + name: SUBSCRIPTION_BILLING_ROOT_MODULE, + }, + styles: { + scssFileName: SUBSCRIPTION_BILLING_SCSS_FILE_NAME, + importStyle: SPARTACUS_SUBSCRIPTION_BILLING, + }, + i18n: { + resources: SUBSCRIPTION_BILLING_TRANSLATIONS, + chunks: SUBSCRIPTION_BILLING_TRANSLATION_CHUNKS_CONFIG, + importPath: SPARTACUS_SUBSCRIPTION_BILLING_ASSETS, + }, +}; diff --git a/projects/schematics/src/shared/libs-constants.ts b/projects/schematics/src/shared/libs-constants.ts index 7e72c4a9969..525863b98e1 100644 --- a/projects/schematics/src/shared/libs-constants.ts +++ b/projects/schematics/src/shared/libs-constants.ts @@ -265,6 +265,10 @@ export const SPARTACUS_OPPS_ROOT = '@spartacus/opps/root'; export const SPARTACUS_SEGMENT_REFS = '@spartacus/segment-refs'; export const SPARTACUS_SEGMENT_REFS_ROOT = `@spartacus/segment-refs/root`; +export const SPARTACUS_SUBSCRIPTION_BILLING = '@spartacus/subscription-billing'; +export const SPARTACUS_SUBSCRIPTION_BILLING_ASSETS = `@spartacus/subscription-billing/assets`; +export const SPARTACUS_SUBSCRIPTION_BILLING_ROOT = `@spartacus/subscription-billing/root`; + export const SPARTACUS_S4_SERVICE = '@spartacus/s4-service'; export const SPARTACUS_S4_SERVICE_ASSETS = `@spartacus/s4-service/assets`; export const SPARTACUS_S4_SERVICE_ROOT = `@spartacus/s4-service/root`; @@ -360,6 +364,8 @@ export const S4OM_FEATURE_NAME = 'S4HANA-Order-Management'; export const SEGMENT_REFS_FEATURE_NAME = 'Segment-Refs'; +export const SUBSCRIPTION_BILLING_FEATURE_NAME = 'Subscription-Billing'; + export const S4_SERVICE_FEATURE_NAME = 's4-service'; export const OPPS_FEATURE_NAME = 'OPPS'; diff --git a/projects/schematics/src/shared/schematics-config-mappings.ts b/projects/schematics/src/shared/schematics-config-mappings.ts index b1474a4cdf2..fd69b12a8b7 100644 --- a/projects/schematics/src/shared/schematics-config-mappings.ts +++ b/projects/schematics/src/shared/schematics-config-mappings.ts @@ -11,6 +11,7 @@ import { OPPS_SCHEMATICS_CONFIG, QUOTE_SCHEMATICS_CONFIG, S4_SERVICE_SCHEMATICS_CONFIG, + SUBSCRIPTION_BILLING_SCHEMATICS_CONFIG, } from './lib-configs'; import { ASM_CUSTOMER_360_SCHEMATICS_CONFIG, @@ -180,6 +181,9 @@ export const SCHEMATICS_CONFIGS: SchematicConfig[] = [ S4_SERVICE_SCHEMATICS_CONFIG, SEGMENT_REFS_SCHEMATICS_CONFIG, + + SUBSCRIPTION_BILLING_SCHEMATICS_CONFIG, + CPQ_QUOTE_SCHEMATICS_CONFIG, ]; diff --git a/projects/schematics/src/shared/utils/graph-utils_spec.ts b/projects/schematics/src/shared/utils/graph-utils_spec.ts index 19c59b19251..3041e973959 100644 --- a/projects/schematics/src/shared/utils/graph-utils_spec.ts +++ b/projects/schematics/src/shared/utils/graph-utils_spec.ts @@ -30,6 +30,7 @@ import { SPARTACUS_SEGMENT_REFS, SPARTACUS_SMARTEDIT, SPARTACUS_STOREFINDER, + SPARTACUS_SUBSCRIPTION_BILLING, SPARTACUS_TRACKING, SPARTACUS_USER, } from '../libs-constants'; @@ -147,6 +148,7 @@ describe('Graph utils', () => { SPARTACUS_CUSTOMER_TICKETING, SPARTACUS_ORGANIZATION, SPARTACUS_ASM, + SPARTACUS_SUBSCRIPTION_BILLING, SPARTACUS_SEGMENT_REFS, SPARTACUS_S4OM, SPARTACUS_S4_SERVICE, @@ -210,6 +212,7 @@ describe('Graph utils', () => { "ASM", "ASM-Customer-360", "cpq-quote", + "Subscription-Billing", "Segment-Refs", "s4-service", "S4HANA-Order-Management", diff --git a/projects/schematics/src/shared/utils/test-utils.ts b/projects/schematics/src/shared/utils/test-utils.ts index a7c5b44b589..8ab0d16cd16 100644 --- a/projects/schematics/src/shared/utils/test-utils.ts +++ b/projects/schematics/src/shared/utils/test-utils.ts @@ -123,6 +123,8 @@ export const oppsFeatureModulePath = 'src/app/spartacus/features/opps/opps-feature.module.ts'; export const s4ServiceFeatureModulePath = 'src/app/spartacus/features/s4-service/s4-service-feature.module.ts'; +export const subscriptionBillingFeatureModulePath = + 'src/app/spartacus/features/subscription-billing/subscription-billing-feature.module.ts'; export function writeFile( host: TempScopedNodeJsSyncHost, diff --git a/projects/storefrontapp-e2e-cypress/cypress/e2e/vendor/subscription-billing/b2b-susbcription-billing-checkout.e2e.cy.ts b/projects/storefrontapp-e2e-cypress/cypress/e2e/vendor/subscription-billing/b2b-susbcription-billing-checkout.e2e.cy.ts new file mode 100644 index 00000000000..ed6d631d91a --- /dev/null +++ b/projects/storefrontapp-e2e-cypress/cypress/e2e/vendor/subscription-billing/b2b-susbcription-billing-checkout.e2e.cy.ts @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as helper from '../../../helpers/vendor/subscription-billing/subscription-billing'; +import { POWERTOOLS_BASESITE } from '../../../sample-data/b2b-checkout'; + +describe('Susbscription Product Checkout Flow', () => { + beforeEach(() => { + cy.restoreLocalStorage(); + Cypress.env('BASE_SITE', POWERTOOLS_BASESITE); + }); + it('should open a subscription product', () => { + helper.openSubscriptionProduct( + POWERTOOLS_BASESITE, + 'USD', + helper.subscription_product_1.code + ); + helper.verifySubscriptionProductDetails(helper.subscription_product_1); + }); +}); diff --git a/projects/storefrontapp-e2e-cypress/cypress/helpers/vendor/subscription-billing/subscription-billing.ts b/projects/storefrontapp-e2e-cypress/cypress/helpers/vendor/subscription-billing/subscription-billing.ts new file mode 100644 index 00000000000..5d018d9f45d --- /dev/null +++ b/projects/storefrontapp-e2e-cypress/cypress/helpers/vendor/subscription-billing/subscription-billing.ts @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + addToCartButton, + breadcrumbContainer, + infoContainer, + itemCounter, + summaryContainer, +} from '../../product-details'; + +export const subscriptionPriceContainer = 'cx-subscription-product-price'; +export const susbscriptionUsageChargeContainer = + 'cx-subscription-product-usage-charge'; + +export const subscription_product_1 = { + code: 'Mobile_2020_Plan_cpq', + name: 'Mobile Plan 2020', + summary: + 'Customizable mobile service plan offering tailored pricing and configurations', + sapSubscriptionTerm: { + name: 'Advanced Mobile Plan', + renewalTerm: { + value: 3, + frequency: { + id: 'MONTHLY', + name: 'Months', + }, + }, + minimumTerm: { + value: 3, + frequency: { + id: 'MONTHLY', + name: 'Months', + }, + }, + }, +}; + +export function verifySubscriptionProductDetails(product) { + cy.intercept({ + method: 'GET', + pathname: `${Cypress.env('OCC_PREFIX')}/${Cypress.env( + 'BASE_SITE' + )}/cms/components`, + }).as('getComponents'); + cy.wait('@getComponents').its('response.statusCode').should('eq', 200); + cy.get(`${breadcrumbContainer} h1`).should('contain', product.name); + cy.get(`${infoContainer} .code`).should('contain', 'ID ' + product.code); + cy.get(`${summaryContainer} .summary`).should('contain', product.summary); + cy.get( + `${subscriptionPriceContainer} .subscription .subscription-name` + ).should('contain', product.sapSubscriptionTerm.name); + cy.get( + `${subscriptionPriceContainer} .subscription .subscription-minimumterm` + ).should( + 'contain', + 'Minimum Term: ' + + product.sapSubscriptionTerm.minimumTerm.value + + ' ' + + product.sapSubscriptionTerm.minimumTerm.frequency.name + ); + cy.get( + `${subscriptionPriceContainer} .subscription .subscription-renewalterm` + ).should( + 'contain', + 'Renewal Term: ' + + product.sapSubscriptionTerm.renewalTerm.value + + ' ' + + product.sapSubscriptionTerm.renewalTerm.frequency.name + ); + cy.get( + `${susbscriptionUsageChargeContainer} .subscription-usage-charge .subscription-usage-charge-name` + ).should('contain', 'Usage Charges'); + cy.get(`${addToCartButton}`).should('exist'); + cy.get(`${itemCounter}`).should('not.exist'); +} + +export function openSubscriptionProduct(baseSite, currency, productCode) { + cy.window().then((win) => win.sessionStorage.clear()); + cy.cxConfig({ + context: { + baseSite: [baseSite], + currency: [currency], + }, + }); + cy.intercept({ + method: 'GET', + path: `${Cypress.env('OCC_PREFIX')}/${Cypress.env( + 'BASE_SITE' + )}/cms/pages?pageType=ProductPage**`, + }).as('productPage'); + cy.visit('/product/' + productCode); + cy.wait(`@productPage`); +} diff --git a/projects/storefrontapp-e2e-cypress/package.json b/projects/storefrontapp-e2e-cypress/package.json index fc8fb459b3a..54bf5579a1d 100644 --- a/projects/storefrontapp-e2e-cypress/package.json +++ b/projects/storefrontapp-e2e-cypress/package.json @@ -18,30 +18,30 @@ "cy:run:core": "cypress run --spec \"cypress/e2e/**/*.core-e2e.cy.ts\"", "cy:run:product-configurator-vc": "cypress run --spec \"cypress/e2e/**/*-configurator*.*e2e.cy.ts\"", "cy:run:cpq": "cypress run --config-file cypress.config.ci.ts --config baseUrl=https://jsapps.cpce-teamtiger1-d2-public.model-t.cc.commerce.ondemand.com,defaultCommandTimeout=100000,requestTimeout=1000000,responseTimeout=1000000,pageLoadTimeout=1000000 --reporter junit --reporter-options mochaFile=results/test-results-[hash].xml --env API_URL=https://api.cpce-teamtiger1-d2-public.model-t.cc.commerce.ondemand.com --spec \"cypress/e2e/**/cpq-configuration.core-e2e.cy.ts\"", - "cy:run:ci": "cypress run --config-file cypress.config.ci.ts --record --key $CYPRESS_KEY --tag \"b2c,all\" --parallel --ci-build-id $BUILD_NUMBER --group B2C --spec \"cypress/e2e/!(vendor|b2b|ssr|cx_ccv2|cx_mcs)/**/(!(my-account-v2))*e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2c-[hash].xml", - "cy:run:ci:core": "cypress run --config-file cypress.config.ci.ts --record --key $CYPRESS_KEY --tag \"b2c,core\" --parallel --ci-build-id $BUILD_NUMBER --group B2C --spec \"cypress/e2e/!(vendor|b2b|ssr|cx_ccv2|cx_mcs)/**/*.core-e2e.cy.ts\"", - "cy:run:ci:b2b": "cypress run --config-file cypress.config.ci.ts --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers --record --key $CYPRESS_KEY --tag \"b2b,all\" --parallel --ci-build-id $BUILD_NUMBER --group B2B --spec \"cypress/e2e/b2b/regression/**/*e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2b-[hash].xml", - "cy:run:ci:core:b2b": "cypress run --config-file cypress.config.ci.ts --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers --record --key $CYPRESS_KEY --tag \"b2b,core\" --parallel --ci-build-id $BUILD_NUMBER --group B2B --spec \"cypress/e2e/b2b/regression/**/*.core-e2e.cy.ts\"", - "cy:run:ci:ccv2": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API --spec $E2ES_TO_RUN", - "cy:run:ci:ccv2-b2b": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API,BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers --spec \"cypress/e2e/cx_ccv2/regression/b2b/**/*.e2e.cy.ts\"", - "cy:run:ci:ccv2-product-configurator": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API,BASE_SITE=$E2E_BASE_SITE,OCC_PREFIX_USER_ENDPOINT=orgUsers --spec $E2ES_TO_RUN", - "cy:run:ci:mcs": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API --spec \"cypress/e2e/cx_mcs/regression/b2c/**/*e2e.cy.ts\"", - "cy:run:ci:ssr": "cypress run --config-file cypress.config.ci.ts --config baseUrl=http://localhost:4000 --record --key $CYPRESS_KEY --tag \"ssr,all\" --parallel --ci-build-id $BUILD_NUMBER --group SSR --spec \"cypress/e2e/ssr/*.e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-ssr-[hash].xml", - "cy:run:ci:core:ssr": "cypress run --config-file cypress.config.ci.ts --config baseUrl=http://localhost:4000 --record --key $CYPRESS_KEY --tag \"ssr,core\" --parallel --ci-build-id $BUILD_NUMBER --group SSR --spec \"cypress/e2e/ssr/*.core-e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-ssr-[hash].xml", - "cy:run:ci:cds": "cypress run --config-file cypress.config.ci.ts --tag \"2011,b2c,all-cds\" --group CDS --spec \"cypress/e2e/vendor/cds/**/*.core-e2e.cy.ts\"", - "cy:run:ci:cdc": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud/ --tag \"2005,cdc\" --group CDC --spec \"cypress/e2e/vendor/cdc/b2c/*.e2e.cy.ts\"", - "cy:run:ci:cdc-b2b": "cypress run --config-file cypress.ci.json --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers,API_URL=https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud/ --tag \"2211,cdc\" --group CDC --spec \"cypress/integration/vendor/cdc/b2b/*.e2e.cy.ts\"", - "cy:run:ci:cdp": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud/ --tag \"2005,cdp\" --group CDP --spec \"cypress/e2e/vendor/cdp/*.e2e.cy.ts\"", - "cy:run:ci:digital-payments": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://backoffice.cp96avkh5f-sapcxteam1-d5-public.model-t.cc.commerce.ondemand.com --tag \"2105,digital-payments\" --group DIGITAL-PAYMENTS --spec \"cypress/e2e/vendor/digital-payments/*.e2e.cy.ts\"", - "cy:run:ci:s4-service": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud/ --tag \"s4-service\" --group s4-service --spec \"cypress/e2e/vendor/s4-service/*.e2e.cy.ts\"", - "cy:run:ci:epd-visualization": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cp96avkh5f-integrati1-d1-public.model-t.cc.commerce.ondemand.com,BASE_SITE=powertools-epdvisualization-spa --tag \"2105,epd-visualization\" --group EPD_VISUALIZATION --ci-build-id $BUILD_NUMBER --spec \"cypress/e2e/vendor/epd-visualization/**/*.e2e.cy.ts\"", - "cy:run:ci:asm": "cypress run --config-file cypress.config.ci.ts --record --key $CYPRESS_KEY --tag \"all-asm\" --spec \"cypress/e2e/vendor/asm/**/*e2e.cy.ts\"", - "cy:run:ci:segment-refs": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-p7-public.model-t.myhybris.cloud/ --tag \"segment-refs\" --group SEGMENT-REFS --spec \"cypress/e2e/vendor/segment-refs/*.e2e.cy.ts\"", - "cy:run:ci:opps": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud/ --tag \"opps\" --group OPPS --spec \"cypress/e2e/vendor/opps/*.e2e.cy.ts\"", - "cy:run:ci:my-account-v2": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud/ --tag \"my-account-v2\" --group MY-ACCOUNT-V2 --spec \"cypress/e2e/regression/my-account/my-account-v2-*.e2e.cy.ts\"", - "cy:run:ci:release": "cypress run --config-file cypress.config.ci.ts --spec \"$(cat tests_to_run.txt)\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2c-[hash].xml", - "cy:run:ci:b2b:release": "cypress run --config-file cypress.config.ci.ts --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers --spec \"cypress/e2e/b2b/regression/**/*e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2b-[hash].xml", - "cy:run:ci:ssr:release": "cypress run --config-file cypress.config.ci.ts --config baseUrl=http://localhost:4000 --spec \"cypress/e2e/ssr/*.e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-ssr-[hash].xml" + "cy:run:ci": "cypress run --config-file cypress.config.ci.ts --record --key $CYPRESS_KEY --tag \"b2c,all\" --parallel --ci-build-id $BUILD_NUMBER --group B2C --spec \"cypress/e2e/!(vendor|b2b|ssr|cx_ccv2|cx_mcs)/**/(!(my-account-v2))*e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2c-[hash].xml --env AMP_API_TOKEN=$AMP_API_TOKEN", + "cy:run:ci:core": "cypress run --config-file cypress.config.ci.ts --record --key $CYPRESS_KEY --tag \"b2c,core\" --parallel --ci-build-id $BUILD_NUMBER --group B2C --spec \"cypress/e2e/!(vendor|b2b|ssr|cx_ccv2|cx_mcs)/**/*.core-e2e.cy.ts\" --env AMP_API_TOKEN=$AMP_API_TOKEN", + "cy:run:ci:b2b": "cypress run --config-file cypress.config.ci.ts --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"b2b,all\" --parallel --ci-build-id $BUILD_NUMBER --group B2B --spec \"cypress/e2e/b2b/regression/**/*e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2b-[hash].xml", + "cy:run:ci:core:b2b": "cypress run --config-file cypress.config.ci.ts --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"b2b,core\" --parallel --ci-build-id $BUILD_NUMBER --group B2B --spec \"cypress/e2e/b2b/regression/**/*.core-e2e.cy.ts\"", + "cy:run:ci:ccv2": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API,AMP_API_TOKEN=$AMP_API_TOKEN --spec $E2ES_TO_RUN", + "cy:run:ci:ccv2-b2b": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API,BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers,AMP_API_TOKEN=$AMP_API_TOKEN --spec \"cypress/e2e/cx_ccv2/regression/b2b/**/*.e2e.cy.ts\"", + "cy:run:ci:ccv2-product-configurator": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API,BASE_SITE=$E2E_BASE_SITE,OCC_PREFIX_USER_ENDPOINT=orgUsers,AMP_API_TOKEN=$AMP_API_TOKEN --spec $E2ES_TO_RUN", + "cy:run:ci:mcs": "cypress run --config-file cypress.config.ci.ts --config baseUrl=$ENDPOINT_URL_PUBLIC_SPARTACUS --reporter junit --reporter-options mochaFile=results/spartacus-test-results-[hash].xml --env API_URL=$ENDPOINT_URL_PUBLIC_API,AMP_API_TOKEN=$AMP_API_TOKEN --spec \"cypress/e2e/cx_mcs/regression/b2c/**/*e2e.cy.ts\"", + "cy:run:ci:ssr": "cypress run --config-file cypress.config.ci.ts --config baseUrl=http://localhost:4000 --record --key $CYPRESS_KEY --tag \"ssr,all\" --parallel --ci-build-id $BUILD_NUMBER --group SSR --spec \"cypress/e2e/ssr/*.e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-ssr-[hash].xml --env AMP_API_TOKEN=$AMP_API_TOKEN", + "cy:run:ci:core:ssr": "cypress run --config-file cypress.config.ci.ts --config baseUrl=http://localhost:4000 --record --key $CYPRESS_KEY --tag \"ssr,core\" --parallel --ci-build-id $BUILD_NUMBER --group SSR --spec \"cypress/e2e/ssr/*.core-e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-ssr-[hash].xml --env AMP_API_TOKEN=$AMP_API_TOKEN", + "cy:run:ci:cds": "cypress run --config-file cypress.config.ci.ts --record --key $CYPRESS_KEY --tag \"2011,b2c,all-cds\" --group CDS --spec \"cypress/e2e/vendor/cds/**/*.core-e2e.cy.ts\" --env AMP_API_TOKEN=$AMP_API_TOKEN", + "cy:run:ci:cdc": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"2005,cdc\" --group CDC --spec \"cypress/e2e/vendor/cdc/b2c/*.e2e.cy.ts\"", + "cy:run:ci:cdc-b2b": "cypress run --config-file cypress.ci.json --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers,API_URL=https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"2211,cdc\" --group CDC --spec \"cypress/integration/vendor/cdc/b2b/*.e2e.cy.ts\"", + "cy:run:ci:cdp": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"2005,cdp\" --group CDP --spec \"cypress/e2e/vendor/cdp/*.e2e.cy.ts\"", + "cy:run:ci:digital-payments": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://backoffice.cp96avkh5f-sapcxteam1-d5-public.model-t.cc.commerce.ondemand.com,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"2105,digital-payments\" --group DIGITAL-PAYMENTS --spec \"cypress/e2e/vendor/digital-payments/*.e2e.cy.ts\"", + "cy:run:ci:subscription-billing": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKE --record --key $CYPRESS_KEY --tag \"subscription-billing\" --group subscription-billing --spec \"cypress/e2e/vendor/subscription-billing/*.e2e.cy.ts\"", + "cy:run:ci:s4-service": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s1-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"s4-service\" --group s4-service --spec \"cypress/e2e/vendor/s4-service/*.e2e.cy.ts\"", + "cy:run:ci:epd-visualization": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cp96avkh5f-integrati1-d1-public.model-t.cc.commerce.ondemand.com,BASE_SITE=powertools-epdvisualization-spa,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"2105,epd-visualization\" --group EPD_VISUALIZATION --ci-build-id $BUILD_NUMBER --spec \"cypress/e2e/vendor/epd-visualization/**/*.e2e.cy.ts\"", + "cy:run:ci:segment-refs": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-p7-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"segment-refs\" --group SEGMENT-REFS --spec \"cypress/e2e/vendor/segment-refs/*.e2e.cy.ts\"", + "cy:run:ci:opps": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"opps\" --group OPPS --spec \"cypress/e2e/vendor/opps/*.e2e.cy.ts\"", + "cy:run:ci:my-account-v2": "cypress run --config-file cypress.config.ci.ts --env API_URL=https://api.cg79x9wuu9-eccommerc1-s5-public.model-t.myhybris.cloud/,AMP_API_TOKEN=$AMP_API_TOKEN --record --key $CYPRESS_KEY --tag \"my-account-v2\" --group MY-ACCOUNT-V2 --spec \"cypress/e2e/regression/my-account/my-account-v2-*.e2e.cy.ts\"", + "cy:run:ci:release": "cypress run --config-file cypress.config.ci.ts --spec \"$(cat tests_to_run.txt)\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2c-[hash].xml --env AMP_API_TOKEN=$AMP_API_TOKEN", + "cy:run:ci:b2b:release": "cypress run --config-file cypress.config.ci.ts --env BASE_SITE=powertools-spa,OCC_PREFIX_USER_ENDPOINT=orgUsers,AMP_API_TOKEN=$AMP_API_TOKEN --spec \"cypress/e2e/b2b/regression/**/*e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-b2b-[hash].xml", + "cy:run:ci:ssr:release": "cypress run --config-file cypress.config.ci.ts --config baseUrl=http://localhost:4000 --spec \"cypress/e2e/ssr/*.e2e.cy.ts\" --reporter junit --reporter-options mochaFile=results/e2e-test-ssr-[hash].xml --env AMP_API_TOKEN=$AMP_API_TOKEN" }, "devDependencies": { "@babel/core": "^7.14.3", diff --git a/projects/storefrontapp/src/app/spartacus/features/subscription-billing/subscription-billing-feature.module.ts b/projects/storefrontapp/src/app/spartacus/features/subscription-billing/subscription-billing-feature.module.ts new file mode 100644 index 00000000000..bcac4be5f1b --- /dev/null +++ b/projects/storefrontapp/src/app/spartacus/features/subscription-billing/subscription-billing-feature.module.ts @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP Spartacus team + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { NgModule } from '@angular/core'; +import { CmsConfig, I18nConfig, provideConfig } from '@spartacus/core'; +import { + subscriptionBillingTranslations, + subscriptionBillingTranslationChunksConfig, +} from '@spartacus/subscription-billing/assets'; +import { + SUBSCRIPTION_BILLING_FEATURE, + SubscriptionBillingRootModule, +} from '@spartacus/subscription-billing/root'; +@NgModule({ + imports: [SubscriptionBillingRootModule], + providers: [ + provideConfig({ + featureModules: { + [SUBSCRIPTION_BILLING_FEATURE]: { + module: () => + import('@spartacus/subscription-billing').then( + (m) => m.SubscriptionBillingModule + ), + }, + }, + }), + provideConfig({ + i18n: { + resources: subscriptionBillingTranslations, + chunks: subscriptionBillingTranslationChunksConfig, + fallbackLang: 'en', + }, + }), + ], +}) +export class SubscriptionBillingFeatureModule {} diff --git a/projects/storefrontapp/src/app/spartacus/spartacus-features.module.ts b/projects/storefrontapp/src/app/spartacus/spartacus-features.module.ts index a7ea5703f1a..a6e7f75910d 100644 --- a/projects/storefrontapp/src/app/spartacus/spartacus-features.module.ts +++ b/projects/storefrontapp/src/app/spartacus/spartacus-features.module.ts @@ -108,6 +108,7 @@ import { SmartEditFeatureModule } from './features/smartedit/smartedit-feature.m import { StoreFinderFeatureModule } from './features/storefinder/storefinder-feature.module'; import { PersonalizationFeatureModule } from './features/tracking/personalization-feature.module'; import { UserFeatureModule } from './features/user/user-feature.module'; +import { SubscriptionBillingFeatureModule } from './features/subscription-billing/subscription-billing-feature.module'; const featureModules = []; @@ -167,6 +168,9 @@ if (environment.omf) { if (environment.cpq) { featureModules.push(CpqQuoteFeatureModule); } +if (environment.subscriptionBilling) { + featureModules.push(SubscriptionBillingFeatureModule); +} @NgModule({ imports: [ // Auth Core diff --git a/projects/storefrontapp/src/environments/environment.prod.ts b/projects/storefrontapp/src/environments/environment.prod.ts index 6037371c0e8..6b734ff4c4a 100644 --- a/projects/storefrontapp/src/environments/environment.prod.ts +++ b/projects/storefrontapp/src/environments/environment.prod.ts @@ -27,4 +27,5 @@ export const environment: Environment = { pdfInvoices: buildProcess.env.CX_PDF_INVOICES, myAccountV2: buildProcess.env.CX_MY_ACCOUNT_V2 ?? false, s4Service: buildProcess.env.CX_S4_SERVICE, + subscriptionBilling: buildProcess.env.CX_SUBSCRIPTION_BILLING ?? false, }; diff --git a/projects/storefrontapp/src/environments/environment.ts b/projects/storefrontapp/src/environments/environment.ts index be90972448d..73902645f34 100644 --- a/projects/storefrontapp/src/environments/environment.ts +++ b/projects/storefrontapp/src/environments/environment.ts @@ -40,4 +40,5 @@ export const environment: Environment = { pdfInvoices: buildProcess.env.CX_PDF_INVOICES ?? false, myAccountV2: buildProcess.env.CX_MY_ACCOUNT_V2 ?? false, s4Service: buildProcess.env.CX_S4_SERVICE ?? false, + subscriptionBilling: buildProcess.env.CX_SUBSCRIPTION_BILLING ?? false, }; diff --git a/projects/storefrontapp/src/environments/models/build.process.env.d.ts b/projects/storefrontapp/src/environments/models/build.process.env.d.ts index 344f31b0ffa..f2940d30005 100644 --- a/projects/storefrontapp/src/environments/models/build.process.env.d.ts +++ b/projects/storefrontapp/src/environments/models/build.process.env.d.ts @@ -29,4 +29,5 @@ interface Env { CX_MY_ACCOUNT_V2: boolean; CX_ESTIMATED_DELIVERY_DATE: boolean; CX_S4_SERVICE: boolean; + CX_SUBSCRIPTION_BILLING: boolean; } diff --git a/projects/storefrontapp/src/environments/models/environment.model.ts b/projects/storefrontapp/src/environments/models/environment.model.ts index bfd0088e6d8..0535478db32 100644 --- a/projects/storefrontapp/src/environments/models/environment.model.ts +++ b/projects/storefrontapp/src/environments/models/environment.model.ts @@ -25,4 +25,5 @@ export interface Environment { myAccountV2: boolean; estimatedDeliveryDate: boolean; s4Service: boolean; + subscriptionBilling: boolean; } diff --git a/projects/storefrontapp/tsconfig.app.prod.json b/projects/storefrontapp/tsconfig.app.prod.json index 67b6a220192..da60909d043 100644 --- a/projects/storefrontapp/tsconfig.app.prod.json +++ b/projects/storefrontapp/tsconfig.app.prod.json @@ -448,6 +448,13 @@ "@spartacus/s4om/root": ["dist/s4om/root"], "@spartacus/segment-refs": ["dist/segment-refs"], "@spartacus/segment-refs/root": ["dist/segment-refs/root"], + "@spartacus/subscription-billing/assets": [ + "dist/subscription-billing/assets" + ], + "@spartacus/subscription-billing": ["dist/subscription-billing"], + "@spartacus/subscription-billing/root": [ + "dist/subscription-billing/root" + ], "@spartacus/assets": ["dist/assets"], "@spartacus/core": ["dist/core"], "@spartacus/storefront": ["dist/storefrontlib"] diff --git a/projects/storefrontapp/tsconfig.server.json b/projects/storefrontapp/tsconfig.server.json index 27f2acef4dc..1f3b87ca966 100644 --- a/projects/storefrontapp/tsconfig.server.json +++ b/projects/storefrontapp/tsconfig.server.json @@ -720,6 +720,15 @@ "@spartacus/segment-refs/root": [ "../../integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "../../integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "../../integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "../../integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": ["../../projects/assets/src/public_api"], "@spartacus/core": ["../../projects/core/public_api"], "@spartacus/storefront": ["../../projects/storefrontlib/public_api"] diff --git a/projects/storefrontapp/tsconfig.server.prod.json b/projects/storefrontapp/tsconfig.server.prod.json index de57960ec0c..0232ed00acc 100644 --- a/projects/storefrontapp/tsconfig.server.prod.json +++ b/projects/storefrontapp/tsconfig.server.prod.json @@ -509,6 +509,13 @@ "@spartacus/s4om/root": ["../../dist/s4om/root"], "@spartacus/segment-refs": ["../../dist/segment-refs"], "@spartacus/segment-refs/root": ["../../dist/segment-refs/root"], + "@spartacus/subscription-billing/assets": [ + "../../dist/subscription-billing/assets" + ], + "@spartacus/subscription-billing": ["../../dist/subscription-billing"], + "@spartacus/subscription-billing/root": [ + "../../dist/subscription-billing/root" + ], "@spartacus/assets": ["../../dist/assets"], "@spartacus/core": ["../../dist/core"], "@spartacus/storefront": ["../../dist/storefrontlib"] diff --git a/projects/storefrontlib/cms-components/product/current-product.service.spec.ts b/projects/storefrontlib/cms-components/product/current-product.service.spec.ts index 74bf4d558aa..3dec5d1004e 100644 --- a/projects/storefrontlib/cms-components/product/current-product.service.spec.ts +++ b/projects/storefrontlib/cms-components/product/current-product.service.spec.ts @@ -124,4 +124,10 @@ describe('CurrentProductService', () => { sub.unsubscribe(); }); + it('should show item counter for any product', () => { + expect(currentProductService.showItemCounter({})).toEqual(true); + expect(currentProductService.showItemCounter({ code: '123' })).toEqual( + true + ); + }); }); diff --git a/projects/storefrontlib/cms-components/product/current-product.service.ts b/projects/storefrontlib/cms-components/product/current-product.service.ts index 0986ab5713c..ce611cd2c86 100644 --- a/projects/storefrontlib/cms-components/product/current-product.service.ts +++ b/projects/storefrontlib/cms-components/product/current-product.service.ts @@ -55,4 +55,8 @@ export class CurrentProductService { .getRouterState() .pipe(map((state) => state.state.params['productCode'])); } + + showItemCounter(_product: Product): boolean { + return true; + } } diff --git a/projects/storefrontstyles/scss/_components.scss b/projects/storefrontstyles/scss/_components.scss index f9da6f6539d..d3f74991cbc 100644 --- a/projects/storefrontstyles/scss/_components.scss +++ b/projects/storefrontstyles/scss/_components.scss @@ -17,6 +17,7 @@ $digital-payments-components-allowlist: () !default; $epd-visualization-components-allowlist: () !default; $myaccount-components-allowlist: () !default; $cpq-quote-allowlist: () !default; +$subscription-billing-components-allowlist: () !default; $selectors: mergeAll( ( @@ -30,7 +31,8 @@ $selectors: mergeAll( $cds-components-allowlist, $digital-payments-components-allowlist, $epd-visualization-components-allowlist, - $cpq-quote-allowlist + $cpq-quote-allowlist, + $subscription-billing-components-allowlist ) ); diff --git a/projects/storefrontstyles/scss/components/index.scss b/projects/storefrontstyles/scss/components/index.scss index 4f666630e86..4ebf3ed8f66 100644 --- a/projects/storefrontstyles/scss/components/index.scss +++ b/projects/storefrontstyles/scss/components/index.scss @@ -7,3 +7,4 @@ @import './cds/index'; @import './digital-payments/index'; @import './cpq-quote/index'; +@import './subscription-billing/index'; diff --git a/projects/storefrontstyles/scss/components/subscription-billing/_index.scss b/projects/storefrontstyles/scss/components/subscription-billing/_index.scss new file mode 100644 index 00000000000..c74fa20a405 --- /dev/null +++ b/projects/storefrontstyles/scss/components/subscription-billing/_index.scss @@ -0,0 +1,5 @@ +@import './product/subscription-product-price'; +@import './product/subscription-product-usage-charge'; + +$subscription-billing-components-allowlist: cx-subscription-product-price, + cx-subscription-product-usage-charge !default; diff --git a/projects/storefrontstyles/scss/components/subscription-billing/product/_subscription-product-price.scss b/projects/storefrontstyles/scss/components/subscription-billing/product/_subscription-product-price.scss new file mode 100644 index 00000000000..96d419e290f --- /dev/null +++ b/projects/storefrontstyles/scss/components/subscription-billing/product/_subscription-product-price.scss @@ -0,0 +1,5 @@ +%cx-subscription-product-price { + .subscription-name { + font-weight: var(--cx-font-weight-bold); + } +} diff --git a/projects/storefrontstyles/scss/components/subscription-billing/product/_subscription-product-usage-charge.scss b/projects/storefrontstyles/scss/components/subscription-billing/product/_subscription-product-usage-charge.scss new file mode 100644 index 00000000000..7520be79dc3 --- /dev/null +++ b/projects/storefrontstyles/scss/components/subscription-billing/product/_subscription-product-usage-charge.scss @@ -0,0 +1,20 @@ +%cx-subscription-product-usage-charge { + .subscription-usage-charge { + margin: 20px 0px; + } + .subscription-usage-charge-name { + font-weight: var(--cx-font-weight-bold); + } + .subscription-usage-charge-entry { + border: 1px solid var(--cx-color-medium); + padding: 5px; + margin: 5px 0px; + display: inline-block; + border-radius: 5px; + } + .subscription-message { + @include type('7'); + color: var(--cx-color-secondary); + margin: 0 0 20px 0; + } +} diff --git a/scripts/install/functions.sh b/scripts/install/functions.sh index 9030835eed6..8dec76ce177 100644 --- a/scripts/install/functions.sh +++ b/scripts/install/functions.sh @@ -174,6 +174,12 @@ function add_S4_SERVICE { fi } +function add_subscription_billing { + if [ "$ADD_SUBSCRIPTION_BILLING" = true ] ; then + ng add --skip-confirmation @spartacus/subscription-billing@${SPARTACUS_VERSION} --interactive false + fi +} + function add_cpq-quote { if [ "$ADD_CPQ_QUOTE" = true ] ; then ng add --skip-confirmation @spartacus/cpq-quote@${SPARTACUS_VERSION} --interactive false @@ -230,6 +236,7 @@ function add_spartacus_csr { add_S4_SERVICE add_requested_delivery_date add_estimated_delivery_date + add_subscription_billing add_cpq-quote add_pdf_invoices remove_npmrc @@ -260,6 +267,7 @@ function add_spartacus_ssr { add_S4_SERVICE add_requested_delivery_date add_estimated_delivery_date + add_subscription_billing add_cpq-quote add_pdf_invoices remove_npmrc @@ -288,6 +296,7 @@ function add_spartacus_ssr_pwa { add_S4_SERVICE add_requested_delivery_date add_estimated_delivery_date + add_subscription_billing add_cpq-quote add_pdf_invoices remove_npmrc @@ -843,6 +852,11 @@ function parseInstallArgs { echo "➖ Added Estimated Delivery Date" shift ;; + subscription-billing) + ADD_SUBSCRIPTION_BILLING=true + echo "➖ Added Subscription Billing" + shift + ;; invoices) ADD_PDF_INVOICES=true echo "➖ Added PDF Invoices" diff --git a/tools/schematics/testing.ts b/tools/schematics/testing.ts index 3f8fd3932a9..ea795a720be 100644 --- a/tools/schematics/testing.ts +++ b/tools/schematics/testing.ts @@ -43,6 +43,7 @@ const integrationLibsFolders: string[] = [ 'segment-refs', 'opps', 's4-service', + 'subscription-billing', 'cpq-quote', ]; @@ -56,6 +57,7 @@ const commands = [ 'build quote/schematics', 'build cdc/schematics', 'build s4-service/schematics', + 'build subscription-billing/schematics', 'build cds/schematics', 'build digital-payments/schematics', 'build epd-visualization/schematics', @@ -412,6 +414,7 @@ async function executeCommand(command: Command): Promise { case 'build cpq-quote/schematics': case 'build cdc/schematics': case 'build s4-service/schematics': + case 'build subscription-billing/schematics': case 'build cds/schematics': case 'build digital-payments/schematics': case 'build epd-visualization/schematics': diff --git a/tsconfig.compodoc.json b/tsconfig.compodoc.json index 13abea160e3..50ae7d114c1 100644 --- a/tsconfig.compodoc.json +++ b/tsconfig.compodoc.json @@ -839,6 +839,15 @@ "@spartacus/segment-refs/root": [ "integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": [ "projects/assets/src/public_api" ], diff --git a/tsconfig.json b/tsconfig.json index 99cb7ef6944..b7fec32a2c7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -843,6 +843,15 @@ "@spartacus/segment-refs/root": [ "integration-libs/segment-refs/root/public_api" ], + "@spartacus/subscription-billing/assets": [ + "integration-libs/subscription-billing/assets/public_api" + ], + "@spartacus/subscription-billing": [ + "integration-libs/subscription-billing/public_api" + ], + "@spartacus/subscription-billing/root": [ + "integration-libs/subscription-billing/root/public_api" + ], "@spartacus/assets": [ "projects/assets/src/public_api" ],