Compare commits

...

9 Commits

Author SHA1 Message Date
Michael Auer
d6775aad69 Merge branch 'hotfix/3452-Autocomplete-Abbrechen-Bei-Suche' 2022-09-28 22:19:02 +02:00
Lorenz Hilpert
3bdcdee031 #3452 Autocomplete wird nicht abgebrochen, wenn Suche ausgelöst wurde 2022-09-12 14:34:24 +02:00
Michael Auer
da2c1c8316 Merge branch 'release/2.0' 2022-08-24 10:33:18 +02:00
Lorenz Hilpert
6067e02729 #3400 Uebergabe 0 Eur wenn kein Preis existiert 2022-08-18 16:57:06 +02:00
Lorenz Hilpert
eb77664ea1 #3387 - Auswertung der Kapazitaeten angepasst 2022-08-18 15:38:24 +02:00
Lorenz Hilpert
d79dbb11fe #2162 - Warnung eingebaut und Anzeigefehler behoben 2022-08-17 17:08:09 +02:00
Lorenz Hilpert
19ccb29248 #2162 - WA - Auf der Details Seite werden nur items mit dem gleichen Kunden angezeigt. 2022-08-16 15:29:33 +02:00
Lorenz Hilpert
fa1769da9f 2022-08-08 12:10:19 +02:00
Andreas Schickinger
57bd8d4dd4 Merged PR 1368: #3337 Hotfix E-Mail Adresse wird nur noch angehakt, wenn auch eine hinterlegt ist
#3337 E-Mail Adresse wird nur noch angehakt, wenn auch eine hinterlegt ist

Related work items: #3337
2022-08-04 09:45:59 +00:00
19 changed files with 259 additions and 71 deletions

View File

