mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Compare commits
50 Commits
feature/re
...
2.3-202306
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bc265a358 | ||
|
|
264d914044 | ||
|
|
12f1e7c3af | ||
|
|
9eb4fbab65 | ||
|
|
8d1a63e47f | ||
|
|
e449e612c1 | ||
|
|
6ba65f031b | ||
|
|
f31ac4c2e3 | ||
|
|
f980f5aaf9 | ||
|
|
87a1e8a2c4 | ||
|
|
5bb9ebd6ec | ||
|
|
45ab1e9cc5 | ||
|
|
8d2685a8c3 | ||
|
|
d38c41a99d | ||
|
|
ff3dacde39 | ||
|
|
90b752e185 | ||
|
|
3ed9227508 | ||
|
|
9cfe8176d4 | ||
|
|
3999b8f623 | ||
|
|
c8f54b8be5 | ||
|
|
413d2f5178 | ||
|
|
35c2a6a046 | ||
|
|
1df201525c | ||
|
|
ef72dcf554 | ||
|
|
c228147c00 | ||
|
|
4b56b973c8 | ||
|
|
28a00b9f22 | ||
|
|
b1fe692de5 | ||
|
|
08b2f6cbc9 | ||
|
|
10e1db388f | ||
|
|
cd7f71b968 | ||
|
|
9361a631dd | ||
|
|
59c5abfd93 | ||
|
|
633c23a6f0 | ||
|
|
779e7323e2 | ||
|
|
6e7fbd940b | ||
|
|
6878b608fc | ||
|
|
a4fab8b64e | ||
|
|
21c0cc8794 | ||
|
|
7ea11ea0c4 | ||
|
|
778343f636 | ||
|
|
d2fb3b6c85 | ||
|
|
4c7b5eec38 | ||
|
|
35068e23cd | ||
|
|
bc30b86cce | ||
|
|
461f166e33 | ||
|
|
ad95faffa7 | ||
|
|
a0eb3c0459 | ||
|
|
fea435a6d2 | ||
|
|
ea9920c4d5 |
@@ -1635,5 +1635,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,7 @@ export class DomainAvailabilityService {
|
||||
),
|
||||
map(([response, supplier, defaultBranch]) => {
|
||||
const price = item?.price;
|
||||
return this._mapToTakeAwayAvailability({ response, supplier, branchId: branch.id ?? defaultBranch.id, quantity, price });
|
||||
return this._mapToTakeAwayAvailability({ response, supplier, branchId: branch?.id ?? defaultBranch?.id, quantity, price });
|
||||
}),
|
||||
shareReplay(1)
|
||||
);
|
||||
@@ -540,6 +540,7 @@ export class DomainAvailabilityService {
|
||||
return preferred.map((p) => {
|
||||
return [
|
||||
{
|
||||
orderDeadline: p?.orderDeadline,
|
||||
availabilityType: p?.status,
|
||||
ssc: p?.ssc,
|
||||
sscText: p?.sscText,
|
||||
@@ -561,7 +562,6 @@ export class DomainAvailabilityService {
|
||||
|
||||
private _mapToShippingAvailability(availabilities: SwaggerAvailabilityDTO[]) {
|
||||
const preferred = availabilities.filter((f) => f.preferred === 1);
|
||||
|
||||
return preferred.map((p) => {
|
||||
return {
|
||||
availabilityType: p?.status,
|
||||
@@ -575,6 +575,7 @@ export class DomainAvailabilityService {
|
||||
supplierInfo: p?.requestStatusCode,
|
||||
lastRequest: p?.requested,
|
||||
itemId: p.itemId,
|
||||
priceMaintained: p.priceMaintained,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ export class CollectOnDeliveryNoteActionHandler extends ActionHandler<OrderItems
|
||||
const response = await this.orderService
|
||||
.OrderCollectOnDeliveryNote({
|
||||
data,
|
||||
eagerLoading: 1,
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
@@ -29,7 +30,7 @@ export class CollectOnDeliveryNoteActionHandler extends ActionHandler<OrderItems
|
||||
|
||||
return {
|
||||
...context,
|
||||
receipts: response.result,
|
||||
receipts: response.result.map((r) => r.data),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActionHandler } from '@core/command';
|
||||
import { OrderService } from '@swagger/oms';
|
||||
import { OrderItemsContext } from './order-items.context';
|
||||
|
||||
@Injectable()
|
||||
export class CollectWithSmallAmountinvoiceActionHandler extends ActionHandler<OrderItemsContext> {
|
||||
constructor(private orderService: OrderService) {
|
||||
super('COLLECT_WITH_SMALLAMOUNTINVOICE');
|
||||
}
|
||||
|
||||
async handler(context: OrderItemsContext): Promise<OrderItemsContext> {
|
||||
const data: Record<number, number> = {};
|
||||
|
||||
context.items.forEach((orderItemSubsetId) => {
|
||||
data[orderItemSubsetId.orderItemSubsetId] =
|
||||
context.itemQuantity?.get(orderItemSubsetId.orderItemSubsetId) ?? orderItemSubsetId.quantity;
|
||||
});
|
||||
|
||||
const response = await this.orderService
|
||||
.OrderCollectWithSmallAmountInvoice({
|
||||
data,
|
||||
eagerLoading: 1,
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
// Für korrekte Navigation nach Aufruf, da ProcessingStatus Serverseitig auf abgeholt gesetzt wird
|
||||
context.items?.forEach((i) => (i.processingStatus = 256));
|
||||
|
||||
return {
|
||||
...context,
|
||||
receipts: response.result.map((r) => r.data),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// start:ng42.barrel
|
||||
export * from './accepted.action-handler';
|
||||
export * from './arrived.action-handler';
|
||||
export * from './assembled.action-handler';
|
||||
@@ -7,6 +6,10 @@ export * from './back-to-stock.action-handler';
|
||||
export * from './canceled-by-buyer.action-handler';
|
||||
export * from './canceled-by-retailer.action-handler';
|
||||
export * from './canceled-by-supplier.action-handler';
|
||||
export * from './change-order-item-status-base.action-handler';
|
||||
export * from './collect-on-deliverynote.action-handler';
|
||||
export * from './collect-with-smallamountinvoice.action-handler';
|
||||
export * from './create-returnitem.action-handler';
|
||||
export * from './create-shipping-note.action-handler';
|
||||
export * from './delivered.action-handler';
|
||||
export * from './determine-supplier.action-handler';
|
||||
@@ -25,16 +28,14 @@ export * from './parked.action-handler';
|
||||
export * from './placed.action-handler';
|
||||
export * from './preperation-for-shipping.action-handler';
|
||||
export * from './print-compartment-label.action-handler';
|
||||
export * from './print-pricediffqrcodelabel.action-handler';
|
||||
export * from './print-shipping-note.action-handler';
|
||||
export * from './re-ordered.action-handler';
|
||||
export * from './print-smallamountinvoice.action-handler';
|
||||
export * from './re-order.action-handler';
|
||||
export * from './re-ordered.action-handler';
|
||||
export * from './redirected-internally.action-handler';
|
||||
export * from './requested.action-handler';
|
||||
export * from './reserved.action-handler';
|
||||
export * from './returned-by-buyer.action-handler';
|
||||
export * from './shipping-note.action-handler';
|
||||
export * from './supplier-temporarily-out-of-stock.action-handler copy';
|
||||
export * from './collect-on-deliverynote.action-handler';
|
||||
export * from './create-returnitem.action-handler';
|
||||
export * from './print-pricediffqrcodelabel.action-handler';
|
||||
// end:ng42.barrel
|
||||
|
||||
@@ -27,7 +27,8 @@ export class PrintShippingNoteActionHandler extends ActionHandler<OrderItemsCont
|
||||
printerType: 'Label',
|
||||
print: async (printer) => {
|
||||
try {
|
||||
for (const group of groupBy(data?.receipts, (receipt) => receipt?.buyer?.buyerNumber)) {
|
||||
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 {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActionHandler } from '@core/command';
|
||||
import { OrderItemsContext } from './order-items.context';
|
||||
import { OMSPrintService } from '@swagger/print';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { PrintModalComponent, PrintModalData } from '@modal/printer';
|
||||
import { NativeContainerService } from 'native-container';
|
||||
import { groupBy } from '@ui/common';
|
||||
|
||||
@Injectable()
|
||||
export class PrintSmallamountinvoiceActionHandler extends ActionHandler<OrderItemsContext> {
|
||||
constructor(
|
||||
private uiModal: UiModalService,
|
||||
private omsPrintService: OMSPrintService,
|
||||
private nativeContainerService: NativeContainerService
|
||||
) {
|
||||
super('PRINT_SMALLAMOUNTINVOICE');
|
||||
}
|
||||
|
||||
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 & 128);
|
||||
for (const group of groupBy(receipts, (receipt) => receipt?.buyer?.buyerNumber)) {
|
||||
await this.omsPrintService
|
||||
.OMSPrintKleinbetragsrechnung({
|
||||
data: group?.items?.map((r) => r?.id),
|
||||
printer,
|
||||
})
|
||||
.toPromise();
|
||||
}
|
||||
return {
|
||||
error: false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
error: true,
|
||||
message: error?.message || error,
|
||||
};
|
||||
}
|
||||
},
|
||||
} as PrintModalData,
|
||||
})
|
||||
.afterClosed$.toPromise();
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
AutocompleteTokenDTO,
|
||||
BranchService,
|
||||
ChangeStockStatusCodeValues,
|
||||
HistoryDTO,
|
||||
@@ -11,9 +10,7 @@ import {
|
||||
OrderItemSubsetDTO,
|
||||
OrderListItemDTO,
|
||||
OrderService,
|
||||
QueryTokenDTO,
|
||||
ReceiptService,
|
||||
ResponseArgsOfIEnumerableOfHistoryDTO,
|
||||
StatusValues,
|
||||
StockStatusCodeService,
|
||||
ValueTupleOfLongAndReceiptTypeAndEntityDTOContainerOfReceiptDTO,
|
||||
@@ -22,7 +19,7 @@ import {
|
||||
} from '@swagger/oms';
|
||||
import { memorize } from '@utils/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, mergeMap, shareReplay } from 'rxjs/operators';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class DomainOmsService {
|
||||
@@ -191,6 +188,10 @@ export class DomainOmsService {
|
||||
);
|
||||
}
|
||||
|
||||
getOrderSource(orderId: number): Observable<string> {
|
||||
return this.getOrder(orderId).pipe(map((order) => order?.features?.orderSource));
|
||||
}
|
||||
|
||||
updateNotifications(orderId: number, changes: { selected: NotificationChannel; email: string; mobile: string }) {
|
||||
const communicationDetails = {
|
||||
email: changes.email,
|
||||
|
||||
11
apps/domain/package-inspection/src/lib/events.ts
Normal file
11
apps/domain/package-inspection/src/lib/events.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { PackageArrivalStatusDTO } from '@swagger/wws';
|
||||
|
||||
export abstract class PackageInspectionEvent {
|
||||
constructor(public readonly type: string) {}
|
||||
}
|
||||
|
||||
export class PackageStatusChangedEvent extends PackageInspectionEvent {
|
||||
constructor(public readonly packageId: string, public readonly status: PackageArrivalStatusDTO) {
|
||||
super('PackageStatusChangedEvent');
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
ListResponseArgsOfPackageDTO,
|
||||
ListResponseArgsOfPackageDTO2,
|
||||
PackageArrivalStatusDTO,
|
||||
PackageDetailResponseDTO,
|
||||
PackageDTO,
|
||||
PackageDTO2,
|
||||
QuerySettingsDTO,
|
||||
QueryTokenDTO,
|
||||
@@ -13,13 +11,18 @@ import {
|
||||
ResponseArgsOfQuerySettingsDTO,
|
||||
WareneingangService,
|
||||
} from '@swagger/wws';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { PackageInspectionEvent, PackageStatusChangedEvent } from './events';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class DomainPackageInspectionService {
|
||||
private _events = new Subject<PackageInspectionEvent>();
|
||||
|
||||
events = this._events.asObservable();
|
||||
|
||||
constructor(private _wareneingang: WareneingangService) {}
|
||||
|
||||
getQuerySettingsResponse(): Observable<ResponseArgsOfQuerySettingsDTO> {
|
||||
@@ -47,23 +50,26 @@ export class DomainPackageInspectionService {
|
||||
}
|
||||
|
||||
changePackageStatusResponse(pkg: PackageDTO2, modifier: string): Observable<ResponseArgsOfPackageArrivalStatusDTO> {
|
||||
return this._wareneingang.WareneingangChangePackageStatus({
|
||||
packageId: pkg.id,
|
||||
payload: {
|
||||
id: pkg.id,
|
||||
annotation: pkg.annotation,
|
||||
area: pkg.area,
|
||||
arrivalChecked: pkg.arrivalChecked,
|
||||
arrivalStatus: pkg.arrivalStatus,
|
||||
deliveryNoteNumber: pkg.deliveryNoteNumber,
|
||||
deliveryTarget: pkg.deliveryTarget,
|
||||
estimatedDeliveryDate: pkg.estimatedDeliveryDate,
|
||||
packageNumber: pkg.packageNumber,
|
||||
supplier: pkg.supplier,
|
||||
trackingNumber: pkg.trackingNumber,
|
||||
},
|
||||
modifier,
|
||||
});
|
||||
return this._wareneingang
|
||||
.WareneingangChangePackageStatus({
|
||||
packageId: pkg.id,
|
||||
payload: {
|
||||
id: pkg.id,
|
||||
annotation: pkg.annotation,
|
||||
area: pkg.area,
|
||||
arrivalChecked: pkg.arrivalChecked,
|
||||
arrivalStatus: pkg.arrivalStatus,
|
||||
deliveryNoteNumber: pkg.deliveryNoteNumber,
|
||||
deliveryTarget: pkg.deliveryTarget,
|
||||
estimatedDeliveryDate: pkg.estimatedDeliveryDate,
|
||||
packageNumber: pkg.packageNumber,
|
||||
supplier: pkg.supplier,
|
||||
trackingNumber: pkg.trackingNumber,
|
||||
scanId: pkg.scanId,
|
||||
},
|
||||
modifier,
|
||||
})
|
||||
.pipe(tap((res) => this._events.next(new PackageStatusChangedEvent(pkg.id, res.result))));
|
||||
}
|
||||
|
||||
changePackageStatus(pkg: PackageDTO2, modifier: string): Observable<PackageArrivalStatusDTO> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Public API Surface of package-inspection
|
||||
*/
|
||||
|
||||
export * from './lib/events';
|
||||
export * from './lib/package-inspection.service';
|
||||
export * from './lib/package-inspection.module';
|
||||
|
||||
@@ -73,10 +73,10 @@
|
||||
<ui-icon icon="documents_refresh" size="24px"></ui-icon>
|
||||
Remission
|
||||
</a>
|
||||
<a [routerLink]="['/filiale/package-inspection']" routerLinkActive="active" (click)="fetchAndOpenPackages()">
|
||||
<!-- <a [routerLink]="['/filiale/package-inspection']" routerLinkActive="active" (click)="fetchAndOpenPackages()">
|
||||
<ui-svg-icon icon="clipboard-check-outline" [size]="24"></ui-svg-icon>
|
||||
Wareneingang
|
||||
</a>
|
||||
</a> -->
|
||||
</ng-container>
|
||||
</shell-footer>
|
||||
</div>
|
||||
|
||||
@@ -94,7 +94,24 @@
|
||||
|
||||
<div class="fetching xsmall" *ngIf="store.fetchingPickUpAvailability$ | async; else showAvailabilityPickUpIcon"></div>
|
||||
<ng-template #showAvailabilityPickUpIcon>
|
||||
<ui-icon *ngIf="store.isPickUpAvailabilityAvailable$ | async" icon="box_out" size="18px"></ui-icon>
|
||||
<ui-icon
|
||||
[uiOverlayTrigger]="orderDeadlineTooltip"
|
||||
*ngIf="store.isPickUpAvailabilityAvailable$ | async"
|
||||
icon="box_out"
|
||||
size="18px"
|
||||
></ui-icon>
|
||||
|
||||
<ui-tooltip
|
||||
[warning]="true"
|
||||
yPosition="above"
|
||||
xPosition="after"
|
||||
[yOffset]="-11"
|
||||
[xOffset]="8"
|
||||
#orderDeadlineTooltip
|
||||
[closeable]="true"
|
||||
>
|
||||
<b>{{ (store.pickUpAvailability$ | async)?.orderDeadline | orderDeadline }}</b>
|
||||
</ui-tooltip>
|
||||
</ng-template>
|
||||
|
||||
<div class="fetching xsmall" *ngIf="store.fetchingDeliveryAvailability$ | async; else showAvailabilityDeliveryIcon"></div>
|
||||
|
||||
@@ -20,6 +20,7 @@ import { DateAdapter } from '@ui/common';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { PurchaseOptionsModalService } from '@shared/modals/purchase-options-modal';
|
||||
import { DomainAvailabilityService } from '@domain/availability';
|
||||
import { DomainCheckoutService } from '@domain/checkout';
|
||||
|
||||
@Component({
|
||||
selector: 'page-article-details',
|
||||
@@ -65,6 +66,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
this.store.isDeliveryB2BAvailabilityAvailable$,
|
||||
]).pipe(map(([digDelivery, b2bDelivery]) => b2bDelivery && !digDelivery));
|
||||
|
||||
customerFeatures$ = this.applicationService.activatedProcessId$.pipe(
|
||||
switchMap((processId) => this._domainCheckoutService.getCustomerFeatures({ processId }))
|
||||
);
|
||||
|
||||
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')));
|
||||
@@ -126,7 +131,8 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
public elementRef: ElementRef,
|
||||
private _purchaseOptionsModalService: PurchaseOptionsModalService,
|
||||
private _availability: DomainAvailabilityService,
|
||||
private _router: Router
|
||||
private _router: Router,
|
||||
private _domainCheckoutService: DomainCheckoutService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -270,14 +276,22 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
type: 'add',
|
||||
processId: this.applicationService.activatedProcessId,
|
||||
items: [item],
|
||||
pickupBranch: selectedBranch,
|
||||
inStoreBranch: selectedBranch,
|
||||
})
|
||||
.afterClosed$.subscribe((result) => {
|
||||
.afterClosed$.subscribe(async (result) => {
|
||||
if (result?.data === 'continue') {
|
||||
this.navigateToShoppingCart();
|
||||
console.log('continue');
|
||||
const customer = await this._domainCheckoutService
|
||||
.getBuyer({ processId: this.applicationService.activatedProcessId })
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
if (customer) {
|
||||
this.navigateToShoppingCart();
|
||||
} else {
|
||||
this.navigateToCustomerSearch();
|
||||
}
|
||||
} else if (result?.data === 'continue-shopping') {
|
||||
this.navigateToResultList();
|
||||
console.log('continue-shopping');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -286,6 +300,24 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
this._router.navigate([`/kunde/${this.applicationService.activatedProcessId}/cart/review`]);
|
||||
}
|
||||
|
||||
async navigateToCustomerSearch() {
|
||||
try {
|
||||
const response = await this.customerFeatures$
|
||||
.pipe(
|
||||
first(),
|
||||
switchMap((customerFeatures) => {
|
||||
return this._domainCheckoutService.canSetCustomer({ processId: this.applicationService.activatedProcessId, customerFeatures });
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
this._router.navigate(['/kunde', this.applicationService.activatedProcessId, 'customer', 'search'], {
|
||||
queryParams: { filter_customertype: response.filter.customertype },
|
||||
});
|
||||
} catch (error) {
|
||||
this._router.navigate(['/kunde', this.applicationService.activatedProcessId, 'customer', 'search']);
|
||||
}
|
||||
}
|
||||
|
||||
async navigateToResultList() {
|
||||
let crumbs = await this.breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this.applicationService.activatedProcessId, ['catalog'])
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ArticleRecommendationsComponent } from './recommendations/article-recom
|
||||
import { PipesModule } from '../shared/pipes/pipes.module';
|
||||
import { UiTooltipModule } from '@ui/tooltip';
|
||||
import { UiCommonModule } from '@ui/common';
|
||||
import { OrderDeadlinePipeModule } from '@shared/pipes/order-deadline';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -22,6 +23,7 @@ import { UiCommonModule } from '@ui/common';
|
||||
UiCommonModule,
|
||||
UiTooltipModule,
|
||||
PipesModule,
|
||||
OrderDeadlinePipeModule,
|
||||
],
|
||||
exports: [ArticleDetailsComponent, ArticleRecommendationsComponent],
|
||||
declarations: [ArticleDetailsComponent, ArticleRecommendationsComponent],
|
||||
|
||||
@@ -129,7 +129,11 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
|
||||
|
||||
//#region Abholung
|
||||
readonly fetchingPickUpAvailability$ = this.select((s) => s.fetchingPickUpAvailability);
|
||||
readonly pickUpAvailability$: Observable<AvailabilityDTO> = combineLatest([this.itemData$, this.branch$, this.isDownload$]).pipe(
|
||||
readonly pickUpAvailability$: Observable<AvailabilityDTO & { orderDeadline?: string }> = combineLatest([
|
||||
this.itemData$,
|
||||
this.branch$,
|
||||
this.isDownload$,
|
||||
]).pipe(
|
||||
tap(() => this.patchState({ fetchingPickUpAvailability: true, fetchingPickUpAvailabilityError: undefined })),
|
||||
switchMap(([item, branch, isDownload]) =>
|
||||
!!item && !!branch && !isDownload
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<ng-container *ngIf="filter$ | async; let filter">
|
||||
<div class="catalog-search-filter-content">
|
||||
<button class="btn-close" type="button" (click)="close.emit()">
|
||||
<ui-icon icon="close" size="20px"></ui-icon>
|
||||
</button>
|
||||
<div class="w-full flex flex-row justify-end items-center">
|
||||
<button (click)="clearFilter(filter)" class="text-[#0556B4] mr-[0.8125rem]">Alle Filter entfernen</button>
|
||||
<button class="text-cool-grey p-4 outline-none border-none bg-transparent" type="button" (click)="close.emit()">
|
||||
<ui-icon icon="close" size="20px"></ui-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="catalog-search-filter-content-main">
|
||||
<div class="catalog-search-filter-content-main -mt-8">
|
||||
<h1 class="text-3xl font-bold text-center py-4">Filter</h1>
|
||||
<ui-filter
|
||||
[filter]="filter"
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
@apply relative mx-auto p-4;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
@apply absolute text-cool-grey top-3 p-4 right-4 outline-none border-none bg-transparent;
|
||||
}
|
||||
|
||||
.catalog-search-filter-content-main {
|
||||
h1.title {
|
||||
@apply text-center;
|
||||
|
||||
@@ -58,4 +58,8 @@ export class ArticleSearchFilterComponent implements OnInit {
|
||||
const queryParams = { main_qs: value?.getQueryParams()?.main_qs || '' };
|
||||
this.articleSearch.setDefaultFilter(queryParams);
|
||||
}
|
||||
|
||||
clearFilter(value: UiFilter) {
|
||||
value.unselectAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,6 +643,7 @@ export class CheckoutReviewComponent extends ComponentStore<CheckoutReviewCompon
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
this.router.navigate(['/kunde', this.applicationService.activatedProcessId, 'customer', 'search'], {
|
||||
queryParams: { filter_customertype: response.filter.customertype },
|
||||
});
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<div class="goods-out-search-filter-content">
|
||||
<button class="btn-close" type="button" (click)="close.emit()">
|
||||
<ui-icon icon="close" size="20px"></ui-icon>
|
||||
</button>
|
||||
<div class="w-full flex flex-row justify-end items-center">
|
||||
<button (click)="clearFilter(filter)" class="text-[#0556B4] mr-[0.8125rem]">Alle Filter entfernen</button>
|
||||
<button class="text-cool-grey p-4 outline-none border-none bg-transparent" type="button" (click)="close.emit()">
|
||||
<ui-icon icon="close" size="20px"></ui-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="goods-out-search-filter-content-main">
|
||||
<div class="goods-out-search-filter-content-main -mt-8">
|
||||
<h1 class="title">Filter</h1>
|
||||
<ui-filter
|
||||
[filter]="filter"
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
@apply relative mx-auto;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
@apply absolute text-inactive-customer top-3 p-4 right-4 outline-none border-none bg-transparent;
|
||||
}
|
||||
|
||||
.goods-out-search-filter-content-main {
|
||||
@apply px-4;
|
||||
h1.title {
|
||||
|
||||
@@ -121,6 +121,10 @@ export class CustomerOrderSearchFilterComponent implements OnInit, OnDestroy {
|
||||
this.updateBreadcrumb();
|
||||
}
|
||||
|
||||
clearFilter(value: UiFilter) {
|
||||
value.unselectAll();
|
||||
}
|
||||
|
||||
getDetailsPath(item: OrderItemListItemDTO) {
|
||||
return item?.compartmentCode
|
||||
? `/kunde/${this.processId}/order/details/compartment/${encodeURIComponent(item?.compartmentCode)}/${item?.processingStatus}`
|
||||
|
||||
@@ -25,18 +25,31 @@ export class OrderBranchIdInputComponent extends AbstractUiFilterInputDirective
|
||||
ngOnInit() {
|
||||
this.control.setValue({ id: Number(this.value) });
|
||||
|
||||
const uiInputChangesSub = this.uiInput?.changes?.subscribe((changes) => {
|
||||
const controlValue = this.control?.value?.id;
|
||||
const changesValue = Number(changes?.target?.value);
|
||||
if (controlValue !== changesValue) {
|
||||
this.control.setValue(changesValue && !isNaN(changesValue) ? { id: changesValue } : undefined);
|
||||
}
|
||||
});
|
||||
|
||||
const onInputChangeSub = this.onUiInputChange$.subscribe((input) => {
|
||||
if (this.control.value !== input.value) {
|
||||
this.control.setValue(input.value ? { id: Number(input.value) } : undefined);
|
||||
const controlValue = this.control?.value?.id;
|
||||
const inputValue = Number(input?.value);
|
||||
if (controlValue !== inputValue) {
|
||||
this.control.setValue(inputValue && !isNaN(inputValue) ? { id: inputValue } : undefined);
|
||||
}
|
||||
});
|
||||
|
||||
const onControlValueChangeSub = this.control.valueChanges.subscribe((value) => {
|
||||
if (this.value !== value) {
|
||||
this.setValue(value ? String(value?.id) : undefined);
|
||||
if (!value) {
|
||||
this.setValue(undefined);
|
||||
} else if (this.value !== String(value?.id)) {
|
||||
this.setValue(String(value?.id));
|
||||
}
|
||||
});
|
||||
|
||||
this._subscriptions.add(uiInputChangesSub);
|
||||
this._subscriptions.add(onInputChangeSub);
|
||||
this._subscriptions.add(onControlValueChangeSub);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ import {
|
||||
ReOrderedActionHandler,
|
||||
CollectOnDeliveryNoteActionHandler,
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
CollectWithSmallAmountinvoiceActionHandler,
|
||||
PrintSmallamountinvoiceActionHandler,
|
||||
} from '@domain/oms';
|
||||
import { CoreCommandModule } from '@core/command';
|
||||
import { CustomerOrderRoutingModule } from './customer-order-routing.module';
|
||||
@@ -89,6 +91,8 @@ import { BreadcrumbModule } from '@shared/components/breadcrumb';
|
||||
SupplierTemporarilyOutOfStockActionHandler,
|
||||
CollectOnDeliveryNoteActionHandler,
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
CollectWithSmallAmountinvoiceActionHandler,
|
||||
PrintSmallamountinvoiceActionHandler,
|
||||
]),
|
||||
],
|
||||
exports: [CustomerOrderComponent],
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
<div class="customer-search-filter-content">
|
||||
<button class="btn-close" type="button" (click)="close.emit()">
|
||||
<ui-icon icon="close" size="20px"></ui-icon>
|
||||
</button>
|
||||
<div *ngIf="filter$ | async; let filter" class="customer-search-filter-content">
|
||||
<div class="w-full flex flex-row justify-end items-center">
|
||||
<button (click)="clearFilter(filter)" class="text-[#0556B4] mr-[0.8125rem]">Alle Filter entfernen</button>
|
||||
<button class="text-cool-grey p-4 outline-none border-none bg-transparent" type="button" (click)="close.emit()">
|
||||
<ui-icon icon="close" size="20px"></ui-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="text-3xl font-bold text-center py-4">Filter</h1>
|
||||
<h1 class="text-3xl font-bold text-center py-4 -mt-8">Filter</h1>
|
||||
|
||||
<ng-container *ngIf="filter$ | async; let filter">
|
||||
<ui-filter
|
||||
[filter]="filter"
|
||||
[loading]="store.fetching$ | async"
|
||||
(search)="applyFilter(filter)"
|
||||
[hint]="store.message$ | async"
|
||||
resizeInputOptionsToElement="page-customer-search-filter .sticky-cta-wrapper"
|
||||
[scanner]="true"
|
||||
></ui-filter>
|
||||
<ui-filter
|
||||
[filter]="filter"
|
||||
[loading]="store.fetching$ | async"
|
||||
(search)="applyFilter(filter)"
|
||||
[hint]="store.message$ | async"
|
||||
resizeInputOptionsToElement="page-customer-search-filter .sticky-cta-wrapper"
|
||||
[scanner]="true"
|
||||
></ui-filter>
|
||||
|
||||
<div class="sticky-cta-wrapper">
|
||||
<button class="cta-reset-filter" (click)="resetFilter()" [disabled]="store.fetching$ | async">
|
||||
Filter zurücksetzen
|
||||
</button>
|
||||
<button class="apply-filter" (click)="applyFilter(filter)" [disabled]="store.fetching$ | async">
|
||||
<ui-spinner [show]="store.fetching$ | async">
|
||||
Filter anwenden
|
||||
</ui-spinner>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
<div class="sticky-cta-wrapper">
|
||||
<button class="cta-reset-filter" (click)="resetFilter()" [disabled]="store.fetching$ | async">
|
||||
Filter zurücksetzen
|
||||
</button>
|
||||
<button class="apply-filter" (click)="applyFilter(filter)" [disabled]="store.fetching$ | async">
|
||||
<ui-spinner [show]="store.fetching$ | async">
|
||||
Filter anwenden
|
||||
</ui-spinner>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
@apply relative mx-auto p-4;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
@apply absolute text-cool-grey top-3 p-4 right-4 outline-none border-none bg-transparent;
|
||||
}
|
||||
|
||||
.sticky-cta-wrapper {
|
||||
@apply fixed text-center inset-x-0 bottom-0;
|
||||
bottom: 30px;
|
||||
|
||||
@@ -45,6 +45,10 @@ export class CustomerSearchFilterComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
clearFilter(value: UiFilter) {
|
||||
value.unselectAll();
|
||||
}
|
||||
|
||||
resetFilter() {
|
||||
this.store.setDefaultFilter();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<ui-checkbox
|
||||
*ngIf="customerType !== 'b2b'"
|
||||
[ngModel]="p4mUser"
|
||||
(ngModelChange)="setValue({ p4mUser: !p4mUser })"
|
||||
[disabled]="p4mReadonly || readonly"
|
||||
>
|
||||
Kundenkarte
|
||||
</ui-checkbox>
|
||||
<ng-container *ifRole="'Store'">
|
||||
<ui-checkbox
|
||||
*ngIf="customerType !== 'b2b'"
|
||||
[ngModel]="p4mUser"
|
||||
(ngModelChange)="setValue({ p4mUser: !p4mUser })"
|
||||
[disabled]="p4mReadonly || readonly"
|
||||
>
|
||||
Kundenkarte
|
||||
</ui-checkbox>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let option of filteredOptions$ | async">
|
||||
<ui-checkbox
|
||||
*ngIf="option?.enabled !== false"
|
||||
|
||||
@@ -4,9 +4,10 @@ import { CommonModule } from '@angular/common';
|
||||
import { CustomerTypeSelectorComponent } from './customer-type-selector.component';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { UiCheckboxModule } from '@ui/checkbox';
|
||||
import { AuthModule } from '@core/auth';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, FormsModule, UiCheckboxModule],
|
||||
imports: [CommonModule, FormsModule, UiCheckboxModule, AuthModule],
|
||||
exports: [CustomerTypeSelectorComponent],
|
||||
declarations: [CustomerTypeSelectorComponent],
|
||||
})
|
||||
|
||||
@@ -41,6 +41,8 @@ import {
|
||||
CollectOnDeliveryNoteActionHandler,
|
||||
CreateReturnItemActionHandler,
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
CollectWithSmallAmountinvoiceActionHandler,
|
||||
PrintSmallamountinvoiceActionHandler,
|
||||
} from '@domain/oms';
|
||||
@NgModule({
|
||||
declarations: [GoodsInComponent],
|
||||
@@ -85,6 +87,8 @@ import {
|
||||
CollectOnDeliveryNoteActionHandler,
|
||||
CreateReturnItemActionHandler,
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
CollectWithSmallAmountinvoiceActionHandler,
|
||||
PrintSmallamountinvoiceActionHandler,
|
||||
]),
|
||||
],
|
||||
exports: [GoodsInComponent],
|
||||
|
||||
@@ -39,6 +39,8 @@ import {
|
||||
ReOrderedActionHandler,
|
||||
CollectOnDeliveryNoteActionHandler,
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
CollectWithSmallAmountinvoiceActionHandler,
|
||||
PrintSmallamountinvoiceActionHandler,
|
||||
} from '@domain/oms';
|
||||
import { CoreCommandModule } from '@core/command';
|
||||
import { ShellBreadcrumbModule } from '@shell/breadcrumb';
|
||||
@@ -87,6 +89,8 @@ import { GoodsInRoutingModule } from './good-out-routing.module';
|
||||
SupplierTemporarilyOutOfStockActionHandler,
|
||||
CollectOnDeliveryNoteActionHandler,
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
CollectWithSmallAmountinvoiceActionHandler,
|
||||
PrintSmallamountinvoiceActionHandler,
|
||||
]),
|
||||
],
|
||||
exports: [GoodsOutComponent],
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</div>
|
||||
|
||||
<div class="package-details-list-item__product-details-2" *ngIf="showStockInfos$ | async">
|
||||
<div class="package-details-list-item__inventory-quantity py-2">
|
||||
<div class="package-details-list-item__inventory-quantity">
|
||||
<div class="grow">
|
||||
<ng-container *ngIf="showStockInfoTooltip$ | async">
|
||||
<button
|
||||
@@ -61,6 +61,7 @@
|
||||
<span class="liefermenge isa-label bg-white text-black px-2 font-bold">{{ item?.quantity }}x</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="package-details-list-item__ssc-text" *ngIf="item?.quantity == 0 && (sscText$ | async)">MS: {{ sscText$ | async }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -69,11 +69,15 @@
|
||||
}
|
||||
|
||||
.package-details-list-item__inventory-quantity {
|
||||
@apply leading-7 flex flex-row items-center;
|
||||
@apply leading-8 flex flex-row items-center;
|
||||
}
|
||||
|
||||
.package-details-list-item__package-quantity {
|
||||
@apply leading-9 flex flex-row items-center;
|
||||
@apply leading-8 flex flex-row items-center;
|
||||
}
|
||||
|
||||
.package-details-list-item__ssc-text {
|
||||
@apply leading-8 flex flex-row items-center;
|
||||
}
|
||||
|
||||
:host.light {
|
||||
|
||||
@@ -24,6 +24,8 @@ export class PackageDetailsListItemComponent implements OnChanges {
|
||||
|
||||
inStock$ = this._itemSubject.pipe(switchMap((item) => this._store.getInStockByEan$(item.product.ean)));
|
||||
|
||||
sscText$ = this._itemSubject.pipe(switchMap((item) => this._store.getSscTextByEan$(item.product.ean)));
|
||||
|
||||
showStockInfoTooltip$ = this._store.arrivalStatus$.pipe(map((arrivalStatus) => arrivalStatus === 0));
|
||||
|
||||
showStockInfos$ = this._store.arrivalStatus$.pipe(map((arrivalStatus) => arrivalStatus !== 8));
|
||||
|
||||
@@ -65,6 +65,10 @@ export class PackageDetailsListStore extends ComponentStore<PackageDetailsListSt
|
||||
}
|
||||
};
|
||||
|
||||
static SSC_TEXT_BY_EAN = (ean: string) => (state: PackageDetailsListState) => {
|
||||
return state.items.find((i) => i.product.ean === ean)?.ssc;
|
||||
};
|
||||
|
||||
static COMPARTMENTY_BY_EAN = (ean: string) => (state: PackageDetailsListState) => {
|
||||
const stockInfoCompartment = PackageDetailsListStore.STOCKINFO_BY_EAN(ean)(state)?.compartment;
|
||||
|
||||
@@ -145,6 +149,10 @@ export class PackageDetailsListStore extends ComponentStore<PackageDetailsListSt
|
||||
return this.select(PackageDetailsListStore.IN_STOCK_BY_EAN_SELECTOR(ean));
|
||||
}
|
||||
|
||||
getSscTextByEan$(ean: string) {
|
||||
return this.select(PackageDetailsListStore.SSC_TEXT_BY_EAN(ean));
|
||||
}
|
||||
|
||||
getCompartmentByEan(ean: string) {
|
||||
return this.get(PackageDetailsListStore.COMPARTMENTY_BY_EAN(ean));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="w-80">
|
||||
<span class="page-package-list-item__package-number">
|
||||
<div class="w-64">
|
||||
<span class="page-package-list-item__package-number truncate">
|
||||
{{ package?.packageNumber }}
|
||||
</span>
|
||||
<span class="page-package-list-item__number-divider" *ngIf="package?.packageNumber && package?.deliveryNoteNumber"> | </span>
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="w-32 page-package-list-item__items-count">{{ package?.items }} <span class="font-normal">Exemplare</span></div>
|
||||
<div class="text-right grow">
|
||||
<div
|
||||
class="rounded inline-block px-4 text-white page-package-list-item__arrival-status"
|
||||
class="rounded inline-block px-4 text-white page-package-list-item__arrival-status whitespace-nowrap"
|
||||
[class]="package?.arrivalStatus | arrivalStatusColorClass"
|
||||
>
|
||||
{{ package?.arrivalStatus | arrivalStatus }}
|
||||
|
||||
@@ -37,7 +37,7 @@ export class WrongDestinationModalComponent {
|
||||
async done(): Promise<void> {
|
||||
let promises: Promise<PackageArrivalStatusDTO>[] = [];
|
||||
for (const pkg of this.packages) {
|
||||
promises.push(this._packageInspectionService.changePackageStatus(pkg, '0').toPromise());
|
||||
promises.push(this._packageInspectionService.changePackageStatus(pkg, '8').toPromise());
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
korrekt?
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white" *ngSwitchCa se="'Fehlt'">
|
||||
<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 />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DomainPackageInspectionService } from '@domain/package-inspection';
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { DomainPackageInspectionService, PackageStatusChangedEvent } from '@domain/package-inspection';
|
||||
import { ComponentStore, OnStoreInit, tapResponse } from '@ngrx/component-store';
|
||||
import { ListResponseArgsOfPackageDTO2, PackageDTO2, QuerySettingsDTO } from '@swagger/wws';
|
||||
import { UiFilter } from '@ui/filter';
|
||||
@@ -9,11 +9,15 @@ import { debounceTime, filter, switchMap, takeUntil, tap, withLatestFrom } from
|
||||
import { INITIAL_RESULT_COMPONENT_STATE, PackageResultComponentState } from './package-result.component.state';
|
||||
|
||||
@Injectable()
|
||||
export class PackageResultComponentStore extends ComponentStore<PackageResultComponentState> implements OnStoreInit {
|
||||
export class PackageResultComponentStore extends ComponentStore<PackageResultComponentState> implements OnStoreInit, OnDestroy {
|
||||
showFilter$ = this.select((state) => state.showFilter);
|
||||
|
||||
fetching$ = this.select((state) => state.fetching);
|
||||
|
||||
get fetching(): boolean {
|
||||
return this.get((f) => f.fetching);
|
||||
}
|
||||
|
||||
filter$ = this.select((state) => state.filter);
|
||||
|
||||
get filter(): UiFilter {
|
||||
@@ -48,6 +52,17 @@ export class PackageResultComponentStore extends ComponentStore<PackageResultCom
|
||||
|
||||
ngrxOnStoreInit() {
|
||||
this.fetchSettings();
|
||||
|
||||
this._packageInspectionService.events.pipe(takeUntil(this.destroy$)).subscribe((event) => {
|
||||
if (event instanceof PackageStatusChangedEvent) {
|
||||
this.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
super.ngOnDestroy();
|
||||
this.cancelFetchPackages();
|
||||
}
|
||||
|
||||
setShowFilter = this.updater((state, showFilter: boolean) => ({ ...state, showFilter }));
|
||||
@@ -66,6 +81,19 @@ export class PackageResultComponentStore extends ComponentStore<PackageResultCom
|
||||
|
||||
setTotal = this.updater((state, total: number) => ({ ...state, total }));
|
||||
|
||||
refresh = this.effect(($) =>
|
||||
$.pipe(
|
||||
debounceTime(250),
|
||||
withLatestFrom(this.filter$, this.packages$),
|
||||
tap(() => this.cancelFetchPackages()),
|
||||
switchMap(([_, filter, packages]) =>
|
||||
this._packageInspectionService
|
||||
.queryPackagesResponse({ ...filter.getQueryToken(), skip: 0, take: Math.max(packages.length, 50) })
|
||||
.pipe(takeUntil(this._cancleFetchPackages$), tapResponse(this.onFetchPackagesResponse, this.onFetchError))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
fetchSettings = this.effect(($) =>
|
||||
$.pipe(
|
||||
switchMap((_) => this._packageInspectionService.getQuerySettings().pipe(tapResponse(this.onFetchSettingsResponse, this.onFetchError)))
|
||||
|
||||
@@ -14,6 +14,7 @@ import { filter, first, map } from 'rxjs/operators';
|
||||
import { PackageListComponent } from '../components/package-list';
|
||||
import { PackageResultCacheData } from './package-result-cache-data';
|
||||
import { PackageResultComponentStore } from './package-result.component.store';
|
||||
import { PackageInspectionNavigationService } from '../services/package-inspection-navigation.service';
|
||||
|
||||
@Component({
|
||||
selector: 'page-package-result',
|
||||
@@ -53,7 +54,8 @@ export class PackageResultComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
private _config: Config,
|
||||
private _breadcrumb: BreadcrumbService,
|
||||
private _router: Router,
|
||||
private _cache: CacheService
|
||||
private _cache: CacheService,
|
||||
private _navigation: PackageInspectionNavigationService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -84,7 +86,7 @@ export class PackageResultComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
const filterSub = combineLatest([initialFilter$, queryParams$]).subscribe(([filter, queryParams]) => {
|
||||
const restoredFilter = this.restoreFilterFromQueryParams(filter, queryParams);
|
||||
const restoredData = this.restoreResultsFromCache(restoredFilter);
|
||||
this.createBreadcrumbIfNotExists(this.store.filter);
|
||||
this.createBreadcrumbIfNotExists(restoredFilter || this.store.filter);
|
||||
this.fetchPackages(restoredFilter, { keep: true, take: restoredData?.packages?.length });
|
||||
});
|
||||
|
||||
@@ -155,6 +157,8 @@ export class PackageResultComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
if (response.result.length === 0) {
|
||||
this.hint$.next('Keine Pakete gefunden');
|
||||
return;
|
||||
} else if (response.result.length === 1) {
|
||||
this._navigation.details(response.result[0].id).navigate();
|
||||
}
|
||||
|
||||
this.cacheData({});
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PackageInspectionModule } from '../package-inspection.module';
|
||||
import { Params, Router } from '@angular/router';
|
||||
|
||||
@Injectable({ providedIn: PackageInspectionModule })
|
||||
export interface Navigation {
|
||||
path: any[];
|
||||
queryParams?: Params;
|
||||
navigate: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PackageInspectionNavigationService {
|
||||
constructor() {}
|
||||
constructor(private _router: Router) {}
|
||||
|
||||
navigateToPackageList(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
details(id: string): Navigation {
|
||||
const path = [`/filiale/package-inspection/packages/${id}`];
|
||||
|
||||
navigateToPackageDetails(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
return {
|
||||
path,
|
||||
navigate: () => this._router.navigate(path),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,14 +207,18 @@ export class BranchSelectorComponent implements OnInit, OnDestroy, AfterViewInit
|
||||
|
||||
clear() {
|
||||
this.setBranch();
|
||||
this.emitValues();
|
||||
this.complete.next('');
|
||||
this.onChange(undefined);
|
||||
this.onTouched();
|
||||
this.valueChange.emit(undefined);
|
||||
}
|
||||
|
||||
emitValues(branch?: BranchDTO) {
|
||||
this.onChange(branch);
|
||||
this.onTouched();
|
||||
this.valueChange.emit(branch);
|
||||
if (!!branch) {
|
||||
this.onChange(branch);
|
||||
this.onTouched();
|
||||
this.valueChange.emit(branch);
|
||||
}
|
||||
}
|
||||
|
||||
closeAndClearAutocomplete() {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
|
||||
<div class="goods-in-out-header-details">
|
||||
<h2 class="goods-in-out-header-details-header">
|
||||
<h2 class="goods-in-out-header-details-header text-2xl">
|
||||
<div class="goods-in-out-header-details-header-name">
|
||||
{{ orderItem?.organisation }}
|
||||
<ng-container *ngIf="!!orderItem?.organisation && (!!orderItem?.firstName || !!orderItem?.lastName)"> - </ng-container>
|
||||
@@ -30,10 +30,18 @@
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<div class="goods-in-out-header-details-paid-marker" *ngIf="orderItem?.features?.paid">
|
||||
<div class="goods-in-out-header-details-paid-marker" *ngIf="orderItem?.features?.paid && !isKulturpass">
|
||||
<ui-icon size="12px" icon="check"></ui-icon>
|
||||
<strong> {{ orderItem?.features?.paid }} </strong>
|
||||
</div>
|
||||
<div class="goods-in-out-header-details-paid-marker text-[#26830C]" *ngIf="isKulturpass">
|
||||
<svg class="fill-current mr-2" xmlns="http://www.w3.org/2000/svg" height="22" viewBox="0 -960 960 960" width="22">
|
||||
<path
|
||||
d="M880-740v520q0 24-18 42t-42 18H140q-24 0-42-18t-18-42v-520q0-24 18-42t42-18h680q24 0 42 18t18 42ZM140-631h680v-109H140v109Zm0 129v282h680v-282H140Zm0 282v-520 520Z"
|
||||
/>
|
||||
</svg>
|
||||
<strong> Bezahlt über KulturPass </strong>
|
||||
</div>
|
||||
|
||||
<div class="goods-in-out-header-details-wrapper">
|
||||
<div class="detail" data-detail-id="VorgangId">
|
||||
@@ -78,7 +86,7 @@
|
||||
</div>
|
||||
<div class="detail" data-detail-id="Bestellkanal">
|
||||
<div class="label">Bestellkanal</div>
|
||||
<div class="value">{{ orderItem?.clientChannel | environmentChannel }}</div>
|
||||
<div class="value">{{ order?.features?.orderSource }}</div>
|
||||
</div>
|
||||
<div class="detail justify-space-between" [ngSwitch]="orderItem.processingStatus" data-detail-id="Geaendert">
|
||||
<ng-container *ifRole="'Store'; else dateCallCenter">
|
||||
@@ -251,7 +259,7 @@
|
||||
<button
|
||||
[uiOverlayTrigger]="deadlineDatepicker"
|
||||
#deadlineDatepickerTrigger="uiOverlayTrigger"
|
||||
[disabled]="!!orderItem?.features?.paid || (changeDateDisabled$ | async)"
|
||||
[disabled]="!isKulturpass && (!!orderItem?.features?.paid || (changeDateDisabled$ | async))"
|
||||
class="cta-pickup-deadline"
|
||||
>
|
||||
<strong>
|
||||
@@ -280,7 +288,7 @@
|
||||
<button
|
||||
[uiOverlayTrigger]="preferredPickUpDatePicker"
|
||||
#preferredPickUpDatePickerTrigger="uiOverlayTrigger"
|
||||
[disabled]="!!orderItem?.features?.paid || (changeDateDisabled$ | async)"
|
||||
[disabled]="(!isKulturpass && !!orderItem?.features?.paid) || (changeDateDisabled$ | async)"
|
||||
class="cta-pickup-preferred"
|
||||
>
|
||||
<strong *ngIf="preferredPickUpDate$ | async; let pickUpDate; else: selectTemplate">
|
||||
|
||||
@@ -35,6 +35,10 @@ export class SharedGoodsInOutOrderDetailsHeaderComponent implements OnChanges {
|
||||
@Input()
|
||||
selectedOrderItemId: number;
|
||||
|
||||
get isKulturpass() {
|
||||
return this.order?.features?.orderSource === 'KulturPass';
|
||||
}
|
||||
|
||||
minDateDatepicker = this.dateAdapter.addCalendarDays(this.dateAdapter.today(), -1);
|
||||
today = this.dateAdapter.today();
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ export class SharedGoodsInOutOrderDetailsItemComponent extends ComponentStore<Sh
|
||||
switchMap(([done, orderItem]) =>
|
||||
this._domainReceiptService
|
||||
.getReceipts({
|
||||
receiptType: 65 as ReceiptType,
|
||||
receiptType: (1 + 64 + 128) as ReceiptType,
|
||||
ids: [orderItem.orderItemSubsetId],
|
||||
eagerLoading: 1,
|
||||
})
|
||||
@@ -184,7 +184,6 @@ export class SharedGoodsInOutOrderDetailsItemComponent extends ComponentStore<Sh
|
||||
(res) => {
|
||||
const receipts = res.result.map((r) => r.item3?.data).filter((f) => !!f);
|
||||
this.receipts = receipts;
|
||||
|
||||
if (typeof done === 'function') {
|
||||
done?.(receipts);
|
||||
}
|
||||
|
||||
@@ -177,16 +177,15 @@ export class SharedGoodsInOutOrderDetailsComponent extends SharedGoodsInOutOrder
|
||||
return;
|
||||
}
|
||||
let receipts: ReceiptDTO[] = [];
|
||||
if (action.command.includes('PRINT_SHIPPINGNOTE')) {
|
||||
if (action.command.includes('PRINT_SHIPPINGNOTE') || action.command === 'PRINT_SMALLAMOUNTINVOICE') {
|
||||
const receiptsPromise = this.orderDetailsItemComponents.toArray().map(
|
||||
(timeComponent) =>
|
||||
(itemCmp) =>
|
||||
new Promise<ReceiptDTO[]>((resolve) => {
|
||||
timeComponent.loadReceipts((r) => resolve(r));
|
||||
itemCmp.loadReceipts((r) => resolve(r));
|
||||
})
|
||||
);
|
||||
|
||||
receipts = await Promise.all(receiptsPromise).then((r) => r.reduce((acc, val) => acc.concat(val), []));
|
||||
|
||||
receipts = unionBy(receipts, 'id');
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<button
|
||||
[uiOverlayTrigger]="deadlineDatepicker"
|
||||
#deadlineDatepickerTrigger="uiOverlayTrigger"
|
||||
[disabled]="!!items[i]?.features?.paid"
|
||||
[disabled]="!isKulturpass(items[i]) && !!items[i]?.features?.paid"
|
||||
class="date-btn"
|
||||
type="button"
|
||||
>
|
||||
|
||||
@@ -23,7 +23,6 @@ import { UiSelectOptionComponent } from '@ui/select';
|
||||
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||
import { first, shareReplay } from 'rxjs/operators';
|
||||
import { ProcessingStatusNameMap } from '../constants/processing-status-name.map';
|
||||
import { EnvironmentChannelPipe } from '../pipes/environment-channel.pipe';
|
||||
import { ProcessingStatusPipe } from '../pipes/processing-status.pipe';
|
||||
import { validateSsc } from '../validators/ssc.validator';
|
||||
|
||||
@@ -32,7 +31,7 @@ import { validateSsc } from '../validators/ssc.validator';
|
||||
templateUrl: 'goods-in-out-order-edit.component.html',
|
||||
styleUrls: ['goods-in-out-order-edit.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [EnvironmentChannelPipe, ProcessingStatusPipe, DatePipe],
|
||||
providers: [ProcessingStatusPipe, DatePipe],
|
||||
})
|
||||
export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy {
|
||||
@ViewChildren('autosize') autosize: QueryList<CdkTextareaAutosize>;
|
||||
@@ -77,7 +76,6 @@ export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy
|
||||
|
||||
constructor(
|
||||
private fb: UntypedFormBuilder,
|
||||
private environmentChannelPipe: EnvironmentChannelPipe,
|
||||
private processingStatusPipe: ProcessingStatusPipe,
|
||||
private datePipe: DatePipe,
|
||||
private omsService: DomainOmsService,
|
||||
@@ -101,7 +99,11 @@ export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy
|
||||
}
|
||||
}
|
||||
|
||||
initForm(items: OrderItemListItemDTO[]) {
|
||||
isKulturpass(item: OrderItemListItemDTO): boolean {
|
||||
return item?.['externalRepositories']?.includes('kulturpass');
|
||||
}
|
||||
|
||||
async initForm(items: OrderItemListItemDTO[]) {
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
@@ -111,7 +113,7 @@ export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy
|
||||
orderId: fb.control({ value: items[0].orderId, disabled: true }),
|
||||
orderNumber: fb.control({ value: items[0].orderNumber, disabled: true }),
|
||||
orderDate: fb.control({ value: this.datePipe.transform(items[0].orderDate), disabled: true }),
|
||||
clientChannel: fb.control({ value: this.environmentChannelPipe.transform(items[0].clientChannel), disabled: true }),
|
||||
clientChannel: fb.control({ value: (await this.getOrderSource()) ?? items[0].features?.orderSource, disabled: true }),
|
||||
buyerNumber: fb.control({ value: items[0].buyerNumber, disabled: true }),
|
||||
items: fb.array([]),
|
||||
notificationChannel: this.notificationsGroup,
|
||||
@@ -172,8 +174,7 @@ export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy
|
||||
}
|
||||
|
||||
async updateNotificationsGroup() {
|
||||
const control = this.control?.getRawValue();
|
||||
const orderId = control?.orderId;
|
||||
const orderId = this.items[0].orderId;
|
||||
|
||||
try {
|
||||
if (orderId) {
|
||||
@@ -192,6 +193,11 @@ export class SharedGoodsInOutOrderEditComponent implements OnChanges, OnDestroy
|
||||
await this.omsService.updateNotifications(orderId, this.notificationsGroup.getRawValue()).toPromise();
|
||||
}
|
||||
|
||||
async getOrderSource() {
|
||||
const orderId = this.items[0].orderId;
|
||||
return this.omsService.getOrderSource(+orderId).toPromise();
|
||||
}
|
||||
|
||||
changeEstimatedDeliveryDate(date: Date, item: OrderItemListItemDTO) {
|
||||
if (!date) {
|
||||
return;
|
||||
|
||||
@@ -2,10 +2,18 @@
|
||||
{{ item?.compartmentCode }}
|
||||
{{ item.compartmentInfo && '_' + item.compartmentInfo }}
|
||||
</div>
|
||||
<div class="goods-in-out-order-group-item-paid" *ngIf="item.features?.paid">
|
||||
<div class="goods-in-out-order-group-item-paid" *ngIf="item.features?.paid && !isKulturpass">
|
||||
<ui-icon size="12px" icon="check"></ui-icon>
|
||||
<strong> {{ item.features?.paid }} </strong>
|
||||
</div>
|
||||
<div class="goods-in-out-order-group-item-paid text-[#26830C]" *ngIf="isKulturpass">
|
||||
<svg class="fill-current mr-2" xmlns="http://www.w3.org/2000/svg" height="22" viewBox="0 -960 960 960" width="22">
|
||||
<path
|
||||
d="M880-740v520q0 24-18 42t-42 18H140q-24 0-42-18t-18-42v-520q0-24 18-42t42-18h680q24 0 42 18t18 42ZM140-631h680v-109H140v109Zm0 129v282h680v-282H140Zm0 282v-520 520Z"
|
||||
/>
|
||||
</svg>
|
||||
<strong> Bezahlt über KulturPass </strong>
|
||||
</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" />
|
||||
|
||||
@@ -84,6 +84,10 @@ export class GoodsInOutOrderGroupItemComponent extends ComponentStore<GoodsInOut
|
||||
return (this.item as any)?.cruda;
|
||||
}
|
||||
|
||||
get isKulturpass() {
|
||||
return this.item?.['externalRepositories']?.includes('kulturpass');
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
selected: false,
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { Injectable, Pipe, PipeTransform } from '@angular/core';
|
||||
import { EnvironmentChannel } from '@swagger/oms';
|
||||
|
||||
@Pipe({
|
||||
name: 'environmentChannel',
|
||||
})
|
||||
@Injectable()
|
||||
export class EnvironmentChannelPipe implements PipeTransform {
|
||||
channels = new Map([
|
||||
[0, ''],
|
||||
[2, 'Filiale'],
|
||||
[4, 'HSC'],
|
||||
[8, 'Online'],
|
||||
]);
|
||||
|
||||
transform(clientChannel: EnvironmentChannel = 0, join: string = ' '): any {
|
||||
if (clientChannel === 0) {
|
||||
return this.channels.get(0);
|
||||
}
|
||||
|
||||
const channelOnlineMobileApp: number = clientChannel;
|
||||
if (channelOnlineMobileApp === 8 || channelOnlineMobileApp === 16 || channelOnlineMobileApp === 24) {
|
||||
return 'hugendubel.de';
|
||||
}
|
||||
|
||||
const channels: string[] = [];
|
||||
this.channels.forEach((value, key) => {
|
||||
// tslint:disable-next-line: no-bitwise
|
||||
if ((clientChannel | key) === key) {
|
||||
channels.push(value);
|
||||
}
|
||||
});
|
||||
return channels.join(join);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { EnvironmentChannelPipe } from './environment-channel.pipe';
|
||||
import { ProcessingStatusOptionsKeyValuePipe, ProcessingStatusOptionsPipe } from './processing-status-options.pipe';
|
||||
import { PaymentTypePipe } from './payment-type.pipe';
|
||||
import { ProcessingStatusPipe } from './processing-status.pipe';
|
||||
@@ -18,7 +17,6 @@ import { AddToPreviousCompartmentCodeLabelPipe } from './add-to-prevoius-compart
|
||||
ProcessingStatusPipe,
|
||||
TitlePipe,
|
||||
ShowCompartmentCodePipe,
|
||||
EnvironmentChannelPipe,
|
||||
ProcessingStatusOptionsKeyValuePipe,
|
||||
PaymentTypePipe,
|
||||
ShowTagsPipe,
|
||||
@@ -33,7 +31,6 @@ import { AddToPreviousCompartmentCodeLabelPipe } from './add-to-prevoius-compart
|
||||
ProcessingStatusPipe,
|
||||
TitlePipe,
|
||||
ShowCompartmentCodePipe,
|
||||
EnvironmentChannelPipe,
|
||||
ProcessingStatusOptionsKeyValuePipe,
|
||||
PaymentTypePipe,
|
||||
ShowTagsPipe,
|
||||
|
||||
@@ -47,3 +47,19 @@
|
||||
.fancy-checkbox:checked::after {
|
||||
@apply opacity-100;
|
||||
}
|
||||
|
||||
.shared-purchase-options-list-item__availability ui-svg-icon {
|
||||
@apply bg-[#D8DFE5] w-7 h-7 rounded-card rounded-br-none grid items-center justify-center;
|
||||
}
|
||||
|
||||
.shared-purchase-options-list-item__availability ui-svg-icon.active {
|
||||
@apply bg-[#596470] text-white;
|
||||
}
|
||||
|
||||
::ng-deep shared-purchase-options-list-item ui-select .ui-input-wrapper {
|
||||
@apply h-full;
|
||||
}
|
||||
|
||||
::ng-deep shared-purchase-options-list-item ui-select .ui-select-toggle {
|
||||
@apply ml-2;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,26 @@
|
||||
{{ availability.data.estimatedShippingDate | date: 'dd. MMMM yyyy' }}
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="'pickup'">
|
||||
<ui-svg-icon icon="isa-box-out" [size]="18"></ui-svg-icon>
|
||||
<ui-svg-icon
|
||||
icon="isa-box-out"
|
||||
[size]="18"
|
||||
#trigger="uiOverlayTrigger"
|
||||
class="cursor-pointer"
|
||||
[class.active]="trigger.opened"
|
||||
[uiOverlayTrigger]="orderDedlineTooltip"
|
||||
></ui-svg-icon>
|
||||
{{ availability.data.estimatedShippingDate | date: 'dd. MMMM yyyy' }}
|
||||
<ui-tooltip
|
||||
#orderDedlineTooltip
|
||||
yPosition="above"
|
||||
xPosition="after"
|
||||
[yOffset]="-11"
|
||||
[xOffset]="4"
|
||||
[warning]="true"
|
||||
[closeable]="true"
|
||||
>
|
||||
<b>{{ availability.data?.orderDeadline | orderDeadline }}</b>
|
||||
</ui-tooltip>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="'in-store'">
|
||||
<ui-svg-icon icon="isa-shopping-bag" [size]="18"></ui-svg-icon>
|
||||
@@ -64,8 +82,50 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="shared-purchase-options-list-item__price text-right ml-4 flex flex-col items-end">
|
||||
<div class="shared-purchase-options-list-item__price-value font-bold text-xl" *ngIf="!(canEditPrice$ | async)">
|
||||
{{ priceValue$ | async | currency: 'EUR':'code' }}
|
||||
<div
|
||||
class="shared-purchase-options-list-item__price-value font-bold text-xl flex flex-row items-center"
|
||||
*ngIf="!(canEditPrice$ | async)"
|
||||
>
|
||||
<ui-svg-icon class="mr-3" [uiOverlayTrigger]="tooltip" icon="mat-info" *ngIf="priceMaintained$ | async"></ui-svg-icon>
|
||||
<ui-tooltip #tooltip yPosition="above" xPosition="after" [yOffset]="-8" [xOffset]="5" [closeable]="true">
|
||||
Günstigerer Preis aus Hugendubel Katalog wird übernommen
|
||||
</ui-tooltip>
|
||||
<ng-container *ngIf="!(setManualPrice$ | async); else setManualPrice">
|
||||
{{ priceValue$ | async | currency: 'EUR':'code' }}
|
||||
</ng-container>
|
||||
<ng-template #setManualPrice>
|
||||
<div class="relative flex flex-row items-start">
|
||||
<ui-select
|
||||
class="w-[6.5rem] min-h-[3.4375rem] p-4 rounded-card border border-solid border-[#AEB7C1] mr-4"
|
||||
tabindex="-1"
|
||||
[formControl]="manualVatFormControl"
|
||||
[defaultLabel]="'MwSt'"
|
||||
>
|
||||
<ui-select-option *ngFor="let vat of vats$ | async" [label]="vat.name + '%'" [value]="vat.vatType"></ui-select-option>
|
||||
</ui-select>
|
||||
|
||||
<shared-input-control [class.ml-8]="manualPriceFormControl?.invalid && manualPriceFormControl?.dirty">
|
||||
<shared-input-control-indicator>
|
||||
<ui-svg-icon *ngIf="manualPriceFormControl?.invalid && manualPriceFormControl?.dirty" icon="mat-info"></ui-svg-icon>
|
||||
</shared-input-control-indicator>
|
||||
<input
|
||||
triggerOn="init"
|
||||
#quantityInput
|
||||
sharedInputControlInput
|
||||
type="string"
|
||||
class="w-24"
|
||||
[formControl]="manualPriceFormControl"
|
||||
placeholder="00,00"
|
||||
(sharedOnInit)="quantityInput.focus()"
|
||||
sharedNumberValue
|
||||
/>
|
||||
<shared-input-control-suffix>EUR</shared-input-control-suffix>
|
||||
<shared-input-control-error error="required">Preis ist ungültig</shared-input-control-error>
|
||||
<shared-input-control-error error="pattern">Preis ist ungültig</shared-input-control-error>
|
||||
<shared-input-control-error error="max">Preis ist ungültig</shared-input-control-error>
|
||||
</shared-input-control>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="shared-purchase-options-list-item__price-value font-bold text-xl" *ngIf="canEditPrice$ | async">
|
||||
<div class="relative flex flex-col">
|
||||
|
||||
@@ -21,9 +21,12 @@ import { UiQuantityDropdownModule } from '@ui/quantity-dropdown';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { UiTooltipModule } from '@ui/tooltip';
|
||||
import { combineLatest, ReplaySubject, Subscription } from 'rxjs';
|
||||
import { map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { map, take, shareReplay, startWith, switchMap, withLatestFrom, last } from 'rxjs/operators';
|
||||
import { GIFT_CARD_MAX_PRICE, PRICE_PATTERN } from '../constants';
|
||||
import { Item, PurchaseOptionsStore } from '../store';
|
||||
import { OrderDeadlinePipeModule } from '@shared/pipes/order-deadline';
|
||||
import { UiSelectModule } from '@ui/select';
|
||||
import { KeyValueDTOOfStringAndString } from '@swagger/cat';
|
||||
|
||||
@Component({
|
||||
selector: 'scale-content, [scaleContent]',
|
||||
@@ -33,7 +36,7 @@ import { Item, PurchaseOptionsStore } from '../store';
|
||||
styles: [
|
||||
`
|
||||
:host {
|
||||
overflow: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
`,
|
||||
],
|
||||
@@ -43,7 +46,7 @@ export class ScaleContentComponent implements AfterContentInit {
|
||||
|
||||
fontSizeInEm = 1;
|
||||
|
||||
adjustmentSteps = 0.1;
|
||||
adjustmentSteps = 0.05;
|
||||
|
||||
constructor(private _elementRef: ElementRef<HTMLElement>, private _renderer: Renderer2) {}
|
||||
|
||||
@@ -54,10 +57,12 @@ export class ScaleContentComponent implements AfterContentInit {
|
||||
adjustFontSize() {
|
||||
const element = this._elementRef.nativeElement;
|
||||
|
||||
const clientRect = element.getClientRects();
|
||||
const scrollHeight = element.scrollHeight;
|
||||
const clientRect = element?.getClientRects();
|
||||
const scrollHeight = element?.scrollHeight;
|
||||
|
||||
if (clientRect[0].height < scrollHeight) {
|
||||
const domRect = clientRect && clientRect[0];
|
||||
|
||||
if (domRect && Math.ceil(domRect?.height) < scrollHeight) {
|
||||
this.fontSizeInEm -= this.adjustmentSteps;
|
||||
} else {
|
||||
return;
|
||||
@@ -78,6 +83,7 @@ export class ScaleContentComponent implements AfterContentInit {
|
||||
imports: [
|
||||
CommonModule,
|
||||
UiQuantityDropdownModule,
|
||||
UiSelectModule,
|
||||
ProductImageModule,
|
||||
UiIconModule,
|
||||
UiSpinnerModule,
|
||||
@@ -88,6 +94,7 @@ export class ScaleContentComponent implements AfterContentInit {
|
||||
UiTooltipModule,
|
||||
UiCommonModule,
|
||||
ScaleContentComponent,
|
||||
OrderDeadlinePipeModule,
|
||||
],
|
||||
host: { class: 'shared-purchase-options-list-item' },
|
||||
})
|
||||
@@ -108,7 +115,15 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
|
||||
quantityFormControl = new FormControl<number>(null);
|
||||
|
||||
priceFormControl = new FormControl<string>(null, [Validators.required, Validators.min(1), Validators.max(GIFT_CARD_MAX_PRICE)]);
|
||||
priceFormControl = new FormControl<string>(null, [
|
||||
Validators.required,
|
||||
Validators.min(1),
|
||||
Validators.max(GIFT_CARD_MAX_PRICE),
|
||||
Validators.pattern(PRICE_PATTERN),
|
||||
]);
|
||||
|
||||
manualPriceFormControl = new FormControl<string>(null, [Validators.required, Validators.max(999.99), Validators.pattern(PRICE_PATTERN)]);
|
||||
manualVatFormControl = new FormControl<string>('', [Validators.required]);
|
||||
|
||||
selectedFormControl = new FormControl<boolean>(false);
|
||||
|
||||
@@ -121,9 +136,27 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
|
||||
price$ = this.item$.pipe(switchMap((item) => this._store.getPrice$(item.id)));
|
||||
|
||||
priceMaintained$ = this.price$.pipe(map((price) => price?.fromCatalogue));
|
||||
|
||||
priceValue$ = this.price$.pipe(map((price) => price?.value?.value));
|
||||
|
||||
priceVat$ = this.price$.pipe(map((price) => price?.vat?.value));
|
||||
vats$ = this._store.vats$.pipe(shareReplay());
|
||||
|
||||
// Ticket #4074 analog zu Ticket #2244
|
||||
// take(2) um die Response des Katalogpreises und danach um die Response der OLAs abzuwarten
|
||||
// Logik gilt ausschließlich für Archivartikel
|
||||
setManualPrice$ = this.price$.pipe(
|
||||
take(2),
|
||||
map((price) => {
|
||||
// Logik nur beim Hinzufügen über Kaufoptionen, da über Ändern im Warenkorb die Info fehlt ob das jeweilige ShoppingCartItem ein Archivartikel ist oder nicht
|
||||
const features = this.item?.features as KeyValueDTOOfStringAndString[];
|
||||
if (!!features && Array.isArray(features)) {
|
||||
const isArchive = !!features?.find((feature) => feature?.enabled === true && feature?.key === 'ARC') ?? false;
|
||||
return isArchive ? !price?.value?.value || price?.vat === undefined : false;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
);
|
||||
|
||||
canEditPrice$ = this.item$.pipe(switchMap((item) => this._store.getCanEditPrice$(item.id)));
|
||||
|
||||
@@ -170,11 +203,11 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
|
||||
constructor(private _store: PurchaseOptionsStore) {}
|
||||
|
||||
// Wichtig für das korrekte Setzen des Preises an das Item für den Endpoint request
|
||||
parsePrice(value: string) {
|
||||
if (PRICE_PATTERN.test(value)) {
|
||||
return parseFloat(value.replace(',', '.'));
|
||||
}
|
||||
this.priceFormControl.setErrors({ pattern: true });
|
||||
}
|
||||
|
||||
stringifyPrice(value: number) {
|
||||
@@ -193,6 +226,7 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
this.initQuantitySubscription();
|
||||
this.initPriceSubscription();
|
||||
this.initSelectedSubscription();
|
||||
this.initManualPriceSubscriptions();
|
||||
}
|
||||
|
||||
ngOnChanges({ item }: SimpleChanges) {
|
||||
@@ -206,6 +240,16 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
this._subscriptions.unsubscribe();
|
||||
}
|
||||
|
||||
// Ticket #4074 analog zu Ticket #2244
|
||||
// Logik gilt ausschließlich für Archivartikel und über die Kaufoptionen. Nicht über den Warenkorb
|
||||
async initManualPriceSubscriptions() {
|
||||
const isManualPrice = await this.setManualPrice$.pipe(last()).toPromise();
|
||||
if (!!isManualPrice) {
|
||||
this.initManualPriceSubscription();
|
||||
this.initManualVatSubscription();
|
||||
}
|
||||
}
|
||||
|
||||
initQuantitySubscription() {
|
||||
const sub = this.item$.subscribe((item) => {
|
||||
if (this.quantityFormControl.value !== item.quantity) {
|
||||
@@ -250,6 +294,51 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
this._subscriptions.add(valueChangesSub);
|
||||
}
|
||||
|
||||
initManualPriceSubscription() {
|
||||
const sub = this.price$.subscribe((price) => {
|
||||
const priceStr = this.stringifyPrice(price?.value?.value);
|
||||
if (priceStr === '') return;
|
||||
|
||||
if (this.parsePrice(this.manualPriceFormControl.value) !== price?.value?.value) {
|
||||
this.manualPriceFormControl.setValue(priceStr);
|
||||
}
|
||||
});
|
||||
|
||||
const valueChangesSub = this.manualPriceFormControl.valueChanges.subscribe((value) => {
|
||||
const price = this._store.getPrice(this.item.id);
|
||||
const parsedPrice = this.parsePrice(value);
|
||||
|
||||
if (!parsedPrice) {
|
||||
this._store.setPrice(this.item.id, null, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (price[this.item.id] !== parsedPrice) {
|
||||
this._store.setPrice(this.item.id, this.parsePrice(value), true);
|
||||
}
|
||||
});
|
||||
this._subscriptions.add(sub);
|
||||
this._subscriptions.add(valueChangesSub);
|
||||
}
|
||||
|
||||
initManualVatSubscription() {
|
||||
const valueChangesSub = this.manualVatFormControl.valueChanges.pipe(withLatestFrom(this.vats$)).subscribe(([formVatType, vats]) => {
|
||||
const price = this._store.getPrice(this.item.id);
|
||||
|
||||
const vat = vats.find((vat) => vat?.vatType === Number(formVatType));
|
||||
|
||||
if (!vat) {
|
||||
this._store.setVat(this.item.id, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (price[this.item.id]?.vat?.vatType !== vat?.vatType) {
|
||||
this._store.setVat(this.item.id, vat);
|
||||
}
|
||||
});
|
||||
this._subscriptions.add(valueChangesSub);
|
||||
}
|
||||
|
||||
initSelectedSubscription() {
|
||||
const sub = this.item$
|
||||
.pipe(switchMap((item) => this._store.selectedItemIds$.pipe(map((ids) => ids.includes(item.id)))))
|
||||
|
||||
@@ -3,15 +3,6 @@
|
||||
Wie möchten Sie die Artikel erhalten?
|
||||
</p>
|
||||
<div class="rounded p-4 shadow-card mt-4 grid grid-flow-col gap-4 justify-center items-center relative">
|
||||
<!-- <ng-container *ngFor="let option of purchasingOptions$ | async">
|
||||
<ng-container [ngSwitch]="option">
|
||||
<app-delivery-purchase-options-tile *ngSwitchCase="'delivery'"> </app-delivery-purchase-options-tile>
|
||||
<app-in-store-purchase-options-tile *ngSwitchCase="'in-store'"> </app-in-store-purchase-options-tile>
|
||||
<app-pickup-purchase-options-tile *ngSwitchCase="'pickup'"> </app-pickup-purchase-options-tile>
|
||||
<app-download-purchase-options-tile *ngSwitchCase="'download'"> </app-download-purchase-options-tile>
|
||||
</ng-container>
|
||||
</ng-container> -->
|
||||
|
||||
<ng-container *ngIf="!(isDownloadOnly$ | async)">
|
||||
<ng-container *ngIf="!(isGiftCardOnly$ | async)">
|
||||
<app-in-store-purchase-options-tile> </app-in-store-purchase-options-tile>
|
||||
@@ -32,13 +23,18 @@
|
||||
</div>
|
||||
<div class="text-center -mx-4 border-t border-gray-200 p-4 border-solid">
|
||||
<ng-container *ngIf="type === 'add'">
|
||||
<button type="button" class="isa-cta-button" [disabled]="!(canContinue$ | async) || saving" (click)="save('continue-shopping')">
|
||||
<button
|
||||
type="button"
|
||||
class="isa-cta-button"
|
||||
[disabled]="!(canContinue$ | async) || saving || !(hasPrice$ | async)"
|
||||
(click)="save('continue-shopping')"
|
||||
>
|
||||
Weiter einkaufen
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-4 isa-cta-button isa-button-primary"
|
||||
[disabled]="!(canContinue$ | async) || saving"
|
||||
[disabled]="!(canContinue$ | async) || saving || !(hasPrice$ | async)"
|
||||
(click)="save('continue')"
|
||||
>
|
||||
Fortfahren
|
||||
@@ -48,7 +44,7 @@
|
||||
<button
|
||||
type="button"
|
||||
class="ml-4 isa-cta-button isa-button-primary"
|
||||
[disabled]="!(canContinue$ | async) || saving"
|
||||
[disabled]="!(canContinue$ | async) || saving || !(hasPrice$ | async)"
|
||||
(click)="save('continue')"
|
||||
>
|
||||
Fortfahren
|
||||
|
||||
@@ -5,7 +5,7 @@ import { PurchaseOptionsModalData } from './purchase-options-modal.data';
|
||||
import { PurchaseOptionsListHeaderComponent } from './purchase-options-list-header';
|
||||
import { PurchaseOptionsListItemComponent } from './purchase-options-list-item';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Subject, zip } from 'rxjs';
|
||||
import {
|
||||
DeliveryPurchaseOptionTileComponent,
|
||||
DownloadPurchaseOptionTileComponent,
|
||||
@@ -13,7 +13,8 @@ import {
|
||||
PickupPurchaseOptionTileComponent,
|
||||
} from './purchase-options-tile';
|
||||
import { isGiftCard, Item, PurchaseOptionsStore } from './store';
|
||||
import { delay, map, shareReplay, skip, takeUntil } from 'rxjs/operators';
|
||||
import { delay, map, shareReplay, skip, switchMap, takeUntil } from 'rxjs/operators';
|
||||
import { KeyValueDTOOfStringAndString } from '@swagger/cat';
|
||||
|
||||
@Component({
|
||||
selector: 'shared-purchase-options-modal',
|
||||
@@ -44,6 +45,34 @@ export class PurchaseOptionsModalComponent implements OnInit, OnDestroy {
|
||||
|
||||
items$ = this.store.items$;
|
||||
|
||||
hasPrice$ = this.items$.pipe(
|
||||
switchMap((items) =>
|
||||
items.map((item) => {
|
||||
let isArchive = false;
|
||||
const features = item?.features as KeyValueDTOOfStringAndString[];
|
||||
// Ticket #4074 analog zu Ticket #2244
|
||||
// Ob Archivartikel kann nur über Kaufoptionen herausgefunden werden, nicht über Ändern im Warenkorb da am ShoppingCartItem das Archivartikel Feature fehlt
|
||||
if (!!features && Array.isArray(features)) {
|
||||
isArchive = !!features?.find((feature) => feature?.enabled === true && feature?.key === 'ARC') ?? false;
|
||||
}
|
||||
return zip(
|
||||
this.store
|
||||
?.getPrice$(item?.id)
|
||||
.pipe(
|
||||
map((price) =>
|
||||
isArchive ? !!price?.value?.value && price?.vat !== undefined && price?.vat?.value !== undefined : !!price?.value?.value
|
||||
)
|
||||
)
|
||||
);
|
||||
})
|
||||
),
|
||||
switchMap((hasPrices) => hasPrices),
|
||||
map((hasPrices) => {
|
||||
const containsItemWithNoPrice = hasPrices?.filter((hasPrice) => hasPrice === false) ?? [];
|
||||
return containsItemWithNoPrice?.length === 0;
|
||||
})
|
||||
);
|
||||
|
||||
purchasingOptions$ = this.store.getPurchaseOptionsInAvailabilities$;
|
||||
|
||||
isDownloadOnly$ = this.purchasingOptions$.pipe(
|
||||
|
||||
@@ -6,4 +6,6 @@ export interface PurchaseOptionsModalData {
|
||||
processId: number;
|
||||
type: ActionType;
|
||||
items: Array<ItemDTO | ShoppingCartItemDTO>;
|
||||
pickupBranch?: BranchDTO;
|
||||
inStoreBranch?: BranchDTO;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div class="purchase-options-tile__heading">
|
||||
<div class="purchase-options-tile__heading" [class.muted]="hasNoInStoreAvailability$ | async">
|
||||
<div class="icon-wrapper">
|
||||
<ui-svg-icon icon="isa-truck"></ui-svg-icon>
|
||||
</div>
|
||||
<span class="purchase-option-name">Versand</span>
|
||||
</div>
|
||||
<div class="purchase-options-tile__body">
|
||||
<div class="purchase-options-tile__body" [class.muted]="hasNoInStoreAvailability$ | async">
|
||||
Artikel geliefert bekommen?
|
||||
</div>
|
||||
<div class="purchase-options-tile__actions">
|
||||
<div class="purchase-options-tile__actions" [class.muted]="hasNoInStoreAvailability$ | async">
|
||||
<span>Versandkostenfrei</span>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { PurchaseOptionsStore } from '../store';
|
||||
import { BasePurchaseOptionDirective } from './base-purchase-option.directive';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-delivery-purchase-options-tile',
|
||||
@@ -13,6 +14,11 @@ import { BasePurchaseOptionDirective } from './base-purchase-option.directive';
|
||||
imports: [CommonModule, UiIconModule],
|
||||
})
|
||||
export class DeliveryPurchaseOptionTileComponent extends BasePurchaseOptionDirective {
|
||||
hasNoInStoreAvailability$ = this.store.purchasingOptions$.pipe(
|
||||
map((po) => !(po.includes('delivery') || po.includes('b2b-delivery') || po.includes('dig-delivery'))),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(protected store: PurchaseOptionsStore, protected cdr: ChangeDetectorRef) {
|
||||
super('delivery');
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div class="purchase-options-tile__heading">
|
||||
<div class="purchase-options-tile__heading" [class.muted]="hasNoInStoreAvailability$ | async">
|
||||
<div class="icon-wrapper">
|
||||
<ui-svg-icon icon="isa-shopping-bag"></ui-svg-icon>
|
||||
</div>
|
||||
<span class="purchase-option-name">Rücklage</span>
|
||||
</div>
|
||||
<div class="purchase-options-tile__body">
|
||||
<div class="purchase-options-tile__body" [class.muted]="hasNoInStoreAvailability$ | async">
|
||||
Artikel zurücklegen lassen oder sofort mitnehmen?
|
||||
</div>
|
||||
<div class="purchase-options-tile__actions group">
|
||||
|
||||
@@ -8,6 +8,7 @@ import { UiIconModule } from '@ui/icon';
|
||||
import { PurchaseOptionsStore } from '../store';
|
||||
import { BasePurchaseOptionDirective } from './base-purchase-option.directive';
|
||||
import { AuthService } from '@core/auth';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-in-store-purchase-options-tile',
|
||||
@@ -21,6 +22,11 @@ import { AuthService } from '@core/auth';
|
||||
export class InStorePurchaseOptionTileComponent extends BasePurchaseOptionDirective {
|
||||
inStoreBranch$ = this.store.inStoreBranch$;
|
||||
|
||||
hasNoInStoreAvailability$ = this.store.purchasingOptions$.pipe(
|
||||
map((po) => !po.includes('in-store')),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(
|
||||
protected store: PurchaseOptionsStore,
|
||||
protected cdr: ChangeDetectorRef,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div class="purchase-options-tile__heading">
|
||||
<div class="purchase-options-tile__heading" [class.muted]="hasNoInStoreAvailability$ | async">
|
||||
<div class="icon-wrapper">
|
||||
<ui-svg-icon icon="isa-box-out"></ui-svg-icon>
|
||||
</div>
|
||||
<span class="purchase-option-name">Abholung</span>
|
||||
</div>
|
||||
<div class="purchase-options-tile__body">
|
||||
<div class="purchase-options-tile__body" [class.muted]="hasNoInStoreAvailability$ | async">
|
||||
Artikel in einer unserer Filialen abholen?
|
||||
</div>
|
||||
<div class="purchase-options-tile__actions group">
|
||||
|
||||
@@ -8,6 +8,7 @@ import { UiIconModule } from '@ui/icon';
|
||||
import { PurchaseOptionsStore } from '../store';
|
||||
import { BasePurchaseOptionDirective } from './base-purchase-option.directive';
|
||||
import { AuthService } from '@core/auth';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pickup-purchase-options-tile',
|
||||
@@ -21,6 +22,11 @@ import { AuthService } from '@core/auth';
|
||||
export class PickupPurchaseOptionTileComponent extends BasePurchaseOptionDirective {
|
||||
pickupBranch$ = this.store.pickupBranch$;
|
||||
|
||||
hasNoInStoreAvailability$ = this.store.purchasingOptions$.pipe(
|
||||
map((po) => !po.includes('pickup')),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(
|
||||
protected store: PurchaseOptionsStore,
|
||||
protected cdr: ChangeDetectorRef,
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
@apply bg-[#D8DFE5] w-[36px] h-[36px] rounded grid items-center justify-center;
|
||||
}
|
||||
|
||||
.purchase-options-tile__heading.muted .icon-wrapper {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
|
||||
.purchase-options-tile__heading .purchase-option-name {
|
||||
@apply ml-3 font-bold text-lg;
|
||||
}
|
||||
@@ -30,6 +34,10 @@
|
||||
@apply text-center font-bold;
|
||||
}
|
||||
|
||||
.muted {
|
||||
@apply text-[#AEB7C1];
|
||||
}
|
||||
|
||||
::ng-deep app-pickup-purchase-options-tile shared-branch-selector.focused,
|
||||
::ng-deep app-in-store-purchase-options-tile shared-branch-selector.focused {
|
||||
@apply visible;
|
||||
|
||||
@@ -178,14 +178,16 @@ export function getItemsForList(state: PurchaseOptionsState): Item[] {
|
||||
return items.filter((item) => itemIds.includes(item.id));
|
||||
}
|
||||
|
||||
export function getAvailabilitiesForItem(itemId: number): (state: PurchaseOptionsState) => Availability[] {
|
||||
export function getAvailabilitiesForItem(
|
||||
itemId: number,
|
||||
allDeliveryAvailabilities?: boolean
|
||||
): (state: PurchaseOptionsState) => Availability[] {
|
||||
return (state) => {
|
||||
let availabilities = getAvailabilities(state);
|
||||
availabilities = availabilities.filter((availability) => availability.itemId === itemId);
|
||||
|
||||
// if 'delivery', 'dig-delivery' and 'b2b-delivery' are present remove 'dig-delivery' and 'b2b-delivery'
|
||||
|
||||
if (availabilities.some((availability) => availability.purchaseOption === 'delivery')) {
|
||||
if (!allDeliveryAvailabilities && availabilities.some((availability) => availability.purchaseOption === 'delivery')) {
|
||||
availabilities = availabilities.filter(
|
||||
(availability) => availability.purchaseOption !== 'dig-delivery' && availability.purchaseOption !== 'b2b-delivery'
|
||||
);
|
||||
@@ -204,7 +206,10 @@ export function getCanEditPrice(itemId: number): (state: PurchaseOptionsState) =
|
||||
};
|
||||
}
|
||||
|
||||
export function getPriceForPurchaseOption(itemId: number, purchaseOption: PurchaseOption): (state: PurchaseOptionsState) => PriceDTO {
|
||||
export function getPriceForPurchaseOption(
|
||||
itemId: number,
|
||||
purchaseOption: PurchaseOption
|
||||
): (state: PurchaseOptionsState) => PriceDTO & { fromCatalogue?: boolean } {
|
||||
return (state) => {
|
||||
const price = getPrices(state)[itemId];
|
||||
|
||||
@@ -212,6 +217,10 @@ export function getPriceForPurchaseOption(itemId: number, purchaseOption: Purcha
|
||||
return price;
|
||||
}
|
||||
|
||||
const item = getItems(state).find((item) => item.id === itemId);
|
||||
|
||||
const type = getType(state);
|
||||
|
||||
let availabilities = getAvailabilitiesForItem(itemId)(state);
|
||||
|
||||
let availability = availabilities.find((availability) => availability.purchaseOption === purchaseOption);
|
||||
@@ -227,15 +236,26 @@ export function getPriceForPurchaseOption(itemId: number, purchaseOption: Purcha
|
||||
}
|
||||
|
||||
availability = availability || digAvailability || b2bAvailability;
|
||||
|
||||
if (!availability?.data?.priceMaintained) {
|
||||
// if price is not maintained, use the cheaper price
|
||||
if (isItemDTO(item, type)) {
|
||||
const catalogAvailability = item?.catalogAvailability?.price;
|
||||
if (
|
||||
catalogAvailability?.value?.value &&
|
||||
availability?.data?.price?.value?.value &&
|
||||
catalogAvailability?.value?.value < availability?.data?.price?.value?.value
|
||||
) {
|
||||
return { ...catalogAvailability, fromCatalogue: true };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (availability && availability.data.price?.value?.value) {
|
||||
return availability.data.price ?? DEFAULT_PRICE_DTO;
|
||||
if (availability && availability.data.price?.value?.value && availability.data.price) {
|
||||
return availability.data.price;
|
||||
}
|
||||
|
||||
const item = getItems(state).find((item) => item.id === itemId);
|
||||
const type = getType(state);
|
||||
|
||||
if (isItemDTO(item, type)) {
|
||||
return item?.catalogAvailability?.price ?? DEFAULT_PRICE_DTO;
|
||||
} else {
|
||||
@@ -280,17 +300,17 @@ export function getAvailabilityWithPurchaseOption(
|
||||
purchaseOption: PurchaseOption
|
||||
): (state: PurchaseOptionsState) => Availability {
|
||||
return (state) => {
|
||||
let availabilities = getAvailabilitiesForItem(itemId)(state);
|
||||
let availabilities = getAvailabilitiesForItem(itemId, true)(state);
|
||||
|
||||
let availability = availabilities.find((availability) => availability.purchaseOption === purchaseOption);
|
||||
|
||||
if (purchaseOption === 'delivery') {
|
||||
const digAvailability = availabilities.find((availability) => availability.purchaseOption === 'dig-delivery');
|
||||
const b2bAvailability = availabilities.find((availability) => availability.purchaseOption === 'b2b-delivery');
|
||||
|
||||
availability = availability || digAvailability || b2bAvailability;
|
||||
if (!(digAvailability && b2bAvailability)) {
|
||||
availability = digAvailability ?? b2bAvailability;
|
||||
}
|
||||
}
|
||||
|
||||
return availability;
|
||||
};
|
||||
}
|
||||
@@ -327,7 +347,6 @@ export function canContinue(state: PurchaseOptionsState): boolean {
|
||||
if (isGiftCard(item, getType(state))) {
|
||||
const price = getPriceForPurchaseOption(item.id, purchaseOption)(state);
|
||||
if (!(price?.value?.value > 0 && price?.value?.value <= GIFT_CARD_MAX_PRICE)) {
|
||||
console.log('price', price);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,21 +11,27 @@ import {
|
||||
UpdateShoppingCartItemDTO,
|
||||
} from '@swagger/checkout';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, shareReplay, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { map, shareReplay, take } from 'rxjs/operators';
|
||||
import { Branch, ItemData } from './purchase-options.types';
|
||||
import { memorize } from '@utils/common';
|
||||
import { AuthService } from '@core/auth';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { DomainOmsService } from '@domain/oms';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PurchaseOptionsService {
|
||||
constructor(
|
||||
private _availabilityService: DomainAvailabilityService,
|
||||
private _checkoutService: DomainCheckoutService,
|
||||
private _omsService: DomainOmsService,
|
||||
private _auth: AuthService,
|
||||
private _app: ApplicationService
|
||||
) {}
|
||||
|
||||
getVats$() {
|
||||
return this._omsService.getVATs();
|
||||
}
|
||||
|
||||
getSelectedBranchForProcess(processId: number): Observable<Branch> {
|
||||
return this._app.getSelectedBranch$(processId).pipe(take(1), shareReplay(1));
|
||||
}
|
||||
|
||||
@@ -26,9 +26,10 @@ import {
|
||||
} from './purchase-options.helpers';
|
||||
import { Observable } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { DEFAULT_PRICE_DTO, DEFAULT_PRICE_VALUE } from '../constants';
|
||||
import { DEFAULT_PRICE_DTO, DEFAULT_PRICE_VALUE, DEFAULT_VAT_VALUE } from '../constants';
|
||||
import { AddToShoppingCartDTO, EntityDTOContainerOfDestinationDTO, UpdateShoppingCartItemDTO } from '@swagger/checkout';
|
||||
import { isEqual, uniqueId } from 'lodash';
|
||||
import { uniqueId } from 'lodash';
|
||||
import { VATDTO } from '@swagger/oms';
|
||||
|
||||
@Injectable()
|
||||
export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
@@ -128,6 +129,10 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
|
||||
fetchingAvailabilities$ = this.select(Selectors.getFetchingAvailabilities);
|
||||
|
||||
get vats$() {
|
||||
return this._service.getVats$();
|
||||
}
|
||||
|
||||
constructor(private _service: PurchaseOptionsService) {
|
||||
super({
|
||||
defaultBranch: undefined,
|
||||
@@ -160,7 +165,7 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
};
|
||||
});
|
||||
|
||||
async initialize({ items, processId, type }: PurchaseOptionsModalData) {
|
||||
async initialize({ items, processId, type, inStoreBranch, pickupBranch }: PurchaseOptionsModalData) {
|
||||
const selectedBranch = await this._service.getSelectedBranchForProcess(processId).toPromise();
|
||||
const defaultBranch = await this._service.fetchDefaultBranch().toPromise();
|
||||
const customerFeatures = await this._service.getCustomerFeatures(processId).toPromise();
|
||||
@@ -170,8 +175,8 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
type: type,
|
||||
items: items.map((item) => ({ ...item, quantity: item['quantity'] ?? 1 })),
|
||||
defaultBranch: selectedBranch ?? defaultBranch,
|
||||
pickupBranch: selectedBranch,
|
||||
inStoreBranch: selectedBranch,
|
||||
pickupBranch: pickupBranch ?? selectedBranch,
|
||||
inStoreBranch: inStoreBranch ?? selectedBranch,
|
||||
customerFeatures,
|
||||
});
|
||||
|
||||
@@ -283,7 +288,6 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
try {
|
||||
this.addFetchingAvailability({ id, itemId: itemData.sourceId, purchaseOption: 'delivery' });
|
||||
const res = await this._service.fetchDeliveryAvailability(itemData, itemData.quantity).toPromise();
|
||||
|
||||
const availability: Availability = {
|
||||
itemId: itemData.sourceId,
|
||||
purchaseOption: 'delivery',
|
||||
@@ -636,14 +640,32 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
return this.select(Selectors.getCanEditPrice(itemId));
|
||||
}
|
||||
|
||||
setPrice(itemId: number, value: number) {
|
||||
setPrice(itemId: number, value: number, manually: boolean = false) {
|
||||
const prices = this.prices;
|
||||
let price = prices[itemId];
|
||||
if (price?.value?.value !== value) {
|
||||
if (!price) {
|
||||
price = { ...DEFAULT_PRICE_DTO, value: { ...DEFAULT_PRICE_VALUE, value } };
|
||||
price = {
|
||||
...DEFAULT_PRICE_DTO,
|
||||
value: { ...DEFAULT_PRICE_VALUE, value },
|
||||
vat: manually ? price?.vat : { ...DEFAULT_VAT_VALUE, ...price?.vat },
|
||||
};
|
||||
} else {
|
||||
price = { ...price, value: { ...price.value, value } };
|
||||
price = { ...price, value: { ...price.value, value }, vat: price?.vat };
|
||||
}
|
||||
|
||||
this.patchState({ prices: { ...prices, [itemId]: price } });
|
||||
}
|
||||
}
|
||||
|
||||
setVat(itemId: number, vat: VATDTO) {
|
||||
const prices = this.prices;
|
||||
let price = prices[itemId];
|
||||
if (price?.vat?.vatType !== vat?.vatType) {
|
||||
if (!price) {
|
||||
price = { ...DEFAULT_PRICE_DTO, value: { ...DEFAULT_PRICE_VALUE, ...price?.value }, vat: { ...DEFAULT_VAT_VALUE, ...vat } };
|
||||
} else {
|
||||
price = { ...price, value: price.value, vat: { ...price.vat, ...vat } };
|
||||
}
|
||||
|
||||
this.patchState({ prices: { ...prices, [itemId]: price } });
|
||||
|
||||
@@ -17,7 +17,7 @@ export type Branch = BranchDTO;
|
||||
export type Availability = {
|
||||
itemId: number;
|
||||
purchaseOption: PurchaseOption;
|
||||
data: AvailabilityDTO;
|
||||
data: AvailabilityDTO & { priceMaintained?: boolean; orderDeadline?: string };
|
||||
};
|
||||
|
||||
export type ItemData = AvailabilityItemData & { sourceId: number; quantity: number };
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { OrderDeadlinePipe } from './order-deadline.pipe';
|
||||
|
||||
@NgModule({
|
||||
imports: [OrderDeadlinePipe],
|
||||
exports: [OrderDeadlinePipe],
|
||||
})
|
||||
export class OrderDeadlinePipeModule {}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({
|
||||
name: 'orderDeadline',
|
||||
pure: true,
|
||||
standalone: true,
|
||||
})
|
||||
export class OrderDeadlinePipe implements PipeTransform {
|
||||
private datePipe: DatePipe;
|
||||
|
||||
constructor(@Inject(LOCALE_ID) private locale: string) {
|
||||
this.datePipe = new DatePipe(this.locale);
|
||||
}
|
||||
|
||||
transform(orderDeadline: string | Date | number): any {
|
||||
if (!orderDeadline) return 'Unbekannte Bestelldeadline';
|
||||
|
||||
const date = new Date(orderDeadline);
|
||||
|
||||
const isToday = date.toDateString() === new Date().toDateString();
|
||||
|
||||
let timeString = '';
|
||||
|
||||
if (isToday) {
|
||||
timeString = this.datePipe.transform(date, 'HH:mm', this.locale);
|
||||
} else {
|
||||
timeString = this.datePipe.transform(date, 'dd.MM HH:mm', this.locale);
|
||||
}
|
||||
|
||||
return `Bestelldeadline ${timeString} Uhr`;
|
||||
}
|
||||
}
|
||||
2
apps/shared/pipes/order-deadline/src/public-api.ts
Normal file
2
apps/shared/pipes/order-deadline/src/public-api.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './lib/order-deadline.pipe';
|
||||
export * from './lib/order-deadline-pipe.module';
|
||||
@@ -14,9 +14,11 @@ export interface AvailabilityDTO {
|
||||
itemId?: number;
|
||||
logistician?: string;
|
||||
logisticianId?: number;
|
||||
orderDeadline?: string;
|
||||
orderReference?: string;
|
||||
preferred?: number;
|
||||
price?: PriceDTO;
|
||||
priceMaintained?: boolean;
|
||||
qty?: number;
|
||||
requestMessage?: string;
|
||||
requestReference?: string;
|
||||
|
||||
@@ -14,9 +14,11 @@ export interface AvailabilityDTO2 {
|
||||
itemId?: number;
|
||||
logistician?: string;
|
||||
logisticianId?: number;
|
||||
orderDeadline?: string;
|
||||
orderReference?: string;
|
||||
preferred?: number;
|
||||
price?: PriceDTO;
|
||||
priceMaintained?: boolean;
|
||||
qty?: number;
|
||||
requestMessage?: string;
|
||||
requestReference?: string;
|
||||
|
||||
@@ -21,6 +21,8 @@ export interface OrderItemSubsetTaskListItemDTO {
|
||||
orderItemSubsetTransition?: EntityDTOContainerOfOrderItemSubsetTransitionDTO;
|
||||
orderNumber?: string;
|
||||
pId?: string;
|
||||
processingComment?: string;
|
||||
processingReference?: string;
|
||||
product?: ProductDTO;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type OrderItemType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64;
|
||||
export type OrderItemType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 256 | 512 | 1024;
|
||||
@@ -1,2 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type ReceiptType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512;
|
||||
export type ReceiptType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024;
|
||||
@@ -63,6 +63,7 @@ class OrderService extends __BaseService {
|
||||
static readonly OrderChangeStatusPath = '/order/{orderId}/orderitem/{orderItemId}/orderitemsubset/{orderItemSubsetId}/changestatus';
|
||||
static readonly OrderChangeStockStatusCodePath = '/order/orderitem/orderitemsubset/changestockstatuscode';
|
||||
static readonly OrderCollectOnDeliveryNotePath = '/order/orderitem/orderitemsubset/collectondeliverynote';
|
||||
static readonly OrderCollectWithSmallAmountInvoicePath = '/order/orderitem/orderitemsubset/collectwithsmallamountinvoice';
|
||||
static readonly OrderSetPreferredPickUpDatePath = '/order/orderitem/orderitemsubset/setpreferredpickupdate';
|
||||
static readonly OrderQueryOrderItemSubsetTasksPath = '/order/item/subset/task/s';
|
||||
static readonly OrderGetOrderItemSubsetTasksPath = '/order/{orderId}/item/{orderItemId}/subset/{orderItemSubsetId}/task';
|
||||
@@ -1056,6 +1057,49 @@ class OrderService extends __BaseService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param params The `OrderService.OrderCollectWithSmallAmountInvoiceParams` containing the following parameters:
|
||||
*
|
||||
* - `data`:
|
||||
*
|
||||
* - `eagerLoading`:
|
||||
*/
|
||||
OrderCollectWithSmallAmountInvoiceResponse(params: OrderService.OrderCollectWithSmallAmountInvoiceParams): __Observable<__StrictHttpResponse<ResponseArgsOfIEnumerableOfEntityDTOContainerOfReceiptDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = params.data;
|
||||
if (params.eagerLoading != null) __params = __params.set('eagerLoading', params.eagerLoading.toString());
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/order/orderitem/orderitemsubset/collectwithsmallamountinvoice`,
|
||||
__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<ResponseArgsOfIEnumerableOfEntityDTOContainerOfReceiptDTO>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param params The `OrderService.OrderCollectWithSmallAmountInvoiceParams` containing the following parameters:
|
||||
*
|
||||
* - `data`:
|
||||
*
|
||||
* - `eagerLoading`:
|
||||
*/
|
||||
OrderCollectWithSmallAmountInvoice(params: OrderService.OrderCollectWithSmallAmountInvoiceParams): __Observable<ResponseArgsOfIEnumerableOfEntityDTOContainerOfReceiptDTO> {
|
||||
return this.OrderCollectWithSmallAmountInvoiceResponse(params).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfIEnumerableOfEntityDTOContainerOfReceiptDTO)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param params The `OrderService.OrderSetPreferredPickUpDateParams` containing the following parameters:
|
||||
*
|
||||
@@ -1512,6 +1556,14 @@ module OrderService {
|
||||
eagerLoading?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for OrderCollectWithSmallAmountInvoice
|
||||
*/
|
||||
export interface OrderCollectWithSmallAmountInvoiceParams {
|
||||
data: {[key: string]: number};
|
||||
eagerLoading?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for OrderSetPreferredPickUpDate
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,8 @@ class ReceiptService extends __BaseService {
|
||||
static readonly ReceiptQueryReceiptsPath = '/receipt/s';
|
||||
static readonly ReceiptCreateShippingNotePath = '/receipt/shippingnote/fromorder';
|
||||
static readonly ReceiptCreateShippingNote2Path = '/receipt/shippingnote/fromitems';
|
||||
static readonly ReceiptCreateInvoicePath = '/receipt/invoice/fromorder';
|
||||
static readonly ReceiptCreateInvoice2Path = '/receipt/invoice/fromitems';
|
||||
static readonly ReceiptGetReceiptsByOrderItemSubsetPath = '/order/orderitem/orderitemsubset/receipts';
|
||||
|
||||
constructor(
|
||||
@@ -168,6 +170,102 @@ class ReceiptService extends __BaseService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param params The `ReceiptService.ReceiptCreateInvoiceParams` containing the following parameters:
|
||||
*
|
||||
* - `orderId`:
|
||||
*
|
||||
* - `locale`:
|
||||
*
|
||||
* - `eagerLoading`:
|
||||
*/
|
||||
ReceiptCreateInvoiceResponse(params: ReceiptService.ReceiptCreateInvoiceParams): __Observable<__StrictHttpResponse<ResponseArgsOfReceiptDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = params.orderId;
|
||||
if (params.locale != null) __params = __params.set('locale', params.locale.toString());
|
||||
if (params.eagerLoading != null) __params = __params.set('eagerLoading', params.eagerLoading.toString());
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/receipt/invoice/fromorder`,
|
||||
__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<ResponseArgsOfReceiptDTO>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param params The `ReceiptService.ReceiptCreateInvoiceParams` containing the following parameters:
|
||||
*
|
||||
* - `orderId`:
|
||||
*
|
||||
* - `locale`:
|
||||
*
|
||||
* - `eagerLoading`:
|
||||
*/
|
||||
ReceiptCreateInvoice(params: ReceiptService.ReceiptCreateInvoiceParams): __Observable<ResponseArgsOfReceiptDTO> {
|
||||
return this.ReceiptCreateInvoiceResponse(params).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfReceiptDTO)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param params The `ReceiptService.ReceiptCreateInvoice2Params` containing the following parameters:
|
||||
*
|
||||
* - `orderItemStatusIds`:
|
||||
*
|
||||
* - `locale`:
|
||||
*
|
||||
* - `eagerLoading`:
|
||||
*/
|
||||
ReceiptCreateInvoice2Response(params: ReceiptService.ReceiptCreateInvoice2Params): __Observable<__StrictHttpResponse<ResponseArgsOfIEnumerableOfReceiptDTO>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = params.orderItemStatusIds;
|
||||
if (params.locale != null) __params = __params.set('locale', params.locale.toString());
|
||||
if (params.eagerLoading != null) __params = __params.set('eagerLoading', params.eagerLoading.toString());
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/receipt/invoice/fromitems`,
|
||||
__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<ResponseArgsOfIEnumerableOfReceiptDTO>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param params The `ReceiptService.ReceiptCreateInvoice2Params` containing the following parameters:
|
||||
*
|
||||
* - `orderItemStatusIds`:
|
||||
*
|
||||
* - `locale`:
|
||||
*
|
||||
* - `eagerLoading`:
|
||||
*/
|
||||
ReceiptCreateInvoice2(params: ReceiptService.ReceiptCreateInvoice2Params): __Observable<ResponseArgsOfIEnumerableOfReceiptDTO> {
|
||||
return this.ReceiptCreateInvoice2Response(params).pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfIEnumerableOfReceiptDTO)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param params The `ReceiptService.ReceiptGetReceiptsByOrderItemSubsetParams` containing the following parameters:
|
||||
*
|
||||
@@ -240,6 +338,24 @@ module ReceiptService {
|
||||
eagerLoading?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for ReceiptCreateInvoice
|
||||
*/
|
||||
export interface ReceiptCreateInvoiceParams {
|
||||
orderId: number;
|
||||
locale?: null | string;
|
||||
eagerLoading?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for ReceiptCreateInvoice2
|
||||
*/
|
||||
export interface ReceiptCreateInvoice2Params {
|
||||
orderItemStatusIds: Array<number>;
|
||||
locale?: null | string;
|
||||
eagerLoading?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for ReceiptGetReceiptsByOrderItemSubset
|
||||
*/
|
||||
|
||||
@@ -186,5 +186,6 @@ export { TermsOfDeliveryDTO2 } from './models/terms-of-delivery-dto2';
|
||||
export { ReadOnlyEntityDTOOfDisplayOrderDTOAndIOrder } from './models/read-only-entity-dtoof-display-order-dtoand-iorder';
|
||||
export { PrintRequestOfIEnumerableOfPriceQRCodeDTO } from './models/print-request-of-ienumerable-of-price-qrcode-dto';
|
||||
export { PriceQRCodeDTO } from './models/price-qrcode-dto';
|
||||
export { ResponseArgsOfIEnumerableOfString } from './models/response-args-of-ienumerable-of-string';
|
||||
export { ListResponseArgsOfKeyValueDTOOfStringAndString } from './models/list-response-args-of-key-value-dtoof-string-and-string';
|
||||
export { ResponseArgsOfIEnumerableOfKeyValueDTOOfStringAndString } from './models/response-args-of-ienumerable-of-key-value-dtoof-string-and-string';
|
||||
|
||||
@@ -1,38 +1,10 @@
|
||||
/* tslint:disable */
|
||||
import { PriceValueDTO } from './price-value-dto';
|
||||
|
||||
/**
|
||||
* PriceQRCodeDTO
|
||||
*/
|
||||
export interface PriceQRCodeDTO {
|
||||
|
||||
/**
|
||||
* Abholfachnummer
|
||||
*/
|
||||
compartmentCode?: string;
|
||||
|
||||
/**
|
||||
* Abholfachnummer Zusatz
|
||||
*/
|
||||
compartmentInfo?: string;
|
||||
|
||||
/**
|
||||
* Anzahl Ausdrucke
|
||||
*/
|
||||
copies?: number;
|
||||
|
||||
/**
|
||||
* EAN
|
||||
*/
|
||||
ean?: string;
|
||||
|
||||
/**
|
||||
* Preis
|
||||
*/
|
||||
price?: PriceValueDTO;
|
||||
|
||||
/**
|
||||
* Titel / Bezeichner
|
||||
*/
|
||||
title?: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/* tslint:disable */
|
||||
import { ResponseArgs } from './response-args';
|
||||
export interface ResponseArgsOfIEnumerableOfString extends ResponseArgs{
|
||||
result?: Array<string>;
|
||||
}
|
||||
@@ -18,8 +18,11 @@ class OMSPrintService extends __BaseService {
|
||||
static readonly OMSPrintAbholscheinByIdPath = '/print/abholschein';
|
||||
static readonly OMSPrintAbholscheinPath = '/print/abholschein/data';
|
||||
static readonly OMSPrintAbholfachetikettPath = '/print/abholfachetikett';
|
||||
static readonly OMSPrintAbholfachetikettDirectPath = '/print-direct/abholfachetikett';
|
||||
static readonly OMSPrintPriceQRCodePath = '/print/priceqrcode';
|
||||
static readonly OMSPrintPriceQRCodeDirectPath = '/print-direct/priceqrcode';
|
||||
static readonly OMSPrintLieferscheinPath = '/print/lieferschein';
|
||||
static readonly OMSPrintKleinbetragsrechnungPath = '/print/kleinbetragsrechnung';
|
||||
|
||||
constructor(
|
||||
config: __Configuration,
|
||||
@@ -136,6 +139,42 @@ class OMSPrintService extends __BaseService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abholfachetikett (direkte Druckeransteuerung)
|
||||
* @param data Bestellpostenteilmenge PKs
|
||||
*/
|
||||
OMSPrintAbholfachetikettDirectResponse(data: PrintRequestOfIEnumerableOfLong): __Observable<__StrictHttpResponse<ResponseArgs>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = data;
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/print-direct/abholfachetikett`,
|
||||
__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<ResponseArgs>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Abholfachetikett (direkte Druckeransteuerung)
|
||||
* @param data Bestellpostenteilmenge PKs
|
||||
*/
|
||||
OMSPrintAbholfachetikettDirect(data: PrintRequestOfIEnumerableOfLong): __Observable<ResponseArgs> {
|
||||
return this.OMSPrintAbholfachetikettDirectResponse(data).pipe(
|
||||
__map(_r => _r.body as ResponseArgs)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abholfachpreis-Etikett
|
||||
* @param data Bestellpostenteilmenge PKs
|
||||
@@ -172,6 +211,42 @@ class OMSPrintService extends __BaseService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abholfachpreis-Etikett (direkte Druckeransteuerung)
|
||||
* @param data Bestellpostenteilmenge PKs
|
||||
*/
|
||||
OMSPrintPriceQRCodeDirectResponse(data: PrintRequestOfIEnumerableOfPriceQRCodeDTO): __Observable<__StrictHttpResponse<ResponseArgs>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = data;
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/print-direct/priceqrcode`,
|
||||
__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<ResponseArgs>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Abholfachpreis-Etikett (direkte Druckeransteuerung)
|
||||
* @param data Bestellpostenteilmenge PKs
|
||||
*/
|
||||
OMSPrintPriceQRCodeDirect(data: PrintRequestOfIEnumerableOfPriceQRCodeDTO): __Observable<ResponseArgs> {
|
||||
return this.OMSPrintPriceQRCodeDirectResponse(data).pipe(
|
||||
__map(_r => _r.body as ResponseArgs)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lieferschein
|
||||
* @param data Lieferschein PKs
|
||||
@@ -207,6 +282,42 @@ class OMSPrintService extends __BaseService {
|
||||
__map(_r => _r.body as ResponseArgs)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kleinbetragsrechnung
|
||||
* @param data Kleinbetragsrechnung PKs
|
||||
*/
|
||||
OMSPrintKleinbetragsrechnungResponse(data: PrintRequestOfIEnumerableOfLong): __Observable<__StrictHttpResponse<ResponseArgs>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = data;
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/print/kleinbetragsrechnung`,
|
||||
__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<ResponseArgs>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Kleinbetragsrechnung
|
||||
* @param data Kleinbetragsrechnung PKs
|
||||
*/
|
||||
OMSPrintKleinbetragsrechnung(data: PrintRequestOfIEnumerableOfLong): __Observable<ResponseArgs> {
|
||||
return this.OMSPrintKleinbetragsrechnungResponse(data).pipe(
|
||||
__map(_r => _r.body as ResponseArgs)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module OMSPrintService {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { StrictHttpResponse as __StrictHttpResponse } from '../strict-http-respo
|
||||
import { Observable as __Observable } from 'rxjs';
|
||||
import { map as __map, filter as __filter } from 'rxjs/operators';
|
||||
|
||||
import { ResponseArgsOfIEnumerableOfString } from '../models/response-args-of-ienumerable-of-string';
|
||||
import { ListResponseArgsOfKeyValueDTOOfStringAndString } from '../models/list-response-args-of-key-value-dtoof-string-and-string';
|
||||
import { ResponseArgs } from '../models/response-args';
|
||||
import { PrintRequest } from '../models/print-request';
|
||||
@@ -15,11 +16,14 @@ import { PrintRequestOfString } from '../models/print-request-of-string';
|
||||
providedIn: 'root',
|
||||
})
|
||||
class PrintService extends __BaseService {
|
||||
static readonly PrintInitializeLabelPrintersPath = '/printers/label/init';
|
||||
static readonly PrintInitializeOfficePrintersPath = '/printers/office/init';
|
||||
static readonly PrintPrintersPath = '/printers';
|
||||
static readonly PrintLabelPrintersPath = '/printers/label';
|
||||
static readonly PrintOfficePrintersPath = '/printers/office';
|
||||
static readonly PrintTestPath = '/print/test';
|
||||
static readonly PrintPrinterDetailsPath = '/printers/details';
|
||||
static readonly PrintDirectPrintTestPath = '/printers/directprinttest';
|
||||
static readonly PrintPrintPdfPath = '/print/pdf';
|
||||
static readonly PrintMonitorPath = '/print/monitor';
|
||||
static readonly PrintStatusPath = '/print/status';
|
||||
@@ -31,6 +35,72 @@ class PrintService extends __BaseService {
|
||||
super(config, http);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize label printers
|
||||
*/
|
||||
PrintInitializeLabelPrintersResponse(): __Observable<__StrictHttpResponse<ResponseArgsOfIEnumerableOfString>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/printers/label/init`,
|
||||
__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<ResponseArgsOfIEnumerableOfString>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Initialize label printers
|
||||
*/
|
||||
PrintInitializeLabelPrinters(): __Observable<ResponseArgsOfIEnumerableOfString> {
|
||||
return this.PrintInitializeLabelPrintersResponse().pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfIEnumerableOfString)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize office printers
|
||||
*/
|
||||
PrintInitializeOfficePrintersResponse(): __Observable<__StrictHttpResponse<ResponseArgsOfIEnumerableOfString>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/printers/office/init`,
|
||||
__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<ResponseArgsOfIEnumerableOfString>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Initialize office printers
|
||||
*/
|
||||
PrintInitializeOfficePrinters(): __Observable<ResponseArgsOfIEnumerableOfString> {
|
||||
return this.PrintInitializeOfficePrintersResponse().pipe(
|
||||
__map(_r => _r.body as ResponseArgsOfIEnumerableOfString)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verfügbare Drucker
|
||||
*/
|
||||
@@ -202,6 +272,40 @@ class PrintService extends __BaseService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data undefined
|
||||
*/
|
||||
PrintDirectPrintTestResponse(data: PrintRequest): __Observable<__StrictHttpResponse<ResponseArgs>> {
|
||||
let __params = this.newParams();
|
||||
let __headers = new HttpHeaders();
|
||||
let __body: any = null;
|
||||
__body = data;
|
||||
let req = new HttpRequest<any>(
|
||||
'POST',
|
||||
this.rootUrl + `/printers/directprinttest`,
|
||||
__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<ResponseArgs>;
|
||||
})
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param data undefined
|
||||
*/
|
||||
PrintDirectPrintTest(data: PrintRequest): __Observable<ResponseArgs> {
|
||||
return this.PrintDirectPrintTestResponse(data).pipe(
|
||||
__map(_r => _r.body as ResponseArgs)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Druckt das übergebene Pdf-Dokument (base64)
|
||||
* @param data Artikel
|
||||
|
||||
@@ -8,6 +8,7 @@ export { EntityDTOBaseOfUserDTOAndIUser } from './models/entity-dtobase-of-user-
|
||||
export { EntityDTOBase } from './models/entity-dtobase';
|
||||
export { EntityDTO } from './models/entity-dto';
|
||||
export { EntityStatus } from './models/entity-status';
|
||||
export { CRUDA } from './models/cruda';
|
||||
export { TouchedBase } from './models/touched-base';
|
||||
export { EntityDTOReferenceContainer } from './models/entity-dtoreference-container';
|
||||
export { ExternalReferenceDTO } from './models/external-reference-dto';
|
||||
|
||||
2
apps/swagger/wws/src/lib/models/cruda.ts
Normal file
2
apps/swagger/wws/src/lib/models/cruda.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type CRUDA = 0 | 1 | 2 | 4 | 8 | 16;
|
||||
@@ -1,9 +1,11 @@
|
||||
/* 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;
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface PackageArrivalStatusDTO {
|
||||
id: string;
|
||||
misrouted?: string;
|
||||
packageNumber?: string;
|
||||
scanId?: string;
|
||||
supplier?: string;
|
||||
trackingNumber?: string;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
import { PackageArrivalStatusDTO } from './package-arrival-status-dto';
|
||||
export interface PackageDTO2 extends PackageArrivalStatusDTO{
|
||||
app?: string;
|
||||
complainedEmail?: string;
|
||||
creditRequestedEmail?: string;
|
||||
items?: number;
|
||||
itemsOrdered?: number;
|
||||
missing?: string;
|
||||
valueOfGoods?: number;
|
||||
weight?: number;
|
||||
}
|
||||
|
||||
@@ -122,8 +122,7 @@ export class UiOverlayTriggerDirective implements OnInit, OnDestroy, OnChanges {
|
||||
createOverlay() {
|
||||
this.overlayRef = this.overlay.create({
|
||||
positionStrategy: this.getPositionStrategy(),
|
||||
hasBackdrop: true,
|
||||
backdropClass: 'cdk-overlay-transparent-backdrop',
|
||||
hasBackdrop: false,
|
||||
});
|
||||
this.overlayRef
|
||||
.backdropClick()
|
||||
@@ -170,4 +169,11 @@ export class UiOverlayTriggerDirective implements OnInit, OnDestroy, OnChanges {
|
||||
updatePosition() {
|
||||
this.overlayRef?.updatePositionStrategy(this.getPositionStrategy());
|
||||
}
|
||||
|
||||
@HostListener('document:click', ['$event'])
|
||||
documentClick(event: MouseEvent) {
|
||||
if (this.viewRef && !this.overlayRef?.hostElement?.contains(event.target as HTMLElement)) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,12 @@ export class UiFilterInputTextComponent extends AbstractUiFilterInputDirective i
|
||||
this.control.setValue(this.value);
|
||||
this.updateValidator();
|
||||
|
||||
const uiInputChangesSub = this.uiInput?.changes?.subscribe((changes) => {
|
||||
if (this.control.value !== changes?.target?.value) this.control.setValue(changes?.target?.value);
|
||||
|
||||
this.updateValidator();
|
||||
});
|
||||
|
||||
const onInputChangeSub = this.onUiInputChange$.subscribe((input) => {
|
||||
if (this.control.value !== input.value) this.control.setValue(input.value);
|
||||
|
||||
@@ -32,6 +38,7 @@ export class UiFilterInputTextComponent extends AbstractUiFilterInputDirective i
|
||||
if (this.value !== value) this.setValue(value);
|
||||
});
|
||||
|
||||
this._subscriptions.add(uiInputChangesSub);
|
||||
this._subscriptions.add(onInputChangeSub);
|
||||
this._subscriptions.add(onControlValueChangeSub);
|
||||
}
|
||||
|
||||
@@ -191,6 +191,21 @@ export class UiFilter implements IUiFilter {
|
||||
};
|
||||
}
|
||||
|
||||
unselectAll() {
|
||||
this.filter?.forEach((uiInputGroup) =>
|
||||
uiInputGroup?.input?.forEach((uiInput) => {
|
||||
uiInput?.setSelected(undefined);
|
||||
uiInput?.setValue(undefined);
|
||||
})
|
||||
);
|
||||
this.input?.forEach((uiInputGroup) =>
|
||||
uiInputGroup?.input?.forEach((uiInput) => {
|
||||
uiInput?.setSelected(undefined);
|
||||
uiInput?.setValue(undefined);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
static create(settings: IUiFilter) {
|
||||
const target = new UiFilter();
|
||||
|
||||
|
||||
@@ -20,27 +20,7 @@ variables:
|
||||
- group: 'GithubCMF'
|
||||
|
||||
jobs:
|
||||
# - job: cibuild_fast
|
||||
# displayName: ISAClient CI Fast
|
||||
# pool:
|
||||
# name: 'Default'
|
||||
# demands:
|
||||
# - Agent.OS -equals Linux
|
||||
# - docker
|
||||
# condition: and(ne(variables['Build.SourceBranch'], 'refs/heads/develop'), ne(variables['Build.SourceBranch'], 'refs/heads/integration'), ne(variables['Build.SourceBranch'], 'refs/heads/master'), not(startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/')), not(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')))
|
||||
# steps:
|
||||
# - task: npmAuthenticate@0
|
||||
# displayName: 'npm auth'
|
||||
# inputs:
|
||||
# workingFile: .npmrc
|
||||
# - task: Docker@2
|
||||
# displayName: 'build ISAClient Debug'
|
||||
# inputs:
|
||||
# command: 'build'
|
||||
# Dockerfile: Dockerfile
|
||||
# buildContext:
|
||||
# tags: '$(Build.BuildNumber)-$(Build.SourceVersion)'
|
||||
# arguments: '--build-arg SEMVERSION=$(Major).$(Minor).$(Patch)'
|
||||
|
||||
- job: unittests
|
||||
displayName: Unit Tests
|
||||
pool:
|
||||
@@ -99,6 +79,7 @@ jobs:
|
||||
fi
|
||||
displayName: Remove docker image
|
||||
condition: always()
|
||||
|
||||
- job: cibuild_debug
|
||||
displayName: ISAClient CI Debug
|
||||
pool:
|
||||
@@ -107,7 +88,15 @@ jobs:
|
||||
- Agent.OS -equals Linux
|
||||
- docker
|
||||
condition: and(ne(variables['Build.SourceBranch'], 'refs/heads/integration'), ne(variables['Build.SourceBranch'], 'refs/heads/master'), not(startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/')), not(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')))
|
||||
variables:
|
||||
- name: DockerTagSourceBranch
|
||||
value: $[replace(variables['Build.SourceBranch'], '/', '_')]
|
||||
- name: 'DockerTag'
|
||||
value: |
|
||||
$(Build.BuildNumber)-$(Build.SourceVersion)
|
||||
$(DockerTagSourceBranch)
|
||||
steps:
|
||||
|
||||
- task: npmAuthenticate@0
|
||||
displayName: 'npm auth'
|
||||
inputs:
|
||||
@@ -121,7 +110,7 @@ jobs:
|
||||
command: 'build'
|
||||
Dockerfile: Dockerfile
|
||||
buildContext:
|
||||
tags: '$(Build.BuildNumber)-$(Build.SourceVersion)'
|
||||
tags: '$(DockerTag)'
|
||||
arguments: |
|
||||
--no-cache
|
||||
--target publish
|
||||
@@ -135,7 +124,7 @@ jobs:
|
||||
containerRegistry: 'Harbor isa'
|
||||
repository: 'isa/ui'
|
||||
command: 'push'
|
||||
tags: '$(Build.BuildNumber)-$(Build.SourceVersion)'
|
||||
tags: '$(DockerTag)'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Artefakt veröffentlichen: HelmValues'
|
||||
@@ -169,6 +158,13 @@ jobs:
|
||||
- Agent.OS -equals Linux
|
||||
- docker
|
||||
condition: or(eq(variables['Build.SourceBranch'], 'refs/heads/integration'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))
|
||||
variables:
|
||||
- name: DockerTagSourceBranch
|
||||
value: $[replace(variables['Build.SourceBranch'], '/', '_')]
|
||||
- name: 'DockerTag'
|
||||
value: |
|
||||
$(Build.BuildNumber)-$(Build.SourceVersion)
|
||||
$(DockerTagSourceBranch)
|
||||
steps:
|
||||
- task: npmAuthenticate@0
|
||||
displayName: 'npm auth'
|
||||
@@ -183,7 +179,7 @@ jobs:
|
||||
command: 'build'
|
||||
Dockerfile: Dockerfile
|
||||
buildContext:
|
||||
tags: '$(Build.BuildNumber)-$(Build.SourceVersion)'
|
||||
tags: '$(DockerTag)'
|
||||
arguments: |
|
||||
--no-cache
|
||||
--target publish
|
||||
@@ -198,7 +194,7 @@ jobs:
|
||||
containerRegistry: 'Harbor isa'
|
||||
repository: 'isa/ui'
|
||||
command: 'push'
|
||||
tags: '$(Build.BuildNumber)-$(Build.SourceVersion)'
|
||||
tags: '$(DockerTag)'
|
||||
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
|
||||
Reference in New Issue
Block a user