mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Merge branch 'develop' into bugfix/1438-Aenderung-Benachrichtigung
This commit is contained in:
40
angular.json
40
angular.json
@@ -2016,6 +2016,46 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@domain/catalog": {
|
||||
"projectType": "library",
|
||||
"root": "apps/domain/catalog",
|
||||
"sourceRoot": "apps/domain/catalog/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"tsConfig": "apps/domain/catalog/tsconfig.lib.json",
|
||||
"project": "apps/domain/catalog/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/domain/catalog/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "apps/domain/catalog/src/test.ts",
|
||||
"tsConfig": "apps/domain/catalog/tsconfig.spec.json",
|
||||
"karmaConfig": "apps/domain/catalog/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"apps/domain/catalog/tsconfig.lib.json",
|
||||
"apps/domain/catalog/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "sales"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ItemDTO, StockInfoDTO } from '@swagger/cat';
|
||||
import { ItemDTO } from '@swagger/cat';
|
||||
import { AvailabilityDTO, BranchDTO, OLAAvailabilityDTO, StoreCheckoutService, SupplierDTO } from '@swagger/checkout';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AvailabilityService as SwaggerAvailabilityService } from '@swagger/availability';
|
||||
import { StockService } from '@swagger/cat';
|
||||
import { map, mergeMap, shareReplay, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||
import { map, shareReplay, switchMap, withLatestFrom, mergeMap } from 'rxjs/operators';
|
||||
import { isArray, isNullOrUndefined, memorize } from '@utils/common';
|
||||
import { OrderService } from '@swagger/oms';
|
||||
|
||||
@@ -39,7 +39,6 @@ export class AvailabilityService {
|
||||
withLatestFrom(takeAwaySupplier$),
|
||||
map(([stocInfos, supplier]) => {
|
||||
item.catalogAvailability;
|
||||
console.log({ stocInfos, supplier });
|
||||
const stockInfo = stocInfos.find((f) => f.branchId === branch.id && f.itemId === item.id);
|
||||
|
||||
if (isNullOrUndefined(supplier)) {
|
||||
@@ -182,13 +181,8 @@ export class AvailabilityService {
|
||||
const logistician$ = this.orderService
|
||||
.OrderGetLogisticians({})
|
||||
.pipe(map((response) => response.result.find((l) => l.logisticianNumber === '2470')));
|
||||
|
||||
return this.getPickUpAvailability({ item, quantity, branch }).pipe(
|
||||
withLatestFrom(logistician$),
|
||||
map(([availability, logistician]) => ({
|
||||
...availability,
|
||||
logistician: { id: logistician.id },
|
||||
})),
|
||||
mergeMap((availability) => logistician$.pipe(map((logistician) => ({ ...availability, logistician: { id: logistician.id } })))),
|
||||
shareReplay()
|
||||
);
|
||||
}
|
||||
|
||||
25
apps/domain/catalog/README.md
Normal file
25
apps/domain/catalog/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Catalog
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project catalog` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project catalog`.
|
||||
|
||||
> Note: Don't forget to add `--project catalog` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build catalog` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build catalog`, go to the dist folder `cd dist/catalog` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test catalog` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
32
apps/domain/catalog/karma.conf.js
Normal file
32
apps/domain/catalog/karma.conf.js
Normal file
@@ -0,0 +1,32 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/domain/catalog'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
7
apps/domain/catalog/ng-package.json
Normal file
7
apps/domain/catalog/ng-package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../../dist/domain/catalog",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
11
apps/domain/catalog/package.json
Normal file
11
apps/domain/catalog/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "@domain/catalog",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^10.1.2",
|
||||
"@angular/core": "^10.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
}
|
||||
16
apps/domain/catalog/src/lib/catalog.module.ts
Normal file
16
apps/domain/catalog/src/lib/catalog.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { DomainCatalogService } from './catalog.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [],
|
||||
exports: [],
|
||||
})
|
||||
export class DomainCatalogModule {
|
||||
static forRoot(): ModuleWithProviders<DomainCatalogModule> {
|
||||
return {
|
||||
ngModule: DomainCatalogModule,
|
||||
providers: [DomainCatalogService],
|
||||
};
|
||||
}
|
||||
}
|
||||
16
apps/domain/catalog/src/lib/catalog.service.spec.ts
Normal file
16
apps/domain/catalog/src/lib/catalog.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CatalogService } from './catalog.service';
|
||||
|
||||
describe('CatalogService', () => {
|
||||
let service: CatalogService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CatalogService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
14
apps/domain/catalog/src/lib/catalog.service.ts
Normal file
14
apps/domain/catalog/src/lib/catalog.service.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PromotionService } from '@swagger/cat';
|
||||
import { memorize } from '@utils/common';
|
||||
import { shareReplay } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class DomainCatalogService {
|
||||
constructor(private promotionService: PromotionService) {}
|
||||
|
||||
@memorize()
|
||||
getPromotionPoints({ items }: { items: { id: number; quantity: number; price?: number }[] }) {
|
||||
return this.promotionService.PromotionLesepunkte(items).pipe(shareReplay());
|
||||
}
|
||||
}
|
||||
6
apps/domain/catalog/src/public-api.ts
Normal file
6
apps/domain/catalog/src/public-api.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
* Public API Surface of catalog
|
||||
*/
|
||||
|
||||
export * from './lib/catalog.service';
|
||||
export * from './lib/catalog.module';
|
||||
24
apps/domain/catalog/src/test.ts
Normal file
24
apps/domain/catalog/src/test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
25
apps/domain/catalog/tsconfig.lib.json
Normal file
25
apps/domain/catalog/tsconfig.lib.json
Normal file
@@ -0,0 +1,25 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
10
apps/domain/catalog/tsconfig.lib.prod.json
Normal file
10
apps/domain/catalog/tsconfig.lib.prod.json
Normal file
@@ -0,0 +1,10 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
17
apps/domain/catalog/tsconfig.spec.json
Normal file
17
apps/domain/catalog/tsconfig.spec.json
Normal file
@@ -0,0 +1,17 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
17
apps/domain/catalog/tslint.json
Normal file
17
apps/domain/catalog/tslint.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { OrderDTO, OrderListItemDTO, OrderService } from '@swagger/oms';
|
||||
import { OrderDTO, OrderListItemDTO, OrderService, StatusValues, ValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO } from '@swagger/oms';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@@ -22,4 +22,20 @@ export class OmsService {
|
||||
getBranches() {
|
||||
return this.orderService.OrderGetBranches({});
|
||||
}
|
||||
|
||||
changeOrderStatus(
|
||||
orderId: number,
|
||||
orderItemId: number,
|
||||
orderItemSubsetId: number,
|
||||
data: StatusValues
|
||||
): Observable<ValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO> {
|
||||
return this.orderService
|
||||
.OrderChangeStatus({
|
||||
data,
|
||||
orderId,
|
||||
orderItemId,
|
||||
orderItemSubsetId,
|
||||
})
|
||||
.pipe(map((o) => o.result));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import { PurchasingOptionsModalComponent, PurchasingOptionsModalData } from '../
|
||||
import { PurchasingOptions } from '../modals/purchasing-options-modal/purchasing-options-modal.store';
|
||||
import { Subject } from 'rxjs';
|
||||
import { StringDictionary } from '@cmf/core';
|
||||
import { DomainCatalogService } from '@domain/catalog';
|
||||
|
||||
@Component({
|
||||
selector: 'page-checkout-review',
|
||||
@@ -77,8 +78,17 @@ export class CheckoutReviewComponent {
|
||||
);
|
||||
|
||||
totalReadingPoints$ = this.items$.pipe(
|
||||
takeUntil(this._orderCompleted),
|
||||
map((items) => items.reduce((total, item) => total + item?.promotion?.points * item?.quantity, 0))
|
||||
switchMap((displayOrders) =>
|
||||
this.domainCatalogService
|
||||
.getPromotionPoints({
|
||||
items: displayOrders.map((i) => ({
|
||||
id: Number(i.product?.catalogProductNumber),
|
||||
quantity: i.quantity,
|
||||
price: i.unitPrice?.value?.value,
|
||||
})),
|
||||
})
|
||||
.pipe(map((response) => Object.values(response.result).reduce((sum, points) => sum + points, 0)))
|
||||
)
|
||||
);
|
||||
|
||||
customerFeatures$ = this.applicationService.activatedProcessId$.pipe(
|
||||
@@ -98,7 +108,8 @@ export class CheckoutReviewComponent {
|
||||
private uiModal: UiModalService,
|
||||
private sso: SsoService,
|
||||
private router: Router,
|
||||
private cdr: ChangeDetectorRef
|
||||
private cdr: ChangeDetectorRef,
|
||||
private domainCatalogService: DomainCatalogService
|
||||
) {}
|
||||
|
||||
async changeItem(shoppingCartItem: ShoppingCartItemDTO) {
|
||||
@@ -162,38 +173,38 @@ export class CheckoutReviewComponent {
|
||||
let availableOptions: PurchasingOptions[] = [];
|
||||
const availabilities: StringDictionary<AvailabilityDTO> = {};
|
||||
|
||||
if (takeAwayAvailability) {
|
||||
if (takeAwayAvailability && this.availabilityService.isAvailable({ availability: takeAwayAvailability })) {
|
||||
availableOptions.push('take-away');
|
||||
availabilities['take-away'] = takeAwayAvailability;
|
||||
}
|
||||
|
||||
if (downloadAvailability) {
|
||||
if (downloadAvailability && this.availabilityService.isAvailable({ availability: downloadAvailability })) {
|
||||
availableOptions.push('download');
|
||||
availabilities['download'] = downloadAvailability;
|
||||
}
|
||||
|
||||
if (pickupAvailability) {
|
||||
if (pickupAvailability && this.availabilityService.isAvailable({ availability: pickupAvailability })) {
|
||||
availableOptions.push('pick-up');
|
||||
availabilities['pick-up'] = pickupAvailability;
|
||||
if (!customerFeatures?.webshop) {
|
||||
if (!customerFeatures?.webshop && this.availabilityService.isAvailable({ availability: b2bAvailability })) {
|
||||
availableOptions.push('b2b-delivery');
|
||||
availabilities['b2b-delivery'] = b2bAvailability;
|
||||
}
|
||||
}
|
||||
|
||||
if (digAvailability && !customerFeatures?.b2b) {
|
||||
if (digAvailability && this.availabilityService.isAvailable({ availability: digAvailability }) && !customerFeatures?.b2b) {
|
||||
console.log('digavailability', digAvailability);
|
||||
availableOptions.push('dig-delivery');
|
||||
availabilities['dig-delivery'] = digAvailability;
|
||||
}
|
||||
|
||||
if (
|
||||
availableOptions.find((o) => o === 'dig-delivery') &&
|
||||
availableOptions.find((o) => o === 'b2b-delivery') &&
|
||||
(!customerFeatures || (!customerFeatures?.b2b && customerFeatures?.webshop))
|
||||
) {
|
||||
availableOptions.push('delivery');
|
||||
availabilities['delivery'] = await this.availabilityService.getDeliveryAvailability({ item, quantity }).toPromise();
|
||||
availableOptions = availableOptions.filter((option) => !(option === 'dig-delivery' || option === 'b2b-delivery'));
|
||||
if (availableOptions.includes('dig-delivery') && availableOptions.includes('b2b-delivery')) {
|
||||
let shippingAvailability = await this.availabilityService.getDeliveryAvailability({ item, quantity }).toPromise();
|
||||
if (shippingAvailability && this.availabilityService.isAvailable({ availability: shippingAvailability })) {
|
||||
availableOptions.push('delivery');
|
||||
availabilities['delivery'] = shippingAvailability;
|
||||
availableOptions = availableOptions.filter((option) => !(option === 'dig-delivery' || option === 'b2b-delivery'));
|
||||
}
|
||||
}
|
||||
|
||||
let option: PurchasingOptions;
|
||||
|
||||
@@ -48,23 +48,23 @@
|
||||
<div class="row item-group-header">
|
||||
<ui-icon
|
||||
class="icon-order-type"
|
||||
[size]="displayOrder.features?.orderType === 'B2B-Versand' ? '50px' : '25px'"
|
||||
[size]="displayOrder.items[0]?.features?.orderType === 'B2B-Versand' ? '50px' : '25px'"
|
||||
[icon]="
|
||||
displayOrder.features?.orderType === 'Abholung'
|
||||
displayOrder.items[0]?.features?.orderType === 'Abholung'
|
||||
? 'box_out'
|
||||
: displayOrder.features?.orderType === 'Versand'
|
||||
: displayOrder.items[0]?.features?.orderType === 'Versand'
|
||||
? 'truck'
|
||||
: displayOrder.features?.orderType === 'Rücklage'
|
||||
: displayOrder.items[0]?.features?.orderType === 'Rücklage'
|
||||
? 'shopping_bag'
|
||||
: displayOrder.features?.orderType === 'B2B-Versand'
|
||||
: displayOrder.items[0]?.features?.orderType === 'B2B-Versand'
|
||||
? 'truck_b2b'
|
||||
: displayOrder.features?.orderType === 'Download'
|
||||
: displayOrder.items[0]?.features?.orderType === 'Download'
|
||||
? 'download'
|
||||
: 'truck'
|
||||
"
|
||||
></ui-icon>
|
||||
<div class="label">
|
||||
{{ displayOrder.features?.orderType }}
|
||||
{{ displayOrder.items[0]?.features?.orderType }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -85,17 +85,24 @@
|
||||
<span class="separator">|</span>
|
||||
<span class="contributors">{{ order?.product?.contributors }}</span>
|
||||
</div>
|
||||
<div class="delivery-row" *ngIf="order?.features?.orderType">
|
||||
<ng-container *ngIf="order?.features?.orderType === 'Abholung'">
|
||||
<div class="delivery-row" [ngSwitch]="order?.features?.orderType">
|
||||
<ng-container *ngSwitchCase="'Abholung'">
|
||||
<span class="supplier">{{ (order?.subsetItems)[0].supplierLabel }}</span>
|
||||
<span class="separator">|</span>
|
||||
<span class="order-type">Abholung ab {{ (order?.subsetItems)[0]?.estimatedShippingDate | date }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="['Versand', 'B2B-Versand', 'DIG-Versand'].indexOf(order?.features?.orderType) > -1">
|
||||
<ng-container *ngSwitchCase="['Versand', 'B2B-Versand', 'DIG-Versand'].indexOf(order?.features?.orderType) > -1">
|
||||
<span class="supplier">{{ (order?.subsetItems)[0].supplierLabel }}</span>
|
||||
<span class="separator">|</span>
|
||||
<span class="order-type">Versanddatum {{ (order?.subsetItems)[0]?.estimatedShippingDate | date }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchDefault>
|
||||
<ng-container *ngIf="(order?.subsetItems)[0].supplierLabel; let supplierLabel">
|
||||
<span class="supplier">{{ supplierLabel }}</span>
|
||||
<span class="separator">|</span>
|
||||
</ng-container>
|
||||
<span class="order-type">{{ order?.features?.orderType }}</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -118,5 +125,9 @@
|
||||
<div class="total-price">Gesamtsumme {{ totalPrice$ | async | currency: ' ' }} {{ totalPriceCurrency$ | async }}</div>
|
||||
<div class="price-info" *ngIf="containsDeliveryOrder$ | async">ohne Versandkosten</div>
|
||||
</div>
|
||||
|
||||
<div class="actions" *ngIf="(takeNowOrders$ | async)?.length === 1 && (isB2BCustomer$ | async)">
|
||||
<button class="cta-shelf" (click)="navigateToShelf()">Zur Warenausgabe</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
box-shadow: 0px -2px 24px 0px #dce2e9;
|
||||
|
||||
.overview {
|
||||
@apply flex flex-row justify-between;
|
||||
@apply flex flex-row items-center justify-between;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,12 @@
|
||||
.price-info {
|
||||
@apply text-right text-sm;
|
||||
}
|
||||
|
||||
.actions {
|
||||
.cta-shelf {
|
||||
@apply bg-brand text-white font-bold text-lg outline-none border-none rounded-full px-6 py-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
|
||||
@@ -2,7 +2,12 @@ import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { DomainCheckoutService } from '@domain/checkout';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { PrintOrderComponent } from '@modal/printer';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { first, map, switchMap } from 'rxjs/operators';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { Router } from '@angular/router';
|
||||
import { OmsService } from '@domain/oms';
|
||||
import { DomainCatalogService } from '@domain/catalog';
|
||||
import { DisplayOrderItemDTO } from '@swagger/oms';
|
||||
|
||||
@Component({
|
||||
selector: 'page-checkout-summary',
|
||||
@@ -23,12 +28,18 @@ export class CheckoutSummaryComponent {
|
||||
);
|
||||
|
||||
totalReadingPoints$ = this.displayOrders$.pipe(
|
||||
map((displayOrders) =>
|
||||
displayOrders.reduce(
|
||||
(total, displayOrder) =>
|
||||
total + displayOrder?.items?.reduce((subTotal, order) => subTotal + order?.promotion?.points * order?.quantity, 0),
|
||||
0
|
||||
)
|
||||
switchMap((displayOrders) =>
|
||||
this.domainCatalogService
|
||||
.getPromotionPoints({
|
||||
items: displayOrders
|
||||
.reduce<DisplayOrderItemDTO[]>((items, order) => [...items, ...order.items], [])
|
||||
.map((i) => ({
|
||||
id: Number(i.product?.catalogProductNumber),
|
||||
quantity: i.quantity,
|
||||
price: i.price?.value?.value,
|
||||
})),
|
||||
})
|
||||
.pipe(map((response) => Object.values(response.result).reduce((sum, points) => sum + points, 0)))
|
||||
)
|
||||
);
|
||||
|
||||
@@ -51,12 +62,52 @@ export class CheckoutSummaryComponent {
|
||||
)
|
||||
);
|
||||
|
||||
constructor(private domainCheckoutService: DomainCheckoutService, private uiModal: UiModalService) {}
|
||||
isB2BCustomer$ = this.displayOrders$.pipe(
|
||||
switchMap((o) =>
|
||||
this.customerService
|
||||
.getCustomers(o[0].buyerNumber, { take: 5 })
|
||||
.pipe(map((customers) => customers.result[0].features?.find((f) => f.enabled && f.key === 'b2b') != null))
|
||||
)
|
||||
);
|
||||
|
||||
takeNowOrders$ = this.displayOrders$.pipe(
|
||||
map((displayOrders) => displayOrders.filter((o) => o.items.find((oi) => oi.features?.orderType === 'Rücklage') != null))
|
||||
);
|
||||
|
||||
constructor(
|
||||
private domainCheckoutService: DomainCheckoutService,
|
||||
private customerService: CrmCustomerService,
|
||||
private domainCatalogService: DomainCatalogService,
|
||||
private router: Router,
|
||||
private omsService: OmsService,
|
||||
private uiModal: UiModalService
|
||||
) {}
|
||||
|
||||
openPrintModal(id: number) {
|
||||
this.uiModal.open({
|
||||
content: PrintOrderComponent,
|
||||
data: id,
|
||||
data: [id],
|
||||
});
|
||||
}
|
||||
|
||||
async navigateToShelf() {
|
||||
let takeNowOrders = await this.takeNowOrders$.pipe(first()).toPromise();
|
||||
if (takeNowOrders.length != 1) return;
|
||||
|
||||
try {
|
||||
for (const takeNowOrder of takeNowOrders) {
|
||||
for (const orderItem of takeNowOrder.items.filter((item) => item.features?.orderType === 'Rücklage')) {
|
||||
await this.omsService
|
||||
.changeOrderStatus(takeNowOrder.id, orderItem.id, orderItem.subsetItems[0]?.id, {
|
||||
processingStatus: 128,
|
||||
})
|
||||
.toPromise();
|
||||
}
|
||||
}
|
||||
|
||||
this.router.navigate(['shelf', 'details', 'order', takeNowOrders[0].orderNumber, 128]);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,5 +99,5 @@ img.thumbnail {
|
||||
}
|
||||
|
||||
.quantity-error {
|
||||
@apply text-brand font-bold text-sm mt-2;
|
||||
@apply text-dark-goldenrod font-bold text-sm mt-2;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,10 @@ export class PurchasingOptionsModalComponent {
|
||||
const newItem: AddToShoppingCartDTO = {
|
||||
quantity,
|
||||
availability,
|
||||
product: item.product,
|
||||
product: {
|
||||
catalogProductNumber: '',
|
||||
...item.product,
|
||||
},
|
||||
promotion: { points: item.promoPoints },
|
||||
};
|
||||
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
<div class="order-col bold">
|
||||
{{ order.processingStatus | processingStatus }}
|
||||
</div>
|
||||
<div class="order-col">{{ order.orderType | orderType }} | {{ order.shopName }}</div>
|
||||
<div class="order-col channel">
|
||||
{{ order.clientChannel | clientChannel }} <span *ngIf="(order.clientChannel | clientChannel) != ''">|</span>
|
||||
{{ order | orderTarget }}
|
||||
</div>
|
||||
<div class="order-col">{{ order.orderValue | currency: ' ' }} {{ order.currency }} | {{ order.itemsCount }} Artikel</div>
|
||||
<a [routerLink]="['/customer', customer?.id, 'order', order?.id]" class="order-col details">Details</a>
|
||||
</div>
|
||||
|
||||
@@ -57,7 +57,11 @@ h1 {
|
||||
}
|
||||
|
||||
.order-row {
|
||||
@apply flex flex-row justify-around bg-white py-4;
|
||||
@apply flex flex-row justify-between bg-white py-4 px-4;
|
||||
}
|
||||
|
||||
.channel {
|
||||
width: 230px;
|
||||
}
|
||||
|
||||
.details {
|
||||
|
||||
@@ -4,10 +4,10 @@ import { CrmCustomerService } from '@domain/crm';
|
||||
import { CustomerDTO } from '@swagger/crm';
|
||||
|
||||
import { first, map, shareReplay, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||
import { OrderItemDTO, OrderListItemDTO } from '@swagger/oms';
|
||||
import { OrderListItemDTO } from '@swagger/oms';
|
||||
import { OmsService } from '@domain/oms';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { BehaviorSubject, combineLatest, merge, of, Subscription } from 'rxjs';
|
||||
import { BehaviorSubject, combineLatest, Subscription } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-orders',
|
||||
|
||||
@@ -15,8 +15,10 @@ export class CantAddCustomerToCartModalComponent {
|
||||
}
|
||||
|
||||
get option() {
|
||||
return this.ref.data.upgradeableTo?.options.values.find((upgradeOption) =>
|
||||
this.ref.data.required.options.values.some((requiredOption) => upgradeOption.key === requiredOption.key)
|
||||
return (
|
||||
this.ref.data.upgradeableTo?.options.values.find((upgradeOption) =>
|
||||
this.ref.data.required.options.values.some((requiredOption) => upgradeOption.key === requiredOption.key)
|
||||
) || { value: this.queryParams }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
22
apps/page/customer/src/lib/pipes/client-channel.pipe.ts
Normal file
22
apps/page/customer/src/lib/pipes/client-channel.pipe.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { OrderType } from '@swagger/oms';
|
||||
|
||||
@Pipe({
|
||||
name: 'clientChannel',
|
||||
})
|
||||
export class ClientChannelPipe implements PipeTransform {
|
||||
clientChannelText = {
|
||||
0: '',
|
||||
1: '',
|
||||
2: 'Filiale',
|
||||
4: 'HSC',
|
||||
8: 'Online',
|
||||
16: 'App',
|
||||
24: 'Mobile Shop',
|
||||
32: '',
|
||||
};
|
||||
|
||||
transform(value: OrderType): string {
|
||||
return this.clientChannelText[value] || '';
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ export * from './country.pipe';
|
||||
export * from './gender.pipe';
|
||||
export * from './address.pipe';
|
||||
export * from './order-type.pipe';
|
||||
export * from './client-channel.pipe';
|
||||
export * from './order-status.pipe';
|
||||
export * from './order-target.pipe';
|
||||
export * from './payment-type.pipe';
|
||||
export * from './processing-status.pipe';
|
||||
export * from './pipes.module';
|
||||
|
||||
17
apps/page/customer/src/lib/pipes/order-target.pipe.ts
Normal file
17
apps/page/customer/src/lib/pipes/order-target.pipe.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { OrderListItemDTO } from '@swagger/oms';
|
||||
|
||||
@Pipe({ name: 'orderTarget' })
|
||||
export class OrderTargetPipe implements PipeTransform {
|
||||
transform(orderListItem: OrderListItemDTO): any {
|
||||
if (orderListItem.orderType === 2) {
|
||||
return 'Versand';
|
||||
}
|
||||
|
||||
if (orderListItem.targetBranchName) {
|
||||
return orderListItem.targetBranchName;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,31 @@ import { GenderPipe } from './gender.pipe';
|
||||
import { OrderTypePipe } from './order-type.pipe';
|
||||
import { ProcessingStatusPipe } from './processing-status.pipe';
|
||||
import { PaymentTypePipe } from './payment-type.pipe';
|
||||
import { ClientChannelPipe } from './client-channel.pipe';
|
||||
import { OrderTargetPipe } from './order-target.pipe';
|
||||
|
||||
@NgModule({
|
||||
exports: [CountryPipe, GenderPipe, AddressPipe, OrderTypePipe, ProcessingStatusPipe, OrderStatusPipe, PaymentTypePipe],
|
||||
declarations: [CountryPipe, GenderPipe, AddressPipe, OrderTypePipe, ProcessingStatusPipe, OrderStatusPipe, PaymentTypePipe],
|
||||
exports: [
|
||||
CountryPipe,
|
||||
GenderPipe,
|
||||
AddressPipe,
|
||||
OrderTypePipe,
|
||||
ProcessingStatusPipe,
|
||||
OrderStatusPipe,
|
||||
PaymentTypePipe,
|
||||
ClientChannelPipe,
|
||||
OrderTargetPipe,
|
||||
],
|
||||
declarations: [
|
||||
CountryPipe,
|
||||
GenderPipe,
|
||||
AddressPipe,
|
||||
OrderTypePipe,
|
||||
ProcessingStatusPipe,
|
||||
OrderStatusPipe,
|
||||
PaymentTypePipe,
|
||||
ClientChannelPipe,
|
||||
OrderTargetPipe,
|
||||
],
|
||||
})
|
||||
export class CustomerPipesModule {}
|
||||
|
||||
@@ -66,6 +66,7 @@ import { CDN_PRODUCT_PICTURES } from './tokens';
|
||||
import { DateAdapter, NativeDateAdapter } from '@ui/common';
|
||||
import { ApplicationRefactImp } from './refact-imp/application.refact-imp';
|
||||
import { CDN_PRODUCT_IMAGE } from 'apps/cdn/product-image/src/lib/tokens';
|
||||
import { DomainCatalogModule } from '@domain/catalog';
|
||||
registerLocaleData(localeDe, localeDeExtra);
|
||||
registerLocaleData(localeDe, 'de', localeDeExtra);
|
||||
|
||||
@@ -140,6 +141,7 @@ export function cdnProdutctPictures(config: AppConfiguration): string {
|
||||
* @core Domain
|
||||
*/
|
||||
DomainCheckoutModule,
|
||||
DomainCatalogModule.forRoot(),
|
||||
|
||||
/**
|
||||
* @ui Modules
|
||||
|
||||
386
package-lock.json
generated
386
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -188,6 +188,9 @@
|
||||
],
|
||||
"@modal/history": [
|
||||
"apps/modal/history/src/public-api.ts"
|
||||
],
|
||||
"@domain/catalog": [
|
||||
"apps/domain/catalog/src/public-api.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user