Compare commits

...

6 Commits

Author SHA1 Message Date
Nino
58ce8d9ace #4514 Added regex pattern to compartmentCode field inside goods in out order edit page 2024-01-05 11:57:27 +01:00
Nino Righi
b9a4b0d315 Merged PR 1718: #4552 Added whitespace
#4552 Added whitespace
2024-01-05 09:19:08 +00:00
Anastasiia Chetverykova
7809e7a2b5 Merged PR 1717: #4552 - Packstückprüfung Anzahl Exemplare
#4552 - Packstückprüfung Anzahl Exemplare
2024-01-04 13:35:57 +00:00
Nino Righi
9a8c74b148 Merged PR 1716: #4534 Goods In Out Order Edit Always Show Price with Two Decimal Places
#4534 Goods In Out Order Edit Always Show Price with Two Decimal Places
2024-01-04 10:36:37 +00:00
Nino Righi
ad62e67771 Merged PR 1715: #4525 Improved Scroll Position Handling in Goods In List and Remission Previe...
#4525 Improved Scroll Position Handling in Goods In List and Remission Preview Page
2024-01-04 09:23:28 +00:00
Nino Righi
6feb8079b7 Merged PR 1714: #4550 Fix Multiple Processes Bug
#4550 Fix Multiple Processes Bug
2024-01-04 08:23:31 +00:00
7 changed files with 82 additions and 52 deletions

View File

