mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
[HIMA-314], [HIMA-313] working on warenausgabe search & search results (API UPDATE)
This commit is contained in:
28
.vscode/launch.json
vendored
28
.vscode/launch.json
vendored
@@ -1,15 +1,15 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "Launch Chrome",
|
||||
"url": "http://localhost:4200",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "Launch Chrome",
|
||||
"url": "https://192.168.2.112:4200",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,38 @@ import { ShelfCustomerOrders } from '../models/shelf-customer-orders.model';
|
||||
import { Gender } from 'swagger/lib/oms/models/gender';
|
||||
import { ShlefOrderItem } from '../models/shelf-order-item.model';
|
||||
|
||||
export const orderStatusMapper: { [id: number]: string } = {
|
||||
0: 'Not Set',
|
||||
1: 'Ordering',
|
||||
2: 'Placed',
|
||||
4: 'Accepted',
|
||||
8: 'Parked',
|
||||
16: 'In Process',
|
||||
32: 'Preparation For Shipping',
|
||||
64: 'Dispatched',
|
||||
128: 'Arrived',
|
||||
256: 'Fetched',
|
||||
512: 'Canceled By Buyer',
|
||||
1024: 'Canceled By Retailer',
|
||||
2048: 'Canceled By Supplier',
|
||||
4096: 'Not Available',
|
||||
8192: 'ReOrdered',
|
||||
16384: 'Returned By Buyer',
|
||||
32768: 'Available For Download',
|
||||
65536: 'Downloaded',
|
||||
131072: 'Not Fetched',
|
||||
262144: 'Back To Stock',
|
||||
524288: 'Requested',
|
||||
1048576: 'Redirected Internally',
|
||||
2097152: 'Overdue',
|
||||
4194304: 'Delivered',
|
||||
8388608: 'Determine Supplier',
|
||||
16777216: 'Supplier Temporarily OutOfStock',
|
||||
33554432: 'Reserved',
|
||||
67108864: 'Assembled',
|
||||
134217728: 'Packed',
|
||||
};
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ShelfMapping {
|
||||
fromOrderItemListItemDTOArrayToShelfCustomerOrders(orders: OrderItemListItemDTO[]): ShelfCustomerOrders[] {
|
||||
@@ -21,14 +53,10 @@ export class ShelfMapping {
|
||||
-1;
|
||||
if (orderFound) {
|
||||
customerOrders.map(customerOrder => {
|
||||
if (
|
||||
customerOrder.firstName === order.firstName &&
|
||||
customerOrder.lastName === order.lastName &&
|
||||
customerOrder.gender === order.gender
|
||||
) {
|
||||
if (customerOrder.customerId === order.buyerNumber) {
|
||||
return {
|
||||
...customerOrder,
|
||||
orders: this.getCustomerOrders(customerOrder.firstName, customerOrder.lastName, customerOrder.gender, orders),
|
||||
orders: this.getCustomerOrders(customerOrder.customerId, orders),
|
||||
};
|
||||
} else {
|
||||
return customerOrder;
|
||||
@@ -36,24 +64,32 @@ export class ShelfMapping {
|
||||
});
|
||||
} else {
|
||||
customerOrders.push(<ShelfCustomerOrders>{
|
||||
customerId: Math.round(Date.now() + Math.random()),
|
||||
customerId: order.buyerNumber,
|
||||
firstName: order.firstName,
|
||||
lastName: order.lastName,
|
||||
gender: order.gender,
|
||||
orders: this.getCustomerOrders(order.firstName, order.lastName, order.gender, orders),
|
||||
orders: this.getCustomerOrders(order.buyerNumber, orders),
|
||||
});
|
||||
}
|
||||
});
|
||||
return customerOrders;
|
||||
}
|
||||
|
||||
private getCustomerOrders(firstName: string, lastName: string, gender: Gender, orders: OrderItemListItemDTO[]): ShelfOrder[] {
|
||||
private getCustomerOrders(customerId: string, orders: OrderItemListItemDTO[]): ShelfOrder[] {
|
||||
const shelfOrders: ShelfOrder[] = [];
|
||||
|
||||
orders.forEach(or => {
|
||||
if (or.firstName === firstName && or.lastName === lastName && or.gender === gender) {
|
||||
if (or.buyerNumber === customerId) {
|
||||
shelfOrders.push(<ShelfOrder>{
|
||||
orderId: or.orderId,
|
||||
processingStatus: or.processingStatus,
|
||||
orderPId: or.orderPId,
|
||||
shopName: or.shopName,
|
||||
orderBranchId: or.orderBranchId,
|
||||
orderNumber: or.orderNumber,
|
||||
orderType: or.orderType,
|
||||
orderDate: or.orderDate,
|
||||
nextProcessingStatus: or.nextProcessingStatus,
|
||||
orderItems: this.orderItems(or.orderId, orders),
|
||||
});
|
||||
}
|
||||
@@ -70,15 +106,9 @@ export class ShelfMapping {
|
||||
orderItems.push(<ShlefOrderItem>{
|
||||
orderItemId: or.orderItemId,
|
||||
orderItemSubsetId: or.orderItemSubsetId,
|
||||
orderPId: or.orderPId,
|
||||
orderItemPId: or.orderItemPId,
|
||||
orderItemSubsetPId: or.orderItemSubsetPId,
|
||||
shopName: or.shopName,
|
||||
orderBranchId: or.orderBranchId,
|
||||
orderNumber: or.orderNumber,
|
||||
orderType: or.orderType,
|
||||
processingStatus: or.processingStatus,
|
||||
orderDate: or.orderDate,
|
||||
|
||||
product: or.product,
|
||||
quantity: or.quantity,
|
||||
overallQuantity: or.overallQuantity,
|
||||
@@ -87,7 +117,6 @@ export class ShelfMapping {
|
||||
organisation: or.organisation,
|
||||
title: or.title,
|
||||
specialComment: or.specialComment,
|
||||
nextProcessingStatus: or.nextProcessingStatus,
|
||||
ssc: or.ssc,
|
||||
sscText: or.sscText,
|
||||
supplier: or.supplier,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Gender } from 'swagger/lib/oms/models/gender';
|
||||
import { ShelfOrder } from './shelf-order.model';
|
||||
|
||||
export class ShelfCustomerOrders {
|
||||
customerId?: number;
|
||||
customerId?: string;
|
||||
lastName?: string;
|
||||
firstName?: string;
|
||||
gender?: Gender;
|
||||
orders?: ShelfCustomerOrders[];
|
||||
orders?: ShelfOrder[];
|
||||
}
|
||||
|
||||
@@ -7,15 +7,8 @@ import { KeyValueDTOOfOrderItemProcessingStatusValueAndString } from 'swagger/li
|
||||
export interface ShlefOrderItem {
|
||||
orderItemId?: number;
|
||||
orderItemSubsetId?: number;
|
||||
orderPId?: string;
|
||||
orderItemPId?: string;
|
||||
orderItemSubsetPId?: string;
|
||||
shopName?: string;
|
||||
orderBranchId?: number;
|
||||
orderNumber?: string;
|
||||
orderType?: OrderType;
|
||||
processingStatus?: OrderItemProcessingStatusValue;
|
||||
orderDate?: string;
|
||||
product?: ProductDTO;
|
||||
quantity?: number;
|
||||
overallQuantity?: number;
|
||||
@@ -24,7 +17,6 @@ export interface ShlefOrderItem {
|
||||
organisation?: string;
|
||||
title?: string;
|
||||
specialComment?: string;
|
||||
nextProcessingStatus?: Array<KeyValueDTOOfOrderItemProcessingStatusValueAndString>;
|
||||
ssc?: string;
|
||||
sscText?: string;
|
||||
supplier?: string;
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import { ShlefOrderItem } from './shelf-order-item.model';
|
||||
import { OrderItemProcessingStatusValue } from 'swagger/lib/oms/models/order-item-processing-status-value';
|
||||
// tslint:disable-next-line: max-line-length
|
||||
import { KeyValueDTOOfOrderItemProcessingStatusValueAndString } from 'swagger/lib/oms/models/key-value-dtoof-order-item-processing-status-value-and-string';
|
||||
import { OrderType } from 'swagger/lib/oms/models/order-type';
|
||||
|
||||
export interface ShelfOrder {
|
||||
orderId?: number;
|
||||
shopName?: string;
|
||||
orderPId?: string;
|
||||
orderBranchId?: number;
|
||||
orderNumber?: string;
|
||||
orderType?: OrderType;
|
||||
orderDate?: string;
|
||||
processingStatus?: OrderItemProcessingStatusValue;
|
||||
nextProcessingStatus?: Array<KeyValueDTOOfOrderItemProcessingStatusValueAndString>;
|
||||
orderItems?: ShlefOrderItem[];
|
||||
}
|
||||
|
||||
@@ -3,26 +3,33 @@ import { OrderService } from 'swagger';
|
||||
import { Suchparameter } from 'swagger/lib/oms/models/suchparameter';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ShelfCustomerOrders } from '../models/shelf-customer-orders.model';
|
||||
import { ShelfMapping } from '../mappings/shelf.mapping';
|
||||
import { OrderItemListItemDTO } from 'swagger/lib/oms/models/order-item-list-item-dto';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CollectingShelfService {
|
||||
constructor(private omsService: OrderService, private shelfMapping: ShelfMapping) {}
|
||||
constructor(private omsService: OrderService) {}
|
||||
|
||||
searchShelf(input: string, branchNumber: string): Observable<ShelfCustomerOrders[]> {
|
||||
searchShelf(
|
||||
input: string,
|
||||
branchNumber: string,
|
||||
skip: number = 0,
|
||||
take: number = 0
|
||||
): Observable<{ result: OrderItemListItemDTO[]; hits: number }> {
|
||||
const params = <Suchparameter>{
|
||||
input: input,
|
||||
branchNumber: branchNumber,
|
||||
skip: skip,
|
||||
take: take,
|
||||
};
|
||||
return this.omsService.OrderWarenausgabe(params).pipe(
|
||||
map(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.message);
|
||||
}
|
||||
return this.shelfMapping.fromOrderItemListItemDTOArrayToShelfCustomerOrders(response.result);
|
||||
return { result: response.result, hits: response.hits };
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -31,13 +38,14 @@ export class CollectingShelfService {
|
||||
const params = <Suchparameter>{
|
||||
input: input,
|
||||
branchNumber: branchNumber,
|
||||
hitsOnly: true,
|
||||
};
|
||||
return this.omsService.OrderWarenausgabe(params).pipe(
|
||||
map(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.message);
|
||||
}
|
||||
return response.result ? response.result.length : 0;
|
||||
return response.hits ? response.hits : 0;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export class CustomerSearchDataSource extends DataSource<User | undefined> {
|
||||
public loading = true;
|
||||
public results = false;
|
||||
public firstLoad = true;
|
||||
public allHits: number = 0;
|
||||
public allHits = 0;
|
||||
|
||||
constructor(
|
||||
private search: string,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="card-container">
|
||||
<div class="card-container" *ngIf="order">
|
||||
<div class="content-container">
|
||||
<span class="customer-name">Recipient name</span>
|
||||
<span class="customer-name">{{ order.firstName }} {{ order.lastName }}</span>
|
||||
<div class="order-details">
|
||||
<ng-container *ngFor="let item of customerOrders; let last = last">
|
||||
<ng-container *ngFor="let item of order.orders; let last = last">
|
||||
<app-shelf-order-item [order]="item"></app-shelf-order-item>
|
||||
<hr *ngIf="!last" class="spacer" />
|
||||
</ng-container>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, OnInit, AfterViewInit, ViewChild, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, OnInit, AfterViewInit, ViewChild, OnDestroy, ChangeDetectionStrategy, Input } from '@angular/core';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { Subject } from 'rxjs';
|
||||
import { ShelfCustomerOrders } from 'apps/sales/src/app/core/models/shelf-customer-orders.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-shelf-customer-order',
|
||||
@@ -9,33 +10,15 @@ import { Subject } from 'rxjs';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ShelfCustomerOrderComponent implements OnInit, OnDestroy {
|
||||
@Input() order: ShelfCustomerOrders;
|
||||
destroy$ = new Subject();
|
||||
|
||||
customerOrders = this.getFakeItems();
|
||||
|
||||
constructor(private store: Store) {}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
console.log(this.order);
|
||||
}
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
}
|
||||
|
||||
getFakeItems() {
|
||||
return Array(2)
|
||||
.fill(0)
|
||||
.map((_x, i) => ({
|
||||
orderId: 'id_' + i,
|
||||
status: 'arrived',
|
||||
items: Array(2)
|
||||
.fill(0)
|
||||
.map((_y, j) => ({
|
||||
title: 'title',
|
||||
coverUrl: '',
|
||||
price: 123,
|
||||
currency: 'EUR',
|
||||
quantity: j,
|
||||
payment: new Date(),
|
||||
})),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<div class="order-container">
|
||||
<div class="order-items">
|
||||
<div class="item" *ngFor="let item of order.items">
|
||||
<img [src]="item.coverUrl | bookImageUrl | async" alt="book" class="thumbnail" />
|
||||
<div class="item" *ngFor="let item of order.orderItems">
|
||||
<img [src]="item.product.ean | bookImageUrl | async" alt="book" class="thumbnail" />
|
||||
<div class="overview">
|
||||
<span class="title">{{ item.title }}</span>
|
||||
<span class="title">{{ item.product.name }}</span>
|
||||
<div class="labels">
|
||||
<span class="label">Preis</span>
|
||||
<span class="label">Menge</span>
|
||||
@@ -12,23 +12,22 @@
|
||||
<div class="data">
|
||||
<span class="text">{{ item.price | bookPrice }} {{ item.currency }}</span>
|
||||
<span class="text">{{ item.quantity }}x</span>
|
||||
<span class="text">{{ item.payment | date: 'dd.MM.yyyy' }}</span>
|
||||
<span class="text">{{ order.orderDate | date: 'dd.MM.yyyy' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-details">
|
||||
<span class="order-id">{{ order.orderId }}</span>
|
||||
<span class="order-id">{{ order.orderNumber }}</span>
|
||||
<div class="order-status">
|
||||
<div *ngIf="order.status == 'arrived'">
|
||||
<div *ngIf="order.processingStatus === 128">
|
||||
<lib-icon name="Check"></lib-icon>
|
||||
<span>eingetroffen</span>
|
||||
</div>
|
||||
<div *ngIf="order.status == 'customer_cancel'">
|
||||
<div *ngIf="order.processingStatus === 512">
|
||||
<lib-icon name="Icon_Close_gray"></lib-icon>
|
||||
<span>storniert Kunde</span>
|
||||
</div>
|
||||
<span>{{ order.processingStatus | orderStatus }}</span>
|
||||
</div>
|
||||
<app-button [primary]="true">Auswählen</app-button>
|
||||
<!-- <app-button [primary]="true">Auswählen</app-button> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.order-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
display: grid;
|
||||
grid-template-columns: auto min-content;
|
||||
}
|
||||
.order-items {
|
||||
margin-top: 30px;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, OnInit, AfterViewInit, ViewChild, OnDestroy, ChangeDetectionStrategy, Input } from '@angular/core';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { Subject } from 'rxjs';
|
||||
import { ShelfOrder } from 'apps/sales/src/app/core/models/shelf-order.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-shelf-order-item',
|
||||
@@ -10,19 +11,7 @@ import { Subject } from 'rxjs';
|
||||
})
|
||||
export class ShelfOrderItemComponent implements OnInit, OnDestroy {
|
||||
destroy$ = new Subject();
|
||||
|
||||
@Input() order: {
|
||||
orderId: string;
|
||||
status: string;
|
||||
items: Array<{
|
||||
title: string;
|
||||
coverUrl: string;
|
||||
price: number;
|
||||
currency: string;
|
||||
quantity: number;
|
||||
payment: Date;
|
||||
}>;
|
||||
};
|
||||
@Input() order: ShelfOrder;
|
||||
|
||||
constructor(private store: Store) {}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="card-container">
|
||||
<div class="icon-container">
|
||||
<div class="product-icon"></div>
|
||||
</div>
|
||||
<div class="content-container">
|
||||
<div class="author align-left">
|
||||
<span>author</span>
|
||||
</div>
|
||||
<div class="title-price">
|
||||
<div class="title align-left">
|
||||
<div>
|
||||
<span>title </span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="price align-right">
|
||||
<span>--</span>
|
||||
<span class="currency"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="type-stock">
|
||||
<div class="type align-left">
|
||||
<div class="type-text align-left">
|
||||
<span>type</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,168 @@
|
||||
@import '../../../../../assets/scss/variables';
|
||||
.card-container {
|
||||
display: grid;
|
||||
grid-template-columns: min-content auto;
|
||||
grid-gap: 7vh;
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
padding: 15px 20px;
|
||||
margin-top: 10px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.recommanded {
|
||||
background-color: $important-notification;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.product-icon {
|
||||
width: 69px;
|
||||
height: 111px;
|
||||
background-color: #e9edf9;
|
||||
color: #e9edf9;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
width: 69px;
|
||||
height: 111px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
display: grid;
|
||||
grid-template-columns: auto;
|
||||
opacity: 1;
|
||||
animation: load 1.5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes load {
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.author span {
|
||||
font-size: 16px;
|
||||
background-color: #e9edf9;
|
||||
color: #e9edf9;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.title-price {
|
||||
display: grid;
|
||||
grid-template-columns: auto min-content;
|
||||
// grid-gap: 8vh;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.title span {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
background-color: #e9edf9;
|
||||
color: #e9edf9;
|
||||
width: 500px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.price span {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
background-color: #e9edf9;
|
||||
color: #e9edf9;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.title-grid {
|
||||
display: grid;
|
||||
grid-template-columns: min-content auto;
|
||||
grid-gap: 2vh;
|
||||
}
|
||||
|
||||
.rec-icon-container {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.currency {
|
||||
margin-left: 5px;
|
||||
display: inline-block;
|
||||
background-color: #e9edf9;
|
||||
color: #e9edf9;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.type-stock {
|
||||
display: grid;
|
||||
grid-template-columns: auto max-content;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.type {
|
||||
display: grid;
|
||||
grid-template-columns: min-content auto;
|
||||
grid-gap: 2vh;
|
||||
background-color: #e9edf9;
|
||||
color: #e9edf9;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.type-text {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.available-stock {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto auto;
|
||||
grid-gap: 2vh;
|
||||
}
|
||||
|
||||
.available-icon-container {
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.stock-icon {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
.available-text span {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.stock span {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.publisher-order {
|
||||
display: grid;
|
||||
grid-template-columns: auto max-content;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.publisher-serial {
|
||||
display: grid;
|
||||
grid-template-columns: max-content min-content auto;
|
||||
grid-gap: 2vh;
|
||||
}
|
||||
|
||||
.publisher-serial span {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.order span {
|
||||
font-size: 16px;
|
||||
color: #a7b9cb;
|
||||
}
|
||||
|
||||
.type-icon-container {
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.publisher {
|
||||
max-width: 300px;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OrderLoadingComponent } from './order-loading.component';
|
||||
|
||||
describe('OrderLoadingComponent', () => {
|
||||
let component: OrderLoadingComponent;
|
||||
let fixture: ComponentFixture<OrderLoadingComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ OrderLoadingComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OrderLoadingComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-order-loading',
|
||||
templateUrl: './order-loading.component.html',
|
||||
styleUrls: ['./order-loading.component.scss'],
|
||||
})
|
||||
export class OrderLoadingComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
<div class="result-container">
|
||||
<cdk-virtual-scroll-viewport autosize class="viewport" #scroller>
|
||||
<app-shelf-customer-order *cdkVirtualFor="let order of ds"></app-shelf-customer-order>
|
||||
<div *cdkVirtualFor="let order of ds">
|
||||
<app-shelf-customer-order *ngIf="order != null; else loadingComponent" [order]="order"></app-shelf-customer-order>
|
||||
</div>
|
||||
<ng-template #loadingComponent>
|
||||
<app-order-loading></app-order-loading>
|
||||
</ng-template>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
|
||||
<app-loading
|
||||
|
||||
@@ -1,24 +1,46 @@
|
||||
import { DataSource, CollectionViewer } from '@angular/cdk/collections';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { take, takeUntil } from 'rxjs/operators';
|
||||
import { take, takeUntil, debounceTime } from 'rxjs/operators';
|
||||
import { SetShelfOrders } from 'apps/sales/src/app/core/store/actions/collecting-shelf.action';
|
||||
import { ShelfCustomerOrders } from 'apps/sales/src/app/core/models/shelf-customer-orders.model';
|
||||
import { ShelfSearch } from 'apps/sales/src/app/core/models/shelf-search.modal';
|
||||
import { CollectingShelfService } from 'apps/sales/src/app/core/services/collecting-shelf.service';
|
||||
import { OrderItemListItemDTO } from 'swagger/lib/oms/models/order-item-list-item-dto';
|
||||
|
||||
export class ShelfSearchDataSource extends DataSource<ShelfCustomerOrders | undefined> {
|
||||
private pageSize = 5;
|
||||
private fetchedPages = new Set<number>();
|
||||
private cachedData = Array.from<ShelfCustomerOrders>({ length: 0 });
|
||||
private dataStream = new BehaviorSubject<(ShelfCustomerOrders | undefined)[]>(this.cachedData);
|
||||
destroy$ = new Subject();
|
||||
public loading = true;
|
||||
public results = false;
|
||||
public allHits = 0;
|
||||
public firstLoad = true;
|
||||
|
||||
constructor(private search: ShelfSearch, private store: Store, private collectingShelf: CollectingShelfService) {
|
||||
super();
|
||||
}
|
||||
connect(collectionViewer: CollectionViewer): Observable<(ShelfCustomerOrders | undefined)[]> {
|
||||
this.fetchAll();
|
||||
collectionViewer.viewChange.pipe(takeUntil(this.destroy$)).subscribe(range => {
|
||||
const startPage = this.getPageForIndex(range.start);
|
||||
const endPage = this.getPageForIndex(range.end - 1);
|
||||
for (let i = startPage; i <= endPage; i++) {
|
||||
this.fetchPage(i);
|
||||
}
|
||||
});
|
||||
|
||||
this.dataStream
|
||||
.pipe(
|
||||
takeUntil(this.destroy$),
|
||||
debounceTime(1000)
|
||||
)
|
||||
.subscribe(i => {
|
||||
this.store.dispatch(new SetShelfOrders([...i]));
|
||||
});
|
||||
|
||||
this.fetchPage(0);
|
||||
return this.dataStream;
|
||||
}
|
||||
|
||||
@@ -26,19 +48,45 @@ export class ShelfSearchDataSource extends DataSource<ShelfCustomerOrders | unde
|
||||
this.destroy$.next();
|
||||
}
|
||||
|
||||
private fetchAll() {
|
||||
public getPageForIndex(index: number): number {
|
||||
return Math.floor(index / this.pageSize);
|
||||
}
|
||||
|
||||
private fetchPage(page: number): number {
|
||||
if (page === 0) {
|
||||
this.results = false;
|
||||
}
|
||||
if (this.fetchedPages.has(page)) {
|
||||
return;
|
||||
}
|
||||
this.fetchedPages.add(page);
|
||||
this.loading = true;
|
||||
|
||||
this.collectingShelf
|
||||
.searchShelf(this.search.input, this.search.branchnumber)
|
||||
.searchShelf(this.search.input, this.search.branchnumber, page * this.pageSize, this.pageSize)
|
||||
.pipe(
|
||||
takeUntil(this.destroy$),
|
||||
take(1)
|
||||
)
|
||||
.subscribe(shelfCustomerOrders => {
|
||||
this.cachedData = shelfCustomerOrders;
|
||||
this.dataStream.next(this.cachedData);
|
||||
this.store.dispatch(new SetShelfOrders(this.cachedData));
|
||||
.subscribe(({ result, hits }: { result: OrderItemListItemDTO[]; hits: number }) => {
|
||||
this.loading = false;
|
||||
this.results = true;
|
||||
|
||||
console.log(this.cachedData);
|
||||
|
||||
if (page === 0) {
|
||||
this.cachedData = Array.from<ShelfCustomerOrders>({ length: hits });
|
||||
this.allHits = hits;
|
||||
}
|
||||
|
||||
this.cachedData.splice(page * this.pageSize, this.pageSize, ...result);
|
||||
this.dataStream.next(this.cachedData);
|
||||
|
||||
if (page === 0) {
|
||||
// dispatch immediately on first page load
|
||||
this.firstLoad = false;
|
||||
this.store.dispatch(new SetShelfOrders(this.cachedData));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import { ShelfSearchResultsComponent } from './pages/shelf-search-results/shelf-
|
||||
import { ShelfSearchComponent } from './pages/shelf-search/shelf-search.component';
|
||||
import { ShelfRoutingModule } from './shelf-routing.module';
|
||||
import { ShelfOrderDetailsComponent } from './pages/shelf-order-details/shelf-order-details.component';
|
||||
import { OrderStatusPipe } from '../../pipes/order-status.pipe';
|
||||
import { OrderLoadingComponent } from './components/order-loading/order-loading.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -36,6 +38,8 @@ import { ShelfOrderDetailsComponent } from './pages/shelf-order-details/shelf-or
|
||||
ShelfOrderDetailsComponent,
|
||||
ShelfArticleDetailsComponent,
|
||||
ShelfPartialCollectionModalComponent,
|
||||
OrderStatusPipe,
|
||||
OrderLoadingComponent,
|
||||
],
|
||||
exports: [],
|
||||
imports: [
|
||||
|
||||
15
apps/sales/src/app/pipes/order-status.pipe.ts
Normal file
15
apps/sales/src/app/pipes/order-status.pipe.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { orderStatusMapper } from '../core/mappings/shelf.mapping';
|
||||
|
||||
@Pipe({
|
||||
name: 'orderStatus',
|
||||
})
|
||||
export class OrderStatusPipe implements PipeTransform {
|
||||
transform(input: number): string {
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return orderStatusMapper[input];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user