Compare commits

...

38 Commits

Author SHA1 Message Date
Nino
0d88b94eac #4750 Code improvements, Check if Icon gets loaded 2024-06-04 14:24:38 +02:00
Nino
6cdbb88f6f Merge branch 'develop' into fix/4750-Remission-Fehlende-Format-Icons 2024-06-04 13:08:39 +02:00
Nino Righi
43d8d220c9 Merged PR 1782: #4750 Check if Icon File exists
#4750 Check if Icon File exists
2024-05-28 16:03:15 +00:00
Nino Righi
e0993d9c46 Merged PR 1781: #4599 Fix Routing After Click on Continue Shopping CTA - On Tablet Size or Sm...
#4599 Fix Routing After Click on Continue Shopping CTA - On Tablet Size or Smaller
2024-05-28 15:57:54 +00:00
Nino Righi
82656d9b27 Merged PR 1780: #4314 Navigation on Product Cover Click
#4314 Navigation on Product Cover Click
2024-05-28 15:57:31 +00:00
Nino
19f892fd46 #4750 Check if Icon File exists 2024-05-28 17:20:05 +02:00
Lorenz Hilpert
df36d0934d Merged PR 1779: #4752 Performance in der WA verbessert -> Details Seite
#4752 Performance in der WA verbessert -> Details Seite
2024-05-28 13:48:00 +00:00
Nino Righi
3a9820aa54 Merged PR 1776: #4721 Removed unnecessary check for scrolling to item
#4721 Removed unnecessary check for scrolling to item
2024-05-02 19:21:52 +00:00
Nino Righi
30ad99332e Merged PR 1775: #3751 ProductGroup and ProductGroupDetails Update
#3751 ProductGroup and ProductGroupDetails Update
2024-04-22 13:31:20 +00:00
Lorenz Hilpert
4b48275910 Merged PR 1774: AHF Performance 2024-04-19 09:54:54 +00:00
Lorenz Hilpert
d3e3316459 Merge branch 'master' into develop 2024-04-17 16:25:02 +02:00
Nino Righi
4ef1bd4df6 Merged PR 1771: #4720 Hotfix Navigation Pickup Shelf Out
#4720 Hotfix Navigation Pickup Shelf Out
2024-04-17 14:21:30 +00:00
Nino Righi
0c2a23e5d2 Merged PR 1773: #3751 Reservation List Show Compartment and ProductGroup from InStock
#3751 Reservation List Show Compartment and ProductGroup from InStock
2024-04-17 08:46:32 +00:00
Nino Righi
36bd2c1eba Merged PR 1772: #4004 Kubi Check If Customer is 18 Years old
#4004 Kubi Check If Customer is 18 Years old
2024-04-15 12:34:14 +00:00
Nino Righi
a38d2eede6 Merged PR 1770: #4709 Removed Save Special Comment CTA on Checkout Cart Review
#4709 Removed Save Special Comment CTA on Checkout Cart Review
2024-04-12 10:37:43 +00:00
Lorenz Hilpert
f5251d9069 Merge tag '3.0' into develop
3.0
2024-04-09 09:35:54 +02:00
Lorenz Hilpert
2bd21e168a Merge branch 'release/3.0' 2024-04-09 09:34:33 +02:00
Lorenz Hilpert
3661bf7580 Merge branch 'develop' into release/3.0 2024-04-03 11:59:12 +02:00
Lorenz Hilpert
9f2a6633f7 Anpasssung Selector Für E2E - Lieferadresse, Rechnugsadresse 2024-04-03 11:30:07 +02:00
Nino
3c4d0ea56c Merge branch 'release/3.0' into develop 2024-03-20 12:10:17 +01:00
Nino
56bb784c83 Added Classes and Data Attributes to package-inspection for e2e testing 2024-03-20 12:06:05 +01:00
Nino Righi
c687570b1f Merged PR 1769: #4712 Removed isShippingEnabled check from availabilities modal
#4712 Removed isShippingEnabled check from availabilities modal
2024-03-20 10:42:59 +00:00
Nino Righi
afe5d3468a Merged PR 1768: Merge Develop to Release 3.0
Merge Develop to Release 3.0
2024-03-15 10:21:12 +00:00
Nino Righi
65f43d22ee Merged PR 1767: #4706 AHF Fix History Navigation after Switching Tabs
#4706 AHF Fix History Navigation after Switching Tabs
2024-03-13 14:17:15 +00:00
Nino Righi
67203a8506 Merged PR 1766: #4696 Bugfix Cover Items
#4696 Bugfix Cover Items
2024-03-13 14:12:08 +00:00
Nino Righi
92e522dedf Merged PR 1765: #4696 PickupShelfIn Details Page Clear Previous Selected OrderItemSubsetId fr...
#4696 PickupShelfIn Details Page Clear Previous Selected OrderItemSubsetId from Store after Leaving Page to avoid side effects
2024-03-12 15:31:21 +00:00
Nino Righi
fb46d329dc Merged PR 1764: #4547 WE Updated Annotation Implementation
#4547 WE Updated Annotation Implementation
2024-03-12 14:43:00 +00:00
Lorenz Hilpert
64d0a9fdb9 Merged PR 1763: #4547 Wareneingang // Kontrolle der Service Packstücke
#4547 Wareneingang // Kontrolle der Service Packstücke
2024-03-11 14:51:46 +00:00
Nino Righi
8f47163627 Merged PR 1762: #4692 Hotfix Undefined Values in Route Url
#4692 Hotfix Undefined Values in Route Url
2024-03-07 14:33:36 +00:00
Nino Righi
49f2a44461 Merged PR 1761: #4691 Small Fixes Customer Create
#4691 Small Fixes Customer Create
2024-03-06 16:01:27 +00:00
Nino Righi
a209d59ea9 Merged PR 1760: #4532 Fallback Route if Url contains Undefined or Null values
#4532 Fallback Route if Url contains Undefined or Null values
2024-03-06 12:13:13 +00:00
Nino Righi
03124d8736 Merged PR 1759: #4688 Change PickUpShelf Navigation based on Area In or Out
#4688 Change PickUpShelf Navigation based on Area In or Out
2024-03-06 11:55:11 +00:00
Nino Righi
a3330263f8 Merged PR 1758: #4689 Pickup Shelf Out Update Quantity After FETCHED_PARTIAL in Result List
#4689 Pickup Shelf Out Update Quantity After FETCHED_PARTIAL in Result List
2024-03-04 16:45:50 +00:00
Nino Righi
89092a5f6e Merged PR 1757: #4690 PickupShelfOut Details Display FETCHED_PARTIAL Action Correctly
#4690 PickupShelfOut Details Display FETCHED_PARTIAL Action Correctly
2024-03-04 15:54:43 +00:00
Nino
42fa108bb6 Pickup Shelf Out Details with Supplier Id Filter 2024-03-01 10:43:32 +01:00
Nino
2692588357 Changed Checkout Summary Navigation To Pickup Shelf Out Filter to supplier id 16 2024-02-29 12:47:45 +01:00
Nino Righi
ec26b5f4c0 Merged PR 1756: #4684 Routing to Pickup Shelf Out Update
#4684 Routing to Pickup Shelf Out Update
2024-02-28 11:28:26 +00:00
Lorenz Hilpert
b838f4c475 Merge branch 'develop' into release/3.0 2024-02-01 18:33:25 +01:00
67 changed files with 699 additions and 206 deletions