@@ -170,10 +170,9 @@ export class CustomerOrderSearchResultsComponent extends ComponentStore<Customer
);
this._searchResultSubscription.add(
this.processId$
combineLatest([this.processId$, this._activatedRoute.queryParams])
.pipe(
debounceTime(150),
withLatestFrom(this._activatedRoute.queryParams),
switchMap(([processId, params]) =>
this._application.getSelectedBranch$(processId).pipe(map((selectedBranch) => ({ processId, params, selectedBranch })))
)
@@ -185,16 +184,6 @@ export class CustomerOrderSearchResultsComponent extends ComponentStore<Customer
if (processChanged) {
if (!!this._customerOrderSearchStore.processId && this._customerOrderSearchStore.filter instanceof Filter) {
const queryToken = {
...this._customerOrderSearchStore.filter?.getQueryParams(),
processId,
branchId: String(selectedBranch?.id),
};
this._customerOrderSearchStore.setCache({
queryToken,
hits: this._customerOrderSearchStore.hits,
results: this._customerOrderSearchStore.results,
});
await this.updateBreadcrumb(processId, this._customerOrderSearchStore.filter?.getQueryParams());
}
this._customerOrderSearchStore.patchState({ processId });
@@ -212,6 +201,7 @@ export class CustomerOrderSearchResultsComponent extends ComponentStore<Customer
if (!isEqual(cleanQueryParams, this.cleanupQueryParams(this._customerOrderSearchStore.filter.getQueryParams()))) {
this._customerOrderSearchStore.setQueryParams(params);
const queryToken = {
...this._customerOrderSearchStore.filter.getQueryParams(),
processId,
@@ -288,13 +278,13 @@ export class CustomerOrderSearchResultsComponent extends ComponentStore<Customer
...this.cleanupQueryParams(this._customerOrderSearchStore?.filter?.getQueryParams()),
main_qs: this.sharedFilterInputGroupMain?.uiInput?.value,
};
this._customerOrderSearchStore?.setQueryParams(queryParams);
})
);
this._router.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
if (event instanceof NavigationStart) {
this.cacheResults();
this._addScrollPositionToCache();
}
});
@@ -335,18 +325,6 @@ export class CustomerOrderSearchResultsComponent extends ComponentStore<Customer
this._onDestroy$.complete();
this._searchResultSubscription.unsubscribe();
const queryToken = {
...this._customerOrderSearchStore.filter?.getQueryParams(),
processId: this._customerOrderSearchStore.processId,
branchId: String(this._customerOrderSearchStore.selectedBranch?.id),
};
this._customerOrderSearchStore.setCache({
queryToken,
hits: this._customerOrderSearchStore.hits,
results: this._customerOrderSearchStore.results,
});
await this.updateBreadcrumb(this._customerOrderSearchStore.processId, this._customerOrderSearchStore.filter?.getQueryParams());
}
@@ -416,6 +394,20 @@ export class CustomerOrderSearchResultsComponent extends ComponentStore<Customer
}
}
cacheResults() {
const queryToken = {
...this._customerOrderSearchStore.filter?.getQueryParams(),
processId: this._customerOrderSearchStore.processId,
branchId: String(this._customerOrderSearchStore.selectedBranch?.id),
};
this._customerOrderSearchStore.setCache({
queryToken,
hits: this._customerOrderSearchStore.hits,
results: this._customerOrderSearchStore.results,
});
}
getBreadcrumbName(params: Record<string, string>) {
const input = params?.main_qs;
@@ -435,8 +427,8 @@ export class CustomerOrderSearchResultsComponent extends ComponentStore<Customer
search({ filter, clear = false }: { filter?: Filter; clear?: boolean }) {
if (!!filter) {
this.sharedFilterInputGroupMain.cancelAutocomplete();
this._customerOrderSearchStore.setQueryParams(filter?.getQueryParams());
}
this._customerOrderSearchStore.search({ clear });
}

View File

@@ -22,6 +22,7 @@ import { debounceTime, first, map, shareReplay, takeUntil, tap } from 'rxjs/oper
import { GoodsInListItemComponent } from './goods-in-list-item/goods-in-list-item.component';
import { GoodsInListStore } from './goods-in-list.store';
import { PickupShelfInNavigationService } from '@shared/services';
import { CacheService } from '@core/cache';
@Component({
selector: 'page-goods-in-list',
@@ -60,20 +61,21 @@ export class GoodsInListComponent implements OnInit, AfterViewInit, OnDestroy {
private _onDestroy$ = new Subject();
private readonly SCROLL_POSITION_TOKEN = 'GOODS_IN_LIST_SCROLL_POSITION';
constructor(
private _breadcrumb: BreadcrumbService,
private _domainOmsService: DomainOmsService,
public store: GoodsInListStore,
private _router: Router,
private _route: ActivatedRoute,
private readonly _config: Config
private readonly _config: Config,
private _cache: CacheService
) {}
ngOnInit() {
this.store.setTake(Number(this._route.snapshot.queryParams.take ?? 25));
this._route.queryParams.pipe(takeUntil(this._onDestroy$), debounceTime(0)).subscribe(async (params) => {
const scrollPos = Number(params.scroll_position ?? 0);
// Initial Search - Always Search If No Params Are Set
if (
(Object.keys(params).length === 0 || this.store.results.length === 0) &&
@@ -82,7 +84,8 @@ export class GoodsInListComponent implements OnInit, AfterViewInit, OnDestroy {
this.store.search({
cb: () => {
setTimeout(() => {
this.scrollContainer?.scrollTo(scrollPos);
this.scrollContainer?.scrollTo(this._getScrollPositionFromCache());
this._removeScrollPositionFromCache();
}, 0);
},
});
@@ -101,7 +104,8 @@ export class GoodsInListComponent implements OnInit, AfterViewInit, OnDestroy {
this.store.search({
cb: () => {
setTimeout(() => {
this.scrollContainer?.scrollTo(scrollPos);
this.scrollContainer?.scrollTo(this._getScrollPositionFromCache());
this._removeScrollPositionFromCache();
}, 0);
},
});
@@ -117,12 +121,13 @@ export class GoodsInListComponent implements OnInit, AfterViewInit, OnDestroy {
this._onDestroy$.next();
this._onDestroy$.complete();
this._addScrollPositionToCache();
this.updateBreadcrumb(this.store.filter.getQueryParams());
}
cleanupQueryParams(params: Record<string, string> = {}) {
const clean = { ...params };
delete clean['scroll_position'];
delete clean['take'];
delete clean['view'];
@@ -143,6 +148,21 @@ export class GoodsInListComponent implements OnInit, AfterViewInit, OnDestroy {
this.listItems.changes.pipe(takeUntil(this._onDestroy$)).subscribe(() => this.registerEditSscDisabled());
}
private _removeScrollPositionFromCache(): void {
this._cache.delete({ processId: this._config.get('process.ids.goodsIn'), token: this.SCROLL_POSITION_TOKEN });
}
private _addScrollPositionToCache(): void {
this._cache.set<number>(
{ processId: this._config.get('process.ids.goodsIn'), token: this.SCROLL_POSITION_TOKEN },
this.scrollContainer?.scrollPos
);
}
private _getScrollPositionFromCache(): number {
return this._cache.get<number>({ processId: this._config.get('process.ids.goodsIn'), token: this.SCROLL_POSITION_TOKEN });
}
navigateToDetails(orderItem: OrderItemListItemDTO) {
if (this.editSsc) {
return;
@@ -184,7 +204,6 @@ export class GoodsInListComponent implements OnInit, AfterViewInit, OnDestroy {
}
async updateBreadcrumb(queryParams: Record<string, string> | Params = this.store.filter?.getQueryParams()) {
const scroll_position = this.scrollContainer?.scrollPos;
const take = this._route?.snapshot?.queryParams?.take;
if (queryParams) {
@@ -192,7 +211,7 @@ export class GoodsInListComponent implements OnInit, AfterViewInit, OnDestroy {
.getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), ['goods-in', 'list'])
.pipe(first())
.toPromise();
const params = { ...queryParams, scroll_position, take };
const params = { ...queryParams, take };
for (const crumb of crumbs) {
this._breadcrumb.patchBreadcrumb(crumb.id, {

View File

@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { KeyValueDTOOfStringAndString, OrderItemListItemDTO } from '@swagger/oms';
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
@@ -10,6 +10,7 @@ import { GoodsInRemissionPreviewStore } from './goods-in-remission-preview.store
import { Config } from '@core/config';
import { ToasterService } from '@shared/shell';
import { PickupShelfInNavigationService } from '@shared/services';
import { CacheService } from '@core/cache';
@Component({
selector: 'page-goods-in-remission-preview',
@@ -22,8 +23,6 @@ export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
private _pickupShelfInNavigationService = inject(PickupShelfInNavigationService);
@ViewChild(UiScrollContainerComponent) scrollContainer: UiScrollContainerComponent;
private _scrollPosition: number;
items$ = this._store.results$;
itemLength$ = this.items$.pipe(map((items) => items?.length));
@@ -52,14 +51,16 @@ export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
byCompartmentCodeFn = (item: OrderItemListItemDTO) =>
!!item.compartmentInfo ? `${item.compartmentCode}_${item.compartmentInfo}` : item.compartmentCode;
private readonly SCROLL_POSITION_TOKEN = 'REMISSION_PREVIEW_SCROLL_POSITION';
constructor(
private _breadcrumb: BreadcrumbService,
private _store: GoodsInRemissionPreviewStore,
private _route: ActivatedRoute,
private _router: Router,
private _modal: UiModalService,
private _config: Config,
private _toast: ToasterService
private _toast: ToasterService,
private _cache: CacheService
) {}
ngOnInit(): void {
@@ -71,9 +72,25 @@ export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this._onDestroy$.next();
this._onDestroy$.complete();
this._addScrollPositionToCache();
this.updateBreadcrumb();
}
private _removeScrollPositionFromCache(): void {
this._cache.delete({ processId: this._config.get('process.ids.goodsIn'), token: this.SCROLL_POSITION_TOKEN });
}
private _addScrollPositionToCache(): void {
this._cache.set<number>(
{ processId: this._config.get('process.ids.goodsIn'), token: this.SCROLL_POSITION_TOKEN },
this.scrollContainer?.scrollPos
);
}
private _getScrollPositionFromCache(): number {
return this._cache.get<number>({ processId: this._config.get('process.ids.goodsIn'), token: this.SCROLL_POSITION_TOKEN });
}
async createBreadcrumb() {
await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists({
key: this._config.get('process.ids.goodsIn'),
@@ -93,7 +110,6 @@ export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
for (const crumb of crumbs) {
this._breadcrumb.patchBreadcrumb(crumb.id, {
name: crumb.name,
params: { scroll_position: this.scrollContainer?.scrollPos },
});
}
}
@@ -133,14 +149,11 @@ export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
this._store.searchResult$.pipe(takeUntil(this._onDestroy$)).subscribe(async (result) => {
await this.createBreadcrumb();
if (this._scrollPosition) {
this.scrollContainer?.scrollTo(Number(this._scrollPosition ?? 0));
this._scrollPosition = undefined;
}
this.scrollContainer?.scrollTo(this._getScrollPositionFromCache() ?? 0);
this._removeScrollPositionFromCache();
});
}
this._scrollPosition = this._route.snapshot.queryParams?.scroll_position;
this._store.search();
}

View File

@@ -97,7 +97,7 @@
</ng-container>
</div>
<div class="text-right">
<span class="font-bold">{{ packageDetails.package.items }}</span> Exemplare
<span class="font-bold">{{ packageDetails?.package?.items ?? '-' }}</span> Exemplare
</div>
</div>
</div>

View File

@@ -44,7 +44,7 @@
<ng-container *ngIf="expanded[i]">
<ui-form-control label="Abholfachnummer" [clearable]="true" variant="inline">
<input uiInput formControlName="compartmentCode" />
<input pattern="^\d{3,4}_\d{4}_\d{1,5}$" uiInput formControlName="compartmentCode" />
</ui-form-control>
<shared-goods-in-out-order-details-tags

View File

@@ -152,10 +152,7 @@ export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy
name: fb.control(item.product?.name),
ean: fb.control(item.product?.ean, [Validators.required]),
quantity: fb.control({ value: item.quantity + ' x', disabled: true }),
price: fb.control(item.price ? String(item.price).replace('.', ',') : '', [
Validators.required,
Validators.pattern(/^\d+([\,]\d{1,2})?$/),
]),
price: fb.control(this.formatPrice(item?.price), [Validators.required, Validators.pattern(/^\d+([\,]\d{1,2})?$/)]),
currency: fb.control(item.currency),
targetBranch: fb.control({ value: item.targetBranch, disabled: true }),
supplier: fb.control({ value: item.supplier, disabled: true }),
@@ -208,6 +205,15 @@ export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy
return this.omsService.getOrderSource(+orderId).toPromise();
}
formatPrice(price: number) {
if (!price) {
return '';
}
const priceWithTwoDecimalPlaces = price.toFixed(2);
return String(priceWithTwoDecimalPlaces).replace('.', ',');
}
changeEstimatedDeliveryDate(date: Date, item: OrderItemListItemDTO) {
if (!date) {
return;

View File

@@ -10,7 +10,7 @@
<div class="w-28 page-package-list-item__estimated-delivery-date">
{{ package?.estimatedDeliveryDate | date }}
</div>
<div class="w-32 page-package-list-item__items-count">{{ package?.items }} <span class="font-normal">Exemplare</span></div>
<div class="w-32 page-package-list-item__items-count">{{ package?.items ?? '-' }} <span class="font-normal">Exemplare</span></div>
<div class="text-right grow">
<div
class="rounded inline-block px-4 text-white page-package-list-item__arrival-status whitespace-nowrap"