@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output } from '@angular/core';
import { UiFilter } from '@ui/filter';
import { ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core';
import { UiFilter, UiFilterComponent } from '@ui/filter';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { ArticleSearchService } from '../article-search.store';
@@ -20,6 +20,9 @@ export class ArticleSearchFilterComponent implements OnInit {
searchboxHint$ = this.articleSearch.searchboxHint$;
@ViewChild(UiFilterComponent, { static: false })
uiFilterComponent: UiFilterComponent;
constructor(private articleSearch: ArticleSearchService) {}
ngOnInit() {
@@ -41,6 +44,7 @@ export class ArticleSearchFilterComponent implements OnInit {
}
applyFilter(value: UiFilter) {
this.uiFilterComponent?.cancelAutocomplete();
this.articleSearch.setFilter(value);
this.articleSearch.search({ clear: true });
this.articleSearch.searchCompleted.pipe(take(1)).subscribe((s) => {

View File

@@ -1,14 +1,13 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { ApplicationService } from '@core/application';
import { DomainCatalogService } from '@domain/catalog';
import { UiFilter } from '@ui/filter';
import { UiFilter, UiFilterInputGroupMainComponent } from '@ui/filter';
import { combineLatest, NEVER, Subscription } from 'rxjs';
import { catchError, debounceTime, first } from 'rxjs/operators';
import { FocusSearchboxEvent } from '../focus-searchbox.event';
import { ArticleSearchService } from '../article-search.store';
import { isEmpty, isEqual } from 'lodash';
import { isEqual } from 'lodash';
@Component({
selector: 'page-article-search-main',
@@ -27,6 +26,9 @@ export class ArticleSearchMainComponent implements OnInit, OnDestroy {
subscriptions = new Subscription();
@ViewChild(UiFilterInputGroupMainComponent, { static: false })
uiInputGroupMain: UiFilterInputGroupMainComponent;
constructor(
private searchService: ArticleSearchService,
private catalog: DomainCatalogService,
@@ -69,6 +71,7 @@ export class ArticleSearchMainComponent implements OnInit, OnDestroy {
}
search(filter: UiFilter) {
this.uiInputGroupMain.cancelAutocomplete();
this.searchService.setFilter(filter);
this.searchService.search({ clear: true });
}

View File

@@ -318,9 +318,22 @@ export class CheckoutReviewComponent extends ComponentStore<CheckoutReviewCompon
const fb = this._fb;
const notificationChannel = await this.notificationChannel$.pipe(first()).toPromise();
const communicationDetails = await this.communicationDetails$.pipe(first()).toPromise();
let selectedNotificationChannel = 0;
if ((notificationChannel & 1) === 1 && communicationDetails.email) {
selectedNotificationChannel += 1;
}
if ((notificationChannel & 2) === 2 && communicationDetails.mobile) {
selectedNotificationChannel += 2;
}
// #1967 Wenn E-Mail und SMS als NotificationChannel gesetzt sind, nur E-Mail anhaken
if ((selectedNotificationChannel & 3) === 3) {
selectedNotificationChannel = 1;
}
this.control = fb.group({
notificationChannel: new FormGroup({
selected: new FormControl((notificationChannel & 3) === 3 || communicationDetails.email ? 1 : notificationChannel),
selected: new FormControl(selectedNotificationChannel),
email: new FormControl(communicationDetails ? communicationDetails.email : '', emailNotificationValidator),
mobile: new FormControl(communicationDetails ? communicationDetails.mobile : '', mobileNotificationValidator),
}),

View File

@@ -1,6 +1,6 @@
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy, Output, EventEmitter } from '@angular/core';
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy, Output, EventEmitter, ViewChild } from '@angular/core';
import { SearchComponentStoreService } from '@store/search-component-store';
import { Filter, UiFilter } from '@ui/filter';
import { Filter, UiFilter, UiFilterComponent } from '@ui/filter';
import { isEqual } from 'lodash';
import { Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
@@ -21,6 +21,9 @@ export class CustomerSearchFilterComponent implements OnInit, OnDestroy {
filterValuesChanged = false;
@ViewChild(UiFilterComponent, { static: false })
uiFilter: UiFilterComponent;
constructor(public store: SearchComponentStoreService, private cdr: ChangeDetectorRef) {}
ngOnInit() {}
@@ -31,6 +34,7 @@ export class CustomerSearchFilterComponent implements OnInit, OnDestroy {
}
applyFilter(filter: UiFilter) {
this.uiFilter?.cancelAutocomplete();
this.store.setFilter(filter);
this.store.search({ clear: true });

View File

@@ -1,8 +1,8 @@
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy, OnInit } from '@angular/core';
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { SearchComponentStoreService } from '@store/search-component-store';
import { UiFilter } from '@ui/filter';
import { UiFilter, UiFilterInputGroupMainComponent } from '@ui/filter';
import { isEqual } from 'lodash';
import { combineLatest, NEVER, Observable, Subject } from 'rxjs';
import { debounceTime, filter, map, switchMap, takeUntil } from 'rxjs/operators';
@@ -26,6 +26,9 @@ export class CustomerSearchMainComponent implements OnInit, OnDestroy {
message$ = this._store.message$;
@ViewChild(UiFilterInputGroupMainComponent, { static: false })
uiInputGroupMain: UiFilterInputGroupMainComponent;
constructor(
public cdr: ChangeDetectorRef,
private _breadcrumb: BreadcrumbService,
@@ -90,6 +93,7 @@ export class CustomerSearchMainComponent implements OnInit, OnDestroy {
}
search(filter: UiFilter) {
this.uiInputGroupMain?.cancelAutocomplete();
this._store.setFilter(filter);
this._store.search({ clear: true });
}

View File

@@ -1,8 +1,8 @@
import { Component, ChangeDetectionStrategy, Output, EventEmitter, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';
import { Component, ChangeDetectionStrategy, Output, EventEmitter, ChangeDetectorRef, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { UiFilter } from '@ui/filter';
import { UiFilter, UiFilterComponent } from '@ui/filter';
import { Observable, Subject } from 'rxjs';
import { first, take, takeUntil } from 'rxjs/operators';
import { GoodsInSearchStore } from '../goods-in-search.store';
@@ -25,6 +25,9 @@ export class GoodsInSearchFilterComponent implements OnInit, OnDestroy {
private _onDestroy$ = new Subject();
@ViewChild(UiFilterComponent, { static: false })
uiFilter: UiFilterComponent;
constructor(
private _goodsInSearchStore: GoodsInSearchStore,
private _breadcrumb: BreadcrumbService,
@@ -59,6 +62,7 @@ export class GoodsInSearchFilterComponent implements OnInit, OnDestroy {
}
async applyFilter() {
this.uiFilter?.cancelAutocomplete();
this._goodsInSearchStore.clearResults();
this._goodsInSearchStore.setFilter(this.filter);
this.message = undefined;

View File

@@ -1,7 +1,8 @@
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ChangeDetectorRef, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { UiFilterInputGroupMainComponent } from '@ui/filter';
import { Subscription } from 'rxjs';
import { first, debounceTime } from 'rxjs/operators';
import { GoodsInSearchStore } from '../goods-in-search.store';
@@ -21,6 +22,9 @@ export class GoodsInSearchMainComponent implements OnInit, OnDestroy {
private _subscriptions = new Subscription();
@ViewChild(UiFilterInputGroupMainComponent, { static: false })
uiFilterGroupMain: UiFilterInputGroupMainComponent;
constructor(
private _goodsInSearchStore: GoodsInSearchStore,
private _cdr: ChangeDetectorRef,
@@ -111,6 +115,7 @@ export class GoodsInSearchMainComponent implements OnInit, OnDestroy {
}
async search() {
this.uiFilterGroupMain?.cancelAutocomplete();
this._goodsInSearchStore.clearResults();
await this.updateQueryParams();
this.message = undefined;

View File

@@ -1,7 +1,7 @@
<shared-goods-in-out-order-details (actionHandled)="actionHandled($event)" [itemsSelectable]="true">
<shared-goods-in-out-order-details-header (editClick)="navigateToEditPage($event)"></shared-goods-in-out-order-details-header>
<shared-goods-in-out-order-details-header (editClick)="navigateToEditPage($event)"> </shared-goods-in-out-order-details-header>
<shared-goods-in-out-order-details-item
*ngFor="let item of itemsWithProcessingStatus$ | async"
*ngFor="let item of items$ | async"
[orderItem]="item"
[order]="order$ | async"
></shared-goods-in-out-order-details-item>

View File

@@ -4,12 +4,14 @@ import { BreadcrumbService } from '@core/breadcrumb';
import { DomainGoodsService, DomainOmsService, OrderItemsContext } from '@domain/oms';
import { ComponentStore, tapResponse } from '@ngrx/component-store';
import { ListResponseArgsOfOrderItemListItemDTO, OrderItemListItemDTO, OrderItemProcessingStatusValue } from '@swagger/oms';
import { UiMessageModalComponent, UiModalService } from '@ui/modal';
import { combineLatest, Observable, Subject } from 'rxjs';
import { debounceTime, filter, first, map, shareReplay, switchMap, takeUntil, tap, withLatestFrom } from 'rxjs/operators';
export interface GoodsOutDetailsComponentState {
fetching: boolean;
orderNumber?: string;
buyerNumber?: string;
processingStatus?: OrderItemProcessingStatusValue;
compartmentCode?: string;
items?: OrderItemListItemDTO[];
@@ -25,6 +27,8 @@ export interface GoodsOutDetailsComponentState {
export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComponentState> implements OnInit, OnDestroy {
orderNumber$ = this.select((s) => decodeURIComponent(s.orderNumber ?? '') || undefined);
buyerNumber$ = this.select((s) => s.buyerNumber);
compartmentCode$ = this.select((s) => decodeURIComponent(s.compartmentCode ?? '') || undefined);
processingStatus$ = this.select((s) => s.processingStatus);
@@ -37,10 +41,6 @@ export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComp
return this.get((s) => s.items);
}
itemsWithProcessingStatus$ = combineLatest([this.items$, this.processingStatus$]).pipe(
map(([items, processingStatus]) => items.filter((item) => item.processingStatus === processingStatus))
);
order$ = this.orderId$.pipe(
filter((orderId) => !!orderId),
switchMap((orderId) => this._omsService.getOrder(orderId)),
@@ -60,7 +60,8 @@ export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComp
private _domainGoodsInService: DomainGoodsService,
private _omsService: DomainOmsService,
private _breadcrumb: BreadcrumbService,
private _router: Router
private _router: Router,
private _uiModal: UiModalService
) {
super({
fetching: false,
@@ -68,6 +69,11 @@ export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComp
}
ngOnInit() {
this._activatedRoute.queryParams.pipe(takeUntil(this._onDestroy$)).subscribe((params) => {
const buyerNumber: string = decodeURIComponent(params.buyerNumber ?? '');
this.patchState({ buyerNumber });
});
this._activatedRoute.params.pipe(takeUntil(this._onDestroy$)).subscribe(async (params) => {
const orderNumber: string = params?.orderNumber;
const compartmentCode = params?.compartmentCode;
@@ -92,6 +98,9 @@ export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComp
key: this.processId,
name: item?.compartmentCode || item?.orderNumber,
path: this.getDetailsPath(item),
params: {
buyerNumber: item.buyerNumber,
},
section: 'customer',
tags: ['goods-out', 'details', item?.compartmentCode || item?.orderNumber],
});
@@ -122,8 +131,8 @@ export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComp
$.pipe(
tap(() => this.patchState({ fetching: false })),
debounceTime(500),
withLatestFrom(this.orderNumber$, this.compartmentCode$, this.processingStatus$),
switchMap(([_, orderNumber, compartmentCode, processingStatus]) => {
withLatestFrom(this.orderNumber$, this.compartmentCode$),
switchMap(([_, orderNumber, compartmentCode]) => {
let request$: Observable<ListResponseArgsOfOrderItemListItemDTO>;
if (compartmentCode) {
request$ = this._domainGoodsInService.getWarenausgabeItemByCompartment(compartmentCode);
@@ -131,14 +140,20 @@ export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComp
request$ = this._domainGoodsInService.getWarenausgabeItemByOrderNumber(orderNumber);
}
return request$.pipe(
return combineLatest([request$, this.processingStatus$, this.buyerNumber$]).pipe(
tapResponse(
(res) => {
this.patchState({
items: res.result,
orderId: res.result[0].orderId,
([res, processingStatus, buyerNumber]) => {
const items = res.result.filter((item) => {
return item.processingStatus === processingStatus && (!!buyerNumber ? item.buyerNumber === buyerNumber : true);
});
this.updateBreadcrumb(res.result.find((item) => item.processingStatus === processingStatus));
this.openModalIfItemsHaveDifferentCustomers(items);
this.patchState({
items,
orderId: items[0].orderId,
});
this.updateBreadcrumb(items[0]);
},
(err) => {},
() => {
@@ -150,12 +165,25 @@ export class GoodsOutDetailsComponent extends ComponentStore<GoodsOutDetailsComp
)
);
openModalIfItemsHaveDifferentCustomers(items: OrderItemListItemDTO[]) {
const buyerNumbers = new Set(items.map((item) => item.buyerNumber));
if (buyerNumbers.size > 1) {
this._uiModal.open({
content: UiMessageModalComponent,
title: 'Achtung',
data: {
message: 'Anzeige ist fehlerhaft.\nEs wurden mehrere Positionen gefunden, die mehreren Kunden unterschiedlichen sind.',
},
});
}
}
navigateToEditPage(orderItem: OrderItemListItemDTO) {
this._router.navigate([this.getEditPath(orderItem)]);
this._router.navigate([this.getEditPath(orderItem)], { queryParams: { buyerNumber: orderItem.buyerNumber } });
}
navigateToDetailsPage(item: OrderItemListItemDTO) {
this._router.navigate([this.getDetailsPath(item)]);
this._router.navigate([this.getDetailsPath(item)], { queryParams: { buyerNumber: item.buyerNumber } });
}
navigateToLandingPage() {

View File

@@ -2,8 +2,10 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { DomainGoodsService } from '@domain/oms';
import { OrderItemListItemDTO } from '@swagger/oms';
import { UiMessageModalComponent, UiModalService } from '@ui/modal';
import { combineLatest, Observable } from 'rxjs';
import { map, shareReplay, switchMap, withLatestFrom } from 'rxjs/operators';
import { map, shareReplay, switchMap, tap, withLatestFrom } from 'rxjs/operators';
@Component({
selector: 'page-goods-out-edit',
@@ -28,14 +30,22 @@ export class GoodsOutEditComponent implements OnInit {
map((params) => decodeURIComponent(params?.compartmentCode ?? '') || undefined)
);
buyerNumber$ = this._activatedRoute.queryParams.pipe(map((params) => params.buyerNumber));
items$ = combineLatest([this.orderNumber$, this.compartmentCode$]).pipe(
switchMap(([orderNumber, compartmentCode]) =>
compartmentCode
? this._domainGoodsInService.getWarenausgabeItemByCompartment(compartmentCode)
: this._domainGoodsInService.getWarenausgabeItemByOrderNumber(orderNumber)
),
withLatestFrom(this.processingStatus$),
map(([response, processingStatus]) => response.result.filter((item) => item.processingStatus === +processingStatus)),
withLatestFrom(this.processingStatus$, this.buyerNumber$),
map(([response, processingStatus, buyerNumber]) => {
console.log(response, processingStatus, buyerNumber);
return response.result.filter(
(item) => item.processingStatus === +processingStatus && (!!buyerNumber ? item.buyerNumber === buyerNumber : true)
);
}),
tap((items) => this.openModalIfItemsHaveDifferentCustomers(items)),
shareReplay()
);
@@ -43,7 +53,8 @@ export class GoodsOutEditComponent implements OnInit {
private _activatedRoute: ActivatedRoute,
private _breadcrumb: BreadcrumbService,
private _domainGoodsInService: DomainGoodsService,
private _router: Router
private _router: Router,
private _uiModal: UiModalService
) {}
ngOnInit() {
@@ -54,6 +65,7 @@ export class GoodsOutEditComponent implements OnInit {
const orderNumber = this._activatedRoute.snapshot.params.orderNumber;
const compartmentCode = this._activatedRoute.snapshot.params.compartmentCode;
const processingStatus = this._activatedRoute.snapshot.params.processingStatus;
const buyerNumber = this._activatedRoute.snapshot.queryParams.buyerNumber;
await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists({
key: this.processId,
name: 'Bearbeiten',
@@ -61,6 +73,7 @@ export class GoodsOutEditComponent implements OnInit {
? `/kunde/${this.processId}/goods/out/details/compartment/${encodeURIComponent(compartmentCode)}/${processingStatus}/edit`
: `/kunde/${this.processId}/goods/out/details/order/${encodeURIComponent(orderNumber)}/${processingStatus}/edit`,
section: 'customer',
params: { buyerNumber },
tags: ['goods-out', 'edit', compartmentCode || orderNumber],
});
}
@@ -69,10 +82,27 @@ export class GoodsOutEditComponent implements OnInit {
const orderNumber = this._activatedRoute.snapshot.params.orderNumber;
const compartmentCode = this._activatedRoute.snapshot.params.compartmentCode;
const processingStatus = options?.processingStatus ? options.processingStatus : this._activatedRoute.snapshot.params.processingStatus;
const buyerNumber = this._activatedRoute.snapshot.queryParams.buyerNumber;
compartmentCode
? this._router.navigate([
`/kunde/${this.processId}/goods/out/details/compartment/${encodeURIComponent(compartmentCode)}/${processingStatus}`,
])
: this._router.navigate([`/kunde/${this.processId}/goods/out/details/order/${encodeURIComponent(orderNumber)}/${processingStatus}`]);
? this._router.navigate(
[`/kunde/${this.processId}/goods/out/details/compartment/${encodeURIComponent(compartmentCode)}/${processingStatus}`],
{ queryParams: { buyerNumber } }
)
: this._router.navigate([`/kunde/${this.processId}/goods/out/details/order/${encodeURIComponent(orderNumber)}/${processingStatus}`], {
queryParams: { buyerNumber },
});
}
openModalIfItemsHaveDifferentCustomers(items: OrderItemListItemDTO[]) {
const buyerNumbers = new Set(items.map((item) => item.buyerNumber));
if (buyerNumbers.size > 1) {
this._uiModal.open({
content: UiMessageModalComponent,
title: 'Achtung',
data: {
message: 'Anzeige ist fehlerhaft.\nEs wurden mehrere Positionen gefunden, die unterschiedlichen Kunden zugeordnet sind.',
},
});
}
}
}

View File

@@ -1,9 +1,19 @@
import { Component, ChangeDetectionStrategy, Output, EventEmitter, ChangeDetectorRef, OnInit, OnDestroy, Input } from '@angular/core';
import {
Component,
ChangeDetectionStrategy,
Output,
EventEmitter,
ChangeDetectorRef,
OnInit,
OnDestroy,
Input,
ViewChild,
} from '@angular/core';
import { Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { OrderItemListItemDTO } from '@swagger/oms';
import { UiFilter } from '@ui/filter';
import { UiFilter, UiFilterComponent } from '@ui/filter';
import { Observable, Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';
import { GoodsOutSearchStore } from '../goods-out-search.store';
@@ -29,6 +39,9 @@ export class GoodsOutSearchFilterComponent implements OnInit, OnDestroy {
private _onDestroy$ = new Subject();
@ViewChild(UiFilterComponent, { static: false })
uiFilter: UiFilterComponent;
constructor(
private _goodsOutSearchStore: GoodsOutSearchStore,
private _breadcrumb: BreadcrumbService,
@@ -63,6 +76,7 @@ export class GoodsOutSearchFilterComponent implements OnInit, OnDestroy {
}
async applyFilter() {
this.uiFilter?.cancelAutocomplete();
this._goodsOutSearchStore.setFilter(this.filter);
this.message = undefined;

View File

@@ -1,7 +1,8 @@
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ChangeDetectorRef, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { OrderItemListItemDTO } from '@swagger/oms';
import { UiFilterInputGroupMainComponent } from '@ui/filter';
import { debounce, isEqual } from 'lodash';
import { BehaviorSubject, combineLatest, Subscription } from 'rxjs';
import { debounceTime, first, map, withLatestFrom } from 'rxjs/operators';
@@ -32,6 +33,9 @@ export class GoodsOutSearchMainComponent implements OnInit, OnDestroy {
processId$ = this._activatedRoute.data.pipe(map((data) => +data.processId));
@ViewChild(UiFilterInputGroupMainComponent, { static: false })
filterInputGroup: UiFilterInputGroupMainComponent;
constructor(
private _goodsOutSearchStore: GoodsOutSearchStore,
private _cdr: ChangeDetectorRef,
@@ -88,6 +92,7 @@ export class GoodsOutSearchMainComponent implements OnInit, OnDestroy {
}
async search() {
this.filterInputGroup?.cancelAutocomplete();
await this.updateQueryParams(this.processId);
this.message = undefined;

View File

@@ -258,9 +258,14 @@ export class GoodsOutSearchResultsComponent extends ComponentStore<GoodsOutSearc
const compartmentCode = orderItem.compartmentCode;
if (compartmentCode) {
this._router.navigate([
`/kunde/${processId}/goods/out/details/compartment/${encodeURIComponent(compartmentCode)}/${processingStatus}`,
]);
this._router.navigate(
[`/kunde/${processId}/goods/out/details/compartment/${encodeURIComponent(compartmentCode)}/${processingStatus}`],
{
queryParams: {
buyerNumber: orderItem.buyerNumber,
},
}
);
} else {
this._router.navigate([`/kunde/${processId}/goods/out/details/order/${encodeURIComponent(orderNumber)}/${processingStatus}`]);
}

View File

@@ -107,9 +107,18 @@ export class AddProductModalComponent implements OnInit, OnDestroy {
return;
}
const item = { ...this.item };
if (!item.retailPrice) {
item.retailPrice = {
value: { value: 0, currency: 'EUR' },
vat: item.retailPrice?.vat,
};
}
try {
const result = await this._remiService
.addProductToRemit(this.item, this.selectedReason, this.form.value.quantity)
.addProductToRemit(item, this.selectedReason, this.form.value.quantity)
.pipe(first())
.toPromise();

View File

@@ -1,11 +1,11 @@
<ng-container *ngIf="requiredCapacities?.length > 1">
<div class="progress-outer">
<div class="progress-inner" [style.width]="capacityPercentage + '%'"></div>
<div class="progress-inner" [style.width]="leistungPercentage + '%'"></div>
</div>
<div class="mt-px-2 text-active-branch">Leistungsplätze: {{ capacity }} von {{ maxCapacity }} Exemplaren</div>
<div class="mt-px-2 text-active-branch">Leistungsplätze: {{ leistung }} von {{ maxLeistung }} Exemplaren</div>
<div class="progress-outer">
<div class="progress-inner" [style.width]="staplePercentage + '%'"></div>
<div class="progress-inner" [style.width]="stapelPercentage + '%'"></div>
</div>
<div class="mt-px-2 text-active-branch">Stapelplätze: {{ staple }} von {{ maxStaple }} Titel</div>
<div class="mt-px-2 text-active-branch">Stapelplätze: {{ stapel }} von {{ maxStapel }} Titel</div>
</ng-container>

View File

@@ -11,38 +11,75 @@ export class RequiredCapacitiesComponent {
@Input()
requiredCapacities: ValueTupleOfStringAndIntegerAndIntegerAndNullableIntegerAndString[];
get capacity() {
return this.requiredCapacities?.find((_) => true)?.item3 || 0;
get leistungCapacity() {
return this.requiredCapacities?.find((cap) => cap.item1 === 'Leistung') || undefined;
}
get maxCapacity() {
return Math.max(this.capacity, this.requiredCapacities?.find((_) => true)?.item2);
get leistung() {
const capacity = this.leistungCapacity;
if (!capacity) {
return 0;
}
return capacity.item3 > capacity.item2 ? capacity.item2 : capacity.item3;
}
get capacityPercentage() {
if (this.maxCapacity > 0) {
return (this.capacity / this.maxCapacity) * 100;
get maxLeistung() {
const capacity = this.leistungCapacity;
if (!capacity) {
return 0;
}
const maxLeistung =
(capacity.item4 || 0) < capacity.item2
? capacity.item4 || (capacity.item3 > capacity.item2 ? capacity.item2 : capacity.item3) || 0
: capacity.item2;
return Math.max(this.leistung, maxLeistung);
}
get leistungPercentage() {
if (this.leistung === this.maxLeistung) {
return 100;
}
if (this.maxLeistung > 0) {
return Math.min(Math.max((this.leistung / this.maxLeistung) * 100, 0), 100);
}
return 0;
}
get staple() {
if (this.requiredCapacities?.length > 0) {
return this.requiredCapacities[1].item3;
}
return 0;
get stapelCapacity() {
return this.requiredCapacities?.find((cap) => cap.item1 === 'Stapel') || undefined;
}
get maxStaple() {
if (this.requiredCapacities?.length > 0) {
return Math.max(this.staple, this.requiredCapacities[1].item2);
get stapel() {
const capacity = this.stapelCapacity;
if (!capacity) {
return 0;
}
return 0;
return capacity.item3 > capacity.item2 ? capacity.item2 : capacity.item3;
}
get staplePercentage() {
if (this.maxStaple > 0) {
return (this.staple / this.maxStaple) * 100;
get maxStapel() {
const capacity = this.stapelCapacity;
if (!capacity) {
return 0;
}
const maxStapel =
(capacity.item4 || 0) < capacity.item2
? capacity.item4 || (capacity.item3 > capacity.item2 ? capacity.item2 : capacity.item3) || 0
: capacity.item2;
return Math.max(this.stapel, maxStapel);
}
get stapelPercentage() {
if (this.stapel === this.maxStapel) {
return 100;
}
if (this.maxStapel > 0) {
return Math.min(Math.max((this.stapel / this.maxStapel) * 100, 0), 100);
}
return 0;
}

View File

@@ -14,7 +14,7 @@ import {
} from '@angular/core';
import { UiAutocompleteComponent } from '@ui/autocomplete';
import { Observable, Subject, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, switchMap, tap } from 'rxjs/operators';
import { debounceTime, distinctUntilChanged, filter, switchMap, takeUntil, tap } from 'rxjs/operators';
import { UiFilterAutocomplete, UiFilterAutocompleteProvider } from '../../providers';
import { IUiInputGroup, UiInput, UiInputGroup } from '../../tree';
@@ -23,6 +23,7 @@ import { IUiInputGroup, UiInput, UiInputGroup } from '../../tree';
templateUrl: 'filter-input-group-main.component.html',
styleUrls: ['filter-input-group-main.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs: 'uiFilterInputGroupMain',
})
export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, AfterViewInit {
@ViewChild(UiAutocompleteComponent, { read: UiAutocompleteComponent, static: false })
@@ -72,6 +73,8 @@ export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, After
complete = new Subject<string>();
private _cancelComplete = new Subject<void>();
private changeSubscriptions: Subscription;
constructor(
@@ -79,6 +82,11 @@ export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, After
private cdr: ChangeDetectorRef
) {}
// cancle autocomplete
cancelAutocomplete() {
this._cancelComplete.next();
}
ngOnInit() {
this._autocompleteProvider = this.autocompleteProviders?.find((provider) => !!provider);
}
@@ -115,7 +123,7 @@ export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, After
this.autocompleteResults$ = this.complete.asObservable().pipe(
debounceTime(this._debounceTimeAutocompleteMilliseconds()),
distinctUntilChanged(),
switchMap(() => this.autocompleteProvider.complete(this.uiInput)),
switchMap(() => this.autocompleteProvider.complete(this.uiInput).pipe(takeUntil(this._cancelComplete))),
tap((complete) => {
if (complete.length > 0) {
this.autocompleteComponent.open();

View File

@@ -168,6 +168,12 @@ export class UiFilter implements IUiFilter {
queryParams['main_qs'] = queryToken.input.qs;
}
if (!!queryToken.filter) {
for (const key in queryToken.filter) {
queryParams[`filter_${key}`] = queryToken.filter[key];
}
}
return queryParams;
}
}

View File

@@ -12,7 +12,9 @@ import {
Inject,
AfterViewInit,
HostListener,
ViewChild,
} from '@angular/core';
import { UiFilterInputGroupMainComponent } from './filter-group/filter-input-group-main';
import { IUiFilter, UiFilter } from './tree/ui-filter';
@Component({
@@ -40,6 +42,9 @@ export class UiFilterComponent implements OnChanges, AfterViewInit {
@Input()
scanner = false;
@ViewChild(UiFilterInputGroupMainComponent)
filterInputGroupMainComponent: UiFilterInputGroupMainComponent;
get uiFilter() {
return this.filter instanceof UiFilter && this.filter;
}
@@ -89,4 +94,8 @@ export class UiFilterComponent implements OnChanges, AfterViewInit {
this.search.emit(query);
}, 1);
}
cancelAutocomplete() {
this.filterInputGroupMainComponent?.cancelAutocomplete();
}
}