Revert "HIMA-1031 continue uncompleted shipping docs (pull request #1185)"

This reverts pull request #1185.

> Ticket: [https://umwerk.atlassian.net/browse/HIMA-1031](https://umwerk.atlassian.net/browse/HIMA-1031)
> 
> * Add new remission overview page
> * Add new remission details page
> * Add continue remission from details page
> * Add delete remission from details page
> 
> \+ Updating Lib dependency to 0.3.7
> 
> ---
> 
> History:
> 
> * Add Remission State existingRemissions plus Actions
> * \[Remission List Create\] - Fetch Uncompleted Remissions
> * Show open shipping documents on create page
> * Add Icon for Open Remission Indicator
> * Add Remission Overview Page incl. Navigation
> * \[Remission Overview\] - Add Header Styling
> * \[Remission Overview Page\] - Fetch all remissions \(last 7 days\)
> * \[Remision Overview Page\] - Add Header incl. Styling
> * \[Remission Overview Page\] - Add Content \+ Styling
> * \[Remission Details Page\] - Add Navigation from Overview Page
> * \[Remission Details Page - Product Details\] - Add Product Details Styling
> * \[Remission Details Page - Product Details\] - Reduce Padding on Products
> * \[Remission Details Page\] - Add Printing \(incl. Error Handling\)
> * Update ISA Remission Dep \+ Delete Shipping Document Error Handling
> * \[Remission Details\] - Add Overview Page Continue Button incl. Navigation
> * Add Scanning if continued shipping document has been scanned
> * Call queryReturns for retrieving remissions on create page
> * Product List Tile Styling \(Border radius only on last item bottom l-r\)
> * Add ShippingDocumentNumber Formatter for deleted shipping documents
> * \[Styling Feedback JSchell\] \+ shipDocId Parser 6-digits in template
> * Add Wording for use case: Continue with Scan
> * Spinner Loading Print & RightAlign Remission Details, Wording Scan Contd
> * Update ISA Remi Dependency to 0.3.7
> * Add Formatted ShippingDocumentNumber in Breadcrumb
> 
> ‌
This commit is contained in:
Eraldo Hasanaj
2020-03-06 16:09:27 +00:00
parent 942aff7493
commit 25e75296db
52 changed files with 175 additions and 1980 deletions

View File

@@ -27,10 +27,7 @@ import { AppState } from './core/store/state/app.state';
import { CartEntryState } from './core/store/state/cart-entry.state';
import { BranchState } from './core/store/state/branches.state';
import { SsoModule } from 'sso';
import {
SsoAuthorizationInterceptor,
HttpErrorHandlerInterceptor
} from './core/interceptors';
import { SsoAuthorizationInterceptor, HttpErrorHandlerInterceptor } from './core/interceptors';
import { DatePipe } from '@angular/common';
import { CountryState } from './core/store/state/countries.state';
import { HimaSalesErrorHandler } from './core/error/hima-sales.error-handler';
@@ -48,12 +45,6 @@ import { AppSwaggerModule } from './app-swagger.module';
import { AppConfiguration } from './app-configuration';
import { FormsState } from './core/store/state/forms.state';
import { LOCALE_ID } from '@angular/core';
import localeDe from '@angular/common/locales/de';
import localeDeExtra from '@angular/common/locales/extra/de';
import { registerLocaleData } from '@angular/common';
registerLocaleData(localeDe, localeDeExtra);
const states = [
AppState,
ProcessState,
@@ -76,9 +67,7 @@ const states = [
FormsState
];
export function remissionModuleOptionsFactory(
config: AppConfiguration
): RemissionModuleOptions {
export function remissionModuleOptionsFactory(config: AppConfiguration): RemissionModuleOptions {
return config.remissionModuleOptions;
}
@@ -130,10 +119,6 @@ export function remissionModuleOptionsFactory(
{
provide: ErrorHandler,
useClass: HimaSalesErrorHandler
},
{
provide: LOCALE_ID,
useValue: 'de'
}
],
bootstrap: [AppComponent]

View File

@@ -1,6 +0,0 @@
import { RemissionProcess } from '@isa/remission';
export interface RemissionExistingOverview {
allRemissions: RemissionProcess[];
openRemissions: RemissionProcess[];
}

View File

@@ -1,9 +1,4 @@
import {
RemissionProcess,
RemissionProduct,
FilterOption,
ShippingDocument
} from '@isa/remission';
import { RemissionProcess, RemissionProduct, FilterOption, ShippingDocument } from '@isa/remission';
import { RemissionResourceType } from '../../modules/remission/models/remission-resource-type.model';
import { RemissionFinishingProcessStatus } from '../../modules/remission/models/remission-finishing-process-status.enum';

View File

@@ -31,8 +31,6 @@ export const SET_REMISSION_FINISHED_PROCESS_STATUS =
export const SET_REMISSION_SCANNED_CONTAINER_ID =
'[REMISSION] Set remission scanned container id';
export const DELETE_SHIPPING_DOCUMENT = '[REMISSION] Delete shipping document';
export const SET_ALL_OPEN_REMISSIONS = '[REMISSION] Set all open remissions';
export const SET_ALL_REMISSIONS = '[REMISSION] Set all remissions';
export class SetRemissionCreated {
static readonly type = SET_REMISSION_CREATED;
@@ -143,15 +141,3 @@ export class DeleteRemissionShippingDocument {
constructor(public remissionProcessId: number) {}
}
export class SetAllOpenExistingRemissions {
static readonly type = SET_ALL_OPEN_REMISSIONS;
constructor(public remissionProcesses: RemissionProcess[]) {}
}
export class SetAllExistingRemissions {
static readonly type = SET_ALL_REMISSIONS;
constructor(public remissionProcesses: RemissionProcess[]) {}
}

View File

@@ -5,6 +5,7 @@ import { isNullOrUndefined } from 'util';
import { RemissionResourceType } from '../../../modules/remission/models/remission-resource-type.model';
import { RemissionFinishingProcessStatus } from '../../../modules/remission/models/remission-finishing-process-status.enum';
import { RemissionSourceType } from '@isa/remission';
import { Observable } from 'rxjs';
export class RemissionSelectors {
@Selector([RemissionState])
@@ -44,9 +45,7 @@ export class RemissionSelectors {
}
@Selector([RemissionState])
static getRemissionFinishingProcessStatus(
remissionState: RemissionStateModel
) {
static getRemissionFinishingProcessStatus(remissionState: RemissionStateModel) {
const remission = remissionState.remission;
return remission.remissionFinishingProcessStatus;
}
@@ -83,27 +82,20 @@ export class RemissionSelectors {
remission.remissionProcessStarted &&
!remission.remissionProcessCompleted &&
!remission.blockReminder &&
remission.remissionFinishingProcessStatus !==
RemissionFinishingProcessStatus.containerScanned
remission.remissionFinishingProcessStatus !== RemissionFinishingProcessStatus.containerScanned
);
}
@Selector([RemissionState])
static getRemissionShippingDocumentstatus(
remissionState: RemissionStateModel
) {
static getRemissionShippingDocumentstatus(remissionState: RemissionStateModel) {
const remission = remissionState.remission;
return remission.shippingDocumentCreated;
}
@Selector([RemissionState])
static getRemissionShippingDocumentProductCount(
remissionState: RemissionStateModel
) {
static getRemissionShippingDocumentProductCount(remissionState: RemissionStateModel) {
const remission = remissionState.remission;
return remission.shippingDocument
? remission.shippingDocument.products.length
: 0;
return remission.shippingDocument ? remission.shippingDocument.products.length : 0;
}
@Selector([RemissionState])
@@ -113,16 +105,13 @@ export class RemissionSelectors {
if (remission && remission.remissionProcess) {
const source = remission.source;
const target = remission.target;
return remission.remissionProcess[source][target][filterId]
.filterGroups;
return remission.remissionProcess[source][target][filterId].filterGroups;
}
};
}
@Selector([RemissionState])
static getRemissionSelectedOptions(
remissionState: RemissionStateModel
): string[] {
static getRemissionSelectedOptions(remissionState: RemissionStateModel): string[] {
const remission = remissionState.remission;
if (remission && remission.remissionProcess) {
const filter = remission.remissionProcess.filter;
@@ -192,16 +181,4 @@ export class RemissionSelectors {
const remission = remissionState.remission;
return remission.searchedProduct;
}
@Selector([RemissionState])
static getAllRemissions(remissionState: RemissionStateModel) {
const existingRemissions = remissionState.existingRemissions;
return existingRemissions.allRemissions;
}
@Selector([RemissionState])
static getAllUncompletedRemissions(remissionState: RemissionStateModel) {
const existingRemissions = remissionState.existingRemissions;
return existingRemissions.openRemissions;
}
}

View File

@@ -1,6 +1,5 @@
import { Remission } from '../../models/remission.model';
import { RemissionExistingOverview } from '../../models/remission-existing-overview.model';
import { State, Action, StateContext, Store, Actions } from '@ngxs/store';
import { State, Action, StateContext, Store } from '@ngxs/store';
import * as actions from '../actions/remission.actions';
import { UserStateSyncData } from '../../models/user-state-sync.model';
import { AppUserDataSync } from '../actions/app.actions';
@@ -15,7 +14,6 @@ import get from 'lodash/get';
export class RemissionStateModel {
remission: Remission;
existingRemissions: RemissionExistingOverview;
}
const initialFilterIdsValue = {
@@ -42,8 +40,7 @@ const intitialFiltersValue = {
@State<RemissionStateModel>({
name: 'remission',
defaults: {
remission: null,
existingRemissions: null
remission: null
}
})
export class RemissionState {
@@ -449,36 +446,6 @@ export class RemissionState {
});
}
@Action(actions.SetAllOpenExistingRemissions)
setAllOpenExistingRemissions(
ctx: StateContext<RemissionStateModel>,
{ remissionProcesses }: actions.SetAllOpenExistingRemissions
) {
const state = ctx.getState();
const currentExistingRemissions = state.existingRemissions;
const existingRemissions: RemissionExistingOverview = {
...currentExistingRemissions,
openRemissions: remissionProcesses
};
ctx.patchState({ existingRemissions });
}
@Action(actions.SetAllExistingRemissions)
setAllExistingRemissions(
ctx: StateContext<RemissionStateModel>,
{ remissionProcesses }: actions.SetAllExistingRemissions
) {
const state = ctx.getState();
const currentExistingRemissions = state.existingRemissions;
const existingRemissions: RemissionExistingOverview = {
...currentExistingRemissions,
allRemissions: remissionProcesses
};
ctx.patchState({ existingRemissions });
}
private syncApiState(remission: Remission) {
const userSyncData: UserStateSyncData = {
remission

View File

@@ -1,13 +1,7 @@
<app-modal id="remission-add-product-to-remission-modal" branch="true">
<div class="modal-wrapper">
<div class="header">
<lib-icon
(click)="closeDialog()"
height="21px"
class="close-icon"
name="close-branch"
alt="close"
></lib-icon>
<lib-icon (click)="closeDialog()" height="21px" class="close-icon" name="close-branch" alt="close"></lib-icon>
</div>
<div class="title">
<span>Artikel zur Remi-Liste hinzufügen</span>
@@ -15,18 +9,12 @@
<hr class="spacer branch" />
<div class="product-wrapper">
<div class="icon">
<img
[src]="product.imageId | bookImageUrl | async"
alt="book"
class="thumbnail"
/>
<img [src]="product.imageId | bookImageUrl | async" alt="book" class="thumbnail" />
</div>
<div class="details">
<div class="authors-title-group-quantity">
<div class="authors-title">
<ng-container
*ngIf="product.contributors; else productNameWithoutContributors"
>
<ng-container *ngIf="product.contributors; else productNameWithoutContributors">
<span>{{ product.contributors + ' - ' + product.name }}</span>
</ng-container>
<ng-template #productNameWithoutContributors>
@@ -73,26 +61,14 @@
<div class="datas">
<div class="data format">
<div class="format-icon">
<lib-icon
name="Icon_{{ product.format }}"
mt="4px"
height="17px"
></lib-icon>
<lib-icon name="Icon_{{ product.format }}" mt="4px" height="17px"></lib-icon>
</div>
<div class="format-description">{{ product.formatDetail }}</div>
</div>
<div class="data">
<div
class="feature-tooltip"
[style.marginLeft.px]="tooltipMl"
*ngIf="toolTipOpened"
>
<div class="feature-tooltip" [style.marginLeft.px]="tooltipMl" *ngIf="toolTipOpened">
{{ selectedFeatureDescription }}
<lib-icon
(click)="closeTooltip()"
height="11px"
name="Delete-white"
></lib-icon>
<lib-icon (click)="closeTooltip()" height="11px" name="Delete-white"></lib-icon>
</div>
<div class="feature-tooltip-arrow-down" [style.marginLeft.px]="tooltipArrowMl" *ngIf="toolTipOpened"></div>
<div class="features item" *ngIf="isArray(product.features); else emptyFeatures">
@@ -130,9 +106,7 @@
</div>
<hr class="spacer branch" />
<div class="actions">
<app-button primary="true" (action)="addProdcutToList()"
>Hinzufügen</app-button
>
<app-button primary="true" (action)="addProdcutToList()">Hinzufügen</app-button>
</div>
</div>
</app-modal>

View File

@@ -1,24 +0,0 @@
<ng-container [ngSwitch]="continueWithScan">
<ng-container *ngSwitchCase="true">
<div class="call-to-action-container" *ngIf="!shippingDocument.isCompleted">
<div class="text">
Um den Warenbegleitschein zu öffnen, scannen Sie die Pachtstück-ID.
</div>
<app-button primary="true" (action)="action.emit()">
Pachtstück-ID scannen
</app-button>
</div>
</ng-container>
<ng-container *ngSwitchDefault>
<div class="call-to-action-container" *ngIf="!shippingDocument.isCompleted">
<div class="text" *ngIf="!!shippingDocument.products?.length">
Bitte prüfen Sie, ob die Artikel in der Wanne mit den Titeln auf dem
Warenbegleitschein identisch sind.
</div>
<app-button primary="true" (action)="action.emit()">
Warenbegleitschein öffnen
</app-button>
</div>
</ng-container>
</ng-container>

View File

@@ -1,17 +0,0 @@
.call-to-action-container {
margin: 24px auto 12px;
display: flex;
width: 50%;
flex-direction: column;
justify-content: center;
align-items: center;
.text {
text-align: center;
margin-bottom: 16px;
font-size: 16px;
font-weight: 600;
color: #557596;
padding: 0 10%;
}
}

View File

@@ -1,26 +0,0 @@
import {
Component,
OnInit,
ChangeDetectionStrategy,
Input,
Output,
EventEmitter
} from '@angular/core';
import { ShippingDocument } from '@isa/remission';
@Component({
selector: 'app-remission-details-primary-cta',
templateUrl: 'remission-details-primary-cta.component.html',
styleUrls: ['./remission-details-primary-cta.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RemissionDetailsPrimaryCtaComponent implements OnInit {
@Input() shippingDocument: ShippingDocument;
@Input() continueWithScan = false;
@Output() action = new EventEmitter();
constructor() {}
ngOnInit() {}
}

View File

@@ -1,39 +0,0 @@
<div class="container">
<div
class="product-wrapper"
[ngClass]="{ 'remove-padding-left-right': removePaddingLeftRight }"
>
<div class="icon">
<img
[src]="product.imageId | bookImageUrl | async"
alt="book"
class="thumbnail"
/>
</div>
<div class="product-details">
<div class="headline">
<div class="title truncate">
{{ product?.contributors }} - {{ product?.name }}
</div>
<div class="department truncate">
{{ product?.productGroup }}: {{ product?.productGroupName }}
</div>
</div>
<div class="content-row">
<div class="content-field">
<span class="descriptor">Remi-Menge</span>
<span class="value">{{ product?.remissionQuantity }}x</span>
</div>
</div>
<div class="content-row">
<div class="content-field">
<span class="descriptor">Platz</span>
<span class="value">{{ product?.placementType }}</span>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,92 +0,0 @@
.container {
min-height: 80px;
margin-bottom: 4px;
border-radius: 5px;
background-color: #ffffff;
font-family: 'Open Sans';
.product-wrapper {
padding-top: 16px;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 16px;
&.remove-padding-left-right {
padding-left: 0;
padding-right: 0;
}
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 25px;
.icon {
.thumbnail {
max-width: 59px;
max-height: 111px;
box-shadow: 0 0 18px 0 #b8b3b7;
border-radius: 6px;
height: 80px;
}
}
.product-details {
overflow: hidden;
.headline {
display: grid;
grid-template-columns: 3fr 150px;
grid-gap: 10px;
align-items: center;
padding-bottom: 8px;
.truncate {
overflow: hidden;
width: fit-content;
margin-right: 2rem;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
}
.title {
font-size: 16px;
font-weight: bold;
color: #000000;
}
.department {
margin-left: auto;
margin-right: 0;
font-size: 16px;
color: #596470;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.content-row {
display: flex;
.content-field {
display: grid;
width: 50%;
grid-template-columns: 1fr 1fr;
align-items: center;
margin: 2px 0;
font-family: 'Open Sans';
font-size: 16px;
@media screen and (min-width: 1200px) {
grid-template-columns: 2fr 3fr;
}
.value {
font-weight: bold;
}
}
}
}
}
}

View File

@@ -1,25 +0,0 @@
import {
Component,
OnInit,
ChangeDetectionStrategy,
Input
} from '@angular/core';
import { RemissionProduct } from '@isa/remission';
@Component({
selector: 'app-remission-details-product',
templateUrl: 'remission-details-product.component.html',
styleUrls: ['./remission-details-product.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RemissionDetailsProductComponent implements OnInit {
@Input()
product: RemissionProduct;
@Input()
removePaddingLeftRight = false;
constructor() {}
ngOnInit() {}
}

View File

@@ -35,7 +35,7 @@
height="17px"
></lib-icon>
</span>
<span class="format-description">{{ product.formatDetail }}</span>
<span class="format-description">{{ product.format }}</span>
<span *ngIf="product.edition">|</span>
<span class="edition">{{ product.edition }}</span>
</div>

View File

@@ -84,17 +84,6 @@
font-weight: bold;
color: #000000;
.format-description {
max-width: 60%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&.expand {
max-width: 80%;
}
}
.format-edition {
display: flex;
flex-direction: row;

View File

@@ -16,27 +16,15 @@
</div>
<div class="card-details">
<div class="icon">
<img
[src]="product.imageId | bookImageUrl | async"
alt="book"
class="thumbnail"
/>
<img [src]="product.imageId | bookImageUrl | async" alt="book" class="thumbnail" />
</div>
<div class="details-info">
<div class="general">
<div class="format-edition item">
<span class="format-icon">
<lib-icon
name="Icon_{{ product.format }}"
mt="4px"
height="17px"
></lib-icon>
<lib-icon name="Icon_{{ product.format }}" mt="4px" height="17px"></lib-icon>
</span>
<span
class="format-description"
[ngClass]="{ expand: !product?.edition?.length }"
>{{ product.formatDetail }}</span
>
<span class="format-description">{{ product.format }}</span>
<span *ngIf="product.edition">|</span>
<span class="edition">{{ product.edition }}</span>
</div>
@@ -48,30 +36,16 @@
<span class="currency">{{ product.currency }}</span>
</div>
<div class="features item" *ngIf="isArray(product.features)">
<ng-container
*ngFor="let feature of product.features; let index = index"
>
<ng-container *ngFor="let feature of product.features; let index = index">
<div class="features__tooltip-container">
<div class="features__tooltip" *ngIf="toolTipOpened[index]">
<div
class="feature-tooltip"
[style.marginLeft.px]="tooltipMl"
>
<div class="feature-tooltip" [style.marginLeft.px]="tooltipMl">
{{ getObjectValue(feature, 0) }}
<lib-icon
(click)="closeTooltip(index)"
height="11px"
name="Delete-white"
></lib-icon>
<lib-icon (click)="closeTooltip(index)" height="11px" name="Delete-white"></lib-icon>
</div>
<div
class="feature-tooltip-arrow-down"
[style.marginLeft.px]="tooltipArrowMl"
></div>
<div class="feature-tooltip-arrow-down" [style.marginLeft.px]="tooltipArrowMl"></div>
</div>
<span (click)="openTooltip(index)">{{
getObjectKey(feature, 0)
}}</span>
<span (click)="openTooltip(index)">{{ getObjectKey(feature, 0) }}</span>
</div>
</ng-container>
</div>
@@ -88,12 +62,8 @@
<div class="data">{{ product.inStock }}x</div>
<div class="data">{{ product.remissionQuantity }}x</div>
<div class="data short">{{ product.remainingQuantity }}x</div>
<div class="data short">
{{ product.placementType ? product.placementType : '&nbsp;' }}
</div>
<div class="data" *ngIf="product.remissionReason">
{{ product.remissionReason }}
</div>
<div class="data short">{{ product.placementType ? product.placementType : '&nbsp;' }}</div>
<div class="data" *ngIf="product.remissionReason">{{ product.remissionReason }}</div>
</div>
</div>
</div>

View File

@@ -81,17 +81,6 @@
font-weight: bold;
color: #000000;
.format-description {
max-width: 60%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&.expand {
max-width: 80%;
}
}
.format-edition {
display: flex;
flex-direction: row;

View File

@@ -1,13 +0,0 @@
<div
class="container"
*ngIf="
numberOfOpenShippingDocuments$ | async as numberOfOpenShippingDocuments
"
>
<lib-icon class="icon" name="Icon_Warenbegleitschein_Red"></lib-icon>
<app-button alignLeft="true" (action)="openOverviewPage()">
<span
>Warenbegleitscheine ({{ numberOfOpenShippingDocuments$ | async }})</span
>
</app-button>
</div>

View File

@@ -1,8 +0,0 @@
.container {
display: flex;
align-items: center;
.icon {
padding-right: 8px;
}
}

View File

@@ -1,51 +0,0 @@
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Store, Select } from '@ngxs/store';
import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors';
import { RemissionProcess } from '@isa/remission';
import { Observable } from 'rxjs';
import { map, filter } from 'rxjs/operators';
import { isNullOrUndefined } from 'util';
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';
@Component({
selector: 'app-remission-open-shipping-documents-widget',
templateUrl: './remission-open-shipping-document-widget.component.html',
styleUrls: ['./remission-open-shipping-document-widget.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RemissionOpenShippingDocumentsWidgetComponent implements OnInit {
@Select(RemissionSelectors.getAllUncompletedRemissions)
uncompletedRemissions$: Observable<RemissionProcess[]>;
numberOfOpenShippingDocuments$: Observable<number>;
constructor(private store: Store, private router: Router) {}
ngOnInit() {
this.numberOfOpenShippingDocuments$ = this.getNumberOfOpenShippingDocuments();
}
openOverviewPage() {
const path = 'remission/overview';
this.store.dispatch(
new AddBreadcrumb(
{
path: path,
name: 'Offene Warenbegleitscheine'
},
'remission'
)
);
this.store.dispatch(new SetBranchProcessCurrentPath(path, true));
this.router.navigate([path]);
}
private getNumberOfOpenShippingDocuments(): Observable<number> {
return this.uncompletedRemissions$.pipe(
filter(remissionProcesses => !isNullOrUndefined(remissionProcesses)),
map(remissionProcesses => remissionProcesses.length)
);
}
}

View File

@@ -1,11 +1,4 @@
import {
Component,
OnInit,
Output,
EventEmitter,
OnDestroy,
ViewChild
} from '@angular/core';
import { Component, OnInit, Output, EventEmitter, OnDestroy, ViewChild } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@@ -32,18 +25,13 @@ export class RemissionPrinterSelectionComponent implements OnInit, OnDestroy {
@Output() print: EventEmitter<string> = new EventEmitter();
@ViewChild('printBtn') printBtn: ButtonComponent;
constructor(
private remissionService: RemissionService,
private modalService: ModalService
) {}
constructor(private remissionService: RemissionService, private modalService: ModalService) {}
ngOnInit() {}
printerSelected(value: string | number) {
this.selected = value;
this.selectedPrinterValue = this.printers.find(
t => t.text === this.selected
).key;
this.selectedPrinterValue = this.printers.find(t => t.text === this.selected).key;
}
emitPrint() {
@@ -69,12 +57,8 @@ export class RemissionPrinterSelectionComponent implements OnInit, OnDestroy {
});
const selectedPrinter = this.printers.find(printer => printer.selected);
this.options = this.printers.map(t => t.text);
this.selectedPrinterValue = selectedPrinter
? selectedPrinter.key
: this.printers[0].key;
this.selected = selectedPrinter
? selectedPrinter.text
: this.options[0];
this.selectedPrinterValue = selectedPrinter ? selectedPrinter.key : this.printers[0].key;
this.selected = selectedPrinter ? selectedPrinter.text : this.options[0];
this.error = false;
this.loaded = true;
if (this.printBtn) {

View File

@@ -91,13 +91,13 @@ export class RemissionShippingDocumentComponent implements OnInit, OnDestroy {
takeUntil(this.destroy$),
map(response => response.result)
)
.subscribe(this.handleDeleteResult);
.subscribe(result => this.handleDeleteResult(result));
}
private handleDeleteResult = (result: {
private handleDeleteResult(result: {
deleted: boolean;
completedRemissionsExist: boolean;
}) => {
}) {
if (result.deleted) {
this.store.dispatch(
new DeleteRemissionShippingDocument(this.remissionProcessId)
@@ -111,7 +111,7 @@ export class RemissionShippingDocumentComponent implements OnInit, OnDestroy {
this.store.dispatch(new ResetRemissionState());
return this.navigateToStartPage();
};
}
navigateToStartPage() {
const path = '/remission/create';

View File

@@ -1,34 +0,0 @@
<div class="content-container">
<div class="content-row">
<div class="content-field">
<span class="descriptor">Status</span>
<span class="value">{{ isCompleted ? 'abgeschlossen' : 'offen' }}</span>
</div>
<div class="content-field" [ngClass]="{ 'position-right': alignRight }">
<span class="descriptor">Lieferant</span>
<span class="value">{{ supplier }}</span>
</div>
</div>
<div class="content-row">
<div class="content-field">
<span class="descriptor">Anzahl Positionen</span>
<span class="value"> {{ numberOfItems }} </span>
</div>
<div class="content-field" [ngClass]="{ 'position-right': alignRight }">
<span class="descriptor">Remissionsdatum</span>
<span class="value">{{ date | date: 'shortDate' }}</span>
</div>
</div>
<div class="content-row" *ngIf="isCompleted && shippingDocumentNumber">
<div class="content-field">
<span class="descriptor">Wannennummer</span>
<span class="value">{{
shippingDocumentNumber | shippingDocumentNumberFormatter
}}</span>
</div>
</div>
</div>

View File

@@ -1,38 +0,0 @@
.content-container {
.content-row {
display: grid;
grid-template-columns: 1fr 1fr;
justify-content: center;
.content-field {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
margin: 0.4rem 0;
font-family: 'Open Sans';
font-size: 16px;
@media screen and (min-width: 1200px) {
grid-template-columns: 2fr 3fr;
}
.value {
font-weight: bold;
}
&.position-right {
& > .descriptor {
margin-left: 7rem;
@media screen and (min-width: 1200px) {
margin-left: 11rem;
}
}
& > .value {
margin-left: auto;
}
}
}
}
}

View File

@@ -1,36 +0,0 @@
import {
Component,
OnInit,
ChangeDetectionStrategy,
Input
} from '@angular/core';
@Component({
selector: 'app-remissions-overview-card-content',
templateUrl: 'remissions-overview-card-content.component.html',
styleUrls: ['./remissions-overview-card-content.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RemissionsOverviewCardContentComponent implements OnInit {
@Input()
isCompleted: boolean;
@Input()
shippingDocumentNumber: string;
@Input()
numberOfItems = 0;
@Input()
supplier = '';
@Input()
date = '';
@Input()
alignRight = false;
constructor() {}
ngOnInit() {}
}

View File

@@ -1,26 +0,0 @@
<div
class="card-container"
[ngClass]="{ last: last }"
(click)="onClickOpenDetails()"
>
<div class="card-wrapper">
<div class="card-header">
<span *ngIf="!shippingDocumentIsCompleted" class="red-circle"></span>
<div class="card-title">
#{{
shippingDocumentNumber
| shippingDocumentNumberFormatter
| packageNumberParser
}}
</div>
</div>
<app-remissions-overview-card-content
[isCompleted]="shippingDocumentIsCompleted"
[supplier]="remissionProcess?.filter?.target?.name"
[numberOfItems]="numberOfShippingDocumentProducts"
[shippingDocumentNumber]="shippingDocumentNumber"
[date]="remissionProcess?.startDate"
></app-remissions-overview-card-content>
</div>
</div>

View File

@@ -1,40 +0,0 @@
.card-container {
min-height: 160px;
margin-bottom: 12px;
border-radius: 5px;
background-color: #ffffff;
font-family: 'Open Sans';
.last {
margin-bottom: 20px;
}
.card-wrapper {
padding-top: 22px;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 16px;
.card-header {
display: flex;
align-items: center;
margin: 8px 0;
.red-circle {
display: inline-block;
width: 10px;
height: 10px;
background: red;
border-radius: 50%;
margin-right: 0.5rem;
}
.card-title {
font-family: 'Open Sans';
font-size: 26px;
font-weight: bold;
color: #000000;
}
}
}
}

View File

@@ -1,73 +0,0 @@
import {
Component,
OnInit,
ChangeDetectionStrategy,
Input,
Output,
EventEmitter
} from '@angular/core';
import { RemissionProcess } from '@isa/remission';
@Component({
selector: 'app-remissions-overview-card',
templateUrl: 'remissions-overview-card.component.html',
styleUrls: ['./remissions-overview-card.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RemissionsOverviewCardComponent implements OnInit {
@Input()
remissionProcess: RemissionProcess;
@Input()
last = false;
@Output()
openDetailsPage = new EventEmitter<number>();
constructor() {}
ngOnInit() {}
onClickOpenDetails() {
this.openDetailsPage.emit(this.remissionProcess.externalId);
}
private shippingDocumentExists(remissionProcess: RemissionProcess): boolean {
return (
!!remissionProcess.shippingDocuments &&
!!remissionProcess.shippingDocuments[0]
);
}
get shippingDocumentId() {
if (!this.shippingDocumentExists(this.remissionProcess)) {
return null;
}
return this.remissionProcess.shippingDocuments[0].id;
}
get shippingDocumentIsCompleted() {
if (!this.shippingDocumentExists(this.remissionProcess)) {
return false;
}
return this.remissionProcess.shippingDocuments[0].isCompleted;
}
get numberOfShippingDocumentProducts() {
if (!this.shippingDocumentExists(this.remissionProcess)) {
return 0;
}
return this.remissionProcess.shippingDocuments[0].products.length;
}
get shippingDocumentNumber() {
if (!this.shippingDocumentExists(this.remissionProcess)) {
return null;
}
return this.remissionProcess.shippingDocuments[0].shippingDocumentNumber;
}
}

View File

@@ -1,11 +1,4 @@
import {
Component,
OnInit,
ViewChild,
ElementRef,
AfterViewInit,
ViewEncapsulation
} from '@angular/core';
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit, ViewEncapsulation } from '@angular/core';
import { isNullOrUndefined } from 'util';
import { Store } from '@ngxs/store';
import { RemissionService, RemissionProduct } from '@isa/remission';
@@ -24,20 +17,14 @@ import { RemissionScanProductInvalidBarcodeComponent } from '../../components/re
styleUrls: ['./remission-add-product-to-remission-list.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class RemissionAddProductToRemissionListComponent
implements OnInit, AfterViewInit {
export class RemissionAddProductToRemissionListComponent implements OnInit, AfterViewInit {
errorMessage: string;
@ViewChild('input') input: ElementRef;
@ViewChild('searchInput') searchInput: SearchInputComponent;
@ViewChild('invalidBarcodeDialog')
invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent;
@ViewChild('invalidBarcodeDialog') invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent;
constructor(
private store: Store,
private remissionService: RemissionService,
private router: Router
) {}
constructor(private store: Store, private remissionService: RemissionService, private router: Router) {}
ngOnInit() {}
@@ -100,9 +87,7 @@ export class RemissionAddProductToRemissionListComponent
)
);
this.router.navigate([path], { queryParams: queryParams });
this.store.dispatch(
new SetBranchProcessCurrentPath(path, true, queryParams)
);
this.store.dispatch(new SetBranchProcessCurrentPath(path, true, queryParams));
}
clearErrors() {

View File

@@ -1,97 +0,0 @@
<ng-container *ngIf="!(isLoading | async); else loading">
<div
class="scroll-container"
*ngIf="remissionProcess$ | async as remissionProcess"
>
<div class="container">
<div class="card-wrapper">
<ng-container
[ngSwitch]="(remissionProcess?.shippingDocuments)[0].isCompleted"
>
<div class="button-wrapper" *ngSwitchCase="false">
<app-button (action)="deleteShippingDocument()" [alignRight]="true"
>Löschen</app-button
>
</div>
<div class="button-wrapper" *ngSwitchDefault>
<app-button
[alignRight]="true"
[disabled]="!!(isPrinting | async)"
(action)="openPrintSelection()"
>Drucken</app-button
>
</div>
</ng-container>
<div class="header">
<div class="title">Warenbegleitschein</div>
<div class="title">
#{{
remissionProcess.shippingDocuments[0].shippingDocumentNumber
| shippingDocumentNumberFormatter
| packageNumberParser
}}
</div>
</div>
<app-remissions-overview-card-content
[isCompleted]="(remissionProcess?.shippingDocuments)[0].isCompleted"
[supplier]="remissionProcess?.filter?.target?.name"
[numberOfItems]="
(remissionProcess?.shippingDocuments)[0].products?.length
"
[shippingDocumentNumber]="
(remissionProcess?.shippingDocuments)[0].shippingDocumentNumber
"
alignRight="true"
[date]="remissionProcess?.startDate"
></app-remissions-overview-card-content>
</div>
</div>
<div
class="container product-container"
[ngClass]="{ last: last }"
*ngFor="
let product of (remissionProcess?.shippingDocuments)[0]?.products;
let last = last
"
>
<div class="card-wrapper products">
<app-remission-details-product
removePaddingLeftRight="true"
[product]="product"
></app-remission-details-product>
</div>
</div>
<app-remission-details-primary-cta
[shippingDocument]="(remissionProcess?.shippingDocuments)[0]"
[continueWithScan]="
shouldScanToContinue((remissionProcess?.shippingDocuments)[0])
"
(action)="openRemission(remissionProcess)"
></app-remission-details-primary-cta>
</div>
<ng-template #loading>
<div class="spinner"></div>
</ng-template>
<app-remission-printer-selection
#printModal
(print)="print($event)"
></app-remission-printer-selection>
<app-remission-confirm-delete-shipping-document
#remissionConfirmDeleteDialog
(confirmDelete)="confirmDeleteShippingDocument()"
></app-remission-confirm-delete-shipping-document>
<lib-remission-shipping-document-scanner
#scanner
*ngIf="isIPad && showScanner"
(scan)="shippingDocumentScanned($event)"
></lib-remission-shipping-document-scanner>
</ng-container>

View File

@@ -1,58 +0,0 @@
.scroll-container {
height: calc(100% - 30px);
overflow-y: auto;
.container {
min-height: 125px;
margin-bottom: 2px;
border-radius: 5px;
background-color: #ffffff;
font-family: 'Open Sans';
&.product-container {
border-radius: 0px;
&.last {
border-radius: 0 0 5px 5px;
}
}
.card-wrapper {
padding-top: 16px;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 16px;
&.products {
padding-top: 8px;
padding-bottom: 8px;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin: 8px 0;
.title {
font-family: 'Open Sans';
font-size: 26px;
font-weight: bold;
color: #000000;
}
}
.button-wrapper {
display: flex;
justify-content: flex-end;
position: relative;
.print-spinner {
position: absolute;
top: -15px;
right: -15px;
}
}
}
}
}

View File

@@ -1,377 +0,0 @@
import {
Component,
OnInit,
OnDestroy,
ViewChild,
AfterContentChecked,
ChangeDetectorRef
} from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import {
RemissionProcess,
RemissionService,
ShippingDocument
} from '@isa/remission';
import { Observable, Subject, BehaviorSubject, of, combineLatest } from 'rxjs';
import {
map,
flatMap,
takeUntil,
filter,
tap,
catchError,
take,
withLatestFrom
} from 'rxjs/operators';
import { Store } from '@ngxs/store';
import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors';
import { isNullOrUndefined } from 'util';
import {
SetAllExistingRemissions,
SetRemissionProcess,
SetRemissionStarted,
SetRemissionShippingDocument
} from 'apps/sales/src/app/core/store/actions/remission.actions';
import { PrinterSelectionComponent } from 'apps/sales/src/app/components/printer-selection/printer-selection.component';
// tslint:disable-next-line: max-line-length
import { RemissionConfirmDeleteShippingDocumentDialogComponent } from '../../components/remission-confirm-delete-shipping-document-dialog/remission-confirm-delete-shipping-document-dialog.component';
import {
AddBreadcrumb,
ResetBreadcrumbsTo
} from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions';
import { ErrorService } from 'apps/sales/src/app/core/error/component/error.service';
import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model';
import { AppService } from '@sales/core-services';
import { RemissionContainerScannerScanditComponent } from 'shared/public_api';
@Component({
selector: 'app-remission-details',
templateUrl: 'remission-details.component.html',
styleUrls: ['./remission-details.component.scss']
// changeDetection: ChangeDetectionStrategy.OnPush
})
export class RemissionDetailsComponent
implements OnInit, OnDestroy, AfterContentChecked {
destroy$ = new Subject();
isLoading = new BehaviorSubject<boolean>(false);
isPrinting = new BehaviorSubject<boolean>(false);
remissionProcess$: Observable<RemissionProcess>;
isIPad = false;
showScanner = false;
@ViewChild('printModal') printModal: PrinterSelectionComponent;
@ViewChild('remissionConfirmDeleteDialog')
remissionConfirmDeleteDialog: RemissionConfirmDeleteShippingDocumentDialogComponent;
@ViewChild('scanner')
scannerComponent: RemissionContainerScannerScanditComponent;
constructor(
private activatedRoute: ActivatedRoute,
private store: Store,
private router: Router,
private cdr: ChangeDetectorRef,
private remissionService: RemissionService,
private errorService: ErrorService,
private appService: AppService
) {}
ngOnInit() {
this.isIPad = this.checkIfIpad();
this.remissionProcess$ = this.getRemissionProcess();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
ngAfterContentChecked() {
this.cdr.detectChanges();
}
getShippingDocumentId(): Observable<number> {
return this.activatedRoute.params.pipe(
map(params => Number(params.shippingDocumentId))
);
}
getRemissionProcess(): Observable<RemissionProcess> {
return this.getShippingDocumentId().pipe(
flatMap(this.getRemissionFromShippingDocumentId)
);
}
openRemission(remissionProcess: RemissionProcess) {
if (this.shouldScanToContinue(remissionProcess.shippingDocuments[0])) {
return this.navigateToScanContainerPage();
}
this.setRemissionInStore(remissionProcess)
.pipe(takeUntil(this.destroy$), take(1))
.subscribe(this.navigateToRemissionStartedPage);
}
private navigateToScanContainerPage = () => {
this.showScanner = true;
this.cdr.detectChanges();
this.scannerComponent.openNativeScanner();
};
shippingDocumentScanned(receiptNumber: string) {
this.store
.select(RemissionSelectors.getAllRemissions)
.pipe(
takeUntil(this.destroy$),
map(remissionProcesses =>
remissionProcesses.find(
remissionProcess =>
remissionProcess.shippingDocuments[0] &&
remissionProcess.shippingDocuments[0].shippingDocumentNumber ===
receiptNumber
)
)
)
.subscribe(this.shippingDocumentScannedResultHandler);
}
private shippingDocumentScannedResultHandler = (
remissionProcess: RemissionProcess
) => {
this.showScanner = false;
this.cdr.detectChanges();
this.setRemissionInStore(remissionProcess)
.pipe(takeUntil(this.destroy$), take(1))
.subscribe(this.navigateToRemissionStartedPage);
};
private setRemissionInStore(remissionProcess: RemissionProcess) {
return this.store
.dispatch(new SetRemissionProcess(remissionProcess, true))
.pipe(
map(_ =>
this.store.dispatch(
new SetRemissionShippingDocument(
remissionProcess.shippingDocuments[0]
)
)
),
map(_ => this.store.dispatch(new SetRemissionStarted(true)))
);
}
private navigateToRemissionStartedPage = () => {
const path = '/remission/started';
this.store.dispatch(
new ResetBreadcrumbsTo(
<Breadcrumb>{
name: 'Remission',
path: path
},
'remission',
true
)
);
this.store.dispatch(new SetBranchProcessCurrentPath(path));
this.router.navigate([path]);
};
deleteShippingDocument() {
this.remissionProcess$
.pipe(
takeUntil(this.destroy$),
filter(remissionProcess => {
const shippingDocument = remissionProcess.shippingDocuments[0];
if (!shippingDocument) {
return false;
}
if (this.hasProducts(shippingDocument)) {
this.remissionConfirmDeleteDialog.openDialog();
return false;
}
return true;
}),
withLatestFrom(this.getShippingDocumentId()),
flatMap(([remissionProcess, shippingDocumentId]) =>
this.remissionService
.deleteShippingDocument({
remissionProcessId: remissionProcess.id,
shippingDocumentId,
externalId: remissionProcess.externalId
})
.pipe(map(response => response.result))
)
)
.subscribe(this.handleDeleteResult);
}
confirmDeleteShippingDocument() {
combineLatest(this.remissionProcess$, this.getShippingDocumentId())
.pipe(
takeUntil(this.destroy$),
flatMap(([remissionProcess, shippingDocumentId]) =>
this.remissionService
.deleteShippingDocument({
remissionProcessId: remissionProcess.id,
shippingDocumentId,
externalId: remissionProcess.externalId
})
.pipe(map(response => response.result))
)
)
.subscribe(this.handleDeleteResult);
}
private handleDeleteResult = (result: {
deleted: boolean;
completedRemissionsExist: boolean;
}) => {
if (!result.deleted) {
return this.handleDeleteError(
'Fehler beim Löschen des Warenbegleitscheins'
);
}
if (result.completedRemissionsExist) {
return this.navigateToCompleteRemissionPage();
}
return this.navigateToOverviewPage();
};
private handleDeleteError = (errorMessage: string) => {
this.errorService.addErrors(400, errorMessage, errorMessage);
};
navigateToOverviewPage = () => {
const path = 'remission/overview';
this.store.dispatch(
new AddBreadcrumb(
{
path: path,
name: 'Offene Warenbegleitscheine'
},
'remission'
)
);
this.store.dispatch(new SetBranchProcessCurrentPath(path, true));
this.router.navigate([path]);
};
navigateToCompleteRemissionPage = () => {
const path = '/remission/finish';
this.store.dispatch(
new AddBreadcrumb(
{
path: path,
name: 'Wannennummer'
},
'remission'
)
);
this.router.navigate([path]);
this.store.dispatch(new SetBranchProcessCurrentPath(path));
};
openPrintSelection() {
this.printModal.openDialog();
}
print(printerKey: string) {
this.isPrinting.next(true);
this.remissionProcess$
.pipe(
takeUntil(this.destroy$),
map(remission => remission.id),
flatMap(remissionProcessId =>
this.remissionService
.printShippingDocument({
remissionProcessId,
printerKey
})
.pipe(
catchError(_ => {
this.isLoading.next(false);
return of(false);
})
)
)
)
.subscribe(this.printSubscriptionHandler, this.printErrorHandler);
}
private printSubscriptionHandler = () => {
this.isPrinting.next(false);
this.printModal.closeModal();
};
private printErrorHandler = () => {
this.isPrinting.next(false);
};
private getRemissionFromShippingDocumentId = (
shippingDocumentId: number
): Observable<RemissionProcess> => {
const allRemissions$ = this.store.select(
RemissionSelectors.getAllRemissions
);
return allRemissions$.pipe(
takeUntil(this.destroy$),
tap(allRemissions => {
if (isNullOrUndefined(allRemissions)) {
this.isLoading.next(true);
this.loadAllRemissions();
}
}),
filter(allRemissions => !isNullOrUndefined(allRemissions)),
map(allRemissions =>
allRemissions.find(
remission =>
remission.shippingDocuments[0] &&
remission.shippingDocuments[0].id === shippingDocumentId
)
)
);
};
private loadAllRemissions() {
this.remissionService
.getAllRemissions({ showLastWeekOnly: true })
.pipe(
takeUntil(this.destroy$),
filter(remissionProcesses => !isNullOrUndefined(remissionProcesses))
)
.subscribe(this.allRemissionsSubscriptionHandler);
}
private allRemissionsSubscriptionHandler = (
remissionProcesses: RemissionProcess[]
) => {
this.isLoading.next(false);
this.store.dispatch(new SetAllExistingRemissions(remissionProcesses));
};
private hasProducts(shippingDocument: ShippingDocument): boolean {
return !!shippingDocument.products.length;
}
private checkIfIpad(): boolean {
return this.appService.isIPadEnv();
}
private isShippingDocumentGenerated(
shippingDocument: ShippingDocument
): boolean {
// 9 indicates that document has been generated
return shippingDocument.shippingDocumentNumber[6] === '9';
}
shouldScanToContinue(shippingDocument: ShippingDocument): boolean {
return !this.isShippingDocumentGenerated(shippingDocument) && !!this.isIPad;
}
}

View File

@@ -1,28 +1,13 @@
import {
Component,
OnInit,
OnDestroy,
ChangeDetectorRef,
ViewChild
} from '@angular/core';
import { Component, OnInit, OnDestroy, ChangeDetectorRef, ViewChild } from '@angular/core';
import { RemissionFinishingProcessStatus } from '../../models/remission-finishing-process-status.enum';
import { Store, Select } from '@ngxs/store';
import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors';
import {
RemissionSupplier,
RemissionProcess,
RemissionService,
ShippingDocument,
Printer
} from '@isa/remission';
import { RemissionSupplier, RemissionProcess, RemissionService, ShippingDocument, Printer } from '@isa/remission';
import { filter, takeUntil, take, switchMap, map } from 'rxjs/operators';
import { isNullOrUndefined } from 'util';
import { Subject, Observable, merge } from 'rxjs';
import { SUPPLIER_PLACEHOLDER } from '../../constants/remission.constants';
import {
AddBreadcrumb,
ResetBreadcrumbsTo
} from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { AddBreadcrumb, ResetBreadcrumbsTo } 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 {
@@ -36,10 +21,8 @@ import {
} from 'apps/sales/src/app/core/store/actions/remission.actions';
import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model';
import { AppService } from '@sales/core-services';
// tslint:disable-next-line: max-line-length
import { RemissionScanProductInvalidBarcodeComponent } from '../../components/remission-scan-product-invalid-barcode/remission-scan-product-invalid-barcode.component';
import { NativeContainerService } from 'shared/lib/remission-container-scanner/native-container.service';
// tslint:disable-next-line: max-line-length
import { RemissionScanShippingDocumentClosedComponent } from '../../components/remission-scan-shipping-document-closed/remission-scan-shipping-document-closed.component';
import { RemissionProcessStatuses } from 'apps/sales/src/app/core/models/remission-process-statuses.model';
import { PrinterSelectionComponent } from 'apps/sales/src/app/components/printer-selection/printer-selection.component';
@@ -50,34 +33,24 @@ import { PrinterSelectionComponent } from 'apps/sales/src/app/components/printer
styleUrls: ['./remission-finish.component.scss']
})
export class RemissionFinishComponent implements OnInit, OnDestroy {
@Select(RemissionSelectors.getRemissionProcess) remissionProcess$: Observable<
RemissionProcess
>;
@Select(RemissionSelectors.getRemissionShippingDocument)
shippingDocument$: Observable<ShippingDocument>;
@Select(RemissionSelectors.getRemissionShippingDocumentstatus)
shippingDocumentStatus$;
@Select(RemissionSelectors.getRemissionProcess) remissionProcess$: Observable<RemissionProcess>;
@Select(RemissionSelectors.getRemissionShippingDocument) shippingDocument$: Observable<ShippingDocument>;
@Select(RemissionSelectors.getRemissionShippingDocumentstatus) shippingDocumentStatus$;
@Select(RemissionSelectors.getRemissionProcess)
currentRemissionProcess$: Observable<RemissionProcess>;
@Select(RemissionSelectors.getRemissionProcessStatuses)
remissionProcessStatuses$: Observable<RemissionProcessStatuses>;
@ViewChild('invalidBarcodeDialog')
invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent;
@ViewChild('invalidDocumentDialog')
invalidDocumentDialog: RemissionScanShippingDocumentClosedComponent;
@ViewChild('invalidBarcodeDialog') invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent;
@ViewChild('invalidDocumentDialog') invalidDocumentDialog: RemissionScanShippingDocumentClosedComponent;
@ViewChild('printModal') printModal: PrinterSelectionComponent;
pageStatus: RemissionFinishingProcessStatus;
suppliers: {
leftSupplier: RemissionSupplier;
rightSupplier: RemissionSupplier;
};
suppliers: { leftSupplier: RemissionSupplier; rightSupplier: RemissionSupplier };
remissionProcess: RemissionProcess;
shippingDocument: ShippingDocument;
destroy$ = new Subject();
containerId: string;
showError = false;
errorMsg =
'Leider haben Sie den falschen Barcode gescannt. Scannen Sie bitte den Barcode seitlich an der Wanne.';
errorMsg = 'Leider haben Sie den falschen Barcode gescannt. Scannen Sie bitte den Barcode seitlich an der Wanne.';
supplier: RemissionSupplier;
startNewRemission = false;
title = {
@@ -138,12 +111,8 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
.subscribe(status => {
this.pageStatus = status;
this.cdrf.detectChanges();
if (
this.pageStatus === RemissionFinishingProcessStatus.containerScanned
) {
this.containerId = this.store.selectSnapshot(
RemissionSelectors.getRemissionContainerId
);
if (this.pageStatus === RemissionFinishingProcessStatus.containerScanned) {
this.containerId = this.store.selectSnapshot(RemissionSelectors.getRemissionContainerId);
} else if (this.pageStatus === RemissionFinishingProcessStatus.notSet) {
this.navigateToNewRemissionList();
}
@@ -180,8 +149,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
)
.subscribe(({ isCompleted }) => {
if (isCompleted) {
this.pageStatus =
RemissionFinishingProcessStatus.containerScanned;
this.pageStatus = RemissionFinishingProcessStatus.containerScanned;
}
});
}
@@ -199,9 +167,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
}
loadCurrentRemissionProcess() {
return this.currentRemissionProcess$.pipe(
filter(data => !isNullOrUndefined(data), take(1))
);
return this.currentRemissionProcess$.pipe(filter(data => !isNullOrUndefined(data), take(1)));
}
continueProcess() {
@@ -213,21 +179,13 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
);
}
shippingDocumentSubscriptionHandler = (
shippingDocument: ShippingDocument
) => {
shippingDocumentSubscriptionHandler = (shippingDocument: ShippingDocument) => {
this.shippingDocument = shippingDocument;
};
remissionProcessSubscriptionHandler = (
remissionProcess: RemissionProcess
) => {
remissionProcessSubscriptionHandler = (remissionProcess: RemissionProcess) => {
this.remissionProcess = remissionProcess;
if (
remissionProcess &&
remissionProcess.filter &&
remissionProcess.filter.target
) {
if (remissionProcess && remissionProcess.filter && remissionProcess.filter.target) {
this.loadSupplier(remissionProcess.filter.target);
}
};
@@ -241,15 +199,11 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
}
if (this.supplier) {
const selectedSupplierName = remissionSuplier.name;
this.title[
RemissionFinishingProcessStatus.finished
] = this.finishPocessTitles[this.supplier.id].replace(
this.title[RemissionFinishingProcessStatus.finished] = this.finishPocessTitles[this.supplier.id].replace(
SUPPLIER_PLACEHOLDER,
selectedSupplierName
);
this.subTitle[
RemissionFinishingProcessStatus.finished
] = this.finishPocessSubTitles[this.supplier.id].replace(
this.subTitle[RemissionFinishingProcessStatus.finished] = this.finishPocessSubTitles[this.supplier.id].replace(
SUPPLIER_PLACEHOLDER,
selectedSupplierName
);
@@ -270,21 +224,17 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
this.pageStatus = RemissionFinishingProcessStatus.finished;
this.store.dispatch(new SetRemissionFinishedProcessStatus(this.pageStatus));
const remissionProcessId = this.remissionProcess.id;
this.remissionService
.completeRemissions({ remissionProcessId })
.subscribe(status => {
if (status) {
this.remissionService
.isPrintingRequired({ remissionProcessId })
.subscribe(isPrintingRequired => {
if (isPrintingRequired) {
this.printModal.openDialog();
} else {
this.store.dispatch(new ResetRemissionState());
}
});
}
});
this.remissionService.completeRemissions({ remissionProcessId }).subscribe(status => {
if (status) {
this.remissionService.isPrintingRequired({ remissionProcessId }).subscribe(isPrintingRequired => {
if (isPrintingRequired) {
this.printModal.openDialog();
} else {
this.store.dispatch(new ResetRemissionState());
}
});
}
});
}
print(selectedPrinter) {
@@ -302,9 +252,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
},
() => {
this.pageStatus = RemissionFinishingProcessStatus.containerScanned;
this.store.dispatch(
new SetRemissionFinishedProcessStatus(this.pageStatus)
);
this.store.dispatch(new SetRemissionFinishedProcessStatus(this.pageStatus));
this.isPrinting = false;
}
);
@@ -373,9 +321,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
if (response.errorReasons.PackageCode) {
this.emptyOrInvalidBarcode = false;
this.pageStatus = RemissionFinishingProcessStatus.start;
this.store.dispatch(
new SetRemissionFinishedProcessStatus(this.pageStatus)
);
this.store.dispatch(new SetRemissionFinishedProcessStatus(this.pageStatus));
const closeDialogRef = this.invalidBarcodeDialog.openDialog();
closeDialogRef.subscribe(() => (this.emptyOrInvalidBarcode = true));
} else {
@@ -383,9 +329,7 @@ export class RemissionFinishComponent implements OnInit, OnDestroy {
}
} else {
this.pageStatus = RemissionFinishingProcessStatus.containerScanned;
this.store.dispatch(
new CompleteRemissionShippingDocument(this.shippingDocument)
);
this.store.dispatch(new CompleteRemissionShippingDocument(this.shippingDocument));
}
});
}

View File

@@ -1,8 +1,4 @@
<div
#remissionListContainer
id="remission-list-container"
class="remission-list-container scrollbar-visible"
>
<div #remissionListContainer id="remission-list-container" class="remission-list-container scrollbar-visible">
<div class="headers" *ngIf="resourceTypeSwitch">
<div class="header-item resource-type">
<lib-double-choice-switch
@@ -11,22 +7,13 @@
(change)="resourceTypeChange($event)"
></lib-double-choice-switch>
</div>
<div class="header-item title">
{{ selectedResourceTypeSpecificModel.headerTitle }}
</div>
<div class="header-item title">{{ selectedResourceTypeSpecificModel.headerTitle }}</div>
<div class="header-item sub-title">
<span
class="align-center"
[ngClass]="{ central: selectedRemissionResourceType === 'zentral' }"
>{{ selectedResourceTypeSpecificModel.headerSubTitle }}</span
>
<span class="align-center" [ngClass]="{ central: selectedRemissionResourceType === 'zentral' }">{{
selectedResourceTypeSpecificModel.headerSubTitle
}}</span>
</div>
<div
*ngIf="
selectedRemissionResourceType === 'ueberlauf';
else supplierAndFilter
"
>
<div *ngIf="selectedRemissionResourceType === 'ueberlauf'; else supplierAndFilter">
<ng-container *ngIf="capacities.length; else spinner">
<div class="progress-wrapper">
<ng-container *ngFor="let item of capacities">
@@ -35,8 +22,7 @@
</div>
<div>
<span
>{{ item.capacity.name }}: {{ item.capacity.utilized }} von
{{ item.capacity.available }} {{ item.capacity.label }}</span
>{{ item.capacity.name }}: {{ item.capacity.utilized }} von {{ item.capacity.available }} {{ item.capacity.label }}</span
>
</div>
</ng-container>
@@ -82,29 +68,15 @@
showOverflowInitialMessage
"
>
<span class="align-center"
>Wählen Sie die Abteilung aus, die Sie remittieren möchten.</span
>
<span class="align-center">Wählen Sie die Abteilung aus, die Sie remittieren möchten.</span>
</div>
<div class="actions" *ngIf="listLoaded && remissionListHits > 0">
<div class="start-remission">
<app-button [primary]="true" (action)="openStartRemissionDialog()"
>Remission starten</app-button
>
<app-button [primary]="true" (action)="openStartRemissionDialog()">Remission starten</app-button>
</div>
<div class="secondary-actions">
<div class="add-article">
<app-button *ngIf="isSafari" (action)="openAddProductToRemission()"
>Artikel hinzufügen</app-button
>
<lib-remission-product-scanner
*ngIf="isNative"
(scan)="searchProductScannedResult($event)"
></lib-remission-product-scanner>
</div>
<div class="open-remissions">
<app-remission-open-shipping-documents-widget></app-remission-open-shipping-documents-widget>
</div>
<div class="add-article">
<app-button *ngIf="isSafari" (action)="openAddProductToRemission()">Artikel hinzufügen</app-button>
<lib-remission-product-scanner *ngIf="isNative" (scan)="searchProductScannedResult($event)"></lib-remission-product-scanner>
</div>
</div>
</ng-template>
@@ -126,10 +98,7 @@
#toTopToBottomActions
></app-remission-to-top-to-bottom-actions>
</div>
<app-remission-start-dialog
(start)="startRemission()"
#remissionStartDialog
></app-remission-start-dialog>
<app-remission-start-dialog (start)="startRemission()" #remissionStartDialog></app-remission-start-dialog>
<app-add-product-to-remission-dialog
*ngIf="searchedRemissionProduct"
[product]="searchedRemissionProduct"
@@ -137,7 +106,5 @@
(closed)="closeAddProductToRemissionDialog()"
#addProductToRemissionDialog
></app-add-product-to-remission-dialog>
<app-remission-scan-product-invalid-barcode
#invalidBarcodeDialog
></app-remission-scan-product-invalid-barcode>
<app-remission-scan-product-invalid-barcode #invalidBarcodeDialog></app-remission-scan-product-invalid-barcode>
</div>

View File

@@ -95,15 +95,8 @@
padding-top: 22px;
}
.secondary-actions {
display: flex;
justify-content: center;
align-items: center;
.add-article,
.open-remissions {
padding-top: 11px;
}
.add-article {
padding-top: 11px;
}
}

View File

@@ -1,27 +1,8 @@
import {
Component,
OnInit,
OnDestroy,
ViewChild,
ChangeDetectorRef,
ElementRef
} from '@angular/core';
import { Component, OnInit, OnDestroy, ViewChild, ChangeDetectorRef, ElementRef } from '@angular/core';
import { Subject, Observable, of } from 'rxjs';
import {
takeUntil,
filter,
take,
tap,
switchMap,
catchError,
delay,
combineAll
} from 'rxjs/operators';
import { takeUntil, filter, take, tap, switchMap, catchError, delay, combineAll } from 'rxjs/operators';
import { DoubleChoiceSwitch } from '@libs/ui';
import {
RemissionResourceType,
RemissionTargetType
} from '../../models/remission-resource-type.model';
import { RemissionResourceType, RemissionTargetType } from '../../models/remission-resource-type.model';
import { ResourceTypeSpecificModel } from '../../models/resource-type-specific-model.model';
import { CapacityTypeClientWrapper } from '../../models/capacity-type-client-wrapper.model';
import { Side } from '@libs/ui/lib/small-double-choice-switch';
@@ -37,10 +18,7 @@ import {
import { Select, Store } from '@ngxs/store';
import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors';
import { RemissionProcessStatuses } from 'apps/sales/src/app/core/models/remission-process-statuses.model';
import {
RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS,
RESOURCE_TYPE_SWITCH
} from '../../constants/remission.constants';
import { RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS, RESOURCE_TYPE_SWITCH } from '../../constants/remission.constants';
import { isNullOrUndefined } from 'util';
import {
SetRemissionProcess,
@@ -49,15 +27,11 @@ import {
SetRemissionTarget,
SetRemissionStarted,
SetRemissionSearchedProduct,
ActivateRemissionReminder,
SetAllOpenExistingRemissions
ActivateRemissionReminder
} from 'apps/sales/src/app/core/store/actions/remission.actions';
import { RemissionHelperService } from '../../services/remission-helper.service';
import { RemissionListComponent } from '../../components/remission-list/remission-list.component';
import {
AddBreadcrumb,
ResetBreadcrumbsTo
} from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { AddBreadcrumb, ResetBreadcrumbsTo } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions';
import { RemissionStartDialogComponent } from '../../components/remission-start-dialog/remission-start-dialog.component';
@@ -88,21 +62,15 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
remissionProcess$: Observable<RemissionProcess>;
remissionSuppliers$ = this.remissionService.getRemissionTargets();
remissionSources$ = this.remissionService.getRemissionSources();
@ViewChild('toTopToBottomActions')
toTopToBottomActions: RemissionToTopToBottomActionsComponent;
@ViewChild('toTopToBottomActions') toTopToBottomActions: RemissionToTopToBottomActionsComponent;
@ViewChild('remissionList') remissionList: RemissionListComponent;
@ViewChild('remissionListContainer') remissionListContainer: ElementRef;
@ViewChild('remissionStartDialog')
remissionStartDialog: RemissionStartDialogComponent;
@ViewChild('addProductToRemissionDialog')
addProductToRemissionDialog: AddProductToRemissionDialogComponent;
@ViewChild('invalidBarcodeDialog')
invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent;
@ViewChild('remissionStartDialog') remissionStartDialog: RemissionStartDialogComponent;
@ViewChild('addProductToRemissionDialog') addProductToRemissionDialog: AddProductToRemissionDialogComponent;
@ViewChild('invalidBarcodeDialog') invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent;
destroy$ = new Subject();
selectedRemissionResourceType: RemissionResourceType =
RemissionResourceType.Central;
selectedResourceTypeSpecificModel: ResourceTypeSpecificModel =
RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[this.selectedRemissionResourceType];
selectedRemissionResourceType: RemissionResourceType = RemissionResourceType.Central;
selectedResourceTypeSpecificModel: ResourceTypeSpecificModel = RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[this.selectedRemissionResourceType];
capacities: CapacityTypeClientWrapper[] = [];
selectedSupplier: Side = Side.LEFT;
suppliers: {
@@ -123,6 +91,7 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
searchedRemissionProduct: RemissionProduct;
showOverflowInitialMessage = true;
lastScrollTop = 0;
private initializeFilters = true;
private resetFilters = false;
constructor(
private remissionService: RemissionService,
@@ -131,6 +100,7 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
private router: Router,
private appService: AppService,
private route: ActivatedRoute,
private cdrf: ChangeDetectorRef,
private nativeContainerService: NativeContainerService
) {}
@@ -201,17 +171,11 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
.subscribe(this.currentRemissionSourcesSubscriptionHandler);
}
currentRemissionSourcesSubscriptionHandler = (
source: RemissionResourceType
) => {
currentRemissionSourcesSubscriptionHandler = (source: RemissionResourceType) => {
this.selectedRemissionResourceType = source;
this.selectedResourceTypeSpecificModel =
RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[source];
this.resourceTypeSwitch.isFirstSwitchedOn =
source === RemissionResourceType.Central;
this.remissionHelper.updateFilters({
remissionProcessId: this.remissionProcess.id
});
this.selectedResourceTypeSpecificModel = RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[source];
this.resourceTypeSwitch.isFirstSwitchedOn = source === RemissionResourceType.Central;
this.remissionHelper.updateFilters({ remissionProcessId: this.remissionProcess.id });
};
loadCurrentRemissionTarget() {
@@ -223,61 +187,36 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
.subscribe(this.currentRemissionTargetSubscriptionHandler);
}
currentRemissionTargetSubscriptionHandler = (
targetName: RemissionTargetType
) => {
currentRemissionTargetSubscriptionHandler = (targetName: RemissionTargetType) => {
const side = targetName === RemissionTargetType.BLANK ? 0 : 1;
if (side !== this.selectedSupplier) {
this.selectedSupplier = side;
this.remissionHelper.updateFilters({
target:
side === Side.LEFT
? this.suppliers.leftSupplier
: this.suppliers.rightSupplier
target: side === Side.LEFT ? this.suppliers.leftSupplier : this.suppliers.rightSupplier
});
}
};
remissionSubsribtionInitialisation() {
this.loadCurrentRemissionProcessStatuses().then(
remissionProcessStatuses => {
if (
remissionProcessStatuses.started &&
!remissionProcessStatuses.completed
) {
this.navigateToStartedRemission();
} else {
this.remissionProcessStatuses = remissionProcessStatuses;
this.remissionProcess$ = !this.remissionProcessStatuses.created
? this.createProcess()
: this.continueProcess();
this.remissionProcess$
.pipe(takeUntil(this.destroy$))
.subscribe(remissionProcess => {
this.remissionProcess = remissionProcess;
this.store.dispatch(
new SetRemissionProcess(remissionProcess, true)
);
(!isNullOrUndefined(remissionProcess.capacities)).ifTrue(() =>
this.capacitiesBinder(remissionProcess.capacities)
);
});
this.loadCurrentRemissionProcessStatuses().then(remissionProcessStatuses => {
if (remissionProcessStatuses.started && !remissionProcessStatuses.completed) {
this.navigateToStartedRemission();
} else {
this.remissionProcessStatuses = remissionProcessStatuses;
this.remissionProcess$ = !this.remissionProcessStatuses.created ? this.createProcess() : this.continueProcess();
this.remissionProcess$.pipe(takeUntil(this.destroy$)).subscribe(remissionProcess => {
this.remissionProcess = remissionProcess;
this.store.dispatch(new SetRemissionProcess(remissionProcess, true));
(!isNullOrUndefined(remissionProcess.capacities)).ifTrue(() => this.capacitiesBinder(remissionProcess.capacities));
});
of(
this.remissionSuppliers$.pipe(
filter(this.remissionSuppliersFilter)
),
this.remissionProcess$
)
.pipe(combineAll(), take(1), takeUntil(this.destroy$))
.subscribe(([suppliers, process]: [any, any]) => {
this.remissionSuppliersSubscriptionHandler(suppliers, process);
});
this.loadUncompletedRemissions();
}
of(this.remissionSuppliers$.pipe(filter(this.remissionSuppliersFilter)), this.remissionProcess$)
.pipe(combineAll(), take(1), takeUntil(this.destroy$))
.subscribe(([suppliers, process]: [any, any]) => {
this.remissionSuppliersSubscriptionHandler(suppliers, process);
});
}
);
});
}
remissionCreatedSuccesfullyHandler = (remissionProcess: RemissionProcess) => {
@@ -288,25 +227,6 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
}
};
loadUncompletedRemissions() {
return this.remissionService
.getAllRemissions({
showLastWeekOnly: true,
showCompleted: false
})
.pipe(
takeUntil(this.destroy$),
filter(remissionProcesses => !isNullOrUndefined(remissionProcesses))
)
.subscribe(this.uncompletedRemissionsSubscriptionHandler);
}
uncompletedRemissionsSubscriptionHandler = (
remissionProcesses: RemissionProcess[]
) => {
this.store.dispatch(new SetAllOpenExistingRemissions(remissionProcesses));
};
loadCurrentRemissionProcessStatuses() {
return this.remissionProcessStatuses$
.pipe(
@@ -333,37 +253,22 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
};
createProcess() {
return this.remissionService
.createProcess()
.pipe(tap(this.remissionCreatedSuccesfullyHandler));
return this.remissionService.createProcess().pipe(tap(this.remissionCreatedSuccesfullyHandler));
}
loadCurrentRemissionProcess() {
return this.currentRemissionProcess$.pipe(
filter(data => !isNullOrUndefined(data), take(1))
);
return this.currentRemissionProcess$.pipe(filter(data => !isNullOrUndefined(data), take(1)));
}
remissionSourcesFilter = (remissionSources: RemissionSourceType[]) => {
return (
remissionSources &&
Array.isArray(remissionSources) &&
remissionSources.length === 2
);
return remissionSources && Array.isArray(remissionSources) && remissionSources.length === 2;
};
remissionSuppliersFilter = (remissionSuppliers: RemissionSupplier[]) => {
return (
remissionSuppliers &&
Array.isArray(remissionSuppliers) &&
remissionSuppliers.length === 2
);
return remissionSuppliers && Array.isArray(remissionSuppliers) && remissionSuppliers.length === 2;
};
remissionSuppliersSubscriptionHandler = (
remissionSuppliers: RemissionSupplier[],
process
) => {
remissionSuppliersSubscriptionHandler = (remissionSuppliers: RemissionSupplier[], process) => {
this.suppliers = {
leftSupplier: remissionSuppliers[0],
rightSupplier: remissionSuppliers[1]
@@ -375,34 +280,22 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
this.remissionProcess = remissionProcess;
this.processNeedsToBeRestoredFromCache.ifTrue(() => this.restoreProcess());
this.selectedRemissionResourceType =
remissionProcess.filter.source === 'zentral'
? RemissionResourceType.Central
: RemissionResourceType.Overflow;
this.store.dispatch(
new SetRemissionSource(this.selectedRemissionResourceType)
);
remissionProcess.filter.source === 'zentral' ? RemissionResourceType.Central : RemissionResourceType.Overflow;
this.store.dispatch(new SetRemissionSource(this.selectedRemissionResourceType));
this.resourceTypeSwitch = {
...this.resourceTypeSwitch,
isFirstSwitchedOn:
this.selectedRemissionResourceType === RemissionResourceType.Central
isFirstSwitchedOn: this.selectedRemissionResourceType === RemissionResourceType.Central
};
this.selectedResourceTypeSpecificModel =
RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[this.selectedRemissionResourceType];
this.selectedResourceTypeSpecificModel = RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[this.selectedRemissionResourceType];
if (this.suppliers) {
setTimeout(() => {
this.selectedSupplier =
get(
remissionProcess,
'filter.target.name',
this.suppliers.leftSupplier.name
) === this.suppliers.leftSupplier.name
get(remissionProcess, 'filter.target.name', this.suppliers.leftSupplier.name) === this.suppliers.leftSupplier.name
? Side.LEFT
: Side.RIGHT;
});
}
(
this.selectedRemissionResourceType === RemissionResourceType.Overflow
).ifTrue(() =>
(this.selectedRemissionResourceType === RemissionResourceType.Overflow).ifTrue(() =>
this.shouldShowOverflowInitialMessage(remissionProcess.filter)
);
this.store
@@ -436,11 +329,7 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
capacitiesBinder = (capacities: CapacityType[]) => {
this.capacities = [];
capacities.forEach(capacity => {
if (
capacity &&
!isNullOrUndefined(capacity.utilized) &&
!isNullOrUndefined(capacity.available)
) {
if (capacity && !isNullOrUndefined(capacity.utilized) && !isNullOrUndefined(capacity.available)) {
let percentage;
const { available, utilized } = capacity;
if (utilized === 0 && available === 0) {
@@ -462,14 +351,9 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
this.listLoaded = false;
this.remissionListHits = 0;
this.resourceTypeSwitch = model;
this.selectedRemissionResourceType = model.isFirstSwitchedOn
? RemissionResourceType.Central
: RemissionResourceType.Overflow;
this.selectedResourceTypeSpecificModel =
RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[this.selectedRemissionResourceType];
this.store.dispatch(
new SetRemissionSource(this.selectedRemissionResourceType)
);
this.selectedRemissionResourceType = model.isFirstSwitchedOn ? RemissionResourceType.Central : RemissionResourceType.Overflow;
this.selectedResourceTypeSpecificModel = RESOURCE_TYPE_SPECIFIC_MODEL_OPTIONS[this.selectedRemissionResourceType];
this.store.dispatch(new SetRemissionSource(this.selectedRemissionResourceType));
this.reinitializeFilters();
this.loadCurrentRemissionTarget();
}
@@ -478,9 +362,7 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
this.selectedSupplier = side;
this.store.dispatch(
new SetRemissionTarget(
side === Side.LEFT
? this.suppliers.leftSupplier
: this.suppliers.rightSupplier,
side === Side.LEFT ? this.suppliers.leftSupplier : this.suppliers.rightSupplier,
this.selectedRemissionResourceType
)
);
@@ -554,10 +436,7 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
}
navigateToTop() {
this.remissionListContainer.nativeElement.scrollTo({
top: 0,
behavior: 'smooth'
});
this.remissionListContainer.nativeElement.scrollTo({ top: 0, behavior: 'smooth' });
}
navigateToBottom() {
@@ -616,9 +495,7 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
this.remissionService
.searchProduct({ ean: input })
.pipe(take(1))
.subscribe(this.searchProductResultHandler, () =>
this.invalidBarcodeDialog.openDialog()
);
.subscribe(this.searchProductResultHandler, () => this.invalidBarcodeDialog.openDialog());
}
searchProductResultHandler = (remissionProduct: RemissionProduct) => {
@@ -640,11 +517,8 @@ export class RemissionListCreateComponent implements OnInit, OnDestroy {
}
private reinitializeFilters() {
const resourceTarget =
this.selectedSupplier === Side.LEFT
? this.suppliers.leftSupplier
: this.suppliers.rightSupplier;
const filters = null;
const resourceTarget = this.selectedSupplier === Side.LEFT ? this.suppliers.leftSupplier : this.suppliers.rightSupplier;
let filters = null;
if (this.resetFilters) {
this.remissionHelper.clearFilters();
this.resetFilters = false;

View File

@@ -1,27 +0,0 @@
<div class="container">
<div class="header">
<lib-icon
class="icon"
width="30px"
name="Icon_Warenbegleitschein"
></lib-icon>
<div class="header-item">
<span class="title">Warenbegleitscheine</span>
</div>
</div>
<ng-container *ngIf="!(isLoading | async); else spinner">
<div class="remission-list" *ngIf="allRemissions$ | async as allRemissions">
<app-remissions-overview-card
*ngFor="let remissionProcess of allRemissions; let last = last"
[remissionProcess]="remissionProcess"
[last]="last"
(openDetailsPage)="navigateToDetailsPage($event)"
></app-remissions-overview-card>
</div>
</ng-container>
<ng-template #spinner>
<div class="spinner"></div>
</ng-template>
</div>

View File

@@ -1,29 +0,0 @@
.container {
height: calc(100% - 30px);
overflow-y: auto;
.header {
display: flex;
flex-flow: column;
align-items: center;
margin-top: 31px;
.header-item {
width: 100%;
display: flex;
justify-content: center;
.title {
margin-top: 8px;
font-family: 'Open Sans';
font-size: 26px;
font-weight: bold;
color: #000000;
}
}
}
.remission-list {
margin: 20px 0 0;
}
}

View File

@@ -1,144 +0,0 @@
import {
Component,
OnInit,
ChangeDetectionStrategy,
OnDestroy
} from '@angular/core';
import { RemissionService, RemissionProcess } from '@isa/remission';
import { Observable, Subject, BehaviorSubject } from 'rxjs';
import { SetAllExistingRemissions } from 'apps/sales/src/app/core/store/actions/remission.actions';
import { Store, Select } from '@ngxs/store';
import { isNullOrUndefined } from 'util';
import { filter, takeUntil, map, take } from 'rxjs/operators';
import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors';
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 { ErrorService } from 'apps/sales/src/app/core/error/component/error.service';
import { ShippingDocumentNumberFormatterPipe } from 'apps/sales/src/app/pipes/shipping-document-number-formatter.pipe';
import { PackageNumberParserPipe } from 'apps/sales/src/app/pipes/package-number-parser.pipe';
@Component({
selector: 'app-remissions-overview',
templateUrl: 'remissions-overview.component.html',
styleUrls: ['./remissions-overview.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RemissionsOverviewComponent implements OnInit, OnDestroy {
destroy$ = new Subject();
isLoading = new BehaviorSubject<boolean>(true);
@Select(RemissionSelectors.getAllRemissions)
allRemissions$: Observable<RemissionProcess[]>;
constructor(
private remissionService: RemissionService,
private store: Store,
private router: Router,
private errorService: ErrorService
) {}
ngOnInit() {
this.loadAllRemissions();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
navigateToDetailsPage(externalRemissionId: number) {
this.allRemissions$
.pipe(
takeUntil(this.destroy$),
map(allRemissions =>
allRemissions.find(
remission => remission.externalId === externalRemissionId
)
),
take(1)
)
.subscribe(this.openDetailsPage);
}
private openDetailsPage = (remissionProcess: RemissionProcess) => {
const shippingDocumentId = this.getShippingDocumentId(remissionProcess);
const shippingDocumentNumber = this.getShippingDocumentNumber(
remissionProcess
);
if (!shippingDocumentId) {
this.errorService.addErrors(
400,
'Für den Vorgang existiert keine Warenbegleischein ID',
'Warenbegleitschein ID unbekannt'
);
}
const path = `remission/overview/${shippingDocumentId}`;
this.store.dispatch(
new AddBreadcrumb(
{
path: path,
name: `Warenbegleitschein ${this.getFormattedShippingDocumentNumber(
shippingDocumentNumber
)}`
},
'remission'
)
);
this.store.dispatch(new SetBranchProcessCurrentPath(path, true));
this.router.navigate([path]);
};
private loadAllRemissions() {
this.remissionService
.getAllRemissions({ showLastWeekOnly: true })
.pipe(
takeUntil(this.destroy$),
filter(remissionProcesses => !isNullOrUndefined(remissionProcesses))
)
.subscribe(
this.allRemissionsSubscriptionHandler,
this.handleRemissionLoadingError
);
}
private handleRemissionLoadingError = (err: any) => {
this.isLoading.next(false);
};
private allRemissionsSubscriptionHandler = (
remissionProcesses: RemissionProcess[]
) => {
this.store.dispatch(new SetAllExistingRemissions(remissionProcesses));
this.isLoading.next(false);
};
private getShippingDocumentId = (remissionProcess: RemissionProcess) => {
if (!remissionProcess.shippingDocuments[0]) {
return null;
}
return remissionProcess.shippingDocuments[0].id;
};
private getShippingDocumentNumber = (remissionProcess: RemissionProcess) => {
if (!remissionProcess.shippingDocuments[0]) {
return null;
}
return remissionProcess.shippingDocuments[0].shippingDocumentNumber;
};
private getFormattedShippingDocumentNumber(
shippingDocumentNumber: string
): string {
const numberFormatter = new ShippingDocumentNumberFormatterPipe();
const numberParser = new PackageNumberParserPipe();
return numberParser.transform(
numberFormatter.transform(shippingDocumentNumber)
);
}
}

View File

@@ -7,8 +7,6 @@ import { RemissionFinishComponent } from './pages/remission-finish/remission-fin
import { RemissionAddProductToRemissionListComponent } from './pages/remission-add-product-to-remission-list/remission-add-product-to-remission-list.component';
// tslint:disable-next-line: max-line-length
import { RemissionGenerateShippingDocumentComponent } from './components/remission-generate-shipping-document/remission-generate-shipping-document.component';
import { RemissionsOverviewComponent } from './pages/remissions-overview/remissions-overview.component';
import { RemissionDetailsComponent } from './pages/remission-details/remission-details.component';
import { CanDeactivatedGuard } from './guard';
@@ -39,14 +37,6 @@ const routes: Routes = [
{
path: 'generate-shipping-document',
component: RemissionGenerateShippingDocumentComponent
},
{
path: 'overview',
component: RemissionsOverviewComponent
},
{
path: 'overview/:shippingDocumentId',
component: RemissionDetailsComponent
}
];

View File

@@ -56,17 +56,7 @@ import { BarcodeSearchModule } from '../barcode-search/barcode-search.module';
// tslint:disable-next-line: max-line-length
import { RemissionScanShippingDocumentClosedComponent } from './components/remission-scan-shipping-document-closed/remission-scan-shipping-document-closed.component';
import { RemissionPrinterSelectionComponent } from './components/remission-printer-selection/remission-printer-selection.component';
// tslint:disable-next-line: max-line-length
import { RemissionConfirmDeleteShippingDocumentDialogComponent } from './components/remission-confirm-delete-shipping-document-dialog/remission-confirm-delete-shipping-document-dialog.component';
// tslint:disable-next-line: max-line-length
import { RemissionOpenShippingDocumentsWidgetComponent } from './components/remission-open-shipping-documents-widget/remission-open-shipping-document-widget.component';
import { RemissionsOverviewComponent } from './pages/remissions-overview/remissions-overview.component';
import { RemissionsOverviewCardComponent } from './components/remissions-overview-card/remissions-overview-card.component';
// tslint:disable-next-line: max-line-length
import { RemissionsOverviewCardContentComponent } from './components/remissions-overview-card-content/remissions-overview-card-content.component';
import { RemissionDetailsComponent } from './pages/remission-details/remission-details.component';
import { RemissionDetailsProductComponent } from './components/remission-details-product/remission-details-product.component';
import { RemissionDetailsPrimaryCtaComponent } from './components/remission-details-primary-cta/remission-details-primary-cta.component';
@NgModule({
declarations: [
@@ -93,14 +83,7 @@ import { RemissionDetailsPrimaryCtaComponent } from './components/remission-deta
RemissionScanProductInvalidBarcodeComponent,
RemissionScanShippingDocumentClosedComponent,
RemissionPrinterSelectionComponent,
RemissionConfirmDeleteShippingDocumentDialogComponent,
RemissionOpenShippingDocumentsWidgetComponent,
RemissionsOverviewComponent,
RemissionsOverviewCardComponent,
RemissionsOverviewCardContentComponent,
RemissionDetailsComponent,
RemissionDetailsProductComponent,
RemissionDetailsPrimaryCtaComponent
RemissionConfirmDeleteShippingDocumentDialogComponent
],
imports: [
BarcodeSearchModule,

View File

@@ -1,30 +0,0 @@
import { ShippingDocumentNumberFormatterPipe } from './shipping-document-number-formatter.pipe';
describe('ShippingDocumentNumberFormatterPipe', () => {
let pipe: ShippingDocumentNumberFormatterPipe;
beforeEach(() => {
pipe = new ShippingDocumentNumberFormatterPipe();
});
it('should create an instance', () => {
const pipeInstance = new ShippingDocumentNumberFormatterPipe();
expect(pipeInstance).toBeTruthy();
});
it('should return 026706900194072971', () => {
const shippingDocumentNumber = '026706900194072971';
const result = pipe.transform(shippingDocumentNumber);
expect(result).toBe('026706900194072971');
});
it('should return 026706900194072972', () => {
const shippingDocumentNumber = '026706900194072972_DEL@2020030516515137470';
const result = pipe.transform(shippingDocumentNumber);
expect(result).toBe('026706900194072972');
});
});

View File

@@ -1,14 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'shippingDocumentNumberFormatter'
})
export class ShippingDocumentNumberFormatterPipe implements PipeTransform {
transform(shippingDocumentNumber: string): string {
if (shippingDocumentNumber.length <= 18) {
return shippingDocumentNumber;
}
return shippingDocumentNumber.slice(0, 18);
}
}

View File

@@ -1,13 +1,14 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'trim'
name: 'trim',
})
export class TrimPipe implements PipeTransform {
transform(value: string): string {
if (!value) {
return '';
}
console.log(value, value.trim());
return value.trim();
}
}

View File

@@ -12,7 +12,6 @@ import { CommonModule } from '@angular/common';
import { SafeHtmlPipe } from '../pipes/safe-html.pipe';
import { PackageNumberParserPipe } from '../pipes/package-number-parser.pipe';
import { AddClassDirective } from './directives/add-class.directive';
import { ShippingDocumentNumberFormatterPipe } from '../pipes/shipping-document-number-formatter.pipe';
const components = [BackArrowComponent];
const directives = [VarDirective, TooltipDirective, AddClassDirective];
@@ -23,8 +22,7 @@ const pipes = [
PhonePipe,
BookThumbnailPipe,
TrimPipe,
PackageNumberParserPipe,
ShippingDocumentNumberFormatterPipe
PackageNumberParserPipe
];
@NgModule({
imports: [CommonModule, IconModule],

View File

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

View File

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -7,7 +7,6 @@
small: type == 'small',
medium: type == 'medium',
big: type == 'big',
'align-left': alignLeft,
'align-right': alignRight,
load: loading,
disabled: disabled && primary,

View File

@@ -66,10 +66,6 @@ button {
&.align-right {
padding-right: 0;
}
&.align-left {
padding-left: 0;
}
}
.spinner {

View File

@@ -26,7 +26,6 @@ export class ButtonComponent {
@Input() stayOnPage = false;
@Input() disabled = false;
@Input() primaryBorders = false;
@Input() alignLeft = false;
@Input() alignRight = false;
@Output() action: EventEmitter<boolean> = new EventEmitter();
@Output() loaded: EventEmitter<boolean> = new EventEmitter();

30
package-lock.json generated
View File

@@ -1039,33 +1039,33 @@
}
},
"@cmf/catalog-api": {
"version": "0.1.26",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/catalog-api/-/catalog-api-0.1.26.tgz",
"integrity": "sha1-3I529t6MTaLpvWd3GUTfKKcFx84=",
"version": "0.1.24",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/catalog-api/-/catalog-api-0.1.24.tgz",
"integrity": "sha1-UJutPTN2kIt0BWZJm6ViXbre7PU=",
"requires": {
"tslib": "^1.9.0"
}
},
"@cmf/core": {
"version": "0.1.26",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/core/-/core-0.1.26.tgz",
"integrity": "sha1-qHkh41QAIUC/NbnDjRMR+uicXyY=",
"version": "0.1.24",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/core/-/core-0.1.24.tgz",
"integrity": "sha1-VikCC0+gVcW2MSt1BODzjlDE5Bw=",
"requires": {
"tslib": "^1.9.0"
}
},
"@cmf/inventory-api": {
"version": "0.1.26",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/inventory-api/-/inventory-api-0.1.26.tgz",
"integrity": "sha1-UP6Fo/ZADXGQPEsFQ9n0tmSXvSE=",
"version": "0.1.24",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/inventory-api/-/inventory-api-0.1.24.tgz",
"integrity": "sha1-HtWtNfsOLGchks2IOL+ZQ2Hv8wQ=",
"requires": {
"tslib": "^1.9.0"
}
},
"@cmf/trade-api": {
"version": "0.1.26",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/trade-api/-/trade-api-0.1.26.tgz",
"integrity": "sha1-JF1sHPIZRwbJMr8lPbqIH2ZdfJc=",
"version": "0.1.24",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@cmf/trade-api/-/trade-api-0.1.24.tgz",
"integrity": "sha1-NVdd17cwWqJMjzPGjZp8BmbSBuM=",
"requires": {
"tslib": "^1.9.0"
}
@@ -1095,9 +1095,9 @@
}
},
"@isa/remission": {
"version": "0.3.7",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@isa/remission/-/remission-0.3.7.tgz",
"integrity": "sha1-2w0FgF/n7jtN87hHSRVKj4OD45E=",
"version": "0.3.2",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/@isa/remission/-/remission-0.3.2.tgz",
"integrity": "sha1-r9vD/L8QNVxPTWR+QBfakeBraA4=",
"requires": {
"tslib": "^1.9.0"
}

View File

@@ -30,14 +30,14 @@
"@angular/pwa": "^0.13.4",
"@angular/router": "~7.2.12",
"@angular/service-worker": "~7.2.12",
"@cmf/catalog-api": "^0.1.26",
"@cmf/core": "^0.1.26",
"@cmf/inventory-api": "^0.1.26",
"@cmf/trade-api": "^0.1.26",
"@cmf/catalog-api": "^0.1.24",
"@cmf/core": "^0.1.24",
"@cmf/inventory-api": "^0.1.24",
"@cmf/trade-api": "^0.1.24",
"@isa/catsearch-api": "^0.0.53",
"@isa/print-api": "0.0.53",
"@isa/remi-api": "^0.0.53",
"@isa/remission": "^0.3.7",
"@isa/remission": "^0.3.2",
"@ng-idle/core": "^8.0.0-beta.4",
"@ng-idle/keepalive": "^8.0.0-beta.4",
"@ngxs/store": "^3.4.1",