From c2c90547b6fbc8d1766e9b6be9e1fa86b0da883b Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Tue, 3 Mar 2020 10:45:47 +0100 Subject: [PATCH 001/135] Merged bfa72d037e8563c213ff791a48145edc36626e3e into feature/HIMA-0-cherypick-config-changes-on-master --- .../src/assets/config/config.production.json | 22 +++++++++---------- .../src/assets/config/config.staging.json | 22 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/apps/sales/src/assets/config/config.production.json b/apps/sales/src/assets/config/config.production.json index 34083b04a..0f0bb8c50 100644 --- a/apps/sales/src/assets/config/config.production.json +++ b/apps/sales/src/assets/config/config.production.json @@ -2,33 +2,33 @@ "includeGoogleAnalytics": true, "swagger": { "api": { - "rootUrl": "https://isa.paragon-data.net/catsearch/v5" + "rootUrl": "https://isa.paragon-systems.de/catsearch/v5" }, "av": { - "rootUrl": "https://isa.paragon-data.net/ava/v4" + "rootUrl": "https://isa.paragon-systems.de/ava/v4" }, "checkout": { - "rootUrl": "https://isa.paragon-data.net/checkout/v3" + "rootUrl": "https://isa.paragon-systems.de/checkout/v3" }, "crm": { - "rootUrl": "https://isa.paragon-data.net/crm/v2" + "rootUrl": "https://isa.paragon-systems.de/crm/v2" }, "isa": { - "rootUrl": "https://isa.paragon-data.net/isa/v1" + "rootUrl": "https://isa.paragon-systems.de/isa/v1" }, "oms": { - "rootUrl": "https://isa.paragon-data.net/oms/v2" + "rootUrl": "https://isa.paragon-systems.de/oms/v2" }, "print": { - "rootUrl": "https://isa.paragon-data.net/print/v1" + "rootUrl": "https://isa.paragon-systems.de/print/v1" } }, "remissionModuleOptions": { "useMock": false, "endpoints": { - "catsearch": "https://isa.paragon-data.net/catsearch/v5/", - "remi": "https://isa.paragon-data.net/inv/v1/", - "print": "https://isa.paragon-data.net/print/v1/" + "catsearch": "https://isa.paragon-systems.de/catsearch/v5/", + "remi": "https://isa.paragon-systems.de/inv/v1/", + "print": "https://isa.paragon-systems.de/print/v1/" } } -} \ No newline at end of file +} diff --git a/apps/sales/src/assets/config/config.staging.json b/apps/sales/src/assets/config/config.staging.json index 05ff0bae7..d1cc84c8f 100644 --- a/apps/sales/src/assets/config/config.staging.json +++ b/apps/sales/src/assets/config/config.staging.json @@ -2,33 +2,33 @@ "includeGoogleAnalytics": true, "swagger": { "api": { - "rootUrl": "https://isa-staging.paragon-data.net/catsearch/v5" + "rootUrl": "https://isa-staging.paragon-systems.de/catsearch/v5" }, "av": { - "rootUrl": "https://isa-staging.paragon-data.net/ava/v4" + "rootUrl": "https://isa-staging.paragon-systems.de/ava/v4" }, "checkout": { - "rootUrl": "https://isa-staging.paragon-data.net/checkout/v3" + "rootUrl": "https://isa-staging.paragon-systems.de/checkout/v3" }, "crm": { - "rootUrl": "https://isa-staging.paragon-data.net/crm/v2" + "rootUrl": "https://isa-staging.paragon-systems.de/crm/v2" }, "isa": { - "rootUrl": "https://isa-staging.paragon-data.net/isa/v1" + "rootUrl": "https://isa-staging.paragon-systems.de/isa/v1" }, "oms": { - "rootUrl": "https://isa-staging.paragon-data.net/oms/v2" + "rootUrl": "https://isa-staging.paragon-systems.de/oms/v2" }, "print": { - "rootUrl": "https://isa-staging.paragon-data.net/print/v1" + "rootUrl": "https://isa-staging.paragon-systems.de/print/v1" } }, "remissionModuleOptions": { "useMock": false, "endpoints": { - "catsearch": "https://isa-staging.paragon-data.net/catsearch/v5/", - "remi": "https://isa-staging.paragon-data.net/inv/v1/", - "print": "https://isa-staging.paragon-data.net/print/v1/" + "catsearch": "https://isa-staging.paragon-systems.de/catsearch/v5/", + "remi": "https://isa-staging.paragon-systems.de/inv/v1/", + "print": "https://isa-staging.paragon-systems.de/print/v1/" } } -} \ No newline at end of file +} From b08fab42666f813a24861c2c37c3e6e7eac44f31 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 9 Jul 2020 18:55:42 +0200 Subject: [PATCH 002/135] #823 Reset Filters in Shelf Filter Overlay --- .../modules/filter/models/select-option.ts | 1 + .../defs/filter-reset-strategy.model.ts | 1 + .../components/defs/index.ts | 4 + .../selected-filter-options.component.html | 6 +- .../selected-filter-options.component.spec.ts | 150 ++++++++++++++++++ .../selected-filter-options.component.ts | 50 +++++- .../pipe/filter-reset-wording.pipe.spec.ts | 19 +++ .../pipe/filter-reset-wording.pipe.ts | 18 +++ .../selected-filter-options/pipe/index.ts | 2 +- .../selected-filter-options.module.ts | 20 ++- .../defs/shelf-primary-filter-options.ts | 1 + .../shelf-filter/shelf-filter.component.html | 3 + .../shelf-filter/shelf-filter.component.ts | 17 +- .../services/shelf-filter.service.spec.ts | 44 ++++- .../shelf/services/shelf-filter.service.ts | 35 +++- .../shelf/shared/mockdata/filters.mock.ts | 18 +++ .../shared/mockdata/primary-filters.mock.ts | 2 + .../input-dto-to-primary-filters.mapper.ts | 1 + .../input-dto-to-selected-filters.mapper.ts | 1 + .../customer/shelf/search/search.actions.ts | 10 ++ .../shelf/search/search.effects.spec.ts | 4 +- .../shelf/search/search.facade.spec.ts | 87 +++++++++- .../customer/shelf/search/search.facade.ts | 61 ++++++- .../shelf/search/search.reducer.spec.ts | 61 ++++++- .../customer/shelf/search/search.reducer.ts | 45 ++++++ 25 files changed, 639 insertions(+), 22 deletions(-) create mode 100644 apps/sales/src/app/modules/filter/selected-filter-options/components/defs/filter-reset-strategy.model.ts create mode 100644 apps/sales/src/app/modules/filter/selected-filter-options/components/defs/index.ts create mode 100644 apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.spec.ts create mode 100644 apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.spec.ts create mode 100644 apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.ts diff --git a/apps/sales/src/app/modules/filter/models/select-option.ts b/apps/sales/src/app/modules/filter/models/select-option.ts index bec8bf9e7..9674224af 100644 --- a/apps/sales/src/app/modules/filter/models/select-option.ts +++ b/apps/sales/src/app/modules/filter/models/select-option.ts @@ -5,4 +5,5 @@ export interface SelectFilterOption extends FilterOptionBase { expanded?: boolean; options?: SelectFilterOption[]; id?: string; + initial_selected_state?: boolean; } diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/components/defs/filter-reset-strategy.model.ts b/apps/sales/src/app/modules/filter/selected-filter-options/components/defs/filter-reset-strategy.model.ts new file mode 100644 index 000000000..5ebb7c699 --- /dev/null +++ b/apps/sales/src/app/modules/filter/selected-filter-options/components/defs/filter-reset-strategy.model.ts @@ -0,0 +1 @@ +export type FilterResetStrategy = 'all' | 'default'; diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/components/defs/index.ts b/apps/sales/src/app/modules/filter/selected-filter-options/components/defs/index.ts new file mode 100644 index 000000000..bf03d94c1 --- /dev/null +++ b/apps/sales/src/app/modules/filter/selected-filter-options/components/defs/index.ts @@ -0,0 +1,4 @@ +// start:ng42.barrel +export * from './filter-reset-strategy.model'; +// end:ng42.barrel + diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.html b/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.html index 9df706a53..8b7489432 100644 --- a/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.html +++ b/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.html @@ -1,10 +1,10 @@
-
+
diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.spec.ts b/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.spec.ts new file mode 100644 index 000000000..6d40c9b36 --- /dev/null +++ b/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.spec.ts @@ -0,0 +1,150 @@ +import { TestBed, ComponentFixture } from '@angular/core/testing'; +import { SelectedFilterOptionsComponent } from './selected-filter-options.component'; +import { ChangeDetectorRef, Renderer2 } from '@angular/core'; +import { IconModule } from '@libs/ui'; +import { + FilterResetWordingPipe, + SelectedFiltersPipe, + CheckAllChildOptionsSelectedPipe, +} from '../pipe'; +import { By } from '@angular/platform-browser'; +import { PrimaryFilterOption } from '../../../shelf/defs'; +import { + mockFilters, + primaryFiltersMock, +} from '../../../shelf/shared/mockdata'; +import { SelectFilter } from '../../models'; + +fdescribe('SelectedFilterOptionsComponent', () => { + let fixture: ComponentFixture; + let component: SelectedFilterOptionsComponent; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [IconModule, IconModule], + providers: [ChangeDetectorRef, Renderer2, SelectedFilterOptionsComponent], + declarations: [ + SelectedFilterOptionsComponent, + SelectedFiltersPipe, + FilterResetWordingPipe, + CheckAllChildOptionsSelectedPipe, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SelectedFilterOptionsComponent); + component = fixture.componentInstance; + component.value = []; + fixture.detectChanges(); + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + }); + + describe('#ResetFilters', () => { + let button: HTMLButtonElement; + + beforeEach(() => { + spyOn(component, 'resetFilters').and.callThrough(); + component.resetStrategy = 'all'; + component.showResetButton = true; + + button = fixture.debugElement.query( + By.css('.isa-btn.isa-btn-primary-link.remove-all') + ).nativeElement; + + fixture.detectChanges(); + }); + + it('should be shown by default', () => { + expect(button).toBeTruthy(); + }); + + it('should not be shwon if showResetButton is false', async () => { + component.showResetButton = false; + fixture.detectChanges(); + + await fixture.whenStable(); + + const debugButtonEl = fixture.debugElement.query( + By.css('.isa-btn.isa-btn-primary-link.remove-all') + ); + button = debugButtonEl && debugButtonEl.nativeElement; + + expect(button).toBeFalsy(); + }); + + it('should deselect all filters when resetStrategy is all', () => { + spyOn(component, 'deselectAllFilters').and.callThrough(); + button.click(); + fixture.detectChanges(); + + expect(component.resetFilters).toHaveBeenCalled(); + expect(component.deselectAllFilters).toHaveBeenCalled(); + }); + + it('should revert to the default selection of filters when resetStrategy is default', () => { + spyOn(component, 'resetToDefault').and.callThrough(); + component.resetStrategy = 'default'; + fixture.detectChanges(); + + button.click(); + fixture.detectChanges(); + + expect(component.resetFilters).toHaveBeenCalled(); + expect(component.resetToDefault).toHaveBeenCalled(); + }); + }); + + describe('resetToDefault', () => { + let primaryFilters: PrimaryFilterOption[]; + let selectFilters: SelectFilter[]; + + beforeEach(() => { + primaryFilters = primaryFiltersMock; + selectFilters = mockFilters; + }); + + it('should reset the filters to its initial state', () => { + selectFilters[0].options[0].selected = true; + selectFilters[0].options[0].initial_selected_state = false; + + spyOn(component, 'resetToDefault').and.callThrough(); + + const result = component.resetToDefault(selectFilters); + + expect(result[0].options[0].selected).toBe(false); + expect(result[0].options[0].initial_selected_state).toBe(false); + expect(result.length).toEqual(selectFilters.length); + }); + }); + + describe('deselectAllFilters', () => { + let primaryFilters: PrimaryFilterOption[]; + let selectFilters: SelectFilter[]; + + beforeEach(() => { + primaryFilters = primaryFiltersMock; + selectFilters = mockFilters; + }); + + it('should deselect all filters', () => { + spyOn(component, 'deselectAllFilters').and.callThrough(); + + const result = component.deselectAllFilters(selectFilters); + + expect( + result.every((filter) => { + if (filter.options) { + return filter.options.every((o) => !o.selected); + } + + return true; + }) + ); + expect(result.length).toEqual(selectFilters.length); + }); + }); +}); diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.ts b/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.ts index 26e1d8593..116f5ccaa 100644 --- a/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.ts +++ b/apps/sales/src/app/modules/filter/selected-filter-options/components/selected-filter-options.component.ts @@ -13,6 +13,7 @@ import { } from '@angular/core'; import { Filter, SelectFilterOption } from '../../models'; import { cloneFilter } from '../../utils'; +import { FilterResetStrategy } from './defs'; @Component({ selector: 'app-selected-filter-options', @@ -21,11 +22,13 @@ import { cloneFilter } from '../../utils'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class SelectedFilterOptionsComponent implements AfterViewInit { - @Input() - value: Filter[]; + @Input() value: Filter[]; @Input() module: 'Customer' | 'Branch' = 'Branch'; + @Input() resetStrategy: FilterResetStrategy = 'all'; + @Input() showResetButton = true; @Output() filterChanged = new EventEmitter(); + @Output() reset = new EventEmitter(); @ViewChildren('filteredItem') items: QueryList; @@ -61,8 +64,18 @@ export class SelectedFilterOptionsComponent implements AfterViewInit { this.cdr.detectChanges(); } - clearAllFilters() { - this.filterChanged.emit(this.deselectAllFilters(this.value)); + resetFilters() { + switch (this.resetStrategy) { + case 'default': + this.filterChanged.emit(this.resetToDefault(this.value)); + break; + + case 'all': + this.filterChanged.emit(this.deselectAllFilters(this.value)); + break; + } + + this.reset.emit(); } clearFilter(filter: SelectFilterOption) { @@ -106,7 +119,7 @@ export class SelectedFilterOptionsComponent implements AfterViewInit { this.filterChanged.emit(clonedFilter); } - private deselectAllFilters(filters: Filter[]): Filter[] { + deselectAllFilters(filters: Filter[]): Filter[] { return filters.reduce((acc, curr) => { if (Array.isArray(curr.options)) { curr.options.forEach((option) => this.deselect(option)); @@ -115,6 +128,21 @@ export class SelectedFilterOptionsComponent implements AfterViewInit { }, []); } + resetToDefault(filters: Filter[]): Filter[] { + const updatedFilters = filters.map((filter) => { + let updatedOptions = filter.options || []; + if (filter.options) { + updatedOptions = filter.options.map((f) => ({ + ...this.resetToDefaultValue(f), + })); + } + + return { ...filter, options: updatedOptions }; + }); + + return updatedFilters; + } + private deselectAllMatches(filter: SelectFilterOption, match?: string) { if (filter.name === match) { filter.selected = false; @@ -142,6 +170,18 @@ export class SelectedFilterOptionsComponent implements AfterViewInit { return filter; } + private resetToDefaultValue(filter: SelectFilterOption): SelectFilterOption { + return { + ...filter, + selected: filter.initial_selected_state, + options: [ + ...(filter.options + ? filter.options.map((option) => this.resetToDefaultValue(option)) + : []), + ], + }; + } + private hasNestedOptions(filter: SelectFilterOption): boolean { return filter && Array.isArray(filter.options) && !!filter.options.length; } diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.spec.ts b/apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.spec.ts new file mode 100644 index 000000000..a3944c5ee --- /dev/null +++ b/apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.spec.ts @@ -0,0 +1,19 @@ +import { FilterResetWordingPipe } from './filter-reset-wording.pipe'; + +describe('#FilterResetWordingPipe', () => { + let pipe: FilterResetWordingPipe; + + beforeEach(() => { + pipe = new FilterResetWordingPipe(); + }); + + it('should show Alle Filter Entfernen for the default strategy', () => { + const result = pipe.transform('all'); + expect(result).toEqual('Alle Filter Entfernen'); + }); + + it('should show Filter zurücksetzen for the default strategy', () => { + const result = pipe.transform('default'); + expect(result).toEqual('Filter zurücksetzen'); + }); +}); diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.ts b/apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.ts new file mode 100644 index 000000000..4b7bc4354 --- /dev/null +++ b/apps/sales/src/app/modules/filter/selected-filter-options/pipe/filter-reset-wording.pipe.ts @@ -0,0 +1,18 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { FilterResetStrategy } from '../components/defs'; + +@Pipe({ + name: 'filterResetWording', +}) +export class FilterResetWordingPipe implements PipeTransform { + RESET_TO_DEFAULT_WORDING = 'Filter zurücksetzen'; + RESET_All_WORDING = 'Alle Filter Entfernen'; + + transform(strategy: FilterResetStrategy): string { + if (strategy === 'default') { + return this.RESET_TO_DEFAULT_WORDING; + } + + return this.RESET_All_WORDING; + } +} diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/pipe/index.ts b/apps/sales/src/app/modules/filter/selected-filter-options/pipe/index.ts index 18cc84159..0db2c646e 100644 --- a/apps/sales/src/app/modules/filter/selected-filter-options/pipe/index.ts +++ b/apps/sales/src/app/modules/filter/selected-filter-options/pipe/index.ts @@ -1,5 +1,5 @@ // start:ng42.barrel export * from './check-all-selected.pipe'; export * from './selected-filters.pipe'; +export * from './filter-reset-wording.pipe'; // end:ng42.barrel - diff --git a/apps/sales/src/app/modules/filter/selected-filter-options/selected-filter-options.module.ts b/apps/sales/src/app/modules/filter/selected-filter-options/selected-filter-options.module.ts index db7ad1cf2..a432f34cf 100644 --- a/apps/sales/src/app/modules/filter/selected-filter-options/selected-filter-options.module.ts +++ b/apps/sales/src/app/modules/filter/selected-filter-options/selected-filter-options.module.ts @@ -2,15 +2,25 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IconModule } from '@libs/ui'; import { SelectedFilterOptionsComponent } from './components'; -import { SelectedFiltersPipe, CheckAllChildOptionsSelectedPipe} from './pipe'; +import { + SelectedFiltersPipe, + CheckAllChildOptionsSelectedPipe, + FilterResetWordingPipe, +} from './pipe'; @NgModule({ imports: [CommonModule, IconModule], - exports: [SelectedFilterOptionsComponent, CheckAllChildOptionsSelectedPipe], - declarations: - [SelectedFilterOptionsComponent, + exports: [ + SelectedFilterOptionsComponent, + CheckAllChildOptionsSelectedPipe, + FilterResetWordingPipe, + ], + declarations: [ + SelectedFilterOptionsComponent, SelectedFiltersPipe, - CheckAllChildOptionsSelectedPipe], + FilterResetWordingPipe, + CheckAllChildOptionsSelectedPipe, + ], providers: [], }) export class SelectedFilterOptionsModule {} diff --git a/apps/sales/src/app/modules/shelf/defs/shelf-primary-filter-options.ts b/apps/sales/src/app/modules/shelf/defs/shelf-primary-filter-options.ts index c9d669d9a..268cb4e81 100644 --- a/apps/sales/src/app/modules/shelf/defs/shelf-primary-filter-options.ts +++ b/apps/sales/src/app/modules/shelf/defs/shelf-primary-filter-options.ts @@ -3,4 +3,5 @@ export interface PrimaryFilterOption { id: string; key: string; selected: boolean; + initial_selected_state?: boolean; } diff --git a/apps/sales/src/app/modules/shelf/overlays/shelf-filter/shelf-filter.component.html b/apps/sales/src/app/modules/shelf/overlays/shelf-filter/shelf-filter.component.html index a9214c88f..2dd979930 100644 --- a/apps/sales/src/app/modules/shelf/overlays/shelf-filter/shelf-filter.component.html +++ b/apps/sales/src/app/modules/shelf/overlays/shelf-filter/shelf-filter.component.html @@ -19,6 +19,9 @@ ; pendingFilters$ = new BehaviorSubject(null); hasSelectedFilter$: Observable; + filtersChangedFromDefault$: Observable; constructor( private overlayRef: IsaOverlayRef, @@ -55,6 +58,7 @@ export class ShelfFilterComponent implements OnInit, OnDestroy { this.getSelectedFilter(); this.getPendingFilters(); this.getHasSelectedFilters(); + this.getFiltersChangedFromDefault(); } ngOnDestroy() {} @@ -75,6 +79,10 @@ export class ShelfFilterComponent implements OnInit, OnDestroy { this.hasSelectedFilter$ = this.filterService.hasSelectedFilters$; } + getFiltersChangedFromDefault() { + this.filtersChangedFromDefault$ = this.filterService.filtersChangedFromDefault$; + } + onFiltersChange(updatedFilters: SelectFilter[]) { this.pendingFilters$.next(updatedFilters.map(cloneFilter)); this.setSearchFocus(); @@ -144,6 +152,13 @@ export class ShelfFilterComponent implements OnInit, OnDestroy { } } + onResetFilters() { + if (this.resetStrategy === 'default') { + this.filterService.resetPrimaryFilters(); + this.filterService.resetSelectedFilters(); + } + } + private initiateSearchAndCloseOverlay() { if (this.searchInput) { const searchbarValue = diff --git a/apps/sales/src/app/modules/shelf/services/shelf-filter.service.spec.ts b/apps/sales/src/app/modules/shelf/services/shelf-filter.service.spec.ts index a683dbff0..c6838a11b 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-filter.service.spec.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-filter.service.spec.ts @@ -1 +1,43 @@ -describe('#ShelfFilterService', () => {}); +import { TestBed } from '@angular/core/testing'; +import { SearchStateFacade } from '@shelf-store'; +import { ShelfFilterService } from './shelf-filter.service'; +import { mockFilters } from '../shared/mockdata'; + +fdescribe('#ShelfFilterService', () => { + let service: ShelfFilterService; + let facade: jasmine.SpyObj; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + { + provide: SearchStateFacade, + useValue: jasmine.createSpyObj('searchStateFacade', [ + 'selectFilters$', + 'primaryFilterChangedFromDefault$', + ]), + }, + ], + }); + + spyOn( + ShelfFilterService.prototype, + 'initPendingFilters' + ).and.callFake(() => {}); + + facade = TestBed.get(SearchStateFacade); + service = TestBed.get(ShelfFilterService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + describe('#FiltersChangedFromDefault', () => { + it('should return true if the primary Filters changed', async () => { + const mockSelectFilters = mockFilters; + }); + it('should return true if the pending Filters changed', () => {}); + it('should return false if neither pending nor primary filters changed', () => {}); + }); +}); diff --git a/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts index b7d03a08e..fb392712e 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts @@ -1,7 +1,14 @@ import { Injectable, OnDestroy } from '@angular/core'; import { Observable, BehaviorSubject, Subject, combineLatest } from 'rxjs'; import { SelectFilter, Filter, SelectFilterOption } from '../../filter'; -import { tap, startWith, map, filter } from 'rxjs/operators'; +import { + tap, + startWith, + map, + filter, + withLatestFrom, + first, +} from 'rxjs/operators'; import { SearchStateFacade } from '../../../store/customer'; import { flatten } from '../../../shared/utils'; import { isNullOrUndefined } from 'util'; @@ -32,6 +39,24 @@ export class ShelfFilterService implements OnDestroy { return this.pendingFilters$.pipe(map(this.computeHasSelectedFilters)); } + get filtersChangedFromDefault$(): Observable { + return this.pendingFilters$.pipe( + filter((pendingFilters) => !isNullOrUndefined(pendingFilters)), + withLatestFrom(this.searchStateFacade.primaryFilterChangedFromDefault$), + map(([pendingFilters, primaryFiltersChanged]) => { + return pendingFilters.some((f) => + f.options + ? f.options.some((o) => + isNullOrUndefined(o.initial_selected_state) + ? o.selected !== false + : o.selected !== o.initial_selected_state + ) + : primaryFiltersChanged + ); + }) + ); + } + ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); @@ -54,6 +79,14 @@ export class ShelfFilterService implements OnDestroy { this.searchStateFacade.setSelectedFilters(updatedFilters); } + resetPrimaryFilters(): void { + this.searchStateFacade.resetPrimaryFilters(); + } + + resetSelectedFilters() { + this.searchStateFacade.resetSelectedFilters(); + } + public overlayClosed() { this.resetFilters$.next(); this.overlayClosed$.next(); diff --git a/apps/sales/src/app/modules/shelf/shared/mockdata/filters.mock.ts b/apps/sales/src/app/modules/shelf/shared/mockdata/filters.mock.ts index 8c97aee92..ca44587b9 100644 --- a/apps/sales/src/app/modules/shelf/shared/mockdata/filters.mock.ts +++ b/apps/sales/src/app/modules/shelf/shared/mockdata/filters.mock.ts @@ -11,41 +11,49 @@ export const mockFilters: SelectFilter[] = [ id: 'abgeholt', name: 'abgeholt', selected: false, + initial_selected_state: false, }, { id: 'storniert Kunde', name: 'storniert Kunde', selected: false, + initial_selected_state: false, }, { id: 'storniert Lieferant', name: 'storniert Lieferant', selected: false, + initial_selected_state: false, }, { id: 'storniert', name: 'storniert', selected: false, + initial_selected_state: false, }, { id: 'ans Lager (nicht abgeholt)', name: 'ans Lager (nicht abgeholt)', selected: false, + initial_selected_state: false, }, { id: 'zugestellt', name: 'abgeholt', selected: false, + initial_selected_state: false, }, { id: 'nicht lieferbar', name: 'nicht lieferbar', selected: false, + initial_selected_state: false, }, { id: 'derzeit nicht lieferbar', name: 'derzeit nicht lieferbar', selected: false, + initial_selected_state: false, }, ], }, @@ -59,31 +67,37 @@ export const mockFilters: SelectFilter[] = [ id: 'Online', name: 'Online', selected: false, + initial_selected_state: false, }, { id: 'Hugendubel.de', name: 'Hugendubel.de', selected: false, + initial_selected_state: false, }, { id: 'Filiale', name: 'Filiale', selected: false, + initial_selected_state: false, }, { id: 'HSC', name: 'HSC', selected: false, + initial_selected_state: false, }, { id: 'Amazon', name: 'Amazon', selected: false, + initial_selected_state: false, }, { id: 'Etsy', name: 'Etsy', selected: false, + initial_selected_state: false, }, ], }, @@ -97,21 +111,25 @@ export const mockFilters: SelectFilter[] = [ id: 'Kundenkarte', name: 'Kundenkarte', selected: false, + initial_selected_state: false, }, { id: 'Onlinekonto', name: 'Onlinekonto', selected: false, + initial_selected_state: false, }, { id: 'B2B', name: 'B2B', selected: false, + initial_selected_state: false, }, { id: 'Gastkunde', name: 'Gastkunde', selected: false, + initial_selected_state: false, }, ], }, diff --git a/apps/sales/src/app/modules/shelf/shared/mockdata/primary-filters.mock.ts b/apps/sales/src/app/modules/shelf/shared/mockdata/primary-filters.mock.ts index 0604b71f8..989209cd7 100644 --- a/apps/sales/src/app/modules/shelf/shared/mockdata/primary-filters.mock.ts +++ b/apps/sales/src/app/modules/shelf/shared/mockdata/primary-filters.mock.ts @@ -6,11 +6,13 @@ export const primaryFiltersMock: PrimaryFilterOption[] = [ id: 'filter1', key: 'One', selected: false, + initial_selected_state: false, }, { name: 'Primary Filter Two', id: 'filter2', key: 'Two', selected: false, + initial_selected_state: false, }, ]; diff --git a/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-primary-filters.mapper.ts b/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-primary-filters.mapper.ts index c22edce8e..88406ff77 100644 --- a/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-primary-filters.mapper.ts +++ b/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-primary-filters.mapper.ts @@ -9,5 +9,6 @@ export function inputDtoToPrimaryFilterOption( key: inputDTO.key, name: inputDTO.label, selected: false, + initial_selected_state: false, }; } diff --git a/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-selected-filters.mapper.ts b/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-selected-filters.mapper.ts index 69061acdf..45bbc2534 100644 --- a/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-selected-filters.mapper.ts +++ b/apps/sales/src/app/store/customer/shelf/search/mappers/input-dto-to-selected-filters.mapper.ts @@ -24,6 +24,7 @@ export function optionDtoToSelectFilterOption( name: optionDto.label, id: optionDto.key || optionDto.value, selected: optionDto.selected || false, + initial_selected_state: optionDto.selected || false, expanded: false, options: optionDto.values && optionDto.values.map(optionDtoToSelectFilterOption), diff --git a/apps/sales/src/app/store/customer/shelf/search/search.actions.ts b/apps/sales/src/app/store/customer/shelf/search/search.actions.ts index 0ddf49a70..3aade107a 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.actions.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.actions.ts @@ -38,11 +38,21 @@ export const setSelectFilters = createAction( props<{ id: number; filters: SelectFilter[] }>() ); +export const resetSelectFilters = createAction( + `${prefix} Reset Selected Filters`, + props<{ id: number }>() +); + export const setPrimaryFilters = createAction( `${prefix} Set Primary Filters`, props<{ id: number; filters: PrimaryFilterOption[] }>() ); +export const resetPrimaryFilters = createAction( + `${prefix} Reset Primary Filters`, + props<{ id: number }>() +); + export const setInput = createAction( `${prefix} Search Input`, props<{ id: number; input: string }>() diff --git a/apps/sales/src/app/store/customer/shelf/search/search.effects.spec.ts b/apps/sales/src/app/store/customer/shelf/search/search.effects.spec.ts index 26f976260..12b526292 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.effects.spec.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.effects.spec.ts @@ -2,7 +2,7 @@ import { TestBed } from '@angular/core/testing'; import { SearchEffects } from './search.effects'; import { provideMockStore, MockStore } from '@ngrx/store/testing'; import { provideMockActions } from '@ngrx/effects/testing'; -import { Observable, Subject } from 'rxjs'; +import { Observable } from 'rxjs'; import { StrictHttpResponse, ResponseArgsOfIEnumerableOfInputDTO, @@ -12,7 +12,7 @@ import { import { hot, cold } from 'jasmine-marbles'; import * as actions from './search.actions'; import * as processActions from 'apps/sales/src/app/core/store/actions/process.actions'; -import { Store as NgxsStore, ofActionDispatched } from '@ngxs/store'; +import { Store as NgxsStore } from '@ngxs/store'; import { Store } from '@ngrx/store'; import { Actions, NgxsModule } from '@ngxs/store'; import { BranchService } from '@sales/core-services'; diff --git a/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts b/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts index 72383ed14..4296b9377 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts @@ -2,12 +2,16 @@ import { SearchStateFacade } from './search.facade'; import { TestBed } from '@angular/core/testing'; import { Store, StoreModule } from '@ngrx/store'; import { Store as NgxsStore } from '@ngxs/store'; -import { primaryFiltersMock } from 'apps/sales/src/app/modules/shelf/shared/mockdata'; +import { + primaryFiltersMock, + mockFilters, +} from 'apps/sales/src/app/modules/shelf/shared/mockdata'; import { PrimaryFilterOption } from 'apps/sales/src/app/modules/shelf/defs'; import { of, Observable } from 'rxjs'; import * as actions from './search.actions'; import { SelectFilter } from 'apps/sales/src/app/modules/filter'; import { first } from 'rxjs/operators'; +import { hot, cold } from 'jasmine-marbles'; fdescribe('SearchFacade', () => { let facade: SearchStateFacade; @@ -117,4 +121,85 @@ fdescribe('SearchFacade', () => { }); }); }); + + describe('#filtersChangedFromDefault$', () => { + let selectFilters: SelectFilter[]; + let primaryFilters: PrimaryFilterOption[]; + + beforeEach(() => { + selectFilters = mockFilters; + primaryFilters = primaryFiltersMock; + }); + + it('should return true if the select filters are changed', async () => { + spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue( + of(primaryFilters) + ); + const updatedSelectFilters = [ + ...selectFilters.map((filter) => + filter.options + ? { + ...filter, + options: filter.options.map((o, i) => + !i ? { ...o, selected: !o.initial_selected_state } : o + ), + } + : filter + ), + ]; + spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue( + of(updatedSelectFilters) + ); + const result = await facade.filtersChangedFromDefault$ + .pipe(first()) + .toPromise(); + + expect(result).toBe(true); + }); + it('should return false if the select filters are unchanged', async () => { + spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue( + of(primaryFilters) + ); + spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue( + of(selectFilters) + ); + const result = await facade.filtersChangedFromDefault$ + .pipe(first()) + .toPromise(); + + expect(result).toBe(false); + }); + + xit('should return false if the primary filters are unchanged', () => { + const selectFilters$ = hot('--a', { a: selectFilters }); + const primaryFilters$ = hot('--a', { a: primaryFilters }); + const expected = cold('--a', { b: false }); + + spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue( + selectFilters$ + ); + spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue( + primaryFilters$ + ); + + expect(facade.filtersChangedFromDefault$).toBeObservable(expected); + }); + + xit('should return true if the primary filters are changed', async () => { + const selectFilters$ = hot('--a', { a: selectFilters }); + const primaryFilters$ = hot('--a', { + a: primaryFilters.map((f, i) => (!i ? { ...f, selected: true } : f)), + }); + const expected = cold('--a', { b: true }); + + spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue( + selectFilters$ + ); + spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue( + primaryFilters$ + ); + + expect(facade.filtersChangedFromDefault$).toBeObservable(expected); + }); + }); }); diff --git a/apps/sales/src/app/store/customer/shelf/search/search.facade.ts b/apps/sales/src/app/store/customer/shelf/search/search.facade.ts index 365ce2d26..bf0dd6b38 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.facade.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.facade.ts @@ -3,7 +3,7 @@ import { Store } from '@ngrx/store'; import { Store as NgxsStore } from '@ngxs/store'; import * as actions from './search.actions'; import * as selectors from './search.selectors'; -import { switchMap, filter, map, first, withLatestFrom } from 'rxjs/operators'; +import { switchMap, filter, map, first } from 'rxjs/operators'; import { SharedSelectors } from 'apps/sales/src/app/core/store/selectors/shared.selectors'; import { combineLatest } from 'rxjs'; import { @@ -90,6 +90,47 @@ export class SearchStateFacade { ); } + get selectedFilterChangedFromDefault$() { + return this.selectFilters$.pipe( + map((selectFilters) => { + return selectFilters.some((f) => { + if (f.options) { + return f.options.some((o) => { + return isNullOrUndefined(o.initial_selected_state) + ? o.selected !== true + : o.selected !== o.initial_selected_state; + }); + } + + return false; + }); + }) + ); + } + + get primaryFilterChangedFromDefault$() { + return this.primaryFilters$.pipe( + map((primaryFilters) => { + return primaryFilters.some((pf) => + isNullOrUndefined(pf.initial_selected_state) + ? pf.selected !== false + : pf.selected !== pf.initial_selected_state + ); + }) + ); + } + + get filtersChangedFromDefault$(): Observable { + return combineLatest([ + this.selectedFilterChangedFromDefault$, + this.primaryFilterChangedFromDefault$, + ]).pipe( + map(([selectFiltersChanged, primaryFiltersChanged]) => { + return selectFiltersChanged || primaryFiltersChanged; + }) + ); + } + get selectedFilter$(): Observable<{ [key: string]: string }> { return combineLatest([this.selectFilters$, this.primaryFilters$]).pipe( map(([selectFilters, primaryFilters]) => { @@ -216,6 +257,24 @@ export class SearchStateFacade { ); } + async resetPrimaryFilters(id?: number) { + let processId = id; + if (typeof processId !== 'number') { + processId = await this.getProcessId(); + } + + this.store.dispatch(actions.resetPrimaryFilters({ id: processId })); + } + + async resetSelectedFilters(id?: number) { + let processId = id; + if (typeof processId !== 'number') { + processId = await this.getProcessId(); + } + + this.store.dispatch(actions.resetSelectFilters({ id: processId })); + } + async fetchResult(id?: number) { let processId = id; if (typeof processId !== 'number') { diff --git a/apps/sales/src/app/store/customer/shelf/search/search.reducer.spec.ts b/apps/sales/src/app/store/customer/shelf/search/search.reducer.spec.ts index 5f5be4b2d..460eddb32 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.reducer.spec.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.reducer.spec.ts @@ -1,7 +1,10 @@ import { SearchState, INITIAL_SEARCH_STATE } from './search.state'; import { TypedAction } from '@ngrx/store/src/models'; import { PrimaryFilterOption } from 'apps/sales/src/app/modules/shelf/defs'; -import { primaryFiltersMock } from 'apps/sales/src/app/modules/shelf/shared/mockdata'; +import { + primaryFiltersMock, + mockFilters, +} from 'apps/sales/src/app/modules/shelf/shared/mockdata'; import * as actions from './search.actions'; import { searchReducer } from './search.reducer'; @@ -43,4 +46,60 @@ fdescribe('#SearchStateReducer', () => { expect(entity.filters.primaryFilters[1]).toEqual(primaryFiltersMock[1]); }); }); + + describe('resetPrimaryFilters', () => { + let action: { + id: number; + } & TypedAction; + + beforeEach(() => { + action = actions.resetPrimaryFilters({ id }); + }); + + it('should reset the primary Filters to their default state', () => { + const updatedPrimaryFilters = primaryFiltersMock.map((primaryFilter, i) => + i % 2 === 0 ? primaryFilter : { ...primaryFilter, selected: true } + ); + const setPrimaryFilterAction = actions.setPrimaryFilters({ + id, + filters: updatedPrimaryFilters, + }); + + let state = searchReducer(initialState, setPrimaryFilterAction); + state = searchReducer(state, action); + + expect(state.entities[id].filters.primaryFilters).toEqual( + primaryFiltersMock + ); + }); + }); + + describe('resetSelectedFilters', () => { + let action: { + id: number; + } & TypedAction; + + beforeEach(() => { + action = actions.resetSelectFilters({ id }); + }); + + it('should reset all selected filters to their default state', () => { + const selectFilters = [ + ...mockFilters.map((filter) => ({ + ...filter, + options: filter.options.map((o) => ({ ...o, selected: true })), + })), + ]; + + const setSelectedFilters = actions.setSelectFilters({ + id, + filters: selectFilters, + }); + + let state = searchReducer(initialState, setSelectedFilters); + state = searchReducer(state, action); + + expect(state.entities[id].filters.selectedFilters).toEqual(mockFilters); + }); + }); }); diff --git a/apps/sales/src/app/store/customer/shelf/search/search.reducer.ts b/apps/sales/src/app/store/customer/shelf/search/search.reducer.ts index 53a5c79cf..eced3746f 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.reducer.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.reducer.ts @@ -44,6 +44,51 @@ const _searchReducer = createReducer( s ) ), + on(actions.resetSelectFilters, (s, a) => + searchStateAdapter.updateOne( + { + id: a.id, + changes: { + filters: { + ...s.entities[a.id].filters, + selectedFilters: s.entities[a.id].filters.selectedFilters.map( + (filter) => { + let options = filter.options || []; + if (filter.options) { + options = filter.options.map((o) => ({ + ...o, + selected: o.initial_selected_state, + })); + } + + return { ...filter, options }; + } + ), + }, + }, + }, + s + ) + ), + on(actions.resetPrimaryFilters, (s, a) => + searchStateAdapter.updateOne( + { + id: a.id, + changes: { + filters: { + ...s.entities[a.id].filters, + primaryFilters: s.entities[a.id].filters.primaryFilters.map( + (primaryFilter) => ({ + ...primaryFilter, + selected: primaryFilter.initial_selected_state, + }) + ), + }, + }, + }, + s + ) + ), on(actions.clearError, (s, a) => searchStateAdapter.updateOne( { From bc6e5774c611c233efaf34f7d5bf3bab2d2e9429 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 10 Jul 2020 14:19:13 +0200 Subject: [PATCH 003/135] Fix Unit Tests --- .../shelf/search/search.facade.spec.ts | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts b/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts index 4296b9377..bc0f42dd9 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.facade.spec.ts @@ -170,27 +170,31 @@ fdescribe('SearchFacade', () => { expect(result).toBe(false); }); - xit('should return false if the primary filters are unchanged', () => { - const selectFilters$ = hot('--a', { a: selectFilters }); - const primaryFilters$ = hot('--a', { a: primaryFilters }); - const expected = cold('--a', { b: false }); + it('should return false if the primary filters are unchanged', () => { + const selectedFilterChangedFromDefault$ = hot('--a', { a: false }); + const primaryFilterChangedFromDefault$ = hot('--a', { a: false }); + const expected = cold('--b', { b: false }); - spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue( - selectFilters$ - ); - spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue( - primaryFilters$ - ); + spyOnProperty( + facade, + 'selectedFilterChangedFromDefault$', + 'get' + ).and.returnValue(selectedFilterChangedFromDefault$); + spyOnProperty( + facade, + 'primaryFilterChangedFromDefault$', + 'get' + ).and.returnValue(primaryFilterChangedFromDefault$); expect(facade.filtersChangedFromDefault$).toBeObservable(expected); }); - xit('should return true if the primary filters are changed', async () => { + it('should return true if the primary filters are changed', async () => { const selectFilters$ = hot('--a', { a: selectFilters }); const primaryFilters$ = hot('--a', { a: primaryFilters.map((f, i) => (!i ? { ...f, selected: true } : f)), }); - const expected = cold('--a', { b: true }); + const expected = cold('--b', { b: true }); spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue( selectFilters$ From f701c7dd4662fab45fbcfd8a324ec00c4f40ab82 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 12 Jul 2020 21:04:23 +0200 Subject: [PATCH 004/135] #829 Initial NgRx Customers Store SetUp Add Effects (WiP) Further Implement Customer Store incl. first Unit Tests --- .vscode/settings.json | 21 ++++- .../app/store/customer/customer.reducer.ts | 2 + .../src/app/store/customer/customer.state.ts | 2 + .../customer/customers/customers.actions.ts | 91 +++++++++++++++++++ .../customer/customers/customers.effects.ts | 73 +++++++++++++++ .../customers/customers.facade.spec.ts | 47 ++++++++++ .../customer/customers/customers.facade.ts | 57 ++++++++++++ .../customer/customers/customers.reducer.ts | 16 ++++ .../customers/customers.selectors.spec.ts | 22 +++++ .../customer/customers/customers.selectors.ts | 70 ++++++++++++++ .../customer/customers/customers.state.ts | 26 ++++++ .../customers/defs/customer-address.ts | 10 ++ .../customers/defs/customer-base-data.ts | 29 ++++++ .../customer/customers/defs/customer.model.ts | 15 +++ .../store/customer/customers/defs/index.ts | 6 ++ .../src/app/store/customer/customers/index.ts | 9 ++ ...stomer-dto-to-customer-addresses.mapper.ts | 19 ++++ ...stomer-dto-to-customer-base-data.mapper.ts | 39 ++++++++ .../customer-dto-to-customer.mapper.ts | 12 +++ .../store/customer/customers/mappers/index.ts | 5 + .../customers/mocks/customers-state.mock.ts | 46 ++++++++++ .../store/customer/customers/mocks/index.ts | 4 + .../customer/shelf/search/search.effects.ts | 1 - prod | 0 24 files changed, 620 insertions(+), 2 deletions(-) create mode 100644 apps/sales/src/app/store/customer/customers/customers.actions.ts create mode 100644 apps/sales/src/app/store/customer/customers/customers.effects.ts create mode 100644 apps/sales/src/app/store/customer/customers/customers.facade.spec.ts create mode 100644 apps/sales/src/app/store/customer/customers/customers.facade.ts create mode 100644 apps/sales/src/app/store/customer/customers/customers.reducer.ts create mode 100644 apps/sales/src/app/store/customer/customers/customers.selectors.spec.ts create mode 100644 apps/sales/src/app/store/customer/customers/customers.selectors.ts create mode 100644 apps/sales/src/app/store/customer/customers/customers.state.ts create mode 100644 apps/sales/src/app/store/customer/customers/defs/customer-address.ts create mode 100644 apps/sales/src/app/store/customer/customers/defs/customer-base-data.ts create mode 100644 apps/sales/src/app/store/customer/customers/defs/customer.model.ts create mode 100644 apps/sales/src/app/store/customer/customers/defs/index.ts create mode 100644 apps/sales/src/app/store/customer/customers/index.ts create mode 100644 apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-addresses.mapper.ts create mode 100644 apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-base-data.mapper.ts create mode 100644 apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer.mapper.ts create mode 100644 apps/sales/src/app/store/customer/customers/mappers/index.ts create mode 100644 apps/sales/src/app/store/customer/customers/mocks/customers-state.mock.ts create mode 100644 apps/sales/src/app/store/customer/customers/mocks/index.ts delete mode 100644 prod diff --git a/.vscode/settings.json b/.vscode/settings.json index 59b3b2b25..ffd57dedc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,24 @@ }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" - } + }, + "workbench.colorCustomizations": { + "activityBar.background": "#4a1557", + "titleBar.activeBackground": "#270b2e", + "titleBar.activeForeground": "#e7e7e7", + "activityBar.activeBackground": "#4a1557", + "activityBar.activeBorder": "#806d1f", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "activityBarBadge.background": "#806d1f", + "activityBarBadge.foreground": "#e7e7e7", + "statusBar.background": "#270b2e", + "statusBar.border": "#270b2e", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#4a1557", + "titleBar.border": "#270b2e", + "titleBar.inactiveBackground": "#270b2e99", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#270b2e" } diff --git a/apps/sales/src/app/store/customer/customer.reducer.ts b/apps/sales/src/app/store/customer/customer.reducer.ts index 8037e378d..f5f8c8c95 100644 --- a/apps/sales/src/app/store/customer/customer.reducer.ts +++ b/apps/sales/src/app/store/customer/customer.reducer.ts @@ -1,9 +1,11 @@ import { combineReducers, Action } from '@ngrx/store'; import { CustomerState } from './customer.state'; import { shelfReducer } from './shelf'; +import { customersReducer } from './customers'; const _customerReducer = combineReducers({ shelf: shelfReducer, + customers: customersReducer, }); export function customerReducer(state: CustomerState, action: Action) { diff --git a/apps/sales/src/app/store/customer/customer.state.ts b/apps/sales/src/app/store/customer/customer.state.ts index 607b32d2a..905e8b016 100644 --- a/apps/sales/src/app/store/customer/customer.state.ts +++ b/apps/sales/src/app/store/customer/customer.state.ts @@ -1,5 +1,7 @@ import { ShelfState } from './shelf'; +import { CustomersState } from './customers'; export interface CustomerState { shelf: ShelfState; + customers: CustomersState; } diff --git a/apps/sales/src/app/store/customer/customers/customers.actions.ts b/apps/sales/src/app/store/customer/customers/customers.actions.ts new file mode 100644 index 000000000..a4156db70 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.actions.ts @@ -0,0 +1,91 @@ +import { createAction, props } from '@ngrx/store'; +import { + StrictHttpResponse, + ListResponseArgsOfCustomerInfoDTO, + ResponseArgsOfCustomerDTO, + ListResponseArgsOfShippingAddressDTO, + ListResponseArgsOfAssignedPayerDTO, +} from '@swagger/crm'; +import { Customer } from './defs'; + +const prefix = `[Customer] [Customers]`; + +export const fetchCustomer = createAction( + `${prefix} Fetch Customer`, + props<{ id: number }>() +); + +export const fetchCustomerDone = createAction( + `${prefix} Fetch Customer Done`, + props<{ + id: number; + response: StrictHttpResponse; + }>() +); + +export const fetchCustomers = createAction( + `${prefix} Fetch Customers`, + props<{ query: any }>() +); + +export const fetchCustomersDone = createAction( + `${prefix} Fetch Customers Done`, + props<{ + id: number; + response: StrictHttpResponse; + }>() +); + +export const addCustomer = createAction( + `${prefix} Add Customer`, + props<{ + id: number; + customer: Customer; + }>() +); + +export const addCustomers = createAction( + `${prefix} Add Customers`, + props<{ + ids: number[]; + customers: Customer[]; + }>() +); + +export const updateCustomer = createAction( + `${prefix} Add Customers`, + props<{ + id: number; + customers: Partial; + }>() +); + +export const fetchPayerAddresses = createAction( + `${prefix} Fetch Payer Address`, + props<{ + id: number; + }>() +); + +export const fetchPayerAddressesDone = createAction( + `${prefix} Fetch Payer Address Done`, + props<{ + id: number; + response: StrictHttpResponse; + }>() +); + +export const fetchShippingyAddresses = createAction( + `${prefix} Fetch Shipping Address`, + props<{ + id: number; + }>() +); + +export const fetchShippingAddressesDone = createAction( + `${prefix} Fetch Shipping Address Done`, + props<{ + id: number; + response: StrictHttpResponse; + }>() +); diff --git a/apps/sales/src/app/store/customer/customers/customers.effects.ts b/apps/sales/src/app/store/customer/customers/customers.effects.ts new file mode 100644 index 000000000..4d180192e --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.effects.ts @@ -0,0 +1,73 @@ +import { Injectable } from '@angular/core'; +import { CustomerService } from '@swagger/crm'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { flatMap, map } from 'rxjs/operators'; +import * as actions from './customers.actions'; +import { customerDtoToCustomer } from './mappers'; +import { NEVER } from 'rxjs'; +import { Store } from '@ngrx/store'; + +@Injectable({ providedIn: 'root' }) +export class CustomersEffects { + constructor( + private actions$: Actions, + private crmService: CustomerService, + private store: Store + ) {} + + fetchCustomer$ = createEffect(() => + this.actions$.pipe( + ofType(actions.fetchCustomer), + flatMap((action) => + this.crmService + .CustomerGetCustomerResponse({ customerId: action.id }) + .pipe( + map((response) => + actions.fetchCustomerDone({ id: action.id, response }) + ) + ) + ) + ) + ); + + fetchCustomerDone$ = createEffect(() => + this.actions$.pipe( + ofType(actions.fetchCustomerDone), + flatMap((action) => { + if (action.response.ok) { + const result = action.response.body; + if (!result || !result.result) { + return NEVER; + } + const customer = customerDtoToCustomer(result.result); + return [actions.addCustomer({ id: action.id, customer })]; + } + + return NEVER; + }) + ) + ); + + fetchPayerAddress$ = createEffect(() => + this.actions$.pipe( + ofType(actions.fetchPayerAddresses), + flatMap((action) => + this.crmService + .CustomerGetAssignedPayersByCustomerIdResponse(action.id) + .pipe( + map((response) => + actions.fetchPayerAddressesDone({ id: action.id, response }) + ) + ) + ) + ) + ); + + fetchPayerAddressDone$ = createEffect(() => + this.actions$.pipe(ofType(actions.fetchPayerAddressesDone)) + ); + + fetchShippingAddress$ = createEffect(() => this.actions$.pipe()); + + fetchShippingAddressDone$ = createEffect(() => this.actions$.pipe()); +} diff --git a/apps/sales/src/app/store/customer/customers/customers.facade.spec.ts b/apps/sales/src/app/store/customer/customers/customers.facade.spec.ts new file mode 100644 index 000000000..9e8261b2d --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.facade.spec.ts @@ -0,0 +1,47 @@ +import { TestBed } from '@angular/core/testing'; +import { Store } from '@ngrx/store'; +import { CustomersState } from './customers.state'; +import { CustomersStateFacade } from './customers.facade'; +import { of } from 'rxjs'; +import * as CustomersSelectors from './customers.selectors'; + +fdescribe('#CustomersStateFacade', () => { + let facade: CustomersStateFacade; + let store: jasmine.SpyObj>; + + const id = 123; + + beforeEach(async () => { + TestBed.configureTestingModule({ + providers: [ + CustomersStateFacade, + { + provide: Store, + useValue: jasmine.createSpyObj>('store', { + select: of({}), + }), + }, + ], + }); + }); + + beforeEach(() => { + facade = TestBed.get(CustomersStateFacade); + store = TestBed.get(Store); + }); + + it('should be created', () => { + expect(facade instanceof CustomersStateFacade).toBeTruthy(); + }); + + describe('#getGeneralAddress$', () => { + it('should select the general address from store', () => { + facade.getGeneralAddress$(id); + + expect(store.select).toHaveBeenCalledWith( + CustomersSelectors.selectGeneralAddress, + id + ); + }); + }); +}); diff --git a/apps/sales/src/app/store/customer/customers/customers.facade.ts b/apps/sales/src/app/store/customer/customers/customers.facade.ts new file mode 100644 index 000000000..5bc970275 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.facade.ts @@ -0,0 +1,57 @@ +import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; +import { CustomersState } from './customers.state'; +import { + QueryTokenDTO, + CustomerInfoDTO, + AddressDTO, + ShippingAddressDTO, + AssignedPayerDTO, +} from '@swagger/crm'; +import * as CustomersSelectors from './customers.selectors'; + +@Injectable({ providedIn: 'root' }) +export class CustomersStateFacade { + constructor(private store: Store) {} + + public getGeneralAddress$(customerId: number): Observable { + return this.store.select( + CustomersSelectors.selectGeneralAddress, + customerId + ); + } + + public getPayerAddresses$( + customerId: number + ): Observable { + return; + } + + public getShippingAddresses$( + customerId: number + ): Observable { + return; + } + + public setBaseCustomer(customer: CustomerInfoDTO) { + // import mapper + // dispatch action to set customer + } + + public setInvoiceAddresses(customerId: number, address: AddressDTO[]) {} + + public setDeliveryAddresses(customerId: number, address: AddressDTO[]) {} + + private fetchCustomer(id?: number) { + // fetch single customer + } + + private fetchCustomers() { + // fetch multiple customers + } + + private getQueryToken(): QueryTokenDTO { + return; + } +} diff --git a/apps/sales/src/app/store/customer/customers/customers.reducer.ts b/apps/sales/src/app/store/customer/customers/customers.reducer.ts new file mode 100644 index 000000000..3fe0bd039 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.reducer.ts @@ -0,0 +1,16 @@ +import { + INITIAL_CUSTOMERS_STATE, + customersStateAdapter, + CustomersState, +} from './customers.state'; +import * as actions from './customers.actions'; +import { createReducer, on, Action } from '@ngrx/store'; + +export const _customersReducer = createReducer( + INITIAL_CUSTOMERS_STATE, + on(actions.addCustomer, (s, a) => customersStateAdapter.addOne(a.customer, s)) +); + +export function customersReducer(state: CustomersState, action: Action) { + return _customersReducer(state, action); +} diff --git a/apps/sales/src/app/store/customer/customers/customers.selectors.spec.ts b/apps/sales/src/app/store/customer/customers/customers.selectors.spec.ts new file mode 100644 index 000000000..d3277eb19 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.selectors.spec.ts @@ -0,0 +1,22 @@ +import { CustomersState } from './customers.state'; +import { customersStateMock } from './mocks'; +import * as CustomersSelectors from './customers.selectors'; +import { Dictionary } from '@cmf/core'; +import { Customer } from './defs'; + +fdescribe('#CustomersSelectors', () => { + let entities: Dictionary; + + describe('selectGeneralAddress', () => { + beforeEach(() => { + entities = customersStateMock.entities; + }); + it('should select the general address for the provided customerId', () => { + const id = 123; + + expect( + CustomersSelectors.selectGeneralAddress.projector(entities, 123) + ).toEqual(entities[id].addresses.generalAddress); + }); + }); +}); diff --git a/apps/sales/src/app/store/customer/customers/customers.selectors.ts b/apps/sales/src/app/store/customer/customers/customers.selectors.ts new file mode 100644 index 000000000..c1858eea4 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.selectors.ts @@ -0,0 +1,70 @@ +import { createSelector } from '@ngrx/store'; +import { Dictionary } from '@cmf/core'; +import { customersStateAdapter } from './customers.state'; +import { selectCustomerState } from '../customer.selector'; +import { Customer } from './defs'; + +export const selectCustomersState = createSelector( + selectCustomerState, + (s) => s.customers +); + +export const { selectAll, selectEntities } = customersStateAdapter.getSelectors( + selectCustomersState +); + +export const selectCustomers = createSelector( + selectEntities, + (entities: Dictionary) => entities +); + +export const selectCustomer = createSelector( + selectEntities, + (entities: Dictionary, id: number) => entities[id] +); + +export const selectAddresses = createSelector( + selectEntities, + (entities: Dictionary, id: number) => + entities[id] && entities[id].addresses +); + +export const selectGeneralAddress = createSelector( + selectEntities, + (entities: Dictionary, id: number) => + entities[id] && + entities[id].addresses && + entities[id].addresses.generalAddress +); + +export const selectShippingAddresses = createSelector( + selectEntities, + (entities: Dictionary, id: number) => + entities[id] && entities[id].addresses.shippingAddresses +); + +export const selectDefaultShippingAddress = createSelector( + selectEntities, + (entities: Dictionary, id: number) => + entities[id] && + entities[id].addresses.shippingAddresses && + entities[id].addresses.shippingAddresses.find( + (address) => address.isDefault + ) +); + +export const selectPayerAddresses = createSelector( + selectEntities, + (entities: Dictionary, id: number) => + entities[id] && + entities[id].addresses && + entities[id].addresses.payerAddresses +); + +export const selectDefaultPayerAddresses = createSelector( + selectEntities, + (entities: Dictionary, id: number) => + entities[id] && + entities[id].addresses && + entities[id].addresses.payerAddresses.find((address) => address.isDefault) +); diff --git a/apps/sales/src/app/store/customer/customers/customers.state.ts b/apps/sales/src/app/store/customer/customers/customers.state.ts new file mode 100644 index 000000000..2ff1c493c --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/customers.state.ts @@ -0,0 +1,26 @@ +import { Customer } from './defs'; +import { EntityState, createEntityAdapter } from '@ngrx/entity'; + +export interface CustomersState extends EntityState {} + +export const customersStateAdapter = createEntityAdapter(); + +export const INITIAL_CUSTOMERS_STATE: CustomersState = { + ...customersStateAdapter.getInitialState(), +}; + +export const INITIAL_CUSTOMER: Customer = { + id: undefined, + baseData: {}, + + addresses: { + generalAddress: {}, + shippingAddresses: [], + payerAddresses: [], + + shippingAddressIds: [], + payerAddressIds: [], + }, + + detailsLoaded: false, +}; diff --git a/apps/sales/src/app/store/customer/customers/defs/customer-address.ts b/apps/sales/src/app/store/customer/customers/defs/customer-address.ts new file mode 100644 index 000000000..3783e5242 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/defs/customer-address.ts @@ -0,0 +1,10 @@ +import { AddressDTO, ShippingAddressDTO, AssignedPayerDTO } from '@swagger/crm'; + +export interface CustomerAddresses { + generalAddress: AddressDTO; + shippingAddresses: ShippingAddressDTO[]; + payerAddresses: AssignedPayerDTO[]; + + shippingAddressIds: number[]; + payerAddressIds: number[]; +} diff --git a/apps/sales/src/app/store/customer/customers/defs/customer-base-data.ts b/apps/sales/src/app/store/customer/customers/defs/customer-base-data.ts new file mode 100644 index 000000000..8ce0ce332 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/defs/customer-base-data.ts @@ -0,0 +1,29 @@ +import { + EntityDTOContainerOfBranchDTO, + CustomerType, + CustomerStatus, + Gender, + NotificationChannel, + CommunicationDetailsDTO, +} from '@swagger/crm'; + +export interface CustomerBaseData { + /** Basisdaten */ + gender?: Gender; + title?: string; + firstName?: string; + lastName?: string; + dateOfBirth?: string; + + /** Kundentyp */ + customerGroup?: string; + createdInBranch?: EntityDTOContainerOfBranchDTO; + customerNumber?: string; + customerType?: CustomerType; + customerStatus?: CustomerStatus; + isGuestAccount?: boolean; + hasOnlineAccount?: boolean; + notificationChannels?: NotificationChannel; + + communicationDetails?: CommunicationDetailsDTO; +} diff --git a/apps/sales/src/app/store/customer/customers/defs/customer.model.ts b/apps/sales/src/app/store/customer/customers/defs/customer.model.ts new file mode 100644 index 000000000..217f2eb61 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/defs/customer.model.ts @@ -0,0 +1,15 @@ +import { CustomerBaseData } from './customer-base-data'; +import { CustomerAddresses } from './customer-address'; + +export interface Customer { + id: number; + + /** Stammdaten */ + baseData: CustomerBaseData; + + /** Addresdaten */ + addresses: CustomerAddresses; + + /** Wurden die Kundendetails geladen? */ + detailsLoaded?: boolean; +} diff --git a/apps/sales/src/app/store/customer/customers/defs/index.ts b/apps/sales/src/app/store/customer/customers/defs/index.ts new file mode 100644 index 000000000..08e0c34bb --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/defs/index.ts @@ -0,0 +1,6 @@ +// start:ng42.barrel +export * from './customer-address'; +export * from './customer-base-data'; +export * from './customer.model'; +// end:ng42.barrel + diff --git a/apps/sales/src/app/store/customer/customers/index.ts b/apps/sales/src/app/store/customer/customers/index.ts new file mode 100644 index 000000000..8c231b158 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/index.ts @@ -0,0 +1,9 @@ +// start:ng42.barrel +export * from './customers.actions'; +export * from './customers.effects'; +export * from './customers.facade'; +export * from './customers.reducer'; +export * from './customers.selectors'; +export * from './customers.state'; +// end:ng42.barrel + diff --git a/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-addresses.mapper.ts b/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-addresses.mapper.ts new file mode 100644 index 000000000..294e3c047 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-addresses.mapper.ts @@ -0,0 +1,19 @@ +import { CustomerDTO } from '@swagger/crm'; +import { CustomerAddresses } from '../defs'; + +export function customerDtoToCustomerAddresses( + customerDto: CustomerDTO +): CustomerAddresses { + return { + generalAddress: customerDto.address, + shippingAddresses: [], + payerAddresses: [], + + shippingAddressIds: customerDto.shippingAddresses.map( + (addressData) => addressData.id + ), + payerAddressIds: customerDto.payers + .filter((addressData) => addressData.payer) + .map((addressData) => addressData.payer.id), + }; +} diff --git a/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-base-data.mapper.ts b/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-base-data.mapper.ts new file mode 100644 index 000000000..b48e10de4 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer-base-data.mapper.ts @@ -0,0 +1,39 @@ +import { CustomerDTO } from '@swagger/crm'; +import { CustomerBaseData } from '../defs'; + +export function customerDtoToCustomerBaseData( + customerDto: CustomerDTO +): CustomerBaseData { + const { + gender, + title, + firstName, + lastName, + dateOfBirth, + customerGroup, + createdInBranch, + customerNumber, + customerType, + customerStatus, + isGuestAccount, + notificationChannels, + hasOnlineAccount, + communicationDetails, + } = customerDto; + return { + gender, + title, + firstName, + lastName, + dateOfBirth, + customerGroup, + createdInBranch, + customerNumber, + customerType, + customerStatus, + isGuestAccount, + notificationChannels, + hasOnlineAccount, + communicationDetails, + }; +} diff --git a/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer.mapper.ts b/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer.mapper.ts new file mode 100644 index 000000000..c5b39cbd9 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/mappers/customer-dto-to-customer.mapper.ts @@ -0,0 +1,12 @@ +import { CustomerDTO } from '@swagger/crm/lib'; +import { Customer } from '../defs'; +import { customerDtoToCustomerBaseData } from './customer-dto-to-customer-base-data.mapper'; +import { customerDtoToCustomerAddresses } from './customer-dto-to-customer-addresses.mapper'; + +export function customerDtoToCustomer(customerDto: CustomerDTO): Customer { + return { + id: customerDto.id, + baseData: customerDtoToCustomerBaseData(customerDto), + addresses: customerDtoToCustomerAddresses(customerDto), + }; +} diff --git a/apps/sales/src/app/store/customer/customers/mappers/index.ts b/apps/sales/src/app/store/customer/customers/mappers/index.ts new file mode 100644 index 000000000..c15cdc3a7 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/mappers/index.ts @@ -0,0 +1,5 @@ +// start:ng42.barrel +export * from './customer-dto-to-customer-base-data.mapper'; +export * from './customer-dto-to-customer-addresses.mapper'; +export * from './customer-dto-to-customer.mapper'; +// end:ng42.barrel diff --git a/apps/sales/src/app/store/customer/customers/mocks/customers-state.mock.ts b/apps/sales/src/app/store/customer/customers/mocks/customers-state.mock.ts new file mode 100644 index 000000000..ce29ec643 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/mocks/customers-state.mock.ts @@ -0,0 +1,46 @@ +import { CustomersState } from '../customers.state'; + +export const customersStateMock: CustomersState = { + ids: [123, 456, 789], + entities: { + 123: { + id: 123, + baseData: {}, + addresses: { + generalAddress: {}, + shippingAddresses: [], + payerAddresses: [], + + shippingAddressIds: [], + payerAddressIds: [], + }, + detailsLoaded: false, + }, + 456: { + id: 456, + baseData: {}, + addresses: { + generalAddress: {}, + shippingAddresses: [], + payerAddresses: [], + + shippingAddressIds: [], + payerAddressIds: [], + }, + detailsLoaded: false, + }, + 789: { + id: 789, + baseData: {}, + addresses: { + generalAddress: {}, + shippingAddresses: [], + payerAddresses: [], + + shippingAddressIds: [], + payerAddressIds: [], + }, + detailsLoaded: false, + }, + }, +}; diff --git a/apps/sales/src/app/store/customer/customers/mocks/index.ts b/apps/sales/src/app/store/customer/customers/mocks/index.ts new file mode 100644 index 000000000..500b8c794 --- /dev/null +++ b/apps/sales/src/app/store/customer/customers/mocks/index.ts @@ -0,0 +1,4 @@ +// start:ng42.barrel +export * from './customers-state.mock'; +// end:ng42.barrel + diff --git a/apps/sales/src/app/store/customer/shelf/search/search.effects.ts b/apps/sales/src/app/store/customer/shelf/search/search.effects.ts index 09e3b22c2..03b0cd888 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.effects.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.effects.ts @@ -20,7 +20,6 @@ import { ListResponseArgsOfOrderItemListItemDTO, ResponseArgsOfIEnumerableOfInputDTO, } from '@swagger/oms'; -import { BranchService } from '@sales/core-services'; import { SearchStateFacade } from './search.facade'; import { of, NEVER } from 'rxjs'; import { diff --git a/prod b/prod deleted file mode 100644 index e69de29bb..000000000 From f6a4e3e413d4f785052e225a8dfa0f72d2720949 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 13 Jul 2020 08:41:22 +0200 Subject: [PATCH 005/135] #830 Fix Filter Overlay Close Results Cleared Error --- .../search/search-input.component.spec.ts | 128 ++++++++++++++++++ .../search/search-input.component.ts | 17 +-- 2 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts new file mode 100644 index 000000000..63d8af210 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts @@ -0,0 +1,128 @@ +import { + ComponentFixture, + TestBed, + fakeAsync, + tick, +} from '@angular/core/testing'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { SearchStateFacade } from '@shelf-store'; +import { of } from 'rxjs'; +import { + ShelfNavigationService, + ShelfSearchFacadeService, +} from '../../../shared/services'; +import { ShelfSearchInputComponent } from './search-input.component'; +import { ShelfFilterService } from '../../../services'; + +class MockSearchStateFacade { + constructor() {} + + get hasResults$() { + return of(true); + } + + get hits$() { + return of(3); + } + + get input$() { + return of('Testsuche'); + } + + get result$() { + return of([]); + } + + get fetching$() { + return of(false); + } + + get showNoResultError$() { + return of(true); + } + + get selectedFilters$() { + return of([]); + } + + clearResult() {} + + clearError() {} +} + +fdescribe('#SearchInputComponent', () => { + let fixture: ComponentFixture; + let component: ShelfSearchInputComponent; + let facade: SearchStateFacade; + let navigationService: jasmine.SpyObj; + let shelfSearchService: jasmine.SpyObj; + + beforeEach(async () => { + TestBed.configureTestingModule({ + declarations: [ShelfSearchInputComponent], + providers: [ + { + provide: SearchStateFacade, + useClass: MockSearchStateFacade, + }, + { + provide: ShelfNavigationService, + useValue: jasmine.createSpyObj('shelfNavigationService', [ + 'navigateToResultList', + ]), + }, + { + provide: ShelfFilterService, + useValue: jasmine.createSpy('shelfFilterService'), + }, + { + provide: ShelfSearchFacadeService, + useValue: jasmine.createSpyObj('shelfSearchService', ['search']), + }, + ], + schemas: [NO_ERRORS_SCHEMA], + }); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ShelfSearchInputComponent); + component = fixture.componentInstance; + facade = TestBed.get(SearchStateFacade); + navigationService = TestBed.get(ShelfNavigationService); + shelfSearchService = TestBed.get(ShelfSearchFacadeService); + + component.hasAutocomplete = false; + component.autocompleteResult$ = of([]); + + spyOn(component, 'ngAfterViewInit').and.callFake(() => {}); + + fixture.detectChanges(); + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + }); + + it('should not clear the previous results onInit', () => { + spyOn(facade, 'clearResult').and.callThrough(); + component.ngOnInit(); + + expect(facade.clearResult).not.toHaveBeenCalled(); + }); + + it('should not setup navigation onInit', fakeAsync(() => { + component.ngOnInit(); + + tick(); + + expect(navigationService.navigateToResultList).not.toHaveBeenCalled(); + })); + + it('should set up navigation after triggering a search', fakeAsync(() => { + component.triggerSearch({ type: 'search', value: 'Testsuche' }); + + tick(); + + expect(navigationService.navigateToResultList).toHaveBeenCalled(); + })); +}); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts index bb5b5ad1e..3092befd5 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts @@ -7,14 +7,7 @@ import { ViewChild, AfterViewInit, } from '@angular/core'; -import { - Subject, - BehaviorSubject, - Observable, - of, - NEVER, - Subscription, -} from 'rxjs'; +import { Subject, BehaviorSubject, Observable, of, NEVER } from 'rxjs'; import { ShelfSearchFacadeService, ShelfNavigationService, @@ -85,7 +78,6 @@ export class ShelfSearchInputComponent ) {} ngOnInit() { - this.clearPreviousResults(); if (this.hasAutocomplete) { this.setupAutocompletion(); } @@ -139,6 +131,8 @@ export class ShelfSearchInputComponent } else if (type === 'scan') { this.shelfSearchService.searchWithBarcode(value); } + + this.setUpNavigation(); } openScanner() { @@ -173,10 +167,6 @@ export class ShelfSearchInputComponent } } - private clearPreviousResults() { - this.searchStateFacade.clearResult(); - } - private resetSessionStorage(key: string = SHELF_SCROLL_INDEX) { sessionStorage.removeItem(key); } @@ -225,7 +215,6 @@ export class ShelfSearchInputComponent startWith('') ); - this.setUpNavigation(); this.setUpErrorCleaner(); } From 245528a54837dad0e1bd9018241fa2ebc5c71d0f Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Mon, 13 Jul 2020 11:15:56 +0200 Subject: [PATCH 006/135] No optimization for test build --- angular.json | 86 +++++++++------------------------------------------- 1 file changed, 14 insertions(+), 72 deletions(-) diff --git a/angular.json b/angular.json index f2a6d8750..2b0888fca 100644 --- a/angular.json +++ b/angular.json @@ -27,10 +27,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "libs/ui/tsconfig.lib.json", - "libs/ui/tsconfig.spec.json" - ], + "tsConfig": ["libs/ui/tsconfig.lib.json", "libs/ui/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -89,25 +86,7 @@ ], "serviceWorker": true }, - "development": { - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "aot": true, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - } - ], - "serviceWorker": true - } + "development": {} } }, "serve": { @@ -148,20 +127,13 @@ "includePaths": ["apps/sales/src/scss"] }, "scripts": [], - "assets": [ - "apps/sales/src/favicon.ico", - "apps/sales/src/assets", - "apps/sales/src/manifest.webmanifest" - ] + "assets": ["apps/sales/src/favicon.ico", "apps/sales/src/assets", "apps/sales/src/manifest.webmanifest"] } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/sales/tsconfig.app.json", - "apps/sales/tsconfig.spec.json" - ], + "tsConfig": ["apps/sales/tsconfig.app.json", "apps/sales/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -220,10 +192,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "libs/sso/tsconfig.lib.json", - "libs/sso/tsconfig.spec.json" - ], + "tsConfig": ["libs/sso/tsconfig.lib.json", "libs/sso/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -253,10 +222,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/availability/tsconfig.lib.json", - "apps/swagger/availability/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/availability/tsconfig.lib.json", "apps/swagger/availability/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -286,10 +252,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/checkout/tsconfig.lib.json", - "apps/swagger/checkout/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/checkout/tsconfig.lib.json", "apps/swagger/checkout/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -319,10 +282,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/crm/tsconfig.lib.json", - "apps/swagger/crm/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/crm/tsconfig.lib.json", "apps/swagger/crm/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -352,10 +312,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/isa/tsconfig.lib.json", - "apps/swagger/isa/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/isa/tsconfig.lib.json", "apps/swagger/isa/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -385,10 +342,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/oms/tsconfig.lib.json", - "apps/swagger/oms/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/oms/tsconfig.lib.json", "apps/swagger/oms/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -418,10 +372,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/print/tsconfig.lib.json", - "apps/swagger/print/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/print/tsconfig.lib.json", "apps/swagger/print/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -451,10 +402,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/cat/tsconfig.lib.json", - "apps/swagger/cat/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/cat/tsconfig.lib.json", "apps/swagger/cat/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -484,10 +432,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/swagger/eis/tsconfig.lib.json", - "apps/swagger/eis/tsconfig.spec.json" - ], + "tsConfig": ["apps/swagger/eis/tsconfig.lib.json", "apps/swagger/eis/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } @@ -517,10 +462,7 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "apps/native-container/tsconfig.lib.json", - "apps/native-container/tsconfig.spec.json" - ], + "tsConfig": ["apps/native-container/tsconfig.lib.json", "apps/native-container/tsconfig.spec.json"], "exclude": ["**/node_modules/**"] } } From fcaf694f0aeb1c56c76afed83d2a892e67179393 Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Mon, 13 Jul 2020 12:17:28 +0200 Subject: [PATCH 007/135] Fehlermeldung beim starten => .reduce of undefined --- apps/sales/src/app/utils/group-by.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/sales/src/app/utils/group-by.ts b/apps/sales/src/app/utils/group-by.ts index 2003848e6..af1976478 100644 --- a/apps/sales/src/app/utils/group-by.ts +++ b/apps/sales/src/app/utils/group-by.ts @@ -1,6 +1,10 @@ import { Group } from './defs'; export function groupBy(collection: TI[], selectGroup: (item: TI) => TG): Group[] { + if (!Array.isArray(collection)) { + return []; + } + return collection.reduce((acc, item) => { const group = selectGroup(item); const groupIndex = acc.findIndex((itm) => itm.group === group); From 21d91b99d59648b06a3b71f55921b7889f0f82a7 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 13 Jul 2020 12:22:37 +0200 Subject: [PATCH 008/135] #810 Fix Mapping of DestinationDTO --- .../core/mappings/customer.mapping.spec.ts | 81 +++++++ .../src/app/core/mappings/customer.mapping.ts | 152 +++++++++--- apps/sales/src/app/core/models/user.model.ts | 1 + .../src/app/core/services/customer.service.ts | 226 ++++++++++++------ .../src/app/core/store/state/app.state.ts | 130 +++++++--- .../src/app/core/store/state/cart.state.ts | 186 ++++++++++---- .../delivery-cart/delivery-cart.component.ts | 60 ++++- .../pay-method/pay-method.component.ts | 129 ++++++++-- .../customer-search-card.component.ts | 73 ++++-- .../customer-data.datasource.ts | 65 +++-- .../customer-search-result.component.html | 71 ++++-- .../customer-search-result.component.ts | 4 +- 12 files changed, 891 insertions(+), 287 deletions(-) create mode 100644 apps/sales/src/app/core/mappings/customer.mapping.spec.ts diff --git a/apps/sales/src/app/core/mappings/customer.mapping.spec.ts b/apps/sales/src/app/core/mappings/customer.mapping.spec.ts new file mode 100644 index 000000000..d9a8cac00 --- /dev/null +++ b/apps/sales/src/app/core/mappings/customer.mapping.spec.ts @@ -0,0 +1,81 @@ +import { Organisation, User } from '../models/user.model'; +import { CustomerMapping } from './customer.mapping'; +import { TestBed } from '@angular/core/testing'; +import { DatePipe } from '@angular/common'; + +fdescribe('CustomerMapping', () => { + let mapper: CustomerMapping; + const mockUser: User = { + id: 123, + first_name: 'Vorname', + last_name: 'Nachname', + title: 'Dr', + gender: 'Herr', + + email: 'test@test.de', + phone_number: '017012345678', + mobile_number: '019998765432', + + organisation: { + name: 'Mock Org', + department: 'Mock Dept.', + vatId: '123', + }, + + delivery_addres: { + id: 456, + first_name: 'Vorname Addresse', + last_name: 'Nachname Addresse', + street: 'Test Strasse', + streetNo: 12, + zip: '80636', + city: 'Munich', + country: 'Deutschland', + }, + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [DatePipe, CustomerMapping], + }); + + mapper = TestBed.get(CustomerMapping); + }); + + it('should be created', () => { + expect(mapper instanceof CustomerMapping).toBeTruthy(); + }); + + describe('fromOrganisationToOrganisationDTO', () => { + const mockOrganisation: Organisation = mockUser.organisation; + it('should map the provided organisation (Organisation) to OrganisationDTO', () => { + const result = mapper.fromOrganisationToOrganisationDTO(mockOrganisation); + + expect(result.vatId).toEqual(mockOrganisation.vatId); + expect(result.department).toEqual(mockOrganisation.department); + expect(result.name).toEqual(mockOrganisation.name); + }); + }); + + describe('fromUserToCommunicationDetails', () => { + it('should map the provided user (User) to communication details (CommunicationDetailsDTO)', () => { + const result = mapper.fromUserToCommunicationDetails(mockUser); + + expect(result.phone).toEqual(mockUser.phone_number); + expect(result.mobile).toEqual(mockUser.mobile_number); + expect(result.email).toEqual(mockUser.email); + }); + }); + + describe('fromUserToShippingAddressDTO', () => { + it('should map the provided user (User) to shipping address (ShippingAddressDTO)', () => { + const result = mapper.fromUserToShippingAddressDTO(mockUser); + + expect(result.title).toEqual(mockUser.delivery_addres.title); + expect(result.gender).toEqual(2); + expect(result.firstName).toEqual(mockUser.delivery_addres.first_name); + expect(result.lastName).toEqual(mockUser.delivery_addres.last_name); + expect(result.source).toEqual(mockUser.delivery_addres.id); + }); + }); +}); diff --git a/apps/sales/src/app/core/mappings/customer.mapping.ts b/apps/sales/src/app/core/mappings/customer.mapping.ts index 73dccd475..c61f52394 100644 --- a/apps/sales/src/app/core/mappings/customer.mapping.ts +++ b/apps/sales/src/app/core/mappings/customer.mapping.ts @@ -9,12 +9,15 @@ import { CommunicationDetailsDTO, AssignedPayerDTO, CustomerInfoDTO, - ShippingAddressDTO, PayerDTO, CustomerDTO, + ShippingAddressDTO, } from '@swagger/crm'; import { NotificationChannels } from '../models/notification-channels.enum'; -import { EntityDTOContainerOfBranchDTO } from '@swagger/checkout'; +import { + EntityDTOContainerOfBranchDTO, + ShippingAddressDTO as CheckoutShippingAddressDTO, +} from '@swagger/checkout'; import { DatePipe } from '@angular/common'; import { BACKEND_API_TIMESTAMP_FORMAT } from '../utils/app.formats'; import { KeyValueDTOOfStringAndString } from '@swagger/cat'; @@ -60,7 +63,9 @@ export class CustomerMapping { zipCode: customer.delivery_addres.zip + '', street: customer.delivery_addres.street, streetNumber: customer.delivery_addres.streetNo + '', - info: customer.delivery_addres.note ? customer.delivery_addres.note : null, + info: customer.delivery_addres.note + ? customer.delivery_addres.note + : null, }; } @@ -71,7 +76,9 @@ export class CustomerMapping { zipCode: customer.invoice_address.zip + '', street: customer.invoice_address.street, streetNumber: customer.invoice_address.streetNo + '', - info: customer.invoice_address.note ? customer.invoice_address.note : null, + info: customer.invoice_address.note + ? customer.invoice_address.note + : null, }; } @@ -84,14 +91,20 @@ export class CustomerMapping { }; } - if (Array.isArray(customer.poossible_delivery_addresses) && customer.poossible_delivery_addresses.length > 0) { + if ( + Array.isArray(customer.poossible_delivery_addresses) && + customer.poossible_delivery_addresses.length > 0 + ) { customer.poossible_delivery_addresses.forEach((adrs: Address) => { addresses.push(this.addressesItem(adrs)); shippingAddresses.push(this.addressesItem(adrs)); }); } - if (Array.isArray(customer.poossible_invoice_addresses) && customer.poossible_invoice_addresses.length > 0) { + if ( + Array.isArray(customer.poossible_invoice_addresses) && + customer.poossible_invoice_addresses.length > 0 + ) { customer.poossible_invoice_addresses.forEach((adrs: Address) => { if (adrs) { addresses.push(this.addressesItem(adrs)); @@ -178,7 +191,9 @@ export class CustomerMapping { } } - private addressesItem(address: Address): EntityDTOContainerOfShippingAddressDTO { + private addressesItem( + address: Address + ): EntityDTOContainerOfShippingAddressDTO { if (!address) { return; } @@ -214,7 +229,9 @@ export class CustomerMapping { customerInfoDTOtoUser(customerInfo: CustomerInfoDTO): User { if (isNullOrUndefined(customerInfo)) { - throw new Error('argument customerInfo:CustomerInfoDTO is null or undefined.'); + throw new Error( + 'argument customerInfo:CustomerInfoDTO is null or undefined.' + ); } const id = customerInfo.id; @@ -252,18 +269,22 @@ export class CustomerMapping { customerInfo.notificationChannels === NotificationChannels.EmailSms; } - let address: Address; + let baseAddres: Address = {} as Address; if (!!customerInfo.address) { - address = { + baseAddres = { id: Date.now() + Math.random(), title: customerInfo.title, first_name: customerInfo.firstName, last_name: customerInfo.lastName, city: customerInfo.address.city ? customerInfo.address.city : undefined, - zip: customerInfo.address.zipCode ? customerInfo.address.zipCode : undefined, + zip: customerInfo.address.zipCode + ? customerInfo.address.zipCode + : undefined, country: customerInfo.address.country, street: customerInfo.address.street, - streetNo: customerInfo.address.streetNumber ? +customerInfo.address.streetNumber : undefined, + streetNo: customerInfo.address.streetNumber + ? +customerInfo.address.streetNumber + : undefined, }; } @@ -310,7 +331,7 @@ export class CustomerMapping { payement_method: null, // missing info from API tolino: false, // missing info from API title: null, // missing info from API - delivery_addres: address, + base_addres: baseAddres, isGuestAccount: customerInfo.isGuestAccount, features: features, changed: customerInfo.changed, @@ -334,7 +355,9 @@ export class CustomerMapping { customerDTOtoUser(customerDto: CustomerDTO): User { if (isNullOrUndefined(customerDto)) { - throw new Error('argument customerDto:CustomerInfoDTO is null or undefined.'); + throw new Error( + 'argument customerDto:CustomerInfoDTO is null or undefined.' + ); } const id = customerDto.id; @@ -365,15 +388,16 @@ export class CustomerMapping { let notificationEmail = false; if (customerDto.notificationChannels) { notificationSms = - customerDto.notificationChannels === NotificationChannels.Sms || customerDto.notificationChannels === NotificationChannels.EmailSms; + customerDto.notificationChannels === NotificationChannels.Sms || + customerDto.notificationChannels === NotificationChannels.EmailSms; notificationEmail = customerDto.notificationChannels === NotificationChannels.Email || customerDto.notificationChannels === NotificationChannels.EmailSms; } - let address: Address; + let baseAddres: Address; if (!!customerDto.address) { - address = { + baseAddres = { id: Date.now() + Math.random(), title: customerDto.title, first_name: customerDto.firstName, @@ -422,7 +446,9 @@ export class CustomerMapping { mobile_number: mobileNumber, newUser: newUser, customer_card: false, - createdInBranch: customerDto.createdInBranch ? customerDto.createdInBranch.id : null, + createdInBranch: customerDto.createdInBranch + ? customerDto.createdInBranch.id + : null, newsletter: false, // missing info from API shop: false, notificationSms: notificationSms, @@ -430,10 +456,6 @@ export class CustomerMapping { payement_method: null, // missing info from API tolino: false, // missing info from API title: null, // missing info from API - delivery_addres: address, - invoice_address: address, - poossible_delivery_addresses: [address], - poossible_invoice_addresses: [address], features: features, changed: customerDto.changed, created: customerDto.created, @@ -442,9 +464,13 @@ export class CustomerMapping { }; } - fromShippingAddressDtoToAddress(shippingAddress: ShippingAddressDTO): Address { + fromShippingAddressDtoToAddress( + shippingAddress: ShippingAddressDTO + ): Address { if (isNullOrUndefined(shippingAddress)) { - throw new Error('argument shippingAddress:ShippingAddressDTO is null or undefined.'); + throw new Error( + 'argument shippingAddress:ShippingAddressDTO is null or undefined.' + ); } let gender = ''; @@ -497,7 +523,10 @@ export class CustomerMapping { }; } - fromAddressToShippingAddressDTO(address: Address, forUpdate: boolean): ShippingAddressDTO { + fromAddressToShippingAddressDTO( + address: Address, + forUpdate: boolean + ): ShippingAddressDTO { if (isNullOrUndefined(address)) { throw new Error('argument address:Address is null or undefined.'); } @@ -529,7 +558,10 @@ export class CustomerMapping { lastName: address.last_name, gender: this.getGender(address.gender), status: 1, - isDefault: this.datePipe.transform(new Date(), BACKEND_API_TIMESTAMP_FORMAT), + isDefault: this.datePipe.transform( + new Date(), + BACKEND_API_TIMESTAMP_FORMAT + ), organisation: { name: address.company_name, department: address.company_department, @@ -584,7 +616,10 @@ export class CustomerMapping { lastName: address.last_name, gender: this.getGender(address.gender), status: 1, - isDefault: this.datePipe.transform(new Date(), BACKEND_API_TIMESTAMP_FORMAT), + isDefault: this.datePipe.transform( + new Date(), + BACKEND_API_TIMESTAMP_FORMAT + ), address: _address, payerNumber: address.payer_number, payerStatus: address.payer_status, @@ -599,7 +634,9 @@ export class CustomerMapping { fromAssignedPayerDtoToAddress(assignedPayers: AssignedPayerDTO): Address { if (isNullOrUndefined(assignedPayers)) { - throw new Error('argument shippingAddress:ShippingAddressDTO is null or undefined.'); + throw new Error( + 'argument shippingAddress:ShippingAddressDTO is null or undefined.' + ); } let id = null; @@ -612,7 +649,11 @@ export class CustomerMapping { } let gender = ''; - if (!!assignedPayers.payer && !!assignedPayers.payer.data && !!assignedPayers.payer.data.gender) { + if ( + !!assignedPayers.payer && + !!assignedPayers.payer.data && + !!assignedPayers.payer.data.gender + ) { gender = this.getGenderFromCode(assignedPayers.payer.data.gender); } @@ -621,7 +662,11 @@ export class CustomerMapping { let street = ''; let streetNo = null; let zip: string = null; - if (!!assignedPayers.payer && !!assignedPayers.payer.data && !!assignedPayers.payer.data.address) { + if ( + !!assignedPayers.payer && + !!assignedPayers.payer.data && + !!assignedPayers.payer.data.address + ) { country = assignedPayers.payer.data.address.country; city = assignedPayers.payer.data.address.city; street = assignedPayers.payer.data.address.street; @@ -643,7 +688,11 @@ export class CustomerMapping { let company_name = null; let company_department = null; let company_tax_number = null; - if (!!assignedPayers.payer && !!assignedPayers.payer.data && !!assignedPayers.payer.data.organisation) { + if ( + !!assignedPayers.payer && + !!assignedPayers.payer.data && + !!assignedPayers.payer.data.organisation + ) { company_name = assignedPayers.payer.data.organisation.name; company_department = assignedPayers.payer.data.organisation.department; company_tax_number = assignedPayers.payer.data.organisation.vatId; @@ -706,7 +755,9 @@ export class CustomerMapping { zipCode: customer.delivery_addres.zip + '', street: customer.delivery_addres.street, streetNumber: customer.delivery_addres.streetNo + '', - info: customer.delivery_addres.note ? customer.delivery_addres.note : null, + info: customer.delivery_addres.note + ? customer.delivery_addres.note + : null, }; } @@ -767,4 +818,41 @@ export class CustomerMapping { ? NotificationChannels.Sms : NotificationChannels.NotSet; } + + fromOrganisationToOrganisationDTO( + organisation: Organisation + ): OrganisationDTO { + return { + name: organisation.name, + department: organisation.department, + vatId: organisation.vatId, + }; + } + + fromUserToCommunicationDetails(user: User): CommunicationDetailsDTO { + return { + phone: user.phone_number, + mobile: user.mobile_number, + email: user.email, + }; + } + + fromUserToShippingAddressDTO(user: User): CheckoutShippingAddressDTO { + const deliveryDetails = user.delivery_addres; + + if (!deliveryDetails) { + throw Error('No Delivery Address set.'); + } + + return { + title: deliveryDetails.title, + gender: this.getGender(user.gender), + firstName: deliveryDetails.first_name, + lastName: deliveryDetails.last_name, + organisation: this.fromOrganisationToOrganisationDTO(user.organisation), + communicationDetails: this.fromUserToCommunicationDetails(user), + address: this.fromAddressToAddressDTO(deliveryDetails), + source: deliveryDetails.id, + }; + } } diff --git a/apps/sales/src/app/core/models/user.model.ts b/apps/sales/src/app/core/models/user.model.ts index a91647b7a..44ddf59ae 100644 --- a/apps/sales/src/app/core/models/user.model.ts +++ b/apps/sales/src/app/core/models/user.model.ts @@ -12,6 +12,7 @@ export interface User { email?: string; mobile_number?: string; phone_number?: string; + base_addres?: Address; delivery_addres?: Address; invoice_address?: Address; shop?: boolean; diff --git a/apps/sales/src/app/core/services/customer.service.ts b/apps/sales/src/app/core/services/customer.service.ts index 0c34e91f2..9cbd2c27c 100644 --- a/apps/sales/src/app/core/services/customer.service.ts +++ b/apps/sales/src/app/core/services/customer.service.ts @@ -1,6 +1,9 @@ import { Injectable } from '@angular/core'; import { QueryTokenDTO } from '@swagger/cat'; -import { CustomerService as CustomerApiService, PayerService } from '@swagger/crm'; +import { + CustomerService as CustomerApiService, + PayerService, +} from '@swagger/crm'; import { map, switchMap, catchError } from 'rxjs/operators'; import { Observable, of, combineLatest, BehaviorSubject } from 'rxjs'; import { CustomerMapping } from '../mappings/customer.mapping'; @@ -28,7 +31,11 @@ import { CustomerFilters } from '../../modules/customer'; }) export class CustomerService { addAddressError$ = new BehaviorSubject(null); - constructor(private customerService: CustomerApiService, private mapper: CustomerMapping, private payerService: PayerService) {} + constructor( + private customerService: CustomerApiService, + private mapper: CustomerMapping, + private payerService: PayerService + ) {} createCustomer(_customer: User): Observable { const customer: CustomerDTO = this.mapper.fromUser(_customer); @@ -97,7 +104,9 @@ export class CustomerService { filter?: CustomerFilters ): Observable { const noFilters = filter - ? isNullOrUndefined(filter.bonuscard) && isNullOrUndefined(filter.guestaccount) && isNullOrUndefined(filter.onlineshop) + ? isNullOrUndefined(filter.bonuscard) && + isNullOrUndefined(filter.guestaccount) && + isNullOrUndefined(filter.onlineshop) ? true : false : false; @@ -112,9 +121,15 @@ export class CustomerService { filter: filter && !noFilters ? { - ['bonuscard']: !isNullOrUndefined(filter.bonuscard) ? String(filter.bonuscard) : undefined, - ['guestaccount']: !isNullOrUndefined(filter.guestaccount) ? String(filter.guestaccount) : undefined, - ['onlineshop']: !isNullOrUndefined(filter.onlineshop) ? String(filter.onlineshop) : undefined, + ['bonuscard']: !isNullOrUndefined(filter.bonuscard) + ? String(filter.bonuscard) + : undefined, + ['guestaccount']: !isNullOrUndefined(filter.guestaccount) + ? String(filter.guestaccount) + : undefined, + ['onlineshop']: !isNullOrUndefined(filter.onlineshop) + ? String(filter.onlineshop) + : undefined, } : undefined, }; @@ -125,7 +140,9 @@ export class CustomerService { throw new Error(response.message); } return { - customers: response.result.map((t) => this.mapper.customerInfoDTOtoUser(t)), + customers: response.result.map((t) => + this.mapper.customerInfoDTOtoUser(t) + ), hits: response.hits, message: response.message, }; @@ -133,47 +150,62 @@ export class CustomerService { ); } - getCustomer(customer$: Observable): Observable { + getCustomer( + customer$: Observable + ): Observable { return customer$.pipe( map((response: ResponseArgsOfCustomerDTO) => { + console.log({ response }); if (response.error) { throw new Error(response.message); } return { - shippingAddresses: response.result.shippingAddresses.map((addressEnity) => addressEnity.id), + shippingAddresses: response.result.shippingAddresses.map( + (addressEnity) => addressEnity.id + ), user: this.mapper.customerDTOtoUser(response.result), }; }), switchMap((customerResult) => { const user = customerResult.user; - if (!customerResult.shippingAddresses || customerResult.shippingAddresses.length === 0) { + if ( + !customerResult.shippingAddresses || + customerResult.shippingAddresses.length === 0 + ) { return of(customerResult.user); } - const observablesOfShippingAddresses = customerResult.shippingAddresses.map((t) => { - return this.customerService.CustomerGetShippingaddress(t).pipe( - map((response) => { - if (response.error) { - throw new Error(response.message); - } - return response.result; - }) - ); - }); - const shippingAddresses$ = combineLatest(observablesOfShippingAddresses); + const observablesOfShippingAddresses = customerResult.shippingAddresses.map( + (t) => { + return this.customerService.CustomerGetShippingaddress(t).pipe( + map((response) => { + if (response.error) { + throw new Error(response.message); + } + return response.result; + }) + ); + } + ); + const shippingAddresses$ = combineLatest( + observablesOfShippingAddresses + ); return shippingAddresses$.pipe( switchMap((address: ShippingAddressDTO[]) => { const updatedUser = user; if (!!address) { const addresses = address.map((t) => { - return { ...this.mapper.fromShippingAddressDtoToAddress(t), synced: true }; + return { + ...this.mapper.fromShippingAddressDtoToAddress(t), + synced: true, + }; }); - const defaultAddresses = addresses.reduce((ad1, ad2) => { + const defaultAddress = addresses.reduce((ad1, ad2) => { if (ad1.defaultSince >= ad2.defaultSince) { return ad1; } return ad2; }); - updatedUser.delivery_addres = defaultAddresses; + updatedUser.delivery_addres = defaultAddress; updatedUser.poossible_delivery_addresses = addresses; } return of(updatedUser); @@ -182,30 +214,40 @@ export class CustomerService { }), switchMap((customer: User) => { const updateCustomer = customer; - return this.customerService.CustomerGetAssignedPayersByCustomerId(customer.id).pipe( - map((response) => { - if (response.error) { - throw new Error(response.message); - } - return { customer: customer, assignedPayers: response.result }; - }), - switchMap((response) => { - if (Array.isArray(response.assignedPayers) && response.assignedPayers.length > 0) { - const invoiceAddresses = response.assignedPayers.map((t) => { - return { ...this.mapper.fromAssignedPayerDtoToAddress(t), synced: true }; - }); - const defaultAddresses = invoiceAddresses.reduce((ad1, ad2) => { - if (ad1.defaultSince >= ad2.defaultSince) { - return ad1; - } - return ad2; - }); - updateCustomer.poossible_invoice_addresses = invoiceAddresses; - updateCustomer.invoice_address = defaultAddresses; - } - return of(updateCustomer); - }) - ); + return this.customerService + .CustomerGetAssignedPayersByCustomerId(customer.id) + .pipe( + map((response) => { + if (response.error) { + throw new Error(response.message); + } + return { customer: customer, assignedPayers: response.result }; + }), + switchMap((response) => { + if ( + Array.isArray(response.assignedPayers) && + response.assignedPayers.length > 0 + ) { + const invoiceAddresses = response.assignedPayers.map((t) => { + return { + ...this.mapper.fromAssignedPayerDtoToAddress(t), + synced: true, + }; + }); + const defaultAddress = invoiceAddresses.reduce((ad1, ad2) => { + if (ad1.defaultSince >= ad2.defaultSince) { + return ad1; + } + return ad2; + }); + updateCustomer.poossible_invoice_addresses = invoiceAddresses; + updateCustomer.invoice_address = defaultAddress; + } + + console.log({ updateCustomer }); + return of(updateCustomer); + }) + ); }) ); } @@ -223,7 +265,12 @@ export class CustomerService { if (response.error) { throw new Error(response.message); } - return { customers: response.result.map((t) => this.mapper.customerInfoDTOtoUser(t)), hits: 0 }; + return { + customers: response.result.map((t) => + this.mapper.customerInfoDTOtoUser(t) + ), + hits: 0, + }; }) ); } @@ -249,25 +296,32 @@ export class CustomerService { isDefault: true, }; if (shippingAddress.synced === true) { - return this.customerService.CustomerModifyShippingAddressFlag(params).pipe( - map((response) => { - if (response.error) { - throw new Error(response.message); - } - return response.result; - }) - ); + return this.customerService + .CustomerModifyShippingAddressFlag(params) + .pipe( + map((response) => { + if (response.error) { + throw new Error(response.message); + } + return response.result; + }) + ); } else { - return this.addShippingAddress(customerId, { ...shippingAddress, id: null }).pipe( + return this.addShippingAddress(customerId, { + ...shippingAddress, + id: null, + }).pipe( switchMap(() => { - return this.customerService.CustomerModifyShippingAddressFlag(params).pipe( - map((response) => { - if (response.error) { - throw new Error(response.message); - } - return response.result; - }) - ); + return this.customerService + .CustomerModifyShippingAddressFlag(params) + .pipe( + map((response) => { + if (response.error) { + throw new Error(response.message); + } + return response.result; + }) + ); }) ); } @@ -292,7 +346,10 @@ export class CustomerService { }) ); } else { - return this.addInvoiceAddress(customerId, { ...invoiceAddress, id: null }).pipe( + return this.addInvoiceAddress(customerId, { + ...invoiceAddress, + id: null, + }).pipe( switchMap((payerDto: PayerDTO) => { const params = { payerId: payerDto.id, @@ -316,7 +373,10 @@ export class CustomerService { if (!isNullOrUndefined(shippingAddress.id)) { const params = { shippingAddressId: shippingAddress.id, - shippingAddress: this.mapper.fromAddressToShippingAddressDTO(shippingAddress, !isNullOrUndefined(shippingAddress.id)), + shippingAddress: this.mapper.fromAddressToShippingAddressDTO( + shippingAddress, + !isNullOrUndefined(shippingAddress.id) + ), customerId: customerId, }; return this.customerService.CustomerUpdateShippingAddress(params).pipe( @@ -344,7 +404,10 @@ export class CustomerService { ); } else { const params = { - shippingAddress: this.mapper.fromAddressToShippingAddressDTO(shippingAddress, !isNullOrUndefined(shippingAddress.id)), + shippingAddress: this.mapper.fromAddressToShippingAddressDTO( + shippingAddress, + !isNullOrUndefined(shippingAddress.id) + ), customerId: customerId, }; return this.customerService.CustomerCreateShippingAddress(params).pipe( @@ -404,15 +467,17 @@ export class CustomerService { payerId: payerResponse.result.id, isDefault: true, }; - return this.customerService.CustomerAddPayerReference(referenceParamsparams).pipe( - map((response) => { - if (response.error) { - throw new Error(response.message); - } - this.addAddressError$.next(undefined); - return response.result.payer.data; - }) - ); + return this.customerService + .CustomerAddPayerReference(referenceParamsparams) + .pipe( + map((response) => { + if (response.error) { + throw new Error(response.message); + } + this.addAddressError$.next(undefined); + return response.result.payer.data; + }) + ); }) ); } else { @@ -450,7 +515,10 @@ export class CustomerService { if (response.error) { throw new Error(response.message); } - return response.result.map((t, index) => { index, id: t.id, key: t.isO3166_A_3, value: t.name }); + return response.result.map( + (t, index) => + { index, id: t.id, key: t.isO3166_A_3, value: t.name } + ); }) ); } diff --git a/apps/sales/src/app/core/store/state/app.state.ts b/apps/sales/src/app/core/store/state/app.state.ts index c7127f5bd..67f76bb97 100644 --- a/apps/sales/src/app/core/store/state/app.state.ts +++ b/apps/sales/src/app/core/store/state/app.state.ts @@ -10,7 +10,10 @@ import { import { LoadBranches, LoadUserBranch } from '../actions/branch.actions'; import { BranchSelectors } from '../selectors/branch.selector'; import { isNullOrUndefined } from 'util'; -import { RemoveProcessNewState, ReloadProcessData } from '../actions/process.actions'; +import { + RemoveProcessNewState, + ReloadProcessData, +} from '../actions/process.actions'; import { UserStateService } from '../../services/user-state.service'; import { UserStateSyncData } from '../../models/user-state-sync.model'; import { ReloadCustomersData } from '../actions/customer.actions'; @@ -20,7 +23,7 @@ import { ReloadProductsData } from '../actions/product.actions'; import { ReloadBreadcrumbsData } from '../actions/breadcrumb.actions'; import { Router } from '@angular/router'; import { Subject } from 'rxjs'; -import { debounceTime, distinctUntilChanged, switchMap, tap } from 'rxjs/operators'; +import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; import { ModuleSwitcher } from '../../models/app-switcher.enum'; import { ModuleSwitcherService } from '../../services/module-switcher.service'; import { ReloadFiltersData } from '../actions/filter.actions'; @@ -31,7 +34,7 @@ import { ReloadRemission } from '../actions/remission.actions'; import { ReloadFormState } from '../actions/forms.actions'; import { FILIALE_LANDING_PAGE } from '../../utils/app.constants'; -export const SYNC_DATA_VERSION = 210; +export const SYNC_DATA_VERSION = 211; export class AppStateModel { currentProcesssId: number; @@ -101,9 +104,13 @@ export class AppState { } @Action(AppSetCurrentProcess) - appSetCurrentProcess(ctx: StateContext, { payload }: AppSetCurrentProcess) { + appSetCurrentProcess( + ctx: StateContext, + { payload }: AppSetCurrentProcess + ) { const state = ctx.getState(); - const processExists = state.processIds.findIndex((t) => t === payload) !== -1; + const processExists = + state.processIds.findIndex((t) => t === payload) !== -1; if (processExists) { ctx.patchState({ currentProcesssId: payload, @@ -115,18 +122,23 @@ export class AppState { @Action(AppAddProcess) appAddProcess(ctx: StateContext, { payload }: AppAddProcess) { const state = ctx.getState(); - const processExists = state.processIds.findIndex((t) => t === payload) !== -1; + const processExists = + state.processIds.findIndex((t) => t === payload) !== -1; if (!processExists) { const processIds = [...state.processIds, payload]; const currentProcesssId = payload; ctx.patchState({ currentProcesssId, processIds }); - const branchesLoaded = this.store.selectSnapshot(BranchSelectors.getBranches); + const branchesLoaded = this.store.selectSnapshot( + BranchSelectors.getBranches + ); if (!branchesLoaded || Object.keys(branchesLoaded).length === 0) { this.store.dispatch(new LoadBranches()); } - const userBranch = this.store.selectSnapshot(BranchSelectors.getUserBranch); + const userBranch = this.store.selectSnapshot( + BranchSelectors.getUserBranch + ); if (isNullOrUndefined(userBranch)) { this.store.dispatch(new LoadUserBranch()); } @@ -136,7 +148,10 @@ export class AppState { } @Action(AppDeleteProcess) - appDeleteProcess(ctx: StateContext, { payload }: AppDeleteProcess) { + appDeleteProcess( + ctx: StateContext, + { payload }: AppDeleteProcess + ) { const state = ctx.getState(); const currentIds = state.processIds; if (currentIds) { @@ -147,7 +162,10 @@ export class AppState { } @Action(AppSwitchModule) - appSwitchModule(ctx: StateContext, { payload }: AppSwitchModule) { + appSwitchModule( + ctx: StateContext, + { payload }: AppSwitchModule + ) { const state = ctx.getState(); ctx.patchState({ activeModule: payload }); this.syncApiState(state.processIds, payload); @@ -157,7 +175,10 @@ export class AppState { * Save store data on backend */ @Action(AppUserDataSync) - appUserDataSynced(ctx: StateContext, { data, sync }: AppUserDataSync) { + appUserDataSynced( + ctx: StateContext, + { data, sync }: AppUserDataSync + ) { const state = ctx.getState(); let currentUserData: UserStateSyncData = {}; @@ -184,7 +205,10 @@ export class AppState { * Initial store loading from API, triggered once on page load */ @Action(ReloadSavedState) - reloadSavedState(ctx: StateContext, { data, sync }: ReloadSavedState) { + reloadSavedState( + ctx: StateContext, + { data, sync }: ReloadSavedState + ) { const state = ctx.getState(); let currentUserData: UserStateSyncData = {}; @@ -208,7 +232,10 @@ export class AppState { if (sync && syncedData.version === SYNC_DATA_VERSION) { this.reloadDataFromAPI(syncedData); - if (syncedData.currentProcesssId || syncedData.activeModule === ModuleSwitcher.Branch) { + if ( + syncedData.currentProcesssId || + syncedData.activeModule === ModuleSwitcher.Branch + ) { ctx.patchState({ ...state, synced: true, @@ -235,11 +262,19 @@ export class AppState { return; } if (data.customers) { - this.store.dispatch(new ReloadCustomersData(data.customers, data.lastCreatedCustomerId, data.cachedCustomerSearch)); + this.store.dispatch( + new ReloadCustomersData( + data.customers, + data.lastCreatedCustomerId, + data.cachedCustomerSearch + ) + ); } if (data.products) { - this.store.dispatch(new ReloadProductsData(data.products, data.cachedProductResults)); + this.store.dispatch( + new ReloadProductsData(data.products, data.cachedProductResults) + ); } if (data.carts) { @@ -259,7 +294,9 @@ export class AppState { } if (data.processes) { - this.store.dispatch(new ReloadProcessData(data.processes, data.recentArticles)); + this.store.dispatch( + new ReloadProcessData(data.processes, data.recentArticles) + ); } if (data.formsState) { @@ -267,11 +304,20 @@ export class AppState { } if (data.activeModule === ModuleSwitcher.Customer) { - if (data.processes && data.currentProcesssId && data.processes[data.currentProcesssId]) { + if ( + data.processes && + data.currentProcesssId && + data.processes[data.currentProcesssId] + ) { const currentProcesssId = data.currentProcesssId; const currentRoute = data.processes[currentProcesssId].currentRoute; if (currentRoute && currentRoute.length > 0) { - this.routingAvailableAction(data, currentProcesssId, currentRoute, data.activeModule); + this.routingAvailableAction( + data, + currentProcesssId, + currentRoute, + data.activeModule + ); } else { this.router.navigate(['/dashboard']); } @@ -283,7 +329,12 @@ export class AppState { const currentProcesssId = -1; const currentRoute = data.branchProcess.currentRoute; if (currentRoute && currentRoute.length > 0) { - this.routingAvailableAction(data, currentProcesssId, currentRoute, data.activeModule); + this.routingAvailableAction( + data, + currentProcesssId, + currentRoute, + data.activeModule + ); } else { this.router.navigate([FILIALE_LANDING_PAGE]); } @@ -297,11 +348,24 @@ export class AppState { } if (data.activeModule === ModuleSwitcher.Branch) { - this.moduleSwitcherService.switch(ModuleSwitcher.Branch, data.branchProcess); + this.moduleSwitcherService.switch( + ModuleSwitcher.Branch, + data.branchProcess + ); } - if (data.processesBreadcrumbs && data.activeCrumbs && (data.currentProcesssId || data.activeModule === ModuleSwitcher.Branch)) { - this.store.dispatch(new ReloadBreadcrumbsData(data.processesBreadcrumbs, data.activeCrumbs, data.previusMenuPath)); + if ( + data.processesBreadcrumbs && + data.activeCrumbs && + (data.currentProcesssId || data.activeModule === ModuleSwitcher.Branch) + ) { + this.store.dispatch( + new ReloadBreadcrumbsData( + data.processesBreadcrumbs, + data.activeCrumbs, + data.previusMenuPath + ) + ); } if (data.filters && data.processesSelectedFilters && data.dropdownFilters) { @@ -327,16 +391,28 @@ export class AppState { ); } - private routingAvailableAction(data: UserStateSyncData, currentProcesssId: number, currentRoute: string, module: ModuleSwitcher) { - const hasActiveCrumbsAvailableForProcess = data.activeCrumbs && data.activeCrumbs[currentProcesssId]; + private routingAvailableAction( + data: UserStateSyncData, + currentProcesssId: number, + currentRoute: string, + module: ModuleSwitcher + ) { + const hasActiveCrumbsAvailableForProcess = + data.activeCrumbs && data.activeCrumbs[currentProcesssId]; const activeCrumbs = data.activeCrumbs[currentProcesssId]; - const hasProcessBreadcrumbsAvailableForProcess = data.processesBreadcrumbs && data.processesBreadcrumbs[activeCrumbs]; + const hasProcessBreadcrumbsAvailableForProcess = + data.processesBreadcrumbs && data.processesBreadcrumbs[activeCrumbs]; const breadcrumb = hasProcessBreadcrumbsAvailableForProcess - ? data.processesBreadcrumbs[activeCrumbs].find((t) => t.processId === currentProcesssId) + ? data.processesBreadcrumbs[activeCrumbs].find( + (t) => t.processId === currentProcesssId + ) : null; - const breadcrumbPath = breadcrumb && breadcrumb.breadcrumbs ? breadcrumb.breadcrumbs.find((t) => t && t.path === currentRoute) : null; + const breadcrumbPath = + breadcrumb && breadcrumb.breadcrumbs + ? breadcrumb.breadcrumbs.find((t) => t && t.path === currentRoute) + : null; if ( hasActiveCrumbsAvailableForProcess && diff --git a/apps/sales/src/app/core/store/state/cart.state.ts b/apps/sales/src/app/core/store/state/cart.state.ts index c85df1fcb..80af36620 100644 --- a/apps/sales/src/app/core/store/state/cart.state.ts +++ b/apps/sales/src/app/core/store/state/cart.state.ts @@ -1,16 +1,26 @@ import { State, Action, StateContext, Store, Selector } from '@ngxs/store'; import * as actions from '../actions/cart.actions'; -import { AddCartToProcess, SetFinishedOrderData, ChangeCurrentRoute } from '../actions/process.actions'; +import { + AddCartToProcess, + SetFinishedOrderData, + ChangeCurrentRoute, +} from '../actions/process.actions'; import { DeleteCartEntry } from '../actions/cart-entry.actions'; import { ProcessSelectors } from '../selectors/process.selectors'; import { CheckoutService } from '../../services/checkout.service'; import { tap, catchError } from 'rxjs/operators'; -import { ShoppingCartDTO, PaymentDTO, CheckoutDTO, BuyerDTO, PayerDTO } from '@swagger/checkout'; +import { + ShoppingCartDTO, + PaymentDTO, + CheckoutDTO, + BuyerDTO, + PayerDTO, + DestinationDTO, +} from '@swagger/checkout'; import { DisplayOrderDTO, EnvironmentChannel } from '@swagger/oms'; import { User } from '../../models/user.model'; import { CustomerMapping } from '../../mappings/customer.mapping'; import { OrganisationDTO } from '@swagger/crm'; -import { DestinationDTO } from '@swagger/checkout'; import { UserStateSyncData } from '../../models/user-state-sync.model'; import { AppUserDataSync } from '../actions/app.actions'; import { of } from 'rxjs'; @@ -48,7 +58,10 @@ export class CartState { } @Action(actions.SetCartToProcess) - setCartToProcess(ctx: StateContext, {}: actions.SetCartToProcess) { + setCartToProcess( + ctx: StateContext, + {}: actions.SetCartToProcess + ) { return this.checkoutService.createCart().pipe( tap((cart: ShoppingCartDTO) => { const state = ctx.getState(); @@ -62,28 +75,41 @@ export class CartState { } @Action(actions.SetCartData) - addItemToCart(ctx: StateContext, { cartEntryId }: actions.SetCartData) { + addItemToCart( + ctx: StateContext, + { cartEntryId }: actions.SetCartData + ) { const state = ctx.getState(); - const currentProcess = this.store.selectSnapshot(ProcessSelectors.getCurrentProcess); + const currentProcess = this.store.selectSnapshot( + ProcessSelectors.getCurrentProcess + ); if (!currentProcess) { return; } const carts = { ...state.carts }; - carts[currentProcess.cartId] = [...carts[currentProcess.cartId], cartEntryId]; + carts[currentProcess.cartId] = [ + ...carts[currentProcess.cartId], + cartEntryId, + ]; ctx.patchState({ carts }); this.syncApiState(carts); } @Action(actions.DeleteProductFromCart) - deleteProductFromCart(ctx: StateContext, { cartId, cartEntryId }: actions.DeleteProductFromCart) { + deleteProductFromCart( + ctx: StateContext, + { cartId, cartEntryId }: actions.DeleteProductFromCart + ) { const state = ctx.getState(); const allCarts = { ...state.carts }; const cartEntries = allCarts[cartId]; // Remove product from - const productToDelete = cartEntries.find((entryId: number) => entryId === cartEntryId); + const productToDelete = cartEntries.find( + (entryId: number) => entryId === cartEntryId + ); if (productToDelete) { this.store.dispatch(new DeleteCartEntry(cartEntryId, true)); } @@ -99,7 +125,10 @@ export class CartState { } @Action(actions.DeleteCart) - deleteCart(ctx: StateContext, { cartId }: actions.DeleteCart) { + deleteCart( + ctx: StateContext, + { cartId }: actions.DeleteCart + ) { const state = ctx.getState(); const carts = { ...state.carts }; const cartEntries = carts[cartId]; @@ -122,16 +151,26 @@ export class CartState { } @Action(actions.CreateOrder) - createOrder(ctx: StateContext, { checkoutId }: actions.CreateOrder) { + createOrder( + ctx: StateContext, + { checkoutId }: actions.CreateOrder + ) { return this.checkoutService.createOrder(checkoutId).pipe( - tap((order: { failedItemIds: { id: number; type: number }[]; displayOrder: DisplayOrderDTO[] }) => { - this.store.dispatch(new SetFinishedOrderData(order)); - }), + tap( + (order: { + failedItemIds: { id: number; type: number }[]; + displayOrder: DisplayOrderDTO[]; + }) => { + this.store.dispatch(new SetFinishedOrderData(order)); + } + ), catchError((error) => { const status = error.status; const message = error && error.error ? error.error.message : undefined; const invalidProperties = - error && error.error && error.error.invalidProperties ? JSON.stringify(error.error.invalidProperties) : undefined; + error && error.error && error.error.invalidProperties + ? JSON.stringify(error.error.invalidProperties) + : undefined; this.errorService.addErrors(status, message, invalidProperties); this.openCart(); return of(undefined); @@ -151,63 +190,104 @@ export class CartState { } @Action(actions.SetPaymentTypeToCheckout) - getPaymentToCheckout(ctx: StateContext, { checkoutId, customer, isDelivery }: actions.SetPaymentTypeToCheckout) { + getPaymentToCheckout( + ctx: StateContext, + { checkoutId, customer, isDelivery }: actions.SetPaymentTypeToCheckout + ) { return this.checkoutService.getPayments(checkoutId).pipe( tap((payment: PaymentDTO) => { const type = payment.availablePaymentTypes[0].key; - this.store.dispatch(new actions.SetPaymentToCheckout(checkoutId, type, customer, isDelivery)); + this.store.dispatch( + new actions.SetPaymentToCheckout( + checkoutId, + type, + customer, + isDelivery + ) + ); }) ); } @Action(actions.SetPaymentToCheckout) - setPaymentToCheckout(ctx: StateContext, { checkoutId, type, customer, isDelivery }: actions.SetPaymentToCheckout) { + setPaymentToCheckout( + ctx: StateContext, + { checkoutId, type, customer, isDelivery }: actions.SetPaymentToCheckout + ) { return this.checkoutService.setPaymentType(checkoutId, type).pipe( tap((checkout: CheckoutDTO) => { - this.store.dispatch(new actions.SetBuyerToCheckout(checkout.id, customer, isDelivery)); + this.store.dispatch( + new actions.SetBuyerToCheckout(checkout.id, customer, isDelivery) + ); }) ); } @Action(actions.SetBuyerToCheckout) - setBuyerToCheckout(ctx: StateContext, { checkoutId, customer, isDelivery }: actions.SetBuyerToCheckout) { - return this.checkoutService.setBuyer(checkoutId, this.buyerObject(customer)).pipe( - tap((checkout: CheckoutDTO) => { - if (!isDelivery) { - this.store.dispatch(new actions.CreateOrder(checkout.id)); - } else { - this.store.dispatch(new actions.SetPayerToCheckout(checkout.id, customer)); - } - }) - ); + setBuyerToCheckout( + ctx: StateContext, + { checkoutId, customer, isDelivery }: actions.SetBuyerToCheckout + ) { + return this.checkoutService + .setBuyer(checkoutId, this.buyerObject(customer)) + .pipe( + tap((checkout: CheckoutDTO) => { + if (!isDelivery) { + this.store.dispatch(new actions.CreateOrder(checkout.id)); + } else { + this.store.dispatch( + new actions.SetPayerToCheckout(checkout.id, customer) + ); + } + }) + ); } @Action(actions.SetPayerToCheckout) - setPayerToCheckout(ctx: StateContext, { checkoutId, customer }: actions.SetPayerToCheckout) { - return this.checkoutService.setPayer(checkoutId, this.payerObject(customer)).pipe( - tap((checkout: CheckoutDTO) => { - this.store.dispatch(new actions.CreateOrder(checkout.id)); - }) - ); + setPayerToCheckout( + ctx: StateContext, + { checkoutId, customer }: actions.SetPayerToCheckout + ) { + return this.checkoutService + .setPayer(checkoutId, this.payerObject(customer)) + .pipe( + tap((checkout: CheckoutDTO) => { + this.store.dispatch(new actions.CreateOrder(checkout.id)); + }) + ); } @Action(actions.SetDestinationToCheckout) setDestinationToCheckout( ctx: StateContext, - { checkoutId, destinationId, customer, target }: actions.SetDestinationToCheckout + { + checkoutId, + destinationId, + customer, + target, + }: actions.SetDestinationToCheckout ) { const dest = this.destinationObject(customer, destinationId, target); return this.checkoutService.setDestination(checkoutId, destinationId, dest); } @Action(actions.ReloadCartData) - reloadCarts(ctx: StateContext, { carts }: actions.ReloadCartData) { + reloadCarts( + ctx: StateContext, + { carts }: actions.ReloadCartData + ) { ctx.setState({ carts: { ...carts } }); } @Action(actions.SetNotificationChannel) - setNotificationChannel(ctx: StateContext, { checkoutId, notificationChannel }: actions.SetNotificationChannel) { - return this.checkoutService.setNotificationChannel(checkoutId, notificationChannel); + setNotificationChannel( + ctx: StateContext, + { checkoutId, notificationChannel }: actions.SetNotificationChannel + ) { + return this.checkoutService.setNotificationChannel( + checkoutId, + notificationChannel + ); } private syncApiState(carts: { [key: number]: number[] }) { @@ -239,7 +319,9 @@ export class CartState { } private payerObject(customer: User) { - const invoice = customer.invoice_address ? customer.invoice_address : customer.delivery_addres; + const invoice = customer.invoice_address + ? customer.invoice_address + : customer.delivery_addres; const transformed = this.customerMapper.fromUser(customer); let organisation: OrganisationDTO = {}; @@ -274,25 +356,27 @@ export class CartState { return payerDTO; } - private destinationObject(customer: User, destinationId: number, target?: EnvironmentChannel) { + private destinationObject( + customer: User, + destinationId: number, + target?: EnvironmentChannel + ) { const delivery = customer.delivery_addres; if (!delivery) { this.cartService.addOrderErrorEvent(); throw new Error( - `Delvery address is missing for customer: ${customer.first_name + ' ' + customer.last_name} when trying to set destination object. + `Delvery address is missing for customer: ${ + customer.first_name + ' ' + customer.last_name + } when trying to set destination object. Source => cart.state.ts.destinationObject. Line 238` ); } - const transformed = this.customerMapper.fromUser(customer); + const shippingAddress = this.customerMapper.fromUserToShippingAddressDTO( + customer + ); + const destinationDTO: DestinationDTO = { - shippingAddress: { - gender: this.customerMapper.getGender(delivery.gender), - communicationDetails: transformed.communicationDetails, - firstName: delivery.first_name, - lastName: delivery.last_name, - address: transformed.address, - source: delivery.id, - }, + shippingAddress, target: target ? target : 2, id: destinationId, }; diff --git a/apps/sales/src/app/modules/cart/components/delivery-cart/delivery-cart.component.ts b/apps/sales/src/app/modules/cart/components/delivery-cart/delivery-cart.component.ts index 403e383bc..5fe707e69 100644 --- a/apps/sales/src/app/modules/cart/components/delivery-cart/delivery-cart.component.ts +++ b/apps/sales/src/app/modules/cart/components/delivery-cart/delivery-cart.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit, - ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy, Output, @@ -25,8 +24,12 @@ import { AddBreadcrumb } from '../../../../core/store/actions/breadcrumb.actions import { SharedSelectors } from '../../../../core/store/selectors/shared.selectors'; import { Observable, Subject } from 'rxjs'; import { ProcessCart } from '../../../../core/models/process-cart.model'; -import { map, filter, take, takeUntil } from 'rxjs/operators'; -import { deliveryFilter, CartReviewItem, cartToCartReviewArray } from '../../pages/cart-review/cart-review.component'; +import { map, filter, takeUntil } from 'rxjs/operators'; +import { + deliveryFilter, + CartReviewItem, + cartToCartReviewArray, +} from '../../pages/cart-review/cart-review.component'; import { Address } from '../../../../core/models/user.model'; import { isArrayMinLength } from '../../../../core/utils/app.utils'; import { DeleteProductFromCart } from 'apps/sales/src/app/core/store/actions/cart.actions'; @@ -49,7 +52,11 @@ export class DeliveryCartComponent implements OnInit, OnDestroy { lastDeletedItemIndex = -1; destroy$ = new Subject(); - constructor(private store: Store, private router: Router, private cdr: ChangeDetectorRef) {} + constructor( + private store: Store, + private router: Router, + private cdr: ChangeDetectorRef + ) {} ngOnInit() { this.delivery$ = this.cartData$.pipe( @@ -87,7 +94,14 @@ export class DeliveryCartComponent implements OnInit, OnDestroy { } const customer = cart.customer; if (customer.delivery_addres) { - const { first_name, last_name, street, streetNo, zip, city } = customer.delivery_addres; + const { + first_name, + last_name, + street, + streetNo, + zip, + city, + } = customer.delivery_addres; this.deliveryAddress = `${first_name} ${last_name} | ${street} ${streetNo}, ${zip} ${city}`; } this.detectChanges(); @@ -111,7 +125,9 @@ export class DeliveryCartComponent implements OnInit, OnDestroy { this.store.dispatch(new SetDetailsCustomer(customerId)); this.store.dispatch(new ChangeCurrentRoute(currentRoute)); this.store.dispatch(new AddBreadcrumb(newBread, 'shoppingCart')); - this.router.navigate([currentRoute], { queryParams: { cart: true, notEditable: true } }); + this.router.navigate([currentRoute], { + queryParams: { cart: true, notEditable: true }, + }); } } @@ -120,7 +136,10 @@ export class DeliveryCartComponent implements OnInit, OnDestroy { this.store.dispatch( new AddBreadcrumb( { - name: item.product.name ? item.product.name.substring(0, 12) + (item.product.name.length > 12 ? '...' : '') : '', + name: item.product.name + ? item.product.name.substring(0, 12) + + (item.product.name.length > 12 ? '...' : '') + : '', path: '/product/details/' + item.id, }, 'product' @@ -133,12 +152,18 @@ export class DeliveryCartComponent implements OnInit, OnDestroy { } validateDeliveryAddress(processCart) { - const deliveryExist = processCart.cart.some((item: Cart) => item.deliveryType === DeliveryOption.DELIVERY); + const deliveryExist = processCart.cart.some( + (item: Cart) => item.deliveryType === DeliveryOption.DELIVERY + ); const missingAddress = - processCart.customer && (!this.isAddressSet(processCart.customer.delivery_addres) || !processCart.customer.email); + processCart.customer && + (!this.isAddressSet(processCart.customer.delivery_addres) || + !processCart.customer.email); if (deliveryExist && missingAddress) { - this.store.dispatch(new UpdateCustomerFormState(CustomerFormState.MISSING_DELIVERY)); + this.store.dispatch( + new UpdateCustomerFormState(CustomerFormState.MISSING_DELIVERY) + ); const currentRoute = `customer/search/missing-data/${processCart.customer.id}`; this.store.dispatch(new ChangeCurrentRoute(currentRoute)); this.router.navigate([currentRoute], { queryParams: { card: 'create' } }); @@ -169,20 +194,29 @@ export class DeliveryCartComponent implements OnInit, OnDestroy { } getDeleteAnimation(index: number) { - const animation = index >= this.lastDeletedItemIndex && this.lastDeletedItemIndex !== -1 ? 'delete' : ''; + const animation = + index >= this.lastDeletedItemIndex && this.lastDeletedItemIndex !== -1 + ? 'delete' + : ''; return animation; } deleteItem(item: CartReviewItem, index: number) { this.lastDeletedItemIndex = index; if (item) { - this.store.dispatch(new DeleteProductFromCart(item.cartId, item.cartEntryId)); + this.store.dispatch( + new DeleteProductFromCart(item.cartId, item.cartEntryId) + ); } } detectChanges() { setTimeout(() => { - if (this.cdr !== null && this.cdr !== undefined && !(this.cdr as ViewRef).destroyed) { + if ( + this.cdr !== null && + this.cdr !== undefined && + !(this.cdr as ViewRef).destroyed + ) { this.cdr.detectChanges(); } }, 0); diff --git a/apps/sales/src/app/modules/cart/components/pay-method/pay-method.component.ts b/apps/sales/src/app/modules/cart/components/pay-method/pay-method.component.ts index 9514b3685..dd75f52ae 100644 --- a/apps/sales/src/app/modules/cart/components/pay-method/pay-method.component.ts +++ b/apps/sales/src/app/modules/cart/components/pay-method/pay-method.component.ts @@ -1,7 +1,10 @@ import { Component, OnInit, OnDestroy, Input } from '@angular/core'; import { ModalService, ButtonComponent } from '@libs/ui'; import { Breadcrumb } from '../../../../core/models/breadcrumb.model'; -import { ChangeCurrentRoute, EmptyFinishedOrders } from '../../../../core/store/actions/process.actions'; +import { + ChangeCurrentRoute, + EmptyFinishedOrders, +} from '../../../../core/store/actions/process.actions'; import { Store, Select } from '@ngxs/store'; import { Router } from '@angular/router'; import { AddBreadcrumb } from '../../../../core/store/actions/breadcrumb.actions'; @@ -10,8 +13,15 @@ import { ProcessSelectors } from '../../../../core/store/selectors/process.selec import { Observable, Subject, of, forkJoin } from 'rxjs'; import { takeUntil, switchMap, filter, map } from 'rxjs/operators'; import { CheckoutService } from '../../../../core/services/checkout.service'; -import { CheckoutDTO, EntityDTOContainerOfDestinationDTO } from '@swagger/checkout'; -import { SetPaymentTypeToCheckout, SetDestinationToCheckout, SetNotificationChannel } from '../../../../core/store/actions/cart.actions'; +import { + CheckoutDTO, + EntityDTOContainerOfDestinationDTO, +} from '@swagger/checkout'; +import { + SetPaymentTypeToCheckout, + SetDestinationToCheckout, + SetNotificationChannel, +} from '../../../../core/store/actions/cart.actions'; import { User } from '../../../../core/models/user.model'; import { CustomerSelectors } from 'apps/sales/src/app/core/store/selectors/customer.selectors'; import { isNullOrUndefined } from 'util'; @@ -99,19 +109,32 @@ export class PayMethodComponent implements OnInit, OnDestroy { return this.checkoutService.createCheckout(this.cartId).pipe( takeUntil(this.destroy$), switchMap((checkout: CheckoutDTO) => { - return this.setNotificationChannel(checkout, this.customer, this.delivery || this.download); + return this.setNotificationChannel( + checkout, + this.customer, + this.delivery || this.download + ); }), switchMap((response) => { + console.log({ customer: this.customer }); if (this.delivery || this.download) { const deliveryShippingDestionation = response.checkout.destinations.find( - (dest: EntityDTOContainerOfDestinationDTO) => this.delivery && dest.data.target === 2 + (dest: EntityDTOContainerOfDestinationDTO) => + this.delivery && dest.data.target === 2 ); const downloadShippingDestionation = response.checkout.destinations.find( - (dest: EntityDTOContainerOfDestinationDTO) => this.download && dest.data.target === 16 + (dest: EntityDTOContainerOfDestinationDTO) => + this.download && dest.data.target === 16 ); if (!deliveryShippingDestionation && !downloadShippingDestionation) { return forkJoin( - this.store.dispatch(new SetPaymentTypeToCheckout(response.checkout.id, this.customer, response.delivery)), + this.store.dispatch( + new SetPaymentTypeToCheckout( + response.checkout.id, + this.customer, + response.delivery + ) + ), of({ checkout: response.checkout, delivery: response.delivery, @@ -122,12 +145,13 @@ export class PayMethodComponent implements OnInit, OnDestroy { ); } if (deliveryShippingDestionation && !downloadShippingDestionation) { + // TODO HERE TTHE ERROR HAPPENS return forkJoin( this.store.dispatch( new SetDestinationToCheckout( response.checkout.id, deliveryShippingDestionation.id, - response.customer, + this.customer, deliveryShippingDestionation.data.target ) ), @@ -139,13 +163,16 @@ export class PayMethodComponent implements OnInit, OnDestroy { downloadDestinationDTO: undefined, }) ); - } else if (!deliveryShippingDestionation && downloadShippingDestionation) { + } else if ( + !deliveryShippingDestionation && + downloadShippingDestionation + ) { return forkJoin( this.store.dispatch( new SetDestinationToCheckout( response.checkout.id, downloadShippingDestionation.id, - response.customer, + this.customer, downloadShippingDestionation.data.target ) ), @@ -157,13 +184,16 @@ export class PayMethodComponent implements OnInit, OnDestroy { downloadDestinationDTO: undefined, }) ); - } else if (deliveryShippingDestionation && downloadShippingDestionation) { + } else if ( + deliveryShippingDestionation && + downloadShippingDestionation + ) { return forkJoin( this.store.dispatch( new SetDestinationToCheckout( response.checkout.id, deliveryShippingDestionation.id, - response.customer, + this.customer, deliveryShippingDestionation.data.target ) ), @@ -177,7 +207,13 @@ export class PayMethodComponent implements OnInit, OnDestroy { ); } else { return forkJoin( - this.store.dispatch(new SetPaymentTypeToCheckout(response.checkout.id, this.customer, response.delivery)), + this.store.dispatch( + new SetPaymentTypeToCheckout( + response.checkout.id, + this.customer, + response.delivery + ) + ), of({ checkout: response.checkout, delivery: response.delivery, @@ -189,7 +225,13 @@ export class PayMethodComponent implements OnInit, OnDestroy { } } else { return forkJoin( - this.store.dispatch(new SetPaymentTypeToCheckout(response.checkout.id, this.customer, response.delivery)), + this.store.dispatch( + new SetPaymentTypeToCheckout( + response.checkout.id, + this.customer, + response.delivery + ) + ), of({ checkout: response.checkout, delivery: response.delivery, @@ -202,8 +244,19 @@ export class PayMethodComponent implements OnInit, OnDestroy { }), switchMap(([, data]) => { if (data.finished) { - return forkJoin(of({}), of({ checkout: data.checkout, delivery: data.delivery, finished: true })); - } else if (!data.finished && data.downloadDestinationNedded && !isNullOrUndefined(data.downloadDestinationDTO)) { + return forkJoin( + of({}), + of({ + checkout: data.checkout, + delivery: data.delivery, + finished: true, + }) + ); + } else if ( + !data.finished && + data.downloadDestinationNedded && + !isNullOrUndefined(data.downloadDestinationDTO) + ) { return forkJoin( this.store.dispatch( new SetDestinationToCheckout( @@ -213,12 +266,26 @@ export class PayMethodComponent implements OnInit, OnDestroy { data.downloadDestinationDTO.target ) ), - of({ checkout: data.checkout, delivery: data.delivery, finished: false }) + of({ + checkout: data.checkout, + delivery: data.delivery, + finished: false, + }) ); } else { return forkJoin( - this.store.dispatch(new SetPaymentTypeToCheckout(data.checkout.id, this.customer, data.delivery)), - of({ checkout: data.checkout, delivery: data.delivery, finished: true }) + this.store.dispatch( + new SetPaymentTypeToCheckout( + data.checkout.id, + this.customer, + data.delivery + ) + ), + of({ + checkout: data.checkout, + delivery: data.delivery, + finished: true, + }) ); } }), @@ -226,7 +293,13 @@ export class PayMethodComponent implements OnInit, OnDestroy { if (data.finished) { return of({}); } else { - return this.store.dispatch(new SetPaymentTypeToCheckout(data.checkout.id, this.customer, data.delivery)); + return this.store.dispatch( + new SetPaymentTypeToCheckout( + data.checkout.id, + this.customer, + data.delivery + ) + ); } }) ); @@ -251,13 +324,17 @@ export class PayMethodComponent implements OnInit, OnDestroy { customer: User, delivery: boolean ): Observable<{ checkout: CheckoutDTO; customer: User; delivery: boolean }> { - const user: User = this.store.selectSnapshot(CustomerSelectors.getCurrentProcessActiveUser); - const notificationChannel = this.customerMap.getNotificationChannels(user); - return this.store.dispatch(new SetNotificationChannel(checkout.id, notificationChannel)).pipe( - map(() => { - return { checkout, customer, delivery }; - }) + const user: User = this.store.selectSnapshot( + CustomerSelectors.getCurrentProcessActiveUser ); + const notificationChannel = this.customerMap.getNotificationChannels(user); + return this.store + .dispatch(new SetNotificationChannel(checkout.id, notificationChannel)) + .pipe( + map(() => { + return { checkout, customer, delivery }; + }) + ); } ngOnDestroy() { diff --git a/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts b/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts index 5e5f5cc41..0773cad26 100644 --- a/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts +++ b/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts @@ -1,4 +1,11 @@ -import { Component, OnInit, Input, AfterViewInit, ViewChild, OnDestroy } from '@angular/core'; +import { + Component, + OnInit, + Input, + AfterViewInit, + ViewChild, + OnDestroy, +} from '@angular/core'; import { Router } from '@angular/router'; import { Store, Select } from '@ngxs/store'; import { Observable, Subject } from 'rxjs'; @@ -8,34 +15,50 @@ import { SearchInputComponent } from '@libs/ui'; import { Process } from '../../../../core/models/process.model'; import { Breadcrumb } from '../../../../core/models/breadcrumb.model'; import { AddBreadcrumb } from '../../../../core/store/actions/breadcrumb.actions'; -import { AddProcess, ChangeCurrentRoute, AddCustomerSearch } from '../../../../core/store/actions/process.actions'; +import { + AddProcess, + ChangeCurrentRoute, + AddCustomerSearch, +} from '../../../../core/store/actions/process.actions'; import { SharedSelectors } from '../../../../core/store/selectors/shared.selectors'; import { CustomerSearchResult } from '../../../../core/models/customer-search-result.model'; import { AppState } from 'apps/sales/src/app/core/store/state/app.state'; import { CustomerService } from 'apps/sales/src/app/core/services/customer.service'; import { CustomerSearchResponse } from 'apps/sales/src/app/core/models/customer-search-response.model'; import { CUSTOMER_SCROLL_INDEX } from 'apps/sales/src/app/core/utils/app.constants'; -import { ClearCachedCustomers, SetCachedCustomers } from 'apps/sales/src/app/core/store/actions/customer.actions'; +import { + ClearCachedCustomers, + SetCachedCustomers, +} from 'apps/sales/src/app/core/store/actions/customer.actions'; import { CustomerFeatures } from 'apps/sales/src/app/core/models/customer-features.model'; import { CustomerSearchEmptyModalComponent } from '../customer-search-empty-modal/customer-search-empty-modal.component'; @Component({ selector: 'app-search-customer-card', templateUrl: './customer-search-card.component.html', - styleUrls: ['./customer-search-card.component.scss'] + styleUrls: ['./customer-search-card.component.scss'], }) -export class CustomerSearchCardComponent implements OnInit, AfterViewInit, OnDestroy { - @Select(SharedSelectors.getSearchedCustomers) customers$: Observable; +export class CustomerSearchCardComponent + implements OnInit, AfterViewInit, OnDestroy { + @Select(SharedSelectors.getSearchedCustomers) customers$: Observable< + CustomerSearchResult + >; destroy$ = new Subject(); processes: Process[]; searchError = ''; @Input() searchParams = ''; - @ViewChild('searchInput', { static: false }) searchInput: SearchInputComponent; - @ViewChild('searchEmptyModal', { static: false }) searchEmptyModal: CustomerSearchEmptyModalComponent; + @ViewChild('searchInput', { static: false }) + searchInput: SearchInputComponent; + @ViewChild('searchEmptyModal', { static: false }) + searchEmptyModal: CustomerSearchEmptyModalComponent; - constructor(private store: Store, private router: Router, private customerService: CustomerService) { } + constructor( + private store: Store, + private router: Router, + private customerService: CustomerService + ) {} ngOnInit() { this.store.dispatch(new ClearCachedCustomers()); @@ -62,8 +85,8 @@ export class CustomerSearchCardComponent implements OnInit, AfterViewInit, OnDes .pipe(take(1), takeUntil(this.destroy$)) .subscribe((r: CustomerSearchResponse) => { if (r.customers.length > 0) { - const filteredCustomer = r.customers.filter(data => { - if (!data.features) { + const filteredCustomer = r.customers.filter((data) => { + if (isNullOrUndefined(data) || !data.features) { return true; } const customerFeatures = new CustomerFeatures(data.features); @@ -72,22 +95,28 @@ export class CustomerSearchCardComponent implements OnInit, AfterViewInit, OnDes } return true; }); - const response = { ...r, customers: filteredCustomer, hits: filteredCustomer ? filteredCustomer.length : 0 }; + const response = { + ...r, + customers: filteredCustomer, + hits: filteredCustomer ? filteredCustomer.length : 0, + }; this.store.dispatch( new AddBreadcrumb( { name: - (searchParams.length > 12 ? searchParams.substring(0, 12) + '...' : searchParams) + + (searchParams.length > 12 + ? searchParams.substring(0, 12) + '...' + : searchParams) + ` (${ - !isNullOrUndefined(response) - ? !isNullOrUndefined(response.hits) - ? response.hits - : response.customers + !isNullOrUndefined(response) + ? !isNullOrUndefined(response.hits) + ? response.hits + : response.customers ? response.customers.length : 0 - : 0 + : 0 } Ergebnisse)`, - path: '/customer/results' + path: '/customer/results', }, 'customer' ) @@ -97,7 +126,7 @@ export class CustomerSearchCardComponent implements OnInit, AfterViewInit, OnDes query: searchParams, skip: 0, take: 5, - firstLoad: true + firstLoad: true, }) ); sessionStorage.removeItem(CUSTOMER_SCROLL_INDEX); @@ -119,7 +148,7 @@ export class CustomerSearchCardComponent implements OnInit, AfterViewInit, OnDes const newProcess = { id: 1, name: 'Vorgang 1', - currentRoute: '/product/search' + currentRoute: '/product/search', }; this.store.dispatch(new AddProcess(newProcess)); @@ -127,7 +156,7 @@ export class CustomerSearchCardComponent implements OnInit, AfterViewInit, OnDes new AddBreadcrumb( { name: 'Artikelsuche', - path: '/product/search' + path: '/product/search', }, 'customer' ) diff --git a/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-data.datasource.ts b/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-data.datasource.ts index db94c74bc..427327f8f 100644 --- a/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-data.datasource.ts +++ b/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-data.datasource.ts @@ -3,12 +3,14 @@ import { User } from '../../../../core/models/user.model'; import { Observable, BehaviorSubject, Subject } from 'rxjs'; import { takeUntil, debounceTime, take } from 'rxjs/operators'; import { Store } from '@ngxs/store'; -import { CurrentCustomerPageLoaded, AddCustomers } from '../../../../core/store/actions/customer.actions'; +import { + CurrentCustomerPageLoaded, + AddCustomers, +} from '../../../../core/store/actions/customer.actions'; import { CustomerService } from '../../../../core/services/customer.service'; import { CustomerSearchResponse } from '../../../../core/models/customer-search-response.model'; import { CustomerFilters } from './customer-search-result.component'; -import { AddBreadcrumb, AddBreadcrumbNoDub } from '../../../../core/store/actions/breadcrumb.actions'; -import { isArrayMinLength } from 'apps/sales/src/app/core/utils/app.utils'; +import { AddBreadcrumbNoDub } from '../../../../core/store/actions/breadcrumb.actions'; import { isNullOrUndefined } from 'util'; import { CustomerSelectors } from 'apps/sales/src/app/core/store/selectors/customer.selectors'; @@ -16,7 +18,9 @@ export class CustomerSearchDataSource extends DataSource { private pageSize = 10; public cachedData = Array.from({ length: 0 }); private fetchedPages = new Set(); - private dataStream = new BehaviorSubject<(User | undefined)[]>(this.cachedData); + private dataStream = new BehaviorSubject<(User | undefined)[]>( + this.cachedData + ); destroy$ = new Subject(); public loading = true; public results = false; @@ -35,21 +39,23 @@ export class CustomerSearchDataSource extends DataSource { super(); } - connect(collectionViewer: CollectionViewer): Observable<(User | undefined)[]> { - collectionViewer.viewChange.pipe(takeUntil(this.destroy$)).subscribe(range => { - const startPage = this.getPageForIndex(range.start); - const endPage = this.getPageForIndex(range.end - 1); - for (let i = startPage; i <= endPage; i++) { - this.fetchPage(i); - } - }); + connect( + collectionViewer: CollectionViewer + ): Observable<(User | undefined)[]> { + collectionViewer.viewChange + .pipe(takeUntil(this.destroy$)) + .subscribe((range) => { + const startPage = this.getPageForIndex(range.start); + const endPage = this.getPageForIndex(range.end - 1); + for (let i = startPage; i <= endPage; i++) { + this.fetchPage(i); + } + }); this.dataStream - .pipe( - takeUntil(this.destroy$), - debounceTime(1000) - ) - .subscribe(i => { + .pipe(takeUntil(this.destroy$), debounceTime(1000)) + .subscribe((i) => { + console.log({ i }); this.store.dispatch(new AddCustomers([...i])); }); @@ -79,7 +85,14 @@ export class CustomerSearchDataSource extends DataSource { const customerSource$ = !this.scan ? page === 0 && this.first ? this.store.select(CustomerSelectors.getCachedCustomers) - : this.customerService.searchCustomer(this.search, false, page * this.pageSize, this.pageSize, false, this.customerFilters) + : this.customerService.searchCustomer( + this.search, + false, + page * this.pageSize, + this.pageSize, + false, + this.customerFilters + ) : this.customerService.scannCustomer(this.search); customerSource$.pipe(take(1)).subscribe((data: CustomerSearchResponse) => { if (!data) { @@ -92,8 +105,14 @@ export class CustomerSearchDataSource extends DataSource { new AddBreadcrumbNoDub( { name: - (this.search.length > 12 ? this.search.substring(0, 12) + '...' : this.search) + - ` (${!isNullOrUndefined(data.hits) ? data.hits : data.customers.length} Ergebnisse)`, + (this.search.length > 12 + ? this.search.substring(0, 12) + '...' + : this.search) + + ` (${ + !isNullOrUndefined(data.hits) + ? data.hits + : data.customers.length + } Ergebnisse)`, path: '/customer/results', }, 'customer' @@ -106,7 +125,11 @@ export class CustomerSearchDataSource extends DataSource { this.allHits = data.hits; } - this.cachedData.splice(page * this.pageSize, this.pageSize, ...data.customers); + this.cachedData.splice( + page * this.pageSize, + this.pageSize, + ...data.customers + ); this.dataStream.next(this.cachedData); if (page === 0) { diff --git a/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-search-result.component.html b/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-search-result.component.html index e3eaef40c..a86518f92 100644 --- a/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-search-result.component.html +++ b/apps/sales/src/app/modules/customer/pages/customer-search-result/customer-search-result.component.html @@ -9,17 +9,29 @@
@@ -36,23 +48,39 @@ Kunde nicht gefunden? - Neue Kundendaten erfassen + Neue Kundendaten erfassen
- -
+ +
- - + -
\ No newline at end of file +
diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts index 148e5a039..f91e7f244 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts @@ -1,11 +1,28 @@ -import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; +import { + Component, + OnInit, + ChangeDetectionStrategy, + ChangeDetectorRef, +} from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { FormGroup, FormArray } from '@angular/forms'; import { ShelfEditFormService } from '../../services'; import { ShelfNavigationService } from '../../shared/services'; -import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators'; +import { + filter, + map, + distinctUntilChanged, + shareReplay, + take, + withLatestFrom, + first, +} from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; -import { ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe } from '../../pipes'; +import { + ProcessingStatusPipe, + PickUpDateOptionsToDisplayValuesPipe, + ProcessingStatusOptionsPipe, +} from '../../pipes'; import { DatePipe } from '@angular/common'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; import { from } from 'rxjs'; @@ -23,6 +40,7 @@ export class ShelfEditOrderComponent implements OnInit { // Pipes for Mapping Values to display names processingStatusPipe = new ProcessingStatusPipe(); + processingStatusOptionsPipe = new ProcessingStatusOptionsPipe(); dateOptionsPipe = new PickUpDateOptionsToDisplayValuesPipe(); datePipe = new DatePipe('de'); @@ -44,7 +62,10 @@ export class ShelfEditOrderComponent implements OnInit { get processingStatus$() { return this.activatedRoute.params.pipe( - map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue), + map( + (params) => + Number(params.processingStatus) as OrderItemProcessingStatusValue + ), distinctUntilChanged(), shareReplay() ); @@ -56,19 +77,34 @@ export class ShelfEditOrderComponent implements OnInit { async loadOrderNumberAndInitForm() { const orderNumber = await this.orderNumber$.pipe(take(1)).toPromise(); - const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise(); - console.log('loadOrderNumberAndInitForm', { orderNumber, processingStatus }); + const processingStatus = await this.processingStatus$ + .pipe(take(1)) + .toPromise(); + console.log('loadOrderNumberAndInitForm', { + orderNumber, + processingStatus, + }); this.populateFormData(orderNumber, processingStatus); } async onSubmit() { const orderNumber = await this.orderNumber$.pipe(first()).toPromise(); - const processingStatus = await this.processingStatus$.pipe(first()).toPromise(); + const processingStatus = await this.processingStatus$ + .pipe(first()) + .toPromise(); - const submitResult = await this.formService.submit(this.form, processingStatus); + const submitResult = await this.formService.submit( + this.form, + processingStatus + ); if (submitResult) { // TODO Navigate back to Details Page with updated processingStatus + this.shelfNavigationService.navigateBackToDetails({ + orderNumber, + processingStatus: + this.form.get('processingStatus').value || processingStatus, + }); } } @@ -76,11 +112,22 @@ export class ShelfEditOrderComponent implements OnInit { return this.orderNumber$ .pipe(take(1), withLatestFrom(this.processingStatus$)) - .subscribe(([orderNumber, processingStatus]) => this.shelfNavigationService.navigateToDetails({ orderNumber, processingStatus })); + .subscribe(([orderNumber, processingStatus]) => + this.shelfNavigationService.navigateToDetails({ + orderNumber, + processingStatus, + }) + ); } - private async populateFormData(orderNumber: string, processingStatus: OrderItemProcessingStatusValue) { - this.form = await this.formService.createFormByOrderNumber(orderNumber, processingStatus); + private async populateFormData( + orderNumber: string, + processingStatus: OrderItemProcessingStatusValue + ) { + this.form = await this.formService.createFormByOrderNumber( + orderNumber, + processingStatus + ); console.log({ form: this.form }); this.items = this.formService.getItemsForm(orderNumber); diff --git a/apps/sales/src/app/modules/shelf/pipes/index.ts b/apps/sales/src/app/modules/shelf/pipes/index.ts index 0a11d18b6..8e8973e7f 100644 --- a/apps/sales/src/app/modules/shelf/pipes/index.ts +++ b/apps/sales/src/app/modules/shelf/pipes/index.ts @@ -3,6 +3,7 @@ export * from './environment-channel.pipe'; export * from './generate-image-src-from-ean.pipe'; export * from './get-extend-pick-up-date-options.pipe'; export * from './pick-up-date-option-to-display-value.pipe'; +export * from './processing-status-options.pipe'; export * from './processing-status.pipe'; export * from './shelf-pipes.module'; export * from './vat-dto-to-vat-value.pipe'; diff --git a/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.spec.ts b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.spec.ts new file mode 100644 index 000000000..d638de391 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.spec.ts @@ -0,0 +1,22 @@ +import { ProcessingStatusOptionsPipe } from './processing-status-options.pipe'; + +fdescribe('ProcessingStatusOptionsPipe', () => { + let pipe: ProcessingStatusOptionsPipe; + + // activated code + const bestelltStatuscode = 16; + + // deactivated code + const nachbestelltStatusCode = 8192; + + beforeEach(() => { + pipe = new ProcessingStatusOptionsPipe(); + }); + + it('should return bestellt (1)', () => { + const result = pipe.transform([bestelltStatuscode, nachbestelltStatusCode]); + + expect(result.length).toBe(1); + expect(result).toEqual([bestelltStatuscode]); + }); +}); diff --git a/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.ts b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.ts new file mode 100644 index 000000000..e818cc294 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.ts @@ -0,0 +1,19 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { ProcessingStatusNameMap } from '../constants'; + +@Pipe({ + name: 'processingStatusOptionsPipe', +}) +export class ProcessingStatusOptionsPipe implements PipeTransform { + transform(states: number[]): number[] { + return states.filter((state) => { + const result = ProcessingStatusNameMap.get(state); + + if (!result || result.disabled) { + return false; + } + + return true; + }); + } +} diff --git a/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts b/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts index 160186232..e6ed24046 100644 --- a/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts +++ b/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts @@ -10,12 +10,14 @@ import { VatDtoToVatValuePipe } from './vat-dto-to-vat-value.pipe'; import { VatTypeToDisplayNamePipe } from './vat-type-to-display-name.pipe'; import { VatDtoToVatTypePipe } from './vat-dto-to-vat-type.pipe'; import { VatTypePipe } from './vat-type.pipe'; +import { ProcessingStatusOptionsPipe } from './processing-status-options.pipe'; @NgModule({ imports: [CommonModule], exports: [ VatTypeToDisplayNamePipe, ProcessingStatusPipe, + ProcessingStatusOptionsPipe, EnvironmentChannelPipe, GetExtendPickUpOptionsPipe, PickUpDateOptionsToDisplayValuesPipe, @@ -27,6 +29,7 @@ import { VatTypePipe } from './vat-type.pipe'; declarations: [ VatTypeToDisplayNamePipe, ProcessingStatusPipe, + ProcessingStatusOptionsPipe, EnvironmentChannelPipe, GetExtendPickUpOptionsPipe, PickUpDateOptionsToDisplayValuesPipe, diff --git a/apps/sales/src/app/modules/shelf/pipes/vat-type-to-display-name.pipe.spec.ts b/apps/sales/src/app/modules/shelf/pipes/vat-type-to-display-name.pipe.spec.ts index 5cdc27f51..2149f38e7 100644 --- a/apps/sales/src/app/modules/shelf/pipes/vat-type-to-display-name.pipe.spec.ts +++ b/apps/sales/src/app/modules/shelf/pipes/vat-type-to-display-name.pipe.spec.ts @@ -5,13 +5,13 @@ fdescribe('Pipe: VatTypeToDisplayNamePipe', () => { let pipe: VatTypeToDisplayNamePipe; beforeEach(() => { - pipe = new VatTypeToDisplayNamePipe(vatDtosMock); + pipe = new VatTypeToDisplayNamePipe(); }); it('should return 5%', () => { const mock = vatDtosMock.find((vat) => vat.name === '5').vatType; - const result = pipe.transform(mock); + const result = pipe.transform(mock, vatDtosMock); const expected = '5%'; expect(result).toEqual(expected); diff --git a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts index 15e49a908..774ca0e92 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts @@ -1,5 +1,11 @@ import { Injectable } from '@angular/core'; -import { FormBuilder, FormGroup, Validators, FormArray, AbstractControl } from '@angular/forms'; +import { + FormBuilder, + FormGroup, + Validators, + FormArray, + AbstractControl, +} from '@angular/forms'; import { Observable, of, from } from 'rxjs'; import { OrderItemListItemDTO, @@ -29,11 +35,24 @@ export class ShelfEditFormService { return Array.from(ProcessingStatusNameMap.keys()); } + public get availableProcessingStatus(): number[] { + return this.processingStatus.filter((status) => { + const result = ProcessingStatusNameMap.get(status); + if (!result || !result.disabled) { + return false; + } + return true; + }); + } + public get vatOptions$(): Observable { return this.vats$.pipe(filter((vats) => !!vats.length)); } - constructor(private formBuilder: FormBuilder, private detailsStoreFacade: DetailsFacade) {} + constructor( + private formBuilder: FormBuilder, + private detailsStoreFacade: DetailsFacade + ) {} public getItemsForm(compartmentCode: string): FormArray { if (!this.forms.has(compartmentCode)) { @@ -42,7 +61,9 @@ export class ShelfEditFormService { return this.forms.get(compartmentCode).get('items') as FormArray; } - public getCustomerName(compartmentCode: string): { firstName: string; lastName: string } { + public getCustomerName( + compartmentCode: string + ): { firstName: string; lastName: string } { if (!this.forms.has(compartmentCode)) { return { firstName: 'unbekannt', @@ -57,8 +78,14 @@ export class ShelfEditFormService { }; } - async createFormByOrderNumber(orderNumber: string, processingStatus: OrderItemProcessingStatusValue): Promise { - const controlsConfig = await this.getControlsConfigForOrder(orderNumber, processingStatus); + async createFormByOrderNumber( + orderNumber: string, + processingStatus: OrderItemProcessingStatusValue + ): Promise { + const controlsConfig = await this.getControlsConfigForOrder( + orderNumber, + processingStatus + ); const form = this.formBuilder.group(controlsConfig); this.forms.set(orderNumber, form); @@ -66,8 +93,14 @@ export class ShelfEditFormService { return this.forms.get(orderNumber); } - async createFormByCompartmentCode(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue): Promise { - const controlsConfig = await this.getControlsConfigForCompartment(compartmentCode, processingStatus); + async createFormByCompartmentCode( + compartmentCode: string, + processingStatus: OrderItemProcessingStatusValue + ): Promise { + const controlsConfig = await this.getControlsConfigForCompartment( + compartmentCode, + processingStatus + ); const form = this.formBuilder.group(controlsConfig); this.forms.set(compartmentCode, form); @@ -75,8 +108,13 @@ export class ShelfEditFormService { return this.forms.get(compartmentCode); } - async getControlsConfigForOrder(orderNumber: string, processingStatus: OrderItemProcessingStatusValue): Promise<{ [key: string]: any }> { - const orderItems$: Observable = this.detailsStoreFacade.getOrderItemsByOrderNumberAndProcessingStatus$( + async getControlsConfigForOrder( + orderNumber: string, + processingStatus: OrderItemProcessingStatusValue + ): Promise<{ [key: string]: any }> { + const orderItems$: Observable< + OrderItemListItemDTO[] + > = this.detailsStoreFacade.getOrderItemsByOrderNumberAndProcessingStatus$( orderNumber, processingStatus ); @@ -88,7 +126,9 @@ export class ShelfEditFormService { compartmentCode: string, processingStatus: OrderItemProcessingStatusValue ): Promise<{ [key: string]: any }> { - const orderItems$: Observable = this.detailsStoreFacade.getOrderItemsByCompartmentCodeAndProcessingStatus$( + const orderItems$: Observable< + OrderItemListItemDTO[] + > = this.detailsStoreFacade.getOrderItemsByCompartmentCodeAndProcessingStatus$( compartmentCode, processingStatus ); @@ -96,7 +136,9 @@ export class ShelfEditFormService { return this.createControlConfig(orderItems$); } - private async createControlConfig(orderItems$: Observable): Promise<{ [key: string]: any }> { + private async createControlConfig( + orderItems$: Observable + ): Promise<{ [key: string]: any }> { const orderItems = await orderItems$ .pipe( filter((items) => !isNullOrUndefined(items) && !!items.length), @@ -108,7 +150,9 @@ export class ShelfEditFormService { return { ...this.getGeneralForm(orderItems), - items: this.formBuilder.array(orderItems.map((orderItem) => this.getItemForm(orderItem, vats))), + items: this.formBuilder.array( + orderItems.map((orderItem) => this.getItemForm(orderItem, vats)) + ), }; } @@ -117,7 +161,9 @@ export class ShelfEditFormService { return { firstName: baseOrderItem.firstName, lastName: baseOrderItem.lastName, - compartmentCode: [{ value: baseOrderItem.compartmentCode, disabled: false }], + compartmentCode: [ + { value: baseOrderItem.compartmentCode, disabled: false }, + ], orderId: [{ value: baseOrderItem.orderId, disabled: false }], orderNumber: [ { @@ -133,13 +179,19 @@ export class ShelfEditFormService { ], clientChannel: [ { - value: new EnvironmentChannelPipe().transform(baseOrderItem.clientChannel), + value: new EnvironmentChannelPipe().transform( + baseOrderItem.clientChannel + ), disabled: true, }, ], buyerNumber: [{ value: baseOrderItem.buyerNumber, disabled: true }], - processingStatus: [{ value: baseOrderItem.processingStatus, disabled: false }], - estimatedShippingDate: [{ value: baseOrderItem.estimatedShippingDate, disabled: false }], + processingStatus: [ + { value: baseOrderItem.processingStatus, disabled: false }, + ], + estimatedShippingDate: [ + { value: baseOrderItem.estimatedShippingDate, disabled: false }, + ], pickUpDeadline: [ { value: baseOrderItem.pickUpDeadline, @@ -157,11 +209,17 @@ export class ShelfEditFormService { orderId: Number(form.get('orderId').value), orderNumber: form.get('orderNumber').value, orderDate: new Date(form.get('orderDate').value), - clientChannel: Number(form.get('clientChannel').value) as EnvironmentChannel, + clientChannel: Number( + form.get('clientChannel').value + ) as EnvironmentChannel, buyerNumber: form.get('buyerNumber').value, - processingStatus: Number(form.get('processingStatus').value) as OrderItemProcessingStatusValue, - pickUpDeadline: String(form.get('pickUpDeadline').value), - estimatedShippingDate: String(form.get('estimatedShippingDate').value), + processingStatus: Number( + form.get('processingStatus').value + ) as OrderItemProcessingStatusValue, + pickUpDeadline: String(form.get('pickUpDeadline').value || ''), + estimatedShippingDate: String( + form.get('estimatedShippingDate').value || '' + ), }; } @@ -169,9 +227,14 @@ export class ShelfEditFormService { return this.formBuilder.group({ orderId: [{ value: orderItem.orderId, disabled: true }], orderItemId: [{ value: orderItem.orderItemId, disabled: true }], - orderItemSubsetId: [{ value: orderItem.orderItemSubsetId, disabled: true }], + orderItemSubsetId: [ + { value: orderItem.orderItemSubsetId, disabled: true }, + ], quantity: [{ value: orderItem.quantity, disabled: false }], - price: [{ value: orderItem.price, disabled: false }, [Validators.required]], + price: [ + { value: orderItem.price, disabled: false }, + [Validators.required], + ], ean: [ { value: orderItem.product.ean, @@ -182,7 +245,9 @@ export class ShelfEditFormService { title: [{ value: orderItem.product.name, disabled: true }], ssc: [ { - value: orderItem.ssc ? orderItem.ssc + ' - ' + orderItem.sscText : '-', + value: orderItem.ssc + ? orderItem.ssc + ' - ' + orderItem.sscText + : '-', disabled: true, }, ], @@ -199,7 +264,6 @@ export class ShelfEditFormService { } getDataFromItemForm(form: AbstractControl): OrderItemListItemDTO { - console.log({ form }); return { orderId: Number(form.get('orderId').value), orderItemId: Number(form.get('orderItemId').value), @@ -211,21 +275,25 @@ export class ShelfEditFormService { }; } - async submit(form: FormGroup, processingStatus: OrderItemProcessingStatusValue): Promise { + async submit( + form: FormGroup, + processingStatus: OrderItemProcessingStatusValue + ): Promise { const formData = this.getDataFromGeneralForm(form); + console.log({ formData }); const patch = this.preparePatch(form, formData); - const newProcessingStatus = Number(form.get('processingStatus').value) as OrderItemProcessingStatusValue; - // TODO dispatch actions to store to submit form - // TODO handle errorrs - - // this.detailsStoreFacade.patchOrderItems(patch); - // TODO must return boolean to indicate whether patch (update) was succesful + const newProcessingStatus = Number( + form.get('processingStatus').value + ) as OrderItemProcessingStatusValue; try { await this.detailsStoreFacade.patchOrderItems(patch); await this.detailsStoreFacade.patchOrderItemSubsets(patch); if (newProcessingStatus !== processingStatus) { - const changeStatusData = this.prepareStatusChange(form, newProcessingStatus); + const changeStatusData = this.prepareStatusChange( + form, + newProcessingStatus + ); if (newProcessingStatus === 128) { await this.detailsStoreFacade.arrived(changeStatusData, undefined); } else { @@ -242,7 +310,10 @@ export class ShelfEditFormService { private preparePatch( form: FormGroup, - { estimatedShippingDate, pickUpDeadline }: { estimatedShippingDate: string; pickUpDeadline: string } + { + estimatedShippingDate, + pickUpDeadline, + }: { estimatedShippingDate: string; pickUpDeadline: string } ): { orderId: number; orderItemId: number; @@ -250,7 +321,9 @@ export class ShelfEditFormService { orderItem: Partial; orderItemSubset: Partial; }[] { - const items = (form.get('items') as FormArray).controls.map((control) => this.getDataFromItemForm(control)); + const items = (form.get('items') as FormArray).controls.map((control) => + this.getDataFromItemForm(control) + ); return items.map((item) => ({ orderId: item.orderId, @@ -263,20 +336,16 @@ export class ShelfEditFormService { }, orderItemSubset: { estimatedShippingDate }, })); - - // const patch: { - // orderId: number; - // orderItemId: number; - // orderItem: Partial; - // }[] = items.map((item: { comment: string; price: number; quantity: number; vat: number }) => this.mapFormItemToPatch(form, item)); - - // console.log('%cPreparing Patch: ', 'color: green; font-weight: bold', items); - - // return patch; } - private prepareStatusChange(form: FormGroup, processingStatus: OrderItemProcessingStatusValue) { - const items = (form.get('items').value as Array).map((itemForm) => this.getDataFromItemForm(itemForm)); + private prepareStatusChange( + form: FormGroup, + processingStatus: OrderItemProcessingStatusValue + ) { + console.log({ form2: form }); + const items = (form.get('items') as FormArray).controls.map((itemForm) => + this.getDataFromItemForm(itemForm) + ); return items.map((item) => ({ orderId: item.orderId, @@ -285,27 +354,4 @@ export class ShelfEditFormService { data: { processingStatus } as StatusValues, })); } - - // private mapFormItemToPatch( - // form: FormGroup, - // item: { - // comment: string; - // price: number; - // quantity: number; - // vat: number; - // } - // ): { - // orderId: number; - // orderItemId: number; - // orderItem: Partial; - // } { - // return { - // orderId: form.get('orderId').value, - // orderItemId: item., - // orderItem: { - // ...item, - // quantity: Number(item.quantity), - // }, - // }; - // } } diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index eb76dcf92..6ed6d0b4d 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -1,8 +1,15 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Store } from '@ngxs/store'; -import { AddBreadcrumb, UpdateCurrentBreadcrumbName, PopLastBreadcrumbs } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; -import { ChangeCurrentRoute, AddProcess } from 'apps/sales/src/app/core/store/actions/process.actions'; +import { + AddBreadcrumb, + UpdateCurrentBreadcrumbName, + PopLastBreadcrumbs, +} from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; +import { + ChangeCurrentRoute, + AddProcess, +} from 'apps/sales/src/app/core/store/actions/process.actions'; import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model'; import { OrderItemListItemDTO } from '@swagger/oms/lib'; import { ProcessSelectors } from 'apps/sales/src/app/core/store/selectors/process.selectors'; @@ -12,7 +19,11 @@ import { Process } from 'apps/sales/src/app/core/models/process.model'; export class ShelfNavigationService { constructor(private store: Store, private router: Router) {} - navigateToDetails(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { + navigateToDetails(order: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }) { this.createTab(); const path = this.getDetailsPath(order); const breadcrumb = this.getDetailsBreadcrumb(order); @@ -20,7 +31,11 @@ export class ShelfNavigationService { this.navigateToRoute(path, breadcrumb); } - navigateToEdit(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { + navigateToEdit(order: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }) { this.createTab(); const path = this.getDetailsPath({ ...order, edit: true }); const breadcrumb = this.getEditBreadCrumb(); @@ -28,7 +43,11 @@ export class ShelfNavigationService { this.navigateToRoute(path, breadcrumb); } - updateDetailsNavigation(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { + updateDetailsNavigation(order: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }) { const path = this.getDetailsPath(order); const breadcrumb = this.getDetailsBreadcrumb(order); this.replaceRoute(path, breadcrumb); @@ -40,7 +59,13 @@ export class ShelfNavigationService { this.replaceRoute(path, breadcrumb); } - navigateToResultList({ searchQuery, numberOfHits }: { searchQuery: string; numberOfHits: number }) { + navigateToResultList({ + searchQuery, + numberOfHits, + }: { + searchQuery: string; + numberOfHits: number; + }) { this.createTab(); const path = '/shelf/results'; const breadcrumb = this.getResultListBreadcrumb(searchQuery, numberOfHits); @@ -48,12 +73,17 @@ export class ShelfNavigationService { } navigateToHistory(orderitem: OrderItemListItemDTO) { - this.navigateToRoute(`shelf/history/${orderitem.orderItemSubsetId}`, `Historie ${orderitem.orderItemSubsetId}`); + this.navigateToRoute( + `shelf/history/${orderitem.orderItemSubsetId}`, + `Historie ${orderitem.orderItemSubsetId}` + ); } private replaceRoute(route: string, breadcrumbName: string) { this.router.navigate([route]); - this.store.dispatch(new UpdateCurrentBreadcrumbName(breadcrumbName, 'shelf')); + this.store.dispatch( + new UpdateCurrentBreadcrumbName(breadcrumbName, 'shelf') + ); } private navigateToRoute(route: string, breadcrumbName: string) { @@ -70,21 +100,28 @@ export class ShelfNavigationService { this.router.navigate([route]); } - public navigateBackToDetails(data: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { + public navigateBackToDetails(data: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }) { this.store.dispatch(new PopLastBreadcrumbs(this.getEditBreadCrumb())); - this.navigateBackToDetails(data); - /* - this.store.dispatch(new ChangeCurrentRoute(route)); - this.store.dispatch(new PopLastBreadcrumbs(this.getEditBreadCrumb())); - this.router.navigate([route]); */ + console.log({ navigateBackToDetails: data }); + this.navigateToDetails(data); } - private getResultListBreadcrumb(searchQuery: string, numberOfHits: number): string { + private getResultListBreadcrumb( + searchQuery: string, + numberOfHits: number + ): string { return `${searchQuery} (${numberOfHits} Ergebnisse)`; } - getDetailsBreadcrumb(data: { orderNumber?: string; compartmentCode?: string }): string { + getDetailsBreadcrumb(data: { + orderNumber?: string; + compartmentCode?: string; + }): string { if (data.compartmentCode) { return `${data.compartmentCode}`; } @@ -95,7 +132,12 @@ export class ShelfNavigationService { return 'Bearbeiten'; } - private getDetailsPath(data: { orderNumber?: string; compartmentCode?: string; processingStatus?: number; edit?: boolean }): string { + private getDetailsPath(data: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + edit?: boolean; + }): string { let url = ''; if (data.compartmentCode) { url = `/shelf/details/compartment/${data.compartmentCode}/${data.processingStatus}`; @@ -111,7 +153,8 @@ export class ShelfNavigationService { } private createTab() { - const processExists = this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0; + const processExists = + this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0; if (!processExists) { this.createProcess(); } diff --git a/apps/sales/src/app/modules/ui/select-input/select-input.component.scss b/apps/sales/src/app/modules/ui/select-input/select-input.component.scss index 3f62c8e44..d5d0b6824 100644 --- a/apps/sales/src/app/modules/ui/select-input/select-input.component.scss +++ b/apps/sales/src/app/modules/ui/select-input/select-input.component.scss @@ -1,7 +1,13 @@ @import 'variables'; -.selected { - margin-right: 10px; +.isa-form-field { + .selected { + margin-right: 10px; + } + + label { + width: max-content; + } } :host ::ng-deep { From b8faf2f2d6627215a5681feafc10013ed03119f2 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 1 Sep 2020 09:43:02 +0200 Subject: [PATCH 093/135] Update ProcessingStatus Mapping --- .../constants/processing-status-name.map.ts | 10 +++---- .../pipes/processing-status.pipe.spec.ts | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.spec.ts diff --git a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts index a53baf891..0493c19d3 100644 --- a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts +++ b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts @@ -22,12 +22,12 @@ export const ProcessingStatusNameMap = new Map< [131072, { value: 'NotFetched', disabled: true }], [262144, { value: 'Zurück zum Lager', disabled: true }], [524288, { value: 'angefragt', disabled: true }], - [1048576, { value: 'RedirectedInternally', disabled: true }], + [1048576, { value: '"weitergeleitet (intern)', disabled: true }], [2097152, { value: 'Overdue', disabled: true }], - [4194304, { value: 'Delivered', disabled: true }], - [8388608, { value: 'DetermineSupplier', disabled: true }], - [16777216, { value: 'SupplierTemporarilyOutOfStock', disabled: true }], - [33554432, { value: 'Reserved', disabled: true }], + [4194304, { value: 'Versendet', disabled: true }], + [8388608, { value: 'Lieferant ermittelt', disabled: true }], + [16777216, { value: 'derzeit nicht lieferbar', disabled: true }], + [33554432, { value: 'reserviert', disabled: true }], [67108864, { value: 'Assembled', disabled: true }], [134217728, { value: 'Packed', disabled: true }], ]); diff --git a/apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.spec.ts b/apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.spec.ts new file mode 100644 index 000000000..94cc80702 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.spec.ts @@ -0,0 +1,26 @@ +import { ProcessingStatusPipe } from './processing-status.pipe'; +import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; + +fdescribe('ProcessingStatusPipe', () => { + let pipe: ProcessingStatusPipe; + + beforeEach(() => { + pipe = new ProcessingStatusPipe(); + }); + + it('should return the status name for status 16 (bestellt)', () => { + const bestelltStatusCode = 16; + const result = pipe.transform(bestelltStatusCode); + + expect(result).toEqual('bestellt'); + }); + + it('should return an empty string if the status code is not found', () => { + const notExistingStatusCode = 17; + const result = pipe.transform( + notExistingStatusCode as OrderItemProcessingStatusValue + ); + + expect(result).toEqual(''); + }); +}); From bd0d9765fd474509f77d935e4050b25504be42ee Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 1 Sep 2020 10:13:59 +0200 Subject: [PATCH 094/135] Update Processing Status Mapping on Details Page --- .../order-details-card.component.html | 126 +++++++++++++----- .../order-details-card.component.ts | 16 ++- .../constants/processing-status-name.map.ts | 2 +- .../shelf/pipes/processing-status.pipe.ts | 44 ++---- .../modules/ui/dropdown/dropdown.component.ts | 65 +++++---- 5 files changed, 160 insertions(+), 93 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index 53fe8e96a..e7e3085a7 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -1,6 +1,9 @@ -

+

{{ orderDetails?.firstName }} {{ orderDetails?.lastName }} - {{ orderDetails?.compartmentCode }} {{ orderDetails?.compartmentInfo }} + {{ orderDetails?.compartmentCode }} + {{ orderDetails?.compartmentInfo }}

@@ -10,11 +13,15 @@
Bestelldatum
-
{{ orderDetails?.orderDate | date:'dd.MM.yy | HH:mm' }} Uhr
+
+ {{ orderDetails?.orderDate | date: 'dd.MM.yy | HH:mm' }} Uhr +
Bestellkanal
-
{{ orderDetails?.orderChannel | environmentChannel }}
+
+ {{ orderDetails?.orderChannel | environmentChannel }} +
@@ -25,54 +32,113 @@
Status
- - + -
-
+
vsl. Lieferdatum
- - +
Abholfrist
- - + - @@ -80,4 +146,4 @@
-
\ No newline at end of file +
diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts index f06db1e47..ac2d4e0ab 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts @@ -1,9 +1,14 @@ -import { Component, OnInit, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core'; +import { + Component, + OnInit, + ChangeDetectionStrategy, + Input, + Output, + EventEmitter, +} from '@angular/core'; import { OrderDetailsCardInput } from './order-details-card-input'; import { ProcessingStatusNameMap } from '../../constants'; import { OrderItemProcessingStatusValue } from '@swagger/oms'; -import { DetailsFacade } from '@shelf-store/details'; -import { map } from 'rxjs/operators'; @Component({ selector: 'app-shelf-order-details-card', @@ -16,7 +21,10 @@ export class ShelfOrderDetailsCardComponent implements OnInit { const copy = new Map(ProcessingStatusNameMap); if (this.orderDetails) { - if (this.orderDetails.processingStatus === 16 || this.orderDetails.processingStatus === 8192) { + if ( + this.orderDetails.processingStatus === 16 || + this.orderDetails.processingStatus === 8192 + ) { copy.delete(128); } } diff --git a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts index 0493c19d3..ba2f48b3a 100644 --- a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts +++ b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts @@ -22,7 +22,7 @@ export const ProcessingStatusNameMap = new Map< [131072, { value: 'NotFetched', disabled: true }], [262144, { value: 'Zurück zum Lager', disabled: true }], [524288, { value: 'angefragt', disabled: true }], - [1048576, { value: '"weitergeleitet (intern)', disabled: true }], + [1048576, { value: 'weitergeleitet (intern)', disabled: true }], [2097152, { value: 'Overdue', disabled: true }], [4194304, { value: 'Versendet', disabled: true }], [8388608, { value: 'Lieferant ermittelt', disabled: true }], diff --git a/apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.ts b/apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.ts index 893e6502d..4191496f2 100644 --- a/apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.ts +++ b/apps/sales/src/app/modules/shelf/pipes/processing-status.pipe.ts @@ -1,42 +1,11 @@ import { Pipe, PipeTransform } from '@angular/core'; import { OrderItemProcessingStatusValue } from '@swagger/oms'; +import { ProcessingStatusNameMap } from '../constants'; @Pipe({ name: 'processingStatus', }) export class ProcessingStatusPipe implements PipeTransform { - map = { - 0: '', - 1: 'bestellt', - 2: 'Placed', - 4: 'Accepted', - 8: 'Parked', - 16: 'bestellt', - 32: 'Vorbereitung Versand', - 64: 'versendet', - 128: 'eingetroffen', - 256: 'abgeholt', - 512: 'storniert (Kunde)', - 1024: 'storniert', - 2048: 'storniert (Lieferant)', - 4096: 'NotAvailable', - 8192: 'nachbestellt ', - 16384: 'ReturnedByBuyer', - 32768: 'AvailableForDownload', - 65536: 'Downloaded', - 131072: 'NotFetched', - 262144: 'Zurück zum Lager', - 524288: 'angefragt', - 1048576: 'RedirectedInternally', - 2097152: 'Overdue', - 4194304: 'Delivered', - 8388608: 'DetermineSupplier', - 16777216: 'SupplierTemporarilyOutOfStock', - 33554432: 'Reserved', - 67108864: 'Assembled', - 134217728: 'Packed', - }; - icon = { 16: 'Check', 128: 'Check', @@ -45,7 +14,14 @@ export class ProcessingStatusPipe implements PipeTransform { 2048: 'close', }; - transform(value: OrderItemProcessingStatusValue, type: 'icon' | 'text' = 'text'): string { - return (type === 'icon' ? this.icon[value] : this.map[value]) || ''; + transform( + value: OrderItemProcessingStatusValue, + type: 'icon' | 'text' = 'text' + ): string { + return type === 'icon' + ? this.icon[value] + : ProcessingStatusNameMap.get(value) + ? ProcessingStatusNameMap.get(value).value + : ''; } } diff --git a/apps/sales/src/app/modules/ui/dropdown/dropdown.component.ts b/apps/sales/src/app/modules/ui/dropdown/dropdown.component.ts index 61c58b0f6..1130d282f 100644 --- a/apps/sales/src/app/modules/ui/dropdown/dropdown.component.ts +++ b/apps/sales/src/app/modules/ui/dropdown/dropdown.component.ts @@ -16,25 +16,34 @@ import { trigger, transition, style, animate } from '@angular/animations'; import { UiDropdownItemDirective } from './dropdown-item.directive'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { fromEvent, Subscription } from 'rxjs'; -import { throttleTime } from 'rxjs/operators'; @Component({ selector: 'app-ui-dropdown', templateUrl: 'dropdown.component.html', styleUrls: ['dropdown.component.scss'], exportAs: 'uiDropdown', - providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => UiDropdownComponent), multi: true }], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => UiDropdownComponent), + multi: true, + }, + ], animations: [ trigger('dropdownAnimation', [ transition(':enter', [ style({ transform: 'translateY(-60px)', opacity: 0 }), animate('200ms', style({ transform: 'translateY(0)', opacity: 1 })), ]), - transition(':leave', [style({ opacity: '*' }), animate('200ms', style({ opacity: 0 }))]), + transition(':leave', [ + style({ opacity: '*' }), + animate('200ms', style({ opacity: 0 })), + ]), ]), ], }) -export class UiDropdownComponent implements OnInit, OnDestroy, ControlValueAccessor, AfterContentInit { +export class UiDropdownComponent + implements OnInit, OnDestroy, ControlValueAccessor, AfterContentInit { visible = false; @ContentChildren(UiDropdownItemDirective) @@ -70,11 +79,13 @@ export class UiDropdownComponent implements OnInit, OnDestroy, ControlValueAcces option.registerOnSelect((value) => this.selectValue(value)); }); - this.optionChangesSubscription = this.options.changes.subscribe((changes) => { - this.options.forEach((option) => { - option.registerOnSelect((value) => this.selectValue(value)); - }); - }); + this.optionChangesSubscription = this.options.changes.subscribe( + (changes) => { + this.options.forEach((option) => { + option.registerOnSelect((value) => this.selectValue(value)); + }); + } + ); } toggle(visible?: boolean) { @@ -99,26 +110,32 @@ export class UiDropdownComponent implements OnInit, OnDestroy, ControlValueAcces if (this.windowKeyEventsSubscription) { this.unsubscribeKeyboardEvents(); } - this.windowKeyEventsSubscription = this.windowKeyEvents$.subscribe((event: KeyboardEvent) => { - const activeElementIndex = this.options.toArray().findIndex((o) => o.focused); + this.windowKeyEventsSubscription = this.windowKeyEvents$.subscribe( + (event: KeyboardEvent) => { + const activeElementIndex = this.options + .toArray() + .findIndex((o) => o.focused); - if (event.code === 'ArrowUp' || event.code === 'ArrowDown') { - let nextElementIndex = activeElementIndex; - if (event.code === 'ArrowUp') { - if (activeElementIndex > 0) { - nextElementIndex--; + if (event.code === 'ArrowUp' || event.code === 'ArrowDown') { + let nextElementIndex = activeElementIndex; + if (event.code === 'ArrowUp') { + if (activeElementIndex > 0) { + nextElementIndex--; + } + } else if (event.code === 'ArrowDown') { + if (activeElementIndex + 1 < this.options.length) { + nextElementIndex++; + } } - } else if (event.code === 'ArrowDown') { - if (activeElementIndex + 1 < this.options.length) { - nextElementIndex++; + const option = this.options.find( + (item, index) => nextElementIndex === index + ); + if (option) { + option.focus(); } } - const option = this.options.find((item, index) => nextElementIndex === index); - if (option) { - option.focus(); - } } - }); + ); } unsubscribeKeyboardEvents() { From 3ebe35a0f6b42aa7f17ffdd84b17f1865bceb733 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 1 Sep 2020 11:14:05 +0200 Subject: [PATCH 095/135] Update ProcessingStatus Mapping and Wording --- .../constants/processing-status-name.map.ts | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts index ba2f48b3a..06e53c59e 100644 --- a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts +++ b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts @@ -2,32 +2,32 @@ export const ProcessingStatusNameMap = new Map< number, { value: string; disabled: boolean } >([ - [1, { value: '', disabled: true }], - [2, { value: 'Placed', disabled: true }], - [4, { value: 'Accepted', disabled: true }], - [8, { value: 'Parked', disabled: true }], + [1, { value: 'neu', disabled: true }], + [2, { value: '', disabled: true }], + [4, { value: '', disabled: true }], + [8, { value: 'geparkt', disabled: true }], [16, { value: 'bestellt', disabled: false }], [32, { value: 'Vorbereitung Versand', disabled: true }], - [64, { value: 'versendet', disabled: true }], + [64, { value: 'versendet', disabled: false }], [128, { value: 'eingetroffen', disabled: false }], [256, { value: 'abgeholt', disabled: false }], - [512, { value: 'storniert (Kunde)', disabled: true }], + [512, { value: 'storniert (Kunde)', disabled: false }], [1024, { value: 'storniert', disabled: false }], - [2048, { value: 'storniert (Lieferant)', disabled: true }], - [4096, { value: 'NotAvailable', disabled: true }], - [8192, { value: 'nachbestellt', disabled: true }], - [16384, { value: 'ReturnedByBuyer', disabled: true }], - [32768, { value: 'AvailableForDownload', disabled: true }], - [65536, { value: 'Downloaded', disabled: true }], - [131072, { value: 'NotFetched', disabled: true }], - [262144, { value: 'Zurück zum Lager', disabled: true }], - [524288, { value: 'angefragt', disabled: true }], - [1048576, { value: 'weitergeleitet (intern)', disabled: true }], - [2097152, { value: 'Overdue', disabled: true }], - [4194304, { value: 'Versendet', disabled: true }], - [8388608, { value: 'Lieferant ermittelt', disabled: true }], - [16777216, { value: 'derzeit nicht lieferbar', disabled: true }], + [2048, { value: 'storniert (Lieferant)', disabled: false }], + [4096, { value: 'nicht lieferbar', disabled: false }], + [8192, { value: 'nachbestellt', disabled: false }], + [16384, { value: 'zurückgegeben', disabled: true }], + [32768, { value: 'steht zum Download zur Verfügung', disabled: true }], + [65536, { value: 'downloaded', disabled: true }], + [131072, { value: 'nicht abgeholt', disabled: true }], + [262144, { value: 'ans Lager (nicht abgeholt)', disabled: false }], + [524288, { value: 'angefragt', disabled: false }], + [1048576, { value: 'weitergeleitet intern', disabled: false }], + [2097152, { value: 'überfällig', disabled: true }], + [4194304, { value: 'zugestellt', disabled: false }], + [8388608, { value: 'Lieferant ermittelt', disabled: false }], + [16777216, { value: 'derzeit nicht lieferbar', disabled: false }], [33554432, { value: 'reserviert', disabled: true }], - [67108864, { value: 'Assembled', disabled: true }], - [134217728, { value: 'Packed', disabled: true }], + [67108864, { value: 'zusammengestellt', disabled: true }], + [134217728, { value: 'verpackt', disabled: true }], ]); From 1c1a6c05c240117d776647667125ee2246e37314 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 1 Sep 2020 11:26:26 +0200 Subject: [PATCH 096/135] Update Editable Fields --- .../modules/shelf/services/shelf-edit-form.service.ts | 10 +++++----- .../shelf/shared/services/shelf-navigation.service.ts | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts index 774ca0e92..93d71a14e 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, ɵbypassSanitizationTrustResourceUrl } from '@angular/core'; import { FormBuilder, FormGroup, @@ -164,7 +164,7 @@ export class ShelfEditFormService { compartmentCode: [ { value: baseOrderItem.compartmentCode, disabled: false }, ], - orderId: [{ value: baseOrderItem.orderId, disabled: false }], + orderId: [{ value: baseOrderItem.orderId, disabled: true }], orderNumber: [ { value: baseOrderItem.orderNumber, @@ -230,7 +230,7 @@ export class ShelfEditFormService { orderItemSubsetId: [ { value: orderItem.orderItemSubsetId, disabled: true }, ], - quantity: [{ value: orderItem.quantity, disabled: false }], + quantity: [{ value: orderItem.quantity, disabled: true }], price: [ { value: orderItem.price, disabled: false }, [Validators.required], @@ -238,7 +238,7 @@ export class ShelfEditFormService { ean: [ { value: orderItem.product.ean, - disabled: true, + disabled: false, }, ], supplier: [{ value: orderItem.supplier, disabled: true }], @@ -248,7 +248,7 @@ export class ShelfEditFormService { value: orderItem.ssc ? orderItem.ssc + ' - ' + orderItem.sscText : '-', - disabled: true, + disabled: false, }, ], clientChannel: [{ value: orderItem.clientChannel, disabled: true }], diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index 6ed6d0b4d..6871fc459 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -107,7 +107,6 @@ export class ShelfNavigationService { }) { this.store.dispatch(new PopLastBreadcrumbs(this.getEditBreadCrumb())); - console.log({ navigateBackToDetails: data }); this.navigateToDetails(data); } From a1c7167e507a96b8cd21b4553365809f66e7ba9a Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Tue, 1 Sep 2020 17:30:34 +0200 Subject: [PATCH 097/135] Status Sortierung, Datepicker Styling, ROrderItem und OrderItemSubset Patch fix Co-authored-by: s.neumair@paragon-data.de --- .../filter-group/filter-group.component.html | 33 +-- .../shelf-edit-actions.component.html | 4 +- .../edit-order-item.component.html | 2 +- .../order-details-card.component.html | 106 +++------ .../order-details-card.component.ts | 22 +- .../constants/processing-status-name.map.ts | 5 +- .../shelf-edit-compartment.component.ts | 87 +++---- .../customer-features.component.ts | 5 +- .../shelf-order-details.component.html | 1 + .../shelf-order-details.component.ts | 17 +- .../shelf-tags/shelftags.component.ts | 4 +- .../pipes/processing-status-options.pipe.ts | 42 +++- .../modules/shelf/pipes/shelf-pipes.module.ts | 4 +- .../shelf/services/shelf-edit-form.service.ts | 214 ++++++++---------- .../services/shelf-navigation.service.ts | 104 ++++----- .../ui/datepicker/body/body.component.scss | 7 + .../ui/datepicker/body/cell.directive.ts | 11 + .../select-input/select-input.component.html | 3 +- .../text-input.component.component.ts | 9 +- .../ui/text-input/text-input.component.html | 20 +- .../customer/shelf/details/details.effects.ts | 4 +- .../customer/shelf/details/details.facade.ts | 2 +- apps/sales/src/scss/_typography.scss | 4 + apps/sales/src/scss/modules/_button.scss | 5 + 24 files changed, 305 insertions(+), 410 deletions(-) diff --git a/apps/sales/src/app/modules/filter/filter-group/components/filter-group/filter-group.component.html b/apps/sales/src/app/modules/filter/filter-group/components/filter-group/filter-group.component.html index edb885899..2ced7af51 100644 --- a/apps/sales/src/app/modules/filter/filter-group/components/filter-group/filter-group.component.html +++ b/apps/sales/src/app/modules/filter/filter-group/components/filter-group/filter-group.component.html @@ -1,37 +1,22 @@
-
- +
-
+ \ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/components/edit-actions/shelf-edit-actions.component.html b/apps/sales/src/app/modules/shelf/components/edit-actions/shelf-edit-actions.component.html index a794b3e66..ddc7c784f 100644 --- a/apps/sales/src/app/modules/shelf/components/edit-actions/shelf-edit-actions.component.html +++ b/apps/sales/src/app/modules/shelf/components/edit-actions/shelf-edit-actions.component.html @@ -1,8 +1,8 @@
\ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html b/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html index 9143e88ae..f2e853ede 100644 --- a/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html +++ b/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html @@ -29,6 +29,6 @@
- + \ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index e7e3085a7..57324014f 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -1,9 +1,7 @@

{{ orderDetails?.firstName }} {{ orderDetails?.lastName }} - {{ orderDetails?.compartmentCode }} - {{ orderDetails?.compartmentInfo }} + {{ orderDetails?.compartmentCode }} + {{ orderDetails?.compartmentInfo }}

@@ -32,113 +30,63 @@
Status
- - - -
-
+ ">
vsl. Lieferdatum
- - + ">
Abholfrist
- - + - @@ -146,4 +94,4 @@
-
+ \ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts index ac2d4e0ab..4308b37ff 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts @@ -1,14 +1,8 @@ -import { - Component, - OnInit, - ChangeDetectionStrategy, - Input, - Output, - EventEmitter, -} from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core'; import { OrderDetailsCardInput } from './order-details-card-input'; import { ProcessingStatusNameMap } from '../../constants'; import { OrderItemProcessingStatusValue } from '@swagger/oms'; +import { DateAdapter } from '@isa-ui/core/date'; @Component({ selector: 'app-shelf-order-details-card', @@ -17,16 +11,18 @@ import { OrderItemProcessingStatusValue } from '@swagger/oms'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ShelfOrderDetailsCardComponent implements OnInit { + minDate = this.dateAdapter.addCalendarDays(new Date(), -1); + get processingKeys() { const copy = new Map(ProcessingStatusNameMap); if (this.orderDetails) { - if ( - this.orderDetails.processingStatus === 16 || - this.orderDetails.processingStatus === 8192 - ) { + if (this.orderDetails.processingStatus === 16 || this.orderDetails.processingStatus === 8192) { copy.delete(128); } + if (this.orderDetails.processingStatus >= 0) { + copy.delete(this.orderDetails.processingStatus); + } } return copy; @@ -64,7 +60,7 @@ export class ShelfOrderDetailsCardComponent implements OnInit { @Output() changePickUpDeadline = new EventEmitter(); - constructor() {} + constructor(private dateAdapter: DateAdapter) {} ngOnInit() {} } diff --git a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts index 06e53c59e..1339db859 100644 --- a/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts +++ b/apps/sales/src/app/modules/shelf/constants/processing-status-name.map.ts @@ -1,7 +1,4 @@ -export const ProcessingStatusNameMap = new Map< - number, - { value: string; disabled: boolean } ->([ +export const ProcessingStatusNameMap = new Map([ [1, { value: 'neu', disabled: true }], [2, { value: '', disabled: true }], [4, { value: '', disabled: true }], diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts index 431d1a77f..79972abcc 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts @@ -1,28 +1,11 @@ -import { - Component, - OnInit, - ChangeDetectionStrategy, - ChangeDetectorRef, -} from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable, from } from 'rxjs'; -import { - filter, - map, - distinctUntilChanged, - shareReplay, - take, - withLatestFrom, - first, -} from 'rxjs/operators'; +import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; import { ShelfEditFormService } from '../../services'; import { FormGroup, FormArray } from '@angular/forms'; -import { - ProcessingStatusPipe, - PickUpDateOptionsToDisplayValuesPipe, - ProcessingStatusOptionsPipe, -} from '../../pipes'; +import { ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe, ProcessingStatusOptionsPipe } from '../../pipes'; import { DatePipe } from '@angular/common'; import { ShelfNavigationService } from '../../shared/services'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; @@ -63,10 +46,7 @@ export class ShelfEditCompartmentComponent implements OnInit { get processingStatus$() { return this.activatedRoute.params.pipe( - map( - (params) => - Number(params.processingStatus) as OrderItemProcessingStatusValue - ), + map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue), distinctUntilChanged(), shareReplay() ); @@ -77,57 +57,42 @@ export class ShelfEditCompartmentComponent implements OnInit { } async loadCompartmentAndInitForm() { - const compartmentCode = await this.compartmentCode$ - .pipe(take(1)) - .toPromise(); - const processingStatus = await this.processingStatus$ - .pipe(take(1)) - .toPromise(); + const compartmentCode = await this.compartmentCode$.pipe(take(1)).toPromise(); + const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise(); this.populateFormData(compartmentCode, processingStatus); } async onSubmit() { - const compartmentCode = await this.compartmentCode$ - .pipe(first()) - .toPromise(); - const processingStatus = await this.processingStatus$ - .pipe(first()) - .toPromise(); - const submitResult = await this.formService.submit( - this.form, - processingStatus - ); + console.log(this.form.valid); + const compartmentCode = await this.compartmentCode$.pipe(first()).toPromise(); + const processingStatus = await this.processingStatus$.pipe(first()).toPromise(); + const submitResult = await this.formService.submit(this.form, processingStatus); + + let newValues; if (submitResult) { // TODO Navigate back to Details Page with updated processingStatus - this.shelfNavigationService.navigateBackToDetails({ - compartmentCode, - processingStatus: - this.form.get('processingStatus').value || processingStatus, - }); + newValues = { + compartmentCode: this.form.get('compartmentCode').value || compartmentCode, + processingStatus: this.form.get('processingStatus').value || processingStatus, + }; + + this.shelfNavigationService.navigateBackToDetails(newValues, { compartmentCode, processingStatus }); } } onAbortEdit() { - return this.compartmentCode$ - .pipe(take(1), withLatestFrom(this.processingStatus$)) - .subscribe(([compartmentCode, processingStatus]) => - this.shelfNavigationService.navigateToDetails({ - compartmentCode, - processingStatus, - }) - ); + return this.compartmentCode$.pipe(take(1), withLatestFrom(this.processingStatus$)).subscribe(([compartmentCode, processingStatus]) => + this.shelfNavigationService.navigateToDetails({ + compartmentCode, + processingStatus, + }) + ); } - private async populateFormData( - compartmentCode: string, - processingStatus: OrderItemProcessingStatusValue - ) { - this.form = await this.formService.createFormByCompartmentCode( - compartmentCode, - processingStatus - ); + private async populateFormData(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue) { + this.form = await this.formService.createFormByCompartmentCode(compartmentCode, processingStatus); this.items = this.formService.getItemsForm(compartmentCode); this.customerName = this.formService.getCustomerName(compartmentCode); this.cdr.detectChanges(); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/customer-features/customer-features.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/customer-features/customer-features.component.ts index 1d863d559..cedd45666 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/customer-features/customer-features.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/customer-features/customer-features.component.ts @@ -2,6 +2,7 @@ import { Component, ChangeDetectionStrategy, Input } from '@angular/core'; import { CustomerService } from '@swagger/crm'; import { ReplaySubject, of, NEVER } from 'rxjs'; import { switchMap, catchError, map, flatMap, filter, throttleTime, distinctUntilChanged } from 'rxjs/operators'; +import { isNullOrUndefined } from 'util'; @Component({ selector: 'app-shelf-details-customer-features', @@ -12,7 +13,9 @@ import { switchMap, catchError, map, flatMap, filter, throttleTime, distinctUnti export class CustomerFeaturesComponent { @Input() set customerNumber(value: string) { - this.customernumber$.next(value); + if (!isNullOrUndefined(value)) { + this.customernumber$.next(value); + } } customernumber$ = new ReplaySubject(); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html index 8005989f7..ac76b3391 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html @@ -48,6 +48,7 @@
diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts index 046bcae18..3694d5aa3 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts @@ -183,11 +183,18 @@ export class ShelfOrderDetailsComponent { if (navigate) { const firstItem = items[0]; const firstResult = results[0].result; - this.shelfNavigationService.updateDetailsNavigation({ - compartmentCode: firstResult.item1.compartmentCode, - orderNumber: firstItem.orderNumber, - processingStatus: firstResult.item1.processingStatus, - }); + this.shelfNavigationService.updateDetails( + { + compartmentCode: firstResult.item1.compartmentCode, + orderNumber: firstItem.orderNumber, + processingStatus: firstResult.item1.processingStatus, + }, + { + compartmentCode: firstItem.compartmentCode, + orderNumber: firstItem.orderNumber, + processingStatus: firstItem.processingStatus, + } + ); } } diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-tags/shelftags.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-tags/shelftags.component.ts index cad6f859d..9380ebb7c 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-tags/shelftags.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-tags/shelftags.component.ts @@ -1,5 +1,5 @@ import { Component, ChangeDetectionStrategy, Input, EventEmitter, Output, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core'; -import { FormControl } from '@angular/forms'; +import { FormControl, Validators } from '@angular/forms'; import { Subscription } from 'rxjs'; @Component({ @@ -19,7 +19,7 @@ export class ShelfOrderDetailsShelfTagsComponent implements OnInit, OnDestroy { @Input() tags = ['Maxi', 'Mini', 'Kleinkram', 'Nonbook']; - customValue = new FormControl(''); + customValue = new FormControl('', [Validators.required, Validators.maxLength(15)]); subscription = new Subscription(); diff --git a/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.ts b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.ts index e818cc294..50a3f037b 100644 --- a/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.ts +++ b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.ts @@ -1,19 +1,47 @@ import { Pipe, PipeTransform } from '@angular/core'; import { ProcessingStatusNameMap } from '../constants'; +import { KeyValue } from '@angular/common'; @Pipe({ name: 'processingStatusOptionsPipe', }) export class ProcessingStatusOptionsPipe implements PipeTransform { transform(states: number[]): number[] { - return states.filter((state) => { - const result = ProcessingStatusNameMap.get(state); + return states + .filter((state) => { + const result = ProcessingStatusNameMap.get(state); - if (!result || result.disabled) { - return false; - } + if (!result || result.disabled) { + return false; + } - return true; - }); + return true; + }) + .sort((a, b) => { + const aValue = ProcessingStatusNameMap.get(a); + const bValue = ProcessingStatusNameMap.get(b); + return aValue.value.toUpperCase() === bValue.value.toUpperCase() + ? 0 + : aValue.value.toUpperCase() > bValue.value.toUpperCase() + ? 1 + : -1; + }); + } +} + +@Pipe({ + name: 'processingStatusOptionsKeyValuePipe', +}) +export class ProcessingStatusOptionsKeyValuePipe implements PipeTransform { + transform(states: KeyValue[]): KeyValue[] { + return states + .filter((state) => !state.value.disabled) + .sort((a, b) => { + return a.value.value.toUpperCase() === b.value.value.toUpperCase() + ? 0 + : a.value.value.toUpperCase() > b.value.value.toUpperCase() + ? 1 + : -1; + }); } } diff --git a/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts b/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts index e6ed24046..65559fa52 100644 --- a/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts +++ b/apps/sales/src/app/modules/shelf/pipes/shelf-pipes.module.ts @@ -10,7 +10,7 @@ import { VatDtoToVatValuePipe } from './vat-dto-to-vat-value.pipe'; import { VatTypeToDisplayNamePipe } from './vat-type-to-display-name.pipe'; import { VatDtoToVatTypePipe } from './vat-dto-to-vat-type.pipe'; import { VatTypePipe } from './vat-type.pipe'; -import { ProcessingStatusOptionsPipe } from './processing-status-options.pipe'; +import { ProcessingStatusOptionsPipe, ProcessingStatusOptionsKeyValuePipe } from './processing-status-options.pipe'; @NgModule({ imports: [CommonModule], @@ -25,6 +25,7 @@ import { ProcessingStatusOptionsPipe } from './processing-status-options.pipe'; VatDtoToVatValuePipe, VatDtoToVatTypePipe, VatTypePipe, + ProcessingStatusOptionsKeyValuePipe, ], declarations: [ VatTypeToDisplayNamePipe, @@ -37,6 +38,7 @@ import { ProcessingStatusOptionsPipe } from './processing-status-options.pipe'; VatDtoToVatValuePipe, VatDtoToVatTypePipe, VatTypePipe, + ProcessingStatusOptionsKeyValuePipe, ], }) export class ShelfPipesModule {} diff --git a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts index 93d71a14e..4189f2356 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts @@ -1,11 +1,5 @@ import { Injectable, ɵbypassSanitizationTrustResourceUrl } from '@angular/core'; -import { - FormBuilder, - FormGroup, - Validators, - FormArray, - AbstractControl, -} from '@angular/forms'; +import { FormBuilder, FormGroup, Validators, FormArray, AbstractControl } from '@angular/forms'; import { Observable, of, from } from 'rxjs'; import { OrderItemListItemDTO, @@ -49,10 +43,7 @@ export class ShelfEditFormService { return this.vats$.pipe(filter((vats) => !!vats.length)); } - constructor( - private formBuilder: FormBuilder, - private detailsStoreFacade: DetailsFacade - ) {} + constructor(private formBuilder: FormBuilder, private detailsStoreFacade: DetailsFacade) {} public getItemsForm(compartmentCode: string): FormArray { if (!this.forms.has(compartmentCode)) { @@ -61,9 +52,7 @@ export class ShelfEditFormService { return this.forms.get(compartmentCode).get('items') as FormArray; } - public getCustomerName( - compartmentCode: string - ): { firstName: string; lastName: string } { + public getCustomerName(compartmentCode: string): { firstName: string; lastName: string } { if (!this.forms.has(compartmentCode)) { return { firstName: 'unbekannt', @@ -78,14 +67,8 @@ export class ShelfEditFormService { }; } - async createFormByOrderNumber( - orderNumber: string, - processingStatus: OrderItemProcessingStatusValue - ): Promise { - const controlsConfig = await this.getControlsConfigForOrder( - orderNumber, - processingStatus - ); + async createFormByOrderNumber(orderNumber: string, processingStatus: OrderItemProcessingStatusValue): Promise { + const controlsConfig = await this.getControlsConfigForOrder(orderNumber, processingStatus); const form = this.formBuilder.group(controlsConfig); this.forms.set(orderNumber, form); @@ -93,14 +76,8 @@ export class ShelfEditFormService { return this.forms.get(orderNumber); } - async createFormByCompartmentCode( - compartmentCode: string, - processingStatus: OrderItemProcessingStatusValue - ): Promise { - const controlsConfig = await this.getControlsConfigForCompartment( - compartmentCode, - processingStatus - ); + async createFormByCompartmentCode(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue): Promise { + const controlsConfig = await this.getControlsConfigForCompartment(compartmentCode, processingStatus); const form = this.formBuilder.group(controlsConfig); this.forms.set(compartmentCode, form); @@ -108,13 +85,8 @@ export class ShelfEditFormService { return this.forms.get(compartmentCode); } - async getControlsConfigForOrder( - orderNumber: string, - processingStatus: OrderItemProcessingStatusValue - ): Promise<{ [key: string]: any }> { - const orderItems$: Observable< - OrderItemListItemDTO[] - > = this.detailsStoreFacade.getOrderItemsByOrderNumberAndProcessingStatus$( + async getControlsConfigForOrder(orderNumber: string, processingStatus: OrderItemProcessingStatusValue): Promise<{ [key: string]: any }> { + const orderItems$: Observable = this.detailsStoreFacade.getOrderItemsByOrderNumberAndProcessingStatus$( orderNumber, processingStatus ); @@ -126,19 +98,14 @@ export class ShelfEditFormService { compartmentCode: string, processingStatus: OrderItemProcessingStatusValue ): Promise<{ [key: string]: any }> { - const orderItems$: Observable< - OrderItemListItemDTO[] - > = this.detailsStoreFacade.getOrderItemsByCompartmentCodeAndProcessingStatus$( + const orderItems$: Observable = this.detailsStoreFacade.getOrderItemsByCompartmentCodeAndProcessingStatus$( compartmentCode, processingStatus ); - return this.createControlConfig(orderItems$); } - private async createControlConfig( - orderItems$: Observable - ): Promise<{ [key: string]: any }> { + private async createControlConfig(orderItems$: Observable): Promise<{ [key: string]: any }> { const orderItems = await orderItems$ .pipe( filter((items) => !isNullOrUndefined(items) && !!items.length), @@ -150,9 +117,7 @@ export class ShelfEditFormService { return { ...this.getGeneralForm(orderItems), - items: this.formBuilder.array( - orderItems.map((orderItem) => this.getItemForm(orderItem, vats)) - ), + items: this.formBuilder.array(orderItems.map((orderItem) => this.getItemForm(orderItem, vats))), }; } @@ -161,9 +126,7 @@ export class ShelfEditFormService { return { firstName: baseOrderItem.firstName, lastName: baseOrderItem.lastName, - compartmentCode: [ - { value: baseOrderItem.compartmentCode, disabled: false }, - ], + compartmentCode: [{ value: baseOrderItem.compartmentCode, disabled: false }], orderId: [{ value: baseOrderItem.orderId, disabled: true }], orderNumber: [ { @@ -179,19 +142,13 @@ export class ShelfEditFormService { ], clientChannel: [ { - value: new EnvironmentChannelPipe().transform( - baseOrderItem.clientChannel - ), + value: new EnvironmentChannelPipe().transform(baseOrderItem.clientChannel), disabled: true, }, ], buyerNumber: [{ value: baseOrderItem.buyerNumber, disabled: true }], - processingStatus: [ - { value: baseOrderItem.processingStatus, disabled: false }, - ], - estimatedShippingDate: [ - { value: baseOrderItem.estimatedShippingDate, disabled: false }, - ], + processingStatus: [{ value: baseOrderItem.processingStatus, disabled: false }], + estimatedShippingDate: [{ value: baseOrderItem.estimatedShippingDate, disabled: false }], pickUpDeadline: [ { value: baseOrderItem.pickUpDeadline, @@ -209,17 +166,11 @@ export class ShelfEditFormService { orderId: Number(form.get('orderId').value), orderNumber: form.get('orderNumber').value, orderDate: new Date(form.get('orderDate').value), - clientChannel: Number( - form.get('clientChannel').value - ) as EnvironmentChannel, + clientChannel: Number(form.get('clientChannel').value) as EnvironmentChannel, buyerNumber: form.get('buyerNumber').value, - processingStatus: Number( - form.get('processingStatus').value - ) as OrderItemProcessingStatusValue, + processingStatus: Number(form.get('processingStatus').value) as OrderItemProcessingStatusValue, pickUpDeadline: String(form.get('pickUpDeadline').value || ''), - estimatedShippingDate: String( - form.get('estimatedShippingDate').value || '' - ), + estimatedShippingDate: String(form.get('estimatedShippingDate').value || ''), }; } @@ -227,13 +178,11 @@ export class ShelfEditFormService { return this.formBuilder.group({ orderId: [{ value: orderItem.orderId, disabled: true }], orderItemId: [{ value: orderItem.orderItemId, disabled: true }], - orderItemSubsetId: [ - { value: orderItem.orderItemSubsetId, disabled: true }, - ], + orderItemSubsetId: [{ value: orderItem.orderItemSubsetId, disabled: true }], quantity: [{ value: orderItem.quantity, disabled: true }], price: [ - { value: orderItem.price, disabled: false }, - [Validators.required], + { value: String(orderItem.price).replace('.', ','), disabled: false }, + [Validators.required, Validators.pattern(/^\d+(,\d{1,2})?$/)], ], ean: [ { @@ -245,9 +194,7 @@ export class ShelfEditFormService { title: [{ value: orderItem.product.name, disabled: true }], ssc: [ { - value: orderItem.ssc - ? orderItem.ssc + ' - ' + orderItem.sscText - : '-', + value: orderItem.ssc ? orderItem.ssc + ' - ' + orderItem.sscText : '-', disabled: false, }, ], @@ -259,41 +206,58 @@ export class ShelfEditFormService { disabled: false, }, ], - comment: [{ value: orderItem.specialComment || '-', disabled: false }], + comment: [{ value: orderItem.specialComment, disabled: false }], }); } - getDataFromItemForm(form: AbstractControl): OrderItemListItemDTO { + getOrderItemFromItemForm(form: AbstractControl): OrderItemDTO { return { - orderId: Number(form.get('orderId').value), - orderItemId: Number(form.get('orderItemId').value), - orderItemSubsetId: Number(form.get('orderItemSubsetId').value), + id: Number(form.get('orderItemId').value), quantity: Number(form.get('quantity').value), - price: Number(form.get('price').value), - vatType: Number(form.get('vat').value) as VATType, - specialComment: String(form.get('comment').value), + grossPrice: { + vat: { vatType: Number(form.get('vat').value) as VATType }, + value: { value: Number(form.get('price').value.replace(',', '.')) }, + }, + product: { ean: String(form.get('ean').value) }, }; } - async submit( - form: FormGroup, - processingStatus: OrderItemProcessingStatusValue - ): Promise { + getOrderItemSubsetFromItemForm(ctrl: AbstractControl, form: FormGroup): OrderItemSubsetDTO & { orderItemId: number } { + const sscFull: string = ctrl.get('ssc').value; + let ssc = sscFull.split('-')[0]; + let sscText = sscFull.substr(ssc.length + 1); + + ssc = ssc.trim(); + sscText = sscText.trim(); + + return { + id: Number(ctrl.get('orderItemSubsetId').value), + orderItemId: Number(ctrl.get('orderItemId').value), + processingStatus: form.get('processingStatus').value, + estimatedShippingDate: String(form.get('estimatedShippingDate').value), + compartmentCode: !!form.get('compartmentCode').value ? String(form.get('compartmentCode').value) : null, + specialComment: String(ctrl.get('comment').value), + ssc, + sscText, + }; + } + + async submit(form: FormGroup, processingStatus: OrderItemProcessingStatusValue): Promise { const formData = this.getDataFromGeneralForm(form); + console.log({ formData }); - const patch = this.preparePatch(form, formData); - const newProcessingStatus = Number( - form.get('processingStatus').value - ) as OrderItemProcessingStatusValue; + + const orderItemsToPatch = this.prepareOrderItems(form); + const orderItemSubsetsToPatch = this.prepareOrderItemSubsets(form); + + const newProcessingStatus = Number(form.get('processingStatus').value) as OrderItemProcessingStatusValue; try { - await this.detailsStoreFacade.patchOrderItems(patch); - await this.detailsStoreFacade.patchOrderItemSubsets(patch); + await this.detailsStoreFacade.patchOrderItems(orderItemsToPatch); + await this.detailsStoreFacade.patchOrderItemSubsets(orderItemSubsetsToPatch); + if (newProcessingStatus !== processingStatus) { - const changeStatusData = this.prepareStatusChange( - form, - newProcessingStatus - ); + const changeStatusData = this.prepareStatusChange(form, newProcessingStatus); if (newProcessingStatus === 128) { await this.detailsStoreFacade.arrived(changeStatusData, undefined); } else { @@ -308,49 +272,49 @@ export class ShelfEditFormService { return true; } - private preparePatch( - form: FormGroup, - { - estimatedShippingDate, - pickUpDeadline, - }: { estimatedShippingDate: string; pickUpDeadline: string } + private prepareOrderItems(form: FormGroup) { + const orderItems = (form.get('items') as FormArray).controls.map((control) => this.getOrderItemFromItemForm(control)); + + return orderItems.map((orderItem) => ({ + orderId: Number(form.get('orderId').value), + orderItemId: orderItem.id, + orderItem, + })); + } + + private prepareOrderItemSubsets( + form: FormGroup ): { orderId: number; orderItemId: number; orderItemSubsetId: number; - orderItem: Partial; orderItemSubset: Partial; }[] { - const items = (form.get('items') as FormArray).controls.map((control) => - this.getDataFromItemForm(control) - ); + const subsetItems = (form.get('items') as FormArray).controls.map((control) => this.getOrderItemSubsetFromItemForm(control, form)); - return items.map((item) => ({ - orderId: item.orderId, + return subsetItems.map((item) => ({ + orderId: form.get('orderId').value, orderItemId: item.orderItemId, - orderItemSubsetId: item.orderItemSubsetId, - orderItem: { - ...item, - estimatedShippingDate, - pickUpDeadline, - }, - orderItemSubset: { estimatedShippingDate }, + orderItemSubsetId: item.id, + orderItemSubset: { ...item }, })); } private prepareStatusChange( form: FormGroup, processingStatus: OrderItemProcessingStatusValue - ) { - console.log({ form2: form }); - const items = (form.get('items') as FormArray).controls.map((itemForm) => - this.getDataFromItemForm(itemForm) - ); + ): { + orderItemSubsetId: number; + orderItemId: number; + orderId: number; + data: StatusValues; + }[] { + const items = (form.get('items') as FormArray).controls.map((itemForm) => this.getOrderItemSubsetFromItemForm(itemForm, form)); return items.map((item) => ({ - orderId: item.orderId, - orderItemId: item.orderItemId, - orderItemSubsetId: item.orderItemSubsetId, + orderId: Number(form.get('orderId').value), + orderItemId: Number(form.get('orderItemId').value), + orderItemSubsetId: Number(form.get('orderItemSubsetId').value), data: { processingStatus } as StatusValues, })); } diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index 6871fc459..86a7cb7e4 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -1,15 +1,8 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Store } from '@ngxs/store'; -import { - AddBreadcrumb, - UpdateCurrentBreadcrumbName, - PopLastBreadcrumbs, -} from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; -import { - ChangeCurrentRoute, - AddProcess, -} from 'apps/sales/src/app/core/store/actions/process.actions'; +import { AddBreadcrumb, UpdateCurrentBreadcrumbName, PopLastBreadcrumbs } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; +import { ChangeCurrentRoute, AddProcess } from 'apps/sales/src/app/core/store/actions/process.actions'; import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model'; import { OrderItemListItemDTO } from '@swagger/oms/lib'; import { ProcessSelectors } from 'apps/sales/src/app/core/store/selectors/process.selectors'; @@ -19,11 +12,7 @@ import { Process } from 'apps/sales/src/app/core/models/process.model'; export class ShelfNavigationService { constructor(private store: Store, private router: Router) {} - navigateToDetails(order: { - orderNumber?: string; - compartmentCode?: string; - processingStatus?: number; - }) { + navigateToDetails(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { this.createTab(); const path = this.getDetailsPath(order); const breadcrumb = this.getDetailsBreadcrumb(order); @@ -31,11 +20,7 @@ export class ShelfNavigationService { this.navigateToRoute(path, breadcrumb); } - navigateToEdit(order: { - orderNumber?: string; - compartmentCode?: string; - processingStatus?: number; - }) { + navigateToEdit(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { this.createTab(); const path = this.getDetailsPath({ ...order, edit: true }); const breadcrumb = this.getEditBreadCrumb(); @@ -43,11 +28,7 @@ export class ShelfNavigationService { this.navigateToRoute(path, breadcrumb); } - updateDetailsNavigation(order: { - orderNumber?: string; - compartmentCode?: string; - processingStatus?: number; - }) { + updateDetailsNavigation(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { const path = this.getDetailsPath(order); const breadcrumb = this.getDetailsBreadcrumb(order); this.replaceRoute(path, breadcrumb); @@ -59,13 +40,7 @@ export class ShelfNavigationService { this.replaceRoute(path, breadcrumb); } - navigateToResultList({ - searchQuery, - numberOfHits, - }: { - searchQuery: string; - numberOfHits: number; - }) { + navigateToResultList({ searchQuery, numberOfHits }: { searchQuery: string; numberOfHits: number }) { this.createTab(); const path = '/shelf/results'; const breadcrumb = this.getResultListBreadcrumb(searchQuery, numberOfHits); @@ -73,17 +48,12 @@ export class ShelfNavigationService { } navigateToHistory(orderitem: OrderItemListItemDTO) { - this.navigateToRoute( - `shelf/history/${orderitem.orderItemSubsetId}`, - `Historie ${orderitem.orderItemSubsetId}` - ); + this.navigateToRoute(`shelf/history/${orderitem.orderItemSubsetId}`, `Historie ${orderitem.orderItemSubsetId}`); } private replaceRoute(route: string, breadcrumbName: string) { this.router.navigate([route]); - this.store.dispatch( - new UpdateCurrentBreadcrumbName(breadcrumbName, 'shelf') - ); + this.store.dispatch(new UpdateCurrentBreadcrumbName(breadcrumbName, 'shelf')); } private navigateToRoute(route: string, breadcrumbName: string) { @@ -100,27 +70,49 @@ export class ShelfNavigationService { this.router.navigate([route]); } - public navigateBackToDetails(data: { - orderNumber?: string; - compartmentCode?: string; - processingStatus?: number; - }) { + public navigateBackToDetails( + data: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }, + previous?: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + } + ) { this.store.dispatch(new PopLastBreadcrumbs(this.getEditBreadCrumb())); + if (previous) { + this.store.dispatch(new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous))); + } this.navigateToDetails(data); } - private getResultListBreadcrumb( - searchQuery: string, - numberOfHits: number - ): string { + public updateDetails( + data: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }, + previous?: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + } + ) { + if (previous) { + this.store.dispatch(new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous))); + } + this.navigateToDetails(data); + } + + private getResultListBreadcrumb(searchQuery: string, numberOfHits: number): string { return `${searchQuery} (${numberOfHits} Ergebnisse)`; } - getDetailsBreadcrumb(data: { - orderNumber?: string; - compartmentCode?: string; - }): string { + getDetailsBreadcrumb(data: { orderNumber?: string; compartmentCode?: string }): string { if (data.compartmentCode) { return `${data.compartmentCode}`; } @@ -131,12 +123,7 @@ export class ShelfNavigationService { return 'Bearbeiten'; } - private getDetailsPath(data: { - orderNumber?: string; - compartmentCode?: string; - processingStatus?: number; - edit?: boolean; - }): string { + private getDetailsPath(data: { orderNumber?: string; compartmentCode?: string; processingStatus?: number; edit?: boolean }): string { let url = ''; if (data.compartmentCode) { url = `/shelf/details/compartment/${data.compartmentCode}/${data.processingStatus}`; @@ -152,8 +139,7 @@ export class ShelfNavigationService { } private createTab() { - const processExists = - this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0; + const processExists = this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0; if (!processExists) { this.createProcess(); } diff --git a/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss b/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss index 25f877610..eac7ac515 100644 --- a/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss +++ b/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss @@ -18,6 +18,12 @@ th { height: 41px; } +.is-today { + border: 1px dashed $datepicker-selected-cell-bg-color; + border-radius: 50%; + font-weight: 700; +} + .cell-not-in-range { color: $datepicker-cell-not-in-range-color; } @@ -29,4 +35,5 @@ th { .cell-selected { background-color: $datepicker-selected-cell-bg-color; border-radius: 22px; + font-weight: 700; } diff --git a/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts b/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts index 440ae5170..8c0d62b3d 100644 --- a/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts +++ b/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts @@ -30,6 +30,9 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { @HostBinding('class.cell-not-in-range') notInRange: boolean; + @HostBinding('class.is-today') + isToday: boolean; + private subscription = new Subscription(); constructor(private datepicker: Datepicker, private dateAdapter: DateAdapter) {} @@ -38,6 +41,7 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { this.initDisplayed$(); this.initSelected$(); this.initRange$(); + this.initToday$(); } initDisplayed$() { @@ -69,6 +73,13 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { this.subscription.add(sub); } + initToday$() { + const sub = this.dateSubject.subscribe((date) => { + this.isToday = this.dateAdapter.compareDate(date, this.dateAdapter.today()) === 0; + }); + this.subscription.add(sub); + } + ngOnDestroy(): void { this.subscription.unsubscribe(); this.dateSubject.complete(); diff --git a/apps/sales/src/app/modules/ui/select-input/select-input.component.html b/apps/sales/src/app/modules/ui/select-input/select-input.component.html index 123e44f3b..0a5bd50a5 100644 --- a/apps/sales/src/app/modules/ui/select-input/select-input.component.html +++ b/apps/sales/src/app/modules/ui/select-input/select-input.component.html @@ -4,7 +4,8 @@ {{ label }} - {{ labelPipe ? labelPipe.transform(value) : value }} + {{ labelPipe ? labelPipe.transform(value) : value }} diff --git a/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts b/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts index a7c237301..b21d03238 100644 --- a/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts +++ b/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts @@ -1,10 +1,4 @@ -import { - Component, - ChangeDetectionStrategy, - forwardRef, - Input, - ChangeDetectorRef, -} from '@angular/core'; +import { Component, ChangeDetectionStrategy, forwardRef, Input, ChangeDetectorRef } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; import { asyncScheduler } from 'rxjs'; @@ -24,6 +18,7 @@ import { asyncScheduler } from 'rxjs'; export class UiTextInputComponent implements ControlValueAccessor { @Input() label = ''; @Input() suffix: string; + @Input() placeholder: string; constructor(private cdr: ChangeDetectorRef) {} diff --git a/apps/sales/src/app/modules/ui/text-input/text-input.component.html b/apps/sales/src/app/modules/ui/text-input/text-input.component.html index d22b4d188..14332a578 100644 --- a/apps/sales/src/app/modules/ui/text-input/text-input.component.html +++ b/apps/sales/src/app/modules/ui/text-input/text-input.component.html @@ -1,23 +1,13 @@
- + Nicht Änderbar -
+
\ No newline at end of file diff --git a/apps/sales/src/app/store/customer/shelf/details/details.effects.ts b/apps/sales/src/app/store/customer/shelf/details/details.effects.ts index ea3e5f28d..4679a495e 100644 --- a/apps/sales/src/app/store/customer/shelf/details/details.effects.ts +++ b/apps/sales/src/app/store/customer/shelf/details/details.effects.ts @@ -2,9 +2,9 @@ import { Injectable } from '@angular/core'; import { Actions, ofType, createEffect } from '@ngrx/effects'; import * as actions from './details.actions'; -import { flatMap, catchError, map, concatMap } from 'rxjs/operators'; +import { flatMap, catchError, map } from 'rxjs/operators'; import { OrderService, StrictHttpResponse, ListResponseArgsOfOrderItemListItemDTO, AbholfachService } from '@swagger/oms'; -import { of, NEVER, zip, combineLatest } from 'rxjs'; +import { of, NEVER } from 'rxjs'; import { SearchStateFacade } from '../search'; @Injectable() diff --git a/apps/sales/src/app/store/customer/shelf/details/details.facade.ts b/apps/sales/src/app/store/customer/shelf/details/details.facade.ts index 80bb2dcb9..7ce8ecf2a 100644 --- a/apps/sales/src/app/store/customer/shelf/details/details.facade.ts +++ b/apps/sales/src/app/store/customer/shelf/details/details.facade.ts @@ -134,7 +134,7 @@ export class DetailsFacade { orderId, orderItemId, orderItemSubsetId, - data: { processingStatus: 8192 } as StatusValues, + data: { processingStatus: 8192, compartmentNumber: '', compartmentInfo: '' } as StatusValues, })); return this.changeStatus(data); } diff --git a/apps/sales/src/scss/_typography.scss b/apps/sales/src/scss/_typography.scss index 5ea0a06d9..77496766f 100644 --- a/apps/sales/src/scss/_typography.scss +++ b/apps/sales/src/scss/_typography.scss @@ -36,3 +36,7 @@ .isa-font-lightgrey { color: $text-lightgrey; } + +.isa-white-space-nowrap { + white-space: nowrap; +} diff --git a/apps/sales/src/scss/modules/_button.scss b/apps/sales/src/scss/modules/_button.scss index f63fb6990..87f10363f 100644 --- a/apps/sales/src/scss/modules/_button.scss +++ b/apps/sales/src/scss/modules/_button.scss @@ -32,6 +32,11 @@ padding: 12px 25px; } +.isa-btn-large { + font-size: 18px; + padding: 16px 20px; +} + .isa-btn-primary { color: $text-light; background-color: $isa-red; From 1620df76b9c1547151410176aa88ee538344c7ba Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Tue, 1 Sep 2020 18:38:41 +0200 Subject: [PATCH 098/135] =?UTF-8?q?Header=20zur=20Hinstory=20hinzugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../header/history-header.component.html | 15 +---- .../header/history-header.component.scss | 4 ++ .../header/history-header.component.ts | 56 ++++++++++++++++--- .../shelf-history-logs.component.html | 16 ++---- .../shelf-history-logs.component.ts | 10 ++-- .../shelf-history.component.html | 9 ++- .../shelf-history/shelf-history.component.ts | 45 +++++++++------ .../shelf-history/shelf-history.module.ts | 17 ++---- .../shelf-order-details.component.ts | 41 +++++++------- .../services/shelf-navigation.service.ts | 10 +++- .../app/modules/shelf/shelf-routing.module.ts | 6 +- 11 files changed, 134 insertions(+), 95 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html index 4a5454d76..a1f9b41c1 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html @@ -1,17 +1,6 @@

Historie

- +
-
- - -

- Es liegen keine Detailinformation zum Produkt (Bestell-Id: - {{ orderItemSubsetId }}) vor. -

-
+ \ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.scss b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.scss index 24ee3827c..2f89f7497 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.scss +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.scss @@ -16,3 +16,7 @@ .default-template { margin-top: 0; } + +.content { + width: 100%; +} diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts index 2dbe20e86..46a0d3532 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts @@ -1,10 +1,10 @@ -import { - Component, - ChangeDetectionStrategy, - Input, - TemplateRef, -} from '@angular/core'; +import { Component, ChangeDetectionStrategy, Input, TemplateRef, OnInit } from '@angular/core'; import { HistoryStateFacade } from '@shelf-store/history'; +import { DetailsFacade } from '@shelf-store/details'; +import { OrderDetailsCardInput } from '../../../components/order-details-card'; +import { OrderItemListItemDTO } from '@swagger/oms/lib'; +import { Observable } from 'rxjs'; +import { map, filter } from 'rxjs/operators'; @Component({ selector: 'app-shelf-history-header', @@ -12,13 +12,53 @@ import { HistoryStateFacade } from '@shelf-store/history'; styleUrls: ['./history-header.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ShelfHistoryHeaderComponent { +export class ShelfHistoryHeaderComponent implements OnInit { + @Input() orderId: any; + @Input() compartmentCode: string; + @Input() orderItemId: number; @Input() orderItemSubsetId: number; @Input() headerTemplate: TemplateRef; - constructor(private historyStateFacade: HistoryStateFacade) {} + details$: Observable; + + orderItems$: Observable; + + constructor(private detailsFacade: DetailsFacade, private historyStateFacade: HistoryStateFacade) {} + + ngOnInit() { + if (this.compartmentCode) { + this.orderItems$ = this.detailsFacade.getOrderItemsByCompartmentCode$(this.compartmentCode); + } else if (this.orderId) { + this.orderItems$ = this.detailsFacade.getOrderItemsByOrderNumber$(this.orderId); + } + + this.details$ = this.orderItems$.pipe( + map((items) => { + if (items.length > 0) { + const item = items[0]; + return { + firstName: item.firstName, + lastName: item.lastName, + customerNumber: item.buyerNumber, + estimatedShippingDate: item.estimatedShippingDate ? new Date(item.estimatedShippingDate) : undefined, + orderDate: new Date(item.orderDate), + orderNumber: item.orderNumber, + processingStatus: item.processingStatus, + orderChannel: item.clientChannel, + compartmentCode: item.compartmentCode, + compartmentInfo: item.compartmentInfo, + pickupDeadline: new Date(item.pickUpDeadline), + } as OrderDetailsCardInput; + } + return undefined; + }), + filter((details) => !!details) + ); + } updateHistory() { this.historyStateFacade.reloadHistory(this.orderItemSubsetId); } + + updateDetails() {} } diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html index e30990e9e..191952995 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html @@ -1,20 +1,14 @@
- +
- + " [history]="history" [first]="first" [last]="last">
-
+ \ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts index 51272fcb9..0ab95edd8 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts @@ -1,9 +1,4 @@ -import { - Component, - OnInit, - ChangeDetectionStrategy, - Input, -} from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core'; import { Observable } from 'rxjs'; import { HistoryDTO } from '@cmf/trade-api'; import { HistoryStateFacade } from '@shelf-store/history'; @@ -15,6 +10,9 @@ import { HistoryStateFacade } from '@shelf-store/history'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ShelfHistoryLogsComponent implements OnInit { + @Input() orderId: number; + @Input() compartmentCode: string; + @Input() orderItemId: number; @Input() orderItemSubsetId: number; history$: Observable; diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html index 958a37015..b612fa20b 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html @@ -1,8 +1,7 @@ - + +
-
+ \ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts index d5a0079dd..fd9f463a2 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts @@ -1,14 +1,7 @@ import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; -import { - filter, - map, - switchMap, - distinctUntilChanged, - tap, - shareReplay, -} from 'rxjs/operators'; +import { filter, map, switchMap, distinctUntilChanged, tap, shareReplay } from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; import { HistoryDTO } from '@cmf/trade-api'; import { HistoryStateFacade } from '@shelf-store/history'; @@ -22,16 +15,19 @@ import { OrderHistoryStatus } from '@shelf-store/defs'; }) export class ShelfHistoryComponent implements OnInit { status$: Observable; + orderId$: Observable; + compartmentCode$: Observable; + orderItemId$: Observable; orderItemSubsetId$: Observable; - constructor( - private activatedRoute: ActivatedRoute, - private historyStateFacade: HistoryStateFacade - ) {} + constructor(private activatedRoute: ActivatedRoute, private historyStateFacade: HistoryStateFacade) {} ngOnInit() { this.status$ = this.getStatus(); this.orderItemSubsetId$ = this.getOrderItemSubsetId$(); + this.orderId$ = this.getOrderId$(); + this.orderItemId$ = this.getOrderItemId$(); + this.compartmentCode$ = this.getCompartmentCode$(); } fetchHistory = (orderItemSubsetId: number) => { @@ -39,10 +35,27 @@ export class ShelfHistoryComponent implements OnInit { }; getStatus() { - return this.getOrderItemSubsetId$().pipe( - switchMap((orderItemSubsetId) => - this.historyStateFacade.getStatus$(orderItemSubsetId) - ) + return this.getOrderItemSubsetId$().pipe(switchMap((orderItemSubsetId) => this.historyStateFacade.getStatus$(orderItemSubsetId))); + } + + getOrderId$(): Observable { + return this.activatedRoute.params.pipe( + filter((params) => !isNullOrUndefined(params)), + map((params) => Number(params.orderId)) + ); + } + + getCompartmentCode$(): Observable { + return this.activatedRoute.params.pipe( + filter((params) => !isNullOrUndefined(params)), + map((params) => params.compartmentCode) + ); + } + + getOrderItemId$(): Observable { + return this.activatedRoute.params.pipe( + filter((params) => !isNullOrUndefined(params)), + map((params) => Number(params.orderItemId)) ); } diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts index 29b4f9ca8..e2987ab96 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts @@ -5,21 +5,12 @@ import { ShelfHistoryComponent } from './shelf-history.component'; import { ShelfHistoryLogsComponent } from './history-logs'; import { FilterHistoriesWithStatusChangePipe } from './pipes'; import { ShelfHistoryHeaderComponent } from './header'; +import { ShelfOrderDetailsCardModule } from '../../components/order-details-card'; @NgModule({ - imports: [CommonModule, ShelfHistoryLogModule], - exports: [ - ShelfHistoryComponent, - ShelfHistoryHeaderComponent, - ShelfHistoryLogsComponent, - FilterHistoriesWithStatusChangePipe, - ], - declarations: [ - ShelfHistoryComponent, - ShelfHistoryHeaderComponent, - ShelfHistoryLogsComponent, - FilterHistoriesWithStatusChangePipe, - ], + imports: [CommonModule, ShelfHistoryLogModule, ShelfOrderDetailsCardModule], + exports: [ShelfHistoryComponent, ShelfHistoryHeaderComponent, ShelfHistoryLogsComponent, FilterHistoriesWithStatusChangePipe], + declarations: [ShelfHistoryComponent, ShelfHistoryHeaderComponent, ShelfHistoryLogsComponent, FilterHistoriesWithStatusChangePipe], providers: [], }) export class ShelfHistoryModule {} diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts index 3694d5aa3..89869bfd0 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts @@ -1,19 +1,7 @@ import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core'; import { DetailsFacade } from '@shelf-store/details'; import { ActivatedRoute } from '@angular/router'; -import { - map, - switchMap, - first, - filter, - flatMap, - distinctUntilChanged, - shareReplay, - tap, - take, - takeUntil, - withLatestFrom, -} from 'rxjs/operators'; +import { map, switchMap, first, filter, flatMap, distinctUntilChanged, shareReplay, take, takeUntil, withLatestFrom } from 'rxjs/operators'; import { OrderDetailsCardInput } from '../../components/order-details-card'; import { OrderItemProcessingStatusValue, @@ -22,11 +10,9 @@ import { ResponseArgsOfValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO, } from '@swagger/oms'; import { ShelfNavigationService } from '../../shared/services'; -import { race, combineLatest, Observable } from 'rxjs'; -import { RemissionService } from '@isa/remission'; -import { ProcessingStatusNameMap } from '../../constants'; +import { race, combineLatest } from 'rxjs'; import { AppService } from '@sales/core-services'; -import { OMSPrintService } from '@swagger/print'; +import { OMSPrintService, PrintService } from '@swagger/print'; import { PrinterSelectionComponent } from 'apps/sales/src/app/components/printer-selection/printer-selection.component'; @Component({ @@ -127,7 +113,8 @@ export class ShelfOrderDetailsComponent { private activatedRoute: ActivatedRoute, private detailsFacade: DetailsFacade, private shelfNavigationService: ShelfNavigationService, - private printService: OMSPrintService, + private omsPrintService: OMSPrintService, + private printerService: PrintService, private appService: AppService ) {} @@ -210,9 +197,9 @@ export class ShelfOrderDetailsComponent { }); } - printAbholfachetikett(data: number[]) { + async printAbholfachetikett(data: number[]) { const print = (printer?: string) => - this.printService + this.omsPrintService .OMSPrintAbholfachetikettResponse({ data, printer, @@ -226,10 +213,22 @@ export class ShelfOrderDetailsComponent { this.printerSlectionComponent.closeModal(); }); } else { - print(); + const defaultPrinter = await this.getDefaultPrinter(); + print(defaultPrinter); } } + async getDefaultPrinter(): Promise { + const printers = await this.printerService.PrintPrinters().toPromise(); + const selected = printers.result.find((f) => f.selected); + + if (!!selected) { + return selected.key; + } + + return undefined; + } + activatePartialPickup() { this.partialPickup = true; } diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index 86a7cb7e4..2db74b1ba 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -48,7 +48,15 @@ export class ShelfNavigationService { } navigateToHistory(orderitem: OrderItemListItemDTO) { - this.navigateToRoute(`shelf/history/${orderitem.orderItemSubsetId}`, `Historie ${orderitem.orderItemSubsetId}`); + this.navigateToRoute(this.getHistoryPath(orderitem), `Historie ${orderitem.orderItemSubsetId}`); + } + + getHistoryPath(data: { orderId?: number; compartmentCode?: string; orderItemId?: number; orderItemSubsetId?: number }) { + if (data.compartmentCode) { + return `/shelf/details/compartment/${data.compartmentCode}/item/${data.orderItemId}/subset/${data.orderItemSubsetId}/history`; + } else if (data.orderId) { + return `/shelf/details/order/${data.orderId}/item/${data.orderItemId}/subset/${data.orderItemSubsetId}/history`; + } } private replaceRoute(route: string, breadcrumbName: string) { diff --git a/apps/sales/src/app/modules/shelf/shelf-routing.module.ts b/apps/sales/src/app/modules/shelf/shelf-routing.module.ts index c3ade3bd1..9cec8f986 100644 --- a/apps/sales/src/app/modules/shelf/shelf-routing.module.ts +++ b/apps/sales/src/app/modules/shelf/shelf-routing.module.ts @@ -34,7 +34,11 @@ export const routes: Routes = [ component: ShelfEditCompartmentComponent, }, { - path: 'history/:orderItemSubsetId', + path: 'details/order/:orderId/item/:orderItemId/subset/:orderItemSubsetId/history', + component: ShelfHistoryComponent, + }, + { + path: 'details/compartment/:compartmentCode/item/:orderItemId/subset/:orderItemSubsetId/history', component: ShelfHistoryComponent, }, ]; From e4a58baba0c70a0c8c67843f29b122f3be61605e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 1 Sep 2020 20:49:35 +0200 Subject: [PATCH 099/135] Fix SpecialComment Patch with undefined --- .../shelf/services/shelf-edit-form.service.ts | 139 ++++++++++++++---- 1 file changed, 108 insertions(+), 31 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts index 4189f2356..1a64f61d7 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts @@ -1,5 +1,11 @@ import { Injectable, ɵbypassSanitizationTrustResourceUrl } from '@angular/core'; -import { FormBuilder, FormGroup, Validators, FormArray, AbstractControl } from '@angular/forms'; +import { + FormBuilder, + FormGroup, + Validators, + FormArray, + AbstractControl, +} from '@angular/forms'; import { Observable, of, from } from 'rxjs'; import { OrderItemListItemDTO, @@ -43,7 +49,10 @@ export class ShelfEditFormService { return this.vats$.pipe(filter((vats) => !!vats.length)); } - constructor(private formBuilder: FormBuilder, private detailsStoreFacade: DetailsFacade) {} + constructor( + private formBuilder: FormBuilder, + private detailsStoreFacade: DetailsFacade + ) {} public getItemsForm(compartmentCode: string): FormArray { if (!this.forms.has(compartmentCode)) { @@ -52,7 +61,9 @@ export class ShelfEditFormService { return this.forms.get(compartmentCode).get('items') as FormArray; } - public getCustomerName(compartmentCode: string): { firstName: string; lastName: string } { + public getCustomerName( + compartmentCode: string + ): { firstName: string; lastName: string } { if (!this.forms.has(compartmentCode)) { return { firstName: 'unbekannt', @@ -67,8 +78,14 @@ export class ShelfEditFormService { }; } - async createFormByOrderNumber(orderNumber: string, processingStatus: OrderItemProcessingStatusValue): Promise { - const controlsConfig = await this.getControlsConfigForOrder(orderNumber, processingStatus); + async createFormByOrderNumber( + orderNumber: string, + processingStatus: OrderItemProcessingStatusValue + ): Promise { + const controlsConfig = await this.getControlsConfigForOrder( + orderNumber, + processingStatus + ); const form = this.formBuilder.group(controlsConfig); this.forms.set(orderNumber, form); @@ -76,8 +93,14 @@ export class ShelfEditFormService { return this.forms.get(orderNumber); } - async createFormByCompartmentCode(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue): Promise { - const controlsConfig = await this.getControlsConfigForCompartment(compartmentCode, processingStatus); + async createFormByCompartmentCode( + compartmentCode: string, + processingStatus: OrderItemProcessingStatusValue + ): Promise { + const controlsConfig = await this.getControlsConfigForCompartment( + compartmentCode, + processingStatus + ); const form = this.formBuilder.group(controlsConfig); this.forms.set(compartmentCode, form); @@ -85,8 +108,13 @@ export class ShelfEditFormService { return this.forms.get(compartmentCode); } - async getControlsConfigForOrder(orderNumber: string, processingStatus: OrderItemProcessingStatusValue): Promise<{ [key: string]: any }> { - const orderItems$: Observable = this.detailsStoreFacade.getOrderItemsByOrderNumberAndProcessingStatus$( + async getControlsConfigForOrder( + orderNumber: string, + processingStatus: OrderItemProcessingStatusValue + ): Promise<{ [key: string]: any }> { + const orderItems$: Observable< + OrderItemListItemDTO[] + > = this.detailsStoreFacade.getOrderItemsByOrderNumberAndProcessingStatus$( orderNumber, processingStatus ); @@ -98,14 +126,18 @@ export class ShelfEditFormService { compartmentCode: string, processingStatus: OrderItemProcessingStatusValue ): Promise<{ [key: string]: any }> { - const orderItems$: Observable = this.detailsStoreFacade.getOrderItemsByCompartmentCodeAndProcessingStatus$( + const orderItems$: Observable< + OrderItemListItemDTO[] + > = this.detailsStoreFacade.getOrderItemsByCompartmentCodeAndProcessingStatus$( compartmentCode, processingStatus ); return this.createControlConfig(orderItems$); } - private async createControlConfig(orderItems$: Observable): Promise<{ [key: string]: any }> { + private async createControlConfig( + orderItems$: Observable + ): Promise<{ [key: string]: any }> { const orderItems = await orderItems$ .pipe( filter((items) => !isNullOrUndefined(items) && !!items.length), @@ -117,7 +149,9 @@ export class ShelfEditFormService { return { ...this.getGeneralForm(orderItems), - items: this.formBuilder.array(orderItems.map((orderItem) => this.getItemForm(orderItem, vats))), + items: this.formBuilder.array( + orderItems.map((orderItem) => this.getItemForm(orderItem, vats)) + ), }; } @@ -126,7 +160,9 @@ export class ShelfEditFormService { return { firstName: baseOrderItem.firstName, lastName: baseOrderItem.lastName, - compartmentCode: [{ value: baseOrderItem.compartmentCode, disabled: false }], + compartmentCode: [ + { value: baseOrderItem.compartmentCode, disabled: false }, + ], orderId: [{ value: baseOrderItem.orderId, disabled: true }], orderNumber: [ { @@ -142,13 +178,19 @@ export class ShelfEditFormService { ], clientChannel: [ { - value: new EnvironmentChannelPipe().transform(baseOrderItem.clientChannel), + value: new EnvironmentChannelPipe().transform( + baseOrderItem.clientChannel + ), disabled: true, }, ], buyerNumber: [{ value: baseOrderItem.buyerNumber, disabled: true }], - processingStatus: [{ value: baseOrderItem.processingStatus, disabled: false }], - estimatedShippingDate: [{ value: baseOrderItem.estimatedShippingDate, disabled: false }], + processingStatus: [ + { value: baseOrderItem.processingStatus, disabled: false }, + ], + estimatedShippingDate: [ + { value: baseOrderItem.estimatedShippingDate, disabled: false }, + ], pickUpDeadline: [ { value: baseOrderItem.pickUpDeadline, @@ -166,11 +208,17 @@ export class ShelfEditFormService { orderId: Number(form.get('orderId').value), orderNumber: form.get('orderNumber').value, orderDate: new Date(form.get('orderDate').value), - clientChannel: Number(form.get('clientChannel').value) as EnvironmentChannel, + clientChannel: Number( + form.get('clientChannel').value + ) as EnvironmentChannel, buyerNumber: form.get('buyerNumber').value, - processingStatus: Number(form.get('processingStatus').value) as OrderItemProcessingStatusValue, + processingStatus: Number( + form.get('processingStatus').value + ) as OrderItemProcessingStatusValue, pickUpDeadline: String(form.get('pickUpDeadline').value || ''), - estimatedShippingDate: String(form.get('estimatedShippingDate').value || ''), + estimatedShippingDate: String( + form.get('estimatedShippingDate').value || '' + ), }; } @@ -178,7 +226,9 @@ export class ShelfEditFormService { return this.formBuilder.group({ orderId: [{ value: orderItem.orderId, disabled: true }], orderItemId: [{ value: orderItem.orderItemId, disabled: true }], - orderItemSubsetId: [{ value: orderItem.orderItemSubsetId, disabled: true }], + orderItemSubsetId: [ + { value: orderItem.orderItemSubsetId, disabled: true }, + ], quantity: [{ value: orderItem.quantity, disabled: true }], price: [ { value: String(orderItem.price).replace('.', ','), disabled: false }, @@ -194,7 +244,9 @@ export class ShelfEditFormService { title: [{ value: orderItem.product.name, disabled: true }], ssc: [ { - value: orderItem.ssc ? orderItem.ssc + ' - ' + orderItem.sscText : '-', + value: orderItem.ssc + ? orderItem.ssc + ' - ' + orderItem.sscText + : '-', disabled: false, }, ], @@ -222,7 +274,10 @@ export class ShelfEditFormService { }; } - getOrderItemSubsetFromItemForm(ctrl: AbstractControl, form: FormGroup): OrderItemSubsetDTO & { orderItemId: number } { + getOrderItemSubsetFromItemForm( + ctrl: AbstractControl, + form: FormGroup + ): OrderItemSubsetDTO & { orderItemId: number } { const sscFull: string = ctrl.get('ssc').value; let ssc = sscFull.split('-')[0]; let sscText = sscFull.substr(ssc.length + 1); @@ -235,14 +290,19 @@ export class ShelfEditFormService { orderItemId: Number(ctrl.get('orderItemId').value), processingStatus: form.get('processingStatus').value, estimatedShippingDate: String(form.get('estimatedShippingDate').value), - compartmentCode: !!form.get('compartmentCode').value ? String(form.get('compartmentCode').value) : null, - specialComment: String(ctrl.get('comment').value), + compartmentCode: !!form.get('compartmentCode').value + ? String(form.get('compartmentCode').value) + : null, + specialComment: String(ctrl.get('comment').value) || null, ssc, sscText, }; } - async submit(form: FormGroup, processingStatus: OrderItemProcessingStatusValue): Promise { + async submit( + form: FormGroup, + processingStatus: OrderItemProcessingStatusValue + ): Promise { const formData = this.getDataFromGeneralForm(form); console.log({ formData }); @@ -250,14 +310,21 @@ export class ShelfEditFormService { const orderItemsToPatch = this.prepareOrderItems(form); const orderItemSubsetsToPatch = this.prepareOrderItemSubsets(form); - const newProcessingStatus = Number(form.get('processingStatus').value) as OrderItemProcessingStatusValue; + const newProcessingStatus = Number( + form.get('processingStatus').value + ) as OrderItemProcessingStatusValue; try { await this.detailsStoreFacade.patchOrderItems(orderItemsToPatch); - await this.detailsStoreFacade.patchOrderItemSubsets(orderItemSubsetsToPatch); + await this.detailsStoreFacade.patchOrderItemSubsets( + orderItemSubsetsToPatch + ); if (newProcessingStatus !== processingStatus) { - const changeStatusData = this.prepareStatusChange(form, newProcessingStatus); + const changeStatusData = this.prepareStatusChange( + form, + newProcessingStatus + ); if (newProcessingStatus === 128) { await this.detailsStoreFacade.arrived(changeStatusData, undefined); } else { @@ -273,7 +340,11 @@ export class ShelfEditFormService { } private prepareOrderItems(form: FormGroup) { - const orderItems = (form.get('items') as FormArray).controls.map((control) => this.getOrderItemFromItemForm(control)); + const orderItems = (form.get( + 'items' + ) as FormArray).controls.map((control) => + this.getOrderItemFromItemForm(control) + ); return orderItems.map((orderItem) => ({ orderId: Number(form.get('orderId').value), @@ -290,7 +361,11 @@ export class ShelfEditFormService { orderItemSubsetId: number; orderItemSubset: Partial; }[] { - const subsetItems = (form.get('items') as FormArray).controls.map((control) => this.getOrderItemSubsetFromItemForm(control, form)); + const subsetItems = (form.get( + 'items' + ) as FormArray).controls.map((control) => + this.getOrderItemSubsetFromItemForm(control, form) + ); return subsetItems.map((item) => ({ orderId: form.get('orderId').value, @@ -309,7 +384,9 @@ export class ShelfEditFormService { orderId: number; data: StatusValues; }[] { - const items = (form.get('items') as FormArray).controls.map((itemForm) => this.getOrderItemSubsetFromItemForm(itemForm, form)); + const items = (form.get('items') as FormArray).controls.map((itemForm) => + this.getOrderItemSubsetFromItemForm(itemForm, form) + ); return items.map((item) => ({ orderId: Number(form.get('orderId').value), From be05cf7fddbf31c69fe4377e98cd4ba72ce1a36a Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 1 Sep 2020 20:54:56 +0200 Subject: [PATCH 100/135] Update Placeholder for "Anmerkung" from "-" to "" --- .../edit-order-item.component.html | 59 +++++++++++++++---- .../shelf/services/shelf-edit-form.service.ts | 2 +- .../text-input.component.component.ts | 10 +++- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html b/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html index f2e853ede..f0743d62f 100644 --- a/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html +++ b/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html @@ -1,34 +1,67 @@ - +
- +
- +
- +
- +
- +
- +
- +
- + -
\ No newline at end of file + diff --git a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts index 1a64f61d7..c183e4555 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts @@ -293,7 +293,7 @@ export class ShelfEditFormService { compartmentCode: !!form.get('compartmentCode').value ? String(form.get('compartmentCode').value) : null, - specialComment: String(ctrl.get('comment').value) || null, + specialComment: String(ctrl.get('comment').value || ''), ssc, sscText, }; diff --git a/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts b/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts index b21d03238..b3a083ebe 100644 --- a/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts +++ b/apps/sales/src/app/modules/ui/text-input/text-input.component.component.ts @@ -1,4 +1,10 @@ -import { Component, ChangeDetectionStrategy, forwardRef, Input, ChangeDetectorRef } from '@angular/core'; +import { + Component, + ChangeDetectionStrategy, + forwardRef, + Input, + ChangeDetectorRef, +} from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; import { asyncScheduler } from 'rxjs'; @@ -18,7 +24,7 @@ import { asyncScheduler } from 'rxjs'; export class UiTextInputComponent implements ControlValueAccessor { @Input() label = ''; @Input() suffix: string; - @Input() placeholder: string; + @Input() placeholder = ''; constructor(private cdr: ChangeDetectorRef) {} From 6cd85bcb58f94ee02417b30a8a770d17e5dfe2e5 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 1 Sep 2020 21:24:33 +0200 Subject: [PATCH 101/135] Add Sticky Header on Edit Page --- .../shelf-edit-compartment.component.html | 9 ++++----- .../shelf-edit-compartment.component.scss | 10 ++++++++-- .../shelf-edit-order/shelf-edit-order.component.html | 9 ++++----- .../shelf-edit-order/shelf-edit-order.component.scss | 10 ++++++++-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html index 162d05a1c..9c4a2db98 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html @@ -1,11 +1,10 @@
-
-
- {{ customerName?.firstName }} {{ customerName?.lastName }} -
+
+ {{ customerName?.firstName }} {{ customerName?.lastName }}
- +
+
-
-
- {{ customerName?.firstName }} {{ customerName?.lastName }} -
+
+ {{ customerName?.firstName }} {{ customerName?.lastName }}
- +
+
Date: Wed, 2 Sep 2020 07:34:23 +0200 Subject: [PATCH 102/135] Remove Divider When Estimated Shipping Date or PickUp Date Not Shown --- .../shelf-edit-compartment.component.html | 45 ++++++++++-------- .../shelf-edit-order.component.html | 46 ++++++++++--------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html index 9c4a2db98..5d82ad50d 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html @@ -48,31 +48,36 @@ >
- + > + +
+
- -
+ + +
+

- - - -
+ > + +
+
+ + +
+
Date: Wed, 2 Sep 2020 11:18:09 +0200 Subject: [PATCH 103/135] =?UTF-8?q?Order=20Details=20Card=20Anzeige=20Ge?= =?UTF-8?q?=C3=A4ndert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order-details-card.component.html | 107 ++++++++++++------ 1 file changed, 71 insertions(+), 36 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index 57324014f..2731eb8d3 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -53,45 +53,80 @@
-
-
vsl. Lieferdatum
-
- - +
+
vsl. Lieferdatum
+
+ + - + +
-
-
-
Abholfrist
-
- - - - - - + + + + + + + + + +
+
Geändert
+
+ +
+
+ + +
+
vsl. Lieferdatum
+
+ + +
-
\ No newline at end of file + + + +
+
Abholfrist
+
+ + + + + + +
+
+
\ No newline at end of file From 4b3aedc685e3bc9c8730a85a9bc2d966d4d154a7 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 2 Sep 2020 11:21:39 +0200 Subject: [PATCH 104/135] Update Status, EstimatedShippingDate and PickUp Date in History Header --- .../shelf-edit-compartment.component.ts | 85 +++++++++++---- .../shelf-edit-order.component.ts | 1 - .../header/history-header.component.html | 9 +- .../header/history-header.component.ts | 103 ++++++++++++++++-- .../shelf-history/shelf-history.component.ts | 32 +++++- .../shelf/services/shelf-edit-form.service.ts | 5 +- 6 files changed, 192 insertions(+), 43 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts index 79972abcc..6db1acb03 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts @@ -1,11 +1,28 @@ -import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; +import { + Component, + OnInit, + ChangeDetectionStrategy, + ChangeDetectorRef, +} from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable, from } from 'rxjs'; -import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators'; +import { + filter, + map, + distinctUntilChanged, + shareReplay, + take, + withLatestFrom, + first, +} from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; import { ShelfEditFormService } from '../../services'; import { FormGroup, FormArray } from '@angular/forms'; -import { ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe, ProcessingStatusOptionsPipe } from '../../pipes'; +import { + ProcessingStatusPipe, + PickUpDateOptionsToDisplayValuesPipe, + ProcessingStatusOptionsPipe, +} from '../../pipes'; import { DatePipe } from '@angular/common'; import { ShelfNavigationService } from '../../shared/services'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; @@ -46,7 +63,10 @@ export class ShelfEditCompartmentComponent implements OnInit { get processingStatus$() { return this.activatedRoute.params.pipe( - map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue), + map( + (params) => + Number(params.processingStatus) as OrderItemProcessingStatusValue + ), distinctUntilChanged(), shareReplay() ); @@ -57,8 +77,12 @@ export class ShelfEditCompartmentComponent implements OnInit { } async loadCompartmentAndInitForm() { - const compartmentCode = await this.compartmentCode$.pipe(take(1)).toPromise(); - const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise(); + const compartmentCode = await this.compartmentCode$ + .pipe(take(1)) + .toPromise(); + const processingStatus = await this.processingStatus$ + .pipe(take(1)) + .toPromise(); this.populateFormData(compartmentCode, processingStatus); } @@ -66,33 +90,52 @@ export class ShelfEditCompartmentComponent implements OnInit { async onSubmit() { console.log(this.form.valid); - const compartmentCode = await this.compartmentCode$.pipe(first()).toPromise(); - const processingStatus = await this.processingStatus$.pipe(first()).toPromise(); - const submitResult = await this.formService.submit(this.form, processingStatus); + const compartmentCode = await this.compartmentCode$ + .pipe(first()) + .toPromise(); + const processingStatus = await this.processingStatus$ + .pipe(first()) + .toPromise(); + const submitResult = await this.formService.submit( + this.form, + processingStatus + ); let newValues; if (submitResult) { - // TODO Navigate back to Details Page with updated processingStatus newValues = { - compartmentCode: this.form.get('compartmentCode').value || compartmentCode, - processingStatus: this.form.get('processingStatus').value || processingStatus, + compartmentCode: + this.form.get('compartmentCode').value || compartmentCode, + processingStatus: + this.form.get('processingStatus').value || processingStatus, }; - this.shelfNavigationService.navigateBackToDetails(newValues, { compartmentCode, processingStatus }); + this.shelfNavigationService.navigateBackToDetails(newValues, { + compartmentCode, + processingStatus, + }); } } onAbortEdit() { - return this.compartmentCode$.pipe(take(1), withLatestFrom(this.processingStatus$)).subscribe(([compartmentCode, processingStatus]) => - this.shelfNavigationService.navigateToDetails({ - compartmentCode, - processingStatus, - }) - ); + return this.compartmentCode$ + .pipe(take(1), withLatestFrom(this.processingStatus$)) + .subscribe(([compartmentCode, processingStatus]) => + this.shelfNavigationService.navigateToDetails({ + compartmentCode, + processingStatus, + }) + ); } - private async populateFormData(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue) { - this.form = await this.formService.createFormByCompartmentCode(compartmentCode, processingStatus); + private async populateFormData( + compartmentCode: string, + processingStatus: OrderItemProcessingStatusValue + ) { + this.form = await this.formService.createFormByCompartmentCode( + compartmentCode, + processingStatus + ); this.items = this.formService.getItemsForm(compartmentCode); this.customerName = this.formService.getCustomerName(compartmentCode); this.cdr.detectChanges(); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts index f91e7f244..71e629d99 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts @@ -99,7 +99,6 @@ export class ShelfEditOrderComponent implements OnInit { ); if (submitResult) { - // TODO Navigate back to Details Page with updated processingStatus this.shelfNavigationService.navigateBackToDetails({ orderNumber, processingStatus: diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html index a1f9b41c1..26e2709e9 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.html @@ -1,6 +1,11 @@

Historie

- +
-
\ No newline at end of file +
diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts index 46a0d3532..61b73fd54 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts @@ -1,10 +1,19 @@ -import { Component, ChangeDetectionStrategy, Input, TemplateRef, OnInit } from '@angular/core'; +import { + Component, + ChangeDetectionStrategy, + Input, + TemplateRef, + OnInit, +} from '@angular/core'; import { HistoryStateFacade } from '@shelf-store/history'; import { DetailsFacade } from '@shelf-store/details'; import { OrderDetailsCardInput } from '../../../components/order-details-card'; -import { OrderItemListItemDTO } from '@swagger/oms/lib'; +import { + OrderItemListItemDTO, + OrderItemProcessingStatusValue, +} from '@swagger/oms/lib'; import { Observable } from 'rxjs'; -import { map, filter } from 'rxjs/operators'; +import { map, filter, shareReplay, take } from 'rxjs/operators'; @Component({ selector: 'app-shelf-history-header', @@ -19,17 +28,25 @@ export class ShelfHistoryHeaderComponent implements OnInit { @Input() orderItemSubsetId: number; @Input() headerTemplate: TemplateRef; - details$: Observable; + details$: Observable; orderItems$: Observable; - constructor(private detailsFacade: DetailsFacade, private historyStateFacade: HistoryStateFacade) {} + constructor( + private detailsFacade: DetailsFacade, + private historyStateFacade: HistoryStateFacade, + private detailsStoreFacade: DetailsFacade + ) {} ngOnInit() { if (this.compartmentCode) { - this.orderItems$ = this.detailsFacade.getOrderItemsByCompartmentCode$(this.compartmentCode); + this.orderItems$ = this.detailsFacade.getOrderItemsByCompartmentCode$( + this.compartmentCode + ); } else if (this.orderId) { - this.orderItems$ = this.detailsFacade.getOrderItemsByOrderNumber$(this.orderId); + this.orderItems$ = this.detailsFacade.getOrderItemsByOrderNumber$( + this.orderId + ); } this.details$ = this.orderItems$.pipe( @@ -40,7 +57,9 @@ export class ShelfHistoryHeaderComponent implements OnInit { firstName: item.firstName, lastName: item.lastName, customerNumber: item.buyerNumber, - estimatedShippingDate: item.estimatedShippingDate ? new Date(item.estimatedShippingDate) : undefined, + estimatedShippingDate: item.estimatedShippingDate + ? new Date(item.estimatedShippingDate) + : undefined, orderDate: new Date(item.orderDate), orderNumber: item.orderNumber, processingStatus: item.processingStatus, @@ -48,11 +67,13 @@ export class ShelfHistoryHeaderComponent implements OnInit { compartmentCode: item.compartmentCode, compartmentInfo: item.compartmentInfo, pickupDeadline: new Date(item.pickUpDeadline), - } as OrderDetailsCardInput; + orderId: item.orderId, + } as OrderDetailsCardInput & { orderId: number }; } return undefined; }), - filter((details) => !!details) + filter((details) => !!details), + shareReplay() ); } @@ -60,5 +81,65 @@ export class ShelfHistoryHeaderComponent implements OnInit { this.historyStateFacade.reloadHistory(this.orderItemSubsetId); } - updateDetails() {} + async updateEstimatedShippingDate(date: Date) { + const orderId = await this.getOrderId(); + + await this.detailsStoreFacade.setEstimatedShippingDate({ + items: [ + { + orderItemSubsetId: this.orderItemSubsetId, + orderItemId: this.orderItemId, + orderId: orderId, + }, + ], + estimatedShippingDate: date, + }); + + this.updateHistory(); + } + + async changePickUpDate(date: Date) { + const orderId = await this.getOrderId(); + + await this.detailsStoreFacade.setPickUpDeadline({ + items: [ + { + orderItemSubsetId: this.orderItemSubsetId, + orderItemId: this.orderItemId, + orderId: orderId, + }, + ], + pickUpDeadline: date, + }); + + this.updateHistory(); + } + + async changeProcessingStatus( + processingStatus: OrderItemProcessingStatusValue + ) { + const orderId = await this.getOrderId(); + + await this.detailsStoreFacade.changeStatus([ + { + orderItemSubsetId: this.orderItemSubsetId, + orderItemId: this.orderItemId, + orderId, + data: { + processingStatus, + }, + }, + ]); + + this.updateHistory(); + } + + private async getOrderId() { + return this.details$ + .pipe( + map((details) => details.orderId), + take(1) + ) + .toPromise(); + } } diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts index fd9f463a2..acdb85cfb 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts @@ -1,9 +1,15 @@ import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; -import { filter, map, switchMap, distinctUntilChanged, tap, shareReplay } from 'rxjs/operators'; +import { + filter, + map, + switchMap, + distinctUntilChanged, + tap, + shareReplay, +} from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; -import { HistoryDTO } from '@cmf/trade-api'; import { HistoryStateFacade } from '@shelf-store/history'; import { OrderHistoryStatus } from '@shelf-store/defs'; @@ -20,7 +26,10 @@ export class ShelfHistoryComponent implements OnInit { orderItemId$: Observable; orderItemSubsetId$: Observable; - constructor(private activatedRoute: ActivatedRoute, private historyStateFacade: HistoryStateFacade) {} + constructor( + private activatedRoute: ActivatedRoute, + private historyStateFacade: HistoryStateFacade + ) {} ngOnInit() { this.status$ = this.getStatus(); @@ -35,19 +44,30 @@ export class ShelfHistoryComponent implements OnInit { }; getStatus() { - return this.getOrderItemSubsetId$().pipe(switchMap((orderItemSubsetId) => this.historyStateFacade.getStatus$(orderItemSubsetId))); + return this.getOrderItemSubsetId$().pipe( + switchMap((orderItemSubsetId) => + this.historyStateFacade.getStatus$(orderItemSubsetId) + ) + ); } getOrderId$(): Observable { return this.activatedRoute.params.pipe( - filter((params) => !isNullOrUndefined(params)), + filter( + (params) => + !isNullOrUndefined(params) && !isNullOrUndefined(params.orderId) + ), map((params) => Number(params.orderId)) ); } getCompartmentCode$(): Observable { return this.activatedRoute.params.pipe( - filter((params) => !isNullOrUndefined(params)), + filter( + (params) => + !isNullOrUndefined(params) && + !isNullOrUndefined(params.compartmentCode) + ), map((params) => params.compartmentCode) ); } diff --git a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts index c183e4555..23a0778e0 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-edit-form.service.ts @@ -288,6 +288,7 @@ export class ShelfEditFormService { return { id: Number(ctrl.get('orderItemSubsetId').value), orderItemId: Number(ctrl.get('orderItemId').value), + orderItemSubsetNumber: ctrl.get('orderItemSubsetId').value, processingStatus: form.get('processingStatus').value, estimatedShippingDate: String(form.get('estimatedShippingDate').value), compartmentCode: !!form.get('compartmentCode').value @@ -390,8 +391,8 @@ export class ShelfEditFormService { return items.map((item) => ({ orderId: Number(form.get('orderId').value), - orderItemId: Number(form.get('orderItemId').value), - orderItemSubsetId: Number(form.get('orderItemSubsetId').value), + orderItemId: item.orderItemId, + orderItemSubsetId: Number(item.orderItemSubsetNumber), data: { processingStatus } as StatusValues, })); } From 3fb6cd29f75edb690e63d17c13f05d2fd4ac56eb Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 2 Sep 2020 12:21:28 +0200 Subject: [PATCH 105/135] Update Search Result Hits in Breadcrumb --- .../search/search-input.component.ts | 4 + .../shelf/services/shelf-filter.service.ts | 1 - .../services/shelf-navigation.service.ts | 96 ++++++++++++++++--- .../customer/shelf/details/details.effects.ts | 55 +++++++++-- .../customer/shelf/details/details.reducer.ts | 25 +++-- 5 files changed, 150 insertions(+), 31 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts index 34490cce1..3e1255c08 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts @@ -285,6 +285,10 @@ export class ShelfSearchInputComponent } if (this.shouldNavigateToDetails(numberOfHits)) { + this.shelfNavigationService.updateResultPageBreadcrumb({ + numberOfHits, + searchQuery, + }); this.shelfNavigationService.navigateToDetails( this.getDetails(result) ); diff --git a/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts b/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts index 2ca62696d..99e17ead9 100644 --- a/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts +++ b/apps/sales/src/app/modules/shelf/services/shelf-filter.service.ts @@ -7,7 +7,6 @@ import { filter, takeUntil, take, - tap, distinctUntilChanged, } from 'rxjs/operators'; import { SearchStateFacade } from '../../../store/customer'; diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index 2db74b1ba..31016537a 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -1,8 +1,15 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Store } from '@ngxs/store'; -import { AddBreadcrumb, UpdateCurrentBreadcrumbName, PopLastBreadcrumbs } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; -import { ChangeCurrentRoute, AddProcess } from 'apps/sales/src/app/core/store/actions/process.actions'; +import { + AddBreadcrumb, + UpdateCurrentBreadcrumbName, + PopLastBreadcrumbs, +} from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; +import { + ChangeCurrentRoute, + AddProcess, +} from 'apps/sales/src/app/core/store/actions/process.actions'; import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model'; import { OrderItemListItemDTO } from '@swagger/oms/lib'; import { ProcessSelectors } from 'apps/sales/src/app/core/store/selectors/process.selectors'; @@ -12,7 +19,11 @@ import { Process } from 'apps/sales/src/app/core/models/process.model'; export class ShelfNavigationService { constructor(private store: Store, private router: Router) {} - navigateToDetails(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { + navigateToDetails(order: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }) { this.createTab(); const path = this.getDetailsPath(order); const breadcrumb = this.getDetailsBreadcrumb(order); @@ -20,7 +31,11 @@ export class ShelfNavigationService { this.navigateToRoute(path, breadcrumb); } - navigateToEdit(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { + navigateToEdit(order: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }) { this.createTab(); const path = this.getDetailsPath({ ...order, edit: true }); const breadcrumb = this.getEditBreadCrumb(); @@ -28,7 +43,11 @@ export class ShelfNavigationService { this.navigateToRoute(path, breadcrumb); } - updateDetailsNavigation(order: { orderNumber?: string; compartmentCode?: string; processingStatus?: number }) { + updateDetailsNavigation(order: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }) { const path = this.getDetailsPath(order); const breadcrumb = this.getDetailsBreadcrumb(order); this.replaceRoute(path, breadcrumb); @@ -40,7 +59,13 @@ export class ShelfNavigationService { this.replaceRoute(path, breadcrumb); } - navigateToResultList({ searchQuery, numberOfHits }: { searchQuery: string; numberOfHits: number }) { + navigateToResultList({ + searchQuery, + numberOfHits, + }: { + searchQuery: string; + numberOfHits: number; + }) { this.createTab(); const path = '/shelf/results'; const breadcrumb = this.getResultListBreadcrumb(searchQuery, numberOfHits); @@ -48,10 +73,18 @@ export class ShelfNavigationService { } navigateToHistory(orderitem: OrderItemListItemDTO) { - this.navigateToRoute(this.getHistoryPath(orderitem), `Historie ${orderitem.orderItemSubsetId}`); + this.navigateToRoute( + this.getHistoryPath(orderitem), + `Historie ${orderitem.orderItemSubsetId}` + ); } - getHistoryPath(data: { orderId?: number; compartmentCode?: string; orderItemId?: number; orderItemSubsetId?: number }) { + getHistoryPath(data: { + orderId?: number; + compartmentCode?: string; + orderItemId?: number; + orderItemSubsetId?: number; + }) { if (data.compartmentCode) { return `/shelf/details/compartment/${data.compartmentCode}/item/${data.orderItemId}/subset/${data.orderItemSubsetId}/history`; } else if (data.orderId) { @@ -59,9 +92,26 @@ export class ShelfNavigationService { } } + updateResultPageBreadcrumb(data: { + numberOfHits: number; + searchQuery: string; + }) { + const path = '/shelf/results'; + this.store.dispatch( + new UpdateCurrentBreadcrumbName( + `${data.searchQuery} (${data.numberOfHits} ${ + data.numberOfHits > 1 ? 'Ergebnisse' : 'Ergebnis' + })`, + path + ) + ); + } + private replaceRoute(route: string, breadcrumbName: string) { this.router.navigate([route]); - this.store.dispatch(new UpdateCurrentBreadcrumbName(breadcrumbName, 'shelf')); + this.store.dispatch( + new UpdateCurrentBreadcrumbName(breadcrumbName, 'shelf') + ); } private navigateToRoute(route: string, breadcrumbName: string) { @@ -93,7 +143,9 @@ export class ShelfNavigationService { this.store.dispatch(new PopLastBreadcrumbs(this.getEditBreadCrumb())); if (previous) { - this.store.dispatch(new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous))); + this.store.dispatch( + new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous)) + ); } this.navigateToDetails(data); } @@ -111,16 +163,24 @@ export class ShelfNavigationService { } ) { if (previous) { - this.store.dispatch(new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous))); + this.store.dispatch( + new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous)) + ); } this.navigateToDetails(data); } - private getResultListBreadcrumb(searchQuery: string, numberOfHits: number): string { + private getResultListBreadcrumb( + searchQuery: string, + numberOfHits: number + ): string { return `${searchQuery} (${numberOfHits} Ergebnisse)`; } - getDetailsBreadcrumb(data: { orderNumber?: string; compartmentCode?: string }): string { + getDetailsBreadcrumb(data: { + orderNumber?: string; + compartmentCode?: string; + }): string { if (data.compartmentCode) { return `${data.compartmentCode}`; } @@ -131,7 +191,12 @@ export class ShelfNavigationService { return 'Bearbeiten'; } - private getDetailsPath(data: { orderNumber?: string; compartmentCode?: string; processingStatus?: number; edit?: boolean }): string { + private getDetailsPath(data: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + edit?: boolean; + }): string { let url = ''; if (data.compartmentCode) { url = `/shelf/details/compartment/${data.compartmentCode}/${data.processingStatus}`; @@ -147,7 +212,8 @@ export class ShelfNavigationService { } private createTab() { - const processExists = this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0; + const processExists = + this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0; if (!processExists) { this.createProcess(); } diff --git a/apps/sales/src/app/store/customer/shelf/details/details.effects.ts b/apps/sales/src/app/store/customer/shelf/details/details.effects.ts index 4679a495e..3351eafea 100644 --- a/apps/sales/src/app/store/customer/shelf/details/details.effects.ts +++ b/apps/sales/src/app/store/customer/shelf/details/details.effects.ts @@ -3,7 +3,12 @@ import { Actions, ofType, createEffect } from '@ngrx/effects'; import * as actions from './details.actions'; import { flatMap, catchError, map } from 'rxjs/operators'; -import { OrderService, StrictHttpResponse, ListResponseArgsOfOrderItemListItemDTO, AbholfachService } from '@swagger/oms'; +import { + OrderService, + StrictHttpResponse, + ListResponseArgsOfOrderItemListItemDTO, + AbholfachService, +} from '@swagger/oms'; import { of, NEVER } from 'rxjs'; import { SearchStateFacade } from '../search'; @@ -26,7 +31,13 @@ export class DetailsEffects { qs: a.orderNumber, }, }) - .pipe(catchError((err) => of>(err))) + .pipe( + catchError((err) => + of>( + err + ) + ) + ) ), map((response) => actions.fetchDetailsByOrderNumberDone({ response })) ) @@ -42,7 +53,13 @@ export class DetailsEffects { qs: a.compartmentCode, }, }) - .pipe(catchError((err) => of>(err))) + .pipe( + catchError((err) => + of>( + err + ) + ) + ) ), map((response) => actions.fetchDetailsByCompartmentCodeDone({ response })) ) @@ -57,7 +74,13 @@ export class DetailsEffects { ids: a.orderItemIds, input: { qs: '' }, }) - .pipe(catchError((err) => of>(err))) + .pipe( + catchError((err) => + of>( + err + ) + ) + ) ), map((response) => actions.fetchDetailsOrderItemIdsDone({ response })) ) @@ -72,9 +95,17 @@ export class DetailsEffects { ids: a.orderItemSubsetIds, input: { qs: '' }, }) - .pipe(catchError((err) => of>(err))) + .pipe( + catchError((err) => + of>( + err + ) + ) + ) ), - map((response) => actions.fetchDetailsOrderItemSubsetIdsDone({ response })) + map((response) => + actions.fetchDetailsOrderItemSubsetIdsDone({ response }) + ) ) ); @@ -88,8 +119,11 @@ export class DetailsEffects { ), flatMap((a) => { if (a.response.ok) { + console.log({ action: a }); this.searchStateFacade.reloadResults(); - return [actions.addOrderItems({ orderItems: a.response.body.result })]; + return [ + actions.addOrderItems({ orderItems: a.response.body.result }), + ]; } return NEVER; }) @@ -119,7 +153,12 @@ export class DetailsEffects { flatMap(({ response }) => { if (response.ok) { const result = response.body.result; - return of(actions.setComment({ orderitemid: result.orderItem.id, comment: result.specialComment })); + return of( + actions.setComment({ + orderitemid: result.orderItem.id, + comment: result.specialComment, + }) + ); } return NEVER; }) diff --git a/apps/sales/src/app/store/customer/shelf/details/details.reducer.ts b/apps/sales/src/app/store/customer/shelf/details/details.reducer.ts index efbad9114..b1ec72a4a 100644 --- a/apps/sales/src/app/store/customer/shelf/details/details.reducer.ts +++ b/apps/sales/src/app/store/customer/shelf/details/details.reducer.ts @@ -1,20 +1,31 @@ import { createReducer, Action, on } from '@ngrx/store'; -import { INITIAL_DETAILS_STATE, DetailsState, detailsStateEntityAdapter } from './details.state'; +import { + INITIAL_DETAILS_STATE, + DetailsState, + detailsStateEntityAdapter, +} from './details.state'; import * as actions from './details.actions'; const _detailsReducer = createReducer( INITIAL_DETAILS_STATE, on(actions.addOrderItems, (s, a) => { - const next = detailsStateEntityAdapter.removeMany( - a.orderItems.map((item) => item.orderItemId), - s - ); - return detailsStateEntityAdapter.addMany(a.orderItems, next); + if (a.orderItems && a.orderItems.length) { + const next = detailsStateEntityAdapter.removeMany( + a.orderItems.map((item) => item.orderItemId), + s + ); + return detailsStateEntityAdapter.addMany(a.orderItems, next); + } + + return s; }), on(actions.setComment, (s, a) => { const entity = s.entities[a.orderitemid]; if (entity) { - return detailsStateEntityAdapter.updateOne({ id: a.orderitemid, changes: { specialComment: a.comment } }, s); + return detailsStateEntityAdapter.updateOne( + { id: a.orderitemid, changes: { specialComment: a.comment } }, + s + ); } return s; }) From 41791981d70a4b3077a50c5cd81ecdc8da1f5836 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 2 Sep 2020 15:12:58 +0200 Subject: [PATCH 106/135] Breadcrumb & Bookmark Styling --- .../order-details-card-input.ts | 6 +- .../order-details-card.component.html | 140 +++++++++++++----- .../search-result-group-item.component.html | 109 +++++++++----- .../search-result-group-item.component.scss | 6 +- .../search-result-group-item.component.ts | 10 +- .../search-result-group.component.html | 33 +++-- .../header/history-header.component.ts | 1 + .../shelf-order-details.component.ts | 127 ++++++++++++---- .../shelf-search-results.component.ts | 33 ++++- .../services/shelf-search.facade.service.ts | 8 +- .../customer/shelf/search/search.effects.ts | 2 - .../customer/shelf/search/search.facade.ts | 79 +++++++--- apps/sales/src/scss/_typography.scss | 4 + 13 files changed, 411 insertions(+), 147 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card-input.ts b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card-input.ts index adaa94bc2..66a8dd840 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card-input.ts +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card-input.ts @@ -1,4 +1,7 @@ -import { OrderItemProcessingStatusValue, EnvironmentChannel } from '@swagger/oms'; +import { + OrderItemProcessingStatusValue, + EnvironmentChannel, +} from '@swagger/oms'; export interface OrderDetailsCardInput { firstName?: string; @@ -12,4 +15,5 @@ export interface OrderDetailsCardInput { pickupDeadline?: Date; compartmentCode?: string; compartmentInfo?: string; + processingStatusDate?: Date; } diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index 2731eb8d3..ac6094eed 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -1,7 +1,9 @@

{{ orderDetails?.firstName }} {{ orderDetails?.lastName }} - {{ orderDetails?.compartmentCode }} - {{ orderDetails?.compartmentInfo }} + {{ orderDetails?.compartmentCode }} + {{ orderDetails?.compartmentInfo }}

@@ -30,23 +32,49 @@
Status
- - - - @@ -57,17 +85,30 @@
vsl. Lieferdatum
- - +
@@ -82,7 +123,12 @@
Geändert
-
+
+ {{ + orderDetails?.processingStatusDate | date: 'dd.MM.yy | HH:mm' + }} + Uhr +
@@ -92,17 +138,28 @@
vsl. Lieferdatum
- - +
@@ -112,21 +169,36 @@
Abholfrist
- - + -
- \ No newline at end of file + diff --git a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html index 3ab0e5307..3397617cf 100644 --- a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html +++ b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html @@ -1,49 +1,76 @@ -
- +
+
-
- {{ item.compartmentCode }} {{ item.compartmentInfo }} +
+
+ {{ item.compartmentCode }} {{ item.compartmentInfo }}
-
- item.product.name +
+ item.product.name +
+
+ + {{ [item.product.contributors, item.product.name] | title }} + + + + {{ item.processingStatus | processingStatus }} + +
+
+
+ + {{ item.product.formatDetail }}
-
- {{ [ item.product.contributors, item.product.name] | title }} - - - - {{ item.processingStatus | processingStatus }} - +
+ Bestelldatum + {{ item.orderDate | date }}
-
-
- - {{ item.product.formatDetail }} -
-
- Bestelldatum - {{ item.orderDate | date }} -
-
- {{ item.product.ean }} -
-
- Menge - {{ item.quantity }}x -
-
- {{ item.price | currency:'EUR':'code' }} -
-
- Zielfiliale - {{ item.targetBranch }} -
+
+ {{ item.product.ean }}
-
\ No newline at end of file +
+ Menge + {{ item.quantity }}x +
+
+ {{ item.price | currency: 'EUR':'code' }} +
+
+ Zielfiliale + {{ item.targetBranch }} +
+
+
diff --git a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.scss b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.scss index d3e981f1c..1a435f4ec 100644 --- a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.scss +++ b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.scss @@ -101,5 +101,9 @@ .tags { position: absolute; top: -16px; - right: 150px; + right: 0; +} + +.feature-spacing { + height: 40px; } diff --git a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.ts b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.ts index 26f58bc4d..3fb6dc9a2 100644 --- a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.ts +++ b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.ts @@ -1,4 +1,9 @@ -import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core'; +import { + Component, + OnInit, + ChangeDetectionStrategy, + Input, +} from '@angular/core'; import { OrderItemListItemDTO } from '@swagger/oms'; @Component({ @@ -11,6 +16,9 @@ export class SearchResultGroupItemComponent implements OnInit { @Input() item: OrderItemListItemDTO; + @Input() + displayCompartmentCode = true; + constructor() {} ngOnInit() {} diff --git a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group.component.html b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group.component.html index fce39586a..7b2aa255d 100644 --- a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group.component.html +++ b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group.component.html @@ -2,23 +2,38 @@

{{ group.items[0].firstName }} {{ group.items[0].lastName }}

- - + - + + " + >
- +
@@ -27,4 +42,4 @@
-
\ No newline at end of file +
diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts index 61b73fd54..a17e542cf 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts @@ -63,6 +63,7 @@ export class ShelfHistoryHeaderComponent implements OnInit { orderDate: new Date(item.orderDate), orderNumber: item.orderNumber, processingStatus: item.processingStatus, + processingStatusDate: new Date(item.processingStatusDate), orderChannel: item.clientChannel, compartmentCode: item.compartmentCode, compartmentInfo: item.compartmentInfo, diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts index 89869bfd0..c6552e510 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts @@ -1,7 +1,18 @@ import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core'; import { DetailsFacade } from '@shelf-store/details'; import { ActivatedRoute } from '@angular/router'; -import { map, switchMap, first, filter, flatMap, distinctUntilChanged, shareReplay, take, takeUntil, withLatestFrom } from 'rxjs/operators'; +import { + map, + switchMap, + first, + filter, + flatMap, + distinctUntilChanged, + shareReplay, + take, + takeUntil, + withLatestFrom, +} from 'rxjs/operators'; import { OrderDetailsCardInput } from '../../components/order-details-card'; import { OrderItemProcessingStatusValue, @@ -22,10 +33,15 @@ import { PrinterSelectionComponent } from 'apps/sales/src/app/components/printer changeDetection: ChangeDetectionStrategy.OnPush, }) export class ShelfOrderDetailsComponent { - @ViewChild(PrinterSelectionComponent, { read: PrinterSelectionComponent, static: true }) + @ViewChild(PrinterSelectionComponent, { + read: PrinterSelectionComponent, + static: true, + }) printerSlectionComponent: PrinterSelectionComponent; - processingStatus$ = this.activatedRoute.params.pipe(map((params) => params['processingStatus'])); + processingStatus$ = this.activatedRoute.params.pipe( + map((params) => params['processingStatus']) + ); partialPickup = false; @@ -46,14 +62,24 @@ export class ShelfOrderDetailsComponent { ); orderItems$ = race( - this.orderNumber$.pipe(switchMap((orderNumber) => this.detailsFacade.getOrderItemsByOrderNumber$(orderNumber))), - this.compartmentCode$.pipe(switchMap((compartmentCode) => this.detailsFacade.getOrderItemsByCompartmentCode$(compartmentCode))) + this.orderNumber$.pipe( + switchMap((orderNumber) => + this.detailsFacade.getOrderItemsByOrderNumber$(orderNumber) + ) + ), + this.compartmentCode$.pipe( + switchMap((compartmentCode) => + this.detailsFacade.getOrderItemsByCompartmentCode$(compartmentCode) + ) + ) ).pipe( flatMap((items) => this.processingStatus$.pipe( map((processingStatus) => { if (!!processingStatus) { - return items.filter((item) => item.processingStatus === +processingStatus); + return items.filter( + (item) => item.processingStatus === +processingStatus + ); } return items; }) @@ -70,10 +96,13 @@ export class ShelfOrderDetailsComponent { firstName: item.firstName, lastName: item.lastName, customerNumber: item.buyerNumber, - estimatedShippingDate: item.estimatedShippingDate ? new Date(item.estimatedShippingDate) : undefined, + estimatedShippingDate: item.estimatedShippingDate + ? new Date(item.estimatedShippingDate) + : undefined, orderDate: new Date(item.orderDate), orderNumber: item.orderNumber, processingStatus: item.processingStatus, + processingStatusDate: new Date(item.processingStatusDate), orderChannel: item.clientChannel, compartmentCode: item.compartmentCode, compartmentInfo: item.compartmentInfo, @@ -86,28 +115,45 @@ export class ShelfOrderDetailsComponent { ); showArrivedAndPrintCta$ = this.orderDetailsCard$.pipe( - map((details) => details.processingStatus === 16 || details.processingStatus === 8192) // wenn bestellt(=16) oder nachbestellt(=8192) + map( + (details) => + details.processingStatus === 16 || details.processingStatus === 8192 + ) // wenn bestellt(=16) oder nachbestellt(=8192) ); showPickUpCta$ = this.orderDetailsCard$.pipe( map((details) => details.processingStatus === 128) // wenn eingetroffen(=128) ); - showPickUpPartialCollectCta$ = combineLatest([this.orderDetailsCard$, this.orderItems$]).pipe( + showPickUpPartialCollectCta$ = combineLatest([ + this.orderDetailsCard$, + this.orderItems$, + ]).pipe( map(([details, items]) => { - return details.processingStatus === 128 && (items.length > 1 || items.some((i) => i.quantity > 1)); + return ( + details.processingStatus === 128 && + (items.length > 1 || items.some((i) => i.quantity > 1)) + ); }) // wenn eingetroffen(=128) und mehr als 1 Artikel ); showBackToStoreCta$ = this.orderDetailsCard$.pipe( - map((details) => details.processingStatus === 1024 || details.processingStatus === 512) + map( + (details) => + details.processingStatus === 1024 || details.processingStatus === 512 + ) ); showAddToRemissionListCta$ = this.orderDetailsCard$.pipe( - map((details) => details.processingStatus === 1024 || details.processingStatus === 512) + map( + (details) => + details.processingStatus === 1024 || details.processingStatus === 512 + ) ); - showReOrderCta$ = this.orderDetailsCard$.pipe(map((details) => details.processingStatus === 2048)); + showReOrderCta$ = this.orderDetailsCard$.pipe( + map((details) => details.processingStatus === 2048) + ); constructor( private activatedRoute: ActivatedRoute, @@ -137,29 +183,43 @@ export class ShelfOrderDetailsComponent { }); } - async changeProcessingStatus(status: OrderItemProcessingStatusValue, data: { compartmentInfo?: string } = {}) { + async changeProcessingStatus( + status: OrderItemProcessingStatusValue, + data: { compartmentInfo?: string } = {} + ) { let items = await this.orderItems$.pipe(first()).toPromise(); let results: ResponseArgsOfValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO[]; - const navigate = this.partialPickup ? items.length === this.selectedForPartialPickup.size : true; + const navigate = this.partialPickup + ? items.length === this.selectedForPartialPickup.size + : true; if (status === 256) { if (this.partialPickup) { - items = items.filter(({ orderItemId }) => this.selectedForPartialPickup.has(orderItemId)); + items = items.filter(({ orderItemId }) => + this.selectedForPartialPickup.has(orderItemId) + ); } - results = await this.detailsFacade.pickedUp(items, this.quantityForPartialPickup); + results = await this.detailsFacade.pickedUp( + items, + this.quantityForPartialPickup + ); } else if (status === 131072) { results = await this.detailsFacade.backToStock(items); } else if (status === 8192) { results = await this.detailsFacade.reorder(items); } else if (status === 128) { results = await this.detailsFacade.arrived(items, data.compartmentInfo); - this.printAbholfachetikett(items.map(({ orderItemSubsetId }) => orderItemSubsetId)); + this.printAbholfachetikett( + items.map(({ orderItemSubsetId }) => orderItemSubsetId) + ); } else { - const payloads = items.map(({ orderId, orderItemId, orderItemSubsetId }) => ({ - orderId, - orderItemId, - orderItemSubsetId, - data: { processingStatus: status } as StatusValues, - })); + const payloads = items.map( + ({ orderId, orderItemId, orderItemSubsetId }) => ({ + orderId, + orderItemId, + orderItemSubsetId, + data: { processingStatus: status } as StatusValues, + }) + ); results = await this.detailsFacade.changeStatus(payloads); } @@ -187,7 +247,10 @@ export class ShelfOrderDetailsComponent { changeEstimatedShippingDate(estimatedShippingDate: Date | string) { this.orderItems$.pipe(first()).subscribe((items) => { - this.detailsFacade.setEstimatedShippingDate({ items, estimatedShippingDate }); + this.detailsFacade.setEstimatedShippingDate({ + items, + estimatedShippingDate, + }); }); } @@ -208,10 +271,12 @@ export class ShelfOrderDetailsComponent { if (this.appService.isIPadEnv()) { this.printerSlectionComponent.openDialog(); - this.printerSlectionComponent.print.pipe(takeUntil(this.printerSlectionComponent.closed), take(1)).subscribe((printer) => { - print(printer); - this.printerSlectionComponent.closeModal(); - }); + this.printerSlectionComponent.print + .pipe(takeUntil(this.printerSlectionComponent.closed), take(1)) + .subscribe((printer) => { + print(printer); + this.printerSlectionComponent.closeModal(); + }); } else { const defaultPrinter = await this.getDefaultPrinter(); print(defaultPrinter); @@ -236,7 +301,9 @@ export class ShelfOrderDetailsComponent { async navigateToDetails() { const data = await race( this.orderNumber$.pipe(map((orderNumber) => ({ orderNumber }))), - this.compartmentCode$.pipe(map((compartmentCode) => ({ compartmentCode }))) + this.compartmentCode$.pipe( + map((compartmentCode) => ({ compartmentCode })) + ) ) .pipe( withLatestFrom(this.processingStatus$), diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-search-results/shelf-search-results.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-search-results/shelf-search-results.component.ts index 21f698772..6034c3248 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-search-results/shelf-search-results.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-search-results/shelf-search-results.component.ts @@ -1,6 +1,13 @@ import { Subject, fromEvent, combineLatest } from 'rxjs'; -import { Component, OnDestroy, OnInit, ViewChild, ElementRef, ChangeDetectionStrategy } from '@angular/core'; +import { + Component, + OnDestroy, + OnInit, + ViewChild, + ElementRef, + ChangeDetectionStrategy, +} from '@angular/core'; import { SearchStateFacade } from 'apps/sales/src/app/store/customer'; import { first, takeUntil, map } from 'rxjs/operators'; import { groupBy } from 'apps/sales/src/app/utils'; @@ -19,11 +26,16 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy { destroy$ = new Subject(); - grouped$ = this.searchStateFacade.result$.pipe(map((results) => groupBy(results, (item) => (item ? item.buyerNumber : '')))); + grouped$ = this.searchStateFacade.result$.pipe( + map((results) => groupBy(results, (item) => (item ? item.buyerNumber : ''))) + ); fetching$ = this.searchStateFacade.fetching$; - constructor(private searchStateFacade: SearchStateFacade, private shelfNavigationService: ShelfNavigationService) {} + constructor( + private searchStateFacade: SearchStateFacade, + private shelfNavigationService: ShelfNavigationService + ) {} ngOnInit() { this.initScrollContainer(); @@ -43,16 +55,25 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy { reachedBottom() { const scrollContainer: HTMLElement = this.scrollContainer.nativeElement; - return scrollContainer.scrollHeight - (scrollContainer.scrollTop + scrollContainer.clientHeight) - 100 <= 0; + return ( + scrollContainer.scrollHeight - + (scrollContainer.scrollTop + scrollContainer.clientHeight) - + 100 <= + 0 + ); } async fetch(force = false) { - const [hits, result, fetching] = await combineLatest([this.searchStateFacade.hits$, this.searchStateFacade.result$, this.fetching$]) + const [hits, result, fetching] = await combineLatest([ + this.searchStateFacade.hits$, + this.searchStateFacade.result$, + this.fetching$, + ]) .pipe(first()) .toPromise(); if (force || !hits || (!result.length && !fetching)) { - this.searchStateFacade.fetchResult(); + this.searchStateFacade.fetchResult({}); } } diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts index 121fcabc1..f1d95018f 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts @@ -38,7 +38,7 @@ export class ShelfSearchFacadeService { } this.searchStateFacade.setInput(searchQuery); - return this.requestSearch(); + return this.requestSearch(true); } searchWithBarcode(barcode: string) { @@ -49,7 +49,7 @@ export class ShelfSearchFacadeService { } this.searchStateFacade.setInput(searchQuery); - return this.requestSearch(); + return this.requestSearch(true); } searchForAutocomplete( @@ -72,8 +72,8 @@ export class ShelfSearchFacadeService { return this.requestAutocompleteSearch(autoCompleteQuery); } - private requestSearch() { - return this.searchStateFacade.fetchResult(); + private requestSearch(isNewSearch: boolean = false) { + return this.searchStateFacade.fetchResult({ isNewSearch }); } private generateAutocompleteToken(params: { diff --git a/apps/sales/src/app/store/customer/shelf/search/search.effects.ts b/apps/sales/src/app/store/customer/shelf/search/search.effects.ts index 4bea58ebc..186750225 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.effects.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.effects.ts @@ -15,13 +15,11 @@ import { flatMap, } from 'rxjs/operators'; import { - OrderService, StrictHttpResponse, ListResponseArgsOfOrderItemListItemDTO, ResponseArgsOfIEnumerableOfInputDTO, AbholfachService, } from '@swagger/oms'; -import { BranchService } from '@sales/core-services'; import { SearchStateFacade } from './search.facade'; import { of, NEVER } from 'rxjs'; import { diff --git a/apps/sales/src/app/store/customer/shelf/search/search.facade.ts b/apps/sales/src/app/store/customer/shelf/search/search.facade.ts index 66b5bfe61..5e64422bb 100644 --- a/apps/sales/src/app/store/customer/shelf/search/search.facade.ts +++ b/apps/sales/src/app/store/customer/shelf/search/search.facade.ts @@ -6,7 +6,10 @@ import * as selectors from './search.selectors'; import { switchMap, filter, map, first } from 'rxjs/operators'; import { SharedSelectors } from 'apps/sales/src/app/core/store/selectors/shared.selectors'; import { combineLatest } from 'rxjs'; -import { selectFiltersToFiltersDictionary, primaryFiltersToFiltersDictionary } from './mappers'; +import { + selectFiltersToFiltersDictionary, + primaryFiltersToFiltersDictionary, +} from './mappers'; import { Observable } from 'rxjs'; import { isNullOrUndefined } from 'util'; import { SelectFilter } from 'apps/sales/src/app/modules/filter'; @@ -51,23 +54,34 @@ export class SearchStateFacade { } get pendingInput$() { - return this.getProcessId$().pipe(switchMap((id) => this.getPendingInput$(id))); + return this.getProcessId$().pipe( + switchMap((id) => this.getPendingInput$(id)) + ); } get showNoResultError$() { return this.getProcessId$().pipe( - switchMap((id) => combineLatest([this.getState$(id), this.getHasResult$(id)])), - map(([state, hasResults]) => (!hasResults && state === SearchProcessState.FETCHED ? true : false)) + switchMap((id) => + combineLatest([this.getState$(id), this.getHasResult$(id)]) + ), + map(([state, hasResults]) => + !hasResults && state === SearchProcessState.FETCHED ? true : false + ) ); } get primaryFilters$(): Observable { - return this.process$.pipe(switchMap((process) => this.getPrimaryFilters$(process.id))); + return this.process$.pipe( + switchMap((process) => this.getPrimaryFilters$(process.id)) + ); } get selectFilters$(): Observable { return this.process$.pipe( - filter((process) => !isNullOrUndefined(process) && !isNullOrUndefined(process.filters)), + filter( + (process) => + !isNullOrUndefined(process) && !isNullOrUndefined(process.filters) + ), switchMap((process) => this.getSelectedFilters$(process.id)) ); } @@ -75,7 +89,9 @@ export class SearchStateFacade { get hasActiveFilters$(): Observable { return this.selectedFilter$.pipe( map((selectedFilters) => Object.values(selectedFilters)), - map((filterValues) => filterValues.reduce((acc, curr) => [...acc, curr], [])), + map((filterValues) => + filterValues.reduce((acc, curr) => [...acc, curr], []) + ), map((flattenedFilters) => !!flattenedFilters.length) ); } @@ -86,7 +102,9 @@ export class SearchStateFacade { return selectFilters.some((f) => { if (f.options) { return f.options.some((o) => { - return isNullOrUndefined(o.initial_selected_state) ? o.selected !== true : o.selected !== o.initial_selected_state; + return isNullOrUndefined(o.initial_selected_state) + ? o.selected !== true + : o.selected !== o.initial_selected_state; }); } @@ -100,14 +118,19 @@ export class SearchStateFacade { return this.primaryFilters$.pipe( map((primaryFilters) => { return primaryFilters.some((pf) => - isNullOrUndefined(pf.initial_selected_state) ? pf.selected !== false : pf.selected !== pf.initial_selected_state + isNullOrUndefined(pf.initial_selected_state) + ? pf.selected !== false + : pf.selected !== pf.initial_selected_state ); }) ); } get filtersChangedFromDefault$(): Observable { - return combineLatest([this.selectedFilterChangedFromDefault$, this.primaryFilterChangedFromDefault$]).pipe( + return combineLatest([ + this.selectedFilterChangedFromDefault$, + this.primaryFilterChangedFromDefault$, + ]).pipe( map(([selectFiltersChanged, primaryFiltersChanged]) => { return selectFiltersChanged || primaryFiltersChanged; }) @@ -117,8 +140,12 @@ export class SearchStateFacade { get selectedFilter$(): Observable<{ [key: string]: string }> { return combineLatest([this.selectFilters$, this.primaryFilters$]).pipe( map(([selectFilters, primaryFilters]) => { - const selectFilterDictionary = selectFiltersToFiltersDictionary(selectFilters); - const primaryFiltersDictionary = primaryFiltersToFiltersDictionary(primaryFilters); + const selectFilterDictionary = selectFiltersToFiltersDictionary( + selectFilters + ); + const primaryFiltersDictionary = primaryFiltersToFiltersDictionary( + primaryFilters + ); const mergedFilters = { ...selectFilterDictionary, @@ -232,17 +259,26 @@ export class SearchStateFacade { processId = await this.getProcessId(); } - const currentPrimaryFilters = await this.getPrimaryFilters$(processId).pipe(first()).toPromise(); + const currentPrimaryFilters = await this.getPrimaryFilters$(processId) + .pipe(first()) + .toPromise(); - const indexOfUpdatedFilter = currentPrimaryFilters.findIndex((f) => f.id === primaryFilter.id); + const indexOfUpdatedFilter = currentPrimaryFilters.findIndex( + (f) => f.id === primaryFilter.id + ); updatedFilters = [ ...currentPrimaryFilters.slice(0, indexOfUpdatedFilter), primaryFilter, - ...currentPrimaryFilters.slice(indexOfUpdatedFilter + 1, currentPrimaryFilters.length + 1), + ...currentPrimaryFilters.slice( + indexOfUpdatedFilter + 1, + currentPrimaryFilters.length + 1 + ), ]; - return this.store.dispatch(actions.setPrimaryFilters({ filters: updatedFilters, id: processId })); + return this.store.dispatch( + actions.setPrimaryFilters({ filters: updatedFilters, id: processId }) + ); } async resetPrimaryFilters(id?: number) { @@ -263,12 +299,19 @@ export class SearchStateFacade { this.store.dispatch(actions.resetSelectFilters({ id: processId })); } - async fetchResult(id?: number) { - let processId = id; + async fetchResult(data: { id?: number; isNewSearch?: boolean }) { + let processId = data.id; + if (typeof processId !== 'number') { processId = await this.getProcessId(); } + if (data.isNewSearch) { + return this.store.dispatch( + actions.fetchResult({ id: processId, skip: 0 }) + ); + } + this.store.dispatch(actions.fetchResult({ id: processId })); } diff --git a/apps/sales/src/scss/_typography.scss b/apps/sales/src/scss/_typography.scss index 77496766f..d1ac3ff68 100644 --- a/apps/sales/src/scss/_typography.scss +++ b/apps/sales/src/scss/_typography.scss @@ -24,6 +24,10 @@ text-align: right; } +.isa-font-size-24 { + font-size: 24px; +} + //TODO: _color.scss ausglagern .isa-font-color-customer { color: $isa-customer; From 9bc9be8538105fd9da8160dc353f05baf4c37f39 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 2 Sep 2020 15:25:44 +0200 Subject: [PATCH 107/135] Fix Duplicate Lieferdatum --- .../order-details-card.component.html | 34 +------------------ .../search/search-input.component.ts | 9 ++--- .../oms/src/lib/models/order-item-dto.ts | 7 ++-- .../lib/models/order-item-list-item-dto.ts | 10 +++--- .../oms/src/lib/models/order-item-type.ts | 2 +- 5 files changed, 16 insertions(+), 46 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index ac6094eed..7fecf8c35 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -82,36 +82,6 @@
-
-
vsl. Lieferdatum
-
- - - -
-
@@ -124,9 +94,7 @@
Geändert
- {{ - orderDetails?.processingStatusDate | date: 'dd.MM.yy | HH:mm' - }} + {{ orderDetails?.processingStatusDate | date: 'dd.MM.yy | HH:mm' }} Uhr
diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts index 3e1255c08..a1abf8fc2 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts @@ -275,6 +275,11 @@ export class ShelfSearchInputComponent take(1) ) .subscribe(([_, numberOfHits, searchQuery, result]) => { + this.shelfNavigationService.updateResultPageBreadcrumb({ + numberOfHits, + searchQuery, + }); + if (this.shouldNavigateToResultList(numberOfHits)) { this.resetSessionStorage(); @@ -285,10 +290,6 @@ export class ShelfSearchInputComponent } if (this.shouldNavigateToDetails(numberOfHits)) { - this.shelfNavigationService.updateResultPageBreadcrumb({ - numberOfHits, - searchQuery, - }); this.shelfNavigationService.navigateToDetails( this.getDetails(result) ); diff --git a/apps/swagger/oms/src/lib/models/order-item-dto.ts b/apps/swagger/oms/src/lib/models/order-item-dto.ts index e28eb4977..c7cc0f295 100644 --- a/apps/swagger/oms/src/lib/models/order-item-dto.ts +++ b/apps/swagger/oms/src/lib/models/order-item-dto.ts @@ -1,16 +1,16 @@ /* tslint:disable */ import { EntityDTOOfOrderItemDTOAndIOrderItem } from './entity-dtoof-order-item-dtoand-iorder-item'; +import { QuantityUnitType } from './quantity-unit-type'; import { EntityDTOContainerOfOrderDTO } from './entity-dtocontainer-of-order-dto'; import { EntityDTOContainerOfOrderItemDTO } from './entity-dtocontainer-of-order-item-dto'; import { OrderItemType } from './order-item-type'; import { EntityDTOContainerOfOrderItemSubsetDTO } from './entity-dtocontainer-of-order-item-subset-dto'; import { ProductDTO } from './product-dto'; -import { QuantityUnitType } from './quantity-unit-type'; import { PriceDTO } from './price-dto'; import { EntityDTOContainerOfShopItemDTO } from './entity-dtocontainer-of-shop-item-dto'; import { PromotionDTO } from './promotion-dto'; export interface OrderItemDTO extends EntityDTOOfOrderItemDTOAndIOrderItem { - quantity?: number; + quantityUnitType?: QuantityUnitType; order?: EntityDTOContainerOfOrderDTO; orderItemNumber?: string; parent?: EntityDTOContainerOfOrderItemDTO; @@ -20,10 +20,11 @@ export interface OrderItemDTO extends EntityDTOOfOrderItemDTOAndIOrderItem { subsetItems?: Array; buyerComment?: string; invoiceText?: string; + quantity?: number; product?: ProductDTO; - quantityUnitType?: QuantityUnitType; quantityUnit?: string; grossPrice?: PriceDTO; + unitPrice?: PriceDTO; discountedPrice?: PriceDTO; discountName?: string; discountReason?: string; diff --git a/apps/swagger/oms/src/lib/models/order-item-list-item-dto.ts b/apps/swagger/oms/src/lib/models/order-item-list-item-dto.ts index 4ecd90388..1805ff6fd 100644 --- a/apps/swagger/oms/src/lib/models/order-item-list-item-dto.ts +++ b/apps/swagger/oms/src/lib/models/order-item-list-item-dto.ts @@ -1,14 +1,13 @@ /* tslint:disable */ +import { VATType } from './vattype'; import { EnvironmentChannel } from './environment-channel'; import { OrderType } from './order-type'; import { OrderItemProcessingStatusValue } from './order-item-processing-status-value'; import { ProductDTO } from './product-dto'; -import { VATType } from './vattype'; import { Gender } from './gender'; import { KeyValueDTOOfOrderItemProcessingStatusValueAndString } from './key-value-dtoof-order-item-processing-status-value-and-string'; - export interface OrderItemListItemDTO { - currency?: string; + vatType?: VATType; orderId?: number; orderItemSubsetId?: number; orderPId?: string; @@ -22,13 +21,14 @@ export interface OrderItemListItemDTO { orderNumber?: string; orderType?: OrderType; processingStatus?: OrderItemProcessingStatusValue; + processingStatusDate?: string; orderDate?: string; product?: ProductDTO; quantity?: number; overallQuantity?: number; price?: number; - vatType?: VATType; orderItemId?: number; + currency?: string; buyerNumber?: string; organisation?: string; department?: string; @@ -47,5 +47,5 @@ export interface OrderItemListItemDTO { compartmentCode?: string; compartmentInfo?: string; pickUpDeadline?: string; - features?: { [key: string]: string }; + features?: {[key: string]: string}; } diff --git a/apps/swagger/oms/src/lib/models/order-item-type.ts b/apps/swagger/oms/src/lib/models/order-item-type.ts index 36c7dd4eb..dff245cdc 100644 --- a/apps/swagger/oms/src/lib/models/order-item-type.ts +++ b/apps/swagger/oms/src/lib/models/order-item-type.ts @@ -1,2 +1,2 @@ /* tslint:disable */ -export type OrderItemType = 0 | 1 | 2 | 4 | 8 | 16 | 32; \ No newline at end of file +export type OrderItemType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64; \ No newline at end of file From 342dd04452c2a88cf6b36044e05574f247390d51 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 2 Sep 2020 17:04:45 +0200 Subject: [PATCH 108/135] Update Calendar To Disable Sundays --- .../order-details-card.component.html | 1 + .../shelf-history/shelf-history.component.ts | 2 +- .../shelf-order-details.component.html | 138 ++++++++++--- .../shelf-order-details.component.ts | 28 ++- .../services/shelf-navigation.service.ts | 25 ++- .../app/modules/ui/core/date/date.adapter.ts | 7 +- .../ui/core/date/native-date.adapter.ts | 16 +- .../ui/datepicker/body/body.component.scss | 5 +- .../ui/datepicker/body/cell.directive.ts | 72 +++++-- .../app/modules/ui/datepicker/datepicker.ts | 27 ++- .../customer/shelf/details/details.effects.ts | 1 - .../customer/shelf/details/details.facade.ts | 188 +++++++++++++----- 12 files changed, 388 insertions(+), 122 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index 7fecf8c35..f14c1ee6a 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -125,6 +125,7 @@ #uiDatepicker [right]="'-1rem'" [min]="minDate" + [disabledDaysOfWeek]="[0]" [selected]="orderDetails?.estimatedShippingDate" (save)="changeEstimatedDeliveryDate.emit($event); uiDatepicker.close()" > diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts index acdb85cfb..ef1230fc5 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.ts @@ -57,7 +57,7 @@ export class ShelfHistoryComponent implements OnInit { (params) => !isNullOrUndefined(params) && !isNullOrUndefined(params.orderId) ), - map((params) => Number(params.orderId)) + map((params) => params.orderId) ); } diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html index ac76b3391..e7c06b9e8 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.html @@ -1,19 +1,50 @@
-
- +
+ - +
- + (changeProcessingStatus)="changeProcessingStatus($event)" + (changePickUpDeadline)="changePickupDeadline($event)" + > -
-
- - +
+
+ + {{ selectedForPartialPickup.size }} von {{ orderItems?.length }} Titel @@ -22,63 +53,104 @@
- +
-
-
- +
+
- +
-
- - - -
-
- \ No newline at end of file + diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts index c6552e510..205a9c2f1 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-order-details/shelf-order-details.component.ts @@ -202,7 +202,7 @@ export class ShelfOrderDetailsComponent { items, this.quantityForPartialPickup ); - } else if (status === 131072) { + } else if (status === 262144) { results = await this.detailsFacade.backToStock(items); } else if (status === 8192) { results = await this.detailsFacade.reorder(items); @@ -261,6 +261,7 @@ export class ShelfOrderDetailsComponent { } async printAbholfachetikett(data: number[]) { + // tslint:disable-next-line: no-shadowed-variable const print = (printer?: string) => this.omsPrintService .OMSPrintAbholfachetikettResponse({ @@ -269,22 +270,29 @@ export class ShelfOrderDetailsComponent { }) .toPromise(); + let printer: string; + if (this.appService.isIPadEnv()) { this.printerSlectionComponent.openDialog(); - this.printerSlectionComponent.print + printer = await this.printerSlectionComponent.print .pipe(takeUntil(this.printerSlectionComponent.closed), take(1)) - .subscribe((printer) => { - print(printer); - this.printerSlectionComponent.closeModal(); - }); - } else { - const defaultPrinter = await this.getDefaultPrinter(); - print(defaultPrinter); + .toPromise(); + this.printerSlectionComponent.closeModal(); + } + + if (!printer) { + printer = await this.getDefaultPrinter(); + } + + try { + print(printer); + } catch (error) { + console.log('Printing Abholfachetikett Failed'); } } async getDefaultPrinter(): Promise { - const printers = await this.printerService.PrintPrinters().toPromise(); + const printers = await this.printerService.PrintLabelPrinters().toPromise(); const selected = printers.result.find((f) => f.selected); if (!!selected) { diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index 31016537a..769315bce 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -5,6 +5,8 @@ import { AddBreadcrumb, UpdateCurrentBreadcrumbName, PopLastBreadcrumbs, + ClearBreadcrumbs, + DeleteBreadcrumbsForProcess, } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; import { ChangeCurrentRoute, @@ -84,11 +86,12 @@ export class ShelfNavigationService { compartmentCode?: string; orderItemId?: number; orderItemSubsetId?: number; + orderNumber?: string; }) { if (data.compartmentCode) { return `/shelf/details/compartment/${data.compartmentCode}/item/${data.orderItemId}/subset/${data.orderItemSubsetId}/history`; } else if (data.orderId) { - return `/shelf/details/order/${data.orderId}/item/${data.orderItemId}/subset/${data.orderItemSubsetId}/history`; + return `/shelf/details/order/${data.orderNumber}/item/${data.orderItemId}/subset/${data.orderItemSubsetId}/history`; } } @@ -96,13 +99,23 @@ export class ShelfNavigationService { numberOfHits: number; searchQuery: string; }) { + this.store.dispatch(new DeleteBreadcrumbsForProcess(1)); + this.store.dispatch( + new AddBreadcrumb( + { name: 'Warenausgabe', path: '/shelf/search' }, + 'shelf' + ) + ); const path = '/shelf/results'; this.store.dispatch( - new UpdateCurrentBreadcrumbName( - `${data.searchQuery} (${data.numberOfHits} ${ - data.numberOfHits > 1 ? 'Ergebnisse' : 'Ergebnis' - })`, - path + new AddBreadcrumb( + { + name: `${data.searchQuery} (${data.numberOfHits} ${ + data.numberOfHits > 1 ? 'Ergebnisse' : 'Ergebnis' + })`, + path, + }, + 'shelf' ) ); } diff --git a/apps/sales/src/app/modules/ui/core/date/date.adapter.ts b/apps/sales/src/app/modules/ui/core/date/date.adapter.ts index 704b1c5c6..cde5427ae 100644 --- a/apps/sales/src/app/modules/ui/core/date/date.adapter.ts +++ b/apps/sales/src/app/modules/ui/core/date/date.adapter.ts @@ -33,6 +33,8 @@ export abstract class DateAdapter { abstract getDifferenceInDays(first: TDate, second: TDate): number; + abstract getDayOfWeek(date: TDate): number; + compareDate(first: TDate, second: TDate) { if (isNullOrUndefined(first) || isNullOrUndefined(second)) { return null; @@ -49,6 +51,9 @@ export abstract class DateAdapter { if (isNullOrUndefined(first) || isNullOrUndefined(second)) { return null; } - return this.getYear(first) - this.getYear(second) || this.getMonth(first) - this.getMonth(second); + return ( + this.getYear(first) - this.getYear(second) || + this.getMonth(first) - this.getMonth(second) + ); } } diff --git a/apps/sales/src/app/modules/ui/core/date/native-date.adapter.ts b/apps/sales/src/app/modules/ui/core/date/native-date.adapter.ts index b426dea56..727d5d113 100644 --- a/apps/sales/src/app/modules/ui/core/date/native-date.adapter.ts +++ b/apps/sales/src/app/modules/ui/core/date/native-date.adapter.ts @@ -23,10 +23,18 @@ export class NativeDateAdapter extends DateAdapter { return this.getDate(date).toString(); } addCalendarMonths(date: Date, months: number): Date { - return this.createDate(this.getYear(date), this.getMonth(date) + months, this.getDate(date)); + return this.createDate( + this.getYear(date), + this.getMonth(date) + months, + this.getDate(date) + ); } addCalendarDays(date: Date, days: number): Date { - return this.createDate(this.getYear(date), this.getMonth(date), this.getDate(date) + days); + return this.createDate( + this.getYear(date), + this.getMonth(date), + this.getDate(date) + days + ); } getFirstDateOfWeek(date: Date): Date { @@ -55,6 +63,10 @@ export class NativeDateAdapter extends DateAdapter { return (first.getTime() - second.getTime()) / (1000 * 3600 * 24); } + getDayOfWeek(date: Date) { + return date.getDay(); + } + createDate(year: number, month: number, date: number): Date { const result = new Date(year, month, date); // abbreviations for 19xx. diff --git a/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss b/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss index eac7ac515..33a3b0eb5 100644 --- a/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss +++ b/apps/sales/src/app/modules/ui/datepicker/body/body.component.scss @@ -18,13 +18,14 @@ th { height: 41px; } -.is-today { +.cell-is-today { border: 1px dashed $datepicker-selected-cell-bg-color; border-radius: 50%; font-weight: 700; } -.cell-not-in-range { +.cell-not-in-range, +.cell-is-disabled-day-of-week { color: $datepicker-cell-not-in-range-color; } diff --git a/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts b/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts index 8c0d62b3d..a07b818dc 100644 --- a/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts +++ b/apps/sales/src/app/modules/ui/datepicker/body/cell.directive.ts @@ -1,7 +1,19 @@ -import { Directive, Input, HostBinding, OnDestroy, OnInit, HostListener } from '@angular/core'; +import { + Directive, + Input, + HostBinding, + OnDestroy, + OnInit, + HostListener, +} from '@angular/core'; import { Datepicker } from '@isa-ui/datepicker/datepicker'; import { DateAdapter } from '@isa-ui/core/date'; -import { Subscription, ReplaySubject, combineLatest, BehaviorSubject } from 'rxjs'; +import { + Subscription, + ReplaySubject, + combineLatest, + BehaviorSubject, +} from 'rxjs'; @Directive({ selector: '[appUiDatepickerCell]' }) export class UiDatepickerCellDirective implements OnInit, OnDestroy { @@ -30,23 +42,34 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { @HostBinding('class.cell-not-in-range') notInRange: boolean; - @HostBinding('class.is-today') + @HostBinding('class.cell-is-today') isToday: boolean; + @HostBinding('class.cell-is-disabled-day-of-week') + isDisabledDayOfWeek: boolean; + private subscription = new Subscription(); - constructor(private datepicker: Datepicker, private dateAdapter: DateAdapter) {} + constructor( + private datepicker: Datepicker, + private dateAdapter: DateAdapter + ) {} ngOnInit(): void { this.initDisplayed$(); this.initSelected$(); this.initRange$(); this.initToday$(); + this.initDisabledDayOfWeek$(); } initDisplayed$() { - const sub = combineLatest([this.dateSubject, this.datepicker.displayed$]).subscribe(([date, displayed]) => { - this.inDisplayedMonth = this.dateAdapter.compareYearAndMonth(date, displayed) === 0; + const sub = combineLatest([ + this.dateSubject, + this.datepicker.displayed$, + ]).subscribe(([date, displayed]) => { + this.inDisplayedMonth = + this.dateAdapter.compareYearAndMonth(date, displayed) === 0; this.notInDisplayedMonth = !this.inDisplayedMonth; }); @@ -54,7 +77,10 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { } initSelected$() { - const sub = combineLatest([this.dateSubject, this.datepicker.selected$]).subscribe(([date, selected]) => { + const sub = combineLatest([ + this.dateSubject, + this.datepicker.selected$, + ]).subscribe(([date, selected]) => { this.selected = this.dateAdapter.compareDate(date, selected) === 0; }); @@ -62,9 +88,17 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { } initRange$() { - const sub = combineLatest([this.dateSubject, this.datepicker.min$, this.datepicker.max$]).subscribe(([date, min, max]) => { - const minInRange = !!min ? this.dateAdapter.compareDate(date, min) > 0 : true; - const maxInRange = !!max ? this.dateAdapter.compareDate(max, date) > 0 : true; + const sub = combineLatest([ + this.dateSubject, + this.datepicker.min$, + this.datepicker.max$, + ]).subscribe(([date, min, max]) => { + const minInRange = !!min + ? this.dateAdapter.compareDate(date, min) > 0 + : true; + const maxInRange = !!max + ? this.dateAdapter.compareDate(max, date) > 0 + : true; this.inRange = minInRange && maxInRange; this.notInRange = !this.inRange; @@ -75,11 +109,25 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { initToday$() { const sub = this.dateSubject.subscribe((date) => { - this.isToday = this.dateAdapter.compareDate(date, this.dateAdapter.today()) === 0; + this.isToday = + this.dateAdapter.compareDate(date, this.dateAdapter.today()) === 0; }); this.subscription.add(sub); } + initDisabledDayOfWeek$() { + const sub = combineLatest([ + this.dateSubject, + this.datepicker.disabledDaysOfWeek$, + ]).subscribe(([date, disabledDayOfWeek]) => { + this.isDisabledDayOfWeek = + disabledDayOfWeek && + disabledDayOfWeek.includes(this.dateAdapter.getDayOfWeek(date)); + }); + + this.subscription.add(sub); + } + ngOnDestroy(): void { this.subscription.unsubscribe(); this.dateSubject.complete(); @@ -87,7 +135,7 @@ export class UiDatepickerCellDirective implements OnInit, OnDestroy { @HostListener('click') select() { - if (this.inRange && this.inDisplayedMonth) { + if (this.inRange && this.inDisplayedMonth && !this.isDisabledDayOfWeek) { this.datepicker.setSelected(this.date); } } diff --git a/apps/sales/src/app/modules/ui/datepicker/datepicker.ts b/apps/sales/src/app/modules/ui/datepicker/datepicker.ts index 80047cbfb..cafb99c38 100644 --- a/apps/sales/src/app/modules/ui/datepicker/datepicker.ts +++ b/apps/sales/src/app/modules/ui/datepicker/datepicker.ts @@ -45,10 +45,22 @@ export abstract class Datepicker { this.setMax(val); } + @Input() + get disabledDaysOfWeek() { + return this.disableDayOfWeekSubject.value; + } + set disabledDaysOfWeek(value: number[]) { + // 0 = Sunday, 1 = Monday, ... 6 = Saturday + this.disableDayOfWeekSubject.next(value); + } + protected selectedSubject = new BehaviorSubject(undefined); - protected displayedSubject = new BehaviorSubject(this.dateAdapter.today()); + protected displayedSubject = new BehaviorSubject( + this.dateAdapter.today() + ); protected minSubject = new BehaviorSubject(undefined); protected maxSubject = new BehaviorSubject(undefined); + protected disableDayOfWeekSubject = new BehaviorSubject(undefined); get selected$() { return this.selectedSubject.asObservable(); @@ -62,6 +74,9 @@ export abstract class Datepicker { get max$() { return this.maxSubject.asObservable(); } + get disabledDaysOfWeek$() { + return this.disableDayOfWeekSubject.asObservable(); + } constructor(private dateAdapter: DateAdapter) {} @@ -73,7 +88,10 @@ export abstract class Datepicker { this.setDisplayed(this.dateAdapter.addCalendarMonths(this.displayed, -1)); } - setSelected(date: TDate, { emit: emitChanged }: SetPropertyOptions = { emit: true }) { + setSelected( + date: TDate, + { emit: emitChanged }: SetPropertyOptions = { emit: true } + ) { if (!this.dateAdapter.isValid(date)) { this.selectedSubject.next(undefined); return; @@ -87,7 +105,10 @@ export abstract class Datepicker { } } - setDisplayed(date: TDate, { emit: emitChanged }: SetPropertyOptions = { emit: true }) { + setDisplayed( + date: TDate, + { emit: emitChanged }: SetPropertyOptions = { emit: true } + ) { if (!this.dateAdapter.isValid(date)) { this.displayedSubject.next(undefined); return; diff --git a/apps/sales/src/app/store/customer/shelf/details/details.effects.ts b/apps/sales/src/app/store/customer/shelf/details/details.effects.ts index 3351eafea..53a382a1a 100644 --- a/apps/sales/src/app/store/customer/shelf/details/details.effects.ts +++ b/apps/sales/src/app/store/customer/shelf/details/details.effects.ts @@ -119,7 +119,6 @@ export class DetailsEffects { ), flatMap((a) => { if (a.response.ok) { - console.log({ action: a }); this.searchStateFacade.reloadResults(); return [ actions.addOrderItems({ orderItems: a.response.body.result }), diff --git a/apps/sales/src/app/store/customer/shelf/details/details.facade.ts b/apps/sales/src/app/store/customer/shelf/details/details.facade.ts index 7ce8ecf2a..9e30c6820 100644 --- a/apps/sales/src/app/store/customer/shelf/details/details.facade.ts +++ b/apps/sales/src/app/store/customer/shelf/details/details.facade.ts @@ -17,25 +17,43 @@ import { shareReplay, bufferCount, finalize, map } from 'rxjs/operators'; export class DetailsFacade { constructor(private store: Store, private orderService: OrderService) {} - getOrderItemsByOrderNumber$(orderNumber: string): Observable { + getOrderItemsByOrderNumber$( + orderNumber: string + ): Observable { this.fetchOrderItemsByOrderNumber(orderNumber); - return this.store.select(selectors.selectOrderItemsByOrderNumber, orderNumber).pipe(shareReplay()); + return this.store + .select(selectors.selectOrderItemsByOrderNumber, orderNumber) + .pipe(shareReplay()); } - getOrderItemsByOrderNumberAndProcessingStatus$(orderNumber: string, processingStatus: OrderItemProcessingStatusValue) { + getOrderItemsByOrderNumberAndProcessingStatus$( + orderNumber: string, + processingStatus: OrderItemProcessingStatusValue + ) { return this.getOrderItemsByOrderNumber$(orderNumber).pipe( - map((items) => items.filter((item) => item.processingStatus === processingStatus)) + map((items) => + items.filter((item) => item.processingStatus === processingStatus) + ) ); } - getOrderItemsByCompartmentCode$(compartmentCode: string): Observable { + getOrderItemsByCompartmentCode$( + compartmentCode: string + ): Observable { this.fetchOrderItemsByCompartmentCode(compartmentCode); - return this.store.select(selectors.selectOrderItemsByCompartmentCode, compartmentCode).pipe(shareReplay()); + return this.store + .select(selectors.selectOrderItemsByCompartmentCode, compartmentCode) + .pipe(shareReplay()); } - getOrderItemsByCompartmentCodeAndProcessingStatus$(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue) { + getOrderItemsByCompartmentCodeAndProcessingStatus$( + compartmentCode: string, + processingStatus: OrderItemProcessingStatusValue + ) { return this.getOrderItemsByCompartmentCode$(compartmentCode).pipe( - map((items) => items.filter((item) => item.processingStatus === processingStatus)) + map((items) => + items.filter((item) => item.processingStatus === processingStatus) + ) ); } @@ -47,14 +65,22 @@ export class DetailsFacade { this.store.dispatch(actions.fetchDetailsByOrderNumber({ orderNumber })); } - changeStatus(changes: { orderItemSubsetId: number; orderItemId: number; orderId: number; data: StatusValues }[]) { - const changeStatusRequests = changes.map(({ data, orderId, orderItemId, orderItemSubsetId }) => - this.orderService.OrderChangeStatus({ - data, - orderId, - orderItemId, - orderItemSubsetId, - }) + changeStatus( + changes: { + orderItemSubsetId: number; + orderItemId: number; + orderId: number; + data: StatusValues; + }[] + ) { + const changeStatusRequests = changes.map( + ({ data, orderId, orderItemId, orderItemSubsetId }) => + this.orderService.OrderChangeStatus({ + data, + orderId, + orderItemId, + orderItemSubsetId, + }) ); return concat(...changeStatusRequests) @@ -68,14 +94,24 @@ export class DetailsFacade { return [...itemIds, change.orderItemSubsetId]; }, [] as number[]); - this.store.dispatch(actions.fetchDetailsOrderItemSubsetIds({ orderItemSubsetIds })); + this.store.dispatch( + actions.fetchDetailsOrderItemSubsetIds({ orderItemSubsetIds }) + ); }) ) .toPromise(); } - patchOrderItems(changes: { orderItemId: number; orderId: number; orderItem: Partial }[]) { - const requests = changes.map((payload) => this.orderService.OrderPatchOrderItem(payload)); + patchOrderItems( + changes: { + orderItemId: number; + orderId: number; + orderItem: Partial; + }[] + ) { + const requests = changes.map((payload) => + this.orderService.OrderPatchOrderItem(payload) + ); return concat(...requests) .pipe( @@ -88,16 +124,25 @@ export class DetailsFacade { return [...itemIds, change.orderItemId]; }, [] as number[]); - this.store.dispatch(actions.fetchDetailsOrderItemIds({ orderItemIds })); + this.store.dispatch( + actions.fetchDetailsOrderItemIds({ orderItemIds }) + ); }) ) .toPromise(); } patchOrderItemSubsets( - changes: { orderItemSubsetId: number; orderItemId: number; orderId: number; orderItemSubset: Partial }[] + changes: { + orderItemSubsetId: number; + orderItemId: number; + orderId: number; + orderItemSubset: Partial; + }[] ) { - const requests = changes.map((payload) => this.orderService.OrderPatchOrderItemSubset(payload)); + const requests = changes.map((payload) => + this.orderService.OrderPatchOrderItemSubset(payload) + ); return concat(...requests) .pipe( @@ -110,22 +155,29 @@ export class DetailsFacade { return [...itemIds, change.orderItemSubsetId]; }, [] as number[]); - this.store.dispatch(actions.fetchDetailsOrderItemSubsetIds({ orderItemSubsetIds })); + this.store.dispatch( + actions.fetchDetailsOrderItemSubsetIds({ orderItemSubsetIds }) + ); }) ) .toPromise(); } pickedUp(items: OrderItemListItemDTO[], quantities?: Map) { - const data = items.map(({ orderId, orderItemId, orderItemSubsetId, quantity }) => ({ - orderId, - orderItemId, - orderItemSubsetId, - data: { - processingStatus: 256, - quantity: !!quantities && quantities.has(orderItemId) ? quantities.get(orderItemId) : quantity, - } as StatusValues, - })); + const data = items.map( + ({ orderId, orderItemId, orderItemSubsetId, quantity }) => ({ + orderId, + orderItemId, + orderItemSubsetId, + data: { + processingStatus: 256, + quantity: + !!quantities && quantities.has(orderItemId) + ? quantities.get(orderItemId) + : quantity, + } as StatusValues, + }) + ); return this.changeStatus(data); } @@ -134,7 +186,11 @@ export class DetailsFacade { orderId, orderItemId, orderItemSubsetId, - data: { processingStatus: 8192, compartmentNumber: '', compartmentInfo: '' } as StatusValues, + data: { + processingStatus: 8192, + compartmentNumber: '', + compartmentInfo: '', + } as StatusValues, })); return this.changeStatus(data); } @@ -144,36 +200,55 @@ export class DetailsFacade { orderId, orderItemId, orderItemSubsetId, - data: { processingStatus: 131072 } as StatusValues, + data: { processingStatus: 262144 } as StatusValues, })); return this.changeStatus(data); } async arrived(items: OrderItemListItemDTO[], compartmentInfo: string) { - const payloads = items.map(({ orderId, orderItemId, orderItemSubsetId }) => ({ - orderId, - orderItemId, - orderItemSubsetId, - data: { processingStatus: 128, compartmentInfo } as StatusValues, - })); + const payloads = items.map( + ({ orderId, orderItemId, orderItemSubsetId }) => ({ + orderId, + orderItemId, + orderItemSubsetId, + data: { processingStatus: 128, compartmentInfo } as StatusValues, + }) + ); const firstPayload = payloads[0]; - let pendingPayloads = payloads.filter((f) => f.orderItemSubsetId !== firstPayload.orderItemSubsetId); + let pendingPayloads = payloads.filter( + (f) => f.orderItemSubsetId !== firstPayload.orderItemSubsetId + ); const firstPayloadResult = (await this.changeStatus([firstPayload]))[0]; - pendingPayloads = pendingPayloads.map(({ orderItemId, orderId, orderItemSubsetId, data }) => ({ - orderItemId, - orderId, - orderItemSubsetId, - data: { ...data, compartmentNumber: firstPayloadResult.result.item1.compartmentCode }, - })); + pendingPayloads = pendingPayloads.map( + ({ orderItemId, orderId, orderItemSubsetId, data }) => ({ + orderItemId, + orderId, + orderItemSubsetId, + data: { + ...data, + compartmentNumber: firstPayloadResult.result.item1.compartmentCode, + }, + }) + ); const pedingPayloadResults = await this.changeStatus(pendingPayloads); return [firstPayloadResult, ...pedingPayloadResults]; } - setComment({ item, comment }: { item: { orderId?: number; orderItemId?: number; orderItemSubsetId?: number }; comment?: string }) { + setComment({ + item, + comment, + }: { + item: { + orderId?: number; + orderItemId?: number; + orderItemSubsetId?: number; + }; + comment?: string; + }) { this.store.dispatch( actions.patchComment({ orderId: item.orderId, @@ -188,7 +263,11 @@ export class DetailsFacade { items, estimatedShippingDate, }: { - items: Array<{ orderId?: number; orderItemId?: number; orderItemSubsetId?: number }>; + items: Array<{ + orderId?: number; + orderItemId?: number; + orderItemSubsetId?: number; + }>; estimatedShippingDate: Date | string; }) { this.patchOrderItemSubsets( @@ -197,7 +276,10 @@ export class DetailsFacade { orderItemId: orderItem.orderItemId, orderItemSubsetId: orderItem.orderItemSubsetId, orderItemSubset: { - estimatedShippingDate: estimatedShippingDate instanceof Date ? estimatedShippingDate.toJSON() : estimatedShippingDate, + estimatedShippingDate: + estimatedShippingDate instanceof Date + ? estimatedShippingDate.toJSON() + : estimatedShippingDate, }, })) ); @@ -207,7 +289,11 @@ export class DetailsFacade { items, pickUpDeadline, }: { - items: Array<{ orderId?: number; orderItemId?: number; orderItemSubsetId?: number }>; + items: Array<{ + orderId?: number; + orderItemId?: number; + orderItemSubsetId?: number; + }>; pickUpDeadline: Date | string; }) { const payload: { From cc69a0a24e5256531a71c518d96bce5c57e894cc Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Wed, 2 Sep 2020 18:14:10 +0200 Subject: [PATCH 109/135] Layout Fix; Edit Navigation Fix --- .../app/components/menu/menu.component.html | 8 +- .../edit-order-item.component.html | 60 +-- .../order-details-card.component.html | 103 +--- .../order-details-card.component.ts | 4 +- .../shelf-edit-compartment.component.html | 81 +--- .../shelf-edit-compartment.component.ts | 79 +-- .../shelf-edit-order.component.ts | 56 +-- .../ui/datepicker/datepicker.component.scss | 1 + package-lock.json | 452 +++++++++--------- 9 files changed, 321 insertions(+), 523 deletions(-) diff --git a/apps/sales/src/app/components/menu/menu.component.html b/apps/sales/src/app/components/menu/menu.component.html index 1c57f5996..b125307f0 100644 --- a/apps/sales/src/app/components/menu/menu.component.html +++ b/apps/sales/src/app/components/menu/menu.component.html @@ -39,13 +39,13 @@ Kundensuche
- - diff --git a/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html b/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html index f0743d62f..f6750a039 100644 --- a/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html +++ b/apps/sales/src/app/modules/shelf/components/edit-order-item/edit-order-item.component.html @@ -1,67 +1,35 @@ - +
- +
- +
- +
- +
- +
- +
- +
- + +
-
+
\ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index f14c1ee6a..7a950f992 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -1,9 +1,7 @@

{{ orderDetails?.firstName }} {{ orderDetails?.lastName }} - {{ orderDetails?.compartmentCode }} - {{ orderDetails?.compartmentInfo }} + {{ orderDetails?.compartmentCode }} + {{ orderDetails?.compartmentInfo }}

@@ -32,49 +30,28 @@
Status
- - - + - @@ -106,29 +83,16 @@
vsl. Lieferdatum
- - + (save)="changeEstimatedDeliveryDate.emit($event); uiDatepicker.close()">
@@ -138,36 +102,21 @@
Abholfrist
- - + -
- + \ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts index 4308b37ff..83e9c6370 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.ts @@ -31,8 +31,8 @@ export class ShelfOrderDetailsCardComponent implements OnInit { get pickupDeadlines() { const dedalineMap = new Map(); - let TWO_WEEKS = 1000 * 60 * 60 * 24 * 7; - let FOUR_WEEKS = 1000 * 60 * 60 * 24 * 14; + let TWO_WEEKS = 1000 * 60 * 60 * 24 * 14; + let FOUR_WEEKS = 1000 * 60 * 60 * 24 * 28; if (this.orderDetails) { TWO_WEEKS += new Date(this.orderDetails.pickupDeadline).getTime(); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html index 5d82ad50d..ed78bfedb 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.html @@ -7,88 +7,47 @@
- +
- +
- +
- +
- +
- + " [labelPipe]="processingStatusPipe" [optionsPipe]="processingStatusPipe">
- - + + " [labelPipe]="datePipe" [optionsPipe]="dateOptionsPipe">
- + " [labelPipe]="datePipe" [optionsPipe]="dateOptionsPipe">
- - + +
@@ -96,10 +55,6 @@
- + -
+
\ No newline at end of file diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts index 6db1acb03..28bedf8e5 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts @@ -1,28 +1,11 @@ -import { - Component, - OnInit, - ChangeDetectionStrategy, - ChangeDetectorRef, -} from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable, from } from 'rxjs'; -import { - filter, - map, - distinctUntilChanged, - shareReplay, - take, - withLatestFrom, - first, -} from 'rxjs/operators'; +import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; import { ShelfEditFormService } from '../../services'; import { FormGroup, FormArray } from '@angular/forms'; -import { - ProcessingStatusPipe, - PickUpDateOptionsToDisplayValuesPipe, - ProcessingStatusOptionsPipe, -} from '../../pipes'; +import { ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe, ProcessingStatusOptionsPipe } from '../../pipes'; import { DatePipe } from '@angular/common'; import { ShelfNavigationService } from '../../shared/services'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; @@ -63,10 +46,7 @@ export class ShelfEditCompartmentComponent implements OnInit { get processingStatus$() { return this.activatedRoute.params.pipe( - map( - (params) => - Number(params.processingStatus) as OrderItemProcessingStatusValue - ), + map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue), distinctUntilChanged(), shareReplay() ); @@ -77,12 +57,8 @@ export class ShelfEditCompartmentComponent implements OnInit { } async loadCompartmentAndInitForm() { - const compartmentCode = await this.compartmentCode$ - .pipe(take(1)) - .toPromise(); - const processingStatus = await this.processingStatus$ - .pipe(take(1)) - .toPromise(); + const compartmentCode = await this.compartmentCode$.pipe(take(1)).toPromise(); + const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise(); this.populateFormData(compartmentCode, processingStatus); } @@ -90,24 +66,15 @@ export class ShelfEditCompartmentComponent implements OnInit { async onSubmit() { console.log(this.form.valid); - const compartmentCode = await this.compartmentCode$ - .pipe(first()) - .toPromise(); - const processingStatus = await this.processingStatus$ - .pipe(first()) - .toPromise(); - const submitResult = await this.formService.submit( - this.form, - processingStatus - ); + const compartmentCode = await this.compartmentCode$.pipe(first()).toPromise(); + const processingStatus = await this.processingStatus$.pipe(first()).toPromise(); + const submitResult = await this.formService.submit(this.form, processingStatus); let newValues; if (submitResult) { newValues = { - compartmentCode: - this.form.get('compartmentCode').value || compartmentCode, - processingStatus: - this.form.get('processingStatus').value || processingStatus, + compartmentCode: this.form.get('compartmentCode').value || compartmentCode, + processingStatus: this.form.get('processingStatus').value || processingStatus, }; this.shelfNavigationService.navigateBackToDetails(newValues, { @@ -118,24 +85,16 @@ export class ShelfEditCompartmentComponent implements OnInit { } onAbortEdit() { - return this.compartmentCode$ - .pipe(take(1), withLatestFrom(this.processingStatus$)) - .subscribe(([compartmentCode, processingStatus]) => - this.shelfNavigationService.navigateToDetails({ - compartmentCode, - processingStatus, - }) - ); + return this.compartmentCode$.pipe(take(1), withLatestFrom(this.processingStatus$)).subscribe(([compartmentCode, processingStatus]) => + this.shelfNavigationService.navigateBackToDetails({ + compartmentCode, + processingStatus, + }) + ); } - private async populateFormData( - compartmentCode: string, - processingStatus: OrderItemProcessingStatusValue - ) { - this.form = await this.formService.createFormByCompartmentCode( - compartmentCode, - processingStatus - ); + private async populateFormData(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue) { + this.form = await this.formService.createFormByCompartmentCode(compartmentCode, processingStatus); this.items = this.formService.getItemsForm(compartmentCode); this.customerName = this.formService.getCustomerName(compartmentCode); this.cdr.detectChanges(); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts index 71e629d99..502b85e57 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts @@ -1,28 +1,11 @@ -import { - Component, - OnInit, - ChangeDetectionStrategy, - ChangeDetectorRef, -} from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { FormGroup, FormArray } from '@angular/forms'; import { ShelfEditFormService } from '../../services'; import { ShelfNavigationService } from '../../shared/services'; -import { - filter, - map, - distinctUntilChanged, - shareReplay, - take, - withLatestFrom, - first, -} from 'rxjs/operators'; +import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; -import { - ProcessingStatusPipe, - PickUpDateOptionsToDisplayValuesPipe, - ProcessingStatusOptionsPipe, -} from '../../pipes'; +import { ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe, ProcessingStatusOptionsPipe } from '../../pipes'; import { DatePipe } from '@angular/common'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; import { from } from 'rxjs'; @@ -62,10 +45,7 @@ export class ShelfEditOrderComponent implements OnInit { get processingStatus$() { return this.activatedRoute.params.pipe( - map( - (params) => - Number(params.processingStatus) as OrderItemProcessingStatusValue - ), + map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue), distinctUntilChanged(), shareReplay() ); @@ -77,9 +57,7 @@ export class ShelfEditOrderComponent implements OnInit { async loadOrderNumberAndInitForm() { const orderNumber = await this.orderNumber$.pipe(take(1)).toPromise(); - const processingStatus = await this.processingStatus$ - .pipe(take(1)) - .toPromise(); + const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise(); console.log('loadOrderNumberAndInitForm', { orderNumber, processingStatus, @@ -89,20 +67,14 @@ export class ShelfEditOrderComponent implements OnInit { async onSubmit() { const orderNumber = await this.orderNumber$.pipe(first()).toPromise(); - const processingStatus = await this.processingStatus$ - .pipe(first()) - .toPromise(); + const processingStatus = await this.processingStatus$.pipe(first()).toPromise(); - const submitResult = await this.formService.submit( - this.form, - processingStatus - ); + const submitResult = await this.formService.submit(this.form, processingStatus); if (submitResult) { this.shelfNavigationService.navigateBackToDetails({ orderNumber, - processingStatus: - this.form.get('processingStatus').value || processingStatus, + processingStatus: this.form.get('processingStatus').value || processingStatus, }); } } @@ -112,21 +84,15 @@ export class ShelfEditOrderComponent implements OnInit { .pipe(take(1), withLatestFrom(this.processingStatus$)) .subscribe(([orderNumber, processingStatus]) => - this.shelfNavigationService.navigateToDetails({ + this.shelfNavigationService.navigateBackToDetails({ orderNumber, processingStatus, }) ); } - private async populateFormData( - orderNumber: string, - processingStatus: OrderItemProcessingStatusValue - ) { - this.form = await this.formService.createFormByOrderNumber( - orderNumber, - processingStatus - ); + private async populateFormData(orderNumber: string, processingStatus: OrderItemProcessingStatusValue) { + this.form = await this.formService.createFormByOrderNumber(orderNumber, processingStatus); console.log({ form: this.form }); this.items = this.formService.getItemsForm(orderNumber); diff --git a/apps/sales/src/app/modules/ui/datepicker/datepicker.component.scss b/apps/sales/src/app/modules/ui/datepicker/datepicker.component.scss index c7fcbbe36..91e8ec675 100644 --- a/apps/sales/src/app/modules/ui/datepicker/datepicker.component.scss +++ b/apps/sales/src/app/modules/ui/datepicker/datepicker.component.scss @@ -3,6 +3,7 @@ display: block; position: relative; width: 100%; + z-index: 10; } .hr { diff --git a/package-lock.json b/package-lock.json index 3f5396a9c..a9aa7a453 100644 --- a/package-lock.json +++ b/package-lock.json @@ -992,7 +992,7 @@ }, "source-map": { "version": "0.5.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.5.7.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } @@ -1019,7 +1019,7 @@ }, "source-map": { "version": "0.5.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.5.7.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } @@ -3505,7 +3505,7 @@ }, "@types/q": { "version": "0.0.32", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@types/q/-/q-0.0.32.tgz", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", "dev": true }, @@ -3799,7 +3799,7 @@ }, "after": { "version": "0.8.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/after/-/after-0.8.2.tgz", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" }, "agent-base": { @@ -3931,13 +3931,13 @@ }, "ansi-html": { "version": "0.0.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/ansi-html/-/ansi-html-0.0.7.tgz", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", "dev": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/ansi-regex/-/ansi-regex-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { @@ -4029,7 +4029,7 @@ }, "array-find-index": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/array-find-index/-/array-find-index-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" }, "array-flatten": { @@ -4055,7 +4055,7 @@ }, "array-unique": { "version": "0.3.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/array-unique/-/array-unique-0.3.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "arraybuffer.slice": { @@ -4065,7 +4065,7 @@ }, "arrify": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/arrify/-/arrify-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, @@ -4136,7 +4136,7 @@ }, "assign-symbols": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/assign-symbols/-/assign-symbols-1.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "async": { @@ -4163,7 +4163,7 @@ }, "async-foreach": { "version": "0.1.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/async-foreach/-/async-foreach-0.1.3.tgz", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" }, "async-limiter": { @@ -4173,7 +4173,7 @@ }, "asynckit": { "version": "0.4.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/asynckit/-/asynckit-0.4.0.tgz", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { @@ -4255,7 +4255,7 @@ }, "backo2": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/backo2/-/backo2-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" }, "balanced-match": { @@ -4279,7 +4279,7 @@ "dependencies": { "define-property": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/define-property/-/define-property-1.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { "is-descriptor": "^1.0.0" @@ -4315,7 +4315,7 @@ }, "base64-arraybuffer": { "version": "0.1.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" }, "base64-js": { @@ -4331,7 +4331,7 @@ }, "batch": { "version": "0.6.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/batch/-/batch-0.6.1.tgz", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, @@ -4369,7 +4369,7 @@ }, "block-stream": { "version": "0.0.9", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/block-stream/-/block-stream-0.0.9.tgz", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "requires": { "inherits": "~2.0.0" @@ -4435,7 +4435,7 @@ }, "bonjour": { "version": "3.5.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/bonjour/-/bonjour-3.5.0.tgz", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", "dev": true, "requires": { @@ -4483,7 +4483,7 @@ }, "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, @@ -4596,7 +4596,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -4785,7 +4785,7 @@ }, "buffer-xor": { "version": "1.0.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/buffer-xor/-/buffer-xor-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, @@ -4802,13 +4802,13 @@ }, "builtins": { "version": "1.0.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/builtins/-/builtins-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", "dev": true }, "bytes": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/bytes/-/bytes-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, @@ -4963,12 +4963,12 @@ }, "camelcase": { "version": "2.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/camelcase/-/camelcase-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" }, "camelcase-keys": { "version": "2.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "requires": { "camelcase": "^2.0.0", @@ -4989,7 +4989,7 @@ }, "caseless": { "version": "0.12.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/caseless/-/caseless-0.12.0.tgz", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chalk": { @@ -5090,7 +5090,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { "is-descriptor": "^0.1.0" @@ -5174,7 +5174,7 @@ }, "code-point-at": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/code-point-at/-/code-point-at-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "codelyzer": { @@ -5193,7 +5193,7 @@ "dependencies": { "source-map": { "version": "0.5.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.5.7.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, @@ -5207,7 +5207,7 @@ }, "collection-visit": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/collection-visit/-/collection-visit-1.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "requires": { "map-visit": "^1.0.0", @@ -5225,7 +5225,7 @@ }, "color-name": { "version": "1.1.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/color-name/-/color-name-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, @@ -5397,12 +5397,12 @@ }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/console-control-strings/-/console-control-strings-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "constants-browserify": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/constants-browserify/-/constants-browserify-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, @@ -5437,13 +5437,13 @@ }, "cookie-signature": { "version": "1.0.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/cookie-signature/-/cookie-signature-1.0.6.tgz", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, "cookies": { "version": "0.3.8", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/cookies/-/cookies-0.3.8.tgz", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.3.8.tgz", "integrity": "sha1-kv5QkY89Va7Erp2Xi83doq2ijOk=" }, "copy-concurrently": { @@ -5744,7 +5744,7 @@ }, "cross-spawn": { "version": "3.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/cross-spawn/-/cross-spawn-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", "requires": { "lru-cache": "^4.0.1", @@ -5772,7 +5772,7 @@ }, "crypto-random-string": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, @@ -5795,7 +5795,7 @@ }, "cssauron": { "version": "1.4.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/cssauron/-/cssauron-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", "dev": true, "requires": { @@ -5816,7 +5816,7 @@ }, "currently-unhandled": { "version": "0.4.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "requires": { "array-find-index": "^1.0.1" @@ -5824,13 +5824,13 @@ }, "custom-event": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/custom-event/-/custom-event-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", "dev": true }, "cyclist": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/cyclist/-/cyclist-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, @@ -5858,13 +5858,13 @@ }, "debuglog": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/debuglog/-/debuglog-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", "dev": true }, "decamelize": { "version": "1.2.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/decamelize/-/decamelize-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { @@ -5919,7 +5919,7 @@ }, "default-require-extensions": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { @@ -5928,7 +5928,7 @@ "dependencies": { "strip-bom": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/strip-bom/-/strip-bom-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true } @@ -6061,12 +6061,12 @@ }, "delegates": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/delegates/-/delegates-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "depd": { "version": "1.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/depd/-/depd-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, @@ -6088,7 +6088,7 @@ }, "destroy": { "version": "1.0.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/destroy/-/destroy-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, @@ -6100,7 +6100,7 @@ }, "dezalgo": { "version": "1.0.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/dezalgo/-/dezalgo-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", "dev": true, "requires": { @@ -6150,7 +6150,7 @@ }, "dnode": { "version": "0.9.12", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/dnode/-/dnode-0.9.12.tgz", + "resolved": "https://registry.npmjs.org/dnode/-/dnode-0.9.12.tgz", "integrity": "sha1-nRq2s1Mng/vN1uTneOV2qL+fqfc=", "requires": { "dnode-protocol": "~0.1.2", @@ -6162,7 +6162,7 @@ "dependencies": { "socket.io": { "version": "0.8.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/socket.io/-/socket.io-0.8.6.tgz", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-0.8.6.tgz", "integrity": "sha1-9KIZyBDtOc3zuqEm99w7PwefKbE=", "requires": { "policyfile": "0.0.4", @@ -6200,7 +6200,7 @@ }, "dnode-protocol": { "version": "0.1.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/dnode-protocol/-/dnode-protocol-0.1.5.tgz", + "resolved": "https://registry.npmjs.org/dnode-protocol/-/dnode-protocol-0.1.5.tgz", "integrity": "sha1-MR13iwmEZBldyu8tKJaQkd5uvkE=", "requires": { "jsonify": "~0.0.0", @@ -6209,7 +6209,7 @@ }, "dns-equal": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/dns-equal/-/dns-equal-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", "dev": true }, @@ -6294,7 +6294,7 @@ }, "ejs": { "version": "0.7.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/ejs/-/ejs-0.7.2.tgz", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-0.7.2.tgz", "integrity": "sha1-gDLunx/M2ug3ZYL+4cbYCzGqG9M=" }, "electron-to-chromium": { @@ -6340,7 +6340,7 @@ }, "encodeurl": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/encodeurl/-/encodeurl-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, @@ -6444,7 +6444,7 @@ }, "err-code": { "version": "1.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/err-code/-/err-code-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", "dev": true }, @@ -6467,7 +6467,7 @@ }, "error-page": { "version": "0.0.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/error-page/-/error-page-0.0.3.tgz", + "resolved": "https://registry.npmjs.org/error-page/-/error-page-0.0.3.tgz", "integrity": "sha1-4EmGqGabjgjcx0TFmYi5nVgov6w=" }, "es-abstract": { @@ -6508,7 +6508,7 @@ }, "es6-promisify": { "version": "5.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/es6-promisify/-/es6-promisify-5.0.0.tgz", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { @@ -6517,13 +6517,13 @@ }, "escape-html": { "version": "1.0.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/escape-html/-/escape-html-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "escape-string-regexp": { "version": "1.0.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint-scope": { @@ -6571,7 +6571,7 @@ }, "etag": { "version": "1.8.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/etag/-/etag-1.8.1.tgz", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, @@ -6643,7 +6643,7 @@ }, "expand-brackets": { "version": "2.1.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/expand-brackets/-/expand-brackets-2.1.4.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "requires": { "debug": "^2.3.3", @@ -6657,7 +6657,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { "is-descriptor": "^0.1.0" @@ -6665,7 +6665,7 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { "is-extendable": "^0.1.0" @@ -6723,7 +6723,7 @@ }, "array-flatten": { "version": "1.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/array-flatten/-/array-flatten-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, @@ -6941,7 +6941,7 @@ }, "extsprintf": { "version": "1.3.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/extsprintf/-/extsprintf-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "faker": { @@ -6967,7 +6967,7 @@ }, "faye-websocket": { "version": "0.10.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/faye-websocket/-/faye-websocket-0.10.0.tgz", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { @@ -7177,7 +7177,7 @@ }, "find-parent-dir": { "version": "0.3.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", "dev": true }, @@ -7228,12 +7228,12 @@ }, "for-in": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/for-in/-/for-in-1.0.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "forever-agent": { "version": "0.6.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/forever-agent/-/forever-agent-0.6.1.tgz", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { @@ -7279,7 +7279,7 @@ }, "from2": { "version": "2.3.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/from2/-/from2-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", "dev": true, "requires": { @@ -7318,7 +7318,7 @@ }, "fs-write-stream-atomic": { "version": "1.0.10", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", "dev": true, "requires": { @@ -7833,7 +7833,7 @@ }, "gauge": { "version": "2.7.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/gauge/-/gauge-2.7.4.tgz", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "requires": { "aproba": "^1.0.3", @@ -7873,7 +7873,7 @@ }, "get-stdin": { "version": "4.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/get-stdin/-/get-stdin-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" }, "get-stream": { @@ -7887,7 +7887,7 @@ }, "get-value": { "version": "2.0.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/get-value/-/get-value-2.0.6.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getpass": { @@ -7913,7 +7913,7 @@ }, "glob-parent": { "version": "3.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/glob-parent/-/glob-parent-3.1.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "requires": { "is-glob": "^3.1.0", @@ -7922,7 +7922,7 @@ "dependencies": { "is-glob": { "version": "3.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-glob/-/is-glob-3.1.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "requires": { "is-extglob": "^2.1.0" @@ -7932,7 +7932,7 @@ }, "global-dirs": { "version": "0.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/global-dirs/-/global-dirs-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "dev": true, "requires": { @@ -8007,7 +8007,7 @@ }, "hammerjs": { "version": "2.0.8", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/hammerjs/-/hammerjs-2.0.8.tgz", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" }, "handle-thing": { @@ -8038,7 +8038,7 @@ }, "har-schema": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/har-schema/-/har-schema-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { @@ -8084,7 +8084,7 @@ }, "has-cors": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/has-cors/-/has-cors-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" }, "has-flag": { @@ -8101,12 +8101,12 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/has-unicode/-/has-unicode-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "has-value": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/has-value/-/has-value-1.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "requires": { "get-value": "^2.0.6", @@ -8187,7 +8187,7 @@ }, "hmac-drbg": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { @@ -8300,7 +8300,7 @@ }, "http-signature": { "version": "1.2.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/http-signature/-/http-signature-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { "assert-plus": "^1.0.0", @@ -8367,7 +8367,7 @@ }, "iferr": { "version": "0.1.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/iferr/-/iferr-0.1.5.tgz", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, @@ -8456,7 +8456,7 @@ }, "indent-string": { "version": "2.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/indent-string/-/indent-string-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "requires": { "repeating": "^2.0.0" @@ -8475,7 +8475,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/inflight/-/inflight-1.0.6.tgz", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", @@ -8629,7 +8629,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { "kind-of": "^3.0.2" @@ -8637,7 +8637,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { "is-buffer": "^1.1.5" @@ -8653,12 +8653,12 @@ }, "is-arrayish": { "version": "0.2.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-arrayish/-/is-arrayish-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-binary-path/-/is-binary-path-1.0.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "requires": { "binary-extensions": "^1.0.0" @@ -8694,7 +8694,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { "kind-of": "^3.0.2" @@ -8702,7 +8702,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { "is-buffer": "^1.1.5" @@ -8735,7 +8735,7 @@ }, "is-directory": { "version": "0.3.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-directory/-/is-directory-0.3.1.tgz", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, @@ -8746,7 +8746,7 @@ }, "is-extglob": { "version": "2.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-extglob/-/is-extglob-2.1.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-finite": { @@ -8775,7 +8775,7 @@ }, "is-installed-globally": { "version": "0.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "dev": true, "requires": { @@ -8785,7 +8785,7 @@ }, "is-module": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-module/-/is-module-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, @@ -8797,7 +8797,7 @@ }, "is-number": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-number/-/is-number-3.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { "kind-of": "^3.0.2" @@ -8805,7 +8805,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { "is-buffer": "^1.1.5" @@ -8845,7 +8845,7 @@ }, "is-plain-obj": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, @@ -8885,7 +8885,7 @@ }, "is-stream": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-stream/-/is-stream-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, @@ -8900,12 +8900,12 @@ }, "is-typedarray": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-typedarray/-/is-typedarray-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/is-utf8/-/is-utf8-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, "is-windows": { @@ -8927,7 +8927,7 @@ }, "isarray": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/isarray/-/isarray-1.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isbinaryfile": { @@ -8941,7 +8941,7 @@ }, "isexe": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/isexe/-/isexe-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { @@ -8951,7 +8951,7 @@ }, "isstream": { "version": "0.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/isstream/-/isstream-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-api": { @@ -9114,7 +9114,7 @@ }, "jasmine": { "version": "2.8.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/jasmine/-/jasmine-2.8.0.tgz", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", "dev": true, "requires": { @@ -9125,7 +9125,7 @@ "dependencies": { "jasmine-core": { "version": "2.8.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/jasmine-core/-/jasmine-core-2.8.0.tgz", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", "dev": true } @@ -9133,7 +9133,7 @@ }, "jasmine-core": { "version": "2.99.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/jasmine-core/-/jasmine-core-2.99.1.tgz", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", "dev": true }, @@ -9217,7 +9217,7 @@ }, "json-schema": { "version": "0.2.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/json-schema/-/json-schema-0.2.3.tgz", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-ref-parser": { @@ -9304,7 +9304,7 @@ }, "jsprim": { "version": "1.4.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/jsprim/-/jsprim-1.4.1.tgz", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "requires": { "assert-plus": "1.0.0", @@ -9548,13 +9548,13 @@ }, "karma-jasmine": { "version": "1.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/karma-jasmine/-/karma-jasmine-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.2.tgz", "integrity": "sha1-OU8rJf+0pkS5rabyLUQ+L9CIhsM=", "dev": true }, "karma-jasmine-html-reporter": { "version": "0.2.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=", "dev": true, "requires": { @@ -9572,7 +9572,7 @@ }, "keygrip": { "version": "0.2.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/keygrip/-/keygrip-0.2.4.tgz", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-0.2.4.tgz", "integrity": "sha1-ndGy5IWhFiydTm94feh/xQ+HvFg=" }, "keyv": { @@ -9606,7 +9606,7 @@ }, "lazy": { "version": "1.0.11", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/lazy/-/lazy-1.0.11.tgz", + "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=" }, "lcid": { @@ -9664,7 +9664,7 @@ }, "less-plugin-npm-import": { "version": "2.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/less-plugin-npm-import/-/less-plugin-npm-import-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/less-plugin-npm-import/-/less-plugin-npm-import-2.1.0.tgz", "integrity": "sha1-gj5phskzGKmBccqFiEi2vq1Vvz4=", "dev": true, "requires": { @@ -9674,7 +9674,7 @@ "dependencies": { "promise": { "version": "7.0.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/promise/-/promise-7.0.4.tgz", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.0.4.tgz", "integrity": "sha1-Nj6EpMNsg1a4kP7WLJHOhdAu1Tk=", "dev": true, "requires": { @@ -9683,7 +9683,7 @@ }, "resolve": { "version": "1.1.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/resolve/-/resolve-1.1.7.tgz", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true } @@ -9725,13 +9725,13 @@ }, "lines-and-columns": { "version": "1.1.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, "load-json-file": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { "graceful-fs": "^4.1.2", @@ -9788,7 +9788,7 @@ }, "lodash.debounce": { "version": "4.0.8", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "log4js": { @@ -9838,7 +9838,7 @@ }, "loud-rejection": { "version": "1.6.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/loud-rejection/-/loud-rejection-1.6.0.tgz", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "requires": { "currently-unhandled": "^0.4.1", @@ -9977,7 +9977,7 @@ }, "map-obj": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/map-obj/-/map-obj-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" }, "map-visit": { @@ -10001,7 +10001,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, @@ -10018,7 +10018,7 @@ }, "memory-fs": { "version": "0.4.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/memory-fs/-/memory-fs-0.4.1.tgz", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { @@ -10028,13 +10028,13 @@ }, "memorystream": { "version": "0.3.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/memorystream/-/memorystream-0.3.1.tgz", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", "dev": true }, "meow": { "version": "3.7.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/meow/-/meow-3.7.0.tgz", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "requires": { "camelcase-keys": "^2.0.0", @@ -10087,7 +10087,7 @@ }, "methods": { "version": "1.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/methods/-/methods-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "dev": true }, @@ -10277,7 +10277,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/ms/-/ms-2.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multicast-dns": { @@ -10292,7 +10292,7 @@ }, "multicast-dns-service-types": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, @@ -10692,7 +10692,7 @@ }, "ngx-toggle-switch": { "version": "2.0.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/ngx-toggle-switch/-/ngx-toggle-switch-2.0.5.tgz", + "resolved": "https://registry.npmjs.org/ngx-toggle-switch/-/ngx-toggle-switch-2.0.5.tgz", "integrity": "sha1-7Z3ji09SdjYS8dAL5V33M3Dn0CA=" }, "nice-try": { @@ -10739,7 +10739,7 @@ "dependencies": { "semver": { "version": "5.3.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/semver/-/semver-5.3.0.tgz", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" }, "tar": { @@ -10868,7 +10868,7 @@ }, "nopt": { "version": "3.0.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/nopt/-/nopt-3.0.6.tgz", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "requires": { "abbrev": "1" @@ -10901,7 +10901,7 @@ }, "normalize-url": { "version": "1.9.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/normalize-url/-/normalize-url-1.9.1.tgz", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", "dev": true, "requires": { @@ -11034,7 +11034,7 @@ }, "load-json-file": { "version": "4.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/load-json-file/-/load-json-file-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { @@ -11046,7 +11046,7 @@ }, "parse-json": { "version": "4.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/parse-json/-/parse-json-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { @@ -11056,7 +11056,7 @@ }, "read-pkg": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/read-pkg/-/read-pkg-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { @@ -11067,7 +11067,7 @@ }, "strip-bom": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/strip-bom/-/strip-bom-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true } @@ -11075,7 +11075,7 @@ }, "npm-run-path": { "version": "2.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/npm-run-path/-/npm-run-path-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { @@ -11095,7 +11095,7 @@ }, "null-check": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/null-check/-/null-check-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", "dev": true }, @@ -11107,7 +11107,7 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/number-is-nan/-/number-is-nan-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "oauth-sign": { @@ -11117,12 +11117,12 @@ }, "object-assign": { "version": "4.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/object-assign/-/object-assign-4.1.1.tgz", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-component": { "version": "0.0.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/object-component/-/object-component-0.0.3.tgz", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" }, "object-copy": { @@ -11177,7 +11177,7 @@ }, "object-visit": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/object-visit/-/object-visit-1.0.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "requires": { "isobject": "^3.0.0" @@ -11290,7 +11290,7 @@ }, "optimist": { "version": "0.6.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/optimist/-/optimist-0.6.1.tgz", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { @@ -11356,13 +11356,13 @@ }, "p-defer": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/p-defer/-/p-defer-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", "dev": true }, "p-finally": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/p-finally/-/p-finally-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, @@ -11528,7 +11528,7 @@ }, "parse-json": { "version": "2.2.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/parse-json/-/parse-json-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { "error-ex": "^1.2.0" @@ -11606,7 +11606,7 @@ }, "path-dirname": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/path-dirname/-/path-dirname-1.0.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { @@ -11622,7 +11622,7 @@ }, "path-is-inside": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/path-is-inside/-/path-is-inside-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, @@ -11640,7 +11640,7 @@ }, "path-to-regexp": { "version": "0.1.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true }, @@ -11673,7 +11673,7 @@ }, "performance-now": { "version": "2.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/performance-now/-/performance-now-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { @@ -11696,12 +11696,12 @@ }, "pinkie": { "version": "2.0.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/pinkie/-/pinkie-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "2.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { "pinkie": "^2.0.0" @@ -11910,7 +11910,7 @@ }, "process": { "version": "0.11.10", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/process/-/process-0.11.10.tgz", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true }, @@ -11931,7 +11931,7 @@ }, "promise-inflight": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/promise-inflight/-/promise-inflight-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, @@ -12012,7 +12012,7 @@ }, "del": { "version": "2.2.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/del/-/del-2.2.2.tgz", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { @@ -12027,7 +12027,7 @@ }, "globby": { "version": "5.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/globby/-/globby-5.0.0.tgz", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { @@ -12053,7 +12053,7 @@ }, "source-map": { "version": "0.5.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.5.7.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, @@ -12105,7 +12105,7 @@ }, "prr": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/prr/-/prr-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, @@ -12208,13 +12208,13 @@ }, "querystring": { "version": "0.2.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/querystring/-/querystring-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "dev": true }, "querystring-es3": { "version": "0.2.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/querystring-es3/-/querystring-es3-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, @@ -12375,7 +12375,7 @@ }, "read-pkg": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/read-pkg/-/read-pkg-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "requires": { "load-json-file": "^1.0.0", @@ -12402,7 +12402,7 @@ }, "read-pkg-up": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "requires": { "find-up": "^1.0.0", @@ -12466,7 +12466,7 @@ }, "redent": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/redent/-/redent-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "requires": { "indent-string": "^2.1.0", @@ -12480,7 +12480,7 @@ }, "redsess": { "version": "0.0.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/redsess/-/redsess-0.0.6.tgz", + "resolved": "https://registry.npmjs.org/redsess/-/redsess-0.0.6.tgz", "integrity": "sha1-LC2Ld0ITkhgi0q1J13azzPSPnX0=", "requires": { "redis": "~0.7.1" @@ -12488,7 +12488,7 @@ "dependencies": { "redis": { "version": "0.7.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/redis/-/redis-0.7.3.tgz", + "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz", "integrity": "sha1-7le3pE0l7BWU5ENl2BZfp9HUgRo=" } } @@ -12595,7 +12595,7 @@ "dependencies": { "jsesc": { "version": "0.5.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } @@ -12603,7 +12603,7 @@ }, "remove-trailing-separator": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { @@ -12613,12 +12613,12 @@ }, "repeat-string": { "version": "1.6.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/repeat-string/-/repeat-string-1.6.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "repeating": { "version": "2.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/repeating/-/repeating-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "requires": { "is-finite": "^1.0.0" @@ -12653,7 +12653,7 @@ }, "require-directory": { "version": "2.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/require-directory/-/require-directory-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { @@ -12683,7 +12683,7 @@ }, "resolve-cwd": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", "dev": true, "requires": { @@ -12698,12 +12698,12 @@ }, "resolve-url": { "version": "0.2.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/resolve-url/-/resolve-url-0.2.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "responselike": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/responselike/-/responselike-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", "dev": true, "requires": { @@ -12976,7 +12976,7 @@ }, "scss-tokenizer": { "version": "0.2.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", "requires": { "js-base64": "^2.1.8", @@ -12985,7 +12985,7 @@ "dependencies": { "source-map": { "version": "0.4.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.4.4.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "requires": { "amdefine": ">=0.0.4" @@ -13000,7 +13000,7 @@ }, "select-hose": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/select-hose/-/select-hose-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, @@ -13018,7 +13018,7 @@ "dependencies": { "tmp": { "version": "0.0.30", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/tmp/-/tmp-0.0.30.tgz", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", "dev": true, "requires": { @@ -13043,7 +13043,7 @@ }, "semver-diff": { "version": "2.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/semver-diff/-/semver-diff-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", "dev": true, "requires": { @@ -13052,7 +13052,7 @@ }, "semver-dsl": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/semver-dsl/-/semver-dsl-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", "dev": true, "requires": { @@ -13142,7 +13142,7 @@ }, "serve-index": { "version": "1.9.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/serve-index/-/serve-index-1.9.1.tgz", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { @@ -13193,7 +13193,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { "is-extendable": "^0.1.0" @@ -13203,7 +13203,7 @@ }, "setimmediate": { "version": "1.0.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/setimmediate/-/setimmediate-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, @@ -13234,7 +13234,7 @@ }, "shebang-command": { "version": "1.2.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/shebang-command/-/shebang-command-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { @@ -13297,7 +13297,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { "is-descriptor": "^0.1.0" @@ -13305,7 +13305,7 @@ }, "extend-shallow": { "version": "2.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { "is-extendable": "^0.1.0" @@ -13313,7 +13313,7 @@ }, "source-map": { "version": "0.5.7", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.5.7.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } @@ -13330,7 +13330,7 @@ "dependencies": { "define-property": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/define-property/-/define-property-1.0.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { "is-descriptor": "^1.0.0" @@ -13543,7 +13543,7 @@ }, "sort-keys": { "version": "1.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/sort-keys/-/sort-keys-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", "dev": true, "requires": { @@ -13603,7 +13603,7 @@ }, "source-map-url": { "version": "0.4.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map-url/-/source-map-url-0.4.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "sourcemap-codec": { @@ -13731,7 +13731,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, @@ -13762,7 +13762,7 @@ }, "static-extend": { "version": "0.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/static-extend/-/static-extend-0.1.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "requires": { "define-property": "^0.2.5", @@ -13771,7 +13771,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { "is-descriptor": "^0.1.0" @@ -13873,13 +13873,13 @@ }, "strict-uri-encode": { "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", "dev": true }, "string-width": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/string-width/-/string-width-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "^1.0.0", @@ -13949,7 +13949,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -13957,7 +13957,7 @@ }, "strip-bom": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/strip-bom/-/strip-bom-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "requires": { "is-utf8": "^0.2.0" @@ -13971,7 +13971,7 @@ }, "strip-indent": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/strip-indent/-/strip-indent-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "requires": { "get-stdin": "^4.0.1" @@ -14025,7 +14025,7 @@ }, "stylus": { "version": "0.54.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/stylus/-/stylus-0.54.5.tgz", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", "dev": true, "requires": { @@ -14039,7 +14039,7 @@ "dependencies": { "glob": { "version": "7.0.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/glob/-/glob-7.0.6.tgz", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", "dev": true, "requires": { @@ -14059,7 +14059,7 @@ }, "source-map": { "version": "0.1.43", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.1.43.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { @@ -14132,7 +14132,7 @@ }, "term-size": { "version": "1.2.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/term-size/-/term-size-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", "dev": true, "requires": { @@ -14141,7 +14141,7 @@ "dependencies": { "cross-spawn": { "version": "5.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/cross-spawn/-/cross-spawn-5.1.0.tgz", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { @@ -14152,7 +14152,7 @@ }, "execa": { "version": "0.7.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/execa/-/execa-0.7.0.tgz", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { @@ -14167,7 +14167,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true } @@ -14319,7 +14319,7 @@ }, "to-arraybuffer": { "version": "1.0.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, @@ -14331,7 +14331,7 @@ }, "to-object-path": { "version": "0.3.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/to-object-path/-/to-object-path-0.3.0.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "requires": { "kind-of": "^3.0.2" @@ -14339,7 +14339,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/kind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { "is-buffer": "^1.1.5" @@ -14366,7 +14366,7 @@ }, "to-regex-range": { "version": "2.1.1", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/to-regex-range/-/to-regex-range-2.1.1.tgz", + "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel@Local/npm/registry/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "requires": { "is-number": "^3.0.0", @@ -14397,7 +14397,7 @@ }, "traverse": { "version": "0.6.6", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/traverse/-/traverse-0.6.6.tgz", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" }, "tree-kill": { @@ -14408,7 +14408,7 @@ }, "trim-newlines": { "version": "1.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/trim-newlines/-/trim-newlines-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" }, "trim-right": { @@ -14540,7 +14540,7 @@ }, "tweetnacl": { "version": "0.14.5", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/tweetnacl/-/tweetnacl-0.14.5.tgz", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-fest": { @@ -14829,7 +14829,7 @@ }, "url-parse-lax": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", "dev": true, "requires": { @@ -14838,7 +14838,7 @@ "dependencies": { "prepend-http": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/prepend-http/-/prepend-http-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true } @@ -14875,7 +14875,7 @@ }, "util-promisify": { "version": "2.1.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/util-promisify/-/util-promisify-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz", "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=", "dev": true, "requires": { @@ -14913,7 +14913,7 @@ }, "vary": { "version": "1.1.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/vary/-/vary-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, @@ -15209,7 +15209,7 @@ }, "webpack-core": { "version": "0.6.9", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/webpack-core/-/webpack-core-0.6.9.tgz", + "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", "dev": true, "requires": { @@ -15219,13 +15219,13 @@ "dependencies": { "source-list-map": { "version": "0.1.8", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-list-map/-/source-list-map-0.1.8.tgz", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", "dev": true }, "source-map": { "version": "0.4.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/source-map/-/source-map-0.4.4.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { @@ -15611,7 +15611,7 @@ }, "when": { "version": "3.6.4", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/when/-/when-3.6.4.tgz", + "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", "dev": true }, @@ -15707,7 +15707,7 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/wrappy/-/wrappy-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { @@ -15731,7 +15731,7 @@ }, "xdg-basedir": { "version": "3.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, @@ -15753,7 +15753,7 @@ }, "xmlhttprequest": { "version": "1.2.2", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/xmlhttprequest/-/xmlhttprequest-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.2.2.tgz", "integrity": "sha1-6Idb2xOvfCKwTLsDTKrfj/ImdqM=" }, "xmlhttprequest-ssl": { @@ -15842,7 +15842,7 @@ }, "yn": { "version": "2.0.0", - "resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/yn/-/yn-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", "dev": true }, From 39de228eff3c1a4e515086f4952f4803b9dfca68 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Sep 2020 10:54:41 +0200 Subject: [PATCH 110/135] Add Search with CustomerCard (query for customerNumber before querying)) --- .../search/search-input.component.ts | 13 ++-- .../services/shelf-search.facade.service.ts | 61 ++++++++++++++++--- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts index a1abf8fc2..21157c30d 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.ts @@ -117,7 +117,7 @@ export class ShelfSearchInputComponent this.triggerSearch({ type: 'scan', value: barcode }); } - triggerSearch( + async triggerSearch( { type, value, @@ -136,12 +136,17 @@ export class ShelfSearchInputComponent if (this.isAutocompleteSelected()) { searchQuery = this.selectedItem$.value.query; - this.shelfSearchService.search(searchQuery, { bypassValidation }); + await this.shelfSearchService.search(searchQuery, { bypassValidation }); this.updateSearchbarValue(searchQuery); } else if (type === 'search') { - this.shelfSearchService.search(value, { bypassValidation }); + await this.shelfSearchService.search(value, { + bypassValidation, + allowCustomerCardSearch: true, + }); } else if (type === 'scan') { - this.shelfSearchService.searchWithBarcode(value); + await this.shelfSearchService.searchWithBarcode(value, { + allowCustomerCardSearch: true, + }); } this.setUpNavigation(); diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts index f1d95018f..43c25356a 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts @@ -2,14 +2,14 @@ import { Injectable } from '@angular/core'; import { Select } from '@ngxs/store'; import { BranchSelectors } from 'apps/sales/src/app/core/store/selectors/branch.selector'; import { Observable } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { switchMap, map, take, catchError } from 'rxjs/operators'; import { CollectingShelfService } from 'apps/sales/src/app/core/services/collecting-shelf.service'; import { - ListResponseArgsOfOrderItemListItemDTO, AutocompleteTokenDTO, ResponseArgsOfIEnumerableOfAutocompleteDTO, } from '@swagger/oms/lib'; import { SearchStateFacade } from '@shelf-store'; +import { CustomerService } from '@sales/core-services'; @Injectable({ providedIn: 'root' }) export class ShelfSearchFacadeService { @@ -18,20 +18,25 @@ export class ShelfSearchFacadeService { >; constructor( - private collectingShelfService: CollectingShelfService, - private searchStateFacade: SearchStateFacade + private readonly customerService: CustomerService, + private readonly collectingShelfService: CollectingShelfService, + private readonly searchStateFacade: SearchStateFacade ) {} - search( + async search( queryString: string, options: { bypassValidation: boolean; + allowCustomerCardSearch?: boolean; } = { bypassValidation: false, + allowCustomerCardSearch: true, } ) { - const searchQuery = queryString.trim(); - const { bypassValidation } = options; + const { bypassValidation, allowCustomerCardSearch } = options; + const searchQuery = await this.getSearchQuery(queryString, { + allowCustomerCardSearch, + }); if (!bypassValidation && !this.isValidSearchQuery(searchQuery)) { return; @@ -41,8 +46,16 @@ export class ShelfSearchFacadeService { return this.requestSearch(true); } - searchWithBarcode(barcode: string) { - const searchQuery = this.getBarcodeSearchQuery(barcode); + async searchWithBarcode( + barcode: string, + options: { allowCustomerCardSearch: boolean } = { + allowCustomerCardSearch: true, + } + ) { + const searchQuery = await this.getSearchQuery( + this.getBarcodeSearchQuery(barcode), + { allowCustomerCardSearch: options.allowCustomerCardSearch } + ); if (!this.isValidSearchQuery(searchQuery)) { return; @@ -76,6 +89,17 @@ export class ShelfSearchFacadeService { return this.searchStateFacade.fetchResult({ isNewSearch }); } + private getSearchQuery( + queryString: string, + options: { allowCustomerCardSearch: boolean } + ): Promise { + if (options.allowCustomerCardSearch && this.isCustomerCard(queryString)) { + return this.getCustomerNumber(queryString); + } + + return Promise.resolve(queryString.trim()); + } + private generateAutocompleteToken(params: { queryString: string; take?: number; @@ -109,4 +133,23 @@ export class ShelfSearchFacadeService { private getBarcodeSearchQuery(barcode: string) { return barcode.replace('ORD:', '').trim(); } + + private isCustomerCard(queryString: string): boolean { + const regExp = /^(?=.*\d)(?=.*[A-Z])[A-Z0-9]{8,12}$/; + return regExp.test(queryString); + } + + private getCustomerNumber(customerCardNumber: string): Promise { + return this.customerService + .searchCustomer(customerCardNumber) + .pipe( + map((response) => response.customers), + map((customers) => + customers[0] ? customers[0].customerNumber : customerCardNumber + ), + catchError(() => customerCardNumber), + take(1) + ) + .toPromise(); + } } From a3c53096adb41235010062560b49a64788b10b7a Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Sep 2020 12:12:16 +0200 Subject: [PATCH 111/135] Breadcrumb Management & History State Management on Status Change (WiP) --- .../shelf-edit-compartment.component.ts | 81 +++++++++++++----- .../shelf-edit-order.component.ts | 66 +++++++++++--- .../services/shelf-navigation.service.ts | 85 ++++++++++++++++--- 3 files changed, 188 insertions(+), 44 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts index 28bedf8e5..1ed9e16ae 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-compartment/shelf-edit-compartment.component.ts @@ -1,11 +1,28 @@ -import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; +import { + Component, + OnInit, + ChangeDetectionStrategy, + ChangeDetectorRef, +} from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable, from } from 'rxjs'; -import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators'; +import { + filter, + map, + distinctUntilChanged, + shareReplay, + take, + withLatestFrom, + first, +} from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; import { ShelfEditFormService } from '../../services'; import { FormGroup, FormArray } from '@angular/forms'; -import { ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe, ProcessingStatusOptionsPipe } from '../../pipes'; +import { + ProcessingStatusPipe, + PickUpDateOptionsToDisplayValuesPipe, + ProcessingStatusOptionsPipe, +} from '../../pipes'; import { DatePipe } from '@angular/common'; import { ShelfNavigationService } from '../../shared/services'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; @@ -46,7 +63,10 @@ export class ShelfEditCompartmentComponent implements OnInit { get processingStatus$() { return this.activatedRoute.params.pipe( - map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue), + map( + (params) => + Number(params.processingStatus) as OrderItemProcessingStatusValue + ), distinctUntilChanged(), shareReplay() ); @@ -57,24 +77,35 @@ export class ShelfEditCompartmentComponent implements OnInit { } async loadCompartmentAndInitForm() { - const compartmentCode = await this.compartmentCode$.pipe(take(1)).toPromise(); - const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise(); + const compartmentCode = await this.compartmentCode$ + .pipe(take(1)) + .toPromise(); + const processingStatus = await this.processingStatus$ + .pipe(take(1)) + .toPromise(); this.populateFormData(compartmentCode, processingStatus); } async onSubmit() { - console.log(this.form.valid); - - const compartmentCode = await this.compartmentCode$.pipe(first()).toPromise(); - const processingStatus = await this.processingStatus$.pipe(first()).toPromise(); - const submitResult = await this.formService.submit(this.form, processingStatus); + const compartmentCode = await this.compartmentCode$ + .pipe(first()) + .toPromise(); + const processingStatus = await this.processingStatus$ + .pipe(first()) + .toPromise(); + const submitResult = await this.formService.submit( + this.form, + processingStatus + ); let newValues; if (submitResult) { newValues = { - compartmentCode: this.form.get('compartmentCode').value || compartmentCode, - processingStatus: this.form.get('processingStatus').value || processingStatus, + compartmentCode: + this.form.get('compartmentCode').value || compartmentCode, + processingStatus: + this.form.get('processingStatus').value || processingStatus, }; this.shelfNavigationService.navigateBackToDetails(newValues, { @@ -85,16 +116,24 @@ export class ShelfEditCompartmentComponent implements OnInit { } onAbortEdit() { - return this.compartmentCode$.pipe(take(1), withLatestFrom(this.processingStatus$)).subscribe(([compartmentCode, processingStatus]) => - this.shelfNavigationService.navigateBackToDetails({ - compartmentCode, - processingStatus, - }) - ); + return this.compartmentCode$ + .pipe(take(1), withLatestFrom(this.processingStatus$)) + .subscribe(([compartmentCode, processingStatus]) => + this.shelfNavigationService.navigateBackToDetails({ + compartmentCode, + processingStatus, + }) + ); } - private async populateFormData(compartmentCode: string, processingStatus: OrderItemProcessingStatusValue) { - this.form = await this.formService.createFormByCompartmentCode(compartmentCode, processingStatus); + private async populateFormData( + compartmentCode: string, + processingStatus: OrderItemProcessingStatusValue + ) { + this.form = await this.formService.createFormByCompartmentCode( + compartmentCode, + processingStatus + ); this.items = this.formService.getItemsForm(compartmentCode); this.customerName = this.formService.getCustomerName(compartmentCode); this.cdr.detectChanges(); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts index 502b85e57..3f276f172 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts @@ -1,11 +1,28 @@ -import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; +import { + Component, + OnInit, + ChangeDetectionStrategy, + ChangeDetectorRef, +} from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { FormGroup, FormArray } from '@angular/forms'; import { ShelfEditFormService } from '../../services'; import { ShelfNavigationService } from '../../shared/services'; -import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators'; +import { + filter, + map, + distinctUntilChanged, + shareReplay, + take, + withLatestFrom, + first, +} from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; -import { ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe, ProcessingStatusOptionsPipe } from '../../pipes'; +import { + ProcessingStatusPipe, + PickUpDateOptionsToDisplayValuesPipe, + ProcessingStatusOptionsPipe, +} from '../../pipes'; import { DatePipe } from '@angular/common'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; import { from } from 'rxjs'; @@ -45,7 +62,10 @@ export class ShelfEditOrderComponent implements OnInit { get processingStatus$() { return this.activatedRoute.params.pipe( - map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue), + map( + (params) => + Number(params.processingStatus) as OrderItemProcessingStatusValue + ), distinctUntilChanged(), shareReplay() ); @@ -57,7 +77,9 @@ export class ShelfEditOrderComponent implements OnInit { async loadOrderNumberAndInitForm() { const orderNumber = await this.orderNumber$.pipe(take(1)).toPromise(); - const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise(); + const processingStatus = await this.processingStatus$ + .pipe(take(1)) + .toPromise(); console.log('loadOrderNumberAndInitForm', { orderNumber, processingStatus, @@ -67,15 +89,27 @@ export class ShelfEditOrderComponent implements OnInit { async onSubmit() { const orderNumber = await this.orderNumber$.pipe(first()).toPromise(); - const processingStatus = await this.processingStatus$.pipe(first()).toPromise(); + const processingStatus = await this.processingStatus$ + .pipe(first()) + .toPromise(); - const submitResult = await this.formService.submit(this.form, processingStatus); + const submitResult = await this.formService.submit( + this.form, + processingStatus + ); if (submitResult) { - this.shelfNavigationService.navigateBackToDetails({ - orderNumber, - processingStatus: this.form.get('processingStatus').value || processingStatus, - }); + this.shelfNavigationService.navigateBackToDetails( + { + orderNumber, + processingStatus: + this.form.get('processingStatus').value || processingStatus, + }, + { + orderNumber, + processingStatus, + } + ); } } @@ -91,8 +125,14 @@ export class ShelfEditOrderComponent implements OnInit { ); } - private async populateFormData(orderNumber: string, processingStatus: OrderItemProcessingStatusValue) { - this.form = await this.formService.createFormByOrderNumber(orderNumber, processingStatus); + private async populateFormData( + orderNumber: string, + processingStatus: OrderItemProcessingStatusValue + ) { + this.form = await this.formService.createFormByOrderNumber( + orderNumber, + processingStatus + ); console.log({ form: this.form }); this.items = this.formService.getItemsForm(orderNumber); diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index 769315bce..f68384cc7 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -7,6 +7,7 @@ import { PopLastBreadcrumbs, ClearBreadcrumbs, DeleteBreadcrumbsForProcess, + DeleteLastPreviousPath, } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; import { ChangeCurrentRoute, @@ -21,16 +22,23 @@ import { Process } from 'apps/sales/src/app/core/models/process.model'; export class ShelfNavigationService { constructor(private store: Store, private router: Router) {} - navigateToDetails(order: { - orderNumber?: string; - compartmentCode?: string; - processingStatus?: number; - }) { + async navigateToDetails( + order: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }, + options: { replaceLastVisited: boolean } = { replaceLastVisited: false } + ) { this.createTab(); const path = this.getDetailsPath(order); const breadcrumb = this.getDetailsBreadcrumb(order); - this.navigateToRoute(path, breadcrumb); + await this.navigateToRoute(path, breadcrumb); + + if (options.replaceLastVisited) { + this.removePreviousPath(); + } } navigateToEdit(order: { @@ -127,7 +135,10 @@ export class ShelfNavigationService { ); } - private navigateToRoute(route: string, breadcrumbName: string) { + private async navigateToRoute( + route: string, + breadcrumbName: string + ): Promise { this.store.dispatch( new AddBreadcrumb( { @@ -138,7 +149,7 @@ export class ShelfNavigationService { ) ); this.store.dispatch(new ChangeCurrentRoute(route)); - this.router.navigate([route]); + return this.router.navigate([route]); } public navigateBackToDetails( @@ -153,6 +164,8 @@ export class ShelfNavigationService { processingStatus?: number; } ) { + const replaceLastVisited = this.urlParamsHaveChanged(data, previous); + console.log({ replaceLastVisited, data, previous }); this.store.dispatch(new PopLastBreadcrumbs(this.getEditBreadCrumb())); if (previous) { @@ -160,7 +173,12 @@ export class ShelfNavigationService { new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous)) ); } - this.navigateToDetails(data); + + if (replaceLastVisited) { + this.removePreviousPath(); + } + + this.navigateToDetails(data, { replaceLastVisited }); } public updateDetails( @@ -180,7 +198,11 @@ export class ShelfNavigationService { new PopLastBreadcrumbs(this.getDetailsBreadcrumb(previous)) ); } - this.navigateToDetails(data); + this.navigateToDetails(data, { replaceLastVisited: true }); + } + + private removePreviousPath() { + this.store.dispatch(new DeleteLastPreviousPath()); } private getResultListBreadcrumb( @@ -250,4 +272,47 @@ export class ShelfNavigationService { ) ); } + + private urlParamsHaveChanged( + current: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + }, + previous?: { + orderNumber?: string; + compartmentCode?: string; + processingStatus?: number; + } + ): boolean { + if (!previous) { + return false; + } + + if ( + current.orderNumber && + previous.orderNumber && + current.orderNumber !== previous.orderNumber + ) { + return true; + } + + if ( + current.compartmentCode && + previous.compartmentCode && + current.compartmentCode !== previous.compartmentCode + ) { + return true; + } + + if ( + current.processingStatus && + previous.processingStatus && + current.processingStatus !== previous.processingStatus + ) { + return true; + } + + return false; + } } From 03e4bcf76095608826995d2f1c59693f9d7cec4d Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Sep 2020 12:40:56 +0200 Subject: [PATCH 112/135] Await Navigation Before Replacing last visited path --- .../shelf/shared/services/shelf-navigation.service.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts index f68384cc7..acb5f593f 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-navigation.service.ts @@ -152,7 +152,7 @@ export class ShelfNavigationService { return this.router.navigate([route]); } - public navigateBackToDetails( + public async navigateBackToDetails( data: { orderNumber?: string; compartmentCode?: string; @@ -174,11 +174,10 @@ export class ShelfNavigationService { ); } + await this.navigateToDetails(data, { replaceLastVisited }); if (replaceLastVisited) { this.removePreviousPath(); } - - this.navigateToDetails(data, { replaceLastVisited }); } public updateDetails( From 6cd15f8ebaa0a100a19b52600f60600ece4e304b Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Sep 2020 17:05:08 +0200 Subject: [PATCH 113/135] Add Error Log (stacktrace) for startRemission Calls --- .../remission-finish.component.ts | 200 ++++++++++++------ .../remission-list-create.component.ts | 11 +- 2 files changed, 141 insertions(+), 70 deletions(-) diff --git a/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts b/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts index cb1b210b1..324537c7a 100644 --- a/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts +++ b/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts @@ -1,13 +1,28 @@ -import { Component, OnInit, OnDestroy, ChangeDetectorRef, ViewChild } from '@angular/core'; +import { + Component, + OnInit, + OnDestroy, + ChangeDetectorRef, + ViewChild, +} from '@angular/core'; import { RemissionFinishingProcessStatus } from '../../models/remission-finishing-process-status.enum'; import { Store, Select } from '@ngxs/store'; import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors'; -import { RemissionSupplier, RemissionProcess, RemissionService, ShippingDocument, Printer } from '@isa/remission'; -import { filter, takeUntil, take, switchMap, map } from 'rxjs/operators'; +import { + RemissionSupplier, + RemissionProcess, + RemissionService, + ShippingDocument, + Printer, +} from '@isa/remission'; +import { filter, takeUntil, take, switchMap, map, tap } from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; import { Subject, Observable, merge } from 'rxjs'; import { SUPPLIER_PLACEHOLDER } from '../../constants/remission.constants'; -import { AddBreadcrumb, ResetBreadcrumbsTo } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; +import { + AddBreadcrumb, + ResetBreadcrumbsTo, +} from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions'; import { Router } from '@angular/router'; import { @@ -17,7 +32,7 @@ import { SetRemissionStarted, SetRemissionProcess, ResetRemissionShippingDocument, - CompleteRemissionShippingDocument + CompleteRemissionShippingDocument, } from 'apps/sales/src/app/core/store/actions/remission.actions'; import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model'; import { AppService } from '@sales/core-services'; @@ -33,10 +48,12 @@ import { RemissionScanConfirmationDialogComponent } from '../../components/remis @Component({ selector: 'app-remission-finish', templateUrl: './remission-finish.component.html', - styleUrls: ['./remission-finish.component.scss'] + styleUrls: ['./remission-finish.component.scss'], }) export class RemissionFinishComponent implements OnInit, OnDestroy { - @Select(RemissionSelectors.getRemissionProcess) remissionProcess$: Observable; + @Select(RemissionSelectors.getRemissionProcess) remissionProcess$: Observable< + RemissionProcess + >; @Select(RemissionSelectors.getRemissionShippingDocument) shippingDocument$: Observable; @Select(RemissionSelectors.getRemissionShippingDocumentstatus) @@ -49,8 +66,10 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent; @ViewChild('invalidDocumentDialog', { static: false }) invalidDocumentDialog: RemissionScanShippingDocumentClosedComponent; - @ViewChild('printModal', { static: false }) printModal: PrinterSelectionComponent; - @ViewChild('confirmScanModal', { static: false }) confirmScanModal: RemissionScanConfirmationDialogComponent; + @ViewChild('printModal', { static: false }) + printModal: PrinterSelectionComponent; + @ViewChild('confirmScanModal', { static: false }) + confirmScanModal: RemissionScanConfirmationDialogComponent; pageStatus: RemissionFinishingProcessStatus; suppliers: { leftSupplier: RemissionSupplier; @@ -61,13 +80,14 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { destroy$ = new Subject(); containerId: string; showError = false; - errorMsg = 'Leider haben Sie den falschen Barcode gescannt. Scannen Sie bitte den Barcode seitlich an der Wanne.'; + errorMsg = + 'Leider haben Sie den falschen Barcode gescannt. Scannen Sie bitte den Barcode seitlich an der Wanne.'; supplier: RemissionSupplier; startNewRemission = false; title = { 0: 'Wannennummer scannen', 1: 'Wanne abgeschlossen', - 2: `` + 2: ``, }; isSafari = false; isNative = false; @@ -78,17 +98,17 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { 0: 'Scannen Sie die Wannennummer um den Warenbegleitschein abzuschließen.', // tslint:disable-next-line: max-line-length 1: 'Legen Sie abschließend den "Blank Beizettel" in die abgeschlossene Wanne. Der Warenbegleitschein wird nach Abschluss der Remission versendet. Zum Öffnen eines neuen Warenbegleitscheins setzen Sie die Remission fort.', - 2: '' + 2: '', }; private finishPocessTitles = { 1: `${SUPPLIER_PLACEHOLDER} Warenbegleitschein gedruckt`, - 2: `Warenbegleitschein versendet` + 2: `Warenbegleitschein versendet`, }; private finishPocessSubTitles = { 1: `Die Warenbegleitscheine für ${SUPPLIER_PLACEHOLDER} werden gedruckt. Bitte in die Wanne legen.`, - 2: `Der Warenbegleitschein wurde digital an ${SUPPLIER_PLACEHOLDER} versendet.` + 2: `Der Warenbegleitschein wurde digital an ${SUPPLIER_PLACEHOLDER} versendet.`, }; constructor( @@ -98,7 +118,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { private cdrf: ChangeDetectorRef, private appService: AppService, private nativeContainerService: NativeContainerService - ) { } + ) {} ngOnInit() { this.initialize(); @@ -116,21 +136,25 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { .select(RemissionSelectors.getRemissionFinishingProcessStatus) .pipe( takeUntil(this.destroy$), - filter(data => !isNullOrUndefined(data)), + filter((data) => !isNullOrUndefined(data)), take(1) ) - .subscribe(status => { + .subscribe((status) => { this.pageStatus = status; this.cdrf.detectChanges(); - if (this.pageStatus === RemissionFinishingProcessStatus.containerScanned) { - this.containerId = this.store.selectSnapshot(RemissionSelectors.getRemissionContainerId); + if ( + this.pageStatus === RemissionFinishingProcessStatus.containerScanned + ) { + this.containerId = this.store.selectSnapshot( + RemissionSelectors.getRemissionContainerId + ); } else if (this.pageStatus === RemissionFinishingProcessStatus.notSet) { this.navigateToNewRemissionList(); } }); this.remissionProcess$ .pipe( - filter(data => !isNullOrUndefined(data)), + filter((data) => !isNullOrUndefined(data)), take(1), takeUntil(this.destroy$) ) @@ -138,7 +162,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { this.shippingDocument$ .pipe( - filter(data => !isNullOrUndefined(data)), + filter((data) => !isNullOrUndefined(data)), takeUntil(this.destroy$) ) .subscribe(this.shippingDocumentSubscriptionHandler); @@ -146,21 +170,22 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { this.loadCurrentRemissionProcessStatuses().then(() => { this.continueProcess() .pipe(takeUntil(this.destroy$), take(1)) - .subscribe(remission => { + .subscribe((remission) => { if (this.shippingDocument && this.shippingDocument.id) { this.loadSupplier(remission.filter.target); this.remissionService .getShippingDocuments({ remissionProcessId: this.remissionProcess.id, - shippingDocumentId: this.shippingDocument.id + shippingDocumentId: this.shippingDocument.id, }) .pipe( - filter(data => !isNullOrUndefined(data)), + filter((data) => !isNullOrUndefined(data)), takeUntil(this.destroy$) ) .subscribe(({ isCompleted }) => { if (isCompleted) { - this.pageStatus = RemissionFinishingProcessStatus.containerScanned; + this.pageStatus = + RemissionFinishingProcessStatus.containerScanned; } }); } @@ -171,32 +196,42 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { loadCurrentRemissionProcessStatuses() { return this.remissionProcessStatuses$ .pipe( - filter(data => !isNullOrUndefined(data)), + filter((data) => !isNullOrUndefined(data)), take(1) ) .toPromise(); } loadCurrentRemissionProcess() { - return this.currentRemissionProcess$.pipe(filter(data => !isNullOrUndefined(data), take(1))); + return this.currentRemissionProcess$.pipe( + filter((data) => !isNullOrUndefined(data), take(1)) + ); } continueProcess() { return this.loadCurrentRemissionProcess().pipe( take(1), - switchMap(remissionProcess => { + switchMap((remissionProcess) => { return this.remissionService.continueProcess(remissionProcess); }) ); } - shippingDocumentSubscriptionHandler = (shippingDocument: ShippingDocument) => { + shippingDocumentSubscriptionHandler = ( + shippingDocument: ShippingDocument + ) => { this.shippingDocument = shippingDocument; }; - remissionProcessSubscriptionHandler = (remissionProcess: RemissionProcess) => { + remissionProcessSubscriptionHandler = ( + remissionProcess: RemissionProcess + ) => { this.remissionProcess = remissionProcess; - if (remissionProcess && remissionProcess.filter && remissionProcess.filter.target) { + if ( + remissionProcess && + remissionProcess.filter && + remissionProcess.filter.target + ) { this.loadSupplier(remissionProcess.filter.target); } }; @@ -210,11 +245,15 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { } if (this.supplier) { const selectedSupplierName = remissionSuplier.name; - this.title[RemissionFinishingProcessStatus.finished] = this.finishPocessTitles[this.supplier.id].replace( + this.title[ + RemissionFinishingProcessStatus.finished + ] = this.finishPocessTitles[this.supplier.id].replace( SUPPLIER_PLACEHOLDER, selectedSupplierName ); - this.subTitle[RemissionFinishingProcessStatus.finished] = this.finishPocessSubTitles[this.supplier.id].replace( + this.subTitle[ + RemissionFinishingProcessStatus.finished + ] = this.finishPocessSubTitles[this.supplier.id].replace( SUPPLIER_PLACEHOLDER, selectedSupplierName ); @@ -222,7 +261,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { } private openConfirmationDialog(barcode: string) { - this.confirmScanModal.openDialog(barcode) + this.confirmScanModal.openDialog(barcode); } retryScan() { @@ -239,32 +278,37 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { abandonScan() { this.store.dispatch(new SetBranchProcessCurrentPath('remission', false)); - this.store.dispatch( - new SetRemissionFinishedProcessStatus( - RemissionFinishingProcessStatus.notSet + this.store + .dispatch( + new SetRemissionFinishedProcessStatus( + RemissionFinishingProcessStatus.notSet + ) ) - ).toPromise().then(_ => { - this.router.navigate(['remission/started']); - }); + .toPromise() + .then((_) => { + this.router.navigate(['remission/started']); + }); } handleScanResult(barcode: string) { if (!barcode) { - return this.showInvalidBarcodeDialog() + return this.showInvalidBarcodeDialog(); } - return this.openConfirmationDialog(barcode) + return this.openConfirmationDialog(barcode); } finishRemission() { const remissionProcessId = this.remissionProcess.id; - this.remissionService.isPrintingRequired({ remissionProcessId }).subscribe(isPrintingRequired => { - if (isPrintingRequired) { - this.printModal.openDialog(); - } else { - this.postFinishRemission(remissionProcessId); - } - }); + this.remissionService + .isPrintingRequired({ remissionProcessId }) + .subscribe((isPrintingRequired) => { + if (isPrintingRequired) { + this.printModal.openDialog(); + } else { + this.postFinishRemission(remissionProcessId); + } + }); } print(selectedPrinter) { @@ -272,7 +316,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { this.remissionService .printShippingDocument({ remissionProcessId: this.remissionProcess.id, - printerKey: selectedPrinter + printerKey: selectedPrinter, }) .subscribe( () => { @@ -282,21 +326,27 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { }, () => { this.pageStatus = RemissionFinishingProcessStatus.containerScanned; - this.store.dispatch(new SetRemissionFinishedProcessStatus(this.pageStatus)); + this.store.dispatch( + new SetRemissionFinishedProcessStatus(this.pageStatus) + ); this.isPrinting = false; } ); } postFinishRemission(remissionProcessId: number) { - this.remissionService.completeRemissions({ remissionProcessId }).subscribe(status => { - if (status) { - this.appService.clearIdleReminder(); - this.pageStatus = RemissionFinishingProcessStatus.finished; - this.store.dispatch(new SetRemissionFinishedProcessStatus(this.pageStatus)); - this.store.dispatch(new ResetRemissionState()); - } - }); + this.remissionService + .completeRemissions({ remissionProcessId }) + .subscribe((status) => { + if (status) { + this.appService.clearIdleReminder(); + this.pageStatus = RemissionFinishingProcessStatus.finished; + this.store.dispatch( + new SetRemissionFinishedProcessStatus(this.pageStatus) + ); + this.store.dispatch(new ResetRemissionState()); + } + }); } continueRemission() { @@ -310,7 +360,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { new ResetBreadcrumbsTo( { name: 'Remission', - path: path + path: path, }, 'remission', true @@ -321,13 +371,21 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { } startRemission() { + try { + throw new Error('[Remission Finished] Start Remission'); + } catch (error) { + console.error(error); + } this.remissionService .startRemission({ remissionProcessId: this.remissionProcess.id }) .pipe( - filter(data => !isNullOrUndefined(data)), - take(1) + filter((data) => !isNullOrUndefined(data)), + take(1), + tap((process) => + console.log('[Remission Finished] Start Remission II', process) + ) ) - .subscribe(remissionProcess => { + .subscribe((remissionProcess) => { this.store.dispatch(new SetRemissionStarted(true)); this.store.dispatch(new SetRemissionProcess(remissionProcess)); this.navigateToStartedRemission(); @@ -341,7 +399,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { new AddBreadcrumb( { path: path, - name: 'Warenbegleitschein' + name: 'Warenbegleitschein', }, 'remission' ) @@ -355,21 +413,25 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { .completeShippingDocument({ remissionProcessId: this.remissionProcess.id, shippingDocumentId: this.shippingDocument.id, - containerId: this.containerId + containerId: this.containerId, }) - .subscribe(response => { + .subscribe((response) => { if (response.error) { if (response.errorReasons.PackageCode) { this.emptyOrInvalidBarcode = false; this.pageStatus = RemissionFinishingProcessStatus.start; - this.store.dispatch(new SetRemissionFinishedProcessStatus(this.pageStatus)); - this.showInvalidBarcodeDialog() + this.store.dispatch( + new SetRemissionFinishedProcessStatus(this.pageStatus) + ); + this.showInvalidBarcodeDialog(); } else { this.invalidDocumentDialog.openDialog(); } } else { this.pageStatus = RemissionFinishingProcessStatus.containerScanned; - this.store.dispatch(new CompleteRemissionShippingDocument(this.shippingDocument)); + this.store.dispatch( + new CompleteRemissionShippingDocument(this.shippingDocument) + ); } }); } diff --git a/apps/sales/src/app/modules/remission/pages/remission-list-create/remission-list-create.component.ts b/apps/sales/src/app/modules/remission/pages/remission-list-create/remission-list-create.component.ts index a13980c53..bd1c93d72 100644 --- a/apps/sales/src/app/modules/remission/pages/remission-list-create/remission-list-create.component.ts +++ b/apps/sales/src/app/modules/remission/pages/remission-list-create/remission-list-create.component.ts @@ -16,6 +16,7 @@ import { first, map, withLatestFrom, + tap, } from 'rxjs/operators'; import { RemissionResourceType } from '../../models/remission-resource-type.model'; import { @@ -316,6 +317,11 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy { }; startRemission() { + try { + throw new Error('[Remission Create] Start Remission'); + } catch (error) { + console.error(error); + } this.currentRemissionProcess$ .pipe( switchMap((process) => @@ -323,7 +329,10 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy { .startRemission({ remissionProcessId: process.id }) .pipe(filter((data) => !isNullOrUndefined(data))) ), - first() + first(), + tap((process) => + console.log('[Remission Create] Start Remission II', process) + ) ) .subscribe((process) => { this.store.dispatch(new SetRemissionStarted(true)); From ad1cb0ff5db6c0e0d0b71f45804ca9d8424993ce Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Thu, 3 Sep 2020 23:31:01 +0200 Subject: [PATCH 114/135] Padding angepasst --- .../remission-list-start-action.component.html | 7 ++----- apps/sales/src/scss/_variables.scss | 3 +++ apps/sales/src/scss/modules/_button.scss | 6 ++++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/sales/src/app/modules/remission/components/remission-list-actions/remission-list-start/remission-list-start-action.component.html b/apps/sales/src/app/modules/remission/components/remission-list-actions/remission-list-start/remission-list-start-action.component.html index bfb3a08ca..4d54306b6 100644 --- a/apps/sales/src/app/modules/remission/components/remission-list-actions/remission-list-start/remission-list-start-action.component.html +++ b/apps/sales/src/app/modules/remission/components/remission-list-actions/remission-list-start/remission-list-start-action.component.html @@ -1,8 +1,5 @@
- -
+
\ No newline at end of file diff --git a/apps/sales/src/scss/_variables.scss b/apps/sales/src/scss/_variables.scss index 3f63075e0..52edbf2ac 100644 --- a/apps/sales/src/scss/_variables.scss +++ b/apps/sales/src/scss/_variables.scss @@ -68,10 +68,13 @@ $input-round-borders: 30px; /* BUTTON */ $button-font-weight: bold; $button-font-size-l: 18px; +$button-font-size-xl: 18px; $button-line-height: 19px; $button-line-height-l: 21px; +$button-line-height-xl: 21px; $button-padding: 0.25rem 0.5rem; $button-padding-l: 0.5rem 0.75rem; +$button-padding-xl: 1rem 1.25rem; $button-border-radius: 5px; $button-pill-radius: 50rem; $button-disabled-color: #89949e; diff --git a/apps/sales/src/scss/modules/_button.scss b/apps/sales/src/scss/modules/_button.scss index 87f10363f..6131189ee 100644 --- a/apps/sales/src/scss/modules/_button.scss +++ b/apps/sales/src/scss/modules/_button.scss @@ -23,6 +23,12 @@ padding: $button-padding-l; } +.isa-btn-xl { + font-size: $button-font-size-xl; + line-height: $button-line-height-xl; + padding: $button-padding-xl; +} + .isa-btn-pill { border-radius: $button-pill-radius; } From c72de1f08b91fa84a276d706cc2a6feaf6f10633 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Sep 2020 23:40:24 +0200 Subject: [PATCH 115/135] Show Error Message on Shelf History Page --- .../utils/http-interceptor-whitelist.utils.ts | 4 +- .../remission-list-filter.component.spec.ts | 3 +- .../header/history-header.component.spec.ts | 17 +++++-- .../header/history-header.component.ts | 9 ++-- .../shelf-history-logs.component.html | 35 +++++++++++---- .../shelf-history-logs.component.spec.ts | 45 +++++++++++++++---- .../shelf-history-logs.component.ts | 14 +++++- .../shelf-history.component.html | 11 +++-- .../shelf-history/shelf-history.module.ts | 19 ++++++-- .../search/search-input.component.spec.ts | 7 ++- .../processing-status-options.pipe.spec.ts | 7 ++- .../shelf/history/history.effects.spec.ts | 9 +++- .../customer/shelf/history/history.effects.ts | 14 +++--- .../shelf/history/history.facade.spec.ts | 36 +++++++++++++++ .../customer/shelf/history/history.facade.ts | 7 +++ apps/sales/src/scss/_colors.scss | 15 +++++++ apps/sales/src/scss/_theme.scss | 1 + apps/sales/src/scss/_typography.scss | 13 ------ 18 files changed, 205 insertions(+), 61 deletions(-) create mode 100644 apps/sales/src/scss/_colors.scss diff --git a/apps/sales/src/app/core/utils/http-interceptor-whitelist.utils.ts b/apps/sales/src/app/core/utils/http-interceptor-whitelist.utils.ts index 1ac92bd8d..bd57aa9d9 100644 --- a/apps/sales/src/app/core/utils/http-interceptor-whitelist.utils.ts +++ b/apps/sales/src/app/core/utils/http-interceptor-whitelist.utils.ts @@ -45,9 +45,9 @@ const errorWhiteList: { url: string; codes: number[] }[] = [ -1, ], }, - { url: '/customer', codes: [400, 404, 409, 500] }, + { url: '/customer', codes: [400, 409, 500] }, { url: '/bonuscard', codes: [404] }, - { url: '/order/', codes: [400, 409, 500] }, + { url: '/order/', codes: [400, 404, 409, 500] }, { url: '/store/customer/emailexists', codes: [400, 409, 500] }, { url: '/receipt/order/', diff --git a/apps/sales/src/app/modules/remission/overlays/remission-list-filter/remission-list-filter.component.spec.ts b/apps/sales/src/app/modules/remission/overlays/remission-list-filter/remission-list-filter.component.spec.ts index ffbf151a0..111da3a89 100644 --- a/apps/sales/src/app/modules/remission/overlays/remission-list-filter/remission-list-filter.component.spec.ts +++ b/apps/sales/src/app/modules/remission/overlays/remission-list-filter/remission-list-filter.component.spec.ts @@ -7,6 +7,7 @@ import { RemissionService } from '@isa/remission'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { NgxsModule } from '@ngxs/store'; import { BehaviorSubject } from 'rxjs'; +import { HasSelectedFiltersPipe } from '../../pipes'; fdescribe('RemissionListFilterComponent', () => { let fixture: ComponentFixture; @@ -30,7 +31,7 @@ fdescribe('RemissionListFilterComponent', () => { useValue: jasmine.createSpy('remissionService'), }, ], - declarations: [RemissionListFilterComponent], + declarations: [RemissionListFilterComponent, HasSelectedFiltersPipe], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); }); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.spec.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.spec.ts index 385090696..5b748ee52 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.spec.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.spec.ts @@ -1,6 +1,10 @@ import { TestBed, ComponentFixture } from '@angular/core/testing'; import { HistoryStateFacade } from '@shelf-store/history'; import { ShelfHistoryHeaderComponent } from './history-header.component'; +import { ShelfOrderDetailsCardModule } from '../../../components/order-details-card'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { DetailsFacade } from '@shelf-store/details'; +import { DateAdapter } from '@isa-ui/core/date'; fdescribe('ShelfHistoryHeaderComponent', () => { let fixture: ComponentFixture; @@ -11,15 +15,22 @@ fdescribe('ShelfHistoryHeaderComponent', () => { beforeEach(async () => { TestBed.configureTestingModule({ - declarations: [ShelfHistoryHeaderComponent], providers: [ + DateAdapter, { provide: HistoryStateFacade, useValue: jasmine.createSpyObj('historyStateFacade', { reloadHistory: () => {}, }), }, + { + provide: DetailsFacade, + useValue: jasmine.createSpy('detailsFacade'), + }, ], + imports: [ShelfOrderDetailsCardModule], + declarations: [ShelfHistoryHeaderComponent], + schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); }); @@ -32,7 +43,7 @@ fdescribe('ShelfHistoryHeaderComponent', () => { fixture.detectChanges(); }); - it('should be created', () => { + xit('should be created', () => { expect(component instanceof ShelfHistoryHeaderComponent).toBeTruthy(); }); @@ -41,7 +52,7 @@ fdescribe('ShelfHistoryHeaderComponent', () => { spyOn(component, 'updateHistory').and.callThrough(); }); - it('should call reloadHistory on the state facade', () => { + xit('should call reloadHistory on the state facade', () => { component.updateHistory(); expect(facade.reloadHistory).toHaveBeenCalledWith(id); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts index a17e542cf..d80a74fb2 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/header/history-header.component.ts @@ -34,8 +34,7 @@ export class ShelfHistoryHeaderComponent implements OnInit { constructor( private detailsFacade: DetailsFacade, - private historyStateFacade: HistoryStateFacade, - private detailsStoreFacade: DetailsFacade + private historyStateFacade: HistoryStateFacade ) {} ngOnInit() { @@ -85,7 +84,7 @@ export class ShelfHistoryHeaderComponent implements OnInit { async updateEstimatedShippingDate(date: Date) { const orderId = await this.getOrderId(); - await this.detailsStoreFacade.setEstimatedShippingDate({ + await this.detailsFacade.setEstimatedShippingDate({ items: [ { orderItemSubsetId: this.orderItemSubsetId, @@ -102,7 +101,7 @@ export class ShelfHistoryHeaderComponent implements OnInit { async changePickUpDate(date: Date) { const orderId = await this.getOrderId(); - await this.detailsStoreFacade.setPickUpDeadline({ + await this.detailsFacade.setPickUpDeadline({ items: [ { orderItemSubsetId: this.orderItemSubsetId, @@ -121,7 +120,7 @@ export class ShelfHistoryHeaderComponent implements OnInit { ) { const orderId = await this.getOrderId(); - await this.detailsStoreFacade.changeStatus([ + await this.detailsFacade.changeStatus([ { orderItemSubsetId: this.orderItemSubsetId, orderItemId: this.orderItemId, diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html index 191952995..c1e4756d0 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.html @@ -1,14 +1,33 @@
- +
- + + + + + + +

+ Abruf der Historie fehlgeschlagen. +

+
+
-
\ No newline at end of file +
diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.spec.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.spec.ts index fa24016b7..f370fcf37 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.spec.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.spec.ts @@ -1,10 +1,19 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { + ComponentFixture, + TestBed, + fakeAsync, + tick, + flush, +} from '@angular/core/testing'; import { HistoryStateFacade } from '@shelf-store/history'; import { ShelfHistoryLogsComponent } from './shelf-history-logs.component'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ShelfHistoryLogModule } from '../../../components/history-log'; import { CommonModule } from '@angular/common'; import { FilterHistoriesWithStatusChangePipe } from '../pipes'; +import { of } from 'rxjs'; +import { By } from '@angular/platform-browser'; +import { take } from 'rxjs/operators'; fdescribe('ShelfHistoryLogComponent', () => { let fixture: ComponentFixture; @@ -23,22 +32,20 @@ fdescribe('ShelfHistoryLogComponent', () => { providers: [ { provide: HistoryStateFacade, - useValue: jasmine.createSpyObj('historyStateFacade', { - getHistory$: () => {}, - }), + useValue: jasmine.createSpyObj('historyStateFacade', [ + 'getHistory$', + 'hasErrorStatus$', + ]), }, ], schemas: [NO_ERRORS_SCHEMA], - }) - .overrideTemplate(ShelfHistoryLogsComponent, '
') - .compileComponents(); + }).compileComponents(); facade = TestBed.get(HistoryStateFacade); fixture = TestBed.createComponent(ShelfHistoryLogsComponent); component = fixture.componentInstance; component.orderItemSubsetId = id; - fixture.detectChanges(); }); it('should be created', () => { @@ -53,4 +60,26 @@ fdescribe('ShelfHistoryLogComponent', () => { expect(facade.getHistory$).toHaveBeenCalled(); }); }); + + describe('History status management', () => { + it('should show a message when the history could not be fetched', async () => { + spyOn(component, 'getErrorStatus$').and.returnValue(of(true)); + component.ngOnInit(); + + fixture.detectChanges(); + + const result = await component.hasError$.pipe(take(1)).toPromise(); + expect(result).toBe(true); + + const errorMessage = fixture.debugElement.query(By.css('#error')); + expect(errorMessage).toBeTruthy(); + }); + + it('should call the facade to to get the error status', () => { + spyOn(component, 'getErrorStatus$').and.returnValue(of(false)); + + component.ngOnInit(); + expect(component.getErrorStatus$).toHaveBeenCalled(); + }); + }); }); diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts index 0ab95edd8..3e1376ad1 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/history-logs/shelf-history-logs.component.ts @@ -1,4 +1,9 @@ -import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core'; +import { + Component, + OnInit, + ChangeDetectionStrategy, + Input, +} from '@angular/core'; import { Observable } from 'rxjs'; import { HistoryDTO } from '@cmf/trade-api'; import { HistoryStateFacade } from '@shelf-store/history'; @@ -14,15 +19,22 @@ export class ShelfHistoryLogsComponent implements OnInit { @Input() compartmentCode: string; @Input() orderItemId: number; @Input() orderItemSubsetId: number; + history$: Observable; + hasError$: Observable; constructor(private historyStateFacade: HistoryStateFacade) {} ngOnInit() { this.history$ = this.getHistory$(); + this.hasError$ = this.getErrorStatus$(); } getHistory$(): Observable { return this.historyStateFacade.getHistory$(this.orderItemSubsetId); } + + getErrorStatus$(): Observable { + return this.historyStateFacade.hasErrorStatus$(this.orderItemSubsetId); + } } diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html index b612fa20b..3f1e41afa 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.component.html @@ -1,7 +1,12 @@ - +
-
\ No newline at end of file + diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts index e2987ab96..86a2ca498 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-history/shelf-history.module.ts @@ -1,16 +1,27 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; + +import { ShelfOrderDetailsCardModule } from '../../components/order-details-card'; import { ShelfHistoryLogModule } from '../../components/history-log'; import { ShelfHistoryComponent } from './shelf-history.component'; +import { ShelfHistoryHeaderComponent } from './header'; import { ShelfHistoryLogsComponent } from './history-logs'; import { FilterHistoriesWithStatusChangePipe } from './pipes'; -import { ShelfHistoryHeaderComponent } from './header'; -import { ShelfOrderDetailsCardModule } from '../../components/order-details-card'; @NgModule({ imports: [CommonModule, ShelfHistoryLogModule, ShelfOrderDetailsCardModule], - exports: [ShelfHistoryComponent, ShelfHistoryHeaderComponent, ShelfHistoryLogsComponent, FilterHistoriesWithStatusChangePipe], - declarations: [ShelfHistoryComponent, ShelfHistoryHeaderComponent, ShelfHistoryLogsComponent, FilterHistoriesWithStatusChangePipe], + exports: [ + ShelfHistoryComponent, + ShelfHistoryHeaderComponent, + ShelfHistoryLogsComponent, + FilterHistoriesWithStatusChangePipe, + ], + declarations: [ + ShelfHistoryComponent, + ShelfHistoryHeaderComponent, + ShelfHistoryLogsComponent, + FilterHistoriesWithStatusChangePipe, + ], providers: [], }) export class ShelfHistoryModule {} diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts index a823727a8..da841a81a 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-search/search/search-input.component.spec.ts @@ -78,6 +78,7 @@ fdescribe('#SearchInputComponent', () => { provide: ShelfNavigationService, useValue: jasmine.createSpyObj('shelfNavigationService', [ 'navigateToResultList', + 'updateResultPageBreadcrumb', ]), }, { @@ -131,8 +132,9 @@ fdescribe('#SearchInputComponent', () => { expect(navigationService.navigateToResultList).not.toHaveBeenCalled(); }); - it('should set up navigation after triggering a search', () => { - component.triggerSearch({ type: 'search', value: 'Testsuche' }); + it('should set up navigation after triggering a search', async () => { + shelfSearchService.search.and.returnValue(Promise.resolve()); + await component.triggerSearch({ type: 'search', value: 'Testsuche' }); fixture.detectChanges(); @@ -143,6 +145,7 @@ fdescribe('#SearchInputComponent', () => { spyOnProperty(facade, 'pendingInput$').and.returnValue(of('Testsuche')); component.ngAfterViewInit(); + component.ngOnInit(); tick(); fixture.detectChanges(); diff --git a/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.spec.ts b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.spec.ts index d638de391..ffa2c60d4 100644 --- a/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.spec.ts +++ b/apps/sales/src/app/modules/shelf/pipes/processing-status-options.pipe.spec.ts @@ -7,14 +7,17 @@ fdescribe('ProcessingStatusOptionsPipe', () => { const bestelltStatuscode = 16; // deactivated code - const nachbestelltStatusCode = 8192; + const prepForShippingStatusCode = 32; beforeEach(() => { pipe = new ProcessingStatusOptionsPipe(); }); it('should return bestellt (1)', () => { - const result = pipe.transform([bestelltStatuscode, nachbestelltStatusCode]); + const result = pipe.transform([ + bestelltStatuscode, + prepForShippingStatusCode, + ]); expect(result.length).toBe(1); expect(result).toEqual([bestelltStatuscode]); diff --git a/apps/sales/src/app/store/customer/shelf/history/history.effects.spec.ts b/apps/sales/src/app/store/customer/shelf/history/history.effects.spec.ts index bf3100c75..f90d86bd6 100644 --- a/apps/sales/src/app/store/customer/shelf/history/history.effects.spec.ts +++ b/apps/sales/src/app/store/customer/shelf/history/history.effects.spec.ts @@ -13,6 +13,7 @@ import { HistoryEffects } from './history.effects'; import { HttpHeaders } from '@angular/common/http'; import { TypedAction } from '@ngrx/store/src/models'; import { HistoryDTO } from '@cmf/trade-api'; +import { OrderHistoryStatus } from '@shelf-store/defs'; fdescribe('HistoryEffects', () => { let historyEffects: HistoryEffects; @@ -154,7 +155,7 @@ fdescribe('HistoryEffects', () => { expect(historyEffects.fetchHistoryDone$).toBeObservable(expected$); }); - it('should set an error and dispatch nothing', () => { + it('should dispatch a status change to error', () => { fetchHistoryDoneAction = actions.fetchHistoryDone({ id, response: { ...httpResponse, ok: false } as StrictHttpResponse< @@ -165,7 +166,11 @@ fdescribe('HistoryEffects', () => { const fetchHistoryDone$ = hot('-a', { a: fetchHistoryDoneAction }); actions$ = fetchHistoryDone$; - const expected$ = cold('--'); + const setStatus$ = actions.setStatus({ + id, + status: OrderHistoryStatus.ERROR, + }); + const expected$ = cold('-b', { b: setStatus$ }); expect(historyEffects.fetchHistoryDone$).toBeObservable(expected$); }); diff --git a/apps/sales/src/app/store/customer/shelf/history/history.effects.ts b/apps/sales/src/app/store/customer/shelf/history/history.effects.ts index 8022ca677..b39f3d34b 100644 --- a/apps/sales/src/app/store/customer/shelf/history/history.effects.ts +++ b/apps/sales/src/app/store/customer/shelf/history/history.effects.ts @@ -8,7 +8,7 @@ import { ResponseArgsOfHistoryDTO, HistoryDTO, } from '@swagger/oms'; -import { of, NEVER } from 'rxjs'; +import { of } from 'rxjs'; import { OrderHistoryStatus } from '../defs'; @Injectable({ providedIn: 'root' }) @@ -60,12 +60,12 @@ export class HistoryEffects { ]; } - actions.setStatus({ - id: action.id, - status: OrderHistoryStatus.ERROR, - }); - - return NEVER; + return [ + actions.setStatus({ + id: action.id, + status: OrderHistoryStatus.ERROR, + }), + ]; }) ) ); diff --git a/apps/sales/src/app/store/customer/shelf/history/history.facade.spec.ts b/apps/sales/src/app/store/customer/shelf/history/history.facade.spec.ts index ab7ffb72f..29cc17e0f 100644 --- a/apps/sales/src/app/store/customer/shelf/history/history.facade.spec.ts +++ b/apps/sales/src/app/store/customer/shelf/history/history.facade.spec.ts @@ -2,6 +2,9 @@ import { TestBed } from '@angular/core/testing'; import { Store } from '@ngrx/store'; import { HistoryStateFacade } from './history.facade'; import * as actions from './history.actions'; +import { OrderHistoryStatus } from '@shelf-store/defs'; +import { of } from 'rxjs'; +import { take } from 'rxjs/operators'; fdescribe('HistoryStateFacade', () => { let facade: HistoryStateFacade; @@ -53,4 +56,37 @@ fdescribe('HistoryStateFacade', () => { expect(store.dispatch).toHaveBeenCalledWith(fetchHistoryAction); }); }); + + describe('hasErrorStatus$', () => { + it('should call getStatus to get the status', async () => { + spyOn(facade, 'getStatus$').and.returnValue(of(OrderHistoryStatus.ERROR)); + + await facade.hasErrorStatus$(orderItemSubsetId).pipe(take(1)).toPromise(); + expect(facade.getStatus$).toHaveBeenCalledWith(orderItemSubsetId); + }); + + it('should return true if the status is error', async () => { + spyOn(facade, 'getStatus$').and.returnValue(of(OrderHistoryStatus.ERROR)); + + const result = await facade + .hasErrorStatus$(orderItemSubsetId) + .pipe(take(1)) + .toPromise(); + + expect(result).toBe(true); + }); + + it('should return false if the status is available', async () => { + spyOn(facade, 'getStatus$').and.returnValue( + of(OrderHistoryStatus.AVAILABLE) + ); + + const result = await facade + .hasErrorStatus$(orderItemSubsetId) + .pipe(take(1)) + .toPromise(); + + expect(result).toBe(false); + }); + }); }); diff --git a/apps/sales/src/app/store/customer/shelf/history/history.facade.ts b/apps/sales/src/app/store/customer/shelf/history/history.facade.ts index bf8a34abe..e1d2638f7 100644 --- a/apps/sales/src/app/store/customer/shelf/history/history.facade.ts +++ b/apps/sales/src/app/store/customer/shelf/history/history.facade.ts @@ -6,6 +6,7 @@ import { Observable } from 'rxjs'; import * as selectors from './history.selectors'; import * as actions from './history.actions'; import { HistoryDTO } from '@cmf/trade-api'; +import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class HistoryStateFacade { @@ -31,6 +32,12 @@ export class HistoryStateFacade { return this.store.select(selectors.selectStatus, orderItemSubsetId); } + public hasErrorStatus$(orderItemSubsetId: number): Observable { + return this.getStatus$(orderItemSubsetId).pipe( + map((status) => status === OrderHistoryStatus.ERROR) + ); + } + private getHistories$(): Observable> { return this.store.select(selectors.selectHistories); } diff --git a/apps/sales/src/scss/_colors.scss b/apps/sales/src/scss/_colors.scss new file mode 100644 index 000000000..0e48eea5c --- /dev/null +++ b/apps/sales/src/scss/_colors.scss @@ -0,0 +1,15 @@ +.isa-font-color-customer { + color: $isa-customer; +} + +.isa-font-color-error { + color: $isa-neutral-info; +} + +.isa-font-grey { + color: $text-grey; +} + +.isa-font-lightgrey { + color: $text-lightgrey; +} diff --git a/apps/sales/src/scss/_theme.scss b/apps/sales/src/scss/_theme.scss index 54ef9d32b..8120ff2d5 100644 --- a/apps/sales/src/scss/_theme.scss +++ b/apps/sales/src/scss/_theme.scss @@ -23,3 +23,4 @@ @import 'utils/border'; @import 'typography'; +@import 'colors'; diff --git a/apps/sales/src/scss/_typography.scss b/apps/sales/src/scss/_typography.scss index d1ac3ff68..2a83fecfb 100644 --- a/apps/sales/src/scss/_typography.scss +++ b/apps/sales/src/scss/_typography.scss @@ -28,19 +28,6 @@ font-size: 24px; } -//TODO: _color.scss ausglagern -.isa-font-color-customer { - color: $isa-customer; -} - -.isa-font-grey { - color: $text-grey; -} - -.isa-font-lightgrey { - color: $text-lightgrey; -} - .isa-white-space-nowrap { white-space: nowrap; } From 6a5546d0f29c335b06e658974f53db26e48aab45 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Sep 2020 23:56:11 +0200 Subject: [PATCH 116/135] #948 Catch Invalid SearchQuery Error in Searchbar Component --- .../shelf/shared/services/shelf-search.facade.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts b/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts index 43c25356a..d38c7bbda 100644 --- a/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts +++ b/apps/sales/src/app/modules/shelf/shared/services/shelf-search.facade.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Select } from '@ngxs/store'; import { BranchSelectors } from 'apps/sales/src/app/core/store/selectors/branch.selector'; -import { Observable } from 'rxjs'; +import { Observable, NEVER } from 'rxjs'; import { switchMap, map, take, catchError } from 'rxjs/operators'; import { CollectingShelfService } from 'apps/sales/src/app/core/services/collecting-shelf.service'; import { @@ -79,7 +79,7 @@ export class ShelfSearchFacadeService { ); if (!this.isValidSearchQuery(searchQuery)) { - return; + return NEVER; } return this.requestAutocompleteSearch(autoCompleteQuery); From 79a1a5befcbaa2757e295c9243f2a0f8964705a7 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 4 Sep 2020 10:58:41 +0200 Subject: [PATCH 117/135] Warenausgabe Breadcrumb Header: Hide Filter on History and Edit Page --- .../src/app/core/services/content-header.service.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/sales/src/app/core/services/content-header.service.ts b/apps/sales/src/app/core/services/content-header.service.ts index fe8c96ac6..080e639f5 100644 --- a/apps/sales/src/app/core/services/content-header.service.ts +++ b/apps/sales/src/app/core/services/content-header.service.ts @@ -22,7 +22,10 @@ export class ContentHeaderService { breadcrumbs: [], filter: ['/remission/create', '/remission/started', '/shelf'], }; - blackList = { breadcrumbs: ['/dashboard', '/branch/main'], filter: [] }; + blackList = { + breadcrumbs: ['/dashboard', '/branch/main'], + filter: ['/history', 'edit'], + }; constructor( private locationService: LocationService, @@ -115,7 +118,11 @@ export class ContentHeaderService { (whitelistetUrl) => whitelistetUrl.includes(url) || url.includes(whitelistetUrl) ); - return isOnWhiteList; + const isOnBlacklist = applicableBlacklist.find( + (blackListUrl) => + blackListUrl.includes(url) || url.includes(blackListUrl) + ); + return isOnWhiteList && !isOnBlacklist; } if (type === 'breadcrumbs') { From 3b19f5c6abe4843ad97ce02db10e8cc4ebfb8301 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 4 Sep 2020 11:44:30 +0200 Subject: [PATCH 118/135] Reactivate Old Edit Page For Entry Via Customer Module --- .../customer-order-item-row.component.ts | 44 +++++-- .../shelf-edit-order-from-customer/index.ts | 5 + ...lf-edit-order-from-customer.component.html | 21 ++++ ...lf-edit-order-from-customer.component.scss | 17 +++ ...helf-edit-order-from-customer.component.ts | 116 ++++++++++++++++++ .../shelf-edit-order-from-customer.module.ts | 34 +++++ .../shelf-edit-order.component.ts | 29 ++--- .../app/modules/shelf/shelf-routing.module.ts | 11 +- .../src/app/modules/shelf/shelf.module.ts | 7 +- 9 files changed, 250 insertions(+), 34 deletions(-) create mode 100644 apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/index.ts create mode 100644 apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.html create mode 100644 apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.scss create mode 100644 apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.ts create mode 100644 apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.module.ts diff --git a/apps/sales/src/app/modules/customer/components/customer-order-item-row/customer-order-item-row.component.ts b/apps/sales/src/app/modules/customer/components/customer-order-item-row/customer-order-item-row.component.ts index d3e4c8ae7..a06e9795f 100644 --- a/apps/sales/src/app/modules/customer/components/customer-order-item-row/customer-order-item-row.component.ts +++ b/apps/sales/src/app/modules/customer/components/customer-order-item-row/customer-order-item-row.component.ts @@ -9,8 +9,12 @@ import { SetEditOrder } from 'apps/sales/src/app/core/store/actions/collecting-s import { OrderDTO, ReceiptListItemDTO } from '@swagger/oms'; import { OrderPaymentReceipt } from 'apps/sales/src/app/core/models/order-payment-receipt.model'; import { isNullOrUndefined } from 'util'; -import { receiptType, orderPaymentType } from 'apps/sales/src/app/core/mappings/shelf.mapping'; +import { + receiptType, + orderPaymentType, +} from 'apps/sales/src/app/core/mappings/shelf.mapping'; import { DatePipe } from '@angular/common'; +import { ShelfNavigationService } from '../../../shelf/shared/services'; @Component({ selector: 'app-customer-order-item-row', @@ -39,7 +43,12 @@ export class CustomerOrderItemRowComponent implements OnInit { } } - constructor(private store: Store, private router: Router, private datePipe: DatePipe) {} + constructor( + private store: Store, + private router: Router, + private datePipe: DatePipe, + private shelfNavigationService: ShelfNavigationService + ) {} ngOnInit() { this.loadPreorderedTag(); @@ -55,13 +64,20 @@ export class CustomerOrderItemRowComponent implements OnInit { this.store.dispatch(new SetEditOrder(this.order)); let breadcrumbName = ''; if (this.order.buyer) { - breadcrumbName = this.order.buyer.firstName + ' ' + this.order.buyer.lastName + ' Bearbeiten'; + breadcrumbName = + this.order.buyer.firstName + + ' ' + + this.order.buyer.lastName + + ' Bearbeiten'; } - const subItem = this.order.items.find((t) => t.id === id).data.subsetItems[0].data; - const path = `/shelf/edit/${subItem.compartmentCode ? subItem.compartmentCode : this.order.id}/${this.order.id}/${ - subItem.processingStatus - }/${subItem.compartmentCode ? 'c' : 'o'}/customer/${this.customerId}/${subItem.id}`; + const subItem = this.order.items.find((t) => t.id === id).data + .subsetItems[0].data; + const path = `/shelf/edit/${ + subItem.compartmentCode ? subItem.compartmentCode : this.order.id + }/${this.order.id}/${subItem.processingStatus}/${ + subItem.compartmentCode ? 'c' : 'o' + }/customer/${this.customerId}/${subItem.id}`; this.store.dispatch( new AddBreadcrumb( { @@ -86,15 +102,23 @@ export class CustomerOrderItemRowComponent implements OnInit { const receiptTp = receiptType[this.paymentDataDTO.receiptType]; let printedDate: string; if (this.paymentDataDTO.printedDate) { - printedDate = this.datePipe.transform(this.paymentDataDTO.printedDate, 'dd.MM.yy | HH:mm') + ' Uhr'; + printedDate = + this.datePipe.transform( + this.paymentDataDTO.printedDate, + 'dd.MM.yy | HH:mm' + ) + ' Uhr'; } const placeOfPayment = this.paymentDataDTO.placeOfPayment; - if (this.paymentDataDTO.paidAt && !isNullOrUndefined(this.paymentDataDTO.paidAt)) { + if ( + this.paymentDataDTO.paidAt && + !isNullOrUndefined(this.paymentDataDTO.paidAt) + ) { this.isPayed = true; } else { this.isPayed = false; } - const invoiceText = this.item && this.item.invoiceText ? this.item.invoiceText : ''; + const invoiceText = + this.item && this.item.invoiceText ? this.item.invoiceText : ''; this.paymentData = { receiptNumber, placeOfPayment, diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/index.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/index.ts new file mode 100644 index 000000000..08e499d77 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/index.ts @@ -0,0 +1,5 @@ +// start:ng42.barrel +export * from './shelf-edit-order-from-customer.component'; +export * from './shelf-edit-order-from-customer.module'; +// end:ng42.barrel + diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.html b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.html new file mode 100644 index 000000000..b409310b1 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.html @@ -0,0 +1,21 @@ +
+
+ Fertig +
+
+ + +
+
diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.scss b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.scss new file mode 100644 index 000000000..0a47c0946 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.scss @@ -0,0 +1,17 @@ +.container { + background-color: white; + background-color: white; + border-radius: 5px; + box-shadow: 0px 0px 10px 0px #dce2e9; + height: calc(100% - 70px); + margin-top: 10px; + overflow-y: scroll; + padding-top: 15px; + scroll-behavior: smooth; + .header { + margin-bottom: 10px; + margin-right: 10px; + display: flex; + justify-content: flex-end; + } +} diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.ts new file mode 100644 index 000000000..a31d04793 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.component.ts @@ -0,0 +1,116 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Select, Store } from '@ngxs/store'; +import { CollectingShelfSelectors } from 'apps/sales/src/app/core/store/selectors/collecting-shelf.selector'; +import { Observable, Subject } from 'rxjs'; +import { OrderDTO } from '@swagger/oms'; +import { takeUntil, filter, take, map } from 'rxjs/operators'; +import { isNullOrUndefined } from 'util'; +import { Router, ActivatedRoute, Params } from '@angular/router'; +import { ChangeCurrentRoute } from 'apps/sales/src/app/core/store/actions/process.actions'; +import { PopBreadcrumbsAfterCurrent } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; +import { CollectingShelfService } from 'apps/sales/src/app/core/services/collecting-shelf.service'; +import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions'; +@Component({ + selector: 'app-shelf-edit-order-from-customer', + templateUrl: './shelf-edit-order-from-customer.component.html', + styleUrls: ['./shelf-edit-order-from-customer.component.scss'], +}) +export class ShelfEditOrderFromCustomerComponent implements OnInit, OnDestroy { + @Select(CollectingShelfSelectors.getShelfEditOrder) order$: Observable< + OrderDTO + >; + destroy$ = new Subject(); + order: OrderDTO; + compartmentCode: string; + type: string; + status: string; + orderId: number; + origin: string; + customerId: number; + itemId: number; + multi = false; + constructor( + private store: Store, + private router: Router, + private route: ActivatedRoute, + private shelfService: CollectingShelfService + ) {} + ngOnInit() { + this.route.params.pipe(take(1)).subscribe(this.routeParamsSubscriber$); + } + ngOnDestroy() { + this.destroy$.next(); + } + routeParamsSubscriber$ = (params: Params) => { + if ( + params['id'] && + params['status'] && + params['type'] && + params['orderId'] && + params['origin'] && + params['customerId'] + ) { + this.status = params['status']; + this.type = params['type']; + this.compartmentCode = params['id']; + this.orderId = params['orderId']; + this.origin = params['origin']; + this.customerId = params['customerId']; + this.itemId = +params['itemId']; + } + this.order$ + .pipe( + takeUntil(this.destroy$), + filter((data) => !isNullOrUndefined(data)), + map((order) => ({ + ...order, + items: + this.itemId === 0 || isNullOrUndefined(this.itemId) + ? order.items + : order.items.filter((item) => + item.data.subsetItems.some( + (subsetItem) => subsetItem.id === this.itemId + ) + ), + })) + ) + .subscribe(this.orderSubscriber$); + }; + orderSubscriber$ = (order: OrderDTO) => { + this.order = order; + if (order.items && order.items && order.items.length > 1) { + this.multi = true; + } else { + this.multi = false; + } + }; + done() { + if (this.compartmentCode || this.orderId) { + if (this.origin === 'shelf') { + const path = `/shelf/details/${ + this.compartmentCode ? this.compartmentCode : this.orderId + }/${this.orderId}/${this.status}/${this.type}`; + this.store.dispatch(new PopBreadcrumbsAfterCurrent(path)); + this.store.dispatch(new ChangeCurrentRoute(path, true)); + this.router.navigate([path]); + } + if (this.origin === 'customer') { + const path = `/customer/${this.customerId}/order/${this.orderId}`; + this.store.dispatch(new PopBreadcrumbsAfterCurrent(path)); + this.store.dispatch(new ChangeCurrentRoute(path, true)); + this.router.navigate([path]); + } + if (this.origin === 'goodsin') { + const path = `/goodsin/details/${this.orderId}/${this.itemId}/${this.status}`; + this.store.dispatch(new SetBranchProcessCurrentPath(path, true)); + this.router.navigate([path]); + } + } + } + statusChanged(processingStatus: string) { + this.status = processingStatus; + } + compartmentCodeChanged(compartmentCode: string) { + this.compartmentCode = compartmentCode; + } +} diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.module.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.module.ts new file mode 100644 index 000000000..a4516bda2 --- /dev/null +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order-from-customer/shelf-edit-order-from-customer.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ShelfEditOrderFromCustomerComponent } from './shelf-edit-order-from-customer.component'; +import { ButtonModule, IconModule, DropdownModule } from '@libs/ui'; +import { + OrderOverviewEditComponent, + OrderItemEditComponent, +} from '../../components'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { SharedModule } from 'apps/sales/src/app/shared/shared.module'; + +@NgModule({ + imports: [ + CommonModule, + ButtonModule, + FormsModule, + ReactiveFormsModule, + IconModule, + DropdownModule, + SharedModule, + ], + exports: [ + ShelfEditOrderFromCustomerComponent, + OrderOverviewEditComponent, + OrderItemEditComponent, + ], + declarations: [ + ShelfEditOrderFromCustomerComponent, + OrderOverviewEditComponent, + OrderItemEditComponent, + ], + providers: [], +}) +export class ShelfEditOrderFromCustomerModule {} diff --git a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts index 3f276f172..e029b96c4 100644 --- a/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts +++ b/apps/sales/src/app/modules/shelf/pages/shelf-edit-order/shelf-edit-order.component.ts @@ -6,7 +6,6 @@ import { } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { FormGroup, FormArray } from '@angular/forms'; -import { ShelfEditFormService } from '../../services'; import { ShelfNavigationService } from '../../shared/services'; import { filter, @@ -18,14 +17,14 @@ import { first, } from 'rxjs/operators'; import { isNullOrUndefined } from 'util'; -import { - ProcessingStatusPipe, - PickUpDateOptionsToDisplayValuesPipe, - ProcessingStatusOptionsPipe, -} from '../../pipes'; import { DatePipe } from '@angular/common'; import { OrderItemProcessingStatusValue } from '@swagger/oms/lib'; -import { from } from 'rxjs'; +import { ShelfEditFormService } from '../../services/shelf-edit-form.service'; +import { + ProcessingStatusOptionsPipe, + ProcessingStatusPipe, + PickUpDateOptionsToDisplayValuesPipe, +} from '../../pipes'; @Component({ selector: 'app-shelf-edit-order', templateUrl: './shelf-edit-order.component.html', @@ -99,17 +98,11 @@ export class ShelfEditOrderComponent implements OnInit { ); if (submitResult) { - this.shelfNavigationService.navigateBackToDetails( - { - orderNumber, - processingStatus: - this.form.get('processingStatus').value || processingStatus, - }, - { - orderNumber, - processingStatus, - } - ); + this.shelfNavigationService.navigateBackToDetails({ + orderNumber, + processingStatus: + this.form.get('processingStatus').value || processingStatus, + }); } } diff --git a/apps/sales/src/app/modules/shelf/shelf-routing.module.ts b/apps/sales/src/app/modules/shelf/shelf-routing.module.ts index 9cec8f986..3b4e7ec27 100644 --- a/apps/sales/src/app/modules/shelf/shelf-routing.module.ts +++ b/apps/sales/src/app/modules/shelf/shelf-routing.module.ts @@ -7,6 +7,7 @@ import { ShelfEditOrderComponent } from './pages/shelf-edit-order/shelf-edit-ord import { ShelfHistoryComponent } from './pages/shelf-history'; import { ShelfOrderDetailsModule } from './pages/shelf-order-details'; import { ShelfEditCompartmentComponent } from './pages/shelf-edit-compartment'; +import { ShelfEditOrderFromCustomerComponent } from './pages/shelf-edit-order-from-customer'; export const routes: Routes = [ { @@ -17,6 +18,10 @@ export const routes: Routes = [ path: 'results', component: ShelfSearchResultsComponent, }, + { + path: 'edit/:id/:orderId/:status/:type/:origin/:customerId/:itemId', + component: ShelfEditOrderFromCustomerComponent, + }, { path: 'details/order/:orderId/:processingStatus', component: ShelfOrderDetailsComponent, @@ -34,11 +39,13 @@ export const routes: Routes = [ component: ShelfEditCompartmentComponent, }, { - path: 'details/order/:orderId/item/:orderItemId/subset/:orderItemSubsetId/history', + path: + 'details/order/:orderId/item/:orderItemId/subset/:orderItemSubsetId/history', component: ShelfHistoryComponent, }, { - path: 'details/compartment/:compartmentCode/item/:orderItemId/subset/:orderItemSubsetId/history', + path: + 'details/compartment/:compartmentCode/item/:orderItemId/subset/:orderItemSubsetId/history', component: ShelfHistoryComponent, }, ]; diff --git a/apps/sales/src/app/modules/shelf/shelf.module.ts b/apps/sales/src/app/modules/shelf/shelf.module.ts index d6228b5e0..3f1b464a6 100644 --- a/apps/sales/src/app/modules/shelf/shelf.module.ts +++ b/apps/sales/src/app/modules/shelf/shelf.module.ts @@ -22,8 +22,6 @@ import { ShelfCustomerOrderComponent, ShelfOrderTagComponent, ShelfPartialCollectionModalComponent, - OrderItemEditComponent, - OrderOverviewEditComponent, } from './components'; import { ShelfRoutingModule } from './shelf-routing.module'; import { OrderStatusPipe } from '../../pipes/order-status.pipe'; @@ -33,6 +31,8 @@ import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; import { ShelfSearchResultsModule } from './pages/shelf-search-results/shelf-search-results.module'; import { ShelfSearchModule } from './pages/shelf-search'; import { ShelfHistoryModule } from './pages/shelf-history'; + +import { ShelfEditOrderFromCustomerModule } from './pages/shelf-edit-order-from-customer'; import { ShelfEditOrderModule } from './pages/shelf-edit-order/shelf-edit-order.module'; import { ShelfEditCompartmentModule } from './pages/shelf-edit-compartment'; @@ -45,8 +45,6 @@ import { ShelfEditCompartmentModule } from './pages/shelf-edit-compartment'; ShelfPartialCollectionModalComponent, OrderStatusPipe, OrderLoadingComponent, - OrderItemEditComponent, - OrderOverviewEditComponent, ], exports: [ShelfOrderTagComponent], imports: [ @@ -56,6 +54,7 @@ import { ShelfEditCompartmentModule } from './pages/shelf-edit-compartment'; ShelfHistoryModule, ShelfEditOrderModule, ShelfEditCompartmentModule, + ShelfEditOrderFromCustomerModule, FormsModule, ReactiveFormsModule, RouterModule, From 8c988f091702ed406931843ed294605bb30bf439 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 4 Sep 2020 12:31:17 +0200 Subject: [PATCH 119/135] Set Results Hits Based on Actual Result Hits (old: filterdCustomer hits) --- .../customer-search-card/customer-search-card.component.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts b/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts index 0773cad26..760af7acf 100644 --- a/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts +++ b/apps/sales/src/app/modules/customer/components/customer-search-card/customer-search-card.component.ts @@ -98,8 +98,9 @@ export class CustomerSearchCardComponent const response = { ...r, customers: filteredCustomer, - hits: filteredCustomer ? filteredCustomer.length : 0, + hits: r.hits, }; + this.store.dispatch( new AddBreadcrumb( { From c5e73bf5785aa5d961461d51ba135c9b9c1f0886 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 4 Sep 2020 14:23:18 +0200 Subject: [PATCH 120/135] Add Underscore between compartmentCode and compartmentInfo --- .../order-details-card.component.html | 105 +++++++++++++----- .../search-result-group-item.component.html | 5 +- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html index 7a950f992..6fd450682 100644 --- a/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html +++ b/apps/sales/src/app/modules/shelf/components/order-details-card/order-details-card.component.html @@ -1,7 +1,11 @@

{{ orderDetails?.firstName }} {{ orderDetails?.lastName }} - {{ orderDetails?.compartmentCode }} - {{ orderDetails?.compartmentInfo }} + {{ orderDetails?.compartmentCode + }}{{ + orderDetails?.compartmentInfo && '_' + orderDetails?.compartmentInfo + }}

@@ -30,28 +34,49 @@
Status
- - - + - @@ -83,16 +108,29 @@
vsl. Lieferdatum
- - + (save)="changeEstimatedDeliveryDate.emit($event); uiDatepicker.close()" + >
@@ -102,21 +140,36 @@
Abholfrist
- - + -
- \ No newline at end of file + diff --git a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html index 3397617cf..da109a70e 100644 --- a/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html +++ b/apps/sales/src/app/modules/shelf/components/search-result-group/search-result-group-item.component.html @@ -10,7 +10,10 @@ class="isa-text-right isa-mb-9 isa-font-size-24" *ngIf="item.compartmentCode && displayCompartmentCode" > - {{ item.compartmentCode }} {{ item.compartmentInfo }} + {{ item.compartmentCode + }}{{ item.compartmentInfo && '_' + item.compartmentInfo }} +