View File

@@ -0,0 +1,31 @@
import { Directive, HostListener, Input } from '@angular/core';
import { ProductCatalogNavigationService } from '@shared/services';
@Directive({
selector: '[productImageNavigation]',
standalone: true,
})
export class NavigateOnClickDirective {
@Input('productImageNavigation') ean: string;
constructor(private readonly _productCatalogNavigation: ProductCatalogNavigationService) {}
@HostListener('click', ['$event'])
async onClick(event: MouseEvent) {
event.preventDefault();
event.stopPropagation();
if (this.ean) {
await this._navigateToProductSearchDetails();
}
}
private async _navigateToProductSearchDetails() {
await this._productCatalogNavigation
.getArticleDetailsPathByEan({
processId: Date.now(),
ean: this.ean,
extras: { queryParams: { main_qs: this.ean } },
})
.navigate();
}
}

View File

@@ -5,4 +5,5 @@
export * from './lib/product-image.service';
export * from './lib/product-image.module';
export * from './lib/product-image.pipe';
export * from './lib/product-image-navigation.directive';
export * from './lib/tokens';

View File

@@ -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,
},
});
}

View File

@@ -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>

View File

@@ -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

View File

@@ -439,11 +439,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
async navigateToResultList() {
const processId = this.applicationService.activatedProcessId;
let crumbs = await this.breadcrumb
.getBreadcrumbsByKeyAndTags$(this.applicationService.activatedProcessId, ['catalog'])
.getBreadcrumbsByKeyAndTags$(this.applicationService.activatedProcessId, ['catalog', 'details'])
.pipe(first())
.toPromise();
crumbs = crumbs.filter((crumb) => !crumb.tags?.includes('details'));
const crumb = crumbs[crumbs.length - 1];
if (!!crumb) {
await this._navigationService.getArticleSearchResultsPath(processId, { queryParams: crumb.params }).navigate();

View File

@@ -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());
}
@@ -271,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) {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);

