mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Compare commits
50 Commits
hotfix/453
...
fix/4752-P
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a07341c80 | ||
|
|
3a9820aa54 | ||
|
|
30ad99332e | ||
|
|
4b48275910 | ||
|
|
d3e3316459 | ||
|
|
4ef1bd4df6 | ||
|
|
0c2a23e5d2 | ||
|
|
36bd2c1eba | ||
|
|
a38d2eede6 | ||
|
|
f5251d9069 | ||
|
|
2bd21e168a | ||
|
|
3661bf7580 | ||
|
|
9f2a6633f7 | ||
|
|
3c4d0ea56c | ||
|
|
56bb784c83 | ||
|
|
c687570b1f | ||
|
|
afe5d3468a | ||
|
|
65f43d22ee | ||
|
|
67203a8506 | ||
|
|
92e522dedf | ||
|
|
fb46d329dc | ||
|
|
64d0a9fdb9 | ||
|
|
8f47163627 | ||
|
|
49f2a44461 | ||
|
|
a209d59ea9 | ||
|
|
03124d8736 | ||
|
|
a3330263f8 | ||
|
|
89092a5f6e | ||
|
|
42fa108bb6 | ||
|
|
2692588357 | ||
|
|
ec26b5f4c0 | ||
|
|
ff985bda64 | ||
|
|
ca255cb592 | ||
|
|
8df5052c76 | ||
|
|
c78ddb5c8c | ||
|
|
5d84b4a55a | ||
|
|
a6142a5d86 | ||
|
|
fdf50fe11e | ||
|
|
e8bf922a67 | ||
|
|
f202ff5291 | ||
|
|
0c25859b6b | ||
|
|
215cb89aff | ||
|
|
9256a79087 | ||
|
|
f1ff9c6c55 | ||
|
|
3f05e57554 | ||
|
|
2062bf3bab | ||
|
|
2d71a567ff | ||
|
|
547e615522 | ||
|
|
5d904e9d88 | ||
|
|
b7ccde4d44 |
@@ -1021,7 +1021,11 @@ export class DomainCheckoutService {
|
||||
|
||||
//#region Common
|
||||
|
||||
@memorize()
|
||||
// Fix für Ticket #4619 Versand Artikel im Warenkob -> keine Änderung bei Kundendaten erfassen
|
||||
// Auskommentiert, da dieser Aufruf oftmals mit gleichen Parametern aufgerufen wird (ohne ausgewählten Kunden nur ein leeres Objekt bei customerFeatures)
|
||||
// memorize macht keinen deepCompare von Objekten und denkt hier, dass immer der gleiche Return Wert zurückkommt, allerdings ist das hier oft nicht der Fall
|
||||
// und der Decorator memorized dann fälschlicherweise
|
||||
// @memorize()
|
||||
canSetCustomer({
|
||||
processId,
|
||||
customerFeatures,
|
||||
|
||||
@@ -1,37 +1,60 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActionHandler } from '@core/command';
|
||||
import { DomainPrinterService } from '@domain/printer';
|
||||
import { DomainPrinterService, Printer } from '@domain/printer';
|
||||
import { PrintModalComponent, PrintModalData } from '@modal/printer';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { NativeContainerService } from 'native-container';
|
||||
import { OrderItemsContext } from './order-items.context';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
|
||||
@Injectable()
|
||||
export class PrintCompartmentLabelActionHandler extends ActionHandler<OrderItemsContext> {
|
||||
constructor(
|
||||
private uiModal: UiModalService,
|
||||
private domainPrinterService: DomainPrinterService,
|
||||
private nativeContainerService: NativeContainerService
|
||||
private nativeContainerService: NativeContainerService,
|
||||
private _environmentSerivce: EnvironmentService
|
||||
) {
|
||||
super('PRINT_COMPARTMENTLABEL');
|
||||
}
|
||||
printCompartmentLabelHelper(printer: string, orderItemSubsetIds: number[]) {
|
||||
return this.domainPrinterService
|
||||
.printCompartmentLabel({
|
||||
printer,
|
||||
orderItemSubsetIds,
|
||||
})
|
||||
.toPromise();
|
||||
}
|
||||
|
||||
async handler(data: OrderItemsContext): Promise<OrderItemsContext> {
|
||||
await this.uiModal
|
||||
.open({
|
||||
content: PrintModalComponent,
|
||||
config: { showScrollbarY: false },
|
||||
data: {
|
||||
printImmediately: !this.nativeContainerService.isNative,
|
||||
printerType: 'Label',
|
||||
print: (printer) =>
|
||||
this.domainPrinterService
|
||||
.printCompartmentLabel({ printer, orderItemSubsetIds: data.items.map((item) => item.orderItemSubsetId) })
|
||||
.toPromise(),
|
||||
} as PrintModalData,
|
||||
})
|
||||
.afterClosed$.toPromise();
|
||||
const printerList = await this.domainPrinterService.getAvailableLabelPrinters().toPromise();
|
||||
let printer: Printer;
|
||||
|
||||
if (Array.isArray(printerList)) {
|
||||
printer = printerList.find((printer) => printer.selected === true);
|
||||
}
|
||||
if (!printer || this._environmentSerivce.matchTablet()) {
|
||||
await this.uiModal
|
||||
.open({
|
||||
content: PrintModalComponent,
|
||||
config: { showScrollbarY: false },
|
||||
data: {
|
||||
printImmediately: !this._environmentSerivce.matchTablet(),
|
||||
printerType: 'Label',
|
||||
print: (printer) =>
|
||||
this.printCompartmentLabelHelper(
|
||||
printer,
|
||||
data.items.map((item) => item.orderItemSubsetId)
|
||||
),
|
||||
} as PrintModalData,
|
||||
})
|
||||
.afterClosed$.toPromise();
|
||||
} else {
|
||||
await this.printCompartmentLabelHelper(
|
||||
printer.key,
|
||||
data.items.map((item) => item.orderItemSubsetId)
|
||||
);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,45 +6,60 @@ import { UiModalService } from '@ui/modal';
|
||||
import { PrintModalComponent, PrintModalData } from '@modal/printer';
|
||||
import { groupBy } from '@ui/common';
|
||||
import { NativeContainerService } from 'native-container';
|
||||
import { ReceiptDTO } from '@swagger/oms';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
|
||||
@Injectable()
|
||||
export class PrintShippingNoteActionHandler extends ActionHandler<OrderItemsContext> {
|
||||
constructor(
|
||||
private uiModal: UiModalService,
|
||||
private domainPrinterService: DomainPrinterService,
|
||||
private nativeContainerService: NativeContainerService
|
||||
private nativeContainerService: NativeContainerService,
|
||||
private _environmentSerivce: EnvironmentService
|
||||
) {
|
||||
super('PRINT_SHIPPINGNOTE');
|
||||
}
|
||||
|
||||
async printShippingNoteHelper(printer: string, receipts: ReceiptDTO[]) {
|
||||
try {
|
||||
for (const group of groupBy(receipts, (receipt) => receipt?.buyer?.buyerNumber)) {
|
||||
await this.domainPrinterService.printShippingNote({ printer, receipts: group?.items?.map((r) => r?.id) }).toPromise();
|
||||
}
|
||||
return {
|
||||
error: false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
error: true,
|
||||
message: error?.message || error,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async handler(data: OrderItemsContext): Promise<OrderItemsContext> {
|
||||
await this.uiModal
|
||||
.open({
|
||||
content: PrintModalComponent,
|
||||
config: { showScrollbarY: false },
|
||||
data: {
|
||||
printImmediately: !this.nativeContainerService.isNative,
|
||||
printerType: 'Label',
|
||||
print: async (printer) => {
|
||||
try {
|
||||
const receipts = data?.receipts?.filter((r) => r?.receiptType & 1);
|
||||
for (const group of groupBy(receipts, (receipt) => receipt?.buyer?.buyerNumber)) {
|
||||
await this.domainPrinterService.printShippingNote({ printer, receipts: group?.items?.map((r) => r?.id) }).toPromise();
|
||||
}
|
||||
return {
|
||||
error: false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
error: true,
|
||||
message: error?.message || error,
|
||||
};
|
||||
}
|
||||
},
|
||||
} as PrintModalData,
|
||||
})
|
||||
.afterClosed$.toPromise();
|
||||
const printerList = await this.domainPrinterService.getAvailableLabelPrinters().toPromise();
|
||||
const receipts = data?.receipts?.filter((r) => r?.receiptType & 1);
|
||||
let printer: Printer;
|
||||
|
||||
if (Array.isArray(printerList)) {
|
||||
printer = printerList.find((printer) => printer.selected === true);
|
||||
}
|
||||
if (!printer || this._environmentSerivce.matchTablet()) {
|
||||
await this.uiModal
|
||||
.open({
|
||||
content: PrintModalComponent,
|
||||
config: { showScrollbarY: false },
|
||||
data: {
|
||||
printImmediately: !this.nativeContainerService.isNative,
|
||||
printerType: 'Label',
|
||||
print: async (printer) => await this.printShippingNoteHelper(printer, receipts),
|
||||
} as PrintModalData,
|
||||
})
|
||||
.afterClosed$.toPromise();
|
||||
} else {
|
||||
await this.printShippingNoteHelper(printer.key, receipts);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export class PickupShelfOutService extends PickupShelfIOService {
|
||||
);
|
||||
}
|
||||
|
||||
const { orderdate } = args.filter?.getQueryToken()?.filter ?? {};
|
||||
const { orderdate, supplier_id } = args.filter?.getQueryToken()?.filter ?? {};
|
||||
|
||||
return this._abholfachService.AbholfachWarenausgabe({
|
||||
input: {
|
||||
@@ -45,6 +45,7 @@ export class PickupShelfOutService extends PickupShelfIOService {
|
||||
archive: String(true),
|
||||
all_branches: String(true),
|
||||
orderdate,
|
||||
supplier_id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -280,6 +280,11 @@
|
||||
"name": "apps",
|
||||
"data": "M226-160q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19Zm254 0q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19Zm254 0q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19ZM226-414q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19Zm254 0q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19Zm254 0q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19ZM226-668q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19Zm254 0q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19Zm254 0q-28 0-47-19t-19-47q0-28 19-47t47-19q28 0 47 19t19 47q0 28-19 47t-47 19Z",
|
||||
"viewBox": "0 -960 960 960"
|
||||
},
|
||||
{
|
||||
"name": "gift",
|
||||
"data": "M2 21V10H0V4H5.2C5.11667 3.85 5.0625 3.69167 5.0375 3.525C5.0125 3.35833 5 3.18333 5 3C5 2.16667 5.29167 1.45833 5.875 0.875C6.45833 0.291667 7.16667 0 8 0C8.38333 0 8.74167 0.0708333 9.075 0.2125C9.40833 0.354167 9.71667 0.55 10 0.8C10.2833 0.533333 10.5917 0.333333 10.925 0.2C11.2583 0.0666667 11.6167 0 12 0C12.8333 0 13.5417 0.291667 14.125 0.875C14.7083 1.45833 15 2.16667 15 3C15 3.18333 14.9833 3.35417 14.95 3.5125C14.9167 3.67083 14.8667 3.83333 14.8 4H20V10H18V21H2ZM12 2C11.7167 2 11.4792 2.09583 11.2875 2.2875C11.0958 2.47917 11 2.71667 11 3C11 3.28333 11.0958 3.52083 11.2875 3.7125C11.4792 3.90417 11.7167 4 12 4C12.2833 4 12.5208 3.90417 12.7125 3.7125C12.9042 3.52083 13 3.28333 13 3C13 2.71667 12.9042 2.47917 12.7125 2.2875C12.5208 2.09583 12.2833 2 12 2ZM7 3C7 3.28333 7.09583 3.52083 7.2875 3.7125C7.47917 3.90417 7.71667 4 8 4C8.28333 4 8.52083 3.90417 8.7125 3.7125C8.90417 3.52083 9 3.28333 9 3C9 2.71667 8.90417 2.47917 8.7125 2.2875C8.52083 2.09583 8.28333 2 8 2C7.71667 2 7.47917 2.09583 7.2875 2.2875C7.09583 2.47917 7 2.71667 7 3ZM2 6V8H9V6H2ZM9 19V10H4V19H9ZM11 19H16V10H11V19ZM18 8V6H11V8H18Z",
|
||||
"viewBox": "0 0 20 21"
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
5
apps/isa-app/src/assets/images/bookmark_responsive.svg
Normal file
5
apps/isa-app/src/assets/images/bookmark_responsive.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="48" height="51" viewBox="0 0 48 51" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 4.47368C8 2.01878 9.99009 0 12.445 0L43.555 0C46.0099 0 48 2.01878 48 4.47368H8Z" fill="#172062"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 4.445C0 1.99009 1.99009 0 4.445 0L42.7807 0V43.4808C42.7807 46.7878 39.2981 48.9368 36.3423 47.4537L23.376 40.948C22.1212 40.3183 20.6426 40.3186 19.3879 40.9486L6.4397 47.4505C3.48377 48.9348 0 46.7859 0 43.4782L0 4.445Z" fill="#0556B4"/>
|
||||
<rect x="19" y="19" width="18" height="17" fill="#0556B4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 606 B |
@@ -35,7 +35,11 @@
|
||||
</div>
|
||||
|
||||
<div class="branch-actions">
|
||||
<button *ngIf="(branch.id | stockInfo: (inStock$ | async))?.availableQuantity > 0" class="cta-reserve" (click)="reserve(branch)">
|
||||
<button
|
||||
*ngIf="(branch.id | stockInfo: (inStock$ | async))?.availableQuantity > 0 && branch?.isShippingEnabled"
|
||||
class="cta-reserve"
|
||||
(click)="reserve(branch)"
|
||||
>
|
||||
Reservieren
|
||||
</button>
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export class ModalAvailabilitiesComponent {
|
||||
(branch) =>
|
||||
branch &&
|
||||
branch?.isOnline &&
|
||||
branch?.isShippingEnabled &&
|
||||
// branch?.isShippingEnabled && ------ Rausgenommen aufgrund des Tickets #4712
|
||||
branch?.isOrderingEnabled &&
|
||||
branch?.id !== userbranch?.id &&
|
||||
branch?.branchType === 1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="page-article-details__wrapper">
|
||||
<div #detailsContainer class="page-article-details__container px-5" *ngIf="store.item$ | async; let item">
|
||||
<div class="page-article-details__product-details mb-3">
|
||||
<div class="page-article-details__product-bookmark justify-self-end">
|
||||
<div class="page-article-details__product-bookmark flex fixed justify-self-end">
|
||||
<div *ngIf="showArchivBadge$ | async" class="archiv-badge">
|
||||
<button [uiOverlayTrigger]="archivTooltip" class="p-0 m-0 outline-none border-none bg-transparent relative -top-[0.3125rem]">
|
||||
<img src="/assets/images/bookmark_benachrichtigung_archiv.svg" alt="Archiv Badge" />
|
||||
@@ -30,9 +30,9 @@
|
||||
</div>
|
||||
<div *ngIf="showPromotionBadge$ | async" class="promotion-badge">
|
||||
<button [uiOverlayTrigger]="promotionTooltip" class="p-0 m-0 outline-none border-none bg-transparent relative -top-[0.3125rem]">
|
||||
<ui-icon-badge icon="gift" alt="Prämienkatalog Badge"></ui-icon-badge>
|
||||
<shared-icon-badge icon="gift" alt="Prämienkatalog Badge"></shared-icon-badge>
|
||||
<ui-tooltip yPosition="above" xPosition="after" [yOffset]="-11" [xOffset]="-8" #promotionTooltip [closeable]="true">
|
||||
Dieser Artikel befindet sich im Prämienkatalog.
|
||||
Der Artikel ist als Prämie für {{ promotionPoints$ | async }} Punkte erhältlich.
|
||||
</ui-tooltip>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,12 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
|
||||
showSubscriptionBadge$ = this.store.item$.pipe(map((item) => item?.features?.find((i) => i.key === 'PFO')));
|
||||
|
||||
showPromotionBadge$ = this.store.item$.pipe(map((item) => item?.features?.find((i) => i.key === 'Promotion')));
|
||||
hasPromotionFeature$ = this.store.item$.pipe(map((item) => !!item?.features?.find((i) => i.key === 'Promotion')));
|
||||
promotionPoints$ = this.store.item$.pipe(map((item) => item?.redemptionPoints));
|
||||
|
||||
showPromotionBadge$ = combineLatest([this.hasPromotionFeature$, this.promotionPoints$]).pipe(
|
||||
map(([hasPromotionFeature, promotionPoints]) => hasPromotionFeature && promotionPoints > 0)
|
||||
);
|
||||
|
||||
showArchivBadge$ = this.store.item$.pipe(map((item) => item?.features?.find((i) => i.key === 'ARC')));
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import { UiCommonModule } from '@ui/common';
|
||||
import { OrderDeadlinePipeModule } from '@shared/pipes/order-deadline';
|
||||
import { IconModule } from '@shared/components/icon';
|
||||
import { ArticleDetailsTextComponent } from './article-details-text/article-details-text.component';
|
||||
import { IconBadgeComponent } from 'apps/shared/components/icon/src/lib/badge/icon-badge.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -28,6 +29,7 @@ import { ArticleDetailsTextComponent } from './article-details-text/article-deta
|
||||
PipesModule,
|
||||
OrderDeadlinePipeModule,
|
||||
ArticleDetailsTextComponent,
|
||||
IconBadgeComponent,
|
||||
],
|
||||
exports: [ArticleDetailsComponent, ArticleRecommendationsComponent],
|
||||
declarations: [ArticleDetailsComponent, ArticleRecommendationsComponent],
|
||||
|
||||
@@ -155,7 +155,7 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
|
||||
|
||||
const cleanQueryParams = this.cleanupQueryParams(queryParams);
|
||||
|
||||
if (this.route.outlet === 'primary' && processChanged) {
|
||||
if (processChanged) {
|
||||
this.scrollToItem(this._getScrollIndexFromCache());
|
||||
}
|
||||
|
||||
@@ -209,7 +209,6 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
|
||||
if (searchCompleted.state.hits === 1) {
|
||||
const item = searchCompleted.state.items.find((f) => f);
|
||||
const ean = this.route?.snapshot?.params?.ean;
|
||||
const itemId = this.route?.snapshot?.params?.id ? Number(this.route?.snapshot?.params?.id) : item.id; // Nicht zum ersten Item der Liste springen wenn bereits eines selektiert ist
|
||||
|
||||
// Navigation from Cart uses ean
|
||||
if (!!ean) {
|
||||
@@ -224,7 +223,7 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
|
||||
await this._navigationService
|
||||
.getArticleDetailsPath({
|
||||
processId,
|
||||
itemId,
|
||||
itemId: item.id,
|
||||
extras: { queryParams: params },
|
||||
})
|
||||
.navigate();
|
||||
@@ -272,7 +271,7 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
|
||||
}
|
||||
|
||||
private _getScrollIndexFromCache(): number {
|
||||
return this.cache.get<number>({ processId: this.getProcessId(), token: this.SCROLL_INDEX_TOKEN });
|
||||
return this.cache.get<number>({ processId: this.getProcessId(), token: this.SCROLL_INDEX_TOKEN }) ?? 0;
|
||||
}
|
||||
|
||||
scrollToItem(i?: number) {
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
|
||||
<ng-container *ngIf="payer$ | async; let payer">
|
||||
<div *ngIf="showAddresses$ | async" class="flex flex-row items-start justify-between p-5 pt-0">
|
||||
<div class="flex flex-row flex-wrap pr-4" data-address-type="Rechnungsadresse">
|
||||
<div class="mr-3">Rechnungsadresse</div>
|
||||
<div class="font-bold">
|
||||
<div class="flex flex-row flex-wrap pr-4" data-address-type="Rechnungsadresse" data-which="Rechnungsadresse">
|
||||
<div class="mr-3" data-what="title">Rechnungsadresse</div>
|
||||
<div class="font-bold" data-what="address">
|
||||
{{ payer | payerAddress }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,9 +47,9 @@
|
||||
|
||||
<ng-container *ngIf="payer$ | async; let payer">
|
||||
<div *ngIf="showAddresses$ | async" class="flex flex-row items-start justify-between px-5">
|
||||
<div class="flex flex-row flex-wrap pr-4" data-address-type="Lieferadresse">
|
||||
<div class="mr-3">Lieferadresse</div>
|
||||
<div class="font-bold">
|
||||
<div class="flex flex-row flex-wrap pr-4" data-address-type="Lieferadresse" data-which="Lieferadresse">
|
||||
<div class="mr-3" data-what="title">Lieferadresse</div>
|
||||
<div class="font-bold" data-what="address">
|
||||
{{ shippingAddress$ | async | shippingAddress }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,17 +19,14 @@
|
||||
placeholder="Eine Anmerkung hinzufügen"
|
||||
[(ngModel)]="value"
|
||||
[rows]="rows"
|
||||
(ngModelChange)="check()"
|
||||
(blur)="save()"
|
||||
(ngModelChange)="updateValue()"
|
||||
(blur)="updateValue()"
|
||||
></textarea>
|
||||
|
||||
<div class="comment-actions py-4">
|
||||
<button type="reset" class="clear pl-4" *ngIf="!disabled && !!value" (click)="clear(); triggerResize()">
|
||||
<shared-icon icon="close" [size]="24"></shared-icon>
|
||||
</button>
|
||||
<button class="cta-save ml-4" type="submit" *ngIf="!disabled && isDirty" (click)="save()">
|
||||
Speichern
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ export class SpecialCommentComponent implements ControlValueAccessor {
|
||||
|
||||
clear() {
|
||||
this.value = '';
|
||||
this.save();
|
||||
this.updateValue();
|
||||
}
|
||||
|
||||
check() {
|
||||
@@ -80,11 +80,12 @@ export class SpecialCommentComponent implements ControlValueAccessor {
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
save() {
|
||||
updateValue() {
|
||||
this.initialValue = this.value;
|
||||
this.onChange(this.value);
|
||||
this.check();
|
||||
}
|
||||
|
||||
setIsDirty(isDirty: boolean) {
|
||||
this.isDirty = isDirty;
|
||||
this.isDirtyChange.emit(isDirty);
|
||||
|
||||
@@ -228,11 +228,12 @@
|
||||
<div class="absolute left-1/2 bottom-10 inline-grid grid-flow-col gap-4 justify-center transform -translate-x-1/2">
|
||||
<button
|
||||
*ifRole="'Store'"
|
||||
[disabled]="isPrinting$ | async"
|
||||
type="button"
|
||||
class="px-6 py-2 rounded-full border-2 border-solid border-brand text-brand bg-white font-bold text-lg whitespace-nowrap h-14"
|
||||
class="px-6 py-2 rounded-full border-2 border-solid border-brand text-brand bg-white font-bold text-lg whitespace-nowrap h-14 flex flex-row items-center justify-center print-button"
|
||||
(click)="printOrderConfirmation()"
|
||||
>
|
||||
Bestellbestätigung drucken
|
||||
<ui-spinner class="min-h-4 min-w-4" [show]="isPrinting$ | async"> Bestellbestätigung drucken </ui-spinner>
|
||||
</button>
|
||||
|
||||
<button
|
||||
|
||||
@@ -96,6 +96,12 @@ hr {
|
||||
}
|
||||
}
|
||||
|
||||
.print-button {
|
||||
&:disabled {
|
||||
@apply bg-inactive-branch border-solid border-inactive-branch text-white cursor-not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.last {
|
||||
@apply pb-5;
|
||||
}
|
||||
|
||||
@@ -135,6 +135,8 @@ export class CheckoutSummaryComponent implements OnInit, OnDestroy {
|
||||
)
|
||||
);
|
||||
|
||||
isPrinting$ = new BehaviorSubject(false);
|
||||
|
||||
totalPriceCurrency$ = this.displayOrders$.pipe(map((displayOrders) => displayOrders[0]?.items[0]?.price?.value?.currency));
|
||||
|
||||
containsDeliveryOrder$ = this.displayOrders$.pipe(
|
||||
@@ -294,22 +296,9 @@ export class CheckoutSummaryComponent implements OnInit, OnDestroy {
|
||||
if (takeNowOrders.length != 1) return;
|
||||
|
||||
try {
|
||||
for (const takeNowOrder of takeNowOrders) {
|
||||
for (const orderItem of takeNowOrder.items.filter((item) => item.features?.orderType === 'Rücklage')) {
|
||||
await this.omsService
|
||||
.changeOrderStatus(takeNowOrder.id, orderItem.id, orderItem.subsetItems[0]?.id, {
|
||||
processingStatus: 128,
|
||||
})
|
||||
.toPromise();
|
||||
}
|
||||
}
|
||||
|
||||
await this.router.navigate(
|
||||
this._shelfOutNavigationService.detailRoute({
|
||||
processId: Date.now(),
|
||||
item: { orderId: takeNowOrders[0].id, orderNumber: takeNowOrders[0].orderNumber, processingStatus: 128 },
|
||||
}).path
|
||||
);
|
||||
await this.router.navigate(this._shelfOutNavigationService.listRoute({ processId: Date.now() }).path, {
|
||||
queryParams: { main_qs: takeNowOrders[0].orderNumber, filter_supplier_id: '16' },
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -322,28 +311,57 @@ export class CheckoutSummaryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async printOrderConfirmation() {
|
||||
this.isPrinting$.next(true);
|
||||
const orders = await this.displayOrders$.pipe(first()).toPromise();
|
||||
await this.uiModal
|
||||
.open({
|
||||
content: PrintModalComponent,
|
||||
data: {
|
||||
printerType: 'Label',
|
||||
printImmediately: !this.isTablet,
|
||||
print: async (printer) => {
|
||||
try {
|
||||
const result = await this.domainPrinterService.printOrder({ orderIds: orders.map((o) => o.id), printer }).toPromise();
|
||||
this._toaster.open({ type: 'success', message: 'Bestellbestätigung wurde gedruckt' });
|
||||
return result;
|
||||
} catch (error) {
|
||||
this._toaster.open({ type: 'danger', message: 'Fehler beim Drucken der Bestellbestätigung' });
|
||||
}
|
||||
const selectedPrinter = await this.domainPrinterService
|
||||
.getAvailableLabelPrinters()
|
||||
.pipe(
|
||||
first(),
|
||||
map((printers) => {
|
||||
if (Array.isArray(printers)) return printers.find((printer) => printer.selected === true);
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
console.log(selectedPrinter);
|
||||
if (!selectedPrinter || this.isTablet) {
|
||||
await this.uiModal
|
||||
.open({
|
||||
content: PrintModalComponent,
|
||||
data: {
|
||||
printerType: 'Label',
|
||||
printImmediately: !this.isTablet,
|
||||
print: async (printer) => {
|
||||
try {
|
||||
const result = await this.domainPrinterService.printOrder({ orderIds: orders.map((o) => o.id), printer }).toPromise();
|
||||
this._toaster.open({ type: 'success', message: 'Bestellbestätigung wurde gedruckt' });
|
||||
return result;
|
||||
} catch (error) {
|
||||
this._toaster.open({ type: 'danger', message: 'Fehler beim Drucken der Bestellbestätigung' });
|
||||
} finally {
|
||||
this.isPrinting$.next(false);
|
||||
}
|
||||
},
|
||||
} as PrintModalData,
|
||||
config: {
|
||||
panelClass: [],
|
||||
showScrollbarY: false,
|
||||
},
|
||||
} as PrintModalData,
|
||||
config: {
|
||||
panelClass: [],
|
||||
showScrollbarY: false,
|
||||
},
|
||||
})
|
||||
.afterClosed$.toPromise();
|
||||
})
|
||||
.afterClosed$.toPromise();
|
||||
this.isPrinting$.next(false);
|
||||
} else {
|
||||
try {
|
||||
const result = await this.domainPrinterService
|
||||
.printOrder({ orderIds: orders.map((o) => o.id), printer: selectedPrinter.key })
|
||||
.toPromise();
|
||||
this._toaster.open({ type: 'success', message: 'Bestellbestätigung wurde gedruckt' });
|
||||
return result;
|
||||
} catch (error) {
|
||||
this._toaster.open({ type: 'danger', message: 'Fehler beim Drucken der Bestellbestätigung' });
|
||||
} finally {
|
||||
this.isPrinting$.next(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,19 @@
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="page-customer-order-details-item__tracking-details" *ngIf="getOrderItemTrackingData(orderItem); let trackingData">
|
||||
<div class="label">{{ trackingData.length > 1 ? 'Sendungsnummern' : 'Sendungsnummer' }}</div>
|
||||
<ng-container *ngFor="let tracking of trackingData">
|
||||
<ng-container *ngIf="tracking.trackingProvider === 'DHL' && !isNative; else noTrackingLink">
|
||||
<a class="value text-[#0556B4]" [href]="getTrackingNumberLink(tracking.trackingNumber)" target="_blank"
|
||||
>{{ tracking.trackingProvider }}: {{ tracking.trackingNumber }}</a
|
||||
>
|
||||
</ng-container>
|
||||
<ng-template #noTrackingLink>
|
||||
<p class="value">{{ tracking.trackingProvider }}: {{ tracking.trackingNumber }}</p>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<hr class="border-[#EDEFF0] border-t-2 my-4" />
|
||||
|
||||
|
||||
@@ -55,6 +55,18 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
.page-customer-order-details-item__tracking-details {
|
||||
@apply flex gap-x-7;
|
||||
|
||||
.label {
|
||||
@apply w-[8.125rem];
|
||||
}
|
||||
|
||||
.value {
|
||||
@apply flex flex-row items-center font-bold;
|
||||
}
|
||||
}
|
||||
|
||||
.page-customer-order-details-item__comment {
|
||||
textarea {
|
||||
@apply w-full flex-grow rounded bg-[#EDEFF0] border-[#AEB7C1] border border-solid outline-none text-p2 p-4;
|
||||
|
||||
@@ -18,6 +18,7 @@ import { isEqual } from 'lodash';
|
||||
import { combineLatest, NEVER, Subject, Observable } from 'rxjs';
|
||||
import { catchError, filter, first, map, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||
import { CustomerOrderDetailsStore } from '../customer-order-details.store';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
|
||||
export interface CustomerOrderDetailsItemComponentState {
|
||||
orderItem?: OrderItemListItemDTO;
|
||||
@@ -142,11 +143,16 @@ export class CustomerOrderDetailsItemComponent extends ComponentStore<CustomerOr
|
||||
|
||||
private _onDestroy$ = new Subject();
|
||||
|
||||
get isNative() {
|
||||
return this._environment.isNative();
|
||||
}
|
||||
|
||||
constructor(
|
||||
private _store: CustomerOrderDetailsStore,
|
||||
private _domainReceiptService: DomainReceiptService,
|
||||
private _omsService: DomainOmsService,
|
||||
private _cdr: ChangeDetectorRef
|
||||
private _cdr: ChangeDetectorRef,
|
||||
private _environment: EnvironmentService
|
||||
) {
|
||||
super({
|
||||
more: false,
|
||||
@@ -231,6 +237,35 @@ export class CustomerOrderDetailsItemComponent extends ComponentStore<CustomerOr
|
||||
return orderItems?.find((orderItem) => orderItem.data.id === orderItemListItem.orderItemId)?.data?.features?.orderType;
|
||||
}
|
||||
|
||||
getOrderItemTrackingData(orderItemListItem: OrderItemListItemDTO): Array<{ trackingProvider: string; trackingNumber: string }> {
|
||||
const orderItems = this.order?.items;
|
||||
const completeTrackingInformation = orderItems
|
||||
?.find((orderItem) => orderItem.data.id === orderItemListItem.orderItemId)
|
||||
?.data?.subsetItems?.find((subsetItem) => subsetItem.id === orderItemListItem.orderItemSubsetId)?.data?.trackingNumber;
|
||||
|
||||
if (!completeTrackingInformation) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Beispielnummer: 'DHL: 124124' - Bei mehreren Tracking-Informationen muss noch ein Splitter eingebaut werden, je nach dem welcher Trenner verwendet wird
|
||||
const trackingInformationPairs = completeTrackingInformation.split(':').map((obj) => obj.trim());
|
||||
return this._trackingTransformationHelper(trackingInformationPairs);
|
||||
}
|
||||
|
||||
// Macht aus einem String Array ein Array von Objekten mit den keys trackingProvider und trackingNumber
|
||||
private _trackingTransformationHelper(trackingInformationPairs: string[]): Array<{ trackingProvider: string; trackingNumber: string }> {
|
||||
return trackingInformationPairs.reduce((acc, current, index, array) => {
|
||||
if (index % 2 === 0) {
|
||||
acc.push({ trackingProvider: current, trackingNumber: array[index + 1] });
|
||||
}
|
||||
return acc;
|
||||
}, [] as { trackingProvider: string; trackingNumber: string }[]);
|
||||
}
|
||||
|
||||
getTrackingNumberLink(trackingNumber: string) {
|
||||
return `https://www.dhl.de/de/privatkunden/dhl-sendungsverfolgung.html?piececode=${trackingNumber}`;
|
||||
}
|
||||
|
||||
triggerResize() {
|
||||
this.autosize.reset();
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ export class CustomerOrderDetailsComponent implements OnInit, AfterViewInit, OnD
|
||||
if (action.command.includes('ARRIVED')) {
|
||||
navigateTo = await this.arrivedActionNavigation();
|
||||
}
|
||||
if (action.command.includes('PRINT_PRICEDIFFQRCODELABEL')) {
|
||||
if (action.command.includes('PRINT_PRICEDIFFQRCODELABEL') || action.command.includes('BACKTOSTOCK')) {
|
||||
navigateTo = 'main';
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
(onInit)="addAddressGroup($event)"
|
||||
(onDestroy)="removeAddressGroup()"
|
||||
[data]="data?.address"
|
||||
[tabIndexStart]="nameFormBlock?.tabIndexEnd + 1"
|
||||
[requiredMarks]="addressRequiredMarks"
|
||||
[validatorFns]="addressValidatorFns"
|
||||
[readonly]="readonly"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { ChangeDetectorRef, Directive, OnDestroy, OnInit, ViewChild, inject } from '@angular/core';
|
||||
import { AbstractControl, AsyncValidatorFn, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { AbstractControl, AsyncValidatorFn, UntypedFormControl, UntypedFormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { AddressDTO, CustomerDTO, CustomerInfoDTO, PayerDTO, ShippingAddressDTO } from '@swagger/crm';
|
||||
import { AddressDTO, CustomerDTO, PayerDTO, ShippingAddressDTO } from '@swagger/crm';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiValidators } from '@ui/validators';
|
||||
import { isNull, merge } from 'lodash';
|
||||
import { isNull } from 'lodash';
|
||||
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
|
||||
import {
|
||||
first,
|
||||
@@ -106,7 +106,8 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.updateBreadcrumb(this.latestProcessId, this.formData);
|
||||
// Fix für #4676 - Breadcrumb wurde beim Schließen des Prozesses neu erstellt und nicht korrekt gelöscht
|
||||
// this.updateBreadcrumb(this.latestProcessId, this.formData);
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
this.busy$.complete();
|
||||
@@ -189,6 +190,47 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
minBirthDateValidator = (): ValidatorFn => {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
const minAge = 18; // 18 years
|
||||
|
||||
if (!control.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const controlBirthDate = new Date(control.value);
|
||||
const minBirthDate = new Date();
|
||||
minBirthDate.setFullYear(minBirthDate.getFullYear() - minAge);
|
||||
|
||||
// Check if customer is over 18 years old
|
||||
if (this._checkIfAgeOver18(controlBirthDate, minBirthDate)) {
|
||||
return null;
|
||||
} else {
|
||||
return { minBirthDate: `Teilnahme ab ${minAge} Jahren` };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
private _checkIfAgeOver18(inputDate: Date, minBirthDate: Date): boolean {
|
||||
// Check year
|
||||
if (inputDate.getFullYear() < minBirthDate.getFullYear()) {
|
||||
return true;
|
||||
}
|
||||
// Check Year + Month
|
||||
else if (inputDate.getFullYear() === minBirthDate.getFullYear() && inputDate.getMonth() < minBirthDate.getMonth()) {
|
||||
return true;
|
||||
}
|
||||
// Check Year + Month + Day
|
||||
else if (
|
||||
inputDate.getFullYear() === minBirthDate.getFullYear() &&
|
||||
inputDate.getMonth() === minBirthDate.getMonth() &&
|
||||
inputDate.getDate() <= minBirthDate.getDate()
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
emailExistsValidator: AsyncValidatorFn = (control) => {
|
||||
return of(control.value).pipe(
|
||||
tap((_) => this.customerExists$.next(false)),
|
||||
@@ -377,7 +419,7 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
} catch (error) {
|
||||
this.form.enable();
|
||||
setTimeout(() => {
|
||||
this.addressFormBlock.setAddressValidationError(error.error.invalidProperties);
|
||||
this.deviatingDeliveryAddressFormBlock.setAddressValidationError(error.error.invalidProperties);
|
||||
}, 10);
|
||||
|
||||
return;
|
||||
|
||||
@@ -70,7 +70,7 @@ export class CreateP4MCustomerComponent extends AbstractCreateCustomer implement
|
||||
|
||||
agbValidatorFns = [Validators.requiredTrue];
|
||||
|
||||
birthDateValidatorFns = [Validators.required];
|
||||
birthDateValidatorFns = [];
|
||||
|
||||
existingCustomer$: Observable<CustomerInfoDTO | null>;
|
||||
|
||||
@@ -138,6 +138,7 @@ export class CreateP4MCustomerComponent extends AbstractCreateCustomer implement
|
||||
|
||||
initMarksAndValidators() {
|
||||
this.asyncLoyaltyCardValidatorFn = [this.checkLoyalityCardValidator];
|
||||
this.birthDateValidatorFns = [Validators.required, this.minBirthDateValidator()];
|
||||
if (this._customerType === 'webshop') {
|
||||
this.emailRequiredMark = true;
|
||||
this.emailValidatorFn = [Validators.required, Validators.email, validateEmail];
|
||||
|
||||
@@ -22,7 +22,7 @@ export class UpdateP4MWebshopCustomerComponent extends AbstractCreateCustomer im
|
||||
|
||||
agbValidatorFns = [Validators.requiredTrue];
|
||||
|
||||
birthDateValidatorFns = [Validators.required];
|
||||
birthDateValidatorFns = [Validators.required, this.minBirthDateValidator()];
|
||||
|
||||
nameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
|
||||
|
||||
@@ -5,3 +5,7 @@
|
||||
.action-wrapper {
|
||||
@apply grid grid-flow-col gap-4 justify-center my-6 fixed bottom-24 inset-x-0;
|
||||
}
|
||||
|
||||
.annotation-layout {
|
||||
@apply col-span-2;
|
||||
}
|
||||
|
||||
@@ -3,33 +3,7 @@
|
||||
</div>
|
||||
<ng-container *ngIf="packageDetails$ | async; else loader; let packageDetails" (sharedOnInit)="calculateListHeight()">
|
||||
<div class="bg-background-liste">
|
||||
<div #handlungsAnweisung [ngSwitch]="packageDetails.package.arrivalStatus | arrivalStatus">
|
||||
<div class="bg-white" *ngSwitchCase="'Falsche Filiale'">
|
||||
<p class="text-center text-xl py-10">
|
||||
Stellen Sie dieses Packstück für die andere Filiale bereit. <br />
|
||||
Der Spediteur holt es zum nächstmöglichen Zeitpunkt ab.
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white" *ngSwitchCase="'Offen'">
|
||||
<p class="text-center text-xl py-10" *ngIf="!(childActions$ | async)">
|
||||
Können Sie sich erinnern, dass Sie dieses Packstück <br />
|
||||
ausgepackt haben?
|
||||
</p>
|
||||
<p class="text-center text-xl py-10" *ngIf="!!(childActions$ | async)">
|
||||
Prüfen Sie bitte stichprobenartig den Filialbestand des <br />
|
||||
dargestellten Artikels. Ist der angezeigte Filialbestand <br />
|
||||
korrekt?
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white" *ngSwitchCase="'Fehlt'">
|
||||
<p class="text-center text-xl py-10">
|
||||
Prüfen Sie bitte stichprobenartig den Filialbestand <br />
|
||||
des dargestellten Artikels. Ist der angezeigte Filialbestand <br />
|
||||
korrekt?
|
||||
</p>
|
||||
</div>
|
||||
<div class="pt-3" *ngSwitchDefault></div>
|
||||
</div>
|
||||
<div class="bg-white text-center text-xl py-10" [innerText]="packageDetails?.package?.features?.['description'] ?? ''"></div>
|
||||
|
||||
<div class="bg-white rounded-t shadow-card grid grid-flow-row p-4 gap-2">
|
||||
<div class="grid grid-cols-6">
|
||||
@@ -38,7 +12,7 @@
|
||||
<span *ngIf="packageDetails.package.packageNumber && packageDetails.package.deliveryNoteNumber"> | </span>
|
||||
{{ packageDetails.package.deliveryNoteNumber }}
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
<div class="col-span-3" [class.annotation-layout]="packageDetails?.package?.features?.['annotation']">
|
||||
<ng-container *ngIf="packageDetails.package.arrivalStatus !== 8; else irrlauferTmplt">
|
||||
Filialstopp
|
||||
<span class="font-bold ml-2">
|
||||
@@ -52,7 +26,7 @@
|
||||
</span>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div data-which="Statusmeldung" class="text-right" *ngIf="!packageDetails?.package?.features?.['annotation']; else annotationTmpl">
|
||||
<ng-container *ngIf="(packageDetails.package.arrivalStatus | arrivalStatus) === 'Fehlt'">
|
||||
<button
|
||||
class="isa-icon-button mr-2"
|
||||
@@ -78,10 +52,16 @@
|
||||
<div
|
||||
class="isa-label text-white font-bold page-package-details__arrival-status"
|
||||
[class]="packageDetails.package.arrivalStatus | arrivalStatusColorClass"
|
||||
data-what="arrival-status"
|
||||
>
|
||||
{{ packageDetails.package.arrivalStatus | arrivalStatus }}
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #annotationTmpl>
|
||||
<div class="page-package-details__annotation text-right text-[#5A728A] col-span-2" data-what="annotation">
|
||||
{{ packageDetails?.package?.features?.['annotation'] }}
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="grid grid-cols-6">
|
||||
<div class="col-span-2">
|
||||
|
||||
@@ -148,7 +148,7 @@ export class PackageDetailsComponent {
|
||||
|
||||
@HostListener('window:resize')
|
||||
calculateListHeight() {
|
||||
const handlungsAnweisungHeight = this.handlungsAnweisung?.nativeElement.offsetHeight;
|
||||
const handlungsAnweisungHeight = this.handlungsAnweisung?.nativeElement?.offsetHeight ?? 0;
|
||||
const windowHeight = window.innerHeight;
|
||||
this.detailsListHeight = windowHeight - handlungsAnweisungHeight - 516;
|
||||
this._cdr.markForCheck();
|
||||
|
||||
@@ -5,14 +5,13 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { NavigationRoute } from '@shared/services';
|
||||
import { DBHOrderItemListItemDTO, KeyValueDTOOfStringAndString } from '@swagger/oms';
|
||||
import { DBHOrderItemListItemDTO, KeyValueDTOOfStringAndString, ListResponseArgsOfDBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { Observable } from 'rxjs';
|
||||
import { RunCheckTrigger } from './trigger';
|
||||
import { OrderItemsContext } from '@domain/oms';
|
||||
import { ActionHandlerService } from './services/action-handler.service';
|
||||
import { Config } from '@core/config';
|
||||
import { debounce } from '@utils/common';
|
||||
|
||||
export type GetNameForBreadcrumbData = {
|
||||
processId: number;
|
||||
@@ -117,31 +116,8 @@ export abstract class PickupShelfBaseComponent implements OnInit {
|
||||
return queryParams;
|
||||
}
|
||||
|
||||
regsiterFetchListResponseHandler() {
|
||||
this.listStore.fetchListResponse$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async ({ processId, queryParams, response }) => {
|
||||
/**
|
||||
* Wenn die Suche erfolgreich war, wird der Benutzer auf die Liste oder Detailseite des gefundenen Artikels weitergeleitet.
|
||||
*/
|
||||
const filterQueryParams = this.listStore.filter.getQueryParams();
|
||||
|
||||
// Only Update QueryParams if the user is already on the details, edit or history page
|
||||
// const view: string = this.activatedRoute.snapshot.data.view;
|
||||
// if (['filter', 'details', 'edit', 'history'].includes(view)) {
|
||||
// await this.router.navigate([], { queryParams: { ...queryParams, ...filterQueryParams }, skipLocationChange: true });
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (response.hits === 1) {
|
||||
const detailsPath = await this.getPathForDetail(response.result[0]).pipe(take(1)).toPromise();
|
||||
await this.router.navigate(detailsPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...detailsPath.queryParams } });
|
||||
} else if (response.hits > 1) {
|
||||
const listPath = await this.getPathFoListBreadcrumb({ processId, queryParams });
|
||||
await this.router.navigate(listPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...listPath.queryParams } });
|
||||
} else {
|
||||
await this.router.navigate([], { queryParams: { ...queryParams, ...filterQueryParams } });
|
||||
}
|
||||
});
|
||||
}
|
||||
// Fix Ticket #4688 Navigation behaves different based on section PickUpShelfOut and PickUpShelfIn
|
||||
abstract regsiterFetchListResponseHandler(): void | Promise<void>;
|
||||
|
||||
/**
|
||||
* Sucht die Breadcrumb anhand des Tags.
|
||||
|
||||
@@ -43,6 +43,7 @@ export abstract class PickupShelfDetailsBaseComponent {
|
||||
this.store.resetCoverItems();
|
||||
}
|
||||
this.store.fetchOrder({ orderId: Number(params.orderId) });
|
||||
|
||||
this.store.fetchOrderItems({
|
||||
orderNumber: params.orderNumber ? decodeURIComponent(params.orderNumber) : undefined,
|
||||
compartmentCode: params.compartmentCode ? decodeURIComponent(params.compartmentCode) : undefined,
|
||||
@@ -124,6 +125,7 @@ export abstract class PickupShelfDetailsBaseComponent {
|
||||
processingStatus: updatedItem.processingStatus,
|
||||
compartmentCode: updatedItem.compartmentCode,
|
||||
compartmentInfo: updatedItem.compartmentInfo,
|
||||
quantity: updatedItem.quantity,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -36,12 +36,22 @@
|
||||
|
||||
<page-pickup-shelf-details-tags class="mb-px-2" *ngIf="showTagsComponent$ | async"></page-pickup-shelf-details-tags>
|
||||
|
||||
<page-pickup-shelf-details-covers
|
||||
*ngIf="(coverOrderItems$ | async)?.length > 0"
|
||||
[coverItems]="coverOrderItems$ | async"
|
||||
[selectedOrderItem]="selectedItem$ | async"
|
||||
(coverClick)="coverClick($event)"
|
||||
></page-pickup-shelf-details-covers>
|
||||
<ng-container *ngIf="fetchingCoverItems$ | async; else coverItemsTmpl">
|
||||
<div class="bg-white grid grid-flow-col gap-5 justify-center items-center h-40">
|
||||
<shared-skeleton-loader class="h-16 w-12"></shared-skeleton-loader>
|
||||
<shared-skeleton-loader class="h-16 w-12"></shared-skeleton-loader>
|
||||
<shared-skeleton-loader class="h-16 w-12"></shared-skeleton-loader>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #coverItemsTmpl>
|
||||
<page-pickup-shelf-details-covers
|
||||
*ngIf="(coverOrderItems$ | async)?.length > 0"
|
||||
[coverItems]="coverOrderItems$ | async"
|
||||
[selectedOrderItem]="selectedItem$ | async"
|
||||
(coverClick)="coverClick($event)"
|
||||
></page-pickup-shelf-details-covers>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<div class="page-pickup-shelf-in-details__action-wrapper">
|
||||
|
||||
@@ -10,13 +10,15 @@ import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { OnInitDirective } from '@shared/directives/element-lifecycle';
|
||||
import { PickupShelfInNavigationService } from '@shared/services';
|
||||
import { BehaviorSubject, asapScheduler, combineLatest } from 'rxjs';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, map, shareReplay } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { DBHOrderItemListItemDTO, KeyValueDTOOfStringAndString } from '@swagger/oms';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { RunCheckTrigger } from '../../trigger';
|
||||
import { PickUpShelfDetailsItemsGroupComponent } from '../../shared/pickup-shelf-details-items-group/pickup-shelf-details-items-group.component';
|
||||
import { isEqual } from 'lodash';
|
||||
import { SkeletonLoaderComponent } from '@shared/components/loader';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-in-details',
|
||||
@@ -37,6 +39,7 @@ import { PickUpShelfDetailsItemsGroupComponent } from '../../shared/pickup-shelf
|
||||
PickupShelfAddToPreviousCompartmentCodeLabelPipe,
|
||||
UiSpinnerModule,
|
||||
OnInitDirective,
|
||||
SkeletonLoaderComponent,
|
||||
],
|
||||
})
|
||||
export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseComponent implements OnInit, AfterViewInit {
|
||||
@@ -49,16 +52,16 @@ export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseCompone
|
||||
|
||||
order$ = this.store.order$;
|
||||
|
||||
orderItems$ = this.store.orderItems$.pipe(shareReplay());
|
||||
orderItems$ = this.store.orderItems$.pipe(shareReplay(1));
|
||||
|
||||
noOrderItemsFound$ = this.store.noOrderItemsFound$;
|
||||
|
||||
fetching$ = this.store.fetchingOrder$;
|
||||
fetchingOrder$ = this.store.fetchingOrder$;
|
||||
fetchingItems$ = this.store.fetchingOrderItems$;
|
||||
fetchingCoverItems$ = this.store.fetchingCoverOrderItems$;
|
||||
|
||||
viewFetching$ = combineLatest([this.fetching$, this.fetchingItems$, this.fetchingCoverItems$]).pipe(
|
||||
map(([fetching, fetchingItems, fetchingCoverItems]) => fetching || fetchingItems || fetchingCoverItems)
|
||||
viewFetching$ = combineLatest([this.fetchingItems$, this.orderItems$]).pipe(
|
||||
map(([fetchingItems, orderItems]) => fetchingItems && orderItems.length === 0)
|
||||
);
|
||||
|
||||
selectedCompartmentInfo = this.store.selectedCompartmentInfo;
|
||||
@@ -102,7 +105,7 @@ export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseCompone
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
combineLatest([this._activatedRoute.params, this.orderItems$])
|
||||
combineLatest([this._activatedRoute.params.pipe(distinctUntilChanged(isEqual)), this.orderItems$.pipe(distinctUntilChanged(isEqual))])
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(([params, items]) => {
|
||||
const orderItemSubsetId = +params?.orderItemSubsetId;
|
||||
@@ -114,9 +117,15 @@ export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseCompone
|
||||
if (!!selectedItem && this.store.selectPreviousSelectedOrderItemSubsetId !== orderItemSubsetId) {
|
||||
this.store.setPreviousSelectedOrderItemSubsetId(orderItemSubsetId); // Wichtig das die ID im Store vorhanden bleibt um z.B. für die Filter eine zurücknavigation zu ermöglichen
|
||||
this.store.selectOrderItem(selectedItem, true); // Wird automatisch unselected wenn die Details Seite verlassen wird
|
||||
this.store.fetchCoverOrderItems();
|
||||
}
|
||||
});
|
||||
|
||||
// Fix #4696 - Always Fetch Cover Order Items
|
||||
this._activatedRoute.params.pipe(distinctUntilChanged(isEqual), takeUntilDestroyed(this.destroyRef)).subscribe((_) => {
|
||||
if (!this.store.coverOrderItems || this.store.coverOrderItems.length === 0) {
|
||||
this.store.fetchCoverOrderItems();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
@@ -141,11 +150,14 @@ export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseCompone
|
||||
try {
|
||||
this.changeActionLoader$.next(action.command);
|
||||
this.store.setDisableHeaderStatusDropdown(true);
|
||||
|
||||
const context = await this.execAction({ action, latestCompartmentCode, latestCompartmentInfo });
|
||||
|
||||
if (!!context) {
|
||||
if (action.command.includes('ARRIVED') || action.command.includes('PRINT_PRICEDIFFQRCODELABEL')) {
|
||||
if (
|
||||
action.command.includes('ARRIVED') ||
|
||||
action.command.includes('PRINT_PRICEDIFFQRCODELABEL') ||
|
||||
action.command.includes('BACKTOSTOCK')
|
||||
) {
|
||||
asapScheduler.schedule(async () => {
|
||||
await this.navigateBasedOnCurrentView();
|
||||
}, 100);
|
||||
@@ -210,17 +222,17 @@ export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseCompone
|
||||
updateDate({ date, type }: { date: Date; type?: 'delivery' | 'pickup' | 'preferred' }) {
|
||||
switch (type) {
|
||||
case 'delivery':
|
||||
this.store.orderItems.forEach((item) =>
|
||||
this.store.selectedOrderItems.forEach((item) =>
|
||||
this.store.patchOrderItemSubset({ item, changes: { estimatedShippingDate: date.toISOString() } })
|
||||
);
|
||||
break;
|
||||
case 'pickup':
|
||||
this.store.orderItems.forEach((item) =>
|
||||
this.store.selectedOrderItems.forEach((item) =>
|
||||
this.store.patchOrderItemSubset({ item, changes: { compartmentStop: date.toISOString() } })
|
||||
);
|
||||
break;
|
||||
case 'preferred':
|
||||
this.store.orderItems.forEach((item) =>
|
||||
this.store.selectedOrderItems.forEach((item) =>
|
||||
this.store.patchOrderItemSubset({ item, changes: { preferredPickUpDate: date.toISOString() } })
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<shared-goods-in-out-order-edit
|
||||
*ngIf="store.orderItems$ | async; let items"
|
||||
(navigation)="navigateToShelfInDetailsPage($event)"
|
||||
[items]="items"
|
||||
></shared-goods-in-out-order-edit>
|
||||
<ng-container *ngIf="store.selectedOrderItem$ | async; let item">
|
||||
<shared-goods-in-out-order-edit
|
||||
*ngIf="item"
|
||||
(navigation)="navigateToShelfInDetailsPage($event)"
|
||||
[items]="[item]"
|
||||
></shared-goods-in-out-order-edit>
|
||||
</ng-container>
|
||||
|
||||
@@ -20,15 +20,23 @@ export class PickupShelfInEditComponent extends PickupShelfDetailsBaseComponent
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.listStore;
|
||||
}
|
||||
|
||||
async navigateToShelfInDetailsPage(changes?: Partial<DBHOrderItemListItemDTO>) {
|
||||
const orderId = (await this.store.orderItems$.pipe(first()).toPromise())?.find((_) => true)?.orderId;
|
||||
const orderNumber = this.activatedRoute?.snapshot?.params?.orderNumber;
|
||||
const compartmentCode = changes?.compartmentCode ?? this.activatedRoute?.snapshot?.params?.compartmentCode;
|
||||
const orderNumber = decodeURIComponent(this.activatedRoute?.snapshot?.params?.orderNumber);
|
||||
let compartmentCode = changes?.compartmentCode ?? this.activatedRoute?.snapshot?.params?.compartmentCode;
|
||||
const processingStatus = changes?.processingStatus ?? this.activatedRoute.snapshot.params.orderItemProcessingStatus;
|
||||
const compartmentInfo = changes?.compartmentInfo ?? this.activatedRoute.snapshot.params.compartmentInfo;
|
||||
let compartmentInfo = changes?.compartmentInfo ?? this.activatedRoute.snapshot.params.compartmentInfo;
|
||||
const item = this.store?.selectedOrderItem;
|
||||
|
||||
if (compartmentCode) {
|
||||
compartmentCode = decodeURIComponent(compartmentCode);
|
||||
}
|
||||
|
||||
if (compartmentInfo) {
|
||||
compartmentInfo = decodeURIComponent(compartmentInfo);
|
||||
}
|
||||
|
||||
await this.router.navigate(
|
||||
this.shelfInNavigation.detailRoute({
|
||||
@@ -38,7 +46,7 @@ export class PickupShelfInEditComponent extends PickupShelfDetailsBaseComponent
|
||||
compartmentCode,
|
||||
processingStatus,
|
||||
compartmentInfo,
|
||||
orderItemSubsetId: this.store?.selectPreviousSelectedOrderItemSubsetId,
|
||||
orderItemSubsetId: item?.orderItemSubsetId,
|
||||
},
|
||||
side: this.side,
|
||||
}).path,
|
||||
|
||||
@@ -16,6 +16,7 @@ import { map, take } from 'rxjs/operators';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { FilterAutocompleteProvider } from '@shared/components/filter';
|
||||
import { PickUpShelfInAutocompleteProvider } from './providers/pickup-shelf-in-autocomplete.provider';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-in',
|
||||
@@ -96,6 +97,10 @@ export class PickupShelfInComponent extends PickupShelfBaseComponent {
|
||||
|
||||
const order = await this.detailsStore.order$.pipe(take(1)).toPromise();
|
||||
|
||||
if (!order) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (order?.orderNumber) {
|
||||
return order?.orderNumber;
|
||||
}
|
||||
@@ -110,6 +115,12 @@ export class PickupShelfInComponent extends PickupShelfBaseComponent {
|
||||
const orderItemSubsetId = this.detailsStore.orderItemSubsetId;
|
||||
const compartmentInfo = this.detailsStore.compartmentInfo;
|
||||
|
||||
// Ticket #4692 - Wenn keine Order vorhanden ist, dann soll Breadcrumb nicht erstellt werden
|
||||
// Dies kann z.B. passieren bei Datenbankproblemen wenn das Fetchen der Order sehr lange braucht
|
||||
if (!order) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this._pickupShelfInNavigationService.detailRoute({
|
||||
item: {
|
||||
orderId: order?.id,
|
||||
@@ -205,4 +216,23 @@ export class PickupShelfInComponent extends PickupShelfBaseComponent {
|
||||
async getNameForHistoryBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
|
||||
return 'Historie';
|
||||
}
|
||||
|
||||
async regsiterFetchListResponseHandler() {
|
||||
this.listStore.fetchListResponse$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async ({ processId, queryParams, response }) => {
|
||||
/**
|
||||
* Wenn die Suche erfolgreich war, wird der Benutzer auf die Liste oder Detailseite des gefundenen Artikels weitergeleitet.
|
||||
*/
|
||||
const filterQueryParams = this.listStore.filter.getQueryParams();
|
||||
|
||||
if (response.hits === 1) {
|
||||
const detailsPath = await this.getPathForDetail(response.result[0]).pipe(take(1)).toPromise();
|
||||
await this.router.navigate(detailsPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...detailsPath.queryParams } });
|
||||
} else if (response.hits > 1) {
|
||||
const listPath = await this.getPathFoListBreadcrumb({ processId, queryParams });
|
||||
await this.router.navigate(listPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...listPath.queryParams } });
|
||||
} else {
|
||||
await this.router.navigate([], { queryParams: { ...queryParams, ...filterQueryParams } });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,9 @@ export class PickupShelfOutDetailsComponent extends PickupShelfDetailsBaseCompon
|
||||
|
||||
order$ = this.store.order$;
|
||||
|
||||
groupedItems$: Observable<Array<{ type: string; items: DBHOrderItemListItemDTO[] }>> = this.store.orderItems$.pipe(
|
||||
orderItems$ = this.store.orderItems$;
|
||||
|
||||
groupedItems$: Observable<Array<{ type: string; items: DBHOrderItemListItemDTO[] }>> = this.orderItems$.pipe(
|
||||
map((items) => {
|
||||
const groups: Array<{ type: string; items: DBHOrderItemListItemDTO[] }> = [];
|
||||
|
||||
@@ -66,10 +68,12 @@ export class PickupShelfOutDetailsComponent extends PickupShelfDetailsBaseCompon
|
||||
})
|
||||
);
|
||||
|
||||
fetching$ = this.store.fetchingOrder$;
|
||||
fetchingOrder$ = this.store.fetchingOrder$;
|
||||
fetchingItems$ = this.store.fetchingOrderItems$;
|
||||
|
||||
viewFetching$ = combineLatest([this.fetching$, this.fetchingItems$]).pipe(map(([fetching, fetchingItems]) => fetching || fetchingItems));
|
||||
viewFetching$ = combineLatest([this.orderItems$, this.fetchingItems$]).pipe(
|
||||
map(([orderItems, fetchingItems]) => orderItems?.length === 0 && fetchingItems)
|
||||
);
|
||||
|
||||
selectedCompartmentInfo = this.store.selectedCompartmentInfo;
|
||||
|
||||
@@ -84,7 +88,7 @@ export class PickupShelfOutDetailsComponent extends PickupShelfDetailsBaseCompon
|
||||
|
||||
addToPreviousCompartmentAction$ = this.store.addToPreviousCompartmentAction$;
|
||||
|
||||
mainActions$ = this.store.mainActions$;
|
||||
mainActions$ = this.store.mainShelfOutActions$;
|
||||
|
||||
trackByFnGroupDBHOrderItemListItemDTO = (index: number, group: { type: string; items: DBHOrderItemListItemDTO[] }) => group.type;
|
||||
|
||||
@@ -105,7 +109,11 @@ export class PickupShelfOutDetailsComponent extends PickupShelfDetailsBaseCompon
|
||||
const context = await this.execAction({ action });
|
||||
|
||||
if (!!context) {
|
||||
if (action.command.includes('ARRIVED') || action.command.includes('PRINT_PRICEDIFFQRCODELABEL')) {
|
||||
if (
|
||||
action.command.includes('ARRIVED') ||
|
||||
action.command.includes('PRINT_PRICEDIFFQRCODELABEL') ||
|
||||
action.command.includes('BACKTOSTOCK')
|
||||
) {
|
||||
const nav = this._pickupShelfOutNavigationService.defaultRoute({ processId: this.processId });
|
||||
await this.router.navigate(nav.path, { queryParams: nav.queryParams, queryParamsHandling: 'preserve' });
|
||||
} else {
|
||||
|
||||
@@ -26,10 +26,18 @@ export class PickupShelfOutEditComponent extends PickupShelfDetailsBaseComponent
|
||||
|
||||
async navigateToShelfOutDetailsPage(changes: Partial<DBHOrderItemListItemDTO>) {
|
||||
const orderId = (await this.store.orderItems$.pipe(first()).toPromise())?.find((_) => true)?.orderId;
|
||||
const orderNumber = this.activatedRoute?.snapshot?.params?.orderNumber;
|
||||
const compartmentCode = changes?.compartmentCode ?? this.activatedRoute?.snapshot?.params?.compartmentCode;
|
||||
const orderNumber = decodeURIComponent(this.activatedRoute?.snapshot?.params?.orderNumber);
|
||||
let compartmentCode = changes?.compartmentCode ?? this.activatedRoute?.snapshot?.params?.compartmentCode;
|
||||
const processingStatus = changes?.processingStatus ?? this.activatedRoute.snapshot.params.orderItemProcessingStatus;
|
||||
const compartmentInfo = changes?.compartmentInfo ?? this.activatedRoute.snapshot.params.compartmentInfo;
|
||||
let compartmentInfo = changes?.compartmentInfo ?? this.activatedRoute.snapshot.params.compartmentInfo;
|
||||
|
||||
if (compartmentCode) {
|
||||
compartmentCode = decodeURIComponent(compartmentCode);
|
||||
}
|
||||
|
||||
if (compartmentInfo) {
|
||||
compartmentInfo = decodeURIComponent(compartmentInfo);
|
||||
}
|
||||
|
||||
await this.router.navigate(
|
||||
this.shelfOutNavigation.detailRoute({
|
||||
|
||||
@@ -15,6 +15,7 @@ import { ActionHandlerServices } from '@domain/oms';
|
||||
import { ActionHandlerService } from '../services/action-handler.service';
|
||||
import { FilterAutocompleteProvider } from '@shared/components/filter';
|
||||
import { PickUpShelfOutAutocompleteProvider } from './providers/pickup-shelf-out-autocomplete.provider';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-out',
|
||||
@@ -203,4 +204,33 @@ export class PickupShelfOutComponent extends PickupShelfBaseComponent {
|
||||
async getNameForHistoryBreadcrumb(data: GetNameForBreadcrumbData): Promise<string> {
|
||||
return 'Historie';
|
||||
}
|
||||
|
||||
async regsiterFetchListResponseHandler() {
|
||||
this.listStore.fetchListResponse$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async ({ processId, queryParams, response }) => {
|
||||
/**
|
||||
* Wenn die Suche erfolgreich war, wird der Benutzer auf die Liste oder Detailseite des gefundenen Artikels weitergeleitet.
|
||||
*/
|
||||
const filterQueryParams = this.listStore.filter.getQueryParams();
|
||||
|
||||
if (response.hits === 1) {
|
||||
const detailsPath = await this.getPathForDetail(response.result[0]).pipe(take(1)).toPromise();
|
||||
await this.router.navigate(detailsPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...detailsPath.queryParams } });
|
||||
} else if (response.hits > 1) {
|
||||
const listPath = await this.getPathFoListBreadcrumb({ processId, queryParams });
|
||||
await this.router.navigate(listPath.path, { queryParams: { ...queryParams, ...filterQueryParams, ...listPath.queryParams } });
|
||||
} else {
|
||||
await this.router.navigate([], { queryParams: { ...queryParams, ...filterQueryParams } });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Ticket 4720 WA // Trefferliste wird übersprungen - Bei mehreren Bestellposten pro Bestellung soll IMMER auf Trefferliste navigiert werden
|
||||
// Damit werden #4684 und #4688 überflüssig
|
||||
|
||||
// REMOVED: Fix Ticket #4684 Navigate on Details if items contain same OrderNumber
|
||||
// private _hasSameOrderNumber(response: ListResponseArgsOfDBHOrderItemListItemDTO) {
|
||||
// if (response.hits === 0) return false;
|
||||
// const orderNumbers = new Set(response.result.map((item) => item.orderNumber));
|
||||
// return orderNumbers.size === 1;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<ng-container *ngIf="orderItem$ | async; let orderItem">
|
||||
<div class="grid grid-flow-row gap-px-2">
|
||||
<div class="bg-[#F5F7FA] flex flex-row justify-between items-center p-4 rounded-t">
|
||||
<div class="grid grid-flow-col gap-[0.4375rem] items-center" *ngIf="features$ | async; let features; else: featureLoading">
|
||||
<shared-icon *ngIf="features?.length > 0" [size]="24" icon="person"></shared-icon>
|
||||
<div class="grid grid-flow-col gap-2 items-center font-bold text-p2" *ngFor="let feature of features">
|
||||
{{ feature?.description }}
|
||||
</div>
|
||||
<div class="grid grid-flow-col gap-[0.4375rem] items-center" *ngIf="fetchingCustomerDone$ | async; else featureLoading">
|
||||
<ng-container *ngIf="features$ | async; let features">
|
||||
<shared-icon *ngIf="features?.length > 0" [size]="24" icon="person"></shared-icon>
|
||||
<div class="grid grid-flow-col gap-2 items-center font-bold text-p2" *ngFor="let feature of features">
|
||||
{{ feature?.description }}
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<button
|
||||
@@ -18,6 +20,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-template #featureLoading>
|
||||
<shared-skeleton-loader class="w-64 h-6"></shared-skeleton-loader>
|
||||
</ng-template>
|
||||
|
||||
<div class="page-pickup-shelf-details-header__details bg-white px-4 pt-4 pb-5">
|
||||
<div class="flex flex-row items-center" [class.mb-8]="!orderItem?.features?.paid && !isKulturpass">
|
||||
<page-pickup-shelf-details-header-nav-menu class="mr-2" [customer]="customer$ | async"></page-pickup-shelf-details-header-nav-menu>
|
||||
@@ -96,7 +102,12 @@
|
||||
</div>
|
||||
<div class="flex flex-row page-pickup-shelf-details-header__order-source" data-detail-id="Bestellkanal">
|
||||
<div class="min-w-[9rem]">Bestellkanal</div>
|
||||
<div class="flex flex-row font-bold">{{ order?.features?.orderSource }}</div>
|
||||
<div class="flex flex-row font-bold">
|
||||
<shared-skeleton-loader class="w-32" *ngIf="fetchingOrder$ | async; else orderSourceTmpl"></shared-skeleton-loader>
|
||||
<ng-template #orderSourceTmpl>
|
||||
{{ order()?.features?.orderSource }}
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-row page-pickup-shelf-details-header__change-date justify-between"
|
||||
@@ -137,21 +148,18 @@
|
||||
data-detail-id="Benachrichtigung"
|
||||
>
|
||||
<div class="min-w-[9rem]">Benachrichtigung</div>
|
||||
<div class="flex flex-row font-bold">{{ (notificationsChannel$ | async | notificationsChannel) || '-' }}</div>
|
||||
<div class="flex flex-row font-bold">
|
||||
<shared-skeleton-loader class="w-32" *ngIf="fetchingOrder$ | async; else notificationsChannelTpl"></shared-skeleton-loader>
|
||||
<ng-template #notificationsChannelTpl>
|
||||
{{ (notificationsChannel$ | async | notificationsChannel) || '-' }}
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #featureLoading>
|
||||
<div class="fetch-wrapper">
|
||||
<div class="fetching"></div>
|
||||
<div class="fetching"></div>
|
||||
<div class="fetching"></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #abholfrist>
|
||||
<div class="min-w-[9rem]">Abholfrist</div>
|
||||
<div *ngIf="!(changeDateLoader$ | async)" class="flex flex-row font-bold">
|
||||
|
||||
@@ -2,7 +2,7 @@ import { AsyncPipe, DatePipe, NgFor, NgIf, NgSwitch, NgSwitchCase, NgTemplateOut
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
||||
import { DBHOrderItemListItemDTO, KeyValueDTOOfStringAndString, NotificationChannel, OrderDTO } from '@swagger/oms';
|
||||
import { PickupShelfDetailsStore } from '../../store';
|
||||
import { map, shareReplay, withLatestFrom } from 'rxjs/operators';
|
||||
import { map, shareReplay, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { BehaviorSubject, Observable, combineLatest } from 'rxjs';
|
||||
import { DateAdapter, UiCommonModule } from '@ui/common';
|
||||
import { IconModule } from '@shared/components/icon';
|
||||
@@ -12,6 +12,8 @@ import { PickupShelfNotificationsChannelPipe } from '../pipes/notifications-chan
|
||||
import { PickupShelfProcessingStatusPipe } from '../pipes/processing-status.pipe';
|
||||
import { UiDatepickerModule } from '@ui/datepicker';
|
||||
import { PickUpShelfDetailsHeaderNavMenuComponent } from '../pickup-shelf-details-header-nav-menu/pickup-shelf-details-header-nav-menu.component';
|
||||
import { SkeletonLoaderComponent } from '@shared/components/loader';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-details-header',
|
||||
@@ -36,6 +38,7 @@ import { PickUpShelfDetailsHeaderNavMenuComponent } from '../pickup-shelf-detail
|
||||
UiCommonModule,
|
||||
UiDatepickerModule,
|
||||
PickUpShelfDetailsHeaderNavMenuComponent,
|
||||
SkeletonLoaderComponent,
|
||||
],
|
||||
})
|
||||
export class PickUpShelfDetailsHeaderComponent {
|
||||
@@ -50,13 +53,11 @@ export class PickUpShelfDetailsHeaderComponent {
|
||||
@Output()
|
||||
updateDate = new EventEmitter<{ date: Date; type?: 'delivery' | 'pickup' | 'preferred' }>();
|
||||
|
||||
get order$(): Observable<OrderDTO> {
|
||||
return this._store.order$;
|
||||
}
|
||||
fetchingOrder$ = this._store.fetchingOrder$;
|
||||
|
||||
get order(): OrderDTO {
|
||||
return this._store.order;
|
||||
}
|
||||
order$ = this._store.order$;
|
||||
|
||||
order = toSignal(this.order$);
|
||||
|
||||
findLatestPreferredPickUpDate$: Observable<Date> = this.order$.pipe(
|
||||
withLatestFrom(this._store.selectedOrderItemIds$),
|
||||
@@ -86,13 +87,17 @@ export class PickUpShelfDetailsHeaderComponent {
|
||||
processId?: number;
|
||||
|
||||
get isKulturpass() {
|
||||
return this.order?.features?.orderSource === 'KulturPass';
|
||||
return this.order()?.features?.orderSource === 'KulturPass';
|
||||
}
|
||||
|
||||
minDateDatepicker = this.dateAdapter.addCalendarDays(this.dateAdapter.today(), -1);
|
||||
today = this.dateAdapter.today();
|
||||
|
||||
orderItem$ = this._store.orderItems$.pipe(map((orderItems) => orderItems?.find((_) => true)));
|
||||
// Daten die im Header Angezeigt werden sollen
|
||||
orderItem$ = combineLatest([
|
||||
this._store.selectedOrderItem$, // Wenn man im Abholfach ist muss das ausgewählte OrderItem genommen werden
|
||||
this._store.selectedOrderItems$.pipe(map((orderItems) => orderItems?.find((_) => true))), // Wenn man in der Warenausgabe ist muss man das erste OrderItem nehmen
|
||||
]).pipe(map(([selectedOrderItem, selectedOrderItems]) => selectedOrderItem || selectedOrderItems));
|
||||
|
||||
changeDateLoader$ = new BehaviorSubject<boolean>(false);
|
||||
changePreferredDateLoader$ = new BehaviorSubject<boolean>(false);
|
||||
@@ -101,6 +106,8 @@ export class PickUpShelfDetailsHeaderComponent {
|
||||
|
||||
changeDateDisabled$ = this.changeStatusDisabled$;
|
||||
|
||||
fetchingCustomerDone$ = this._store.fetchingCustomer$.pipe(map((fetchingCustomer) => !fetchingCustomer));
|
||||
|
||||
customer$ = this._store.customer$;
|
||||
|
||||
features$ = this.customer$.pipe(
|
||||
|
||||
@@ -77,7 +77,10 @@ export class PickUpShelfDetailsItemComponent extends ComponentStore<PickUpShelfD
|
||||
set orderItem(orderItem: DBHOrderItemListItemDTO) {
|
||||
if (!isEqual(this.orderItem, orderItem)) {
|
||||
// Remove Prev OrderItem from selected list
|
||||
this._store.selectOrderItem(this.orderItem, false);
|
||||
if (this.orderItem?.orderItemSubsetId !== orderItem?.orderItemSubsetId) {
|
||||
this._store.selectOrderItem(this.orderItem, false);
|
||||
}
|
||||
|
||||
this.patchState({ orderItem, quantity: orderItem?.quantity, more: false });
|
||||
this.specialCommentControl.reset(orderItem?.specialComment);
|
||||
// Add New OrderItem to selected list if selected was set to true by its input
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*ngIf="historyItem$ | async; let item"
|
||||
class="self-end"
|
||||
type="button"
|
||||
(click)="store.processId !== 7000 ? navigateToShelfOutDetailsPage(item) : navigateToShelfInDetailsPage(item)"
|
||||
(click)="listStore.processId !== 7000 ? navigateToShelfOutDetailsPage(item) : navigateToShelfInDetailsPage(item)"
|
||||
>
|
||||
<shared-icon icon="close" [size]="26"></shared-icon>
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AsyncPipe, NgIf } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { DomainOmsService } from '@domain/oms';
|
||||
import { PickupShelfIOService } from '@domain/pickup-shelf';
|
||||
@@ -9,8 +9,8 @@ import { PickUpShelfOutNavigationService, PickupShelfInNavigationService } from
|
||||
import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map, shareReplay, switchMap, take } from 'rxjs/operators';
|
||||
import { PickupShelfStore } from '../../store';
|
||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||
import { PickupShelfDetailsBaseComponent } from '../../pickup-shelf-details-base.component';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-history',
|
||||
@@ -21,9 +21,7 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||
host: { class: 'page-pickup-shelf-history' },
|
||||
imports: [AsyncPipe, NgIf, SharedHistoryListModule, IconModule],
|
||||
})
|
||||
export class PickUpShelfHistoryComponent {
|
||||
store = inject(PickupShelfStore);
|
||||
|
||||
export class PickUpShelfHistoryComponent extends PickupShelfDetailsBaseComponent {
|
||||
compartmentCode$: Observable<string> = this._activatedRoute.params.pipe(
|
||||
map((params) => decodeURIComponent(params?.compartmentCode ?? '') || undefined)
|
||||
);
|
||||
@@ -62,12 +60,14 @@ export class PickUpShelfHistoryComponent {
|
||||
private _shelfInNavigation: PickupShelfInNavigationService,
|
||||
private _omsService: DomainOmsService,
|
||||
private _pickupShelfIOService: PickupShelfIOService
|
||||
) {}
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async navigateToShelfOutDetailsPage(item: DBHOrderItemListItemDTO) {
|
||||
await this._router.navigate(
|
||||
this._shelfOutNavigation.detailRoute({
|
||||
processId: this.store.processId,
|
||||
processId: this.listStore.processId,
|
||||
item: {
|
||||
compartmentCode: item.compartmentCode,
|
||||
orderId: item.orderId,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[routerLink]="itemDetailsLink"
|
||||
[routerLinkActive]="!isTablet && !primaryOutletActive ? 'active' : ''"
|
||||
queryParamsHandling="preserve"
|
||||
(click)="isDesktopLarge ? scrollIntoView() : ''"
|
||||
(click)="onDetailsClick()"
|
||||
>
|
||||
<div
|
||||
class="page-pickup-shelf-list-item__item-grid-container"
|
||||
|
||||
@@ -10,6 +10,7 @@ import { PickupShelfProcessingStatusPipe } from '../pipes/processing-status.pipe
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { PickupShelfStore } from '../../store';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { CacheService } from '@core/cache';
|
||||
|
||||
@Component({
|
||||
selector: 'page-pickup-shelf-list-item',
|
||||
@@ -34,6 +35,8 @@ import { map } from 'rxjs/operators';
|
||||
providers: [PickupShelfProcessingStatusPipe],
|
||||
})
|
||||
export class PickUpShelfListItemComponent {
|
||||
private cache = inject(CacheService);
|
||||
|
||||
store = inject(PickupShelfStore);
|
||||
|
||||
@Input() item: DBHOrderItemListItemDTO;
|
||||
@@ -85,6 +88,45 @@ export class PickUpShelfListItemComponent {
|
||||
private _processingStatusPipe: PickupShelfProcessingStatusPipe
|
||||
) {}
|
||||
|
||||
onDetailsClick() {
|
||||
if (this.isDesktopLarge) {
|
||||
this.scrollIntoView();
|
||||
}
|
||||
|
||||
if (!this.hasOrderItemInCache()) {
|
||||
this.addOrderItemIntoCache();
|
||||
}
|
||||
}
|
||||
|
||||
hasOrderItemInCache() {
|
||||
const items =
|
||||
this.cache.get<DBHOrderItemListItemDTO[]>({
|
||||
name: 'orderItems',
|
||||
orderId: this.item.orderId,
|
||||
compartmentCode: this.item.compartmentCode,
|
||||
compartmentInfo: this.item.compartmentInfo,
|
||||
orderItemProcessingStatus: this.item.processingStatus,
|
||||
store: 'PickupShelfDetailsStore',
|
||||
}) ?? [];
|
||||
|
||||
return items.some((i) => i.orderItemSubsetId === this.item.orderItemSubsetId);
|
||||
}
|
||||
|
||||
addOrderItemIntoCache() {
|
||||
this.cache.set(
|
||||
{
|
||||
name: 'orderItems',
|
||||
orderId: this.item.orderId,
|
||||
compartmentCode: this.item.compartmentCode,
|
||||
compartmentInfo: this.item.compartmentInfo,
|
||||
orderItemProcessingStatus: this.item.processingStatus,
|
||||
store: 'PickupShelfDetailsStore',
|
||||
},
|
||||
[this.item],
|
||||
{ persist: false, ttl: 1000 }
|
||||
);
|
||||
}
|
||||
|
||||
scrollIntoView() {
|
||||
this._elRef.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PickupShelfDetailsState } from './pickup-shelf-details.state';
|
||||
import { DBHOrderItemListItemDTO } from '@swagger/oms';
|
||||
import { DBHOrderItemListItemDTO, KeyValueDTOOfStringAndString } from '@swagger/oms';
|
||||
|
||||
export const selectOrder = (s: PickupShelfDetailsState) => s.order;
|
||||
|
||||
@@ -100,9 +100,9 @@ export const selectedOrderItems = (s: PickupShelfDetailsState) => {
|
||||
|
||||
export const selectedOrderItem = (s: PickupShelfDetailsState) => {
|
||||
const orderItems = selectOrderItems(s);
|
||||
const selectedOrderItemId = selectPreviousSelectedOrderItemSubsetId(s);
|
||||
const displayedOrderItemSubsetId = selectDisplayedOrderItemSubsetId(s);
|
||||
|
||||
return orderItems?.find((oi) => oi?.orderItemSubsetId === selectedOrderItemId);
|
||||
return orderItems?.find((oi) => oi?.orderItemSubsetId === displayedOrderItemSubsetId);
|
||||
};
|
||||
|
||||
export const selectSelectedOrderItemQuantity = (s: PickupShelfDetailsState) => {
|
||||
@@ -245,6 +245,26 @@ export const selectMainActions = (s: PickupShelfDetailsState) => {
|
||||
?.filter((action) => (fetchPartial ? !action.command.includes('FETCHED_PARTIAL') : true));
|
||||
};
|
||||
|
||||
export const selectShelfOutMainActions = (s: PickupShelfDetailsState) => {
|
||||
const items = selectOrderItems(s);
|
||||
const fetchPartial = selectFetchPartial(s);
|
||||
|
||||
// Ticket #4690 Consider every Item for selecting the main actions in Details View - Only for PickUpShelfOut
|
||||
const actions: KeyValueDTOOfStringAndString[] = [];
|
||||
for (const item of items) {
|
||||
const actionsFromItem = item?.actions
|
||||
?.filter((action) => typeof action?.enabled !== 'boolean')
|
||||
?.filter((action) => (fetchPartial ? !action.command.includes('FETCHED_PARTIAL') : true));
|
||||
for (const action of actionsFromItem) {
|
||||
if (!actions.find((a) => a.command === action.command)) {
|
||||
actions.push(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actions;
|
||||
};
|
||||
|
||||
export const selectCustomerNumber = (s: PickupShelfDetailsState) => {
|
||||
const order = selectOrder(s);
|
||||
return order?.buyer?.buyerNumber;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ComponentStore, tapResponse } from '@ngrx/component-store';
|
||||
import { PickupShelfDetailsState } from './pickup-shelf-details.state';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import {
|
||||
DBHOrderItemListItemDTO,
|
||||
EntityDTOContainerOfOrderItemSubsetDTO,
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
} from '@swagger/oms';
|
||||
import { PickupShelfIOService, PickupShelfService } from '@domain/pickup-shelf';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { delayWhen, filter, mergeMap, switchMap, take, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { delayWhen, filter, map, mergeMap, switchMap, take, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import * as Selectors from './pickup-shelf-details.selectors';
|
||||
@@ -56,10 +56,20 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
return this.get(Selectors.selectFetchingOrder);
|
||||
}
|
||||
|
||||
orderItems$ = this.select(Selectors.selectOrderItems);
|
||||
// orderItems$ = this.select(Selectors.selectOrderItems);
|
||||
|
||||
// get orderItems() {
|
||||
// return this.get(Selectors.selectOrderItems);
|
||||
// }
|
||||
|
||||
orderItems$ = combineLatest([
|
||||
this.select(Selectors.selectOrderItems),
|
||||
this.select((s) => s).pipe(switchMap((s) => this._listStore.itemsForPreview$(s))),
|
||||
]).pipe(map(([orderItems, itemsForPreview]) => (orderItems?.length ? orderItems : itemsForPreview)));
|
||||
|
||||
get orderItems() {
|
||||
return this.get(Selectors.selectOrderItems);
|
||||
const orderItems = this.get(Selectors.selectOrderItems);
|
||||
return orderItems?.length ? orderItems : this.get((s) => this._listStore.itemsForPreview(s));
|
||||
}
|
||||
|
||||
fetchingOrderItems$ = this.select(Selectors.selectFetchingOrderItems);
|
||||
@@ -211,6 +221,12 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
return this.get(Selectors.selectMainActions);
|
||||
}
|
||||
|
||||
mainShelfOutActions$ = this.select(Selectors.selectShelfOutMainActions);
|
||||
|
||||
get mainShelfOutActions() {
|
||||
return this.get(Selectors.selectShelfOutMainActions);
|
||||
}
|
||||
|
||||
customerNumber$ = this.select(Selectors.selectCustomerNumber);
|
||||
|
||||
get customerNumber() {
|
||||
@@ -332,8 +348,8 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
|
||||
fetchOrder = this.effect((trigger$: Observable<{ orderId: number }>) =>
|
||||
trigger$.pipe(
|
||||
filter(({ orderId }) => this.order?.id !== orderId),
|
||||
tap(({ orderId }) => this.beforeFetchOrder(orderId)),
|
||||
// delay(10000),
|
||||
switchMap(({ orderId }) =>
|
||||
this._pickupShelfService.getOrderByOrderId(orderId).pipe(tapResponse(this.fetchOrderSuccess, this.fetchOrderFailed))
|
||||
)
|
||||
@@ -341,7 +357,7 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
);
|
||||
|
||||
private beforeFetchOrder = (orderId) => {
|
||||
const order = this._cacheService.get<OrderDTO>({ name: 'order', orderId, store: 'PickupShelfDetailsStore' });
|
||||
const order = this._cacheService.get<OrderDTO>({ name: 'order', orderId, store: 'PickupShelfDetailsStore' }) ?? { id: orderId };
|
||||
const customer = this._cacheService.get<CustomerInfoDTO>({
|
||||
name: 'customer',
|
||||
orderId,
|
||||
@@ -474,7 +490,7 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
fetchCustomer = this.effect((trigger$: Observable<{ buyerNumber: string }>) =>
|
||||
trigger$.pipe(
|
||||
filter(({ buyerNumber }) => this.customer?.customerNumber !== buyerNumber),
|
||||
tap(this.beforeFetchCustomer),
|
||||
tap(() => this.beforeFetchCustomer()),
|
||||
switchMap(({ buyerNumber }) =>
|
||||
this._customerService.getCustomers(buyerNumber).pipe(tapResponse(this.fetchCustomerSuccess, this.fetchCustomerFailed))
|
||||
)
|
||||
@@ -487,7 +503,7 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
orderId: this.order.id,
|
||||
store: 'PickupShelfDetailsStore',
|
||||
});
|
||||
this.patchState({ fetchingCustomer: true, customer });
|
||||
this.patchState({ fetchingCustomer: !customer, customer: customer });
|
||||
};
|
||||
|
||||
fetchCustomerSuccess = (res: ListResponseArgsOfCustomerInfoDTO) => {
|
||||
@@ -496,6 +512,7 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
// check if response contains exactly one customer
|
||||
if (customers.length > 1) {
|
||||
this._modal.error('Fehler beim Laden des Kunden', new Error('Es wurde mehr als ein Kunde gefunden.'));
|
||||
this.patchState({ fetchingCustomer: false });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -512,6 +529,7 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
|
||||
// also check if the order is a KulturPass order, then there may be no customer
|
||||
if (!isKulturpass && customer?.customerNumber !== this.order.buyer.buyerNumber) {
|
||||
this._modal.error('Fehler beim Laden des Kunden', new Error('Der Kunde ist nicht der Bestellung zugeordnet.'));
|
||||
this.patchState({ fetchingCustomer: false });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Filter } from '@shared/components/filter';
|
||||
import { PickupShelfState } from './pickup-shelf.state';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { PickupShelfDetailsState } from './pickup-shelf-details.state';
|
||||
import {
|
||||
selectDisplayedCompartmentCode,
|
||||
selectDisplayedCompartmentInfo,
|
||||
selectDisplayedOrderItemProcessingStatus,
|
||||
selectOrder,
|
||||
} from './pickup-shelf-details.selectors';
|
||||
|
||||
export function selectProcessId(state: PickupShelfState) {
|
||||
return state.processId;
|
||||
@@ -64,3 +71,27 @@ export function selectListHits(state: PickupShelfState) {
|
||||
export function selectSelectedListItems(state: PickupShelfState) {
|
||||
return state.selectedListItems ?? [];
|
||||
}
|
||||
|
||||
export const selectItemsForPreview = (detailsState: PickupShelfDetailsState) => (state: PickupShelfState) => {
|
||||
const orderId = selectOrder(detailsState)?.id;
|
||||
|
||||
let items = state.list.filter((item) => item.orderId === orderId);
|
||||
|
||||
const processingStatus = selectDisplayedOrderItemProcessingStatus(detailsState);
|
||||
if (processingStatus) {
|
||||
items = items?.filter((oi) => oi.processingStatus === processingStatus);
|
||||
}
|
||||
|
||||
const compartmentCode = selectDisplayedCompartmentCode(detailsState);
|
||||
if (compartmentCode) {
|
||||
items = items?.filter((oi) => oi.compartmentCode === compartmentCode);
|
||||
|
||||
const compartmentInfo = selectDisplayedCompartmentInfo(detailsState);
|
||||
|
||||
if (compartmentInfo) {
|
||||
items = items?.filter((oi) => oi.compartmentInfo === compartmentInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@ import * as Selectors from './pickup-shelf.selectors';
|
||||
import { Observable, Subject, combineLatest } from 'rxjs';
|
||||
import { CacheService } from '@core/cache';
|
||||
import { Filter } from '@shared/components/filter';
|
||||
import { PickupShelfDetailsState } from './pickup-shelf-details.state';
|
||||
|
||||
@Injectable()
|
||||
export class PickupShelfStore extends ComponentStore<PickupShelfState> implements OnStoreInit {
|
||||
@@ -104,6 +105,10 @@ export class PickupShelfStore extends ComponentStore<PickupShelfState> implement
|
||||
return this.get(Selectors.selectSelectedListItems);
|
||||
}
|
||||
|
||||
itemsForPreview$ = (state: PickupShelfDetailsState) => this.select(Selectors.selectItemsForPreview(state));
|
||||
|
||||
itemsForPreview = (state: PickupShelfDetailsState) => this.get(Selectors.selectItemsForPreview(state));
|
||||
|
||||
constructor() {
|
||||
// Nicht entfernen sonst wird der Store nicht initialisiert
|
||||
super({});
|
||||
@@ -237,16 +242,17 @@ export class PickupShelfStore extends ComponentStore<PickupShelfState> implement
|
||||
|
||||
private beforeFetchList = (emitFetchListResponse: boolean, filter: Filter, processId: number) => {
|
||||
this.cancelListRequests();
|
||||
this.patchState({ fetchingList: true });
|
||||
const queryToken = filter.getQueryParams();
|
||||
const cachedListResponse = this._cacheService.get<ListResponseArgsOfDBHOrderItemListItemDTO>({ processId, queryToken });
|
||||
|
||||
let list: DBHOrderItemListItemDTO[] = [];
|
||||
|
||||
if (!!cachedListResponse) {
|
||||
this.patchState({ fetchingList: false, list: cachedListResponse.result, listHits: cachedListResponse.hits });
|
||||
this.patchState({ list: cachedListResponse.result, listHits: cachedListResponse.hits });
|
||||
list = cachedListResponse.result;
|
||||
} else {
|
||||
this.patchState({ fetchingList: true, list: [], listHits: 0 });
|
||||
this.patchState({ list: [], listHits: 0 });
|
||||
}
|
||||
|
||||
return { emitFetchListResponse, filter, processId, list };
|
||||
|
||||
@@ -11,6 +11,7 @@ import { UiTooltipModule } from '@ui/tooltip';
|
||||
import { UiCommonModule } from '@ui/common';
|
||||
import { UiDropdownModule } from '@ui/dropdown';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { SharedProductGroupPipe } from '@shared/pipes/product-group';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -25,6 +26,7 @@ import { UiIconModule } from '@ui/icon';
|
||||
UiTooltipModule,
|
||||
UiDropdownModule,
|
||||
UiIconModule,
|
||||
SharedProductGroupPipe,
|
||||
],
|
||||
exports: [AddProductModalComponent],
|
||||
declarations: [AddProductModalComponent],
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export * from './product-group.pipe';
|
||||
export * from './remission-pipe.module';
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AssortmentPipe } from './assortment.pipe';
|
||||
import { ProductGroupPipe } from './product-group.pipe';
|
||||
import { ShortReceiptNumberPipe } from './short-receipt-number.pipe';
|
||||
import { SupplierPipe } from './supplier.pipe';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProductGroupPipe, AssortmentPipe, ShortReceiptNumberPipe, SupplierPipe],
|
||||
exports: [ProductGroupPipe, AssortmentPipe, ShortReceiptNumberPipe, SupplierPipe],
|
||||
declarations: [AssortmentPipe, ShortReceiptNumberPipe, SupplierPipe],
|
||||
exports: [AssortmentPipe, ShortReceiptNumberPipe, SupplierPipe],
|
||||
})
|
||||
export class RemissionPipeModule {}
|
||||
|
||||
@@ -31,6 +31,6 @@ export class RemissionFilterComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
resetFilter() {
|
||||
this.store.loadFilter();
|
||||
this.store.loadFilter({ loadDefault: true });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { UiTooltipModule } from '@ui/tooltip';
|
||||
import { UiCommonModule } from '@ui/common';
|
||||
import { AddProductToShippingDocumentModalModule } from '../../modals/add-product-to-shipping-document-modal/add-product-to-shipping-document-modal.module';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { SharedProductGroupPipe } from '@shared/pipes/product-group';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -18,6 +19,7 @@ import { UiSpinnerModule } from '@ui/spinner';
|
||||
RemissionPipeModule,
|
||||
UiTooltipModule,
|
||||
AddProductToShippingDocumentModalModule,
|
||||
SharedProductGroupPipe,
|
||||
],
|
||||
exports: [RemissionListItemComponent],
|
||||
declarations: [RemissionListItemComponent],
|
||||
|
||||
@@ -163,7 +163,7 @@ export class RemissionListComponentStore extends ComponentStore<RemissionState>
|
||||
combineLatest([this.selectedSource$, this.selectedSupplier$])
|
||||
.pipe(takeUntil(this._onDestroy$))
|
||||
.subscribe(() => {
|
||||
this.loadFilter();
|
||||
this.loadFilter({});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -227,12 +227,12 @@ export class RemissionListComponentStore extends ComponentStore<RemissionState>
|
||||
)
|
||||
);
|
||||
|
||||
loadFilter = this.effect(($) =>
|
||||
$.pipe(
|
||||
loadFilter = this.effect((options$: Observable<{ loadDefault?: boolean }>) =>
|
||||
options$.pipe(
|
||||
// tap((_) => (this.getCachedData()?.hits === 0 ? this.setFetching(true) : null)),
|
||||
withLatestFrom(this.selectedSupplier$, this.selectedSource$, this._activatedRoute.queryParams),
|
||||
filter(([, selectedSupplier, selectedSource]) => !!selectedSupplier?.id && !!selectedSource),
|
||||
switchMap(([, selectedSupplier, selectedSource, queryParams]) =>
|
||||
filter(([loadDefault, selectedSupplier, selectedSource]) => !!selectedSupplier?.id && !!selectedSource),
|
||||
switchMap(([loadDefault, selectedSupplier, selectedSource, queryParams]) =>
|
||||
this._domainRemissionService
|
||||
.getQuerySettings({
|
||||
supplierId: selectedSupplier.id,
|
||||
@@ -245,7 +245,8 @@ export class RemissionListComponentStore extends ComponentStore<RemissionState>
|
||||
settings?.filter?.forEach((filter) => (filter.input = filter.input?.filter((input) => input.options?.values?.length > 0)));
|
||||
|
||||
const filter = UiFilter.create(settings);
|
||||
if (!!queryParams) {
|
||||
|
||||
if (!!queryParams && !loadDefault) {
|
||||
filter?.fromQueryParams(queryParams);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,10 @@ import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { RemissionPipeModule } from '../../pipes';
|
||||
import { SharedShippingDocumentDetailsItemComponent } from './shipping-document-details-item/shipping-document-details-item.component';
|
||||
import { SharedShippingDocumentDetailsComponent } from './shipping-document-details.component';
|
||||
import { SharedProductGroupPipe } from '@shared/pipes/product-group';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, RemissionPipeModule, ProductImageModule, UiSpinnerModule],
|
||||
imports: [CommonModule, RemissionPipeModule, ProductImageModule, UiSpinnerModule, SharedProductGroupPipe],
|
||||
exports: [SharedShippingDocumentDetailsComponent, SharedShippingDocumentDetailsItemComponent],
|
||||
declarations: [SharedShippingDocumentDetailsComponent, SharedShippingDocumentDetailsItemComponent],
|
||||
providers: [],
|
||||
|
||||
@@ -18,7 +18,21 @@
|
||||
<div class="goods-in-out-order-group-item-details-thumbnail">
|
||||
<img loading="lazy" *ngIf="item?.product?.ean | productImage; let productImage" [src]="productImage" [alt]="item?.product?.name" />
|
||||
</div>
|
||||
<div class="goods-in-out-order-group-item-details-data">
|
||||
<div data-which="item-details-data" class="goods-in-out-order-group-item-details-data">
|
||||
<div
|
||||
data-what="product-group"
|
||||
*ngIf="item?.product?.productGroup"
|
||||
class="goods-in-out-order-group-item-details__product-group flex flex-row justify-end items-center text-p3"
|
||||
>
|
||||
{{ item?.product?.productGroup }}: {{ item?.product?.productGroup | productGroup }}
|
||||
</div>
|
||||
<div
|
||||
*ngIf="compartmentFromStock"
|
||||
data-what="compartment"
|
||||
class="goods-in-out-order-group-item-details__compartment flex flex-row justify-end items-center text-p3"
|
||||
>
|
||||
{{ compartmentFromStock }}
|
||||
</div>
|
||||
<div class="item-top-row">
|
||||
<div class="item-title">{{ [item.product.contributors, item.product.name] | title }}</div>
|
||||
<div class="item-processing-status">
|
||||
|
||||
@@ -78,7 +78,15 @@ export class GoodsInOutOrderGroupItemComponent extends ComponentStore<GoodsInOut
|
||||
showSupplier: boolean;
|
||||
|
||||
@Input()
|
||||
showInStock: StockInfoDTO[];
|
||||
showInStock?: StockInfoDTO[];
|
||||
|
||||
get stockInfoForItem() {
|
||||
return this.showInStock?.find((stock) => stock?.ean === this.item?.product?.ean);
|
||||
}
|
||||
|
||||
get compartmentFromStock() {
|
||||
return this.stockInfoForItem?.compartment;
|
||||
}
|
||||
|
||||
get cruda() {
|
||||
return (this.item as any)?.cruda;
|
||||
|
||||
@@ -10,6 +10,7 @@ import { UiSelectBulletModule } from '@ui/select-bullet';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { UiQuantityDropdownModule } from '@ui/quantity-dropdown';
|
||||
import { UiSpinnerModule } from 'apps/ui/spinner/src/lib/ui-spinner.module';
|
||||
import { SharedProductGroupPipe } from '@shared/pipes/product-group';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -21,6 +22,7 @@ import { UiSpinnerModule } from 'apps/ui/spinner/src/lib/ui-spinner.module';
|
||||
FormsModule,
|
||||
UiQuantityDropdownModule,
|
||||
UiSpinnerModule,
|
||||
SharedProductGroupPipe,
|
||||
],
|
||||
exports: [GoodsInOutOrderGroupComponent, GoodsInOutOrderGroupItemComponent],
|
||||
declarations: [GoodsInOutOrderGroupComponent, GoodsInOutOrderGroupItemComponent],
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<img [src]="'/assets/images/bookmark_responsive.svg'" [alt]="alt" />
|
||||
<shared-icon [icon]="icon" [size]="20"></shared-icon>
|
||||
@@ -0,0 +1,13 @@
|
||||
:host {
|
||||
@apply flex relative;
|
||||
}
|
||||
|
||||
img {
|
||||
@apply relative;
|
||||
}
|
||||
|
||||
shared-icon {
|
||||
@apply absolute text-white;
|
||||
top: calc(50% - 1rem);
|
||||
left: calc(50% - 0.785rem);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { IconModule } from '../icon.module';
|
||||
|
||||
@Component({
|
||||
selector: 'shared-icon-badge',
|
||||
templateUrl: 'icon-badge.component.html',
|
||||
styleUrls: ['icon-badge.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [IconModule],
|
||||
})
|
||||
export class IconBadgeComponent {
|
||||
@Input()
|
||||
icon: string;
|
||||
|
||||
@Input()
|
||||
alt: string;
|
||||
}
|
||||
@@ -1,16 +1,20 @@
|
||||
:host {
|
||||
@apply inline-block min-h-[1rem] min-w-[2rem] bg-gray-500;
|
||||
@apply inline-block min-h-[1rem] min-w-[2rem] overflow-hidden rounded;
|
||||
background: rgb(238, 238, 238);
|
||||
}
|
||||
|
||||
.gr-bar {
|
||||
@apply w-full h-full;
|
||||
animation: load 1s ease-in-out infinite;
|
||||
|
||||
background: linear-gradient(75deg, rgba(238, 238, 238, 1) 0%, rgba(190, 190, 190, 1) 50%, rgba(238, 238, 238, 1) 100%);
|
||||
}
|
||||
|
||||
@keyframes load {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
30% {
|
||||
opacity: 0.5;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<div class="gr-bar"></div>
|
||||
|
||||
@@ -2,3 +2,7 @@
|
||||
@apply flex flex-row justify-between items-center bg-white rounded mt-px-2 px-4 font-bold;
|
||||
height: 53px;
|
||||
}
|
||||
|
||||
:host.has-annotation {
|
||||
@apply text-[#5A728A];
|
||||
}
|
||||
|
||||
@@ -11,11 +11,18 @@
|
||||
{{ 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="text-right grow">
|
||||
<div data-which="Statusmeldung" class="text-right grow">
|
||||
<div
|
||||
*ngIf="!hasAnnotation; else annotationTmpl"
|
||||
class="rounded inline-block px-4 text-white page-package-list-item__arrival-status whitespace-nowrap"
|
||||
data-what="arrival-status"
|
||||
[class]="package?.arrivalStatus | arrivalStatusColorClass"
|
||||
>
|
||||
{{ package?.arrivalStatus | arrivalStatus }}
|
||||
</div>
|
||||
<ng-template #annotationTmpl>
|
||||
<div data-what="annotation" class="page-package-list-item__annotation">
|
||||
{{ annotation }}
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, ChangeDetectionStrategy, Input } from '@angular/core';
|
||||
import { Component, ChangeDetectionStrategy, Input, OnChanges, SimpleChanges, HostBinding } from '@angular/core';
|
||||
import { PackageDTO2 } from '@swagger/wws';
|
||||
|
||||
@Component({
|
||||
@@ -7,9 +7,19 @@ import { PackageDTO2 } from '@swagger/wws';
|
||||
styleUrls: ['package-list-item.component.css'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class PackageListItemComponent {
|
||||
export class PackageListItemComponent implements OnChanges {
|
||||
@Input()
|
||||
package: PackageDTO2;
|
||||
|
||||
constructor() {}
|
||||
annotation: string | undefined;
|
||||
|
||||
@HostBinding('class.has-annotation')
|
||||
hasAnnotation = false;
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.package) {
|
||||
this.annotation = this.package?.features?.['annotation'] ?? undefined;
|
||||
this.hasAnnotation = !!this.annotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
apps/shared/pipes/product-group/ng-package.json
Normal file
6
apps/shared/pipes/product-group/ng-package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "../../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,9 @@ import { distinctUntilChanged, map, switchMap } from 'rxjs/operators';
|
||||
@Pipe({
|
||||
name: 'productGroup',
|
||||
pure: false,
|
||||
standalone: true,
|
||||
})
|
||||
export class ProductGroupPipe implements PipeTransform, OnDestroy {
|
||||
export class SharedProductGroupPipe implements PipeTransform, OnDestroy {
|
||||
result: string;
|
||||
|
||||
productGroup$ = new Subject<string>();
|
||||
1
apps/shared/pipes/product-group/src/public-api.ts
Normal file
1
apps/shared/pipes/product-group/src/public-api.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './lib/product-group.pipe';
|
||||
@@ -2,6 +2,7 @@ import { Injectable, inject } from '@angular/core';
|
||||
import { NavigationRoute } from './defs/navigation-route';
|
||||
import { Router } from '@angular/router';
|
||||
import { OrderItemProcessingStatusValue } from '@swagger/oms';
|
||||
import { isBoolean } from 'lodash';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PickUpShelfOutNavigationService {
|
||||
|
||||
@@ -230,11 +230,36 @@ export class ShellSideMenuComponent {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
// #4692 Return Fallback if Values contain undefined or null values, regardless if path is from type string or array
|
||||
if (typeof lastCrumb?.path === 'string') {
|
||||
if (lastCrumb?.path?.includes('undefined') || lastCrumb?.path?.includes('null')) {
|
||||
return fallback;
|
||||
}
|
||||
} else {
|
||||
let valuesToCheck = [];
|
||||
|
||||
for (const value of lastCrumb?.path) {
|
||||
if (value?.outlets && value?.outlets?.primary && value?.outlets?.side) {
|
||||
valuesToCheck.push(...Object.values(value?.outlets?.primary), ...Object.values(value?.outlets?.side));
|
||||
} else {
|
||||
valuesToCheck.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.checkIfArrayContainsUndefinedOrNull(valuesToCheck)) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
return { path: lastCrumb.path, queryParams: lastCrumb.params };
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
checkIfArrayContainsUndefinedOrNull(array: any[]) {
|
||||
return array?.includes(undefined) || array?.includes('undefined') || array?.includes(null) || array?.includes('null');
|
||||
}
|
||||
|
||||
getLastActivatedCustomerProcessId$() {
|
||||
return this._app.getProcesses$('customer').pipe(
|
||||
map((processes) => {
|
||||
|
||||
@@ -4,7 +4,6 @@ export { DialogOfString } from './models/dialog-of-string';
|
||||
export { DialogSettings } from './models/dialog-settings';
|
||||
export { DialogContentType } from './models/dialog-content-type';
|
||||
export { KeyValueDTOOfStringAndString } from './models/key-value-dtoof-string-and-string';
|
||||
export { IPublicUserInfo } from './models/ipublic-user-info';
|
||||
export { ProblemDetails } from './models/problem-details';
|
||||
export { LesepunkteRequest } from './models/lesepunkte-request';
|
||||
export { ListResponseArgsOfItemDTO } from './models/list-response-args-of-item-dto';
|
||||
@@ -29,9 +28,11 @@ export { AvailabilityType } from './models/availability-type';
|
||||
export { StockInfoDTO } from './models/stock-info-dto';
|
||||
export { StockStatus } from './models/stock-status';
|
||||
export { ShelfInfoDTO } from './models/shelf-info-dto';
|
||||
export { Successor } from './models/successor';
|
||||
export { ReviewDTO } from './models/review-dto';
|
||||
export { EntityDTO } from './models/entity-dto';
|
||||
export { EntityStatus } from './models/entity-status';
|
||||
export { CRUDA } from './models/cruda';
|
||||
export { QueryTokenDTO } from './models/query-token-dto';
|
||||
export { CatalogType } from './models/catalog-type';
|
||||
export { QueryTokenDTO2 } from './models/query-token-dto2';
|
||||
|
||||
@@ -13,6 +13,11 @@ export interface AvailabilityDTO {
|
||||
*/
|
||||
at?: string;
|
||||
|
||||
/**
|
||||
* EVT
|
||||
*/
|
||||
firstDayOfSale?: string;
|
||||
|
||||
/**
|
||||
* Produkt / Artikel PK
|
||||
*/
|
||||
|
||||
2
apps/swagger/cat/src/lib/models/cruda.ts
Normal file
2
apps/swagger/cat/src/lib/models/cruda.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type CRUDA = 0 | 1 | 2 | 4 | 8 | 16;
|
||||
@@ -1,11 +1,14 @@
|
||||
/* tslint:disable */
|
||||
import { TouchedBase } from './touched-base';
|
||||
import { CRUDA } from './cruda';
|
||||
import { EntityStatus } from './entity-status';
|
||||
export interface EntityDTO extends TouchedBase{
|
||||
changed?: string;
|
||||
created?: string;
|
||||
cruda?: CRUDA;
|
||||
id?: number;
|
||||
pId?: string;
|
||||
status?: EntityStatus;
|
||||
uId?: string;
|
||||
version?: number;
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
/* tslint:disable */
|
||||
export interface IPublicUserInfo {
|
||||
alias?: string;
|
||||
displayName?: string;
|
||||
isAuthenticated: boolean;
|
||||
username?: string;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { ReviewDTO } from './review-dto';
|
||||
import { ShelfInfoDTO } from './shelf-info-dto';
|
||||
import { SpecDTO } from './spec-dto';
|
||||
import { StockInfoDTO } from './stock-info-dto';
|
||||
import { Successor } from './successor';
|
||||
import { TextDTO } from './text-dto';
|
||||
import { ItemType } from './item-type';
|
||||
export interface ItemDTO extends EntityDTO{
|
||||
@@ -57,6 +58,11 @@ export interface ItemDTO extends EntityDTO{
|
||||
*/
|
||||
promoPoints?: number;
|
||||
|
||||
/**
|
||||
* Einlöse-Prämienpunkte
|
||||
*/
|
||||
redemptionPoints?: number;
|
||||
|
||||
/**
|
||||
* Rezensionen
|
||||
*/
|
||||
@@ -95,7 +101,7 @@ export interface ItemDTO extends EntityDTO{
|
||||
/**
|
||||
* Nachfolgeartikel
|
||||
*/
|
||||
successor?: ItemDTO;
|
||||
successor?: Successor;
|
||||
|
||||
/**
|
||||
* Texte
|
||||
|
||||
@@ -14,6 +14,7 @@ export interface ProductDTO extends TouchedBase{
|
||||
manufacturer?: string;
|
||||
name?: string;
|
||||
productGroup?: string;
|
||||
productGroupDetails?: string;
|
||||
publicationDate?: string;
|
||||
serial?: string;
|
||||
size?: SizeOfString;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* tslint:disable */
|
||||
import { DialogOfString } from './dialog-of-string';
|
||||
import { IPublicUserInfo } from './ipublic-user-info';
|
||||
export interface ResponseArgs {
|
||||
dialog?: DialogOfString;
|
||||
error: boolean;
|
||||
invalidProperties?: {[key: string]: string};
|
||||
message?: string;
|
||||
requestId?: number;
|
||||
userInfo?: IPublicUserInfo;
|
||||
}
|
||||
|
||||
14
apps/swagger/cat/src/lib/models/successor.ts
Normal file
14
apps/swagger/cat/src/lib/models/successor.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/* tslint:disable */
|
||||
import { ProductDTO } from './product-dto';
|
||||
export interface Successor extends ProductDTO{
|
||||
|
||||
/**
|
||||
* PK
|
||||
*/
|
||||
id?: number;
|
||||
|
||||
/**
|
||||
* Ab
|
||||
*/
|
||||
start?: string;
|
||||
}
|
||||
@@ -30,7 +30,6 @@ export { DialogOfString } from './models/dialog-of-string';
|
||||
export { DialogSettings } from './models/dialog-settings';
|
||||
export { DialogContentType } from './models/dialog-content-type';
|
||||
export { KeyValueDTOOfStringAndString } from './models/key-value-dtoof-string-and-string';
|
||||
export { IPublicUserInfo } from './models/ipublic-user-info';
|
||||
export { ProblemDetails } from './models/problem-details';
|
||||
export { ResponseArgsOfPackageDTO } from './models/response-args-of-package-dto';
|
||||
export { ResponseArgsOfNullableBoolean } from './models/response-args-of-nullable-boolean';
|
||||
@@ -85,11 +84,11 @@ export { VATValueDTO } from './models/vatvalue-dto';
|
||||
export { VATType } from './models/vattype';
|
||||
export { QuantityValueDTO } from './models/quantity-value-dto';
|
||||
export { QueryTokenDTO } from './models/query-token-dto';
|
||||
export { ResponseArgsOfProductListDTO } from './models/response-args-of-product-list-dto';
|
||||
export { ResponseArgsOfString } from './models/response-args-of-string';
|
||||
export { DocumentPayloadOfIEnumerableOfProductListItemDTO } from './models/document-payload-of-ienumerable-of-product-list-item-dto';
|
||||
export { ListResponseArgsOfProductListDTO } from './models/list-response-args-of-product-list-dto';
|
||||
export { ResponseArgsOfIEnumerableOfProductListDTO } from './models/response-args-of-ienumerable-of-product-list-dto';
|
||||
export { ResponseArgsOfProductListDTO } from './models/response-args-of-product-list-dto';
|
||||
export { ResponseArgsOfProductListItemDTO } from './models/response-args-of-product-list-item-dto';
|
||||
export { BatchResponseArgsOfProductListItemDTOAndString } from './models/batch-response-args-of-product-list-item-dtoand-string';
|
||||
export { KeyValuePairOfStringAndProductListItemDTO } from './models/key-value-pair-of-string-and-product-list-item-dto';
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
/* tslint:disable */
|
||||
export interface IPublicUserInfo {
|
||||
alias?: string;
|
||||
displayName?: string;
|
||||
isAuthenticated: boolean;
|
||||
username?: string;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ export interface PackageDTO2 extends PackageArrivalStatusDTO{
|
||||
app?: string;
|
||||
complainedEmail?: string;
|
||||
creditRequestedEmail?: string;
|
||||
features?: {[key: string]: string};
|
||||
items?: number;
|
||||
itemsOrdered?: number;
|
||||
missing?: string;
|
||||
|
||||
@@ -10,6 +10,7 @@ export interface ProductListDTO2 extends EntityDTOBase{
|
||||
command?: string;
|
||||
commandData?: string;
|
||||
description?: string;
|
||||
key?: string;
|
||||
name?: string;
|
||||
organizationalUnit?: string;
|
||||
parent?: EntityDTOContainerOfProductListDTO2;
|
||||
|
||||
@@ -12,6 +12,7 @@ export interface ProductListItemDTO2 extends EntityDTOBase{
|
||||
command?: string;
|
||||
commandData?: string;
|
||||
description?: string;
|
||||
key?: string;
|
||||
name?: string;
|
||||
organizationalUnit?: string;
|
||||
parent?: EntityDTOContainerOfProductListItemDTO2;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* tslint:disable */
|
||||
import { DialogOfString } from './dialog-of-string';
|
||||
import { IPublicUserInfo } from './ipublic-user-info';
|
||||
export interface ResponseArgs {
|
||||
dialog?: DialogOfString;
|
||||
error: boolean;
|
||||
invalidProperties?: {[key: string]: string};
|
||||
message?: string;
|
||||
requestId?: number;
|
||||
userInfo?: IPublicUserInfo;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ import { map as __map, filter as __filter } from 'rxjs/operators';
|
||||
import { ResponseArgsOfQuerySettingsDTO } from '../models/response-args-of-query-settings-dto';
|
||||
import { ListResponseArgsOfProductListItemDTO } from '../models/list-response-args-of-product-list-item-dto';
|
||||
import { QueryTokenDTO } from '../models/query-token-dto';
|
||||
import { ResponseArgsOfProductListDTO } from '../models/response-args-of-product-list-dto';
|
||||
import { ProductListDTO } from '../models/product-list-dto';
|
||||
import { ProductListItemDTO } from '../models/product-list-item-dto';
|
||||
import { ResponseArgsOfString } from '../models/response-args-of-string';
|
||||
import { DocumentPayloadOfIEnumerableOfProductListItemDTO } from '../models/document-payload-of-ienumerable-of-product-list-item-dto';
|
||||
import { ListResponseArgsOfProductListDTO } from '../models/list-response-args-of-product-list-dto';
|
||||
import { ResponseArgsOfProductListDTO } from '../models/response-args-of-product-list-dto';
|
||||
import { ProductListDTO } from '../models/product-list-dto';
|
||||
import { ResponseArgsOfProductListItemDTO } from '../models/response-args-of-product-list-item-dto';
|
||||
import { ProductListItemDTO } from '../models/product-list-item-dto';
|
||||
import { BatchResponseArgsOfProductListItemDTOAndString } from '../models/batch-response-args-of-product-list-item-dtoand-string';
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -24,6 +24,9 @@ import { BatchResponseArgsOfProductListItemDTOAndString } from '../models/batch-
|
||||
class ProductListService extends __BaseService {
|
||||
static readonly ProductListQueryProductListItemsSettingsPath = '/inventory/productlist/items/s/settings';
|
||||
static readonly ProductListQueryProductListItemPath = '/inventory/productlist/items/s';
|
||||
static readonly ProductListGetProductListPath = '/inventory/productlist/key/{key}';
|
||||
static readonly ProductListCreateOrUpdateProductlistPath = '/inventory/productlist/{key}';
|
||||
static readonly ProductListAddOrUpdateProductListItemsPath = '/inventory/productlist/{key}/items';
|
||||
static readonly ProductListProductListItemPdfAsBase64Path = '/inventory/productlist/items/pdf/base64';
|
||||
static readonly ProductListQueryProductListPath = '/inventory/productlist/s';
|
||||
static readonly ProductListCreateProductListPath = '/inventory/productlist';
|
||||
@@ -109,6 +112,132 @@ class ProductListService extends __BaseService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Productliste by key
|
||||
* @param key undefined
|
||||
*/
|
||||
ProductListGetProductListResponse(key: string): __Observable<__StrictHttpResponse<ResponseArgsOfProductListDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
|
||||
let req = new HttpRequest<any>(
|
||||
'GET',
|
||||
this.rootUrl + `/inventory/productlist/key/${encodeURIComponent(String(key))}`,
|
||||
__body,
|
||||
{
|
||||
headers: __headers,
|
||||
params: __params,
|
||||
responseType: 'json'
|
||||
});
|
||||
|
||||
return this.http.request<any>(req).pipe(
|
||||
__filter(_r => _r instanceof HttpResponse),
|
||||
__map((_r) => {
|
||||
return _r as __StrictHttpResponse<ResponseArgsOfProductListDTO>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Productliste by key
|
||||
* @param key undefined
|
||||
*/
|
||||
ProductListGetProductList(key: string): __Observable<ResponseArgsOfProductListDTO> {
|
||||
return this.ProductListGetProductListResponse(key).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfProductListDTO)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or Update Productlist
|
||||
* @param params The `ProductListService.ProductListCreateOrUpdateProductlistParams` containing the following parameters:
|
||||
*
|
||||
* - `payload`:
|
||||
*
|
||||
* - `key`:
|
||||
*/
|
||||
ProductListCreateOrUpdateProductlistResponse(params: ProductListService.ProductListCreateOrUpdateProductlistParams): __Observable<__StrictHttpResponse<ResponseArgsOfProductListDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = params.payload;
|
||||
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/inventory/productlist/${encodeURIComponent(String(params.key))}`,
|
||||
__body,
|
||||
{
|
||||
headers: __headers,
|
||||
params: __params,
|
||||
responseType: 'json'
|
||||
});
|
||||
|
||||
return this.http.request<any>(req).pipe(
|
||||
__filter(_r => _r instanceof HttpResponse),
|
||||
__map((_r) => {
|
||||
return _r as __StrictHttpResponse<ResponseArgsOfProductListDTO>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Create or Update Productlist
|
||||
* @param params The `ProductListService.ProductListCreateOrUpdateProductlistParams` containing the following parameters:
|
||||
*
|
||||
* - `payload`:
|
||||
*
|
||||
* - `key`:
|
||||
*/
|
||||
ProductListCreateOrUpdateProductlist(params: ProductListService.ProductListCreateOrUpdateProductlistParams): __Observable<ResponseArgsOfProductListDTO> {
|
||||
return this.ProductListCreateOrUpdateProductlistResponse(params).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfProductListDTO)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Or Update List Items
|
||||
* @param params The `ProductListService.ProductListAddOrUpdateProductListItemsParams` containing the following parameters:
|
||||
*
|
||||
* - `payload`:
|
||||
*
|
||||
* - `key`:
|
||||
*/
|
||||
ProductListAddOrUpdateProductListItemsResponse(params: ProductListService.ProductListAddOrUpdateProductListItemsParams): __Observable<__StrictHttpResponse<ListResponseArgsOfProductListItemDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = params.payload;
|
||||
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/inventory/productlist/${encodeURIComponent(String(params.key))}/items`,
|
||||
__body,
|
||||
{
|
||||
headers: __headers,
|
||||
params: __params,
|
||||
responseType: 'json'
|
||||
});
|
||||
|
||||
return this.http.request<any>(req).pipe(
|
||||
__filter(_r => _r instanceof HttpResponse),
|
||||
__map((_r) => {
|
||||
return _r as __StrictHttpResponse<ListResponseArgsOfProductListItemDTO>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Add Or Update List Items
|
||||
* @param params The `ProductListService.ProductListAddOrUpdateProductListItemsParams` containing the following parameters:
|
||||
*
|
||||
* - `payload`:
|
||||
*
|
||||
* - `key`:
|
||||
*/
|
||||
ProductListAddOrUpdateProductListItems(params: ProductListService.ProductListAddOrUpdateProductListItemsParams): __Observable<ListResponseArgsOfProductListItemDTO> {
|
||||
return this.ProductListAddOrUpdateProductListItemsResponse(params).pipe(
|
||||
__map(_r => _r.body as ListResponseArgsOfProductListItemDTO)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Artikelliste als PDF (base64)
|
||||
* @param payload DocumentPayload mit EANsK
|
||||
@@ -326,7 +455,7 @@ class ProductListService extends __BaseService {
|
||||
/**
|
||||
* @param productlistUId undefined
|
||||
*/
|
||||
ProductListProductlistCompletedResponse(productlistUId: null | string): __Observable<__StrictHttpResponse<ResponseArgsOfProductListDTO>> {
|
||||
ProductListProductlistCompletedResponse(productlistUId: string): __Observable<__StrictHttpResponse<ResponseArgsOfProductListDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
@@ -351,7 +480,7 @@ class ProductListService extends __BaseService {
|
||||
/**
|
||||
* @param productlistUId undefined
|
||||
*/
|
||||
ProductListProductlistCompleted(productlistUId: null | string): __Observable<ResponseArgsOfProductListDTO> {
|
||||
ProductListProductlistCompleted(productlistUId: string): __Observable<ResponseArgsOfProductListDTO> {
|
||||
return this.ProductListProductlistCompletedResponse(productlistUId).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfProductListDTO)
|
||||
);
|
||||
@@ -451,7 +580,7 @@ class ProductListService extends __BaseService {
|
||||
/**
|
||||
* @param productListItemUId undefined
|
||||
*/
|
||||
ProductListProductListItemCompletedResponse(productListItemUId: null | string): __Observable<__StrictHttpResponse<ResponseArgsOfProductListItemDTO>> {
|
||||
ProductListProductListItemCompletedResponse(productListItemUId: string): __Observable<__StrictHttpResponse<ResponseArgsOfProductListItemDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
@@ -476,7 +605,7 @@ class ProductListService extends __BaseService {
|
||||
/**
|
||||
* @param productListItemUId undefined
|
||||
*/
|
||||
ProductListProductListItemCompleted(productListItemUId: null | string): __Observable<ResponseArgsOfProductListItemDTO> {
|
||||
ProductListProductListItemCompleted(productListItemUId: string): __Observable<ResponseArgsOfProductListItemDTO> {
|
||||
return this.ProductListProductListItemCompletedResponse(productListItemUId).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfProductListItemDTO)
|
||||
);
|
||||
@@ -519,6 +648,22 @@ class ProductListService extends __BaseService {
|
||||
|
||||
module ProductListService {
|
||||
|
||||
/**
|
||||
* Parameters for ProductListCreateOrUpdateProductlist
|
||||
*/
|
||||
export interface ProductListCreateOrUpdateProductlistParams {
|
||||
payload: ProductListDTO;
|
||||
key: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for ProductListAddOrUpdateProductListItems
|
||||
*/
|
||||
export interface ProductListAddOrUpdateProductListItemsParams {
|
||||
payload: Array<ProductListItemDTO>;
|
||||
key: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for ProductListCreateProductList
|
||||
*/
|
||||
@@ -541,7 +686,7 @@ module ProductListService {
|
||||
* Parameters for ProductListGetProductlistItems
|
||||
*/
|
||||
export interface ProductListGetProductlistItemsParams {
|
||||
productlistUId: null | string;
|
||||
productlistUId: string;
|
||||
take?: null | number;
|
||||
skip?: null | number;
|
||||
}
|
||||
@@ -558,7 +703,7 @@ module ProductListService {
|
||||
* Parameters for ProductListUpdateProductListItem
|
||||
*/
|
||||
export interface ProductListUpdateProductListItemParams {
|
||||
productListItemUId: null | string;
|
||||
productListItemUId: string;
|
||||
data: ProductListItemDTO;
|
||||
locale?: null | string;
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ module StockService {
|
||||
/**
|
||||
* Filial-Nr
|
||||
*/
|
||||
branchNumber: null | string;
|
||||
branchNumber: string;
|
||||
|
||||
/**
|
||||
* Lokalisierung (optional)
|
||||
|
||||
@@ -102,7 +102,7 @@ class WareneingangService extends __BaseService {
|
||||
* Packstück-Details
|
||||
* @param packageId undefined
|
||||
*/
|
||||
WareneingangGetPackageDetailsResponse(packageId: null | string): __Observable<__StrictHttpResponse<ResponseArgsOfPackageDetailResponseDTO>> {
|
||||
WareneingangGetPackageDetailsResponse(packageId: string): __Observable<__StrictHttpResponse<ResponseArgsOfPackageDetailResponseDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
@@ -128,7 +128,7 @@ class WareneingangService extends __BaseService {
|
||||
* Packstück-Details
|
||||
* @param packageId undefined
|
||||
*/
|
||||
WareneingangGetPackageDetails(packageId: null | string): __Observable<ResponseArgsOfPackageDetailResponseDTO> {
|
||||
WareneingangGetPackageDetails(packageId: string): __Observable<ResponseArgsOfPackageDetailResponseDTO> {
|
||||
return this.WareneingangGetPackageDetailsResponse(packageId).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfPackageDetailResponseDTO)
|
||||
);
|
||||
@@ -192,8 +192,8 @@ module WareneingangService {
|
||||
*/
|
||||
export interface WareneingangChangePackageStatusParams {
|
||||
payload: PackageArrivalStatusDTO;
|
||||
packageId: null | string;
|
||||
modifier: null | string;
|
||||
packageId: string;
|
||||
modifier: string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user