[HIMA-217] finished implementing wareneingang details page for more articles

This commit is contained in:
Eraldo Hasanaj
2019-10-24 17:14:37 +02:00
parent 96779c8359
commit e534b5c3e1
24 changed files with 479 additions and 59 deletions

View File

@@ -150,7 +150,8 @@ export class CollectingShelfService {
orderItemId: number,
orderItemSubsetId: number,
quantity: number,
processingStatus: number
processingStatus: number,
compartmentInfo?: string
): Observable<ValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO> {
const params = <OrderService.OrderChangeStatusParams>{
orderId,
@@ -159,6 +160,7 @@ export class CollectingShelfService {
data: <StatusValues>{
quantity,
processingStatus,
compartmentInfo,
},
};
return this.omsService.OrderChangeStatus(params).pipe(

View File

@@ -169,7 +169,7 @@ export class AppState {
if (sync && syncedData.version === 12) {
this.reloadDataFromAPI(syncedData);
if (syncedData.currentProcesssId) {
if (syncedData.currentProcesssId || syncedData.activeModule === ModuleSwitcher.Branch) {
ctx.patchState({
...state,
synced: true,
@@ -215,43 +215,65 @@ export class AppState {
this.store.dispatch(new ReloadBranchProcess(data.branchProcess));
}
if (data.processes && data.currentProcesssId) {
if (data.processes && (data.currentProcesssId || data.activeModule === ModuleSwitcher.Branch)) {
const currentProcesssId = data.activeModule === ModuleSwitcher.Customer ? data.currentProcesssId : -1;
this.store.dispatch(new ReloadProcessData(data.processes, data.recentArticles));
if (data.processes[data.currentProcesssId]) {
const currentRoute = data.processes[data.currentProcesssId].currentRoute;
if (data.processes[currentProcesssId]) {
const currentRoute =
data.activeModule === ModuleSwitcher.Customer ? data.processes[currentProcesssId].currentRoute : data.branchProcess.currentRoute;
if (currentRoute && currentRoute.length > 0) {
if (data.activeCrumbs && data.activeCrumbs[data.currentProcesssId]) {
const activeCrumbs = data.activeCrumbs[data.currentProcesssId];
if (data.activeCrumbs && data.activeCrumbs[currentProcesssId]) {
const activeCrumbs = data.activeCrumbs[currentProcesssId];
if (data.processesBreadcrumbs && data.processesBreadcrumbs[activeCrumbs]) {
const breadcrumb = data.processesBreadcrumbs[activeCrumbs].find(t => t.processId === data.currentProcesssId);
const breadcrumb = data.processesBreadcrumbs[activeCrumbs].find(t => t.processId === currentProcesssId);
if (breadcrumb && breadcrumb.breadcrumbs) {
const breadcrumbPath = breadcrumb.breadcrumbs.find(t => t && t.path === currentRoute);
if (breadcrumbPath) {
this.router.navigate([breadcrumbPath.path], { queryParams: breadcrumbPath.queryParams });
} else {
this.navigateToCourrentRoute(currentRoute, data.processes[data.currentProcesssId].currentRouteQueryParams);
this.navigateToCourrentRoute(
currentRoute,
data.activeModule === ModuleSwitcher.Customer
? data.processes[currentProcesssId].currentRouteQueryParams
: data.branchProcess.currentRouteQueryParams
);
}
} else {
this.navigateToCourrentRoute(currentRoute, data.processes[data.currentProcesssId].currentRouteQueryParams);
this.navigateToCourrentRoute(
currentRoute,
data.activeModule === ModuleSwitcher.Customer
? data.processes[currentProcesssId].currentRouteQueryParams
: data.branchProcess.currentRouteQueryParams
);
}
} else {
this.navigateToCourrentRoute(currentRoute, data.processes[data.currentProcesssId].currentRouteQueryParams);
this.navigateToCourrentRoute(
currentRoute,
data.activeModule === ModuleSwitcher.Customer
? data.processes[currentProcesssId].currentRouteQueryParams
: data.branchProcess.currentRouteQueryParams
);
}
} else {
this.navigateToCourrentRoute(currentRoute, data.processes[data.currentProcesssId].currentRouteQueryParams);
this.navigateToCourrentRoute(
currentRoute,
data.activeModule === ModuleSwitcher.Customer
? data.processes[currentProcesssId].currentRouteQueryParams
: data.branchProcess.currentRouteQueryParams
);
}
} else {
this.router.navigate(['/dashboard']);
this.router.navigate([ModuleSwitcher.Customer ? '/dashboard' : '/branch/main']);
}
} else {
this.router.navigate(['/dashboard']);
this.router.navigate([ModuleSwitcher.Customer ? '/dashboard' : '/branch/main']);
}
} else {
this.router.navigate(['/dashboard']);
this.router.navigate([ModuleSwitcher.Customer ? '/dashboard' : '/branch/main']);
}
if (data.branchProcess) {
this.store.dispatch(new ReloadProcessData(data.processes, data.recentArticles));
this.store.dispatch(new ReloadBranchProcess(data.branchProcess));
}
if (data.activeModule === ModuleSwitcher.Branch && data.branchProcess) {
@@ -260,7 +282,7 @@ export class AppState {
}
}
if (data.processesBreadcrumbs && data.activeCrumbs && data.currentProcesssId) {
if (data.processesBreadcrumbs && data.activeCrumbs && (data.currentProcesssId || data.activeModule === ModuleSwitcher.Branch)) {
this.store.dispatch(new ReloadBreadcrumbsData(data.processesBreadcrumbs, data.activeCrumbs, data.previusMenuPath));
}

View File

@@ -1,3 +1,4 @@
export const CUSTOMER_SCROLL_INDEX = 'customerScrollIndex';
export const PRODUCT_SCROLL_INDEX = 'productScrollIndex';
export const SHELF_SCROLL_INDEX = 'shelfScrollIndex';
export const GOODS_IN_SCROLL_INDEX = 'goodsInScrollIndex';

View File

@@ -59,7 +59,7 @@ export class CustomerOrderItemRowComponent implements OnInit {
const path = `/shelf/edit/${subItem.compartmentCode ? subItem.compartmentCode : this.order.id}/${this.order.id}/${
subItem.processingStatus
}/${subItem.compartmentCode ? 'c' : 'o'}/customer/${this.customerId}`;
}/${subItem.compartmentCode ? 'c' : 'o'}/customer/${this.customerId}/0`;
this.store.dispatch(
new AddBreadcrumb(
<Breadcrumb>{

View File

@@ -54,11 +54,11 @@
<div class="data" *ngIf="expand">
<span class="text">{{ _article.messageNumber || '&nbsp;' }}</span>
</div>
<div class="labels" *ngIf="expand">
<!-- <div class="labels" *ngIf="expand">
<span class="label" *ngIf="_article.remark">Anmerkung</span>
</div>
<div class="data" *ngIf="expand">
<span class="text" *ngIf="_article.remark">{{ _article.remark || '&nbsp;' }}</span>
</div>
</div> -->
</div>
</div>

View File

@@ -6,6 +6,8 @@ import { Store } from '@ngxs/store';
import { Router } from '@angular/router';
import { AddBreadcrumb } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions';
import { GOODS_IN_SCROLL_INDEX } from 'apps/sales/src/app/core/utils/app.constants';
import { AppState } from 'apps/sales/src/app/core/store/state/app.state';
@Component({
selector: 'app-goods-in-order-card',
@@ -26,6 +28,7 @@ export class GoodsInOrderCardComponent implements OnInit {
@Input() isChildItem: boolean;
@Input() first: boolean;
@Input() hasTrailingItem: boolean;
@Input() index: number;
processingStatus: string;
item: OrderItemListItemDTO;
features: { [key: string]: string };
@@ -64,7 +67,12 @@ export class GoodsInOrderCardComponent implements OnInit {
ngOnInit() {}
details() {
this.navigate(`/goodsin/details/${this.item.orderId}/${this.item.processingStatus}`, `${this.item.firstName} ${this.item.lastName}`);
const processId = this.store.selectSnapshot(AppState.getCurrentProcessId);
sessionStorage.setItem(GOODS_IN_SCROLL_INDEX, this.index + ':' + processId);
this.navigate(
`/goodsin/details/${this.item.orderId}/${this.item.orderItemId}/${this.item.processingStatus}`,
`${this.item.firstName} ${this.item.lastName}`
);
}
navigate(path: string, name: string) {

View File

@@ -14,7 +14,7 @@ export const routes: Routes = [
component: GoodsInSearchResultsComponent,
},
{
path: 'details/:id/:status',
path: 'details/:id/:itemId/:status',
component: GoodsInOrderDetailsComponent,
},
];

View File

@@ -2,7 +2,16 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { GoodsInRoutingModule } from './goods-in-routing.module';
import { GoodsInSearchComponent } from './pages/goods-in-search/goods-in-search.component';
import { SearchInputModule, LoadingModule, IconModule, ButtonModule, DropdownModule, DatePickerModule, TagModule } from '@libs/ui';
import {
SearchInputModule,
LoadingModule,
IconModule,
ButtonModule,
DropdownModule,
DatePickerModule,
TagModule,
CheckboxModule,
} from '@libs/ui';
import { GoodsInSearchResultsComponent } from './pages/goods-in-search-results/goods-in-search-results.component';
import { GoodsInOrderDetailsComponent } from './pages/goods-in-order-details/goods-in-order-details.component';
import { GoodsInOrderLoadingComponent } from './components/order-loading/goods-in-order-loading.component';
@@ -11,6 +20,7 @@ import { GoodsInOrderCardComponent } from './components/goods-in-order-card/good
import { SharedModule } from '../../shared/shared.module';
import { GoodsInOrderTagComponent } from './components/goods-in-order-tag/goods-in-order-tag.component';
import { GoodsInArticleDetailsComponent } from './components/goods-in-article-details/goods-in-article-details.component';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
@@ -34,6 +44,8 @@ import { GoodsInArticleDetailsComponent } from './components/goods-in-article-de
DropdownModule,
DatePickerModule,
TagModule,
CheckboxModule,
FormsModule,
],
})
export class GoodsInModule {}

View File

@@ -70,6 +70,36 @@
<div class="multiple" *ngIf="order && order.items && order.items.length != 1">
<ng-container *ngTemplateOutlet="readMoreButton; context: { $implicit: i }"></ng-container>
</div>
<div class="not-available-extras">
<hr class="spacer branch" />
<div class="row">
<div class="data-container">
<div class="label"><span>Anmerkung</span></div>
<div class="data" [ngClass]="{ 'pt-1': notAvailableModel.comment.disabled, 'pl-1': notAvailableModel.comment.disabled }">
<span *ngIf="notAvailableModel.comment.disabled">{{ notAvailableModel.comment.value }}</span>
<input type="text" *ngIf="!notAvailableModel.comment.disabled" [(ngModel)]="notAvailableModel.comment.value" class="input" />
</div>
</div>
<div class="action">
<span (click)="changeInputStatus('comment', false)" *ngIf="notAvailableModel.comment.disabled">{{
notAvailableModel.comment.value !== '' ? 'Ändern' : 'Hinzufügen'
}}</span>
<div class="save-action" *ngIf="!notAvailableModel.comment.disabled">
<lib-icon
*ngIf="!notAvailableModel.comment.errors && notAvailableModel.comment.value !== ''"
name="close-branch"
alt="close"
height="18px"
width="18px"
pr="10px"
pt="3px"
(click)="clear('comment')"
></lib-icon>
<span (click)="addComment(item.data)">Speichern</span>
</div>
</div>
</div>
</div>
<hr class="spacer branch" />
</ng-container>
</div>
@@ -93,16 +123,41 @@
</ng-template>
</ng-template>
<div class="tags">
<lib-tag mode="label" label="Maxi" (changed)="tagUpdated($event, 0)"></lib-tag>
<lib-tag mode="label" label="Mini" (changed)="tagUpdated($event, 1)"></lib-tag>
<lib-tag mode="label" label="Kleinkram" (changed)="tagUpdated($event, 2)"></lib-tag>
<lib-tag mode="label" label="Nonbook" (changed)="tagUpdated($event, 3)"></lib-tag>
<lib-tag mode="input" (changed)="tagUpdated($event, 4)"></lib-tag>
<div class="all-items" *ngIf="isPositiveStatus">
<ng-container *ngFor="let item of allItems">
<div class="all-items-item" [ngClass]="{ current: +item.id === +itemId }">
<img [src]="item.product.ean | bookImageUrl | async" alt="book" class="thumbnail" />
</div>
</ng-container>
</div>
<div class="tags" *ngIf="isPositiveStatus && tags">
<lib-tag mode="label" *ngIf="tags[0]" [selected]="tags[0].selected" label="Maxi" (changed)="tagUpdated($event, 0)"></lib-tag>
<lib-tag mode="label" *ngIf="tags[1]" [selected]="tags[1].selected" label="Mini" (changed)="tagUpdated($event, 1)"></lib-tag>
<lib-tag mode="label" *ngIf="tags[2]" [selected]="tags[2].selected" label="Kleinkram" (changed)="tagUpdated($event, 2)"></lib-tag>
<lib-tag mode="label" *ngIf="tags[3]" [selected]="tags[3].selected" label="Nonbook" (changed)="tagUpdated($event, 3)"></lib-tag>
<lib-tag mode="input" *ngIf="tags[4]" [selected]="tags[4].selected" (changed)="tagUpdated($event, 4)"></lib-tag>
</div>
<div class="actions">
<app-button [primary]="true" *ngIf="isPositiveStatus" (action)="setAllArrived()">Status auf 'eingetroffen' setzen</app-button>
<app-button [primary]="true" *ngIf="isNegativeStatus" (action)="setAllBackToStock()">Status auf 'ans Lager' setzen</app-button>
</div>
<div class="label" *ngIf="isPositiveStatus && allItems.length > 1">
<div class="checkbox" [ngClass]="{ 'un-checked': !labelChecked }">
<div class="filter-checkbox" (click)="labelChanged(!labelChecked)">
<div>
<lib-icon height="22px" name="Check_box_b"></lib-icon>
</div>
<div class="checked-box" *ngIf="labelChecked">
<lib-icon name="Check_f_b"></lib-icon>
</div>
</div>
<span>neues Abholfachettikett drucken</span>
</div>
<div class="info">
<span>Dies scheint eine Bestellung mit 2 Artikel zu sein. Bitte Artikel zur Seite legen und sammeln.</span>
</div>
</div>
</div>

View File

@@ -272,6 +272,144 @@
}
}
.all-items {
display: flex;
justify-content: center;
.all-items-item {
margin-right: 15px;
opacity: 0.5;
&.current {
opacity: 1;
}
}
.thumbnail {
margin-top: 18px;
max-width: 58px;
max-height: 95px;
box-shadow: 0 0 18px 0 #b8b3b7;
border-radius: 6px;
}
}
.label {
display: flex;
flex-direction: column;
.checkbox {
display: flex;
justify-content: center;
flex-direction: row;
&.un-checked {
margin-bottom: -5px;
}
.filter-checkbox {
padding-right: 10px;
cursor: pointer;
}
.checked-box {
margin-left: 3px;
margin-top: -27px;
}
span {
font-size: 16px;
font-weight: 600;
color: #000000;
}
}
.info {
display: flex;
justify-content: center;
flex-direction: row;
margin-top: 27px;
span {
width: 402px;
text-align: center;
font-size: 16px;
color: #596470;
font-weight: 600;
}
}
}
.not-available-extras {
display: flex;
flex-direction: column;
.row {
display: flex;
flex-direction: row;
padding-top: 5px;
padding-bottom: 5px;
justify-content: space-between;
.data-container {
display: flex;
flex-direction: row;
width: 100%;
.label span {
font-size: 16px;
font-weight: bold;
margin-right: 20px;
line-height: 25px;
padding-bottom: 0px;
}
.data {
width: 100%;
.input {
font-family: 'Open Sans';
border: none;
font-size: 16px;
color: black;
opacity: 1;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
caret-color: #f70400;
}
.message-data {
display: flex;
flex-direction: row;
.input {
width: 50px;
}
span {
padding-left: 10px;
}
}
}
.input:focus {
outline: none;
}
}
.action {
cursor: pointer;
span {
font-size: 18px;
color: #f70400;
font-weight: bold;
}
.save-action {
display: flex;
flex-direction: row;
}
}
}
}
@keyframes shake {
10% {
transform: translate3d(-1px, 0, 0);

View File

@@ -13,15 +13,19 @@ import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actio
import { AddBreadcrumb } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model';
import { SetEditOrder } from 'apps/sales/src/app/core/store/actions/collecting-shelf.action';
import { mapToIterable } from 'apps/sales/src/app/core/utils/app.utils';
import { CheckboxOption } from '@libs/ui';
enum Tag {
Maxi,
Mini,
SmallThings,
NonBooks,
Custom,
Maxi = 0,
Mini = 1,
SmallThings = 2,
NonBooks = 3,
Custom = 4,
}
export const tagsValues: number[] = [0, 1, 2, 3, 4];
@Component({
selector: 'app-goods-in-order-details',
templateUrl: './goods-in-order-details.component.html',
@@ -29,8 +33,10 @@ enum Tag {
})
export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
orderId: number;
itemId: number;
processingStatus: number;
order: OrderDTO;
allItems: OrderItemDTO[] = [];
expand = {};
esitmatedShippingDate: Date;
orderChannel: string;
@@ -50,8 +56,19 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
isNegativeStatus = false;
destroy$ = new Subject();
tags: {
[tag: number]: { label: string; selected: boolean };
} = {};
[tag: number]: { label?: string; selected: boolean };
} = {
0: { selected: false },
1: { selected: false },
2: { selected: false },
3: { selected: false },
4: { selected: false },
};
labelChecked = false;
notAvailableModel = {
comment: { value: '', disabled: true, errors: undefined },
message: { code: '', value: '', valid: false, disabled: true, errors: undefined },
};
constructor(private route: ActivatedRoute, private shelfService: CollectingShelfService, private router: Router, private store: Store) {}
get status() {
@@ -79,8 +96,9 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
}
paramsToOrderSwitcher = (params: Params) => {
if (params && params['id'] && params['status']) {
if (params && params['id'] && params['itemId'] && params['status']) {
this.orderId = params['id'];
this.itemId = params['itemId'];
this.processingStatus = params['status'];
return this.shelfService.getOrderByOrderId(this.orderId);
}
@@ -103,9 +121,13 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
if (this.order.clientChannel) {
this.orderChannel = orderChannelMapper[this.order.clientChannel];
}
if (this.order.items[0] && this.order.items[0].data.subsetItems[0] && this.order.items[0].data.subsetItems[0].data.specialComment) {
this.notAvailableModel.comment.value = this.order.items[0].data.subsetItems[0].data.specialComment;
}
};
filterOrder(orderDTO: OrderDTO) {
this.allItems = [];
let order = orderDTO;
if (order) {
order = {
@@ -113,30 +135,45 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
items: [
...order.items
.map(item => {
const filteredItemsByStatus = {
...item.data,
subsetItems: [
...item.data.subsetItems
.map(subitem => {
if (subitem && subitem.data && subitem.data.processingStatus === +this.processingStatus) {
return subitem;
}
})
.filter(f => f && f.data),
],
};
this.allItems.push(filteredItemsByStatus);
const subitems = {
...item,
data: {
...item.data,
subsetItems: [
...item.data.subsetItems
.map(subitem => {
if (subitem && subitem.data && subitem.data.processingStatus === +this.processingStatus) {
return subitem;
}
})
.filter(f => f && f.data),
],
},
data: filteredItemsByStatus,
};
return subitems;
})
.filter(f => f && f.data && f.data.subsetItems && f.data.subsetItems.length > 0),
.filter(f => f && f.data && f.id === +this.itemId && f.data.subsetItems && f.data.subsetItems.length > 0),
],
};
}
this.sortAllItems();
return order;
}
sortAllItems() {
if (this.allItems && this.allItems.length > 1) {
const indexOfMovingItem = this.allItems.findIndex(item => +item.id === +this.itemId);
if (indexOfMovingItem === 0) {
return;
}
const itemToMove = this.allItems[0];
this.allItems[0] = this.allItems[indexOfMovingItem];
this.allItems[indexOfMovingItem] = itemToMove;
}
}
expanded(bookIndex) {
return !!this.expand[bookIndex];
}
@@ -206,6 +243,13 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
newStatus: number
) {
let itemsProcessed = 0;
let tag: string;
tagsValues.forEach(key => {
const currTag = this.tags[+key];
if (currTag.selected) {
tag = currTag.label;
}
});
patchingSubsetItemSequentially$
.pipe(
takeUntil(this.destroy$),
@@ -215,7 +259,8 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
data.orderItemId,
data.orderItemSubsetId,
data.quantity,
data.processingStatus
data.processingStatus,
tag
);
}),
catchError(error => {
@@ -298,7 +343,8 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
if (this.order.buyer) {
breadcrumbName = this.order.buyer.firstName + ' ' + this.order.buyer.lastName + ' Barbeiten';
}
const path = `/shelf/edit/${this.order.id}/${this.order.id}/${this.processingStatus}/o/goodsin/${this.order.buyer.source}`;
// tslint:disable-next-line: max-line-length
const path = `/shelf/edit/${this.order.id}/${this.order.id}/${this.processingStatus}/o/goodsin/${this.order.buyer.source}/${this.order.items[0].id}`;
this.store.dispatch(
new AddBreadcrumb(
<Breadcrumb>{
@@ -314,6 +360,45 @@ export class GoodsInOrderDetailsComponent implements OnInit, OnDestroy {
}
tagUpdated(value: { label: string; selected: boolean }, tag: Tag) {
tagsValues.forEach(key => {
if (this.tags[key]) {
this.tags[key].selected = false;
}
});
this.tags[tag] = value;
}
labelChanged(selected: boolean) {
this.labelChecked = selected;
}
changeInputStatus(input: string, status: boolean) {
this.notAvailableModel[input].disabled = status;
}
clear(input: string) {
this.notAvailableModel[input].value = '';
}
addComment(orderItem: OrderItemDTO) {
orderItem.subsetItems.forEach(subsetItem => {
this.shelfService
.patchOrderItemSubset(this.orderId, orderItem.id, subsetItem.id, {
...subsetItem,
specialComment: this.notAvailableModel.comment.value,
})
.pipe(
takeUntil(this.destroy$),
catchError(error => {
console.log('Error Cought', error);
return of(undefined);
})
)
.subscribe((response: OrderItemSubsetDTO) => {
if (response) {
this.notAvailableModel.comment.disabled = true;
}
});
});
}
}

View File

@@ -7,6 +7,7 @@
[orderItem]="order"
[first]="first"
[isChildItem]="isChildItem(order, index)"
[index]="index"
[hasTrailingItem]="hasTrailingItem(order, index)"
></app-goods-in-order-card>
</ng-container>

View File

@@ -1,4 +1,4 @@
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core';
import { ViewRef_ } from '@angular/core/src/view';
import { GoodsInSearch } from 'apps/sales/src/app/core/models/GoodsInSearch.model';
import { GoodsInSearchResultsDataSource } from './goods-in-search-results.datasource';
@@ -11,8 +11,10 @@ import { ModuleSwitcher } from 'apps/sales/src/app/core/models/app-switcher.enum
import { GoodsInSelectors } from 'apps/sales/src/app/core/store/selectors/goods-in.selectors';
import { isNullOrUndefined } from 'util';
import { OrderItemListItemDTO } from 'swagger/lib/oms/models/order-item-list-item-dto';
import { ActivatedRoute } from '@angular/router';
import { SetGoodsInUseCache } from 'apps/sales/src/app/core/store/actions/goods-in.actions';
import { GOODS_IN_SCROLL_INDEX } from 'apps/sales/src/app/core/utils/app.constants';
import { ListRange } from '@angular/cdk/collections';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
@Component({
selector: 'app-goods-in-search-results',
@@ -21,11 +23,14 @@ import { SetGoodsInUseCache } from 'apps/sales/src/app/core/store/actions/goods-
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GoodsInSearchResultsComponent implements OnInit, OnDestroy {
@ViewChild('scroller') scroller: CdkVirtualScrollViewport;
goodsInSearch: GoodsInSearch;
ds: GoodsInSearchResultsDataSource;
destroy$ = new Subject();
loading = true;
useCache = false;
id: number;
doScroll = true;
constructor(private cdr: ChangeDetectorRef, private goodsInService: GoodsInService, private store: Store) {}
ngOnInit() {
@@ -50,9 +55,21 @@ export class GoodsInSearchResultsComponent implements OnInit, OnDestroy {
.subscribe(search => {
this.useCache = this.store.selectSnapshot(GoodsInSelectors.getGoodsInCacheState);
this.goodsInSearch = search;
this.id = this.store.selectSnapshot(AppState.getCurrentProcessId);
this.loadDataSource(search);
this.useCache.ifTrue(() => this.store.dispatch(new SetGoodsInUseCache(false)));
});
this.scroller.renderedRangeStream
.pipe(
takeUntil(this.destroy$),
filter(data => !isNullOrUndefined(data))
)
.subscribe(range => {
if (this.doScroll) {
this.scrollToIndexCached(range);
}
});
}
loadDataSource(goodsInSearch: GoodsInSearch) {
@@ -83,6 +100,28 @@ export class GoodsInSearchResultsComponent implements OnInit, OnDestroy {
return curr.firstName === next.firstName && curr.lastName === next.lastName;
}
scrollToIndexCached(range: ListRange) {
setTimeout(() => {
const index = this.getIndex();
this.scroller.scrollToIndex(index);
if (range.start <= index && range.end >= index) {
this.doScroll = false;
sessionStorage.removeItem(GOODS_IN_SCROLL_INDEX);
}
}, 1);
}
getIndex() {
const index = sessionStorage.getItem(GOODS_IN_SCROLL_INDEX);
if (!isNullOrUndefined(index)) {
const ids = index.split(':');
if (this.id === +ids[1]) {
return +ids[0];
}
}
return 0;
}
detectChanges() {
setTimeout(() => {
if (this.cdr !== null && this.cdr !== undefined && !(this.cdr as ViewRef_).destroyed) {

View File

@@ -16,6 +16,7 @@ import {
import { AddBreadcrumb } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions';
import { Router } from '@angular/router';
import { GOODS_IN_SCROLL_INDEX } from 'apps/sales/src/app/core/utils/app.constants';
@Component({
selector: 'app-goods-in-search',
@@ -51,9 +52,10 @@ export class GoodsInSearchComponent implements OnInit {
this.store.dispatch(new SetGoodsInCachedOrders({ results: data.results, hits: data.hits }));
this.store.dispatch(new SetGoodsInSearch({ input: input, branchnumber: branchNo }));
this.store.dispatch(new SetGoodsInUseCache(true));
sessionStorage.removeItem(GOODS_IN_SCROLL_INDEX);
if (data.results.length === 1) {
const item = data.results[0];
this.navigate(`details/${item.orderId}`, item.product.name);
this.navigate(`/goodsin/details/${item.orderId}/${item.orderItemId}/${item.processingStatus}`, item.product.name);
} else {
this.navigate('/goodsin/results', `${input} (${data.hits} Ergebnisse)`);
}

View File

@@ -28,6 +28,7 @@ export class ShelfEditOrderComponent implements OnInit, OnDestroy {
orderId: number;
origin: string;
customerId: number;
itemId: number;
multi = false;
constructor(private store: Store, private router: Router, private route: ActivatedRoute, private shelfService: CollectingShelfService) {}
@@ -54,6 +55,7 @@ export class ShelfEditOrderComponent implements OnInit, OnDestroy {
this.orderId = params['orderId'];
this.origin = params['origin'];
this.customerId = params['customerId'];
this.itemId = params['itemId'];
}
};
@@ -83,7 +85,7 @@ export class ShelfEditOrderComponent implements OnInit, OnDestroy {
this.router.navigate([path]);
}
if (this.origin === 'goodsin') {
const path = `/goodsin/details/${this.orderId}/${this.status}`;
const path = `/goodsin/details/${this.orderId}/${this.itemId}/${this.status}`;
this.store.dispatch(new SetBranchProcessCurrentPath(path, true));
this.router.navigate([path]);
}

View File

@@ -663,7 +663,7 @@ export class ShelfOrderDetailsComponent implements OnInit, OnDestroy {
}
const path = `/shelf/edit/${this.order.compartmentCode ? this.order.compartmentCode : this.order.orderId}/${this.order.orderId}/${
this.status
}/${this.order.compartmentCode ? 'c' : 'o'}/shelf/0`;
}/${this.order.compartmentCode ? 'c' : 'o'}/shelf/0/0`;
this.store.dispatch(
new AddBreadcrumb(
<Breadcrumb>{

View File

@@ -19,7 +19,7 @@ export const routes: Routes = [
component: ShelfOrderDetailsComponent,
},
{
path: 'edit/:id/:orderId/:status/:type/:origin/:customerId',
path: 'edit/:id/:orderId/:status/:type/:origin/:customerId/:itemId',
component: ShelfEditOrderComponent,
},
];

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com -->
<title>Check_box Copy 20</title>
<desc>Created with Sketch.</desc>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="S6_HIMA-590_Hugendubel_ISA_Filter_Bestand_1_2" transform="translate(-362.000000, -357.000000)" stroke="#596470" stroke-width="2">
<rect id="Check_box-Copy-20" x="363" y="358" width="20" height="20" rx="2"></rect>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 678 B

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="12px" viewBox="0 0 15 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com -->
<title>Check Copy 14</title>
<desc>Created with Sketch.</desc>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="S6_HIMA-590_Hugendubel_ISA_Filter_Bestand_1_2" transform="translate(-366.000000, -548.000000)" fill="#596470" stroke="#596470" stroke-width="0.4">
<path d="M379.077212,549.007856 C378.896281,549.034607 378.729451,549.123199 378.603736,549.259288 C375.894759,552.04321 373.867212,554.340502 371.281763,557.027669 L368.339447,554.478668 C368.117572,554.285351 367.811826,554.228455 367.537859,554.329503 C367.263892,554.430551 367.063533,554.674114 367.01257,554.968063 C366.961607,555.262012 367.067821,555.561466 367.291035,555.753155 L370.808287,558.80502 C371.13199,559.083792 371.610142,559.061162 371.907428,558.753 C374.810149,555.770051 376.884432,553.378304 379.753607,550.429748 C380.005415,550.179109 380.071653,549.790923 379.917799,549.467498 C379.763946,549.144072 379.424839,548.958646 379.077212,549.007856 L379.077212,549.007856 Z" id="Check-Copy-14"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M19.42 1.42C20.75 1.42 21.42 2.09 21.42 3.42C21.42 13.02 21.42 18.35 21.42 19.42C21.42 20.75 20.75 21.42 19.42 21.42C9.82 21.42 4.49 21.42 3.42 21.42C2.09 21.42 1.42 20.75 1.42 19.42C1.42 9.82 1.42 4.49 1.42 3.42C1.42 2.09 2.09 1.42 3.42 1.42C13.02 1.42 18.35 1.42 19.42 1.42Z" id="f8osrtuwt"></path><path d="M16.52 6.68C13.81 9.46 11.79 11.76 9.2 14.45C8.91 14.19 6.55 12.15 6.26 11.9C6.04 11.7 5.73 11.65 5.46 11.75C5.18 11.85 4.98 12.09 4.93 12.39C4.88 12.68 4.99 12.98 5.21 13.17C5.56 13.48 8.38 15.92 8.73 16.22C9.05 16.5 9.53 16.48 9.83 16.17C12.73 13.19 14.8 10.8 17.67 7.85C17.92 7.6 17.99 7.21 17.84 6.89C17.68 6.56 17.34 6.38 17 6.43C17 6.43 17 6.43 17 6.43C16.76 6.5 16.61 6.59 16.52 6.68Z" id="eE2nfCQJu"></path></defs><g><g><g><use xlink:href="#f8osrtuwt" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#f8osrtuwt" opacity="1" fill-opacity="0" stroke="#596470" stroke-width="2" stroke-opacity="1"></use></g></g><g><use xlink:href="#eE2nfCQJu" opacity="1" fill="#596470" fill-opacity="1"></use><g><use xlink:href="#eE2nfCQJu" opacity="1" fill-opacity="0" stroke="#596470" stroke-width="0.4" stroke-opacity="1.00"></use></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -27,7 +27,14 @@
<div class="grid-item day align-center" [ngClass]="{ sunday: last }" *ngFor="let day of week; let last = last">
<div
(click)="selectDay(day)"
[ngClass]="{ 'selected-day': day === currentDay && month === selectedMonth && year === selectedYear }"
[ngClass]="{
'selected-day': day === currentDay && month === selectedMonth && year === selectedYear,
'base-date':
day === baseDay &&
month === baseMonth &&
year === baseYear &&
!(day === currentDay && month === selectedMonth && year === selectedYear)
}"
*ngIf="day !== 0"
>
{{ day }}

View File

@@ -34,6 +34,20 @@
color: #89949e;
}
.base-date {
font-weight: bold;
color: #000000;
height: 30px;
width: 38px;
background-color: #ffffff;
border: 2px solid #d5d9dd;
position: absolute;
margin-top: -10px;
padding-top: 8px;
margin-left: 8px;
border-radius: 20px;
}
.selected-day {
font-weight: bold;
color: #000000;

View File

@@ -15,6 +15,9 @@ export class DatePickerComponent implements OnInit {
currentDay: number;
selectedMonth: number;
selectedYear: number;
baseDay: number;
baseMonth: number;
baseYear: number;
month: number;
months = {
0: 'Januar',
@@ -55,6 +58,9 @@ export class DatePickerComponent implements OnInit {
this.selectedMonth = this.month;
this.year = this.baseDate.getFullYear();
this.selectedYear = this.year;
this.baseDay = this.currentDay;
this.baseMonth = this.selectedMonth;
this.baseYear = this.selectedYear;
this.monthMatrix = this.fillMonthMatrix(this.month, this.year);
}

View File

@@ -12,6 +12,7 @@
[(ngModel)]="label"
[ngClass]="{ selected: selected === true }"
type="text"
maxlength="15"
(input)="inputUpdated($event)"
placeholder="..."
/>