View File

@@ -296,18 +296,8 @@ 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.listRoute({ processId: Date.now() }).path, {
queryParams: { main_qs: takeNowOrders[0].orderNumber },
queryParams: { main_qs: takeNowOrders[0].orderNumber, filter_supplier_id: '16' },
});
} catch (e) {
console.error(e);

View File

@@ -38,7 +38,6 @@
(onInit)="addAddressGroup($event)"
(onDestroy)="removeAddressGroup()"
[data]="data?.address"
[tabIndexStart]="nameFormBlock?.tabIndexEnd + 1"
[requiredMarks]="addressRequiredMarks"
[validatorFns]="addressValidatorFns"
[readonly]="readonly"

View File

@@ -1,6 +1,6 @@
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';
@@ -190,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)),
@@ -378,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;

View File

@@ -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];

View File

@@ -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'];

View File

@@ -42,6 +42,7 @@
<img
class="thumbnail"
loading="lazy"
[productImageNavigation]="orderItem?.product?.ean"
*ngIf="orderItem?.product?.ean | productImage; let productImage"
[src]="productImage"
[alt]="orderItem?.product?.name"

View File

@@ -1,6 +1,6 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProductImageModule } from 'apps/cdn/product-image/src/public-api';
import { NavigateOnClickDirective, ProductImageModule } from 'apps/cdn/product-image/src/public-api';
import { UiIconModule } from '@ui/icon';
import { UiInputModule } from '@ui/input';
import { FormsModule } from '@angular/forms';
@@ -8,7 +8,7 @@ import { GoodsInListItemComponent } from './goods-in-list-item.component';
import { PipesModule } from 'apps/shared/components/goods-in-out/src/lib/pipes/pipes.module';
@NgModule({
imports: [CommonModule, PipesModule, UiIconModule, ProductImageModule, FormsModule, UiInputModule],
imports: [CommonModule, PipesModule, UiIconModule, ProductImageModule, FormsModule, UiInputModule, NavigateOnClickDirective],
exports: [GoodsInListItemComponent],
declarations: [GoodsInListItemComponent],
providers: [],

View File

@@ -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;
}

View File

@@ -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">

View File

@@ -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();

View File

@@ -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.

View File

@@ -125,6 +125,7 @@ export abstract class PickupShelfDetailsBaseComponent {
processingStatus: updatedItem.processingStatus,
compartmentCode: updatedItem.compartmentCode,
compartmentInfo: updatedItem.compartmentInfo,
quantity: updatedItem.quantity,
},
});
});

View File

@@ -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">

View File

@@ -18,6 +18,7 @@ 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',
@@ -38,6 +39,7 @@ import { isEqual } from 'lodash';
PickupShelfAddToPreviousCompartmentCodeLabelPipe,
UiSpinnerModule,
OnInitDirective,
SkeletonLoaderComponent,
],
})
export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseComponent implements OnInit, AfterViewInit {
@@ -54,12 +56,12 @@ export class PickupShelfInDetailsComponent extends PickupShelfDetailsBaseCompone
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;
@@ -115,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() {

View File

@@ -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 } });
}
});
}
}

View File

@@ -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;

View File

@@ -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;
// }
}

View File

@@ -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">

View File

