diff --git a/src/app/core/models/line-item/line-item.model.ts b/src/app/core/models/line-item/line-item.model.ts index f56189d10e..01d475ad76 100644 --- a/src/app/core/models/line-item/line-item.model.ts +++ b/src/app/core/models/line-item/line-item.model.ts @@ -28,16 +28,10 @@ export interface LineItem { total: PriceItem; undiscountedTotal; valueRebatesTotal?: PriceItem; - - // attributes needed for quote feature - originTotal?: PriceItem; }; isHiddenGift: boolean; isFreeGift: boolean; - // attributes needed for quote feature - originSingleBasePrice?: PriceItem; - isQuantityFixed?: boolean; } diff --git a/src/app/extensions/quoting/facades/quote-context.facade.ts b/src/app/extensions/quoting/facades/quote-context.facade.ts index c4c91989ce..93a7ee2c51 100644 --- a/src/app/extensions/quoting/facades/quote-context.facade.ts +++ b/src/app/extensions/quoting/facades/quote-context.facade.ts @@ -43,6 +43,7 @@ export abstract class QuoteContextFacade entityAsQuoteRequest: QuoteRequest; entityAsQuote: Quote; state: QuoteStatus; + editable: boolean; justSubmitted: boolean; }> implements OnDestroy { @@ -88,6 +89,8 @@ export abstract class QuoteContextFacade 'state', timer(0, 2000).pipe(switchMapTo(this.select('entity').pipe(map(QuotingHelper.state))), distinctUntilChanged()) ); + + this.connect('editable', this.select('state').pipe(map(state => state === 'New'))); } updateItem(item: LineItemUpdate) { diff --git a/src/app/extensions/quoting/models/quoting/quoting.mapper.spec.ts b/src/app/extensions/quoting/models/quoting/quoting.mapper.spec.ts index 207322713f..dab49b6b5f 100644 --- a/src/app/extensions/quoting/models/quoting/quoting.mapper.spec.ts +++ b/src/app/extensions/quoting/models/quoting/quoting.mapper.spec.ts @@ -210,6 +210,11 @@ describe('Quoting Mapper', () => { "type": "Money", "value": 1002.95, }, + "originTotal": Object { + "currency": "USD", + "type": "Money", + "value": 1002.95, + }, "productSKU": "10696946", "quantity": Object { "type": "Quantity", @@ -221,17 +226,10 @@ describe('Quoting Mapper', () => { "type": "Money", "value": 10.95, }, - "totals": Object { - "originTotal": Object { - "currency": "USD", - "type": "Money", - "value": 1002.95, - }, - "total": Object { - "currency": "USD", - "type": "Money", - "value": 10.95, - }, + "total": Object { + "currency": "USD", + "type": "Money", + "value": 10.95, }, }, ], @@ -363,12 +361,10 @@ describe('Quoting Mapper', () => { "type": "Money", "value": 964.5, }, - "totals": Object { - "total": Object { - "currency": "USD", - "type": "Money", - "value": 964.5, - }, + "total": Object { + "currency": "USD", + "type": "Money", + "value": 964.5, }, }, ], diff --git a/src/app/extensions/quoting/models/quoting/quoting.mapper.ts b/src/app/extensions/quoting/models/quoting/quoting.mapper.ts index 9e52a52fb8..6e1dcb091b 100644 --- a/src/app/extensions/quoting/models/quoting/quoting.mapper.ts +++ b/src/app/extensions/quoting/models/quoting/quoting.mapper.ts @@ -78,10 +78,8 @@ export class QuotingMapper { singleBasePrice: PriceMapper.fromData(item.singlePrice), originSingleBasePrice: PriceMapper.fromData(item.originSinglePrice), - totals: { - total: PriceMapper.fromData(item.totalPrice), - originTotal: PriceMapper.fromData(item.originTotalPrice), - }, + total: PriceMapper.fromData(item.totalPrice), + originTotal: PriceMapper.fromData(item.originTotalPrice), })), }; return mapped; @@ -110,7 +108,7 @@ export class QuotingMapper { productSKU: itemData.productSKU, quantity: itemData.quantity, singleBasePrice: PriceMapper.fromData(itemData.singlePrice), - totals: { total: PriceMapper.fromData(itemData.totalPrice) }, + total: PriceMapper.fromData(itemData.totalPrice), }; } }), diff --git a/src/app/extensions/quoting/models/quoting/quoting.model.ts b/src/app/extensions/quoting/models/quoting/quoting.model.ts index 18130f0a7a..2a955b57a9 100644 --- a/src/app/extensions/quoting/models/quoting/quoting.model.ts +++ b/src/app/extensions/quoting/models/quoting/quoting.model.ts @@ -30,17 +30,15 @@ export interface QuoteRequestItem extends QuoteItemStub { quantity: Attribute; singleBasePrice: Price; - totals: { total: Price }; + total: Price; } -interface QuoteItem extends QuoteRequestItem { +export interface QuoteItem extends QuoteRequestItem { originQuantity: Attribute; originSingleBasePrice: Price; - totals: { - total: Price; - originTotal: Price; - }; + total: Price; + originTotal: Price; } interface QuoteBase extends QuoteStub { diff --git a/src/app/extensions/quoting/quoting.module.ts b/src/app/extensions/quoting/quoting.module.ts index 49891ed7af..c24aec34d0 100644 --- a/src/app/extensions/quoting/quoting.module.ts +++ b/src/app/extensions/quoting/quoting.module.ts @@ -8,6 +8,8 @@ import { ProductAddToQuoteComponent } from './shared/product-add-to-quote/produc import { QuoteEditComponent } from './shared/quote-edit/quote-edit.component'; import { QuoteExpirationDateComponent } from './shared/quote-expiration-date/quote-expiration-date.component'; import { QuoteInteractionsComponent } from './shared/quote-interactions/quote-interactions.component'; +import { QuoteLineItemListElementComponent } from './shared/quote-line-item-list-element/quote-line-item-list-element.component'; +import { QuoteLineItemListComponent } from './shared/quote-line-item-list/quote-line-item-list.component'; import { QuoteStateComponent } from './shared/quote-state/quote-state.component'; import { QuoteViewComponent } from './shared/quote-view/quote-view.component'; import { QuoteWidgetComponent } from './shared/quote-widget/quote-widget.component'; @@ -21,6 +23,8 @@ import { QuoteWidgetComponent } from './shared/quote-widget/quote-widget.compone QuoteEditComponent, QuoteExpirationDateComponent, QuoteInteractionsComponent, + QuoteLineItemListComponent, + QuoteLineItemListElementComponent, QuoteStateComponent, QuoteViewComponent, QuoteWidgetComponent, diff --git a/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.html b/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.html index b03358e897..2f3ee8ed96 100644 --- a/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.html +++ b/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.html @@ -51,15 +51,7 @@

{{ 'quote.items.table.heading' | translate }}

- +
diff --git a/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.spec.ts b/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.spec.ts index d2e92359da..b3923aea7f 100644 --- a/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.spec.ts +++ b/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.spec.ts @@ -6,9 +6,9 @@ import { EMPTY } from 'rxjs'; import { instance, mock, when } from 'ts-mockito'; import { InplaceEditComponent } from 'ish-shared/components/common/inplace-edit/inplace-edit.component'; -import { LineItemListComponent } from 'ish-shared/components/line-item/line-item-list/line-item-list.component'; import { QuoteContextFacade } from '../../facades/quote-context.facade'; +import { QuoteLineItemListComponent } from '../quote-line-item-list/quote-line-item-list.component'; import { QuoteStateComponent } from '../quote-state/quote-state.component'; import { QuoteEditComponent } from './quote-edit.component'; @@ -26,7 +26,7 @@ describe('Quote Edit Component', () => { imports: [ReactiveFormsModule, TranslateModule.forRoot()], declarations: [ MockComponent(InplaceEditComponent), - MockComponent(LineItemListComponent), + MockComponent(QuoteLineItemListComponent), MockComponent(QuoteStateComponent), QuoteEditComponent, ], diff --git a/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.ts b/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.ts index b56afa29a8..bb8a34ccb6 100644 --- a/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.ts +++ b/src/app/extensions/quoting/shared/quote-edit/quote-edit.component.ts @@ -3,8 +3,6 @@ import { FormControl, FormGroup } from '@angular/forms'; import { pick } from 'lodash-es'; import { Observable } from 'rxjs'; -import { LineItemUpdate } from 'ish-core/models/line-item-update/line-item-update.model'; - import { QuoteContextFacade } from '../../facades/quote-context.facade'; import { QuoteRequest } from '../../models/quoting/quoting.model'; @@ -52,12 +50,4 @@ export class QuoteEditComponent implements OnInit { reset() { this.form.reset(this.valuesFromQuote); } - - onUpdateItem(item: LineItemUpdate) { - this.context.updateItem(item); - } - - onDeleteItem(itemId: string) { - this.context.deleteItem(itemId); - } } diff --git a/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.html b/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.html new file mode 100644 index 0000000000..27aded37cb --- /dev/null +++ b/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.html @@ -0,0 +1,138 @@ +
+ +
+ + + +
+ +
+ +
+ {{ product.name }} + + + + + + + + + + +
+ + + + + +
+
+ + +
+
+ + + + + + {{ lineItem.quantity.value | number }} + +
+
+
+ + +
+
+ + + + + + {{ lineItem.quantity.value | number }} + +
+
+ + +
+ +

+ {{ 'quote.items.original_price.label' | translate }} {{ lineItem.originSingleBasePrice | ishPrice }} +

+ + +

+ {{ + 'quote.items.suggested_price.label' | translate + }} + {{ lineItem.singleBasePrice | ishPrice }} +

+
+
+
+

{{ lineItem.originTotal | ishPrice }}

+ + + {{ 'quote.items.suggested_price.label' | translate }} +
{{ lineItem.total | ishPrice }}
+
+
+
diff --git a/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.spec.ts b/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.spec.ts new file mode 100644 index 0000000000..d37efee216 --- /dev/null +++ b/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.spec.ts @@ -0,0 +1,139 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { FaIconComponent } from '@fortawesome/angular-fontawesome'; +import { TranslateModule } from '@ngx-translate/core'; +import { MockComponent, MockPipe } from 'ng-mocks'; +import { of } from 'rxjs'; +import { anything, capture, instance, mock, verify, when } from 'ts-mockito'; + +import { ShoppingFacade } from 'ish-core/facades/shopping.facade'; +import { PricePipe } from 'ish-core/models/price/price.pipe'; +import { ProductView } from 'ish-core/models/product-view/product-view.model'; +import { ProductRoutePipe } from 'ish-core/routing/product/product-route.pipe'; +import { findAllCustomElements, findAllDataTestingIDs } from 'ish-core/utils/dev/html-query-utils'; +import { ProductBundleDisplayComponent } from 'ish-shared/components/product/product-bundle-display/product-bundle-display.component'; +import { ProductIdComponent } from 'ish-shared/components/product/product-id/product-id.component'; +import { ProductInventoryComponent } from 'ish-shared/components/product/product-inventory/product-inventory.component'; +import { ProductVariationDisplayComponent } from 'ish-shared/components/product/product-variation-display/product-variation-display.component'; +import { InputComponent } from 'ish-shared/forms/components/input/input.component'; +import { ProductImageComponent } from 'ish-shell/header/product-image/product-image.component'; + +import { LazyProductAddToOrderTemplateComponent } from '../../../order-templates/exports/lazy-product-add-to-order-template/lazy-product-add-to-order-template.component'; +import { LazyProductAddToWishlistComponent } from '../../../wishlists/exports/lazy-product-add-to-wishlist/lazy-product-add-to-wishlist.component'; +import { QuoteContextFacade } from '../../facades/quote-context.facade'; + +import { QuoteLineItemListElementComponent } from './quote-line-item-list-element.component'; + +describe('Quote Line Item List Element Component', () => { + let component: QuoteLineItemListElementComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + let quoteContext: QuoteContextFacade; + + beforeEach(async () => { + const shoppingFacade = mock(ShoppingFacade); + when(shoppingFacade.product$(anything(), anything())).thenReturn( + of({ + sku: '123', + } as ProductView) + ); + + quoteContext = mock(QuoteContextFacade); + + await TestBed.configureTestingModule({ + imports: [RouterTestingModule, TranslateModule.forRoot()], + declarations: [ + MockComponent(FaIconComponent), + MockComponent(InputComponent), + MockComponent(LazyProductAddToOrderTemplateComponent), + MockComponent(LazyProductAddToWishlistComponent), + MockComponent(ProductBundleDisplayComponent), + MockComponent(ProductIdComponent), + MockComponent(ProductImageComponent), + MockComponent(ProductInventoryComponent), + MockComponent(ProductVariationDisplayComponent), + MockPipe(PricePipe), + MockPipe(ProductRoutePipe), + QuoteLineItemListElementComponent, + ], + providers: [ + { provide: QuoteContextFacade, useFactory: () => instance(quoteContext) }, + { provide: ShoppingFacade, useFactory: () => instance(shoppingFacade) }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(QuoteLineItemListElementComponent); + component = fixture.componentInstance; + element = fixture.nativeElement; + component.lineItem = { + id: 'item123', + quantity: { value: 3 }, + }; + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + expect(element).toBeTruthy(); + expect(() => component.ngOnChanges()).not.toThrow(); + expect(() => fixture.detectChanges()).not.toThrow(); + }); + + it('should render all sub elements when initialized read only', () => { + component.ngOnChanges(); + fixture.detectChanges(); + + expect(findAllCustomElements(element)).toMatchInlineSnapshot(` + Array [ + "ish-product-image", + "ish-product-id", + "ish-product-inventory", + ] + `); + expect(findAllDataTestingIDs(fixture)).toMatchInlineSnapshot(` + Array [ + "product-list-item", + "total-price", + ] + `); + }); + + it('should render all sub elements when initialized editable', () => { + when(quoteContext.select('editable')).thenReturn(of(true)); + + component.ngOnChanges(); + fixture.detectChanges(); + + expect(findAllCustomElements(element)).toMatchInlineSnapshot(` + Array [ + "ish-product-image", + "ish-product-id", + "ish-product-inventory", + "ish-lazy-product-add-to-order-template", + "ish-lazy-product-add-to-wishlist", + "fa-icon", + "ish-input", + "ish-input", + ] + `); + expect(findAllDataTestingIDs(fixture)).toMatchInlineSnapshot(` + Array [ + "product-list-item", + "remove-pli-item123-element", + "total-price", + ] + `); + }); + + it('should use context to delete items', () => { + component.onDeleteItem(); + + verify(quoteContext.deleteItem(anything())).once(); + expect(capture(quoteContext.deleteItem).last()).toMatchInlineSnapshot(` + Array [ + "item123", + ] + `); + }); +}); diff --git a/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.ts b/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.ts new file mode 100644 index 0000000000..00bfdeaed2 --- /dev/null +++ b/src/app/extensions/quoting/shared/quote-line-item-list-element/quote-line-item-list-element.component.ts @@ -0,0 +1,85 @@ +import { ChangeDetectionStrategy, Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { Observable, ReplaySubject, Subject } from 'rxjs'; +import { debounceTime, map, shareReplay, switchMap, takeUntil } from 'rxjs/operators'; + +import { ShoppingFacade } from 'ish-core/facades/shopping.facade'; +import { ProductView } from 'ish-core/models/product-view/product-view.model'; +import { ProductCompletenessLevel, ProductHelper } from 'ish-core/models/product/product.model'; +import { whenTruthy } from 'ish-core/utils/operators'; +import { SpecialValidators } from 'ish-shared/forms/validators/special-validators'; + +import { QuoteContextFacade } from '../../facades/quote-context.facade'; +import { QuoteItem, QuoteRequestItem } from '../../models/quoting/quoting.model'; + +@Component({ + selector: 'ish-quote-line-item-list-element', + templateUrl: './quote-line-item-list-element.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class QuoteLineItemListElementComponent implements OnChanges, OnInit, OnDestroy { + @Input() lineItem: Partial< + Pick & + Pick< + QuoteItem, + 'id' | 'productSKU' | 'quantity' | 'originSingleBasePrice' | 'singleBasePrice' | 'total' | 'originTotal' + > + >; + + isVariationProduct = ProductHelper.isVariationProduct; + isBundleProduct = ProductHelper.isProductBundle; + + editable$: Observable; + + private sku$ = new ReplaySubject(1); + product$: Observable; + form$: Observable; + private destroy$ = new Subject(); + + constructor(private context: QuoteContextFacade, private shoppingFacade: ShoppingFacade) {} + + ngOnInit() { + this.editable$ = this.context.select('editable'); + this.product$ = this.shoppingFacade.product$(this.sku$, ProductCompletenessLevel.List); + this.form$ = this.product$.pipe( + whenTruthy(), + map( + product => + new FormGroup({ + quantity: new FormControl(this.lineItem?.quantity?.value, [ + Validators.required, + Validators.max(product.maxOrderQuantity), + SpecialValidators.integer, + ]), + }) + ), + shareReplay(1) + ); + this.form$ + .pipe( + whenTruthy(), + switchMap(form => form.get('quantity').valueChanges), + debounceTime(800), + takeUntil(this.destroy$) + ) + .subscribe(quantity => { + this.context.updateItem({ + itemId: this.lineItem?.id, + quantity, + }); + }); + } + + ngOnChanges(): void { + this.sku$.next(this.lineItem?.productSKU); + } + + onDeleteItem() { + this.context.deleteItem(this.lineItem.id); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } +} diff --git a/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.html b/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.html new file mode 100644 index 0000000000..3cd090551d --- /dev/null +++ b/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.html @@ -0,0 +1,28 @@ +
+ +
+
+ {{ 'shopping_cart.product_description.heading' | translate }} +
+
+ {{ 'shopping_cart.qty.heading' | translate }} +
+
{{ 'shopping_cart.price.heading' | translate }}
+
{{ 'shopping_cart.total.heading' | translate }}
+
+
+ + +
+ +
+
+ +
{{ 'quote.items.total.label' | translate }}
+ +
+
{{ total$ | async | ishPrice }}
+
+
+
+
diff --git a/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.spec.ts b/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.spec.ts new file mode 100644 index 0000000000..70b3ede34d --- /dev/null +++ b/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.spec.ts @@ -0,0 +1,69 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { MockComponent, MockPipe } from 'ng-mocks'; +import { of } from 'rxjs'; +import { instance, mock, when } from 'ts-mockito'; + +import { Price } from 'ish-core/models/price/price.model'; +import { PricePipe } from 'ish-core/models/price/price.pipe'; + +import { QuoteContextFacade } from '../../facades/quote-context.facade'; +import { QuoteLineItemListElementComponent } from '../quote-line-item-list-element/quote-line-item-list-element.component'; + +import { QuoteLineItemListComponent } from './quote-line-item-list.component'; + +describe('Quote Line Item List Component', () => { + let component: QuoteLineItemListComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + let quoteContext: QuoteContextFacade; + + beforeEach(async () => { + quoteContext = mock(QuoteContextFacade); + when(quoteContext.select('entity', 'items')).thenReturn( + of([ + { + id: '4712', + quantity: { value: 10 }, + productSKU: '4713', + singleBasePrice: { value: 2, currency: 'USD', type: 'Money' }, + }, + ]) + ); + when(quoteContext.select('entity', 'total')).thenReturn(of({ value: 1 } as Price)); + + await TestBed.configureTestingModule({ + declarations: [MockComponent(QuoteLineItemListElementComponent), MockPipe(PricePipe), QuoteLineItemListComponent], + imports: [TranslateModule.forRoot()], + providers: [{ provide: QuoteContextFacade, useFactory: () => instance(quoteContext) }], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(QuoteLineItemListComponent); + component = fixture.componentInstance; + element = fixture.nativeElement; + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + expect(element).toBeTruthy(); + expect(() => fixture.detectChanges()).not.toThrow(); + }); + + describe('totals', () => { + it('should render totals if set', () => { + fixture.detectChanges(); + + expect(element.textContent).toContain('quote.items.total.label'); + }); + + it('should not render totals if no line items present', () => { + when(quoteContext.select('entity', 'items')).thenReturn(of([])); + + fixture.detectChanges(); + + expect(element.textContent).not.toContain('quote.items.total.label'); + }); + }); +}); diff --git a/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.ts b/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.ts new file mode 100644 index 0000000000..71ad17306a --- /dev/null +++ b/src/app/extensions/quoting/shared/quote-line-item-list/quote-line-item-list.component.ts @@ -0,0 +1,30 @@ +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { Observable, combineLatest } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { Price } from 'ish-core/models/price/price.model'; + +import { QuoteContextFacade } from '../../facades/quote-context.facade'; + +@Component({ + selector: 'ish-quote-line-item-list', + templateUrl: './quote-line-item-list.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class QuoteLineItemListComponent implements OnInit { + total$: Observable; + lineItems$: Observable; + editable$: Observable; + displayTotal$: Observable; + + constructor(private context: QuoteContextFacade) {} + + ngOnInit() { + this.total$ = this.context.select('entity', 'total'); + this.lineItems$ = this.context.select('entity', 'items'); + this.displayTotal$ = combineLatest([this.total$, this.lineItems$]).pipe( + map(([total, items]) => !!total && !!items?.length) + ); + this.editable$ = this.context.select('editable'); + } +} diff --git a/src/app/extensions/quoting/shared/quote-view/quote-view.component.html b/src/app/extensions/quoting/shared/quote-view/quote-view.component.html index f2215a1554..3409f00a78 100644 --- a/src/app/extensions/quoting/shared/quote-view/quote-view.component.html +++ b/src/app/extensions/quoting/shared/quote-view/quote-view.component.html @@ -96,13 +96,7 @@

{{ 'quote.items.table.heading' | translate }}

- +
diff --git a/src/app/extensions/quoting/shared/quote-view/quote-view.component.spec.ts b/src/app/extensions/quoting/shared/quote-view/quote-view.component.spec.ts index b1935db960..088175d97a 100644 --- a/src/app/extensions/quoting/shared/quote-view/quote-view.component.spec.ts +++ b/src/app/extensions/quoting/shared/quote-view/quote-view.component.spec.ts @@ -7,9 +7,9 @@ import { instance, mock } from 'ts-mockito'; import { ServerHtmlDirective } from 'ish-core/directives/server-html.directive'; import { AccountFacade } from 'ish-core/facades/account.facade'; import { DatePipe } from 'ish-core/pipes/date.pipe'; -import { LineItemListComponent } from 'ish-shared/components/line-item/line-item-list/line-item-list.component'; import { QuoteContextFacade } from '../../facades/quote-context.facade'; +import { QuoteLineItemListComponent } from '../quote-line-item-list/quote-line-item-list.component'; import { QuoteStateComponent } from '../quote-state/quote-state.component'; import { QuoteViewComponent } from './quote-view.component'; @@ -23,7 +23,7 @@ describe('Quote View Component', () => { await TestBed.configureTestingModule({ imports: [RouterTestingModule, TranslateModule.forRoot()], declarations: [ - MockComponent(LineItemListComponent), + MockComponent(QuoteLineItemListComponent), MockComponent(QuoteStateComponent), MockDirective(ServerHtmlDirective), MockPipe(DatePipe), diff --git a/src/app/shared/components/line-item/line-item-description/line-item-description.component.ts b/src/app/shared/components/line-item/line-item-description/line-item-description.component.ts index 4c2b58ed67..f109ce60d3 100644 --- a/src/app/shared/components/line-item/line-item-description/line-item-description.component.ts +++ b/src/app/shared/components/line-item/line-item-description/line-item-description.component.ts @@ -23,7 +23,7 @@ import { ProductHelper } from 'ish-core/models/product/product.model'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineItemDescriptionComponent { - @Input() pli: LineItemView; + @Input() pli: Partial; @Input() product: ProductView; @Input() editable = true; @Input() lineItemViewType?: 'simple' | 'availability'; diff --git a/src/app/shared/components/line-item/line-item-edit-dialog/line-item-edit-dialog.component.ts b/src/app/shared/components/line-item/line-item-edit-dialog/line-item-edit-dialog.component.ts index 738c3ba1f8..16b032092a 100644 --- a/src/app/shared/components/line-item/line-item-edit-dialog/line-item-edit-dialog.component.ts +++ b/src/app/shared/components/line-item/line-item-edit-dialog/line-item-edit-dialog.component.ts @@ -48,7 +48,7 @@ import { SpecialValidators } from 'ish-shared/forms/validators/special-validator changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineItemEditDialogComponent implements OnInit, OnDestroy, OnChanges { - @Input() lineItem: LineItemView; + @Input() lineItem: Partial; @Input() modalDialogRef?: ModalDialogComponent; @Input() editable = true; @Output() updateItem = new EventEmitter(); diff --git a/src/app/shared/components/line-item/line-item-edit/line-item-edit.component.ts b/src/app/shared/components/line-item/line-item-edit/line-item-edit.component.ts index c86322db7e..1a636275a2 100644 --- a/src/app/shared/components/line-item/line-item-edit/line-item-edit.component.ts +++ b/src/app/shared/components/line-item/line-item-edit/line-item-edit.component.ts @@ -22,7 +22,7 @@ import { ProductHelper } from 'ish-core/models/product/product.model'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineItemEditComponent { - @Input() lineItem: LineItemView; + @Input() lineItem: Partial; @Input() product: ProductView; @Input() editable = true; @Output() updateItem = new EventEmitter(); diff --git a/src/app/shared/components/line-item/line-item-list/line-item-list.component.html b/src/app/shared/components/line-item/line-item-list/line-item-list.component.html index 3e53d7f0ee..232ba9f77a 100644 --- a/src/app/shared/components/line-item/line-item-list/line-item-list.component.html +++ b/src/app/shared/components/line-item/line-item-list/line-item-list.component.html @@ -113,27 +113,11 @@
- -

- {{ 'quote.items.original_price.label' | translate }} {{ pli.originSingleBasePrice | ishPrice }} -

- -

- {{ - 'quote.items.suggested_price.label' | translate - }} - {{ pli.singleBasePrice | ishPrice }} -

+

{{ pli.singleBasePrice | ishPrice }}

-

{{ pli.totals.originTotal | ishPrice }}

- - - {{ - 'quote.items.suggested_price.label' | translate - }}
{{ pli.totals.total | ishPrice }}
diff --git a/src/app/shared/components/line-item/line-item-list/line-item-list.component.spec.ts b/src/app/shared/components/line-item/line-item-list/line-item-list.component.spec.ts index 30f8471ffa..f86722bc3a 100644 --- a/src/app/shared/components/line-item/line-item-list/line-item-list.component.spec.ts +++ b/src/app/shared/components/line-item/line-item-list/line-item-list.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { TranslateModule } from '@ngx-translate/core'; -import { MockComponent, MockComponents, MockPipe } from 'ng-mocks'; +import { MockComponent, MockPipe } from 'ng-mocks'; import { of } from 'rxjs'; import { anything, instance, mock, when } from 'ts-mockito'; @@ -38,10 +38,10 @@ describe('Line Item List Component', () => { MockComponent(BasketPromotionComponent), MockComponent(FaIconComponent), MockComponent(InputComponent), + MockComponent(LazyProductAddToOrderTemplateComponent), + MockComponent(LazyProductAddToWishlistComponent), MockComponent(LineItemDescriptionComponent), MockComponent(ProductImageComponent), - MockComponents(LazyProductAddToOrderTemplateComponent), - MockComponents(LazyProductAddToWishlistComponent), MockPipe(PricePipe), MockPipe(ProductRoutePipe), ], diff --git a/src/app/shared/components/product/product-rating/product-rating.component.spec.ts b/src/app/shared/components/product/product-rating/product-rating.component.spec.ts index e8eb6fd0e1..a759aff1c4 100644 --- a/src/app/shared/components/product/product-rating/product-rating.component.spec.ts +++ b/src/app/shared/components/product/product-rating/product-rating.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MockComponents } from 'ng-mocks'; +import { MockComponent } from 'ng-mocks'; import { Product } from 'ish-core/models/product/product.model'; import { ProductRatingStarComponent } from 'ish-shared/components/product/product-rating-star/product-rating-star.component'; @@ -13,7 +13,7 @@ describe('Product Rating Component', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [MockComponents(ProductRatingStarComponent), ProductRatingComponent], + declarations: [MockComponent(ProductRatingStarComponent), ProductRatingComponent], }).compileComponents(); }); diff --git a/tslint.json b/tslint.json index 834bca02c7..ef9d60188d 100644 --- a/tslint.json +++ b/tslint.json @@ -433,6 +433,12 @@ "filePattern": "^.*\\.spec\\.ts*$", "message": "Use MockComponent for individual components in tests instead." }, + { + "import": "^MockComponents$", + "from": "ng-mocks", + "filePattern": "^.*\\.spec\\.ts*$", + "message": "Use MockComponent for individual components in tests instead." + }, { "import": "^PipesModule$", "from": "ish-core/pipes.module",