MERGE branch integration into develop (CONFLICTS resolved)

This commit is contained in:
Michael Auer
2020-09-09 15:24:42 +02:00
11 changed files with 413 additions and 137 deletions

16
.npmrc
View File

@@ -1,13 +1,3 @@
registry=https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/
always-auth=true
; Treat this auth token like a password. Do not share it with anyone, including Microsoft support. This token expires on or before 25.08.2020.
; begin auth token
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/:username=hugendubel
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/:_password=M2JkaDdwNjIzbWVoZGlmeDU3N2Ficjc3M252NXBkaWg1M2VtaW94dXp5amwyejNkaW5yYQ==
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/:email=npm requires email to be set but doesn't use the value
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/:username=hugendubel
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/:_password=M2JkaDdwNjIzbWVoZGlmeDU3N2Ficjc3M252NXBkaWg1M2VtaW94dXp5amwyejNkaW5yYQ==
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/:email=npm requires email to be set but doesn't use the value
; end auth token
@isa:registry=https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/
@cmf:registry=https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/
always-auth=true

View File

@@ -10,7 +10,7 @@ import { ErrorService } from './error.service';
@Component({
selector: 'app-error',
templateUrl: './error.component.html',
styleUrls: ['./error.component.scss']
styleUrls: ['./error.component.scss'],
})
export class ErrorComponent implements OnInit, OnDestroy {
id = 'error-modal';
@@ -42,7 +42,7 @@ export class ErrorComponent implements OnInit, OnDestroy {
this.formatInvalidProperties(invalidProperties);
}
this.title = logout ? 'Willkommen zurück!' : 'Irgendwas hat nicht funktioniert…';
this.message = logout ? 'Sie waren seit 5 Stunden nicht in der ISA.<br> Bitte melden Sie sich erneut an.' : '';
this.message = logout ? 'Sie waren zu lange nicht in der ISA aktiv.<br>Bitte melden Sie sich erneut an.' : '';
if (this.validMessageCodes.includes(code) && !isNullOrUndefined(message)) {
this.message = message;
}
@@ -76,13 +76,9 @@ export class ErrorComponent implements OnInit, OnDestroy {
}
formatInvalidProperties(invalidProperties: string) {
const properties = invalidProperties
.replace('{', '')
.replace('}', '')
.replace(/"/g, '')
.split(',');
const properties = invalidProperties.replace('{', '').replace('}', '').replace(/"/g, '').split(',');
if (properties && properties.length > 0) {
this.invalidAttributes = properties.map(propertie => {
this.invalidAttributes = properties.map((propertie) => {
const keyValuePropertie = propertie.split(':');
return { key: keyValuePropertie[0], value: keyValuePropertie[1] };
});

View File

@@ -31,6 +31,7 @@ import { CollectingShelfSelectors } from '../store/selectors/collecting-shelf.se
})
export class CollectingShelfService {
constructor(
private abholfachService: AbholfachService,
private omsService: OrderService,
private abholfach: AbholfachService,
private mapper: ShelfMapping,
@@ -60,7 +61,11 @@ export class CollectingShelfService {
throw new Error(response.message);
}
return {
result: this.mapper.fromOrderItemListItemDTOArrayToCollectingShelfOrder(response.result, this, skip === 0),
result: this.mapper.fromOrderItemListItemDTOArrayToCollectingShelfOrder(
response.result,
this,
skip === 0
),
hits: response.hits,
};
})
@@ -68,7 +73,9 @@ export class CollectingShelfService {
}
searchShelfCached() {
return this.store.select(CollectingShelfSelectors.getCachedResults).pipe(filter((data) => !isNullOrUndefined(data)));
return this.store
.select(CollectingShelfSelectors.getCachedResults)
.pipe(filter((data) => !isNullOrUndefined(data)));
}
searchShelfHasResults(input: string, branchNumber: string): Observable<number> {
@@ -146,7 +153,9 @@ export class CollectingShelfService {
);
}
getOrderItemSubsetByOrderItemSubsetId(orderItemSubsetId: number): Observable<OrderItemSubsetDTO> {
getOrderItemSubsetByOrderItemSubsetId(
orderItemSubsetId: number
): Observable<OrderItemSubsetDTO> {
return this.omsService.OrderGetOrderItemSubset(orderItemSubsetId).pipe(
map((response) => {
if (response.error) {
@@ -157,13 +166,18 @@ export class CollectingShelfService {
);
}
getOrdersByCompartmentNumber(compartmentNumbers: string[], orderId: number): Observable<OrderDTO> {
getOrdersByCompartmentNumber(
compartmentNumbers: string[],
orderId: number
): Observable<OrderDTO> {
return this.omsService.OrderGetOrdersByCompartment(compartmentNumbers).pipe(
map((response) => {
if (response.error) {
throw new Error(response.message);
}
return response.result ? response.result.find((o) => +o.id === +orderId) : null;
return response.result
? response.result.find((o) => +o.id === +orderId)
: null;
})
);
}
@@ -222,8 +236,16 @@ export class CollectingShelfService {
);
}
extendPickUpPeriod(orderId: number, orderItemId: number, orderItemSubsetId: number, date: Date): Observable<OrderItemSubsetDTO> {
const compartmentStop = this.datepipe.transform(date, BACKEND_API_TIMESTAMP_FORMAT);
extendPickUpPeriod(
orderId: number,
orderItemId: number,
orderItemSubsetId: number,
date: Date
): Observable<OrderItemSubsetDTO> {
const compartmentStop = this.datepipe.transform(
date,
BACKEND_API_TIMESTAMP_FORMAT
);
const params = <OrderService.OrderPatchOrderItemSubsetParams>{
orderId,
orderItemId,
@@ -242,8 +264,16 @@ export class CollectingShelfService {
);
}
updateEstimatedShippingDate(orderId: number, orderItemId: number, orderItemSubsetId: number, date: Date): Observable<OrderItemSubsetDTO> {
const estimatedShippingDate = this.datepipe.transform(date, BACKEND_API_TIMESTAMP_FORMAT);
updateEstimatedShippingDate(
orderId: number,
orderItemId: number,
orderItemSubsetId: number,
date: Date
): Observable<OrderItemSubsetDTO> {
const estimatedShippingDate = this.datepipe.transform(
date,
BACKEND_API_TIMESTAMP_FORMAT
);
const params = <OrderService.OrderPatchOrderItemSubsetParams>{
orderId,
orderItemId,
@@ -262,7 +292,11 @@ export class CollectingShelfService {
);
}
patchOrderItem(orderId: number, orderItemId: number, orderItem: OrderItemDTO) {
patchOrderItem(
orderId: number,
orderItemId: number,
orderItem: OrderItemDTO
) {
const params = <OrderService.OrderPatchOrderItemParams>{
orderId,
orderItemId,
@@ -347,7 +381,9 @@ export class CollectingShelfService {
if (response.error) {
throw new Error(response.message);
}
return response.result && response.result[0] ? response.result[0].supplierDescription : null;
return response.result && response.result[0]
? response.result[0].supplierDescription
: null;
})
);
}
@@ -374,14 +410,23 @@ export class CollectingShelfService {
);
}
processOrderCompartmentNumber(orders: OrderItemListItemDTO[], order: OrderItemListItemDTO, index: number, firstBatch: boolean) {
processOrderCompartmentNumber(
orders: OrderItemListItemDTO[],
order: OrderItemListItemDTO,
index: number,
firstBatch: boolean
) {
const tempOrders = [...orders];
const prevOrders = tempOrders.slice(0, index);
let hideCompartmentNumber = false;
if (index === 0 && !firstBatch) {
const olderOrders = this.store.selectSnapshot(CollectingShelfSelectors.getShelfOrders);
const olderOrders = this.store.selectSnapshot(
CollectingShelfSelectors.getShelfOrders
);
if (olderOrders && olderOrders.length > 0) {
const filteredOrders = olderOrders.filter((t) => t.orderId === order.orderId);
const filteredOrders = olderOrders.filter(
(t) => t.orderId === order.orderId
);
if (
order.compartmentCode &&
order.processingStatus &&
@@ -390,8 +435,10 @@ export class CollectingShelfService {
filteredOrders[filteredOrders.length - 1] &&
filteredOrders[filteredOrders.length - 1].compartmentCode &&
filteredOrders[filteredOrders.length - 1].processingStatus &&
filteredOrders[filteredOrders.length - 1].compartmentCode === order.compartmentCode &&
filteredOrders[filteredOrders.length - 1].processingStatus === order.processingStatus
filteredOrders[filteredOrders.length - 1].compartmentCode ===
order.compartmentCode &&
filteredOrders[filteredOrders.length - 1].processingStatus ===
order.processingStatus
) {
hideCompartmentNumber = true;
}
@@ -404,8 +451,10 @@ export class CollectingShelfService {
prevOrders[prevOrders.length - 1] &&
prevOrders[prevOrders.length - 1].compartmentCode &&
prevOrders[prevOrders.length - 1].processingStatus &&
prevOrders[prevOrders.length - 1].compartmentCode === order.compartmentCode &&
prevOrders[prevOrders.length - 1].processingStatus === order.processingStatus
prevOrders[prevOrders.length - 1].compartmentCode ===
order.compartmentCode &&
prevOrders[prevOrders.length - 1].processingStatus ===
order.processingStatus
) {
hideCompartmentNumber = true;
}

View File

@@ -3,7 +3,10 @@ import * as actions from '../actions/cart-entry.actions';
import { CartEntry } from '../../models/cart-entry.model';
import { SetCartData } from '../actions/cart.actions';
import { BranchSelectors } from '../selectors/branch.selector';
import { DeliveryOption, DeliveryType } from '../../models/delivery-option.model';
import {
DeliveryOption,
DeliveryType,
} from '../../models/delivery-option.model';
import {
ShippingTarget,
BranchDTO,
@@ -43,16 +46,29 @@ export class CartEntryStateModel {
},
})
export class CartEntryState {
constructor(private store: Store, private checkoutService: CheckoutService, private customerMapping: CustomerMapping) {}
constructor(
private store: Store,
private checkoutService: CheckoutService,
private customerMapping: CustomerMapping
) {}
@Action(actions.SetCartEntry)
setCartEntryData(
ctx: StateContext<CartEntryStateModel>,
{ quantity, deliveryType, bookId, availability, branch, promoPoints }: actions.SetCartEntry
{
quantity,
deliveryType,
bookId,
availability,
branch,
promoPoints,
}: actions.SetCartEntry
) {
const products = this.store.selectSnapshot(ProductSelectors.getProducts);
const branches = this.store.selectSnapshot(BranchSelectors.getBranches);
const currentProcess = this.store.selectSnapshot(ProcessSelectors.getCurrentProcess);
const currentProcess = this.store.selectSnapshot(
ProcessSelectors.getCurrentProcess
);
const state = ctx.getState();
if (!currentProcess || !currentProcess.cartId) {
@@ -60,11 +76,22 @@ export class CartEntryState {
}
const cartId = currentProcess.cartId;
const existingItemId = this.itemExistInCart(state.cartEntries, bookId, deliveryType, branch, cartId);
const existingItemId = this.itemExistInCart(
state.cartEntries,
bookId,
deliveryType,
branch,
cartId
);
if (existingItemId) {
this.store.dispatch(
new actions.UpdateCartEntryQuantity(state.cartEntries[existingItemId].quantity + quantity, existingItemId, availability, '')
new actions.UpdateCartEntryQuantity(
state.cartEntries[existingItemId].quantity + quantity,
existingItemId,
availability,
''
)
);
} else {
return this.addItemToCart$(
@@ -83,21 +110,43 @@ export class CartEntryState {
@Action(actions.UpdateCartEntryType)
updateCartEntryData(
ctx: StateContext<CartEntryStateModel>,
{ deliveryType, bookId, availability, branch, oldDeliveryType, oldBranch }: actions.UpdateCartEntryType
{
deliveryType,
bookId,
availability,
branch,
oldDeliveryType,
oldBranch,
}: actions.UpdateCartEntryType
) {
const branches = this.store.selectSnapshot(BranchSelectors.getBranches);
const currentProcess = this.store.selectSnapshot(ProcessSelectors.getCurrentProcess);
const currentProcess = this.store.selectSnapshot(
ProcessSelectors.getCurrentProcess
);
if (!currentProcess) {
return;
}
const state = ctx.getState();
const existingItemId = this.itemExistInCart(state.cartEntries, bookId, oldDeliveryType, oldBranch, currentProcess.cartId);
const existingItemId = this.itemExistInCart(
state.cartEntries,
bookId,
oldDeliveryType,
oldBranch,
currentProcess.cartId
);
const newBranch = branches[branch];
const itemToUpdate = { ...state.cartEntries[existingItemId] };
const cartEntries = { ...state.cartEntries };
const destination = this.createDestinationObject(deliveryType, newBranch, availability as any);
const ava: UpdateDestinationAvailability = this.availibilityObjectForUpdate(availability as any, deliveryType);
const destination = this.createDestinationObject(
deliveryType,
newBranch,
availability as any
);
const ava: UpdateDestinationAvailability = this.availibilityObjectForUpdate(
availability as any,
deliveryType
);
itemToUpdate.quantity = itemToUpdate.quantity;
itemToUpdate.deliveryType = deliveryType;
@@ -129,20 +178,33 @@ export class CartEntryState {
: undefined;
cartEntries[existingItemId] = itemToUpdate;
return this.checkoutService.updateItemInCart(currentProcess.cartId, existingItemId, destination, itemToUpdate.quantity, ava).pipe(
tap(() => {
ctx.patchState({
cartEntries,
});
this.syncApiState(cartEntries);
})
);
return this.checkoutService
.updateItemInCart(
currentProcess.cartId,
existingItemId,
destination,
itemToUpdate.quantity,
ava
)
.pipe(
tap(() => {
ctx.patchState({
cartEntries,
});
this.syncApiState(cartEntries);
})
);
}
@Action(actions.SetShippingForDownloadCart)
setShippingForDownloadCart(ctx: StateContext<CartEntryStateModel>, { address, cartEntriesIds }: actions.SetShippingForDownloadCart) {
setShippingForDownloadCart(
ctx: StateContext<CartEntryStateModel>,
{ address, cartEntriesIds }: actions.SetShippingForDownloadCart
) {
const state = ctx.getState();
const currentProcess = this.store.selectSnapshot(ProcessSelectors.getCurrentProcess);
const currentProcess = this.store.selectSnapshot(
ProcessSelectors.getCurrentProcess
);
if (currentProcess) {
const cartEntries = { ...state.cartEntries };
@@ -150,12 +212,19 @@ export class CartEntryState {
return from(cartEntriesIds).pipe(
concatMap((cartEntryId) =>
this.checkoutService
.updateDestinationForItemInCart(currentProcess.cartId, cartEntryId, <EntityDTOContainerOfDestinationDTO>{
data: <DestinationDTO>{ shippingAddress: address },
})
.updateDestinationForItemInCart(
currentProcess.cartId,
cartEntryId,
<EntityDTOContainerOfDestinationDTO>{
data: <DestinationDTO>{ shippingAddress: address },
}
)
.pipe(
tap(() => {
const cartEntry = { ...cartEntries[cartEntryId], shippingAddress: address };
const cartEntry = {
...cartEntries[cartEntryId],
shippingAddress: address,
};
cartEntries[cartEntryId] = cartEntry;
ctx.patchState({
@@ -174,10 +243,17 @@ export class CartEntryState {
@Action(actions.UpdateCartEntryQuantity)
updateCartEntryQuantity(
ctx: StateContext<CartEntryStateModel>,
{ quantity, cartEntryId, availabilityMsg, availability }: actions.UpdateCartEntryQuantity
{
quantity,
cartEntryId,
availabilityMsg,
availability,
}: actions.UpdateCartEntryQuantity
) {
const state = ctx.getState();
const currentProcess = this.store.selectSnapshot(ProcessSelectors.getCurrentProcess);
const currentProcess = this.store.selectSnapshot(
ProcessSelectors.getCurrentProcess
);
const cartEntries = { ...state.cartEntries };
const updateEntry = { ...cartEntries[cartEntryId] };
@@ -201,10 +277,18 @@ export class CartEntryState {
products[updateEntry.bookId],
quantity,
branches[updateEntry.branch],
(updateEntry.availability ? updateEntry.availability : products[updateEntry.bookId].catalogAvailability) as any, // TODO: Typisierung
(updateEntry.availability
? updateEntry.availability
: products[updateEntry.bookId].catalogAvailability) as any, // TODO: Typisierung
products[updateEntry.bookId].promoPoints
).pipe(
switchMap((updatedItem) => this.checkoutService.updateQuantityForItemInCart(currentProcess.cartId, cartEntryId, updatedItem)),
switchMap((updatedItem) =>
this.checkoutService.updateQuantityForItemInCart(
currentProcess.cartId,
cartEntryId,
updatedItem
)
),
tap(() => {
this.syncApiState(cartEntries);
})
@@ -212,9 +296,14 @@ export class CartEntryState {
}
@Action(actions.DeleteCartEntry)
deleteCartItem(ctx: StateContext<CartEntryStateModel>, { cartEntryId, hardDelete }: actions.DeleteCartEntry) {
deleteCartItem(
ctx: StateContext<CartEntryStateModel>,
{ cartEntryId, hardDelete }: actions.DeleteCartEntry
) {
const state = ctx.getState();
const currentProcess = this.store.selectSnapshot(ProcessSelectors.getCurrentProcess);
const currentProcess = this.store.selectSnapshot(
ProcessSelectors.getCurrentProcess
);
const cartEntries = { ...state.cartEntries };
const cartEntry = cartEntries[cartEntryId];
@@ -226,10 +315,18 @@ export class CartEntryState {
products[cartEntry.bookId],
0,
branches[cartEntry.branch],
(cartEntry.availability ? cartEntry.availability : products[cartEntry.bookId].catalogAvailability) as any, // TODO: Typisierung
(cartEntry.availability
? cartEntry.availability
: products[cartEntry.bookId].catalogAvailability) as any, // TODO: Typisierung
products[cartEntry.bookId].promoPoints
).pipe(
switchMap((updatedItem) => this.checkoutService.updateQuantityForItemInCart(currentProcess.cartId, cartEntryId, updatedItem)),
switchMap((updatedItem) =>
this.checkoutService.updateQuantityForItemInCart(
currentProcess.cartId,
cartEntryId,
updatedItem
)
),
tap(() => {
delete cartEntries[cartEntryId];
@@ -243,11 +340,17 @@ export class CartEntryState {
}
@Action(actions.ReloadCartEntryData)
reloadCartEntries(ctx: StateContext<CartEntryStateModel>, { cartEntries }: actions.ReloadCartEntryData) {
reloadCartEntries(
ctx: StateContext<CartEntryStateModel>,
{ cartEntries }: actions.ReloadCartEntryData
) {
ctx.setState({ cartEntries: { ...cartEntries } });
}
private availibilityObjectForUpdate(ava: AvailabilityDTO, deliveryType: string): UpdateDestinationAvailability {
private availibilityObjectForUpdate(
ava: AvailabilityDTO,
deliveryType: string
): UpdateDestinationAvailability {
let data: UpdateDestinationAvailability = { availabilityType: ava.status };
if (deliveryType === DeliveryOption.DELIVERY) {
@@ -300,10 +403,15 @@ export class CartEntryState {
branch: number,
cartId: number
): null | number {
const existingCartEntriesIds = this.store.selectSnapshot(CartState.getCartEntries)(cartId);
const existingCartEntriesIds = this.store.selectSnapshot(
CartState.getCartEntries
)(cartId);
const existingEntries = existingCartEntriesIds.map((id) => cartEntries[id]);
const updateItem = existingEntries.find(
(cartitem: CartEntry) => cartitem.bookId === bookId && cartitem.deliveryType === deliveryType && cartitem.branch === branch
(cartitem: CartEntry) =>
cartitem.bookId === bookId &&
cartitem.deliveryType === deliveryType &&
cartitem.branch === branch
);
if (updateItem) {
@@ -311,7 +419,11 @@ export class CartEntryState {
for (const key of existingCartEntriesIds) {
const currentItem = cartEntries[key];
if (currentItem.bookId === bookId && currentItem.deliveryType === deliveryType && currentItem.branch === branch) {
if (
currentItem.bookId === bookId &&
currentItem.deliveryType === deliveryType &&
currentItem.branch === branch
) {
itemId = key;
break;
}
@@ -338,7 +450,12 @@ export class CartEntryState {
if (deliveryType === DeliveryOption.TAKE_NOW) {
getBranchSupplierId$ = this.checkoutService
.getSuppliers()
.pipe(map((suppliers) => suppliers.find((supplier) => supplier.supplierNumber === 'F').id));
.pipe(
map(
(suppliers) =>
suppliers.find((supplier) => supplier.supplierNumber === 'F').id
)
);
}
const addItemToCart$ = (item: AddToShoppingCartDTO) =>
@@ -346,8 +463,10 @@ export class CartEntryState {
tap((shoppingCart: ShoppingCartDTO) => {
const newItemIndex = Object.keys(shoppingCart.items).length - 1;
const newItemId = shoppingCart.items[newItemIndex].id;
const deliveryDate = shoppingCart.items[newItemIndex].data.availability.estimatedShippingDate
? shoppingCart.items[newItemIndex].data.availability.estimatedShippingDate
const deliveryDate = shoppingCart.items[newItemIndex].data
.availability.estimatedShippingDate
? shoppingCart.items[newItemIndex].data.availability
.estimatedShippingDate
: null;
const pickUpDate = availability.at ? availability.at : null;
@@ -403,9 +522,13 @@ export class CartEntryState {
);
if (deliveryType === DeliveryOption.DOWNLOAD) {
const customer = this.store.selectSnapshot(CustomerSelectors.getCurrentProcessActiveUser);
const customer = this.store.selectSnapshot(
CustomerSelectors.getCurrentProcessActiveUser
);
return this.checkoutService.getSuppliers().pipe(
map((suppliers) => suppliers.find((supplier) => supplier.supplierNumber === 'DIG')),
map((suppliers) =>
suppliers.find((supplier) => supplier.supplierNumber === 'DIG')
),
map((supplier) =>
this.createObjectForDonwload(
deliveryType,
@@ -422,7 +545,17 @@ export class CartEntryState {
);
} else {
return getBranchSupplierId$.pipe(
map((supplierId) => this.createObjectForAPI(deliveryType, book, quantity, availability, supplierId, branch, promoPoints)),
map((supplierId) =>
this.createObjectForAPI(
deliveryType,
book,
quantity,
availability,
supplierId,
branch,
promoPoints
)
),
flatMap((item) => addItemToCart$(item))
);
}
@@ -437,7 +570,11 @@ export class CartEntryState {
branch: BranchDTO,
promoPoints: number
): AddToShoppingCartDTO {
const destination: EntityDTOContainerOfDestinationDTO = this.createDestinationObject(deliveryType, branch, availability);
const destination: EntityDTOContainerOfDestinationDTO = this.createDestinationObject(
deliveryType,
branch,
availability
);
const item: AddToShoppingCartDTO = {
product: {
@@ -453,7 +590,9 @@ export class CartEntryState {
ssc: availability.ssc ? availability.ssc : null,
sscText: availability.sscText ? availability.sscText : null,
estimatedShippingDate: availability.at ? availability.at : null,
supplierProductNumber: availability.supplierProductNumber ? availability.supplierProductNumber : null,
supplierProductNumber: availability.supplierProductNumber
? availability.supplierProductNumber
: null,
isPrebooked: availability.isPrebooked,
},
promotion: { points: promoPoints },
@@ -472,7 +611,12 @@ export class CartEntryState {
promoPoints: number,
customer?: User
): AddToShoppingCartDTO {
const destination: EntityDTOContainerOfDestinationDTO = this.createDestinationObject(deliveryType, branch, availability, customer);
const destination: EntityDTOContainerOfDestinationDTO = this.createDestinationObject(
deliveryType,
branch,
availability,
customer
);
const item: AddToShoppingCartDTO = {
product: {
@@ -488,7 +632,9 @@ export class CartEntryState {
ssc: availability.ssc ? availability.ssc : null,
sscText: availability.sscText ? availability.sscText : null,
estimatedShippingDate: availability.at ? availability.at : null,
supplierProductNumber: availability.supplierProductNumber ? availability.supplierProductNumber : null,
supplierProductNumber: availability.supplierProductNumber
? availability.supplierProductNumber
: null,
isPrebooked: availability.isPrebooked,
},
promotion: { points: promoPoints },
@@ -522,8 +668,14 @@ export class CartEntryState {
},
};
} else if (targetType === DeliveryType['Download']) {
const address = customer ? (customer.delivery_addres ? customer.delivery_addres : customer.invoice_address) : null;
const addressDto: AddressDTO = address ? this.customerMapping.fromAddressToAddressDTO(address) : null;
const address = customer
? customer.delivery_addres
? customer.delivery_addres
: customer.invoice_address
: null;
const addressDto: AddressDTO = address
? this.customerMapping.fromAddressToAddressDTO(address)
: null;
destination = {
data: {
target: targetType,
@@ -561,9 +713,13 @@ export class CartEntryState {
let item$: Observable<AddToShoppingCartDTO>;
if (deliveryType === DeliveryOption.DOWNLOAD) {
item$ = this.checkoutService.getSuppliers().pipe(
map((suppliers) => suppliers.find((supplier) => supplier.supplierNumber === 'DIG')),
map((suppliers) =>
suppliers.find((supplier) => supplier.supplierNumber === 'DIG')
),
flatMap((supplier) => {
const customer = this.store.selectSnapshot(CustomerSelectors.getCurrentProcessActiveUser);
const customer = this.store.selectSnapshot(
CustomerSelectors.getCurrentProcessActiveUser
);
return of(
this.createObjectForDonwload(
deliveryType,
@@ -580,13 +736,36 @@ export class CartEntryState {
);
} else if (deliveryType === DeliveryOption.TAKE_NOW) {
item$ = this.checkoutService.getSuppliers().pipe(
map((suppliers) => suppliers.find((supplier) => supplier.supplierNumber === 'F').id),
map(
(suppliers) =>
suppliers.find((supplier) => supplier.supplierNumber === 'F').id
),
flatMap((supplierId) => {
return of(this.createObjectForAPI(deliveryType, book, quantity, availability, supplierId, branch, promoPoints));
return of(
this.createObjectForAPI(
deliveryType,
book,
quantity,
availability,
supplierId,
branch,
promoPoints
)
);
})
);
} else {
return of(this.createObjectForAPI(deliveryType, book, quantity, availability, availability.supplierId, branch, promoPoints));
return of(
this.createObjectForAPI(
deliveryType,
book,
quantity,
availability,
availability.supplierId,
branch,
promoPoints
)
);
}
return item$.pipe(
map((it) => {

View File

@@ -7,35 +7,50 @@ import { GoodsInService } from 'apps/sales/src/app/core/services/goods-in.servic
import { GoodsInSearch } from 'apps/sales/src/app/core/models/GoodsInSearch.model';
import { SetGoodsInOrders } from 'apps/sales/src/app/core/store/actions/goods-in.actions';
export class GoodsInSearchResultsDataSource extends DataSource<OrderItemListItemDTO | undefined> {
export class GoodsInSearchResultsDataSource extends DataSource<
OrderItemListItemDTO | undefined
> {
private pageSize = 10;
private fetchedPages = new Set<number>();
private cachedData = Array.from<OrderItemListItemDTO>({ length: 10 });
private dataStream = new BehaviorSubject<(OrderItemListItemDTO | undefined)[]>(this.cachedData);
private dataStream = new BehaviorSubject<
(OrderItemListItemDTO | undefined)[]
>(this.cachedData);
destroy$ = new Subject();
public loading = true;
public results = false;
public allHits = 0;
public firstLoad = true;
constructor(private search: GoodsInSearch, private store: Store, private goodsInService: GoodsInService, private useCache: Boolean) {
constructor(
private search: GoodsInSearch,
private store: Store,
private goodsInService: GoodsInService,
private useCache: Boolean
) {
super();
}
connect(collectionViewer: CollectionViewer): Observable<(OrderItemListItemDTO | undefined)[]> {
collectionViewer.viewChange.pipe(takeUntil(this.destroy$)).subscribe((range) => {
const startPage = this.getPageForIndex(range.start);
const endPage = this.getPageForIndex(range.end);
for (let i = startPage; i <= endPage; i++) {
if (this.firstLoad && i === 0) {
return;
connect(
collectionViewer: CollectionViewer
): Observable<(OrderItemListItemDTO | undefined)[]> {
collectionViewer.viewChange
.pipe(takeUntil(this.destroy$))
.subscribe((range) => {
const startPage = this.getPageForIndex(range.start);
const endPage = this.getPageForIndex(range.end);
for (let i = startPage; i <= endPage; i++) {
if (this.firstLoad && i === 0) {
return;
}
this.fetchPage(i);
}
this.fetchPage(i);
}
});
});
this.dataStream.pipe(takeUntil(this.destroy$), debounceTime(1000)).subscribe((i) => {
this.store.dispatch(new SetGoodsInOrders([...i]));
});
this.dataStream
.pipe(takeUntil(this.destroy$), debounceTime(1000))
.subscribe((i) => {
this.store.dispatch(new SetGoodsInOrders([...i]));
});
this.fetchPage(0);
return this.dataStream;
@@ -82,25 +97,45 @@ export class GoodsInSearchResultsDataSource extends DataSource<OrderItemListItem
const shelfSearch$ =
page === 0 && this.useCache
? this.goodsInService.searchCachedOrders()
: this.goodsInService.search(this.search.input, this.search.branchnumber, page * this.pageSize, this.pageSize);
: this.goodsInService.search(
this.search.input,
page * this.pageSize,
this.pageSize
);
shelfSearch$.pipe(take(1)).subscribe(({ results, hits }: { results: OrderItemListItemDTO[]; hits: number }) => {
this.loading = false;
this.results = true;
shelfSearch$
.pipe(take(1))
.subscribe(
({
results,
hits,
}: {
results: OrderItemListItemDTO[];
hits: number;
}) => {
this.loading = false;
this.results = true;
if (page === 0) {
this.cachedData = Array.from<OrderItemListItemDTO>({ length: hits });
this.allHits = hits;
}
if (page === 0) {
this.cachedData = Array.from<OrderItemListItemDTO>({
length: hits,
});
this.allHits = hits;
}
this.cachedData.splice(page * this.pageSize, this.pageSize, ...results);
this.dataStream.next(this.cachedData);
this.cachedData.splice(
page * this.pageSize,
this.pageSize,
...results
);
this.dataStream.next(this.cachedData);
if (page === 0) {
// dispatch immediately on first page load
this.firstLoad = false;
this.store.dispatch(new SetGoodsInOrders(this.cachedData));
}
});
if (page === 0) {
// dispatch immediately on first page load
this.firstLoad = false;
this.store.dispatch(new SetGoodsInOrders(this.cachedData));
}
}
);
}
}

View File

@@ -23,9 +23,14 @@ import { GOODS_IN_SCROLL_INDEX } from 'apps/sales/src/app/core/utils/app.constan
styleUrls: ['./goods-in-search.component.scss'],
})
export class GoodsInSearchComponent implements OnInit {
@ViewChild('searchInput', { static: false }) searchInput: SearchInputComponent;
@ViewChild('searchInput', { static: false })
searchInput: SearchInputComponent;
error: string;
constructor(private store: Store, private goodsInService: GoodsInService, private router: Router) { }
constructor(
private store: Store,
private goodsInService: GoodsInService,
private router: Router
) {}
ngOnInit() {
this.initialize();
@@ -34,7 +39,7 @@ export class GoodsInSearchComponent implements OnInit {
search(input: string) {
const branchNo = this.store.selectSnapshot(BranchSelectors.getUserBranch);
this.goodsInService
.search(input, branchNo, 0, 10)
.search(input, 0, 10)
.pipe(take(1))
.subscribe((data) => this.searchResultHandler(data, input, branchNo));
}
@@ -43,18 +48,29 @@ export class GoodsInSearchComponent implements OnInit {
this.store.dispatch(new ClearGoodsInCachedOrders());
}
searchResultHandler(data: { results: OrderItemListItemDTO[]; hits: number }, input: string, branchNo: string) {
searchResultHandler(
data: { results: OrderItemListItemDTO[]; hits: number },
input: string,
branchNo: string
) {
if (data && data.results && data.results.length > 0) {
this.error = null;
this.searchInput.stopLoading();
this.store.dispatch(new SetGoodsInOrders(data.results));
this.store.dispatch(new SetGoodsInCachedOrders({ results: data.results, hits: data.hits }));
this.store.dispatch(new SetGoodsInSearch({ input: input, branchnumber: branchNo }));
this.store.dispatch(
new SetGoodsInCachedOrders({ results: data.results, hits: data.hits })
);
this.store.dispatch(
new SetGoodsInSearch({ input: input, branchnumber: branchNo })
);
this.store.dispatch(new SetGoodsInUseCache(true));
sessionStorage.removeItem(GOODS_IN_SCROLL_INDEX);
if (data.results.length === 1) {
const item = data.results[0];
this.navigate(`/goodsin/details/${item.orderId}/${item.orderItemId}/${item.processingStatus}`, item.product.name);
this.navigate(
`/goodsin/details/${item.orderId}/${item.orderItemId}/${item.processingStatus}`,
item.product.name
);
} else {
this.navigate('/goodsin/results', `${input} (${data.hits} Ergebnisse)`);
}

View File

@@ -18,6 +18,9 @@
* BROWSER POLYFILLS
*/
/** Intersection Observer Polyfil for iOS < 12.2 */
import 'intersection-observer';
/** IE9, IE10, IE11, and Chrome <55 requires all of the following polyfills.
* This also includes Android Emulators with older versions of Chrome and Google Search/Googlebot
*/

View File

@@ -11,5 +11,6 @@
"serviceIndex": true,
"apiModule": true,
"enumModule": true,
"generateExamples": false
}
"generateExamples": false,
"ignoreUnusedModels": false
}

View File

@@ -11,5 +11,6 @@
"serviceIndex": true,
"apiModule": true,
"enumModule": true,
"generateExamples": false
}
"generateExamples": false,
"ignoreUnusedModels": false
}

5
package-lock.json generated
View File

@@ -8589,6 +8589,11 @@
"ipaddr.js": "^1.9.0"
}
},
"intersection-observer": {
"version": "0.11.0",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/intersection-observer/-/intersection-observer-0.11.0.tgz",
"integrity": "sha1-9OoGcHAyb2g5PuFhzAospMAEDG8="
},
"invariant": {
"version": "2.2.4",
"resolved": "https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel/npm/registry/invariant/-/invariant-2.2.4.tgz",

View File

@@ -75,6 +75,7 @@
"core-js": "^2.6.5",
"faker": "^4.1.0",
"hammerjs": "^2.0.8",
"intersection-observer": "^0.11.0",
"ng-circle-progress": "^1.4.0",
"ng-connection-service": "^1.0.4",
"ngx-infinite-scroll": "^7.2.0",