@@ -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,7 +87,7 @@ 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);
@@ -105,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(

View File

@@ -32,7 +32,11 @@
</div>
<div class="page-pickup-shelf-details-item__item-container">
<div class="page-pickup-shelf-details-item__thumbnail">
<img [src]="orderItem.product?.ean | productImage" [alt]="orderItem.product?.name" />
<img
[productImageNavigation]="orderItem?.product?.ean"
[src]="orderItem.product?.ean | productImage"
[alt]="orderItem.product?.name"
/>
</div>
<div class="page-pickup-shelf-details-item__details">
<div class="flex flex-row justify-between items-start mb-[1.3125rem]">

View File

@@ -12,7 +12,7 @@ import {
inject,
} from '@angular/core';
import { FormsModule, ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
import { ProductImageModule } from '@cdn/product-image';
import { NavigateOnClickDirective, ProductImageModule } from '@cdn/product-image';
import { DBHOrderItemListItemDTO, OrderDTO, ReceiptDTO } from '@swagger/oms';
import { UiCommonModule } from '@ui/common';
import { UiTooltipModule } from '@ui/tooltip';
@@ -57,6 +57,7 @@ export interface PickUpShelfDetailsItemComponentState {
IconModule,
UiQuantityDropdownModule,
NotificationTypePipe,
NavigateOnClickDirective,
],
})
export class PickUpShelfDetailsItemComponent extends ComponentStore<PickUpShelfDetailsItemComponentState> implements OnInit {

View File

@@ -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>

View File

@@ -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,

View File

@@ -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"
@@ -15,6 +15,7 @@
class="page-pickup-shelf-list-item__item-image w-[3.125rem] max-h-[4.9375rem]"
loading="lazy"
*ngIf="item?.product?.ean | productImage; let productImage"
[productImageNavigation]="item?.product?.ean"
[src]="productImage"
[alt]="item?.product?.name"
/>

View File

@@ -1,7 +1,7 @@
import { CurrencyPipe, DatePipe, NgFor, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, ElementRef, Input, inject } from '@angular/core';
import { RouterLink, RouterLinkActive } from '@angular/router';
import { ProductImageModule } from '@cdn/product-image';
import { NavigateOnClickDirective, ProductImageModule } from '@cdn/product-image';
import { EnvironmentService } from '@core/environment';
import { IconModule } from '@shared/components/icon';
import { DBHOrderItemListItemDTO } from '@swagger/oms';
@@ -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',
@@ -30,10 +31,13 @@ import { map } from 'rxjs/operators';
ProductImageModule,
UiCommonModule,
PickupShelfProcessingStatusPipe,
NavigateOnClickDirective,
],
providers: [PickupShelfProcessingStatusPipe],
})
export class PickUpShelfListItemComponent {
private cache = inject(CacheService);
store = inject(PickupShelfStore);
@Input() item: DBHOrderItemListItemDTO;
@@ -85,6 +89,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' });
}

View File

@@ -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;
@@ -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;

View File

