mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 499: #1243 Warenausgabe Status in Trefferliste setzen
#1243 Warenausgabe Status in Trefferliste setzen
This commit is contained in:
@@ -1,19 +1,9 @@
|
||||
<div class="tags" *ngIf="item.features">
|
||||
<lib-icon
|
||||
*ngIf="item.features?.prebooked && item.processingStatus !== 256"
|
||||
name="tag_icon_preorder"
|
||||
height="48px"
|
||||
></lib-icon>
|
||||
<lib-icon *ngIf="item.features?.prebooked && item.processingStatus !== 256" name="tag_icon_preorder" height="48px"></lib-icon>
|
||||
</div>
|
||||
<div class="feature-spacing" *ngIf="item.features?.prebooked"></div>
|
||||
<div
|
||||
class="isa-text-right isa-mb-9 isa-font-size-18"
|
||||
*ngIf="item.compartmentCode && displayCompartmentCode"
|
||||
>
|
||||
<strong
|
||||
>{{ item.compartmentCode
|
||||
}}{{ item.compartmentInfo && '_' + item.compartmentInfo }}
|
||||
</strong>
|
||||
<div class="isa-text-right isa-mb-9 isa-font-size-18" *ngIf="item.compartmentCode && displayCompartmentCode">
|
||||
<strong>{{ item.compartmentCode }}{{ item.compartmentInfo && '_' + item.compartmentInfo }} </strong>
|
||||
</div>
|
||||
<div class="isa-paid-marker isa-mt-9 isa-mb-9" *ngIf="item.features?.paid">
|
||||
<lib-icon height="24px" width="24px" name="Check_green_circle"></lib-icon>
|
||||
@@ -24,16 +14,9 @@
|
||||
<img class="thumbnail" src="{{ cdnProdutctPictures }}/{{ item.product.ean }}.jpg?showDummy=true" alt="item.product.name" />
|
||||
</div>
|
||||
<div class="title">
|
||||
<strong class="product-name">
|
||||
{{ [item.product.contributors, item.product.name] | title }}</strong
|
||||
>
|
||||
<strong class="product-name"> {{ [item.product.contributors, item.product.name] | title }}</strong>
|
||||
<strong class="processing-status">
|
||||
<lib-icon
|
||||
class="isa-mr-9"
|
||||
*ngIf="item.processingStatus | processingStatus: 'icon'; let icon"
|
||||
[name]="icon"
|
||||
[ngClass]="icon"
|
||||
>
|
||||
<lib-icon class="isa-mr-9" *ngIf="item.processingStatus | processingStatus: 'icon'; let icon" [name]="icon" [ngClass]="icon">
|
||||
</lib-icon>
|
||||
{{ item.processingStatus | processingStatus }}
|
||||
</strong>
|
||||
@@ -43,57 +26,29 @@
|
||||
</div>
|
||||
<div class="details">
|
||||
<div class="item-type">
|
||||
<lib-icon
|
||||
class="isa-mr-9"
|
||||
name="Icon_{{ item.product.format }}"
|
||||
></lib-icon>
|
||||
<lib-icon class="isa-mr-9" name="Icon_{{ item.product.format }}"></lib-icon>
|
||||
<strong class="item-type-text">{{ item.product.formatDetail }}</strong>
|
||||
</div>
|
||||
<ng-container [ngSwitch]="item.processingStatus">
|
||||
<div class="order-date spec" *ngSwitchCase="256">
|
||||
<span>Geändert</span>
|
||||
<strong
|
||||
>{{
|
||||
item.processingStatusDate | date: 'dd.MM.yy | HH:mm'
|
||||
}}
|
||||
Uhr</strong
|
||||
>
|
||||
<strong>{{ item.processingStatusDate | date: 'dd.MM.yy | HH:mm' }} Uhr</strong>
|
||||
</div>
|
||||
<div class="order-date spec" *ngSwitchCase="512">
|
||||
<span>Geändert</span>
|
||||
<strong
|
||||
>{{
|
||||
item.processingStatusDate | date: 'dd.MM.yy | HH:mm'
|
||||
}}
|
||||
Uhr</strong
|
||||
>
|
||||
<strong>{{ item.processingStatusDate | date: 'dd.MM.yy | HH:mm' }} Uhr</strong>
|
||||
</div>
|
||||
<div class="order-date spec" *ngSwitchCase="1024">
|
||||
<span>Geändert</span>
|
||||
<strong
|
||||
>{{
|
||||
item.processingStatusDate | date: 'dd.MM.yy | HH:mm'
|
||||
}}
|
||||
Uhr</strong
|
||||
>
|
||||
<strong>{{ item.processingStatusDate | date: 'dd.MM.yy | HH:mm' }} Uhr</strong>
|
||||
</div>
|
||||
<div class="order-date spec" *ngSwitchCase="2048">
|
||||
<span>Geändert</span>
|
||||
<strong
|
||||
>{{
|
||||
item.processingStatusDate | date: 'dd.MM.yy | HH:mm'
|
||||
}}
|
||||
Uhr</strong
|
||||
>
|
||||
<strong>{{ item.processingStatusDate | date: 'dd.MM.yy | HH:mm' }} Uhr</strong>
|
||||
</div>
|
||||
<div class="order-date spec" *ngSwitchCase="4096">
|
||||
<span>Geändert</span>
|
||||
<strong
|
||||
>{{
|
||||
item.processingStatusDate | date: 'dd.MM.yy | HH:mm'
|
||||
}}
|
||||
Uhr</strong
|
||||
>
|
||||
<strong>{{ item.processingStatusDate | date: 'dd.MM.yy | HH:mm' }} Uhr</strong>
|
||||
</div>
|
||||
<div class="order-date spec" *ngSwitchDefault>
|
||||
<span>Bestelldatum</span>
|
||||
@@ -114,5 +69,10 @@
|
||||
<span>Zielfiliale</span>
|
||||
<strong>{{ item.targetBranch }}</strong>
|
||||
</div>
|
||||
|
||||
<div class="selection" *ngIf="item.processingStatus === 128" [class.hide]="checkboxDisabled$ | async">
|
||||
<input type="checkbox" [ngModel]="selected" />
|
||||
<span class="checkmark" (click)="selectionChange()"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -48,15 +48,74 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 340px;
|
||||
grid-template-columns: 1fr 340px 80px;
|
||||
grid-template-rows: auto auto auto;
|
||||
grid-template-areas: 'item-type order-date' 'item-number quantity' 'price target-branch';
|
||||
grid-area: details;
|
||||
}
|
||||
|
||||
.selection {
|
||||
grid-row: 1 / span 3;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
font-size: 22px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
input {
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.checkmark {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
background-color: #eee;
|
||||
-webkit-box-shadow: inset 0px 0px 2px 0px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: inset 0px 0px 2px 0px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0px 0px 2px 0px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&:hover input ~ .checkmark {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
input:checked ~ .checkmark {
|
||||
background-color: #1f466d;
|
||||
}
|
||||
|
||||
.checkmark:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: none;
|
||||
}
|
||||
|
||||
input:checked ~ .checkmark:after {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.checkmark:after {
|
||||
left: 10px;
|
||||
top: 5px;
|
||||
width: 7px;
|
||||
height: 13px;
|
||||
border: solid white;
|
||||
border-width: 0 3px 3px 0;
|
||||
-webkit-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
|
||||
.item-type {
|
||||
grid-area: item-type;
|
||||
position: relative;
|
||||
@@ -115,3 +174,7 @@
|
||||
.feature-spacing {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: collapse;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Component, OnInit, ChangeDetectionStrategy, Input, Inject } from '@angular/core';
|
||||
import { Component, OnInit, ChangeDetectionStrategy, Input, Inject, Output, EventEmitter, OnDestroy } from '@angular/core';
|
||||
import { OrderItemListItemDTO } from '@swagger/oms';
|
||||
import { CDN_PRODUCT_PICTURES } from 'apps/sales/src/app/tokens';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-result-group-item',
|
||||
@@ -8,14 +10,51 @@ import { CDN_PRODUCT_PICTURES } from 'apps/sales/src/app/tokens';
|
||||
styleUrls: ['search-result-group-item.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class SearchResultGroupItemComponent implements OnInit {
|
||||
export class SearchResultGroupItemComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
item: OrderItemListItemDTO;
|
||||
|
||||
@Input()
|
||||
displayCompartmentCode = true;
|
||||
|
||||
@Input()
|
||||
disableSelection: EventEmitter<OrderItemListItemDTO>;
|
||||
|
||||
@Input()
|
||||
setSelection: EventEmitter<OrderItemListItemDTO>;
|
||||
|
||||
@Output()
|
||||
itemSelected = new EventEmitter<{ item: OrderItemListItemDTO; checked: boolean }>();
|
||||
|
||||
setSelectionSubscribtion: Subscription;
|
||||
|
||||
selected: boolean;
|
||||
|
||||
checkboxDisabled$: Observable<boolean>;
|
||||
|
||||
constructor(@Inject(CDN_PRODUCT_PICTURES) public cdnProdutctPictures: string) {}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
this.setSelectionSubscribtion = this.setSelection.subscribe((item) => {
|
||||
this.selected = this.item.orderItemSubsetId === item.orderItemSubsetId;
|
||||
});
|
||||
this.checkboxDisabled$ = this.disableSelection.pipe(
|
||||
map((item) => {
|
||||
if (!item) return false;
|
||||
|
||||
return this.item.orderId != item.orderId || this.item.processingStatus != item.processingStatus;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.setSelectionSubscribtion) {
|
||||
this.setSelectionSubscribtion.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
selectionChange() {
|
||||
this.selected = !this.selected;
|
||||
this.itemSelected.emit({ item: this.item, checked: this.selected });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,18 @@
|
||||
<div class="isa-card">
|
||||
<h3 class="heading">
|
||||
{{ group.items[0].firstName }} {{ group.items[0].lastName }}
|
||||
</h3>
|
||||
<ng-container
|
||||
*ngFor="
|
||||
let byOrderNumber of group.items | groupBy: byOrderNumberFn;
|
||||
let lastOrder = last
|
||||
"
|
||||
>
|
||||
<ng-container
|
||||
*ngFor="
|
||||
let byProcessingStatus of byOrderNumber.items
|
||||
| groupBy: byProcessingStatusFn;
|
||||
let lastStatus = last
|
||||
"
|
||||
>
|
||||
<ng-container
|
||||
*ngFor="
|
||||
let groupedBy of byProcessingStatus.items
|
||||
| groupBy: byCompartmentCodeFn;
|
||||
let lastCompartment = last
|
||||
"
|
||||
>
|
||||
<h3 class="heading">{{ group.items[0].firstName }} {{ group.items[0].lastName }}</h3>
|
||||
<ng-container *ngFor="let byOrderNumber of group.items | groupBy: byOrderNumberFn; let lastOrder = last">
|
||||
<ng-container *ngFor="let byProcessingStatus of byOrderNumber.items | groupBy: byProcessingStatusFn; let lastStatus = last">
|
||||
<ng-container *ngFor="let groupedBy of byProcessingStatus.items | groupBy: byCompartmentCodeFn; let lastCompartment = last">
|
||||
<div class="isa-mb-12 isa-mt-12">
|
||||
<app-search-result-group-item
|
||||
*ngFor="
|
||||
let item of groupedBy.items;
|
||||
let firstItem = first;
|
||||
let lastItem = last
|
||||
"
|
||||
*ngFor="let item of groupedBy.items; let firstItem = first; let lastItem = last"
|
||||
[item]="item"
|
||||
[class.group-item-bottom-space]="!lastItem"
|
||||
(click)="selectOrderItemListItem.emit(item)"
|
||||
[displayCompartmentCode]="
|
||||
firstItem | showCompartmentCode: item:group.items
|
||||
"
|
||||
(click)="onItemClick({ e: $event, item: item })"
|
||||
(itemSelected)="onItemSelected($event)"
|
||||
[disableSelection]="disableSelection"
|
||||
[setSelection]="setSelection"
|
||||
[displayCompartmentCode]="firstItem | showCompartmentCode: item:group.items"
|
||||
>
|
||||
</app-search-result-group-item>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
ChangeDetectionStrategy,
|
||||
Input,
|
||||
EventEmitter,
|
||||
Output,
|
||||
} from '@angular/core';
|
||||
import { Component, OnInit, ChangeDetectionStrategy, Input, EventEmitter, Output } from '@angular/core';
|
||||
import { OrderItemListItemDTO } from '@swagger/oms';
|
||||
import { Group } from 'apps/sales/src/app/utils';
|
||||
import { ShelfNavigationService } from '../../shared/services';
|
||||
@@ -23,6 +16,18 @@ export class SearchResultGroupComponent implements OnInit {
|
||||
@Output()
|
||||
selectOrderItemListItem = new EventEmitter<OrderItemListItemDTO>();
|
||||
|
||||
@Output()
|
||||
orderListItemChecked = new EventEmitter<{ item: OrderItemListItemDTO; checked: boolean }>();
|
||||
|
||||
@Input()
|
||||
disableSelection: EventEmitter<OrderItemListItemDTO>;
|
||||
|
||||
@Input()
|
||||
setSelection: EventEmitter<OrderItemListItemDTO>;
|
||||
|
||||
@Output()
|
||||
refreshCheckedState = new EventEmitter<void>();
|
||||
|
||||
byOrderNumberFn = (item: OrderItemListItemDTO) => item.orderNumber;
|
||||
|
||||
byProcessingStatusFn = (item: OrderItemListItemDTO) => item.processingStatus;
|
||||
@@ -31,9 +36,21 @@ export class SearchResultGroupComponent implements OnInit {
|
||||
|
||||
constructor(private navigationFacade: ShelfNavigationService) {}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
this.refreshCheckedState.emit();
|
||||
}
|
||||
|
||||
navigateToDetails(orderItem: OrderItemListItemDTO) {
|
||||
this.navigationFacade.navigateToDetails(orderItem);
|
||||
}
|
||||
|
||||
onItemClick({ e, item }) {
|
||||
if (e.target.className !== 'checkmark') {
|
||||
this.selectOrderItemListItem.emit(item);
|
||||
}
|
||||
}
|
||||
|
||||
onItemSelected({ item, checked }) {
|
||||
this.orderListItemChecked.emit({ item, checked });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,10 @@ import { SearchResultGroupItemComponent } from './search-result-group-item.compo
|
||||
import { IconModule } from '@libs/ui';
|
||||
import { PipesModule } from 'apps/sales/src/app/pipes/pipes.module';
|
||||
import { ShelfPipesModule } from '../../pipes';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, IconModule, PipesModule, ShelfPipesModule],
|
||||
imports: [CommonModule, FormsModule, IconModule, PipesModule, ShelfPipesModule],
|
||||
exports: [SearchResultGroupComponent],
|
||||
declarations: [SearchResultGroupComponent, SearchResultGroupItemComponent],
|
||||
providers: [],
|
||||
|
||||
@@ -1,23 +1,6 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
QueryList,
|
||||
ViewChild,
|
||||
ViewChildren,
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, QueryList, ViewChild, ViewChildren } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import {
|
||||
map,
|
||||
switchMap,
|
||||
first,
|
||||
filter,
|
||||
flatMap,
|
||||
distinctUntilChanged,
|
||||
shareReplay,
|
||||
withLatestFrom,
|
||||
take,
|
||||
tap,
|
||||
} from 'rxjs/operators';
|
||||
import { map, switchMap, first, filter, flatMap, distinctUntilChanged, shareReplay, withLatestFrom, take, tap } from 'rxjs/operators';
|
||||
import {
|
||||
OrderItemProcessingStatusValue,
|
||||
OrderItemListItemDTO,
|
||||
@@ -67,14 +50,10 @@ export class ShelfOrderDetailsComponent {
|
||||
get processingStatusChangeData() {
|
||||
return {
|
||||
...{
|
||||
...(this.compartmentInfoFromTag
|
||||
? { compartmentInfo: this.compartmentInfoFromTag }
|
||||
: {}),
|
||||
...(this.compartmentInfoFromTag ? { compartmentInfo: this.compartmentInfoFromTag } : {}),
|
||||
},
|
||||
...{
|
||||
...(this.quantityForPartialPickup
|
||||
? { quantityForPartialPickup: this.quantityForPartialPickup }
|
||||
: {}),
|
||||
...(this.quantityForPartialPickup ? { quantityForPartialPickup: this.quantityForPartialPickup } : {}),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -89,9 +68,7 @@ export class ShelfOrderDetailsComponent {
|
||||
};
|
||||
}
|
||||
|
||||
processingStatus$ = this.activatedRoute.params.pipe(
|
||||
map((params) => params['processingStatus'])
|
||||
);
|
||||
processingStatus$ = this.activatedRoute.params.pipe(map((params) => params['processingStatus']));
|
||||
|
||||
partialPickup = false;
|
||||
activeButton: HTMLButtonElement;
|
||||
@@ -118,13 +95,9 @@ export class ShelfOrderDetailsComponent {
|
||||
|
||||
orderItems$ = this.getOrderItems$();
|
||||
|
||||
orderDetailsCard$ = this.orderDetailsService.orderDetailsCardFromOrderItems$(
|
||||
this.orderItems$
|
||||
);
|
||||
orderDetailsCard$ = this.orderDetailsService.orderDetailsCardFromOrderItems$(this.orderItems$);
|
||||
|
||||
showPickUpAndPrintOption$ = this.orderDetailsService.showPickUpAndPrintOption$(
|
||||
this.orderDetailsCard$
|
||||
);
|
||||
showPickUpAndPrintOption$ = this.orderDetailsService.showPickUpAndPrintOption$(this.orderDetailsCard$);
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
@@ -165,36 +138,22 @@ export class ShelfOrderDetailsComponent {
|
||||
const items = await this.orderItems$.pipe(first()).toPromise();
|
||||
let results: ResponseArgsOfValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO[];
|
||||
|
||||
results = await this.orderDetailsService.setProcessingStatus(
|
||||
items,
|
||||
status,
|
||||
this.processingStatusChangeData
|
||||
);
|
||||
results = await this.orderDetailsService.setProcessingStatus(items, status, this.processingStatusChangeData);
|
||||
|
||||
if (data.shouldPrint) {
|
||||
await this.abholfachEtikettService.print(
|
||||
this.abholfachEtikettService.orderSubsetIdsForWhichToPrintAbholfachEtikett(
|
||||
items
|
||||
),
|
||||
this.abholfachEtikettService.orderSubsetIdsForWhichToPrintAbholfachEtikett(items),
|
||||
this.printData
|
||||
);
|
||||
}
|
||||
|
||||
if (data.createShippingNote) {
|
||||
const receipts = await this.shippingNoteService.create(
|
||||
this.shippingNoteService.getSubsetIdsForWhichToCreateShippingNotes(
|
||||
items
|
||||
),
|
||||
this.printData
|
||||
);
|
||||
const existingReceipts: ReceiptDTO[] = items.reduce(
|
||||
(acc, curr) => [...(acc || []), ...curr.receipts],
|
||||
[]
|
||||
);
|
||||
await this.shippingNoteService.print(
|
||||
[...existingReceipts, ...(receipts || [])],
|
||||
this.shippingNoteService.getSubsetIdsForWhichToCreateShippingNotes(items),
|
||||
this.printData
|
||||
);
|
||||
const existingReceipts: ReceiptDTO[] = items.reduce((acc, curr) => [...(acc || []), ...curr.receipts], []);
|
||||
await this.shippingNoteService.print([...existingReceipts, ...(receipts || [])], this.printData);
|
||||
}
|
||||
|
||||
this.statusChangeInProgress$.next(false);
|
||||
@@ -231,9 +190,7 @@ export class ShelfOrderDetailsComponent {
|
||||
async navigateToDetails() {
|
||||
const data = await race(
|
||||
this.orderNumber$.pipe(map((orderNumber) => ({ orderNumber }))),
|
||||
this.compartmentCode$.pipe(
|
||||
map((compartmentCode) => ({ compartmentCode }))
|
||||
)
|
||||
this.compartmentCode$.pipe(map((compartmentCode) => ({ compartmentCode })))
|
||||
)
|
||||
.pipe(
|
||||
withLatestFrom(this.processingStatus$),
|
||||
@@ -265,9 +222,7 @@ export class ShelfOrderDetailsComponent {
|
||||
})[]
|
||||
) {
|
||||
const totalQuantity = items.reduce((sum, item) => sum + item.quantity, 0);
|
||||
const totalSelected = Array.from(
|
||||
this.quantityForPartialPickup.values()
|
||||
).reduce((sum, q) => sum + q, 0);
|
||||
const totalSelected = Array.from(this.quantityForPartialPickup.values()).reduce((sum, q) => sum + q, 0);
|
||||
const shouldNavigate = totalQuantity === totalSelected;
|
||||
|
||||
return shouldNavigate;
|
||||
@@ -290,8 +245,7 @@ export class ShelfOrderDetailsComponent {
|
||||
results: ResponseArgsOfValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO[]
|
||||
) {
|
||||
const firstItem = Array.isArray(items) && items[0];
|
||||
const firstResult =
|
||||
Array.isArray(results) && results[0] && results[0].result;
|
||||
const firstResult = Array.isArray(results) && results[0] && results[0].result;
|
||||
|
||||
if (!firstItem || !firstResult) {
|
||||
return;
|
||||
@@ -311,10 +265,7 @@ export class ShelfOrderDetailsComponent {
|
||||
);
|
||||
}
|
||||
|
||||
async handleActionClick(
|
||||
action: KeyValueDTOOfStringAndString,
|
||||
target: HTMLButtonElement
|
||||
) {
|
||||
async handleActionClick(action: KeyValueDTOOfStringAndString, target: HTMLButtonElement) {
|
||||
this.activeButton = target;
|
||||
this.setState(action);
|
||||
}
|
||||
@@ -323,9 +274,7 @@ export class ShelfOrderDetailsComponent {
|
||||
let navigate = true;
|
||||
let items = await this.orderItems$.pipe(first()).toPromise();
|
||||
let results: ResponseArgsOfValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO[];
|
||||
let currentReceipts: ReceiptDTO[] = this.orderDetailsService.getReceipts(
|
||||
items
|
||||
);
|
||||
let currentReceipts: ReceiptDTO[] = this.orderDetailsService.getReceipts(items);
|
||||
let remainingItemsAfterPartialRemit: (OrderItemListItemDTO & {
|
||||
receipts?: ReceiptDTO[];
|
||||
})[] = [];
|
||||
@@ -349,35 +298,24 @@ export class ShelfOrderDetailsComponent {
|
||||
return false;
|
||||
});
|
||||
|
||||
items = items.filter(({ orderItemId }) =>
|
||||
this.selectedForPartialPickup.has(orderItemId)
|
||||
);
|
||||
items = items.filter(({ orderItemId }) => this.selectedForPartialPickup.has(orderItemId));
|
||||
}
|
||||
|
||||
const actionsToTake = this.actionHandlerService.getActions(action);
|
||||
|
||||
for (const a of actionsToTake) {
|
||||
try {
|
||||
const {
|
||||
results: newResults,
|
||||
receipts: newReceipts,
|
||||
} = await this.executeAction(a, items, currentReceipts);
|
||||
const { results: newResults, receipts: newReceipts } = await this.executeAction(a, items, currentReceipts);
|
||||
|
||||
if (newResults) {
|
||||
results = newResults;
|
||||
}
|
||||
|
||||
if (Array.isArray(newReceipts)) {
|
||||
currentReceipts = Array.from(
|
||||
new Set([...(currentReceipts || []), ...(newReceipts || [])])
|
||||
);
|
||||
currentReceipts = Array.from(new Set([...(currentReceipts || []), ...(newReceipts || [])]));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`Fehler beim Aktualisieren des Postens ${
|
||||
err.message ? '(Meldung ' + err.message + ')' : ''
|
||||
})`
|
||||
);
|
||||
console.error(`Fehler beim Aktualisieren des Postens ${err.message ? '(Meldung ' + err.message + ')' : ''})`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -419,9 +357,7 @@ export class ShelfOrderDetailsComponent {
|
||||
let receipts: ReceiptDTO[];
|
||||
|
||||
if (this.actionHandlerService.shouldDetermineSupplier(command)) {
|
||||
const updatedItems = await this.orderDetailsService.setDetermineSupplier(
|
||||
items
|
||||
);
|
||||
const updatedItems = await this.orderDetailsService.setDetermineSupplier(items);
|
||||
this.navigateAfterSupplierDetermined(updatedItems);
|
||||
}
|
||||
|
||||
@@ -431,9 +367,7 @@ export class ShelfOrderDetailsComponent {
|
||||
|
||||
if (this.actionHandlerService.shouldCreateShippingNote(command)) {
|
||||
receipts = await this.shippingNoteService.create(
|
||||
this.shippingNoteService.getSubsetIdsForWhichToCreateShippingNotes(
|
||||
items
|
||||
),
|
||||
this.shippingNoteService.getSubsetIdsForWhichToCreateShippingNotes(items),
|
||||
this.printData
|
||||
);
|
||||
}
|
||||
@@ -444,9 +378,7 @@ export class ShelfOrderDetailsComponent {
|
||||
|
||||
if (this.actionHandlerService.shouldPrintAbholfachetikett(command)) {
|
||||
await this.abholfachEtikettService.print(
|
||||
this.abholfachEtikettService.orderSubsetIdsForWhichToPrintAbholfachEtikett(
|
||||
items
|
||||
),
|
||||
this.abholfachEtikettService.orderSubsetIdsForWhichToPrintAbholfachEtikett(items),
|
||||
this.printData
|
||||
);
|
||||
}
|
||||
@@ -460,38 +392,22 @@ export class ShelfOrderDetailsComponent {
|
||||
receipts?: ReceiptDTO[];
|
||||
})[]
|
||||
) {
|
||||
const targetStatus = this.actionHandlerService.getNewProcessingStatus(
|
||||
command
|
||||
);
|
||||
const results = await this.orderDetailsService.setProcessingStatus(
|
||||
items,
|
||||
targetStatus,
|
||||
this.processingStatusChangeData
|
||||
);
|
||||
const targetStatus = this.actionHandlerService.getNewProcessingStatus(command);
|
||||
const results = await this.orderDetailsService.setProcessingStatus(items, targetStatus, this.processingStatusChangeData);
|
||||
|
||||
return results.filter((result) => !!result);
|
||||
}
|
||||
|
||||
private getOrderItems$() {
|
||||
return race(
|
||||
this.orderNumber$.pipe(
|
||||
switchMap((orderNumber) =>
|
||||
this.detailsFacade.getOrderItemsByOrderNumber$(orderNumber)
|
||||
)
|
||||
),
|
||||
this.compartmentCode$.pipe(
|
||||
switchMap((compartmentCode) =>
|
||||
this.detailsFacade.getOrderItemsByCompartmentCode$(compartmentCode)
|
||||
)
|
||||
)
|
||||
this.orderNumber$.pipe(switchMap((orderNumber) => this.detailsFacade.getOrderItemsByOrderNumber$(orderNumber))),
|
||||
this.compartmentCode$.pipe(switchMap((compartmentCode) => this.detailsFacade.getOrderItemsByCompartmentCode$(compartmentCode)))
|
||||
).pipe(
|
||||
flatMap((items) =>
|
||||
this.processingStatus$.pipe(
|
||||
map((processingStatus) => {
|
||||
if (!!processingStatus) {
|
||||
return items.filter(
|
||||
(item) => item.processingStatus === +processingStatus
|
||||
);
|
||||
return items.filter((item) => item.processingStatus === +processingStatus);
|
||||
}
|
||||
return items;
|
||||
})
|
||||
@@ -506,14 +422,8 @@ export class ShelfOrderDetailsComponent {
|
||||
this.quantityForPartialPickup.delete(orderItem.orderItemId);
|
||||
}
|
||||
|
||||
private setItemForPartialPickUp(
|
||||
orderItem: OrderItemListItemDTO,
|
||||
quantity?: number
|
||||
) {
|
||||
private setItemForPartialPickUp(orderItem: OrderItemListItemDTO, quantity?: number) {
|
||||
this.selectedForPartialPickup.set(orderItem.orderItemId, orderItem);
|
||||
this.quantityForPartialPickup.set(
|
||||
orderItem.orderItemId,
|
||||
isNullOrUndefined(quantity) ? orderItem.quantity : quantity
|
||||
);
|
||||
this.quantityForPartialPickup.set(orderItem.orderItemId, isNullOrUndefined(quantity) ? orderItem.quantity : quantity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
*ngFor="let group of grouped$ | async; let i = index"
|
||||
[group]="group"
|
||||
(selectOrderItemListItem)="navigateToDetails($event)"
|
||||
(orderListItemChecked)="itemChecked($event)"
|
||||
(refreshCheckedState)="refreshCheckedState($event)"
|
||||
[disableSelection]="disableSelection"
|
||||
[setSelection]="setSelection"
|
||||
>
|
||||
</app-search-result-group>
|
||||
<app-loading
|
||||
@@ -14,3 +18,26 @@
|
||||
text="Inhalte werden geladen"
|
||||
></app-loading>
|
||||
</div>
|
||||
|
||||
<div class="actions" *ngIf="checkedItems.length > 0">
|
||||
<button
|
||||
*ngIf="pickUpAndPrintActionVisible"
|
||||
class="isa-btn isa-btn-primary isa-btn-pill isa-btn-xl"
|
||||
(click)="pickUpAndPrintClick()"
|
||||
[disabled]="statusChangeInProgress$ | async"
|
||||
>
|
||||
<span>abgeholt und Lieferschein drucken</span>
|
||||
<div class="spinner isa-btn-loader" *ngIf="statusChangeInProgress$ | async"></div>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="pickUpActionVisible"
|
||||
class="isa-btn isa-btn-primary isa-btn-pill isa-btn-xl"
|
||||
(click)="pickUpClick()"
|
||||
[disabled]="statusChangeInProgress$ | async"
|
||||
>
|
||||
<span>abgeholt</span>
|
||||
<div class="spinner isa-btn-loader" *ngIf="statusChangeInProgress$ | async"></div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<app-printer-selection></app-printer-selection>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@import 'variables';
|
||||
|
||||
cdk-virtual-scroll-viewport {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -10,3 +12,16 @@ cdk-virtual-scroll-viewport {
|
||||
.item {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
bottom: 15px;
|
||||
|
||||
button {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
import {
|
||||
Subject,
|
||||
fromEvent,
|
||||
combineLatest,
|
||||
Observable,
|
||||
BehaviorSubject,
|
||||
} from 'rxjs';
|
||||
import { Subject, fromEvent, combineLatest, Observable, BehaviorSubject } from 'rxjs';
|
||||
|
||||
import {
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
ChangeDetectionStrategy,
|
||||
} from '@angular/core';
|
||||
import { Component, OnDestroy, OnInit, ViewChild, ElementRef, ChangeDetectionStrategy, EventEmitter } from '@angular/core';
|
||||
import { SearchStateFacade } from 'apps/sales/src/app/store/customer';
|
||||
import { first, takeUntil, map, withLatestFrom } from 'rxjs/operators';
|
||||
import { Group, groupBy } from 'apps/sales/src/app/utils';
|
||||
@@ -22,6 +9,8 @@ import { ShelfNavigationService } from '../../shared/services';
|
||||
import { Select } from '@ngxs/store';
|
||||
import { ProcessSelectors } from 'apps/sales/src/app/core/store/selectors/process.selectors';
|
||||
import { ORDER_DETAILS_PREFIX } from './order-details-prefix';
|
||||
import { ShelfOrderDetailsService, ShelfShippingNoteService } from '../../services';
|
||||
import { PrinterSelectionComponent } from 'apps/sales/src/app/components/printer-selection/printer-selection.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-shelf-search-results',
|
||||
@@ -33,9 +22,13 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('scroll', { static: true })
|
||||
scrollContainer: ElementRef;
|
||||
|
||||
@Select(ProcessSelectors.getCurrentProcessId) currentProcessId$: Observable<
|
||||
number
|
||||
>;
|
||||
@Select(ProcessSelectors.getCurrentProcessId) currentProcessId$: Observable<number>;
|
||||
|
||||
@ViewChild(PrinterSelectionComponent, {
|
||||
read: PrinterSelectionComponent,
|
||||
static: true,
|
||||
})
|
||||
printerSelectionComponent: PrinterSelectionComponent;
|
||||
|
||||
destroy$ = new Subject();
|
||||
isFetching$ = new BehaviorSubject<boolean>(false);
|
||||
@@ -43,12 +36,42 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
|
||||
grouped$: Observable<Group<string, OrderItemListItemDTO>[]>;
|
||||
|
||||
fetching$: Observable<boolean>;
|
||||
statusChangeInProgress$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
scrollStorageKey = ORDER_DETAILS_PREFIX;
|
||||
|
||||
disableSelection = new EventEmitter<OrderItemListItemDTO>();
|
||||
setSelection = new EventEmitter<OrderItemListItemDTO>();
|
||||
|
||||
checkedItems = new Array<OrderItemListItemDTO>();
|
||||
|
||||
get pickUpActionVisible(): boolean {
|
||||
if (this.checkedItems.length <= 0) return false;
|
||||
|
||||
return this.checkedItems.every((item) => item.processingStatus === 128 && (!item.features || item.features['paid'] !== 'Bezahlt'));
|
||||
}
|
||||
|
||||
get pickUpAndPrintActionVisible(): boolean {
|
||||
if (this.checkedItems.length <= 0) return false;
|
||||
|
||||
return this.checkedItems.every((item) => item.processingStatus === 128 && item.features && item.features['paid'] === 'Bezahlt');
|
||||
}
|
||||
|
||||
get printData(): {
|
||||
printerComponent: PrinterSelectionComponent;
|
||||
statusObs$?: BehaviorSubject<boolean>;
|
||||
} {
|
||||
return {
|
||||
printerComponent: this.printerSelectionComponent,
|
||||
statusObs$: this.statusChangeInProgress$,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(
|
||||
private searchStateFacade: SearchStateFacade,
|
||||
private shelfNavigationService: ShelfNavigationService
|
||||
private shelfNavigationService: ShelfNavigationService,
|
||||
private orderDetailsService: ShelfOrderDetailsService,
|
||||
private shippingNoteService: ShelfShippingNoteService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -57,6 +80,15 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
|
||||
this.initFetch();
|
||||
}
|
||||
|
||||
refreshCheckedState() {
|
||||
setTimeout(() => {
|
||||
this.checkedItems.forEach((i) => {
|
||||
this.setSelection.emit(i);
|
||||
this.disableSelection.emit(i);
|
||||
});
|
||||
}, 1);
|
||||
}
|
||||
|
||||
initFetch() {
|
||||
if (this.isFromSearchPage()) {
|
||||
this.fetch();
|
||||
@@ -66,11 +98,7 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
initFacade() {
|
||||
this.grouped$ = this.searchStateFacade.result$.pipe(
|
||||
map((results) =>
|
||||
groupBy(results, (item) => (item ? item.buyerNumber : ''))
|
||||
)
|
||||
);
|
||||
this.grouped$ = this.searchStateFacade.result$.pipe(map((results) => groupBy(results, (item) => (item ? item.buyerNumber : ''))));
|
||||
this.fetching$ = this.searchStateFacade.fetching$;
|
||||
}
|
||||
|
||||
@@ -87,30 +115,17 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
|
||||
|
||||
reachedBottom() {
|
||||
const scrollContainer: HTMLElement = this.scrollContainer.nativeElement;
|
||||
return (
|
||||
scrollContainer.scrollHeight -
|
||||
(scrollContainer.scrollTop + scrollContainer.clientHeight) -
|
||||
100 <=
|
||||
0
|
||||
);
|
||||
return scrollContainer.scrollHeight - (scrollContainer.scrollTop + scrollContainer.clientHeight) - 100 <= 0;
|
||||
}
|
||||
|
||||
async fetch(force = false, isInitialFetch = false) {
|
||||
const [hits, result, fetching] = await combineLatest([
|
||||
this.searchStateFacade.hits$,
|
||||
this.searchStateFacade.result$,
|
||||
this.fetching$,
|
||||
])
|
||||
const [hits, result, fetching] = await combineLatest([this.searchStateFacade.hits$, this.searchStateFacade.result$, this.fetching$])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
if (isInitialFetch) {
|
||||
await this.searchStateFacade.fetchResult({ isNewSearch: true });
|
||||
} else if (
|
||||
(force && this.resultListNotFullyLoaded(hits, result.length || 0)) ||
|
||||
!hits ||
|
||||
(!result.length && !fetching)
|
||||
) {
|
||||
} else if ((force && this.resultListNotFullyLoaded(hits, result.length || 0)) || !hits || (!result.length && !fetching)) {
|
||||
await this.searchStateFacade.fetchResult({});
|
||||
}
|
||||
}
|
||||
@@ -119,14 +134,57 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
|
||||
this.shelfNavigationService.navigateToDetails(orderItemListItem);
|
||||
}
|
||||
|
||||
itemChecked({ item, checked }) {
|
||||
if (checked) {
|
||||
this.checkedItems.push(item);
|
||||
} else {
|
||||
let index = this.checkedItems.indexOf(item);
|
||||
if (index > -1) {
|
||||
this.checkedItems.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.checkedItems.length === 0) {
|
||||
this.disableSelection.emit(undefined);
|
||||
} else {
|
||||
this.disableSelection.emit(item);
|
||||
}
|
||||
}
|
||||
|
||||
async pickUpClick() {
|
||||
if (this.checkedItems.length <= 0) return;
|
||||
this.statusChangeInProgress$.next(true);
|
||||
|
||||
await this.orderDetailsService.setProcessingStatus(this.checkedItems, 256, {});
|
||||
await this.searchStateFacade.reloadResults();
|
||||
|
||||
this.statusChangeInProgress$.next(false);
|
||||
this.checkedItems.splice(0, this.checkedItems.length);
|
||||
}
|
||||
|
||||
async pickUpAndPrintClick() {
|
||||
if (this.checkedItems.length <= 0) return;
|
||||
this.statusChangeInProgress$.next(true);
|
||||
|
||||
await this.orderDetailsService.setProcessingStatus(this.checkedItems, 256, {});
|
||||
|
||||
let receipts = await this.shippingNoteService.create(
|
||||
this.shippingNoteService.getSubsetIdsForWhichToCreateShippingNotes(this.checkedItems),
|
||||
this.printData
|
||||
);
|
||||
|
||||
if (await this.shippingNoteService.print(receipts, this.printData)) {
|
||||
await this.searchStateFacade.reloadResults();
|
||||
}
|
||||
this.statusChangeInProgress$.next(false);
|
||||
this.checkedItems.splice(0, this.checkedItems.length);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
}
|
||||
|
||||
private resultListNotFullyLoaded(
|
||||
hits: number,
|
||||
numberOfFetchedResults: number
|
||||
): boolean {
|
||||
private resultListNotFullyLoaded(hits: number, numberOfFetchedResults: number): boolean {
|
||||
return numberOfFetchedResults < hits;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@ import { CommonModule } from '@angular/common';
|
||||
import { LoadingModule } from '@libs/ui';
|
||||
import { SearchResultGroupModule } from '../../components/search-result-group';
|
||||
import { SharedModule } from 'apps/sales/src/app/shared/shared.module';
|
||||
import { PrinterSelectionModule } from 'apps/sales/src/app/components/printer-selection/printer-selection.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, LoadingModule, SearchResultGroupModule, SharedModule],
|
||||
imports: [CommonModule, LoadingModule, SearchResultGroupModule, SharedModule, PrinterSelectionModule],
|
||||
exports: [ShelfSearchResultsComponent],
|
||||
declarations: [ShelfSearchResultsComponent],
|
||||
providers: [],
|
||||
|
||||
Reference in New Issue
Block a user