chore: prettier write

This commit is contained in:
Lorenz Hilpert
2025-02-24 15:29:32 +01:00
parent eb6149a6e3
commit 3f77646f8a
425 changed files with 4021 additions and 1617 deletions

View File

@@ -1,4 +1,12 @@
import { Component, ChangeDetectionStrategy, ElementRef, ViewChild, NgZone, AfterViewInit, OnDestroy } from '@angular/core';
import {
Component,
ChangeDetectionStrategy,
ElementRef,
ViewChild,
NgZone,
AfterViewInit,
OnDestroy,
} from '@angular/core';
import { BarcodeCapture, BarcodeCaptureSettings, Symbology } from 'scandit-web-datacapture-barcode';
import { Camera, DataCaptureContext, DataCaptureView, FrameSourceState } from 'scandit-web-datacapture-core';

View File

@@ -1,5 +1,16 @@
import { DOCUMENT } from '@angular/common';
import { Component, effect, HostListener, inject, Inject, Injector, OnInit, Renderer2, signal, untracked } from '@angular/core';
import {
Component,
effect,
HostListener,
inject,
Inject,
Injector,
OnInit,
Renderer2,
signal,
untracked,
} from '@angular/core';
import { Title } from '@angular/platform-browser';
import { SwUpdate } from '@angular/service-worker';
import { ApplicationService } from '@core/application';
@@ -121,7 +132,10 @@ export class AppComponent implements OnInit {
}
logVersion() {
console.log(`%c${this._config.get('title')}\r\nVersion: ${packageInfo.version}`, 'font-weight: bold; font-size: 20px;');
console.log(
`%c${this._config.get('title')}\r\nVersion: ${packageInfo.version}`,
'font-weight: bold; font-size: 20px;',
);
}
determinePlatform() {

View File

@@ -40,9 +40,12 @@ export class CreateKubiCustomerCommand extends ActionHandler<Result<CustomerInfo
customerType = 'store';
}
await this._router.navigate(['/kunde', this._application.activatedProcessId, 'customer', 'create', `${customerType}-p4m`], {
await this._router.navigate(
['/kunde', this._application.activatedProcessId, 'customer', 'create', `${customerType}-p4m`],
{
queryParams: { formData },
});
},
);
return data;
}
}

View File

