diff --git a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.html b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.html index 446b18eddec..c98bd36b640 100644 --- a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.html +++ b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.html @@ -11,8 +11,11 @@ {{ discount.isoCode }}{{ - getDiscountedPrice(quoteDiscountData.basePrice?.value, discount.value) - | number: '1.2-2' : 'en-US' + getDiscountedPrice( + quoteDiscountData.basePrice?.value ?? 0, + discount.appliedValue, + quoteDiscountData.quantity + ) | number: '1.2-2' : 'en-US' }} diff --git a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.spec.ts b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.spec.ts index 4cb775ef20a..7d77352a755 100644 --- a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.spec.ts +++ b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.spec.ts @@ -28,7 +28,7 @@ describe('CpqQuoteDiscountComponent', () => { beforeEach(async () => { cpqQuoteServiceMock = { - isFlag$: of(false), // Mock isFlag$ to return false + isFlag$: of(false), }; mockCartItemContext = new MockCartItemContext(); await TestBed.configureTestingModule({ @@ -54,7 +54,7 @@ describe('CpqQuoteDiscountComponent', () => { const contentElements = fixture.nativeElement.querySelectorAll( '.cx-total, .cx-formatted-value' ); - expect(contentElements.length).toBeGreaterThan(0); // Ensure that at least one element is found + expect(contentElements.length).toBeGreaterThan(0); }); it('should create', () => { expect(component).toBeTruthy(); @@ -92,23 +92,35 @@ describe('CpqQuoteDiscountComponent', () => { const htmlElem = fixture.nativeElement; expect(htmlElem.querySelectorAll('.cx-discount').length).toBe(1); }); - it('should display the appliedValue data', () => { const discounts: CpqDiscounts[] = [ { appliedValue: 30, isoCode: 'USD', value: 15 }, ]; mockCartItemContext.item$.next({ cpqDiscounts: discounts, + basePrice: { value: 100, formattedValue: 'USD100.00' }, + quantity: 1, }); - fixture.detectChanges(); const htmlElem = fixture.nativeElement; const discountsDisplayed = htmlElem.querySelectorAll('.cx-discount'); expect(discountsDisplayed.length).toBe(discounts.length); - for (let i = 0; i < discountsDisplayed.length; i++) { - expect(discountsDisplayed[i].textContent).toContain( - component.getDiscountedPrice(discounts[i].appliedValue, 100) // Assuming 100 as base price + const expectedDiscountedPrice = component.getDiscountedPrice( + 100, + discounts[i].appliedValue, + 1 + ); + const formattedPrice = new Intl.NumberFormat('en-US', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }).format(expectedDiscountedPrice ?? 0); + const expectedDisplayValue = `${discounts[i].isoCode}${formattedPrice}`; + console.log( + `Expected: ${expectedDisplayValue}, Actual: ${discountsDisplayed[i].textContent}` + ); + expect(discountsDisplayed[i].textContent.trim()).toBe( + expectedDisplayValue ); } }); diff --git a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.ts b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.ts index f6860df2761..870f44fbee6 100644 --- a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.ts +++ b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote-discount-tbody/cpq-quote.component.ts @@ -51,12 +51,20 @@ export class CpqQuoteDiscountComponent implements OnInit, OnDestroy { } } getDiscountedPrice( - basePrice: number | undefined, - discountPercentage: number | undefined + basePrice: number, + appliedDiscount: number | undefined, + quantity: number | undefined ): number | undefined { - if (basePrice !== undefined && discountPercentage !== undefined) { - const discountAmount = (basePrice * discountPercentage) / 100; - return basePrice - discountAmount; + if ( + basePrice > 0 && + appliedDiscount !== undefined && + quantity !== undefined && + quantity > 0 + ) { + const totalBasePrice = basePrice * quantity; + const discountedPrice = totalBasePrice - appliedDiscount; + return discountedPrice / quantity; } + return undefined; } } diff --git a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.html b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.html index 31d7e9a35da..8404be7856c 100644 --- a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.html +++ b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.html @@ -13,9 +13,15 @@ 'discountCaption' | cxTranslate : { - discount: discount?.value, + discount: formatDiscount( + getDiscountPercentage( + quoteDiscountData.basePrice?.value ?? 0, + discount.appliedValue, + quoteDiscountData.quantity + ) + ), } }} - + + diff --git a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.spec.ts b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.spec.ts index 004436cb20f..31b1788ba97 100644 --- a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.spec.ts +++ b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.spec.ts @@ -109,5 +109,51 @@ describe('CpqQuoteOfferComponent', () => { component.ngOnInit(); expect(component.quoteDiscountData).toBeNull(); }); + it('should calculate the correct discount percentage', () => { + const basePrice = 100; + const appliedDiscount = 20; + const quantity = 1; + const expectedPercentage = + (appliedDiscount / (basePrice * quantity)) * 100; + const result = component.getDiscountPercentage( + basePrice, + appliedDiscount, + quantity + ); + expect(result).toBe(expectedPercentage); + }); + }); + describe('formatDiscount', () => { + it('should return an empty string for undefined input', () => { + expect(component.formatDiscount(undefined)).toBe(''); + }); + + it('should return "5" for input 5', () => { + expect(component.formatDiscount(5)).toBe('5'); + }); + + it('should return "5.50" for input 5.5', () => { + expect(component.formatDiscount(5.5)).toBe('5.50'); + }); + + it('should return "5.12" for input 5.1234', () => { + expect(component.formatDiscount(5.1234)).toBe('5.12'); + }); + + it('should return "0" for input 0', () => { + expect(component.formatDiscount(0)).toBe('0'); + }); + + it('should return "-3" for input -3', () => { + expect(component.formatDiscount(-3)).toBe('-3'); + }); + + it('should return "-3.25" for input -3.25', () => { + expect(component.formatDiscount(-3.25)).toBe('-3.25'); + }); + + it('should return "1000000" for input 1000000', () => { + expect(component.formatDiscount(1000000)).toBe('1000000'); + }); }); }); diff --git a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.ts b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.ts index 15f7e6fd113..eaa949001f4 100644 --- a/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.ts +++ b/integration-libs/cpq-quote/cpq-quote-discount/components/cpq-quote/cpq-quote-offer.component.ts @@ -45,4 +45,28 @@ export class CpqQuoteOfferComponent implements OnInit, OnDestroy { this.subscription.unsubscribe(); } } + + getDiscountPercentage( + basePrice: number, + appliedDiscount: number | undefined, + quantity: number | undefined + ): number | undefined { + if ( + basePrice > 0 && + appliedDiscount !== undefined && + quantity !== undefined && + quantity > 0 + ) { + const totalBasePrice = basePrice * quantity; + return (appliedDiscount / totalBasePrice) * 100; + } + return undefined; + } + + formatDiscount(value: number | undefined): string { + if (value === undefined) { + return ''; + } + return Number.isInteger(value) ? value.toFixed(0) : value.toFixed(2); + } }