@@ -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 { debounceTime, delayWhen, distinctUntilChanged, 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';
@@ -27,7 +27,6 @@ import { CacheService } from '@core/cache';
import { RunCheckTrigger } from '../trigger';
import { DomainReceiptService } from '@domain/oms';
import { PickupShelfStore } from './pickup-shelf.store';
import { isEqual } from 'lodash';
@Injectable()
export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsState> {
@@ -57,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);
@@ -212,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() {
@@ -334,6 +349,7 @@ export class PickupShelfDetailsStore extends ComponentStore<PickupShelfDetailsSt
fetchOrder = this.effect((trigger$: Observable<{ orderId: number }>) =>
trigger$.pipe(
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;
}

View File

@@ -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;
};

View File

@@ -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({});

View File

@@ -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],

View File

@@ -1,2 +1 @@
export * from './product-group.pipe';
export * from './remission-pipe.module';

View File

@@ -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 {}

View File

@@ -21,16 +21,24 @@
</div>
<div class="product-data-grid grid gap-6 items-start">
<div>
<img class="max-w-full max-h-full shadow rounded" src="{{ item.ean | productImage }}" alt="item.dto.product.name" />
<img
[productImageNavigation]="item?.ean"
class="max-w-full max-h-full shadow rounded"
src="{{ item.ean | productImage }}"
alt="item.dto.product.name"
/>
</div>
<div class="grid grid-flow-row gap-1 w-48">
<div
class="overflow-hidden overflow-ellipsis whitespace-nowrap"
*ngIf="!!item.format && !!item.formatDetail && item.format !== 'UNKNOWN'"
>
<img class="inline" src="/assets/images/Icon_{{ item.dto.product.format }}.svg" [alt]="item.formatDetail" />
<span class="ml-1 font-bold format-detail">{{ item.formatDetail }}</span>
<div class="overflow-hidden overflow-ellipsis whitespace-nowrap" *ngIf="formatAvailable">
<img
*ngIf="formatIconAvailable"
class="inline mr-1"
[src]="formatIconUrl"
[alt]="item.formatDetail"
(error)="formatIconAvailable = false"
/>
<span class="font-bold format-detail">{{ item.formatDetail }}</span>
</div>
<div class="font-bold ean">
{{ item.ean }}

View File

@@ -10,7 +10,7 @@ import {
} from '@swagger/remi';
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
import { mapFromReturnItemDTO, mapFromReturnSuggestionDTO } from 'apps/domain/remission/src/lib/mappings';
import { BehaviorSubject, Subject } from 'rxjs';
import { Subject } from 'rxjs';
import { first, takeUntil } from 'rxjs/operators';
import { AddProductToShippingDocumentModalComponent } from '../../modals/add-product-to-shipping-document-modal/add-product-to-shipping-document-modal.component';
import { RemissionListComponentStore } from '../remission-list.component-store';
@@ -55,6 +55,16 @@ export class RemissionListItemComponent implements OnDestroy {
loading$ = this._listComponent.remittingItem$.asObservable();
get formatIconUrl() {
return `/assets/images/Icon_${this.item.dto.product.format}.svg`;
}
get formatAvailable() {
return !!this.item.format && !!this.item.formatDetail && this.item.format !== 'UNKNOWN';
}
formatIconAvailable: boolean = true;
constructor(
private _modal: UiModalService,
private _remissionService: DomainRemissionService,

View File

@@ -2,12 +2,13 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RemissionListItemComponent } from './remission-list-item.component';
import { ProductImageModule } from '@cdn/product-image';
import { NavigateOnClickDirective, ProductImageModule } from '@cdn/product-image';
import { RemissionPipeModule } from '../../pipes';
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,8 @@ import { UiSpinnerModule } from '@ui/spinner';
RemissionPipeModule,
UiTooltipModule,
AddProductToShippingDocumentModalModule,
SharedProductGroupPipe,
NavigateOnClickDirective,
],
exports: [RemissionListItemComponent],
declarations: [RemissionListItemComponent],

View File

@@ -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: [],

View File

@@ -16,9 +16,29 @@
</div>
<div class="goods-in-out-order-group-item-details">
<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" />
<img
[productImageNavigation]="item?.product?.ean"
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">

View File

@@ -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;

View File

@@ -4,12 +4,13 @@ import { CommonModule } from '@angular/common';
import { GoodsInOutOrderGroupComponent } from './goods-in-out-order-group.component';
import { GoodsInOutOrderGroupItemComponent } from './goods-in-out-order-group-item.component';
import { UiIconModule } from '@ui/icon';
import { ProductImageModule } from '@cdn/product-image';
import { NavigateOnClickDirective, ProductImageModule } from '@cdn/product-image';
import { PipesModule } from '../pipes/pipes.module';
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,8 @@ import { UiSpinnerModule } from 'apps/ui/spinner/src/lib/ui-spinner.module';
FormsModule,
UiQuantityDropdownModule,
UiSpinnerModule,
SharedProductGroupPipe,
NavigateOnClickDirective,
],
exports: [GoodsInOutOrderGroupComponent, GoodsInOutOrderGroupItemComponent],
declarations: [GoodsInOutOrderGroupComponent, GoodsInOutOrderGroupItemComponent],

View File

@@ -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%);
}
}

View File

@@ -0,0 +1 @@
<div class="gr-bar"></div>

View File

@@ -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];
}

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,6 @@
{
"$schema": "../../../../node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -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>();

View File

@@ -0,0 +1 @@
export * from './lib/product-group.pipe';

View File

@@ -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) => {

View File

@@ -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';

View File

@@ -1,7 +0,0 @@
/* tslint:disable */
export interface IPublicUserInfo {
alias?: string;
displayName?: string;
isAuthenticated: boolean;
username?: string;
}

View File

@@ -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;

View File

@@ -10,6 +10,7 @@ export interface ProductListDTO2 extends EntityDTOBase{
command?: string;
commandData?: string;
description?: string;
key?: string;
name?: string;
organizationalUnit?: string;
parent?: EntityDTOContainerOfProductListDTO2;

View File

@@ -12,6 +12,7 @@ export interface ProductListItemDTO2 extends EntityDTOBase{
command?: string;
commandData?: string;
description?: string;
key?: string;
name?: string;
organizationalUnit?: string;
parent?: EntityDTOContainerOfProductListItemDTO2;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -684,7 +684,7 @@ module StockService {
/**
* Filial-Nr
*/
branchNumber: null | string;
branchNumber: string;
/**
* Lokalisierung (optional)

View File

@@ -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;
}
}