@@ -4,7 +4,10 @@ import { ApplicationService } from '@core/application';
import { Config } from '@core/config';
import { take } from 'rxjs/operators';
export const ActivateProcessIdGuard: CanActivateFn = async (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
export const ActivateProcessIdGuard: CanActivateFn = async (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
) => {
const application = inject(ApplicationService);
const processIdStr = route.params.processId;
@@ -27,10 +30,8 @@ export const ActivateProcessIdGuard: CanActivateFn = async (route: ActivatedRout
return true;
};
export const ActivateProcessIdWithConfigKeyGuard: (key: string) => CanActivateFn = (key) => async (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) => {
export const ActivateProcessIdWithConfigKeyGuard: (key: string) => CanActivateFn =
(key) => async (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
const application = inject(ApplicationService);
const config = inject(Config);

View File

@@ -6,10 +6,16 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivateAssortmentGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _config: Config) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _config: Config,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService.getProcessById$(this._config.get('process.ids.assortment')).pipe(first()).toPromise();
const process = await this._applicationService
.getProcessById$(this._config.get('process.ids.assortment'))
.pipe(first())
.toPromise();
if (!process) {
await this._applicationService.createProcess({
id: this._config.get('process.ids.assortment'),

View File

@@ -8,10 +8,7 @@ export class CanActivateCartWithProcessIdGuard {
constructor(private readonly _applicationService: ApplicationService) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService
.getProcessById$(+route.params.processId)
.pipe(first())
.toPromise();
const process = await this._applicationService.getProcessById$(+route.params.processId).pipe(first()).toPromise();
// if (!(process?.type === 'cart')) {
// // TODO:

View File

@@ -14,7 +14,10 @@ export class CanActivateCartGuard {
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const processes = await this._applicationService.getProcesses$('customer').pipe(first()).toPromise();
let lastActivatedProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart')
.pipe(first())
.toPromise()
)?.id;
if (!lastActivatedProcessId) {
lastActivatedProcessId = Date.now();

View File

@@ -6,13 +6,13 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivateCustomerOrdersWithProcessIdGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _breadcrumbService: BreadcrumbService) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _breadcrumbService: BreadcrumbService,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService
.getProcessById$(+route.params.processId)
.pipe(first())
.toPromise();
const process = await this._applicationService.getProcessById$(+route.params.processId).pipe(first()).toPromise();
if (!process) {
const processes = await this._applicationService.getProcesses$('customer').pipe(first()).toPromise();
@@ -31,10 +31,7 @@ export class CanActivateCustomerOrdersWithProcessIdGuard {
// Fix #3292: Alle Breadcrumbs die nichts mit dem aktuellen Prozess zu tun haben, müssen removed werden
async removeBreadcrumbWithSameProcessId(route: ActivatedRouteSnapshot) {
const crumbs = await this._breadcrumbService
.getBreadcrumbByKey$(+route.params.processId)
.pipe(first())
.toPromise();
const crumbs = await this._breadcrumbService.getBreadcrumbByKey$(+route.params.processId).pipe(first()).toPromise();
// Entferne alle Crumbs die nichts mit den Kundenbestellungen zu tun haben
if (crumbs.length > 1) {

View File

@@ -17,11 +17,17 @@ export class CanActivateCustomerOrdersGuard {
const processes = await this._applicationService.getProcesses$('customer').pipe(first()).toPromise();
let lastActivatedProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart')
.pipe(first())
.toPromise()
)?.id;
const lastActivatedCartCheckoutProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout')
.pipe(first())
.toPromise()
)?.id;
const activatedProcessId = await this._applicationService.getActivatedProcessId$().pipe(first()).toPromise();

View File

@@ -6,13 +6,13 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivateCustomerWithProcessIdGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _breadcrumbService: BreadcrumbService) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _breadcrumbService: BreadcrumbService,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService
.getProcessById$(+route.params.processId)
.pipe(first())
.toPromise();
const process = await this._applicationService.getProcessById$(+route.params.processId).pipe(first()).toPromise();
// if (!(process?.type === 'cart')) {
// // TODO:
@@ -37,10 +37,7 @@ export class CanActivateCustomerWithProcessIdGuard {
// Fix #3292: Alle Breadcrumbs die nichts mit dem aktuellen Prozess zu tun haben, müssen removed werden
async removeBreadcrumbWithSameProcessId(route: ActivatedRouteSnapshot) {
const crumbs = await this._breadcrumbService
.getBreadcrumbByKey$(+route.params.processId)
.pipe(first())
.toPromise();
const crumbs = await this._breadcrumbService.getBreadcrumbByKey$(+route.params.processId).pipe(first()).toPromise();
// Entferne alle Crumbs die nichts mit der Kundensuche zu tun haben
if (crumbs.length > 1) {

View File

@@ -17,15 +17,24 @@ export class CanActivateCustomerGuard {
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const processes = await this._applicationService.getProcesses$('customer').pipe(first()).toPromise();
let lastActivatedProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart')
.pipe(first())
.toPromise()
)?.id;
const lastActivatedCartCheckoutProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout')
.pipe(first())
.toPromise()
)?.id;
const lastActivatedGoodsOutProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'goods-out').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'goods-out')
.pipe(first())
.toPromise()
)?.id;
const activatedProcessId = await this._applicationService.getActivatedProcessId$().pipe(first()).toPromise();

View File

@@ -6,10 +6,16 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivateGoodsInGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _config: Config) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _config: Config,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService.getProcessById$(this._config.get('process.ids.goodsIn')).pipe(first()).toPromise();
const process = await this._applicationService
.getProcessById$(this._config.get('process.ids.goodsIn'))
.pipe(first())
.toPromise();
if (!process) {
await this._applicationService.createProcess({
id: this._config.get('process.ids.goodsIn'),

View File

@@ -6,13 +6,13 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivateGoodsOutWithProcessIdGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _breadcrumbService: BreadcrumbService) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _breadcrumbService: BreadcrumbService,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService
.getProcessById$(+route.params.processId)
.pipe(first())
.toPromise();
const process = await this._applicationService.getProcessById$(+route.params.processId).pipe(first()).toPromise();
if (!process) {
// const processes = await this._applicationService.getProcesses$('customer').pipe(first()).toPromise();
@@ -31,10 +31,7 @@ export class CanActivateGoodsOutWithProcessIdGuard {
// Fix #3292: Alle Breadcrumbs die nichts mit dem aktuellen Prozess zu tun haben, müssen removed werden
async removeBreadcrumbWithSameProcessId(route: ActivatedRouteSnapshot) {
const crumbs = await this._breadcrumbService
.getBreadcrumbByKey$(+route.params.processId)
.pipe(first())
.toPromise();
const crumbs = await this._breadcrumbService.getBreadcrumbByKey$(+route.params.processId).pipe(first()).toPromise();
// Entferne alle Crumbs die nichts mit der Warenausgabe zu tun haben
if (crumbs.length > 1) {

View File

@@ -9,7 +9,7 @@ export class CanActivateGoodsOutGuard {
constructor(
private readonly _applicationService: ApplicationService,
private readonly _checkoutService: DomainCheckoutService,
private readonly _router: Router
private readonly _router: Router,
) {}
// !!! Ticket #3272 Code soll vorerst bestehen bleiben. Prozess Warenausgabe soll wieder Vorgang heißen (wie aktuell im Produktiv), bis zum neuen Navigationskonzept
@@ -103,11 +103,17 @@ export class CanActivateGoodsOutGuard {
const processes = await this._applicationService.getProcesses$('customer').pipe(first()).toPromise();
let lastActivatedProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart')
.pipe(first())
.toPromise()
)?.id;
const lastActivatedCartCheckoutProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout')
.pipe(first())
.toPromise()
)?.id;
const activatedProcessId = await this._applicationService.getActivatedProcessId$().pipe(first()).toPromise();

View File

@@ -6,7 +6,10 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivatePackageInspectionGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _config: Config) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _config: Config,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService

View File

@@ -6,13 +6,13 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivateProductWithProcessIdGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _breadcrumbService: BreadcrumbService) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _breadcrumbService: BreadcrumbService,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService
.getProcessById$(+route.params.processId)
.pipe(first())
.toPromise();
const process = await this._applicationService.getProcessById$(+route.params.processId).pipe(first()).toPromise();
// if (!(process?.type === 'cart')) {
// // TODO:
@@ -37,10 +37,7 @@ export class CanActivateProductWithProcessIdGuard {
// Fix #3292: Alle Breadcrumbs die nichts mit dem aktuellen Prozess zu tun haben, müssen removed werden
async removeBreadcrumbWithSameProcessId(route: ActivatedRouteSnapshot) {
const crumbs = await this._breadcrumbService
.getBreadcrumbByKey$(+route.params.processId)
.pipe(first())
.toPromise();
const crumbs = await this._breadcrumbService.getBreadcrumbByKey$(+route.params.processId).pipe(first()).toPromise();
// Entferne alle Crumbs die nichts mit der Artikelsuche zu tun haben
if (crumbs.length > 1) {

View File

@@ -16,15 +16,24 @@ export class CanActivateProductGuard {
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const processes = await this._applicationService.getProcesses$('customer').pipe(first()).toPromise();
let lastActivatedProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart')
.pipe(first())
.toPromise()
)?.id;
const lastActivatedCartCheckoutProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'cart-checkout')
.pipe(first())
.toPromise()
)?.id;
const lastActivatedGoodsOutProcessId = (
await this._applicationService.getLastActivatedProcessWithSectionAndType$('customer', 'goods-out').pipe(first()).toPromise()
await this._applicationService
.getLastActivatedProcessWithSectionAndType$('customer', 'goods-out')
.pipe(first())
.toPromise()
)?.id;
const activatedProcessId = await this._applicationService.getActivatedProcessId$().pipe(first()).toPromise();

View File

@@ -9,11 +9,14 @@ export class CanActivateRemissionGuard {
constructor(
private readonly _applicationService: ApplicationService,
private readonly _config: Config,
private readonly _router: Router
private readonly _router: Router,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService.getProcessById$(this._config.get('process.ids.remission')).pipe(first()).toPromise();
const process = await this._applicationService
.getProcessById$(this._config.get('process.ids.remission'))
.pipe(first())
.toPromise();
if (!process) {
await this._applicationService.createProcess({
id: this._config.get('process.ids.remission'),

View File

@@ -6,10 +6,16 @@ import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CanActivateTaskCalendarGuard {
constructor(private readonly _applicationService: ApplicationService, private readonly _config: Config) {}
constructor(
private readonly _applicationService: ApplicationService,
private readonly _config: Config,
) {}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const process = await this._applicationService.getProcessById$(this._config.get('process.ids.taskCalendar')).pipe(first()).toPromise();
const process = await this._applicationService
.getProcessById$(this._config.get('process.ids.taskCalendar'))
.pipe(first())
.toPromise();
if (!process) {
await this._applicationService.createProcess({
id: this._config.get('process.ids.taskCalendar'),

View File

@@ -5,7 +5,7 @@ import { take } from 'rxjs/operators';
export const ProcessIdGuard: CanActivateFn = async (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
state: RouterStateSnapshot,
): Promise<boolean | UrlTree> => {
const application = inject(ApplicationService);
const router = inject(Router);

View File

@@ -4,7 +4,10 @@ import { ApplicationService } from '@core/application';
import { Observable } from 'rxjs';
export abstract class SectionResolver {
constructor(protected section: 'customer' | 'branch', protected applicationService: ApplicationService) {}
constructor(
protected section: 'customer' | 'branch',
protected applicationService: ApplicationService,
) {}
resolve(route: ActivatedRouteSnapshot): Observable<string> | Promise<string> | string {
this.applicationService.setSection(this.section);

View File

@@ -43,7 +43,11 @@ export class RootStateService {
takeUntil(this._cancelSave),
debounceTime(1000),
switchMap((state) => {
const raw = JSON.stringify({ ...state, version: packageInfo.version, sub: this._authService.getClaimByKey('sub') });
const raw = JSON.stringify({
...state,
version: packageInfo.version,
sub: this._authService.getClaimByKey('sub'),
});
RootStateService.SaveToLocalStorageRaw(raw);
return this._userStateService.UserStateSetUserState({ content: raw });
}),

View File

@@ -1,219 +1,222 @@
/* cyrillic-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-cyrillic-ext1.woff2') format('woff2');
src: url("./Open_Sans-400-cyrillic-ext1.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-cyrillic2.woff2') format('woff2');
src: url("./Open_Sans-400-cyrillic2.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-greek-ext3.woff2') format('woff2');
src: url("./Open_Sans-400-greek-ext3.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-greek4.woff2') format('woff2');
src: url("./Open_Sans-400-greek4.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* hebrew */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-hebrew5.woff2') format('woff2');
src: url("./Open_Sans-400-hebrew5.woff2") format("woff2");
unicode-range: U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* vietnamese */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-vietnamese6.woff2') format('woff2');
src: url("./Open_Sans-400-vietnamese6.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-latin-ext7.woff2') format('woff2');
src: url("./Open_Sans-400-latin-ext7.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
font-stretch: normal;
src: url('./Open_Sans-400-latin8.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
U+2212, U+2215, U+FEFF, U+FFFD;
src: url("./Open_Sans-400-latin8.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-cyrillic-ext9.woff2') format('woff2');
src: url("./Open_Sans-600-cyrillic-ext9.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-cyrillic10.woff2') format('woff2');
src: url("./Open_Sans-600-cyrillic10.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-greek-ext11.woff2') format('woff2');
src: url("./Open_Sans-600-greek-ext11.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-greek12.woff2') format('woff2');
src: url("./Open_Sans-600-greek12.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* hebrew */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-hebrew13.woff2') format('woff2');
src: url("./Open_Sans-600-hebrew13.woff2") format("woff2");
unicode-range: U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* vietnamese */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-vietnamese14.woff2') format('woff2');
src: url("./Open_Sans-600-vietnamese14.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-latin-ext15.woff2') format('woff2');
src: url("./Open_Sans-600-latin-ext15.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 600;
font-stretch: normal;
src: url('./Open_Sans-600-latin16.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
U+2212, U+2215, U+FEFF, U+FFFD;
src: url("./Open_Sans-600-latin16.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-cyrillic-ext17.woff2') format('woff2');
src: url("./Open_Sans-700-cyrillic-ext17.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-cyrillic18.woff2') format('woff2');
src: url("./Open_Sans-700-cyrillic18.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-greek-ext19.woff2') format('woff2');
src: url("./Open_Sans-700-greek-ext19.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-greek20.woff2') format('woff2');
src: url("./Open_Sans-700-greek20.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* hebrew */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-hebrew21.woff2') format('woff2');
src: url("./Open_Sans-700-hebrew21.woff2") format("woff2");
unicode-range: U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* vietnamese */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-vietnamese22.woff2') format('woff2');
src: url("./Open_Sans-700-vietnamese22.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-latin-ext23.woff2') format('woff2');
src: url("./Open_Sans-700-latin-ext23.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Open Sans';
font-family: "Open Sans";
font-style: normal;
font-weight: 700;
font-stretch: normal;
src: url('./Open_Sans-700-latin24.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
U+2212, U+2215, U+FEFF, U+FFFD;
src: url("./Open_Sans-700-latin24.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@@ -35,7 +35,9 @@ export class ApplicationService {
getProcesses$(section?: 'customer' | 'branch') {
const processes$ = this.store.select(selectProcesses);
return processes$.pipe(map((processes) => processes.filter((process) => (section ? process.section === section : true))));
return processes$.pipe(
map((processes) => processes.filter((process) => (section ? process.section === section : true))),
);
}
getProcessById$(processId: number): Observable<ApplicationProcess> {
@@ -135,7 +137,10 @@ export class ApplicationService {
this.store.dispatch(setSection({ section }));
}
getLastActivatedProcessWithSectionAndType$(section: 'customer' | 'branch', type: string): Observable<ApplicationProcess> {
getLastActivatedProcessWithSectionAndType$(
section: 'customer' | 'branch',
type: string,
): Observable<ApplicationProcess> {
return this.getProcesses$(section).pipe(
map((processes) =>
processes

View File

@@ -11,8 +11,17 @@ export const addProcess = createAction(`${prefix} Add Process`, props<{ process:
export const removeProcess = createAction(`${prefix} Remove Process`, props<{ processId: number }>());
export const setActivatedProcess = createAction(`${prefix} Set Activated Process`, props<{ activatedProcessId: number }>());
export const setActivatedProcess = createAction(
`${prefix} Set Activated Process`,
props<{ activatedProcessId: number }>(),
);
export const patchProcess = createAction(`${prefix} Patch Process`, props<{ processId: number; changes: Partial<ApplicationProcess> }>());
export const patchProcess = createAction(
`${prefix} Patch Process`,
props<{ processId: number; changes: Partial<ApplicationProcess> }>(),
);
export const patchProcessData = createAction(`${prefix} Patch Process Data`, props<{ processId: number; data: Record<string, any> }>());
export const patchProcessData = createAction(
`${prefix} Patch Process Data`,
props<{ processId: number; data: Record<string, any> }>(),
);

View File

@@ -120,7 +120,10 @@ export class BreadcrumbService {
if (recursive) {
const breadcrumbs = await this.getBreadcrumbByKey$(breadcrumb.key).pipe(take(1)).toPromise();
breadcrumbsToRemove = [...breadcrumbsToRemove, ...breadcrumbs.filter((crumb) => crumb.timestamp > breadcrumb.timestamp)];
breadcrumbsToRemove = [
...breadcrumbsToRemove,
...breadcrumbs.filter((crumb) => crumb.timestamp > breadcrumb.timestamp),
];
}
if (!breadcrumbsToRemove.length) {
@@ -135,7 +138,10 @@ export class BreadcrumbService {
crumbs.forEach((crumb) => this.removeBreadcrumb(crumb.id));
}
getLatestBreadcrumbForSection(section: 'customer' | 'branch', predicate: (crumb: Breadcrumb) => boolean = (_) => true) {
getLatestBreadcrumbForSection(
section: 'customer' | 'branch',
predicate: (crumb: Breadcrumb) => boolean = (_) => true,
) {
return this.store
.select(selectors.selectBreadcrumbsBySection, { section })
.pipe(map((crumbs) => crumbs.sort((a, b) => b.timestamp - a.timestamp).find((f) => predicate(f))));

View File

@@ -11,7 +11,10 @@ export const addBreadcrumb = createAction(`${prefix} Add Breadcrumb`, props<{ br
/**
* Action um Breadcrumb im State zu ändern
*/
export const updateBreadcrumb = createAction(`${prefix} Update Breadcrumb`, props<{ id: number; changes: Partial<Breadcrumb> }>());
export const updateBreadcrumb = createAction(
`${prefix} Update Breadcrumb`,
props<{ id: number; changes: Partial<Breadcrumb> }>(),
);
/**
* Action um Breadcrumb im State zu entfernen

View File

@@ -43,7 +43,10 @@ describe('Breadcrumb Reducer', () => {
const state = breadcrumbReducer(INIT, action.addBreadcrumb({ breadcrumb }));
const fixture = breadcrumbReducer(state, action.updateBreadcrumb({ id: breadcrumb.id, changes: { name: 'Test Name 2' } }));
const fixture = breadcrumbReducer(
state,
action.updateBreadcrumb({ id: breadcrumb.id, changes: { name: 'Test Name 2' } }),
);
expect(fixture.entities[breadcrumb.id]).toEqual(expected);
});

View File

@@ -10,26 +10,46 @@ describe('Breadcrumb Selectors', () => {
beforeEach(() => {
state = breadcrumbReducer(
INIT,
action.addBreadcrumb({ breadcrumb: { id: 1, key: 'unit-test-1', path: '', name: 'Unit Test 1', section: 'customer' } }),
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({
breadcrumb: { id: 2, key: 'unit-test-1', path: '', name: 'Unit Test 1', tags: ['details'], section: 'customer' },
breadcrumb: { id: 1, key: 'unit-test-1', path: '', name: 'Unit Test 1', section: 'customer' },
}),
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({ breadcrumb: { id: 3, key: 'unit-test-2', path: '', name: 'Unit Test 1', section: 'customer' } }),
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({ breadcrumb: { id: 4, key: 'unit-test-3', path: '', name: 'Unit Test 1', section: 'customer' } }),
action.addBreadcrumb({
breadcrumb: {
id: 2,
key: 'unit-test-1',
path: '',
name: 'Unit Test 1',
tags: ['details'],
section: 'customer',
},
}),
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({
breadcrumb: { id: 5, key: 'unit-test-3', path: '', name: 'Unit Test 1', tags: ['details'], section: 'customer' },
breadcrumb: { id: 3, key: 'unit-test-2', path: '', name: 'Unit Test 1', section: 'customer' },
}),
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({
breadcrumb: { id: 4, key: 'unit-test-3', path: '', name: 'Unit Test 1', section: 'customer' },
}),
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({
breadcrumb: {
id: 5,
key: 'unit-test-3',
path: '',
name: 'Unit Test 1',
tags: ['details'],
section: 'customer',
},
}),
);
});

View File

@@ -20,7 +20,9 @@ export const selectBreadcrumbById = createSelector(selectEntities, (entities, id
/**
* Gibt alle Breadcrumb Entities als Array zurück die den key enthalten
*/
export const selectBreadcrumbsByKey = createSelector(selectAll, (entities, key: string) => entities.filter((crumb) => crumb.key == key));
export const selectBreadcrumbsByKey = createSelector(selectAll, (entities, key: string) =>
entities.filter((crumb) => crumb.key == key),
);
/**
* Gibt alle Breadcrumb Entities als Array zurück die den key und tag enthalten
@@ -37,12 +39,15 @@ export const selectBreadcrumbsByKeyAndTag = createSelector(
export const selectBreadcrumbsByKeyAndTags = createSelector(
selectAll,
(entities: Breadcrumb[], { key, tags }: { key: string; tags: string[] }) =>
entities.filter((crumb) => crumb.key == key && isArray(crumb.tags) && tags.every((tag) => crumb.tags.includes(tag))),
entities.filter(
(crumb) => crumb.key == key && isArray(crumb.tags) && tags.every((tag) => crumb.tags.includes(tag)),
),
);
/**
* Gibt alle Breadcrumb Entities als Array zurück die die tags enthalten
*/
export const selectBreadcrumbsBySection = createSelector(selectAll, (entities: Breadcrumb[], { section }: { section: string }) =>
entities.filter((crumb) => crumb.section === section),
export const selectBreadcrumbsBySection = createSelector(
selectAll,
(entities: Breadcrumb[], { section }: { section: string }) => entities.filter((crumb) => crumb.section === section),
);

View File

@@ -4,7 +4,10 @@ import { CommandService } from './command.service';
import { FEATURE_ACTION_HANDLERS, ROOT_ACTION_HANDLERS } from './tokens';
export function provideActionHandlers(actionHandlers: Type<ActionHandler>[]): Provider[] {
return [CommandService, actionHandlers.map((handler) => ({ provide: FEATURE_ACTION_HANDLERS, useClass: handler, multi: true }))];
return [
CommandService,
actionHandlers.map((handler) => ({ provide: FEATURE_ACTION_HANDLERS, useClass: handler, multi: true })),
];
}
@NgModule({})
@@ -12,14 +15,20 @@ export class CoreCommandModule {
static forRoot(actionHandlers: Type<ActionHandler>[]): ModuleWithProviders<CoreCommandModule> {
return {
ngModule: CoreCommandModule,
providers: [CommandService, actionHandlers.map((handler) => ({ provide: ROOT_ACTION_HANDLERS, useClass: handler, multi: true }))],
providers: [
CommandService,
actionHandlers.map((handler) => ({ provide: ROOT_ACTION_HANDLERS, useClass: handler, multi: true })),
],
};
}
static forChild(actionHandlers: Type<ActionHandler>[]): ModuleWithProviders<CoreCommandModule> {
return {
ngModule: CoreCommandModule,
providers: [CommandService, actionHandlers.map((handler) => ({ provide: FEATURE_ACTION_HANDLERS, useClass: handler, multi: true }))],
providers: [
CommandService,
actionHandlers.map((handler) => ({ provide: FEATURE_ACTION_HANDLERS, useClass: handler, multi: true })),
],
};
}
}

View File

@@ -21,7 +21,9 @@ export class ConfigModule {
providers: [
Config,
configLoaderProvider,
options.jsonConfigLoaderUrl ? { provide: CORE_JSON_CONFIG_LOADER_URL, useValue: options.jsonConfigLoaderUrl } : null,
options.jsonConfigLoaderUrl
? { provide: CORE_JSON_CONFIG_LOADER_URL, useValue: options.jsonConfigLoaderUrl }
: null,
],
};
}

View File

@@ -19,7 +19,12 @@ import { AvailabilityDTO as CatAvailabilityDTO } from '@generated/swagger/cat-se
import { map, shareReplay, switchMap, withLatestFrom, mergeMap, timeout, first } from 'rxjs/operators';
import { isArray, memorize } from '@utils/common';
import { LogisticianDTO, LogisticianService } from '@generated/swagger/oms-api';
import { ResponseArgsOfIEnumerableOfStockInfoDTO, StockDTO, StockInfoDTO, StockService } from '@generated/swagger/inventory-api';
import {
ResponseArgsOfIEnumerableOfStockInfoDTO,
StockDTO,
StockInfoDTO,
StockService,
} from '@generated/swagger/inventory-api';
import { PriceDTO } from '@generated/swagger/availability-api';
import { AvailabilityByBranchDTO, ItemData, Ssc } from './defs';
import { Availability } from './defs/availability';
@@ -171,7 +176,13 @@ export class DomainAvailabilityService {
),
map(([response, supplier, defaultBranch]) => {
const price = item?.price;
return this._mapToTakeAwayAvailability({ response, supplier, branchId: branch?.id ?? defaultBranch?.id, quantity, price });
return this._mapToTakeAwayAvailability({
response,
supplier,
branchId: branch?.id ?? defaultBranch?.id,
quantity,
price,
});
}),
shareReplay(1),
);
@@ -216,7 +227,13 @@ export class DomainAvailabilityService {
switchMap((s) => this._stockService.StockInStockByEAN({ eans, stockId: s.id })),
withLatestFrom(this.getTakeAwaySupplier(), this.getDefaultBranch()),
map(([response, supplier, defaultBranch]) => {
return this._mapToTakeAwayAvailability({ response, supplier, branchId: branchId ?? defaultBranch.id, quantity, price });
return this._mapToTakeAwayAvailability({
response,
supplier,
branchId: branchId ?? defaultBranch.id,
quantity,
price,
});
}),
shareReplay(1),
);
@@ -329,7 +346,10 @@ export class DomainAvailabilityService {
this.getPickUpAvailability({ item, quantity, branch: branch ?? defaultBranch }).pipe(
mergeMap((availability) =>
logistician$.pipe(
map((logistician) => ({ ...(availability?.length > 0 ? availability[0] : []), logistician: { id: logistician.id } })),
map((logistician) => ({
...(availability?.length > 0 ? availability[0] : []),
logistician: { id: logistician.id },
})),
),
),
shareReplay(1),
@@ -427,7 +447,9 @@ export class DomainAvailabilityService {
return this.getPickUpAvailabilities(payload, true).pipe(
timeout(20000),
switchMap((availability) =>
logistician$.pipe(map((logistician) => ({ availability: [...availability], logistician: { id: logistician.id } }))),
logistician$.pipe(
map((logistician) => ({ availability: [...availability], logistician: { id: logistician.id } })),
),
),
shareReplay(1),
);
@@ -512,7 +534,9 @@ export class DomainAvailabilityService {
return availability;
}
private _mapToPickUpAvailability(availabilities: SwaggerAvailabilityDTO[]): Availability<AvailabilityDTO, SwaggerAvailabilityDTO>[] {
private _mapToPickUpAvailability(
availabilities: SwaggerAvailabilityDTO[],
): Availability<AvailabilityDTO, SwaggerAvailabilityDTO>[] {
if (isArray(availabilities)) {
const preferred = availabilities.filter((f) => f.preferred === 1);
const totalAvailable = availabilities.reduce((sum, av) => sum + (av?.qty || 0), 0);
@@ -572,7 +596,9 @@ export class DomainAvailabilityService {
}
const stock$ = branchId$.pipe(
mergeMap((branchId) => this._stockService.StockGetStocksByBranch({ branchId }).pipe(map((response) => response.result?.[0]))),
mergeMap((branchId) =>
this._stockService.StockGetStocksByBranch({ branchId }).pipe(map((response) => response.result?.[0])),
),
);
return stock$.pipe(
@@ -598,7 +624,9 @@ export class DomainAvailabilityService {
getInStock({ itemIds, branchId }: { itemIds: number[]; branchId: number }): Observable<StockInfoDTO[]> {
return this.getStockByBranch(branchId).pipe(
mergeMap((stock) =>
this._stockService.StockInStock({ articleIds: itemIds, stockId: stock.id }).pipe(map((response) => response.result)),
this._stockService
.StockInStock({ articleIds: itemIds, stockId: stock.id })
.pipe(map((response) => response.result)),
),
);
}

View File

@@ -90,10 +90,15 @@ export class DomainInStockService {
const grouped = groupBy(itemBranchData, 'branchId');
Object.keys(grouped).forEach((key) => {
const branchId = Number(key);
const itemIds = itemBranchData.filter((itemBranch) => itemBranch.branchId === branchId).map((item) => item.itemId);
const itemIds = itemBranchData
.filter((itemBranch) => itemBranch.branchId === branchId)
.map((item) => item.itemId);
this._availability
.getInStock({ itemIds, branchId })
.subscribe(this._fetchStockDataResponse({ itemIds, branchId }), this._fetchStockDataError({ itemIds, branchId }));
.subscribe(
this._fetchStockDataResponse({ itemIds, branchId }),
this._fetchStockDataError({ itemIds, branchId }),
);
});
}
@@ -101,7 +106,9 @@ export class DomainInStockService {
({ itemIds, branchId }: { itemIds: number[]; branchId: number }) =>
(stockInfos: StockInfoDTO[]) => {
itemIds.forEach((itemId) => {
const stockInfo = stockInfos.find((stockInfo) => stockInfo.itemId === itemId && stockInfo.branchId === branchId);
const stockInfo = stockInfos.find(
(stockInfo) => stockInfo.itemId === itemId && stockInfo.branchId === branchId,
);
let inStock = 0;
if (stockInfo?.inStock) {

View File

@@ -1,6 +1,11 @@
import { Injectable } from '@angular/core';
import { ApplicationService } from '@core/application';
import { AutocompleteTokenDTO, PromotionService, QueryTokenDTO, SearchService } from '@generated/swagger/cat-search-api';
import {
AutocompleteTokenDTO,
PromotionService,
QueryTokenDTO,
SearchService,
} from '@generated/swagger/cat-search-api';
import { memorize } from '@utils/common';
import { map, share, shareReplay } from 'rxjs/operators';

View File

@@ -21,6 +21,9 @@ export class DomainCheckoutModule {
}
@NgModule({
imports: [StoreModule.forFeature(storeFeatureName, domainCheckoutReducer), EffectsModule.forFeature([DomainCheckoutEffects])],
imports: [
StoreModule.forFeature(storeFeatureName, domainCheckoutReducer),
EffectsModule.forFeature([DomainCheckoutEffects]),
],
})
export class RootDomainCheckoutModule {}

View File

@@ -135,7 +135,13 @@ export class DomainCheckoutService {
);
}
addItemToShoppingCart({ processId, items }: { processId: number; items: AddToShoppingCartDTO[] }): Observable<ShoppingCartDTO> {
addItemToShoppingCart({
processId,
items,
}: {
processId: number;
items: AddToShoppingCartDTO[];
}): Observable<ShoppingCartDTO> {
return this.getShoppingCart({ processId }).pipe(
first(),
mergeMap((cart) =>
@@ -488,7 +494,11 @@ export class DomainCheckoutService {
checkAvailabilities({ processId }: { processId: number }): Observable<any> {
const shoppingCart$ = this.getShoppingCart({ processId }).pipe(first());
const itemsToCheck$ = shoppingCart$.pipe(
map((cart) => cart?.items?.filter((item) => item?.data?.features?.orderType === 'Download' && !item.data.availability.lastRequest)),
map((cart) =>
cart?.items?.filter(
(item) => item?.data?.features?.orderType === 'Download' && !item.data.availability.lastRequest,
),
),
);
return itemsToCheck$.pipe(
@@ -537,7 +547,8 @@ export class DomainCheckoutService {
const itemsToUpdate$ = shoppingCart$.pipe(
map((cart) =>
cart?.items?.filter(
(item) => item?.data?.features?.orderType === 'DIG-Versand' || item?.data?.features?.orderType === 'B2B-Versand',
(item) =>
item?.data?.features?.orderType === 'DIG-Versand' || item?.data?.features?.orderType === 'B2B-Versand',
),
),
);
@@ -770,7 +781,9 @@ export class DomainCheckoutService {
const availabilities$ = this.validateAvailabilities({ processId });
return combineLatest([olaStatus$, availabilities$]).pipe(map(([olaStatus, availabilities]) => olaStatus && availabilities));
return combineLatest([olaStatus$, availabilities$]).pipe(
map(([olaStatus, availabilities]) => olaStatus && availabilities),
);
}
completeCheckout({ processId }: { processId: number }): Observable<DisplayOrderDTO[]> {
@@ -871,7 +884,8 @@ export class DomainCheckoutService {
const setPaymentType$ = itemOrderOptions$.pipe(
mergeMap(({ hasDownload, hasDelivery, hasDigDelivery, hasB2BDelivery }) => {
const paymentType = hasDownload || hasDelivery || hasDigDelivery || hasB2BDelivery ? 128 /* Rechnung */ : 4; /* Bar */
const paymentType =
hasDownload || hasDelivery || hasDigDelivery || hasB2BDelivery ? 128 /* Rechnung */ : 4; /* Bar */
return this.setPayment({ processId, paymentType });
}),
shareReplay(),
@@ -1057,7 +1071,13 @@ export class DomainCheckoutService {
.pipe(shareReplay(1));
}
setNotificationChannels({ processId, notificationChannels }: { processId: number; notificationChannels: NotificationChannel }): void {
setNotificationChannels({
processId,
notificationChannels,
}: {
processId: number;
notificationChannels: NotificationChannel;
}): void {
this.store.dispatch(DomainCheckoutActions.setNotificationChannels({ processId, notificationChannels }));
}
@@ -1065,7 +1085,15 @@ export class DomainCheckoutService {
return this.store.select(DomainCheckoutSelectors.selectNotificationChannels, { processId });
}
setBuyerCommunicationDetails({ processId, mobile, email }: { processId: number; mobile?: string; email?: string }): void {
setBuyerCommunicationDetails({
processId,
mobile,
email,
}: {
processId: number;
mobile?: string;
email?: string;
}): void {
this.store.dispatch(DomainCheckoutActions.setBuyerCommunicationDetails({ processId, mobile, email }));
}
@@ -1125,7 +1153,11 @@ export class DomainCheckoutService {
.pipe(
map((r) => {
return r.result.filter(
(branch) => branch.status === 1 && branch.branchType === 1 && branch.isOnline === true && branch.isShippingEnabled === true,
(branch) =>
branch.status === 1 &&
branch.branchType === 1 &&
branch.isOnline === true &&
branch.isShippingEnabled === true,
);
}),
shareReplay(),

View File

@@ -14,9 +14,15 @@ import { DisplayOrderDTO, DisplayOrderItemDTO } from '@generated/swagger/oms-api
const prefix = '[DOMAIN-CHECKOUT]';
export const setShoppingCart = createAction(`${prefix} Set Shopping Cart`, props<{ processId: number; shoppingCart: ShoppingCartDTO }>());
export const setShoppingCart = createAction(
`${prefix} Set Shopping Cart`,
props<{ processId: number; shoppingCart: ShoppingCartDTO }>(),
);
export const setCheckout = createAction(`${prefix} Set Checkout`, props<{ processId: number; checkout: CheckoutDTO }>());
export const setCheckout = createAction(
`${prefix} Set Checkout`,
props<{ processId: number; checkout: CheckoutDTO }>(),
);
export const setNotificationChannels = createAction(
`${prefix} Set Notification Channel`,
@@ -45,7 +51,10 @@ export const setShippingAddress = createAction(
props<{ processId: number; shippingAddress: ShippingAddressDTO }>(),
);
export const removeCheckoutWithProcessId = createAction(`${prefix} Remove Checkout With Process Id`, props<{ processId: number }>());
export const removeCheckoutWithProcessId = createAction(
`${prefix} Remove Checkout With Process Id`,
props<{ processId: number }>(),
);
export const setOrders = createAction(`${prefix} Add Orders`, props<{ orders: DisplayOrderDTO[] }>());
@@ -57,11 +66,20 @@ export const setBuyer = createAction(`${prefix} Set Buyer`, props<{ processId: n
export const setPayer = createAction(`${prefix} Set Payer`, props<{ processId: number; payer: PayerDTO }>());
export const setSpecialComment = createAction(`${prefix} Set Agent Comment`, props<{ processId: number; agentComment: string }>());
export const setSpecialComment = createAction(
`${prefix} Set Agent Comment`,
props<{ processId: number; agentComment: string }>(),
);
export const setOlaError = createAction(`${prefix} Set Ola Error`, props<{ processId: number; olaErrorIds: number[] }>());
export const setOlaError = createAction(
`${prefix} Set Ola Error`,
props<{ processId: number; olaErrorIds: number[] }>(),
);
export const setCustomer = createAction(`${prefix} Set Customer`, props<{ processId: number; customer: CustomerDTO }>());
export const setCustomer = createAction(
`${prefix} Set Customer`,
props<{ processId: number; customer: CustomerDTO }>(),
);
export const addShoppingCartItemAvailabilityToHistory = createAction(
`${prefix} Add Shopping Cart Item Availability To History`,

View File

@@ -12,7 +12,9 @@ const _domainCheckoutReducer = createReducer(
const entity = getOrCreateCheckoutEntity({ processId, entities: s.entities });
const addedShoppingCartItems =
shoppingCart?.items?.filter((item) => !entity.shoppingCart?.items?.find((i) => i.id === item.id))?.map((item) => item.data) ?? [];
shoppingCart?.items
?.filter((item) => !entity.shoppingCart?.items?.find((i) => i.id === item.id))
?.map((item) => item.data) ?? [];
entity.shoppingCart = shoppingCart;
@@ -118,10 +120,14 @@ const _domainCheckoutReducer = createReducer(
entity.customer = customer;
return storeCheckoutAdapter.setOne(entity, s);
}),
on(DomainCheckoutActions.addShoppingCartItemAvailabilityToHistory, (s, { processId, shoppingCartItemId, availability }) => {
on(
DomainCheckoutActions.addShoppingCartItemAvailabilityToHistory,
(s, { processId, shoppingCartItemId, availability }) => {
const entity = getOrCreateCheckoutEntity({ processId, entities: s.entities });
const itemAvailabilityTimestamp = entity?.itemAvailabilityTimestamp ? { ...entity?.itemAvailabilityTimestamp } : {};
const itemAvailabilityTimestamp = entity?.itemAvailabilityTimestamp
? { ...entity?.itemAvailabilityTimestamp }
: {};
const item = entity?.shoppingCart?.items?.find((i) => i.id === shoppingCartItemId)?.data;
@@ -132,13 +138,16 @@ const _domainCheckoutReducer = createReducer(
entity.itemAvailabilityTimestamp = itemAvailabilityTimestamp;
return storeCheckoutAdapter.setOne(entity, s);
}),
},
),
on(
DomainCheckoutActions.addShoppingCartItemAvailabilityToHistoryByShoppingCartId,
(s, { shoppingCartId, shoppingCartItemId, availability }) => {
const entity = getCheckoutEntityByShoppingCartId({ shoppingCartId, entities: s.entities });
const itemAvailabilityTimestamp = entity?.itemAvailabilityTimestamp ? { ...entity?.itemAvailabilityTimestamp } : {};
const itemAvailabilityTimestamp = entity?.itemAvailabilityTimestamp
? { ...entity?.itemAvailabilityTimestamp }
: {};
const item = entity?.shoppingCart?.items?.find((i) => i.id === shoppingCartItemId)?.data;
@@ -157,7 +166,13 @@ export function domainCheckoutReducer(state, action) {
return _domainCheckoutReducer(state, action);
}
function getOrCreateCheckoutEntity({ entities, processId }: { entities: Dictionary<CheckoutEntity>; processId: number }): CheckoutEntity {
function getOrCreateCheckoutEntity({
entities,
processId,
}: {
entities: Dictionary<CheckoutEntity>;
processId: number;
}): CheckoutEntity {
let entity = entities[processId];
if (isNullOrUndefined(entity)) {

View File

@@ -23,7 +23,8 @@ export const selectCheckoutByProcessId = createSelector(
export const selectCustomerFeaturesByProcessId = createSelector(
selectEntities,
(entities: Dictionary<CheckoutEntity>, { processId }: { processId: number }) => getCusomterFeatures(entities[processId]?.customer),
(entities: Dictionary<CheckoutEntity>, { processId }: { processId: number }) =>
getCusomterFeatures(entities[processId]?.customer),
);
export const selectShippingAddressByProcessId = createSelector(
@@ -48,12 +49,14 @@ export const selectSpecialComment = createSelector(
export const selectNotificationChannels = createSelector(
selectEntities,
(entities: Dictionary<CheckoutEntity>, { processId }: { processId: number }) => entities[processId]?.notificationChannels,
(entities: Dictionary<CheckoutEntity>, { processId }: { processId: number }) =>
entities[processId]?.notificationChannels,
);
export const selectBuyerCommunicationDetails = createSelector(
selectEntities,
(entities: Dictionary<CheckoutEntity>, { processId }: { processId: number }) => entities[processId]?.buyer?.communicationDetails,
(entities: Dictionary<CheckoutEntity>, { processId }: { processId: number }) =>
entities[processId]?.buyer?.communicationDetails,
);
export const selectOrders = createSelector(storeFeatureSelector, (s) => s.orders);

View File

@@ -226,7 +226,13 @@ export class CrmCustomerService {
}
async updateToOnlineCustomer(customer: CustomerDTO): Promise<Result<CustomerDTO>> {
const payload: CustomerDTO = { shippingAddresses: [], payers: [], ...customer, customerType: 8, hasOnlineAccount: true };
const payload: CustomerDTO = {
shippingAddresses: [],
payers: [],
...customer,
customerType: 8,
hasOnlineAccount: true,
};
const notificationChannels = this.getNotificationChannelForCommunicationDetails({
communicationDetails: payload?.communicationDetails,
@@ -466,18 +472,27 @@ export class CrmCustomerService {
return this.loyaltyCardService.LoyaltyCardCheckLoyaltyCard({ loyaltyCardNumber, customerId });
}
createPayer(customerId: number, payer: PayerDTO, isDefault?: boolean): Promise<[Result<PayerDTO>, Result<AssignedPayerDTO>]> {
createPayer(
customerId: number,
payer: PayerDTO,
isDefault?: boolean,
): Promise<[Result<PayerDTO>, Result<AssignedPayerDTO>]> {
return this.getCustomer(customerId)
.pipe(
mergeMap((customerResponse) =>
this.payerService
.PayerCreatePayer({ ...payer, payerType: customerResponse.result.customerType })
.pipe(
this.payerService.PayerCreatePayer({ ...payer, payerType: customerResponse.result.customerType }).pipe(
mergeMap((payerResponse) =>
this.customerService
.CustomerAddPayerReference({ customerId: customerId, payerId: payerResponse.result.id, isDefault: isDefault })
.CustomerAddPayerReference({
customerId: customerId,
payerId: payerResponse.result.id,
isDefault: isDefault,
})
.pipe(
map((assigendPayerResponse) => [payerResponse, assigendPayerResponse] as [Result<PayerDTO>, Result<AssignedPayerDTO>]),
map(
(assigendPayerResponse) =>
[payerResponse, assigendPayerResponse] as [Result<PayerDTO>, Result<AssignedPayerDTO>],
),
),
),
),
@@ -496,7 +511,11 @@ export class CrmCustomerService {
return this.customerService.CustomerModifyPayerReference({ payerId, customerId, isDefault });
}
createShippingAddress(customerId: number, shippingAddress: ShippingAddressDTO, isDefault?: boolean): Promise<Result<ShippingAddressDTO>> {
createShippingAddress(
customerId: number,
shippingAddress: ShippingAddressDTO,
isDefault?: boolean,
): Promise<Result<ShippingAddressDTO>> {
const data: ShippingAddressDTO = { ...shippingAddress };
if (isDefault) {
data.isDefault = new Date().toJSON();
@@ -504,7 +523,9 @@ export class CrmCustomerService {
delete data.isDefault;
}
return this.shippingAddressService.ShippingAddressCreateShippingAddress({ customerId, shippingAddress: data }).toPromise();
return this.shippingAddressService
.ShippingAddressCreateShippingAddress({ customerId, shippingAddress: data })
.toPromise();
}
updateShippingAddress(
@@ -530,7 +551,9 @@ export class CrmCustomerService {
return this.shippingAddressService.ShippingAddressGetShippingaddress(shippingAddressId);
}
getShippingAddresses(params: ShippingAddressService.ShippingAddressGetShippingAddressesParams): Observable<Result<ShippingAddressDTO[]>> {
getShippingAddresses(
params: ShippingAddressService.ShippingAddressGetShippingAddressesParams,
): Observable<Result<ShippingAddressDTO[]>> {
return this.shippingAddressService.ShippingAddressGetShippingAddresses(params);
}

View File

@@ -3,7 +3,12 @@ import { AddressHelper } from './address.helper';
describe('AddressHelper', () => {
describe('hasRequiredProperties', () => {
it('should return true', () => {
const result = AddressHelper.hasRequiredProperties({ city: 'Teststadt', street: 'Teststr.', zipCode: '12345', country: 'DEU' });
const result = AddressHelper.hasRequiredProperties({
city: 'Teststadt',
street: 'Teststr.',
zipCode: '12345',
country: 'DEU',
});
expect(result).toBeTruthy();
});

View File

@@ -9,7 +9,11 @@ describe('ShippingAddressHelper', () => {
});
it('should return the latest default shippingAdress', () => {
const shippingAdress: ShippingAddressDTO[] = [{ isDefault: new Date().toJSON() }, { isDefault: new Date(2020, 5, 15).toJSON() }, {}];
const shippingAdress: ShippingAddressDTO[] = [
{ isDefault: new Date().toJSON() },
{ isDefault: new Date(2020, 5, 15).toJSON() },
{},
];
expect(ShippingAddressHelper.getDefaultShippingAddress(shippingAdress)).toEqual(shippingAdress[0]);
});
});

View File

@@ -21,7 +21,9 @@ export class PrintShippingNoteActionHandler extends ActionHandler<OrderItemsCont
async printShippingNoteHelper(printer: string, receipts: ReceiptDTO[]) {
try {
for (const group of groupBy(receipts, (receipt) => receipt?.buyer?.buyerNumber)) {
await this.domainPrinterService.printShippingNote({ printer, receipts: group?.items?.map((r) => r?.id) }).toPromise();
await this.domainPrinterService
.printShippingNote({ printer, receipts: group?.items?.map((r) => r?.id) })
.toPromise();
}
return {
error: false,

View File

@@ -21,7 +21,10 @@ export class PrintSmallamountinvoiceActionHandler extends ActionHandler<OrderIte
super('PRINT_SMALLAMOUNTINVOICE');
}
private _printKleinbetragsrechnungHelper(printer: string, receiptGroup: Group<string, ReceiptDTO>): Promise<ResponseArgs> {
private _printKleinbetragsrechnungHelper(
printer: string,
receiptGroup: Group<string, ReceiptDTO>,
): Promise<ResponseArgs> {
return firstValueFrom(
this.omsPrintService.OMSPrintKleinbetragsrechnung({
data: receiptGroup?.items?.map((r) => r?.id),

View File

@@ -33,7 +33,10 @@ export class ShopWithKulturpassActionHandler extends ActionHandler<OrderItemsCon
command = result.data[1];
if (displayOrder) {
const subsetItems = displayOrder.items.reduce((acc, item) => [...acc, ...item.subsetItems], [] as DisplayOrderItemSubsetDTO[]);
const subsetItems = displayOrder.items.reduce(
(acc, item) => [...acc, ...item.subsetItems],
[] as DisplayOrderItemSubsetDTO[],
);
const orderItems = await this.getItems(displayOrder.orderNumber);

View File

@@ -48,10 +48,14 @@ export class DomainOmsService {
}
getHistory(orderItemSubsetId: number): Observable<HistoryDTO[]> {
return this.orderService.OrderGetOrderItemStatusHistory({ orderItemSubsetId }).pipe(map((response) => response.result));
return this.orderService
.OrderGetOrderItemStatusHistory({ orderItemSubsetId })
.pipe(map((response) => response.result));
}
getReceipts(orderItemSubsetIds: number[]): Observable<ValueTupleOfLongAndReceiptTypeAndEntityDTOContainerOfReceiptDTO[]> {
getReceipts(
orderItemSubsetIds: number[],
): Observable<ValueTupleOfLongAndReceiptTypeAndEntityDTOContainerOfReceiptDTO[]> {
return this.receiptService
.ReceiptGetReceiptsByOrderItemSubset({
payload: {
@@ -133,14 +137,20 @@ export class DomainOmsService {
.pipe(map((o) => o.result));
}
setEstimatedShippingDate(orderId: number, orderItemId: number, orderItemSubsetId: number, estimatedShippingDate: Date | string) {
setEstimatedShippingDate(
orderId: number,
orderItemId: number,
orderItemSubsetId: number,
estimatedShippingDate: Date | string,
) {
return this.orderService
.OrderPatchOrderItemSubset({
orderId,
orderItemId,
orderItemSubsetId,
orderItemSubset: {
estimatedShippingDate: estimatedShippingDate instanceof Date ? estimatedShippingDate.toJSON() : estimatedShippingDate,
estimatedShippingDate:
estimatedShippingDate instanceof Date ? estimatedShippingDate.toJSON() : estimatedShippingDate,
},
})
.pipe(map((response) => response.result));
@@ -171,7 +181,15 @@ export class DomainOmsService {
return this.orderService.OrderChangeStockStatusCode(payload).pipe(map((response) => response.result));
}
orderAtSupplier({ orderId, orderItemId, orderItemSubsetId }: { orderId: number; orderItemId: number; orderItemSubsetId: number }) {
orderAtSupplier({
orderId,
orderItemId,
orderItemSubsetId,
}: {
orderId: number;
orderItemId: number;
orderItemSubsetId: number;
}) {
return this._orderCheckoutService.OrderCheckoutOrderSubsetItemAtSupplier({
orderId,
orderItemId,
@@ -273,7 +291,14 @@ export class DomainOmsService {
skip?: number;
}): Observable<Record<string, Date[]>> {
return this.orderService
.OrderGetOrderItemSubsetTasks({ orderId, orderItemId, orderItemSubsetId, completed: new Date(0).toISOString(), take, skip })
.OrderGetOrderItemSubsetTasks({
orderId,
orderItemId,
orderItemSubsetId,
completed: new Date(0).toISOString(),
take,
skip,
})
.pipe(
map((res) =>
res.result

View File

@@ -54,7 +54,9 @@ export class PickupShelfInService extends PickupShelfIOService {
});
}
getOrderItemsByCustomerNumber(args: { customerNumber: string }): Observable<ListResponseArgsOfDBHOrderItemListItemDTO> {
getOrderItemsByCustomerNumber(args: {
customerNumber: string;
}): Observable<ListResponseArgsOfDBHOrderItemListItemDTO> {
return this._abholfachService.AbholfachWareneingang({
filter: { orderitemprocessingstatus: '16;128;8192;1048576' },
input: {

View File

@@ -25,5 +25,7 @@ export abstract class PickupShelfIOService {
filter?: Filter;
}): Observable<ListResponseArgsOfDBHOrderItemListItemDTO>;
abstract getOrderItemsByCustomerNumber(args: { customerNumber: string }): Observable<ListResponseArgsOfDBHOrderItemListItemDTO>;
abstract getOrderItemsByCustomerNumber(args: {
customerNumber: string;
}): Observable<ListResponseArgsOfDBHOrderItemListItemDTO>;
}

View File

@@ -55,7 +55,9 @@ export class PickupShelfOutService extends PickupShelfIOService {
});
}
getOrderItemsByCustomerNumber(args: { customerNumber: string }): Observable<ListResponseArgsOfDBHOrderItemListItemDTO> {
getOrderItemsByCustomerNumber(args: {
customerNumber: string;
}): Observable<ListResponseArgsOfDBHOrderItemListItemDTO> {
throw new Error('Method not implemented.');
}
}

View File

@@ -50,7 +50,11 @@ export class DomainPrinterService {
}
if (response.error) {
return {
error: response.message ? response.message : response.error.message ? response.error.message : 'Ein Fehler ist aufgetreten',
error: response.message
? response.message
: response.error.message
? response.error.message
: 'Ein Fehler ist aufgetreten',
};
}
@@ -81,7 +85,11 @@ export class DomainPrinterService {
}
if (response.error) {
return {
error: response.message ? response.message : response.error.message ? response.error.message : 'Ein Fehler ist aufgetreten',
error: response.message
? response.message
: response.error.message
? response.error.message
: 'Ein Fehler ist aufgetreten',
};
}
@@ -112,7 +120,11 @@ export class DomainPrinterService {
}
if (response.error) {
return {
error: response.message ? response.message : response.error.message ? response.error.message : 'Ein Fehler ist aufgetreten',
error: response.message
? response.message
: response.error.message
? response.error.message
: 'Ein Fehler ist aufgetreten',
};
}
@@ -208,7 +220,9 @@ export class DomainPrinterService {
});
}
printProductListItemsResponse(payload: DocumentPayloadOfIEnumerableOfProductListItemDTO): Observable<ResponseArgsOfString> {
printProductListItemsResponse(
payload: DocumentPayloadOfIEnumerableOfProductListItemDTO,
): Observable<ResponseArgsOfString> {
return this._productListService.ProductListProductListItemPdfAsBase64(payload);
}
@@ -254,7 +268,15 @@ export class DomainPrinterService {
);
}
printDisplayInfoDTOList({ displayInfos, printer, title }: { displayInfos: DisplayInfoDTO[]; printer: string; title?: string }) {
printDisplayInfoDTOList({
displayInfos,
printer,
title,
}: {
displayInfos: DisplayInfoDTO[];
printer: string;
title?: string;
}) {
return this.eisPublicDocumentService
.EISPublicDocumentGetInfosPdfAsBase64({
payload: { data: displayInfos, title },

View File

@@ -1,7 +1,13 @@
import { Logger } from '@core/logger';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
import { SearchService } from '@generated/swagger/cat-search-api';
import { PackageService, RemiService, ReturnService, StockService, SupplierService } from '@generated/swagger/inventory-api';
import {
PackageService,
RemiService,
ReturnService,
StockService,
SupplierService,
} from '@generated/swagger/inventory-api';
import { DomainRemissionService } from './remission.service';
import { DateAdapter } from '@ui/common';
@@ -9,7 +15,16 @@ describe('DomainRemissionService', () => {
let service: SpectatorService<DomainRemissionService>;
const createService = createServiceFactory({
service: DomainRemissionService,
mocks: [RemiService, StockService, SupplierService, PackageService, ReturnService, SearchService, Logger, DateAdapter],
mocks: [
RemiService,
StockService,
SupplierService,
PackageService,
ReturnService,
SearchService,
Logger,
DateAdapter,
],
});
beforeEach(() => {

View File

@@ -174,7 +174,9 @@ export class DomainRemissionService {
);
}
getItemsForPflichtremission(arg: { queryToken: RemiQueryTokenDTO }): Observable<{ hits: number; result: RemissionListItem[] }> {
getItemsForPflichtremission(arg: {
queryToken: RemiQueryTokenDTO;
}): Observable<{ hits: number; result: RemissionListItem[] }> {
return this._remiService
.RemiPflichtremissionsartikel({
queryToken: arg.queryToken,
@@ -187,7 +189,9 @@ export class DomainRemissionService {
);
}
getItemsForAbteilungsremission(arg: { queryToken: RemiQueryTokenDTO }): Observable<{ hits: number; result: RemissionListItem[] }> {
getItemsForAbteilungsremission(arg: {
queryToken: RemiQueryTokenDTO;
}): Observable<{ hits: number; result: RemissionListItem[] }> {
return this._remiService
.RemiUeberlauf({
queryToken: arg.queryToken,
@@ -213,7 +217,9 @@ export class DomainRemissionService {
.pipe(
map((res) => {
const o = items.map((item) => {
const stockInfo = res?.result?.find((stockInfo) => stockInfo.itemId === +item.dto.product.catalogProductNumber);
const stockInfo = res?.result?.find(
(stockInfo) => stockInfo.itemId === +item.dto.product.catalogProductNumber,
);
if (!stockInfo) {
const defaultStockData = {
@@ -423,7 +429,15 @@ export class DomainRemissionService {
return this._returnService.ReturnDeleteReturnItem({ itemId });
}
removeReturnItemFromReceipt({ returnId, receiptId, receiptItemId }: { returnId: number; receiptId: number; receiptItemId: number }) {
removeReturnItemFromReceipt({
returnId,
receiptId,
receiptItemId,
}: {
returnId: number;
receiptId: number;
receiptItemId: number;
}) {
return this._returnService.ReturnRemoveReturnItem({ returnId, receiptItemId, receiptId });
}

View File

@@ -1,3 +1,10 @@
export type ProcessingStatusType = 'Approved' | 'InProcess' | 'Completed' | 'Overdue' | 'Archived' | 'Uncompleted' | 'Removed';
export type ProcessingStatusType =
| 'Approved'
| 'InProcess'
| 'Completed'
| 'Overdue'
| 'Archived'
| 'Uncompleted'
| 'Removed';
export type ProcessingStatusList = ProcessingStatusType[];

View File

@@ -75,7 +75,8 @@ export class NativeContainerService {
}
if (this.windowRef.nativeWindow['isRunningNative'] === undefined) {
this.windowRef.nativeWindow['isRunningNative'] = (_) => window.postMessage({ status: 'INIT', data: 'Is a WebView' }, '*');
this.windowRef.nativeWindow['isRunningNative'] = (_) =>
window.postMessage({ status: 'INIT', data: 'Is a WebView' }, '*');
}
// Try sending ping request, to invoke the containers isRunningNative event

View File

@@ -27,7 +27,9 @@ export class AddressSelectionModalService {
.toPromise();
if (addresses?.length > 0) {
const modalResult = await this.modal.open({ content: AddressSelectionModalComponent, data: addresses }).afterClosed$.toPromise();
const modalResult = await this.modal
.open({ content: AddressSelectionModalComponent, data: addresses })
.afterClosed$.toPromise();
if (modalResult?.data) {
if (modalResult.data === 'continue') {
return address;

View File

@@ -16,7 +16,10 @@
</ui-searchbox>
<p class="subtitle">
<span class="bold">{{ item.product?.name }}</span> ist in den <span class="bold">Umkreisfilialen</span> folgendermaßen verfügbar:
<span class="bold">{{ item.product?.name }}</span>
ist in den
<span class="bold">Umkreisfilialen</span>
folgendermaßen verfügbar:
</p>
<hr />

View File

@@ -46,7 +46,9 @@ export class ModalAvailabilitiesComponent {
branch?.id !== userbranch?.id &&
branch?.branchType === 1,
)
.filter((b) => b.name?.toLowerCase()?.indexOf(search?.toLowerCase()) > -1 || b.address?.zipCode.indexOf(search) > -1)
.filter(
(b) => b.name?.toLowerCase()?.indexOf(search?.toLowerCase()) > -1 || b.address?.zipCode.indexOf(search) > -1,
)
.sort((a, b) =>
this.branchSorterFn(
a,

View File

@@ -36,7 +36,9 @@ export class KulturpassOrderItemStore extends ComponentStore<KulturpassOrderItem
readonly itemQuantity$ = this.select((state) => state.item?.quantity ?? 0);
readonly availability$ = this.item$.pipe(switchMap((item) => this._parentStore.getAvailability$(getCatalogProductNumber(item))));
readonly availability$ = this.item$.pipe(
switchMap((item) => this._parentStore.getAvailability$(getCatalogProductNumber(item))),
);
readonly availableQuantity$ = this.availability$.pipe(map((availability) => availability?.inStock ?? 0));

View File

@@ -22,7 +22,8 @@
<div class="overflow-y-auto -mx-4 scroll-bar">
<div *ngIf="emptyShoppingCart$ | async" class="h-full grid items-center justify-center">
<h3 class="text-xl font-bold text-center text-gray-500">
Warenkorb ist leer, bitte suchen oder scannen <br />
Warenkorb ist leer, bitte suchen oder scannen
<br />
Sie Artikel um den Warenkob zu füllen.
</h3>
</div>
@@ -30,8 +31,7 @@
class="border-b border-solid border-[#EFF1F5]"
*ngFor="let item of items$ | async; trackBy: trackItemById"
[item]="item"
>
</shared-kulturpass-order-item>
></shared-kulturpass-order-item>
</div>
<div class="flex flex-row justify-evenly items-stretch border-t border-solid border-[#EFF1F5] py-3 px-4 -mx-4">
<div class="grid grid-flow-row text-xl">

View File

@@ -19,7 +19,13 @@ import { getCatalogProductNumber } from './catalog-product-number';
styleUrls: ['kulturpass-order-modal.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'shared-kulturpass-order-modal' },
imports: [KulturpassOrderSearchboxComponent, CommonModule, BranchNamePipe, KulturpassOrderItemComponent, LoaderComponent],
imports: [
KulturpassOrderSearchboxComponent,
CommonModule,
BranchNamePipe,
KulturpassOrderItemComponent,
LoaderComponent,
],
providers: [provideComponentStore(KulturpassOrderModalStore)],
})
export class KulturpassOrderModalComponent implements OnInit {
@@ -33,7 +39,9 @@ export class KulturpassOrderModalComponent implements OnInit {
kulturpassCode$ = this._store.orderItemListItem$.pipe(map((orderItemListItem) => orderItemListItem.buyerNumber));
credit$ = this._store.orderItemListItem$.pipe(map((orderItemListItem) => orderItemListItem?.retailPrice?.value?.value ?? 0));
credit$ = this._store.orderItemListItem$.pipe(
map((orderItemListItem) => orderItemListItem?.retailPrice?.value?.value ?? 0),
);
total$ = this._store.shoppingCart$.pipe(map((shoppingCart) => shoppingCart?.total?.value ?? 0));

View File

@@ -93,12 +93,19 @@ export class KulturpassOrderModalStore extends ComponentStore<KulturpassOrderMod
readonly fetchShoppingCart$ = this.select((state) => state.fetchShoppingCart);
readonly updateFetchShoppingCart = this.updater((state, fetchShoppingCart: boolean) => ({ ...state, fetchShoppingCart }));
readonly updateFetchShoppingCart = this.updater((state, fetchShoppingCart: boolean) => ({
...state,
fetchShoppingCart,
}));
readonly ordering$ = this.select((state) => state.ordering);
loadBranch = this.effect(($) =>
$.pipe(switchMap(() => this._branchService.BranchGetBranches({}).pipe(tapResponse(this.handleBranchResponse, this.handleBranchError)))),
$.pipe(
switchMap(() =>
this._branchService.BranchGetBranches({}).pipe(tapResponse(this.handleBranchResponse, this.handleBranchError)),
),
),
);
handleBranchResponse = (res: ResponseArgsOfIEnumerableOfBranchDTO) => {
@@ -193,7 +200,9 @@ export class KulturpassOrderModalStore extends ComponentStore<KulturpassOrderMod
),
);
handleOrderResponse = (res: ResponseArgsOfValueTupleOfIEnumerableOfDisplayOrderDTOAndIEnumerableOfKeyValueDTOOfStringAndString) => {
handleOrderResponse = (
res: ResponseArgsOfValueTupleOfIEnumerableOfDisplayOrderDTOAndIEnumerableOfKeyValueDTOOfStringAndString,
) => {
this.onOrderSuccess(res.result.item1[0], res.result.item2);
};
@@ -205,7 +214,10 @@ export class KulturpassOrderModalStore extends ComponentStore<KulturpassOrderMod
};
itemQuantityByCatalogProductNumber(catalogProductNumber: string) {
return this.shoppingCart?.items?.find((i) => getCatalogProductNumber(i?.data) === catalogProductNumber)?.data?.quantity ?? 0;
return (
this.shoppingCart?.items?.find((i) => getCatalogProductNumber(i?.data) === catalogProductNumber)?.data
?.quantity ?? 0
);
}
canAddItem = this.effect((item$: Observable<ItemDTO>) =>
@@ -285,7 +297,8 @@ export class KulturpassOrderModalStore extends ComponentStore<KulturpassOrderMod
}
// Preis und priceMaintained werden immer erst vom Katalog genommen. Bei nicht Verfügbarkeit greifen die anderen Availabilities
const offlinePrice = item?.catalogAvailability?.price?.value?.value ?? takeAwayAvailability?.price?.value?.value ?? -1;
const offlinePrice =
item?.catalogAvailability?.price?.value?.value ?? takeAwayAvailability?.price?.value?.value ?? -1;
const availability = takeAwayAvailability;
availability.price = item?.catalogAvailability?.price ?? takeAwayAvailability?.price;

View File

@@ -8,5 +8,4 @@
(search)="search($event)"
(scan)="search($event)"
[hint]="hint$ | async"
>
</ui-searchbox>
></ui-searchbox>

View File

@@ -19,7 +19,10 @@ export interface KulturpassOrderSearchboxState {
}
@Injectable()
export class KulturpassOrderSearchboxStore extends ComponentStore<KulturpassOrderSearchboxState> implements OnStoreInit {
export class KulturpassOrderSearchboxStore
extends ComponentStore<KulturpassOrderSearchboxState>
implements OnStoreInit
{
private _parentStore = inject(KulturpassOrderModalStore);
private _catalogService = inject(DomainCatalogService);
private _availabilityService = inject(DomainAvailabilityService);
@@ -63,7 +66,11 @@ export class KulturpassOrderSearchboxStore extends ComponentStore<KulturpassOrde
loadBranch = this.effect(($) =>
$.pipe(
switchMap(() => this._availabilityService.getDefaultBranch().pipe(tapResponse(this.handleBranchResponse, this.handleBranchError))),
switchMap(() =>
this._availabilityService
.getDefaultBranch()
.pipe(tapResponse(this.handleBranchResponse, this.handleBranchError)),
),
),
);
@@ -80,7 +87,9 @@ export class KulturpassOrderSearchboxStore extends ComponentStore<KulturpassOrde
tap(() => this.patchState({ fetching: true })),
withLatestFrom(this.query$),
switchMap(([_, query]) =>
this._catalogService.getDetailsByEan({ ean: query?.trim() }).pipe(tapResponse(this.handleSearchResponse, this.handleSearchError)),
this._catalogService
.getDetailsByEan({ ean: query?.trim() })
.pipe(tapResponse(this.handleSearchResponse, this.handleSearchError)),
),
),
);

View File

@@ -33,7 +33,6 @@
*ngSwitchCase="'Wareneingang Lagerware'"
[notifications]="notifications[selectedArea]"
(navigated)="close()"
>
</modal-notifications-package-inspection-group>
></modal-notifications-package-inspection-group>
</ng-container>
</ng-container>

View File

@@ -1,7 +1,14 @@
import { ItemType, PriceDTO, PriceValueDTO, VATValueDTO } from '@generated/swagger/checkout-api';
import { OrderType, PurchaseOption } from './store';
export const PURCHASE_OPTIONS: PurchaseOption[] = ['in-store', 'pickup', 'delivery', 'dig-delivery', 'b2b-delivery', 'download'];
export const PURCHASE_OPTIONS: PurchaseOption[] = [
'in-store',
'pickup',
'delivery',
'dig-delivery',
'b2b-delivery',
'download',
];
export const DELIVERY_PURCHASE_OPTIONS: PurchaseOption[] = ['delivery', 'dig-delivery', 'b2b-delivery'];

View File

@@ -15,7 +15,7 @@
@apply transition-all;
@apply duration-200;
@apply ease-in-out;
content: '';
content: "";
top: 0;
left: 0;
right: 0;
@@ -31,7 +31,7 @@
}
.fancy-checkbox::after {
content: '';
content: "";
background-image: url("data:image/svg+xml,%3Csvg width='100%25' height='100%25' viewBox='0 0 24 24' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve' xmlns:serif='http://www.serif.com/'%3E%3Cpath fill='white' d='M21.432,3.715C21.432,3.715 21.432,3.715 21.432,3.715C21.115,3.76 20.823,3.911 20.604,4.143C16.03,8.727 12.603,12.511 8.244,16.932C8.244,16.932 3.297,12.754 3.297,12.754C2.909,12.424 2.374,12.327 1.895,12.499C1.895,12.499 1.895,12.499 1.895,12.499C1.415,12.672 1.065,13.088 0.975,13.589C0.885,14.091 1.072,14.602 1.463,14.929L7.415,19.966C7.981,20.441 8.818,20.403 9.338,19.877C14.251,14.954 17.761,11.007 22.616,6.141C23.057,5.714 23.172,5.051 22.903,4.499C22.903,4.499 22.903,4.499 22.903,4.499C22.633,3.948 22.04,3.631 21.432,3.715Z'/%3E%3C/svg%3E%0A");
@apply absolute;
top: 0.4rem;

View File

@@ -123,7 +123,8 @@
</shared-input-control>
<ui-tooltip [warning]="true" xPosition="after" yPosition="below" [xOffset]="-55" [yOffset]="18" [closeable]="true" #giftCardTooltip>
Tragen Sie hier den <br />
Tragen Sie hier den
<br />
Gutscheinbetrag ein.
</ui-tooltip>
</div>

View File

@@ -48,8 +48,14 @@
@apply rounded;
}
::ng-deep app-pickup-purchase-options-tile shared-branch-selector.shared-branch-selector-opend .shared-branch-selector-input-container,
::ng-deep app-in-store-purchase-options-tile shared-branch-selector.shared-branch-selector-opend .shared-branch-selector-input-container {
::ng-deep
app-pickup-purchase-options-tile
shared-branch-selector.shared-branch-selector-opend
.shared-branch-selector-input-container,
::ng-deep
app-in-store-purchase-options-tile
shared-branch-selector.shared-branch-selector-opend
.shared-branch-selector-input-container {
@apply shadow-card;
}

View File

@@ -2,7 +2,14 @@ import { PriceDTO } from '@generated/swagger/availability-api';
import { ItemDTO } from '@generated/swagger/cat-search-api';
import { AvailabilityDTO, OLAAvailabilityDTO, ShoppingCartItemDTO } from '@generated/swagger/checkout-api';
import { GIFT_CARD_TYPE } from '../constants';
import { ActionType, Item, ItemData, ItemPayloadWithSourceId, OrderType, PurchaseOption } from './purchase-options.types';
import {
ActionType,
Item,
ItemData,
ItemPayloadWithSourceId,
OrderType,
PurchaseOption,
} from './purchase-options.types';
export function isItemDTO(item: any, type: ActionType): item is ItemDTO {
return type === 'add';

View File

@@ -1,8 +1,22 @@
import { PriceDTO, PriceValueDTO } from '@generated/swagger/checkout-api';
import { DEFAULT_PRICE_DTO, DEFAULT_PRICE_VALUE, GIFT_CARD_MAX_PRICE, GIFT_CARD_TYPE, PURCHASE_OPTIONS } from '../constants';
import {
DEFAULT_PRICE_DTO,
DEFAULT_PRICE_VALUE,
GIFT_CARD_MAX_PRICE,
GIFT_CARD_TYPE,
PURCHASE_OPTIONS,
} from '../constants';
import { isArchive, isGiftCard, isItemDTO } from './purchase-options.helpers';
import { PurchaseOptionsState } from './purchase-options.state';
import { ActionType, Availability, Branch, CanAdd, FetchingAvailability, Item, PurchaseOption } from './purchase-options.types';
import {
ActionType,
Availability,
Branch,
CanAdd,
FetchingAvailability,
Item,
PurchaseOption,
} from './purchase-options.types';
export function getType(state: PurchaseOptionsState): ActionType {
return state.type;
@@ -108,13 +122,17 @@ export function getPurchaseOptionsInAvailabilities(state: PurchaseOptionsState):
purchaseOptions = Array.from(new Set(purchaseOptions));
// if 'delivery' is not present but 'dig-delivery' or 'b2b-delivery' is present, add 'delivery' to the list
if (!purchaseOptions.includes('delivery') && (purchaseOptions.includes('dig-delivery') || purchaseOptions.includes('b2b-delivery'))) {
if (
!purchaseOptions.includes('delivery') &&
(purchaseOptions.includes('dig-delivery') || purchaseOptions.includes('b2b-delivery'))
) {
purchaseOptions.push('delivery');
}
// if remove 'dig-delivery' and 'b2b-delivery' and 'catalog' as 'catalog' is not a purchase option but is needed for other data (Needed for #4813 and Bugfix for #4710)
purchaseOptions = purchaseOptions.filter(
(purchaseOption) => purchaseOption !== 'dig-delivery' && purchaseOption !== 'b2b-delivery' && purchaseOption !== 'catalog',
(purchaseOption) =>
purchaseOption !== 'dig-delivery' && purchaseOption !== 'b2b-delivery' && purchaseOption !== 'catalog',
);
return purchaseOptions.sort((a, b) => PURCHASE_OPTIONS.indexOf(a) - PURCHASE_OPTIONS.indexOf(b));
@@ -124,14 +142,18 @@ export function getFetchingAvailabilities(state: PurchaseOptionsState): Array<Fe
return state.fetchingAvailabilities;
}
export function getFetchingAvailabilitiesForItem(itemId: number): (state: PurchaseOptionsState) => Array<FetchingAvailability> {
export function getFetchingAvailabilitiesForItem(
itemId: number,
): (state: PurchaseOptionsState) => Array<FetchingAvailability> {
return (state: PurchaseOptionsState) => {
const fetchingAvailabilities = getFetchingAvailabilities(state);
return fetchingAvailabilities.filter((fa) => fa.itemId === itemId);
};
}
export function getItemsThatHaveAnAvailabilityForPurchaseOption(purchaseOption: PurchaseOption): (state: PurchaseOptionsState) => Item[] {
export function getItemsThatHaveAnAvailabilityForPurchaseOption(
purchaseOption: PurchaseOption,
): (state: PurchaseOptionsState) => Item[] {
return (state) => {
const availabilities = getAvailabilities(state);
const items = getItems(state);
@@ -159,7 +181,9 @@ export function getItemsThatHaveAnAvailabilityAndCanAddForPurchaseOption(purchas
const canAddResults = getCanAddResults(state);
return items.filter((item) =>
canAddResults.some((canAdd) => canAdd.itemId === item.id && canAdd.purchaseOption === purchaseOption && canAdd.canAdd),
canAddResults.some(
(canAdd) => canAdd.itemId === item.id && canAdd.purchaseOption === purchaseOption && canAdd.canAdd,
),
);
};
}
@@ -198,14 +222,20 @@ export function getAvailabilitiesForItem(
availabilities = availabilities.filter((availability) => availability.itemId === itemId);
// if 'delivery', 'dig-delivery' and 'b2b-delivery' are present remove 'dig-delivery' and 'b2b-delivery'
if (!allDeliveryAvailabilities && availabilities.some((availability) => availability.purchaseOption === 'delivery')) {
if (
!allDeliveryAvailabilities &&
availabilities.some((availability) => availability.purchaseOption === 'delivery')
) {
availabilities = availabilities.filter(
(availability) => availability.purchaseOption !== 'dig-delivery' && availability.purchaseOption !== 'b2b-delivery',
(availability) =>
availability.purchaseOption !== 'dig-delivery' && availability.purchaseOption !== 'b2b-delivery',
);
}
const optionsOrder = PURCHASE_OPTIONS;
return availabilities.sort((a, b) => optionsOrder.indexOf(a.purchaseOption) - optionsOrder.indexOf(b.purchaseOption));
return availabilities.sort(
(a, b) => optionsOrder.indexOf(a.purchaseOption) - optionsOrder.indexOf(b.purchaseOption),
);
};
}
@@ -346,7 +376,10 @@ export function getAvailabilityPriceForPurchaseOption(
};
}
export function getPriceForPurchaseOption(itemId: number, purchaseOption: PurchaseOption): (state: PurchaseOptionsState) => PriceDTO {
export function getPriceForPurchaseOption(
itemId: number,
purchaseOption: PurchaseOption,
): (state: PurchaseOptionsState) => PriceDTO {
return (state) => {
if (getCanEditPrice(itemId)(state)) {
const price = getPrices(state)[itemId];
@@ -367,7 +400,9 @@ export function getQuantityForItem(itemId: number): (state: PurchaseOptionsState
};
}
export function getCanAddResultForItemAndCurrentPurchaseOption(itemId: number): (state: PurchaseOptionsState) => CanAdd {
export function getCanAddResultForItemAndCurrentPurchaseOption(
itemId: number,
): (state: PurchaseOptionsState) => CanAdd {
return (state) => {
const fetchingAvailabilities = getFetchingAvailabilitiesForItem(itemId)(state);
const purchaseOption = getPurchaseOption(state);
@@ -386,7 +421,9 @@ export function getCanAddResultForItemAndCurrentPurchaseOption(itemId: number):
const canAddResults = getCanAddResults(state);
return canAddResults.find((canAddResult) => canAddResult.itemId === itemId && canAddResult.purchaseOption === purchaseOption);
return canAddResults.find(
(canAddResult) => canAddResult.itemId === itemId && canAddResult.purchaseOption === purchaseOption,
);
};
}
@@ -410,10 +447,15 @@ export function getAvailabilityWithPurchaseOption(
};
}
export function getCanAddResultWithPurchaseOption(itemId: number, purchaseOption: PurchaseOption): (state: PurchaseOptionsState) => CanAdd {
export function getCanAddResultWithPurchaseOption(
itemId: number,
purchaseOption: PurchaseOption,
): (state: PurchaseOptionsState) => CanAdd {
return (state) => {
const canAddResults = getCanAddResults(state);
return canAddResults.find((canAddResult) => canAddResult.itemId === itemId && canAddResult.purchaseOption === purchaseOption);
return canAddResults.find(
(canAddResult) => canAddResult.itemId === itemId && canAddResult.purchaseOption === purchaseOption,
);
};
}

View File

@@ -1,5 +1,13 @@
import { PriceDTO } from '@generated/swagger/checkout-api';
import { ActionType, Availability, Branch, CanAdd, FetchingAvailability, Item, PurchaseOption } from './purchase-options.types';
import {
ActionType,
Availability,
Branch,
CanAdd,
FetchingAvailability,
Item,
PurchaseOption,
} from './purchase-options.types';
export interface PurchaseOptionsState {
type: ActionType;

View File

@@ -27,7 +27,11 @@ import {
import { Observable } from 'rxjs';
import { first, switchMap } from 'rxjs/operators';
import { DEFAULT_PRICE_DTO, DEFAULT_PRICE_VALUE, DEFAULT_VAT_VALUE } from '../constants';
import { AddToShoppingCartDTO, EntityDTOContainerOfDestinationDTO, UpdateShoppingCartItemDTO } from '@generated/swagger/checkout-api';
import {
AddToShoppingCartDTO,
EntityDTOContainerOfDestinationDTO,
UpdateShoppingCartItemDTO,
} from '@generated/swagger/checkout-api';
import { uniqueId } from 'lodash';
import { VATDTO } from '@generated/swagger/oms-api';
import { DomainCatalogService } from '@domain/catalog';
@@ -248,7 +252,9 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
private async _loadCatalogueAvailability() {
const items = this.items;
if (this.type === 'update') {
const items = await this._catalogService.searchByEans({ eans: this.items.map((item) => item.product.ean) }).toPromise();
const items = await this._catalogService
.searchByEans({ eans: this.items.map((item) => item.product.ean) })
.toPromise();
if (items.result.length > 0) await this._addCatalogueAvailabilities(items.result);
} else {
await this._addCatalogueAvailabilities(items as ItemDTO[]);
@@ -404,7 +410,9 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
if (this._service.isAvailable(availability.data)) {
const availabilities = this.availabilities;
const index = availabilities.findIndex((a) => a.itemId === availability.itemId && a.purchaseOption === availability.purchaseOption);
const index = availabilities.findIndex(
(a) => a.itemId === availability.itemId && a.purchaseOption === availability.purchaseOption,
);
if (index > -1) {
availabilities[index] = availability;
@@ -423,7 +431,9 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
private _addCanAddResult(canAdd: CanAdd) {
let canAddResults = this.canAddResults;
canAddResults = canAddResults.filter((c) => !(c.itemId === canAdd.itemId && c.purchaseOption === canAdd.purchaseOption));
canAddResults = canAddResults.filter(
(c) => !(c.itemId === canAdd.itemId && c.purchaseOption === canAdd.purchaseOption),
);
canAddResults.push(canAdd);
this.patchState({ canAddResults });
}
@@ -440,7 +450,9 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
this.items.forEach((item) => {
// Get Rücklage availability
const inStoreAvailability = this.availabilities.find((a) => a.itemId === item.id && a.purchaseOption === 'in-store');
const inStoreAvailability = this.availabilities.find(
(a) => a.itemId === item.id && a.purchaseOption === 'in-store',
);
if (inStoreAvailability) {
payloads['Rücklage'].push(
mapToItemPayload({
@@ -453,9 +465,15 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
}
// Get Versand availability
let deliveryAvailability = this.availabilities.find((a) => a.itemId === item.id && a.purchaseOption === 'delivery');
const digDeliveryAvailability = this.availabilities.find((a) => a.itemId === item.id && a.purchaseOption === 'dig-delivery');
const b2bDeliveryAvailability = this.availabilities.find((a) => a.itemId === item.id && a.purchaseOption === 'b2b-delivery');
let deliveryAvailability = this.availabilities.find(
(a) => a.itemId === item.id && a.purchaseOption === 'delivery',
);
const digDeliveryAvailability = this.availabilities.find(
(a) => a.itemId === item.id && a.purchaseOption === 'dig-delivery',
);
const b2bDeliveryAvailability = this.availabilities.find(
(a) => a.itemId === item.id && a.purchaseOption === 'b2b-delivery',
);
deliveryAvailability = deliveryAvailability || digDeliveryAvailability || b2bDeliveryAvailability;
if (deliveryAvailability) {
payloads['Versand'].push(
@@ -482,7 +500,9 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
}
// Get Download availability
const downloadAvailability = this.availabilities.find((a) => a.itemId === item.id && a.purchaseOption === 'download');
const downloadAvailability = this.availabilities.find(
(a) => a.itemId === item.id && a.purchaseOption === 'download',
);
if (downloadAvailability) {
payloads['Download'].push(
mapToItemPayload({
@@ -714,7 +734,11 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
let price = prices[itemId];
if (price?.vat?.vatType !== vat?.vatType) {
if (!price) {
price = { ...DEFAULT_PRICE_DTO, value: { ...DEFAULT_PRICE_VALUE, ...price?.value }, vat: { ...DEFAULT_VAT_VALUE, ...vat } };
price = {
...DEFAULT_PRICE_DTO,
value: { ...DEFAULT_PRICE_VALUE, ...price?.value },
vat: { ...DEFAULT_VAT_VALUE, ...vat },
};
} else {
price = { ...price, value: price.value, vat: { ...price.vat, ...vat } };
}
@@ -829,10 +853,14 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
const purchaseOption = this.purchaseOption;
if (type === 'add') {
const payloads = this.selectedItemIds.map((itemId) => this.getAddToShoppingCartDTOForItem(itemId, purchaseOption));
const payloads = this.selectedItemIds.map((itemId) =>
this.getAddToShoppingCartDTOForItem(itemId, purchaseOption),
);
await this._service.addItemToShoppingCart(this.processId, payloads).toPromise();
} else if (type === 'update') {
const payloads = this.selectedItemIds.map((itemId) => this.getUpdateShoppingCartItemDTOForItem(itemId, purchaseOption));
const payloads = this.selectedItemIds.map((itemId) =>
this.getUpdateShoppingCartItemDTOForItem(itemId, purchaseOption),
);
for (const itemId of this.selectedItemIds) {
const item = this.items.find((i) => i.id === itemId);

View File

@@ -4,7 +4,14 @@ import { AvailabilityDTO, BranchDTO, ItemPayload, ShoppingCartItemDTO } from '@g
export type ActionType = 'add' | 'update';
export type PurchaseOption = 'delivery' | 'dig-delivery' | 'b2b-delivery' | 'pickup' | 'in-store' | 'download' | 'catalog';
export type PurchaseOption =
| 'delivery'
| 'dig-delivery'
| 'b2b-delivery'
| 'pickup'
| 'in-store'
| 'download'
| 'catalog';
export type OrderType = 'Rücklage' | 'Abholung' | 'Versand' | 'Download';

View File

@@ -11,7 +11,8 @@ import { UiModalRef } from '@ui/modal';
})
export class ModalReviewsComponent {
reviews = this.modalRef.data;
rating = Math.floor((this.reviews.map((r) => r.rating).reduce((total, num) => total + num) / this.reviews.length) * 2) / 2;
rating =
Math.floor((this.reviews.map((r) => r.rating).reduce((total, num) => total + num) / this.reviews.length) * 2) / 2;
expandIds: string[] = [];
constructor(private modalRef: UiModalRef<void, ReviewDTO[]>) {}

View File

@@ -49,7 +49,10 @@ export class SendOrderConfirmationModalComponent implements OnInit {
try {
await this.orderService
.OrderPatchOrder({ orderId: order.id, order: { notificationChannels, buyer: { communicationDetails: { email } } } })
.OrderPatchOrder({
orderId: order.id,
order: { notificationChannels, buyer: { communicationDetails: { email } } },
})
.toPromise();
const response = await this.orderService.OrderOrderConfirmationTask(order.id).toPromise();
this.toaster.open({

View File

@@ -1,6 +1,7 @@
<h2 class="text-center font-bold text-xl mt-10">Sie haben {{ packageCount }} Irrläufer</h2>
<p class="text-center text-xl mt-4">
Stellen Sie diese Packstücke für die anderen Filialen bereit. <br />
Stellen Sie diese Packstücke für die anderen Filialen bereit.
<br />
Der Spediteur holt Sie zum nächstmöglichsten Zeitpunkt ab.
</p>
<page-package-list [packages]="packages" [showHeader]="false" navigationEnabled="false"></page-package-list>

View File

@@ -3,7 +3,8 @@
>
<p class="page-price-update-item__item-instruction font-bold text-lg">{{ item?.task?.instruction }}</p>
<p class="page-price-update-item__item-due-date text-p2">
gültig ab <span class="font-bold ml-2">{{ item?.task?.dueDate | date }}</span>
gültig ab
<span class="font-bold ml-2">{{ item?.task?.dueDate | date }}</span>
</p>
</div>
@@ -50,7 +51,8 @@
<div class="page-price-update-item__item-misc">
{{ environment.isTablet() ? (item?.product?.manufacturer | substr: 18) : item?.product?.manufacturer }} | {{ item?.product?.ean }}
<br />
{{ item?.product?.volume }} <span *ngIf="item?.product?.volume && item?.product?.publicationDate">|</span>
{{ item?.product?.volume }}
<span *ngIf="item?.product?.volume && item?.product?.publicationDate">|</span>
{{ publicationDate }}
</div>
</div>
@@ -76,8 +78,9 @@
*ngIf="inStock$ | async; let stock"
[class.skeleton]="stock?.inStock === undefined"
class="min-w-[1rem] text-right inline-block"
>{{ stock?.inStock }}</span
>
{{ stock?.inStock }}
</span>
x
</div>
</div>

View File

@@ -16,7 +16,9 @@ import { trigger, transition, style, animate } from '@angular/animations';
style({ transform: 'scale(1.2)', opacity: 0 }),
animate('250ms cubic-bezier(0.35, 0, 0.25, 1)', style({ transform: 'scale(1)', opacity: 1 })),
]),
transition(':leave', [animate('250ms cubic-bezier(0.35, 0, 0.25, 1)', style({ transform: 'scale(0.8)', opacity: 0 }))]),
transition(':leave', [
animate('250ms cubic-bezier(0.35, 0, 0.25, 1)', style({ transform: 'scale(0.8)', opacity: 0 })),
]),
]),
],
standalone: false,

View File

@@ -11,7 +11,15 @@ import { PriceUpdateItemComponent } from './price-update-item.component';
import { PriceUpdateListComponent } from './price-update-list.component';
@NgModule({
imports: [FormsModule, CommonModule, UiCommonModule, UiIconModule, ProductImageModule, UiSpinnerModule, UiOrderByFilterModule],
imports: [
FormsModule,
CommonModule,
UiCommonModule,
UiIconModule,
ProductImageModule,
UiSpinnerModule,
UiOrderByFilterModule,
],
exports: [PriceUpdateListComponent, PriceUpdateItemComponent, PriceUpdateItemLoaderComponent],
declarations: [PriceUpdateListComponent, PriceUpdateItemComponent, PriceUpdateItemLoaderComponent],
providers: [],

View File

@@ -11,8 +11,11 @@
</button>
</div>
<page-price-update-list *ngIf="showList$ | async; else noResults" [items]="store.items$ | async" [fetching]="store.fetching$ | async">
</page-price-update-list>
<page-price-update-list
*ngIf="showList$ | async; else noResults"
[items]="store.items$ | async"
[fetching]="store.fetching$ | async"
></page-price-update-list>
<shell-filter-overlay #filterOverlay class="relative">
<div class="relative">

View File

@@ -94,7 +94,9 @@ export class PriceUpdateComponentStore extends ComponentStore<PriceUpdateCompone
fetchSettings = this.effect(($) =>
$.pipe(
switchMap((_) => this._productListService.getQuerySettings().pipe(tapResponse(this.onFetchSettingsResponse, this.onFetchError))),
switchMap((_) =>
this._productListService.getQuerySettings().pipe(tapResponse(this.onFetchSettingsResponse, this.onFetchError)),
),
),
);
@@ -137,7 +139,9 @@ export class PriceUpdateComponentStore extends ComponentStore<PriceUpdateCompone
data: {
printerType: 'Office',
print: (printer) =>
this._domainPrinterService.printProductListItems({ data: selectableItems, printer, title: 'Preisänderungen' }).toPromise(),
this._domainPrinterService
.printProductListItems({ data: selectableItems, printer, title: 'Preisänderungen' })
.toPromise(),
} as PrintModalData,
config: {
panelClass: [],
@@ -161,7 +165,10 @@ export class PriceUpdateComponentStore extends ComponentStore<PriceUpdateCompone
let items = this.items;
if (response.error) {
this._uiModal.error('Setzen der Produkte auf Erledigt enthält fehlerhafte Einträge.', new Error(response.message));
this._uiModal.error(
'Setzen der Produkte auf Erledigt enthält fehlerhafte Einträge.',
new Error(response.message),
);
} else if (response.successful) {
items = items.filter((item) => !response.successful.some((s) => s.key === item.uId));
} else {

View File

@@ -35,7 +35,9 @@ export class PriceUpdateComponent implements OnInit {
* Zeigt die liste an, wenn entweder keine items geladen werden oder wenn items geladen wurden
* und mindestens ein item vorhanden ist.
*/
showList$ = combineLatest([this.store.fetching$, this.store.items$]).pipe(map(([fetching, items]) => fetching || items.length > 0));
showList$ = combineLatest([this.store.fetching$, this.store.items$]).pipe(
map(([fetching, items]) => fetching || items.length > 0),
);
constructor(
public store: PriceUpdateComponentStore,
@@ -132,7 +134,10 @@ export class PriceUpdateComponent implements OnInit {
}
async removeBreadcrumbs(): Promise<void> {
const filterCrumbs = await this._breadcrumb.getBreadcrumbsByKeyAndTag$(this.breadcrumbKey, 'filter').pipe(first()).toPromise();
const filterCrumbs = await this._breadcrumb
.getBreadcrumbsByKeyAndTag$(this.breadcrumbKey, 'filter')
.pipe(first())
.toPromise();
const crumbs = [...filterCrumbs];
for (let crumb of crumbs) {
await this._breadcrumb.removeBreadcrumb(crumb.id);

View File

@@ -8,7 +8,14 @@ import { PriceUpdateComponent } from './price-update.component';
import { IconComponent } from '@shared/components/icon';
@NgModule({
imports: [CommonModule, PriceUpdateListModule, UiFilterNextModule, SharedFilterOverlayModule, UiSpinnerModule, IconComponent],
imports: [
CommonModule,
PriceUpdateListModule,
UiFilterNextModule,
SharedFilterOverlayModule,
UiSpinnerModule,
IconComponent,
],
exports: [PriceUpdateComponent],
declarations: [PriceUpdateComponent],
providers: [],

View File

@@ -6,6 +6,9 @@
</page-article-details-text-link>
<br />
</ng-container>
<ng-container *ngSwitchDefault> {{ line }} <br /> </ng-container>
<ng-container *ngSwitchDefault>
{{ line }}
<br />
</ng-container>
</ng-container>
</ng-container>

View File

@@ -11,7 +11,15 @@ import { ReiheRoutePipe } from './reihe-route.pipe';
styleUrls: ['article-details-text.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page-article-details-text' },
imports: [ArticleDetailsTextLinkComponent, NgFor, NgSwitch, NgSwitchCase, NgSwitchDefault, LineTypePipe, ReiheRoutePipe],
imports: [
ArticleDetailsTextLinkComponent,
NgFor,
NgSwitch,
NgSwitchCase,
NgSwitchDefault,
LineTypePipe,
ReiheRoutePipe,
],
})
export class ArticleDetailsTextComponent {
@Input()

View File

@@ -15,18 +15,18 @@
grid-template-columns: max-content auto;
grid-template-rows: 2.1875rem repeat(11, minmax(auto, max-content));
grid-template-areas:
'. . . bookmark'
'image contributors contributors contributors'
'image title title print'
'image title title .'
'image misc price price'
'image misc price price'
'image origin origin stock'
'image origin origin stock'
'image specs availabilities availabilities'
'image specs ssc ssc'
'image . ssc ssc'
'image . ssc ssc';
". . . bookmark"
"image contributors contributors contributors"
"image title title print"
"image title title ."
"image misc price price"
"image misc price price"
"image origin origin stock"
"image origin origin stock"
"image specs availabilities availabilities"
"image specs ssc ssc"
"image . ssc ssc"
"image . ssc ssc";
}
.page-article-details__product-bookmark {

View File

@@ -20,7 +20,11 @@ import { DateAdapter } from '@ui/common';
import { DatePipe } from '@angular/common';
import { PurchaseOptionsModalService } from '@modal/purchase-options';
import { EnvironmentService } from '@core/environment';
import { CheckoutNavigationService, ProductCatalogNavigationService, CustomerSearchNavigation } from '@shared/services/navigation';
import {
CheckoutNavigationService,
ProductCatalogNavigationService,
CustomerSearchNavigation,
} from '@shared/services/navigation';
import { DomainCheckoutService } from '@domain/checkout';
import { Store } from '@ngrx/store';
import moment, { Moment } from 'moment';
@@ -63,9 +67,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
shareReplay(),
);
showDeliveryTruck$ = combineLatest([this.store.isDeliveryAvailabilityAvailable$, this.store.isDeliveryDigAvailabilityAvailable$]).pipe(
map(([delivery, digDelivery]) => delivery || digDelivery),
);
showDeliveryTruck$ = combineLatest([
this.store.isDeliveryAvailabilityAvailable$,
this.store.isDeliveryDigAvailabilityAvailable$,
]).pipe(map(([delivery, digDelivery]) => delivery || digDelivery));
showDeliveryB2BTruck$ = combineLatest([
this.store.isDeliveryDigAvailabilityAvailable$,
@@ -88,7 +93,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
showArchivBadge$ = this.store.item$.pipe(map((item) => item?.features?.find((i) => i.key === 'ARC')));
isBadgeVisible$ = combineLatest([this.showSubscriptionBadge$, this.showPromotionBadge$, this.showArchivBadge$]).pipe(
map(([showSubscriptionBadge, showPromotionBadge, showArchivBadge]) => showSubscriptionBadge || showPromotionBadge || showArchivBadge),
map(
([showSubscriptionBadge, showPromotionBadge, showArchivBadge]) =>
showSubscriptionBadge || showPromotionBadge || showArchivBadge,
),
);
contributors$ = this.store.item$.pipe(map((item) => item?.product?.contributors?.split(';').map((m) => m.trim())));
@@ -115,7 +123,9 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
publicationDate$ = this.store.item$.pipe(
filter((item) => !!item?.product?.publicationDate),
map((item) => {
const firstDayOfSale = item.catalogAvailability?.firstDayOfSale ? moment(item.catalogAvailability.firstDayOfSale) : null;
const firstDayOfSale = item.catalogAvailability?.firstDayOfSale
? moment(item.catalogAvailability.firstDayOfSale)
: null;
const publicationDate = item.product?.publicationDate ? moment(item.product.publicationDate) : null;
if (!firstDayOfSale && !publicationDate) {
@@ -236,7 +246,9 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
.pipe(
debounceTime(0),
switchMap((params) =>
this.applicationService.getSelectedBranch$(Number(params.processId)).pipe(map((selectedBranch) => ({ params, selectedBranch }))),
this.applicationService
.getSelectedBranch$(Number(params.processId))
.pipe(map((selectedBranch) => ({ params, selectedBranch }))),
),
)
.subscribe(({ params, selectedBranch }) => {
@@ -287,7 +299,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
}
getDetailsPath(ean?: string) {
return this._navigationService.getArticleDetailsPathByEan({ processId: this.applicationService.activatedProcessId, ean }).path;
return this._navigationService.getArticleDetailsPathByEan({
processId: this.applicationService.activatedProcessId,
ean,
}).path;
}
async updateBreadcrumb(item: ItemDTO) {
@@ -303,7 +318,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
this.breadcrumb.addBreadcrumbIfNotExists({
key: this.applicationService.activatedProcessId,
name: item.product?.name,
path: this._navigationService.getArticleDetailsPath({ processId: this.applicationService.activatedProcessId, itemId: item.id }).path,
path: this._navigationService.getArticleDetailsPath({
processId: this.applicationService.activatedProcessId,
itemId: item.id,
}).path,
params: this.activatedRoute.snapshot.queryParams,
tags: ['catalog', 'details', `${item.id}`],
section: 'customer',
@@ -328,8 +346,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
this.breadcrumb.addBreadcrumbIfNotExists({
key: this.applicationService.activatedProcessId,
name: item.product?.name,
path: this._navigationService.getArticleDetailsPath({ processId: this.applicationService.activatedProcessId, itemId: item.id })
.path,
path: this._navigationService.getArticleDetailsPath({
processId: this.applicationService.activatedProcessId,
itemId: item.id,
}).path,
params: this.activatedRoute.snapshot.queryParams,
tags: ['catalog', 'details', `${item.id}`],
section: 'customer',
@@ -339,8 +359,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
this.breadcrumb.patchBreadcrumb(crumb.id, {
key: this.applicationService.activatedProcessId,
name: item.product?.name,
path: this._navigationService.getArticleDetailsPath({ processId: this.applicationService.activatedProcessId, itemId: item.id })
.path,
path: this._navigationService.getArticleDetailsPath({
processId: this.applicationService.activatedProcessId,
itemId: item.id,
}).path,
params: this.activatedRoute.snapshot.queryParams,
tags: ['catalog', 'details', `${item.id}`],
section: 'customer',
@@ -355,7 +377,8 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
data: {
printerType: 'Label',
// TODO: remove item: item as PrinterItemDTO when the backend is fixed
print: (printer) => this.domainPrinterService.printProduct({ item: item as PrinterItemDTO, printer }).toPromise(),
print: (printer) =>
this.domainPrinterService.printProduct({ item: item as PrinterItemDTO, printer }).toPromise(),
} as PrintModalData,
config: {
panelClass: [],
@@ -459,7 +482,10 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
.pipe(
first(),
switchMap((customerFeatures) => {
return this._domainCheckoutService.canSetCustomer({ processId: this.applicationService.activatedProcessId, customerFeatures });
return this._domainCheckoutService.canSetCustomer({
processId: this.applicationService.activatedProcessId,
customerFeatures,
});
}),
)
.toPromise();

View File

@@ -47,11 +47,16 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
readonly fetchingItem$ = this.select((s) => s.fetchingItem);
readonly item$ = this.select((s) => s.item);
readonly itemData$ = this.select(this.item$, (item) =>
!!item ? ({ ean: item?.product?.ean, itemId: item?.id, price: item?.catalogAvailability?.price } as ItemData) : undefined,
!!item
? ({ ean: item?.product?.ean, itemId: item?.id, price: item?.catalogAvailability?.price } as ItemData)
: undefined,
);
//#endregion
readonly isDownload$ = this.select(this.item$, (item) => !!(item?.product?.format === 'EB' || item?.product?.format === 'DL'));
readonly isDownload$ = this.select(
this.item$,
(item) => !!(item?.product?.format === 'EB' || item?.product?.format === 'DL'),
);
get processId() {
return this.get((s) => s.processId);
@@ -74,13 +79,17 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
readonly reviewRating$ = this.item$.pipe(
filter((i) => !!i),
map((i) => (i.reviews?.length > 0 ? i.reviews.map((r) => r.rating).reduce((total, num) => total + num) / i.reviews.length : 0)),
map((i) =>
i.reviews?.length > 0 ? i.reviews.map((r) => r.rating).reduce((total, num) => total + num) / i.reviews.length : 0,
),
);
readonly recommendations$ = this.item$.pipe(
filter((item) => !!item),
switchMap((item) =>
item.ids?.dig ? this.domainCatalogService.getRecommendations({ digId: item.ids['dig'] }).pipe(map((res) => res.result)) : of([]),
item.ids?.dig
? this.domainCatalogService.getRecommendations({ digId: item.ids['dig'] }).pipe(map((res) => res.result))
: of([]),
),
);
@@ -222,7 +231,9 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
//#region DIG Versandverfügbarkeit
readonly fetchingDeliveryDigAvailability$ = this.select((s) => s.fetchingDeliveryDigAvailability);
readonly deliveryDigAvailability$ = combineLatest([this.itemData$, this.isDownload$]).pipe(
tap(() => this.patchState({ fetchingDeliveryDigAvailability: true, fetchingDeliveryDigAvailabilityError: undefined })),
tap(() =>
this.patchState({ fetchingDeliveryDigAvailability: true, fetchingDeliveryDigAvailabilityError: undefined }),
),
switchMap(([item, isDownload]) =>
!!item && !isDownload
? this.domainAvailabilityService.getDigDeliveryAvailability({ item, quantity: 1 }).pipe(
@@ -245,7 +256,9 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
//#region B2B Versandverfügbarkeit
readonly fetchingDeliveryB2BAvailability$ = this.select((s) => s.fetchingDeliveryB2BAvailability);
readonly deliveryB2BAvailability$ = combineLatest([this.itemData$, this.isDownload$, this.branch$]).pipe(
tap(() => this.patchState({ fetchingDeliveryB2BAvailability: true, fetchingDeliveryB2BAvailabilityError: undefined })),
tap(() =>
this.patchState({ fetchingDeliveryB2BAvailability: true, fetchingDeliveryB2BAvailabilityError: undefined }),
),
switchMap(([item, isDownload, branch]) =>
!!item && !isDownload
? this.domainAvailabilityService.getB2bDeliveryAvailability({ item, quantity: 1, branch }).pipe(
@@ -274,7 +287,11 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
this.downloadAvailability$,
]).pipe(
withLatestFrom(this.domainAvailabilityService.sscs$),
map(([[item, isDownload, pickupAvailability, deliveryDigAvailability, deliveryB2BAvailability, downloadAvailability], sscs]) => {
map(
([
[item, isDownload, pickupAvailability, deliveryDigAvailability, deliveryB2BAvailability, downloadAvailability],
sscs,
]) => {
let availability: AvailabilityDTO;
if (isDownload) {
@@ -304,7 +321,8 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
sscText = availability?.sscText;
const sscExists = !!sscs?.find((ssc) => !!item?.id && ssc?.itemId === item.id);
const sscEqualsCatalogSsc = ssc === item.catalogAvailability.ssc && sscText === item.catalogAvailability.sscText;
const sscEqualsCatalogSsc =
ssc === item.catalogAvailability.ssc && sscText === item.catalogAvailability.sscText;
// To keep result list in sync with details page
if (!sscExists && !sscEqualsCatalogSsc) {
@@ -313,7 +331,8 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
}
return [ssc, sscText].filter((f) => !!f).join(' - ');
}),
},
),
);
constructor(
@@ -402,7 +421,10 @@ export class ArticleDetailsStore extends ComponentStore<ArticleDetailsState> {
});
async navigateBack() {
const crumb = await this._breadcrumb.getLastActivatedBreadcrumbByKey$(this._appService.activatedProcessId).pipe(first()).toPromise();
const crumb = await this._breadcrumb
.getLastActivatedBreadcrumbByKey$(this._appService.activatedProcessId)
.pipe(first())
.toPromise();
if (crumb) {
await this._router.navigate([crumb.path]);
} else {

View File

@@ -20,6 +20,9 @@ export class ArticleRecommendationsComponent {
) {}
getDetailsPath(ean?: string) {
return this._navigationService.getArticleDetailsPathByEan({ processId: this._applicationService.activatedProcessId, ean }).path;
return this._navigationService.getArticleDetailsPathByEan({
processId: this._applicationService.activatedProcessId,
ean,
}).path;
}
}

View File

@@ -76,7 +76,9 @@ export function mapFilterArrayToStringDictionary(source: Filter[]): { [key: stri
const selected = options.filter((o) => o.selected);
const selectedSubOptions: FilterOption[] = [];
const optionsWithSuboptions: FilterOption[] = options.filter((o) => (isSelectFilterOption(o) ? o?.options?.length > 0 : null));
const optionsWithSuboptions: FilterOption[] = options.filter((o) =>
isSelectFilterOption(o) ? o?.options?.length > 0 : null,
);
for (const o of optionsWithSuboptions) {
if (isSelectFilterOption(o)) {
const subOptions = o.options.filter((sO) => sO.selected);
@@ -117,7 +119,9 @@ export function mapSelectedFilterToParams(source: Filter[]): string {
const selected = options.filter((o) => o.type === 'select' && o.selected);
const selectedSubOptions: FilterOption[] = [];
const optionsWithSuboptions: FilterOption[] = options.filter((o) => (isSelectFilterOption(o) ? o?.options?.length > 0 : null));
const optionsWithSuboptions: FilterOption[] = options.filter((o) =>
isSelectFilterOption(o) ? o?.options?.length > 0 : null,
);
for (const o of optionsWithSuboptions) {
if (isSelectFilterOption(o)) {
const subOptions = o.options.filter((sO) => sO.type === 'select' && sO.selected);

View File

@@ -38,11 +38,13 @@ export class ArticleSearchFilterComponent implements OnInit, OnDestroy {
}
get sideOutlet() {
return this._activatedRoute?.parent?.children?.find((childRoute) => childRoute?.outlet === 'side')?.snapshot?.routeConfig?.path;
return this._activatedRoute?.parent?.children?.find((childRoute) => childRoute?.outlet === 'side')?.snapshot
?.routeConfig?.path;
}
get primaryOutlet() {
return this._activatedRoute?.parent?.children?.find((childRoute) => childRoute?.outlet === 'primary')?.snapshot?.routeConfig?.path;
return this._activatedRoute?.parent?.children?.find((childRoute) => childRoute?.outlet === 'primary')?.snapshot
?.routeConfig?.path;
}
get closeFilterRoute() {
@@ -146,10 +148,14 @@ export class ArticleSearchFilterComponent implements OnInit, OnDestroy {
hasSelectedOptions(filter: Filter) {
// Is Query available
const hasInputOptions = !!filter.input.find((input) => !!input.input.find((fi) => fi.hasFilterInputOptionsSelected()));
const hasInputOptions = !!filter.input.find(
(input) => !!input.input.find((fi) => fi.hasFilterInputOptionsSelected()),
);
// Are filter or filterChips selected
const hasFilterOptions = !!filter.filter.find((input) => !!input.input.find((fi) => fi.hasFilterInputOptionsSelected()));
const hasFilterOptions = !!filter.filter.find(
(input) => !!input.input.find((fi) => fi.hasFilterInputOptionsSelected()),
);
return hasInputOptions || hasFilterOptions;
}

View File

@@ -35,7 +35,10 @@ export class ArticleSearchMainComponent implements OnInit, OnDestroy {
hasFilter$ = combineLatest([this.searchService.filter$, this.searchService.defaultSettings$]).pipe(
map(([filter, defaultFilter]) => {
const filterQueryParams = filter?.getQueryParams();
return !isEqual(this.resetQueryParamsQueryAndOrderBy(filterQueryParams), Filter.create(defaultFilter).getQueryParams());
return !isEqual(
this.resetQueryParamsQueryAndOrderBy(filterQueryParams),
Filter.create(defaultFilter).getQueryParams(),
);
}),
);
@@ -165,7 +168,10 @@ export class ArticleSearchMainComponent implements OnInit, OnDestroy {
}
async updateBreadcrumb(processId: number, queryParams: Record<string, string>) {
const crumbs = await this.breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'main']).pipe(first()).toPromise();
const crumbs = await this.breadcrumb
.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'main'])
.pipe(first())
.toPromise();
crumbs.forEach((crumb) => {
this.breadcrumb.patchBreadcrumb(crumb.id, {
@@ -196,8 +202,14 @@ export class ArticleSearchMainComponent implements OnInit, OnDestroy {
}
async removeResultsAndDetailsBreadcrumbs(processId: number) {
const resultsCrumbs = await this.breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'results']).pipe(first()).toPromise();
const detailCrumbs = await this.breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'details']).pipe(first()).toPromise();
const resultsCrumbs = await this.breadcrumb
.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'results'])
.pipe(first())
.toPromise();
const detailCrumbs = await this.breadcrumb
.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'details'])
.pipe(first())
.toPromise();
resultsCrumbs?.forEach((crumb) => {
this.breadcrumb.removeBreadcrumb(crumb.id);

View File

@@ -11,13 +11,13 @@
.page-search-result-item__item-grid-container {
@apply grid grid-flow-row gap-y-[0.375rem] gap-x-6;
grid-template-areas:
'contributors contributors contributors'
'title title price'
'title title price'
'title title select'
'format format select'
'manufacturer manufacturer stock'
'misc ssc ssc';
"contributors contributors contributors"
"title title price"
"title title price"
"title title select"
"format format select"
"manufacturer manufacturer stock"
"misc ssc ssc";
}
.page-search-result-item__item-grid-container-primary {
@@ -25,9 +25,9 @@
grid-template-rows: 1.3125rem 1.3125rem auto;
grid-template-columns: 37.5% 32.5% 20% auto;
grid-template-areas:
'contributors format price .'
'title manufacturer stock select'
'title misc ssc .';
"contributors format price ."
"title manufacturer stock select"
"title misc ssc .";
}
.page-search-result-item__item-contributors {

View File

@@ -84,7 +84,10 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
hasFilter$ = combineLatest([this.searchService.filter$, this.searchService.defaultSettings$]).pipe(
map(([filter, defaultFilter]) => {
const filterQueryParams = filter?.getQueryParams();
return !isEqual(this.resetQueryParamsQueryAndOrderBy(filterQueryParams), Filter.create(defaultFilter).getQueryParams());
return !isEqual(
this.resetQueryParamsQueryAndOrderBy(filterQueryParams),
Filter.create(defaultFilter).getQueryParams(),
);
}),
);
@@ -130,7 +133,9 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
.pipe(
debounceTime(0),
switchMap(([processId, queryParams]) =>
this.application.getSelectedBranch$(processId).pipe(map((selectedBranch) => ({ processId, queryParams, selectedBranch }))),
this.application
.getSelectedBranch$(processId)
.pipe(map((selectedBranch) => ({ processId, queryParams, selectedBranch }))),
),
)
.subscribe(async ({ processId, queryParams, selectedBranch }) => {
@@ -174,7 +179,8 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
}
if (
data.items?.length === 0 &&
this.route?.parent?.children?.find((childRoute) => childRoute?.outlet === 'side')?.snapshot?.routeConfig?.path !== 'filter'
this.route?.parent?.children?.find((childRoute) => childRoute?.outlet === 'side')?.snapshot?.routeConfig
?.path !== 'filter'
) {
this.search({ clear: true });
} else {
@@ -246,7 +252,9 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
})
.navigate();
} else {
await this._navigationService.getArticleSearchResultsPath(processId, { queryParams: params }).navigate();
await this._navigationService
.getArticleSearchResultsPath(processId, { queryParams: params })
.navigate();
}
}
}
@@ -297,7 +305,11 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
scrolledIndexChange(index: number) {
const completeListFetched = this.searchService.items.length === this.searchService.hits;
if (index && !completeListFetched && this.searchService.items.length <= this.scrollContainer?.getRenderedRange()?.end) {
if (
index &&
!completeListFetched &&
this.searchService.items.length <= this.scrollContainer?.getRenderedRange()?.end
) {
this.search({ clear: false });
}
@@ -309,7 +321,11 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
async ngOnDestroy() {
this.subscriptions?.unsubscribe();
this.cacheCurrentData(this.searchService.processId, this.searchService.filter.getQueryParams(), this.searchService?.selectedBranch?.id);
this.cacheCurrentData(
this.searchService.processId,
this.searchService.filter.getQueryParams(),
this.searchService?.selectedBranch?.id,
);
await this.updateBreadcrumbs(this.searchService.processId, this.searchService.filter.getQueryParams());
this.unselectAll();
@@ -338,7 +354,8 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
}
getDetailsPath(itemId: number) {
return this._navigationService.getArticleDetailsPath({ processId: this.application.activatedProcessId, itemId }).path;
return this._navigationService.getArticleDetailsPath({ processId: this.application.activatedProcessId, itemId })
.path;
}
async updateBreadcrumbs(
@@ -380,7 +397,10 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
}
async removeDetailsBreadcrumb(processId: number) {
const crumbs = await this.breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'details']).pipe(first()).toPromise();
const crumbs = await this.breadcrumb
.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'details'])
.pipe(first())
.toPromise();
crumbs?.forEach((crumb) => this.breadcrumb.removeBreadcrumb(crumb.id));
}
@@ -495,7 +515,10 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterVi
const downloadItem: ItemData = { ean, itemId, price };
// #4180 Für Download Artikel muss hier immer zwingend der logistician gesetzt werden, da diese Artikel direkt zugeordnet dem Warenkorb hinzugefügt werden
const downloadAvailability = await this._availability.getDownloadAvailability({ item: downloadItem }).pipe(first()).toPromise();
const downloadAvailability = await this._availability
.getDownloadAvailability({ item: downloadItem })
.pipe(first())
.toPromise();
shoppingCartItem.destination = { data: { target: 16, logistician: downloadAvailability?.logistician } };
if (downloadAvailability) {
shoppingCartItem.availability = { ...shoppingCartItem.availability, ...downloadAvailability };

View File

@@ -7,8 +7,7 @@
[branchType]="1"
[value]="selectedBranch$ | async"
(valueChange)="patchProcessData($event)"
>
</shared-branch-selector>
></shared-branch-selector>
<ui-tooltip #tooltip yPosition="below" xPosition="after" [xOffset]="-263" [yOffset]="4" [closeable]="true">
{{ stockTooltipText$ | async }}
</ui-tooltip>

View File

@@ -22,7 +22,11 @@ shared-branch-selector.shared-branch-selector-opend {
@apply rounded-[5px];
}
::ng-deep page-catalog shared-branch-selector .shared-branch-selector-input-container .shared-branch-selector-input-icon {
::ng-deep
page-catalog
shared-branch-selector
.shared-branch-selector-input-container
.shared-branch-selector-input-icon {
@apply pl-2 border-l border-solid border-[#AEB7C1] transition-all duration-300 ease-in-out;
}

View File

@@ -1,4 +1,13 @@
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ElementRef,
OnDestroy,
OnInit,
Renderer2,
ViewChild,
} from '@angular/core';
import { ApplicationService } from '@core/application';
import { AuthService } from '@core/auth';
import { EnvironmentService } from '@core/environment';
@@ -68,7 +77,9 @@ export class PageCatalogComponent implements OnInit, AfterViewInit, OnDestroy {
ngOnInit() {
this.activatedProcessId$ = this.application.activatedProcessId$.pipe(map((processId) => String(processId)));
this.selectedBranch$ = this.activatedProcessId$.pipe(switchMap((processId) => this.application.getSelectedBranch$(Number(processId))));
this.selectedBranch$ = this.activatedProcessId$.pipe(
switchMap((processId) => this.application.getSelectedBranch$(Number(processId))),
);
this.stockTooltipText$ = combineLatest([this.defaultBranch$, this.selectedBranch$]).pipe(
map(([defaultBranch, selectedBranch]) => {
@@ -83,7 +94,9 @@ export class PageCatalogComponent implements OnInit, AfterViewInit, OnDestroy {
}
ngAfterViewInit(): void {
this._actions.pipe(takeUntil(this._onDestroy$), withLatestFrom(this.stockTooltipText$)).subscribe(([action, text]) => {
this._actions
.pipe(takeUntil(this._onDestroy$), withLatestFrom(this.stockTooltipText$))
.subscribe(([action, text]) => {
if (action.type === 'OPEN_TOOLTIP_NO_BRANCH_SELECTED' && !!text) {
this.branchInputNoBranchSelectedTrigger.open();
}

View File

@@ -3,7 +3,8 @@
<div class="headline">
<h1 class="title">Neuanlage</h1>
<p class="paragraph">
Hier können Sie Artikel manuell<br />
Hier können Sie Artikel manuell
<br />
oder per Dummy anlegen.
</p>
</div>
@@ -20,8 +21,7 @@
[hint]="message$ | async"
tabindex="0"
[scanner]="true"
>
</ui-searchbox>
></ui-searchbox>
</ui-form-control>
<ui-form-control label="Titel" requiredMark="*">
<input tabindex="0" uiInput formControlName="name" />
@@ -54,8 +54,7 @@
[selected]="estimatedShippingDate$ | async"
saveLabel="Übernehmen"
(save)="changeEstimatedShippingDate($event); uiDatepicker.close()"
>
</ui-datepicker>
></ui-datepicker>
</ui-form-control>
</div>
<ui-form-control label="Autor">

View File

@@ -112,7 +112,9 @@ export class CheckoutDummyComponent implements OnInit, OnDestroy {
this.control
.get('price')
.setValue(
item?.catalogAvailability?.price?.value?.value ? String(item?.catalogAvailability?.price?.value?.value).replace('.', ',') : '',
item?.catalogAvailability?.price?.value?.value
? String(item?.catalogAvailability?.price?.value?.value).replace('.', ',')
: '',
);
this.control.get('vat').setValue(item?.catalogAvailability?.price?.vat?.vatType);
}
@@ -206,12 +208,16 @@ export class CheckoutDummyComponent implements OnInit, OnDestroy {
let filter: { [key: string]: string };
if (!customer && !this._ref?.data?.changeDataFromCart) {
filter = customerFilter;
const path = this._customerNavigationService.defaultRoute({ processId: this._applicationService.activatedProcessId }).path;
const path = this._customerNavigationService.defaultRoute({
processId: this._applicationService.activatedProcessId,
}).path;
await this._router.navigate(path, {
queryParams: { customertype: filter.customertype },
});
} else {
await this._checkoutNavigationService.getCheckoutReviewPath(this._applicationService.activatedProcessId).navigate();
await this._checkoutNavigationService
.getCheckoutReviewPath(this._applicationService.activatedProcessId)
.navigate();
}
this._ref?.close();
});
@@ -224,12 +230,16 @@ export class CheckoutDummyComponent implements OnInit, OnDestroy {
let filter: { [key: string]: string };
if (!customer && !this._ref?.data?.changeDataFromCart) {
filter = customerFilter;
const path = this._customerNavigationService.defaultRoute({ processId: this._applicationService.activatedProcessId }).path;
const path = this._customerNavigationService.defaultRoute({
processId: this._applicationService.activatedProcessId,
}).path;
await this._router.navigate(path, {
queryParams: { customertype: filter.customertype },
});
} else {
await this._checkoutNavigationService.getCheckoutReviewPath(this._applicationService.activatedProcessId).navigate();
await this._checkoutNavigationService
.getCheckoutReviewPath(this._applicationService.activatedProcessId)
.navigate();
}
this._ref?.close();
});

Some files were not shown because too many files have changed in this diff Show More