mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
301 lines
9.2 KiB
TypeScript
301 lines
9.2 KiB
TypeScript
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
|
import {
|
|
Component,
|
|
ChangeDetectionStrategy,
|
|
OnInit,
|
|
OnDestroy,
|
|
ViewChild,
|
|
ViewChildren,
|
|
QueryList,
|
|
TrackByFunction,
|
|
inject,
|
|
} from '@angular/core';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { ApplicationService } from '@core/application';
|
|
import { BreadcrumbService } from '@core/breadcrumb';
|
|
import { Config } from '@core/config';
|
|
import { RemissionListItem } from '@domain/remission';
|
|
import { SupplierDTO } from '@generated/swagger/inventory-api';
|
|
import { Subject, combineLatest, BehaviorSubject } from 'rxjs';
|
|
import { debounceTime, first, map, shareReplay, takeUntil, withLatestFrom } from 'rxjs/operators';
|
|
import { RemissionListItemComponent } from './remission-list-item';
|
|
import { RemissionListComponentStore } from './remission-list.component-store';
|
|
import { RemissionComponentStore } from './remission.component-store';
|
|
import { ShellService } from '@shared/shell';
|
|
|
|
@Component({
|
|
selector: 'page-remission-list',
|
|
templateUrl: 'remission-list.component.html',
|
|
styleUrls: ['remission-list.component.scss'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
providers: [RemissionComponentStore],
|
|
standalone: false,
|
|
})
|
|
export class RemissionListComponent implements OnInit, OnDestroy {
|
|
shellService = inject(ShellService);
|
|
|
|
@ViewChildren(RemissionListItemComponent) listItems: QueryList<RemissionListItemComponent>;
|
|
@ViewChild('scrollContainer', { static: true })
|
|
scrollContainer: CdkVirtualScrollViewport;
|
|
|
|
private _onDestroy$ = new Subject<void>();
|
|
|
|
get processId() {
|
|
return this._config.get('process.ids.remission');
|
|
}
|
|
|
|
get suppliers$() {
|
|
return this._remissionListStore.suppliers$;
|
|
}
|
|
|
|
get selectedSupplier$() {
|
|
return this._remissionListStore.selectedSupplier$;
|
|
}
|
|
|
|
get selectedSupplierId$() {
|
|
return this._remissionListStore.selectedSupplier$.pipe(map((s) => s?.id));
|
|
}
|
|
|
|
get sources$() {
|
|
return this._remissionListStore.sources$;
|
|
}
|
|
|
|
get selectedSource$() {
|
|
return this._remissionListStore.selectedSource$;
|
|
}
|
|
|
|
get items$() {
|
|
return this._remissionListStore.items$;
|
|
}
|
|
|
|
get requiredCapacities$() {
|
|
return this._remissionListStore.requiredCapacities$;
|
|
}
|
|
|
|
get hits$() {
|
|
return this._remissionListStore.hits$;
|
|
}
|
|
|
|
get fetching$() {
|
|
return this._remissionListStore.fetching$;
|
|
}
|
|
|
|
get return$() {
|
|
return this._remissionStore.return$;
|
|
}
|
|
|
|
get filter$() {
|
|
return this._remissionListStore.filter$;
|
|
}
|
|
|
|
showSelectDepartmenttext$ = combineLatest([this.filter$, this.selectedSource$]).pipe(
|
|
map(([filter, source]) => {
|
|
if (source !== 'Abteilungsremission') {
|
|
return false;
|
|
}
|
|
|
|
if (filter?.getQueryToken()?.filter?.abteilungen) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}),
|
|
);
|
|
|
|
listEmpty$ = combineLatest([this.fetching$, this.hits$]).pipe(
|
|
map(([loading, hits]) => !loading && hits === 0),
|
|
shareReplay(),
|
|
);
|
|
|
|
get queryParams$() {
|
|
return this._activatedRoute.queryParams.pipe(
|
|
withLatestFrom(this._remissionListStore.filter$, this.selectedSupplierId$, this.selectedSource$),
|
|
map(([params, filter, supplier, source]) => {
|
|
let queryParams = params;
|
|
if (filter) {
|
|
queryParams = { ...filter.getQueryParams(), ...params, supplier, source };
|
|
}
|
|
return queryParams;
|
|
}),
|
|
);
|
|
}
|
|
|
|
get returnCount$() {
|
|
return this._remissionStore.returnCount$;
|
|
}
|
|
|
|
showStartRemissionAction$ = combineLatest([this.listEmpty$, this.return$]).pipe(map(([empty, r]) => !empty && !r));
|
|
|
|
filteredSuppliers$ = combineLatest([this._remissionStore.uncompleted$, this.suppliers$, this.selectedSupplier$]).pipe(
|
|
map(([uncompleted, suppliers, selectedSupplier]) => {
|
|
if (!uncompleted) {
|
|
return suppliers;
|
|
}
|
|
return suppliers.filter((supplier) => supplier?.id === selectedSupplier?.id);
|
|
}),
|
|
);
|
|
|
|
trackByItemId: TrackByFunction<RemissionListItem> = (_, item) => item.dto.id;
|
|
|
|
showScrollArrow$ = new BehaviorSubject<boolean>(false);
|
|
|
|
remittingItem$ = new BehaviorSubject<boolean>(false);
|
|
|
|
constructor(
|
|
private readonly _remissionListStore: RemissionListComponentStore,
|
|
private readonly _remissionStore: RemissionComponentStore,
|
|
private readonly _router: Router,
|
|
private readonly _activatedRoute: ActivatedRoute,
|
|
private readonly _breadcrumb: BreadcrumbService,
|
|
private readonly _applicationService: ApplicationService,
|
|
private readonly _config: Config,
|
|
) {}
|
|
|
|
ngOnInit() {
|
|
this._activatedRoute.queryParams
|
|
.pipe(takeUntil(this._onDestroy$), debounceTime(0))
|
|
.subscribe(async (queryParams) => {
|
|
const { supplier, source } = queryParams;
|
|
|
|
if (supplier) {
|
|
this._remissionListStore.setSelectedSupplierId(+supplier);
|
|
}
|
|
|
|
if (source) {
|
|
this._remissionListStore.setSelectedSource(source);
|
|
}
|
|
|
|
const data = await this._remissionListStore.getCachedData();
|
|
if (data.items?.length !== 0) {
|
|
this._remissionListStore.setItems(data.items);
|
|
this._remissionListStore.setHits(data.hits);
|
|
this.scrollTop(Number(queryParams?.scroll_position ?? 0));
|
|
}
|
|
|
|
await this.updateBreadcrumb(queryParams);
|
|
await this.removeBreadcrumbs();
|
|
});
|
|
|
|
this._remissionListStore.filter$
|
|
.pipe(takeUntil(this._onDestroy$), withLatestFrom(this._remissionListStore.selectedSource$))
|
|
.subscribe(([_, source]) => {
|
|
if (source === 'Abteilungsremission') {
|
|
this._remissionListStore.loadRequiredCapacities();
|
|
}
|
|
});
|
|
|
|
this._activatedRoute.params.pipe(takeUntil(this._onDestroy$)).subscribe((params) => {
|
|
const id = +params.returnId;
|
|
if (id) {
|
|
// Remission wurde gestartet
|
|
this._remissionStore.getReturn(id);
|
|
} else {
|
|
// Für die Anzahl der Warenbegleitscheine, wenn keine Remission gestartet wurde
|
|
this._remissionStore.getReturns(false);
|
|
}
|
|
});
|
|
|
|
this._remissionStore.getReturnCompleted.pipe(takeUntil(this._onDestroy$)).subscribe((returnDto) => {
|
|
if (returnDto) {
|
|
this._remissionListStore.setSelectedSupplierId(returnDto.supplier.id);
|
|
}
|
|
|
|
if (!returnDto || !!returnDto.completed) {
|
|
this._applicationService.patchProcessData(this._remissionListStore.processId, {
|
|
active: undefined,
|
|
});
|
|
this._router.navigate(['./'], { relativeTo: this._activatedRoute.parent });
|
|
}
|
|
});
|
|
}
|
|
|
|
async ngOnDestroy() {
|
|
this._onDestroy$.next();
|
|
this._onDestroy$.complete();
|
|
|
|
if (this._remissionStore.return) {
|
|
this._remissionListStore.cacheCurrentData();
|
|
const params = await this._activatedRoute.queryParams.pipe(first()).toPromise();
|
|
await this.updateBreadcrumb(params);
|
|
}
|
|
}
|
|
|
|
async updateBreadcrumb(queryParams: Record<string, string> = {}) {
|
|
const scroll_position = this.scrollContainer.measureScrollOffset('top');
|
|
const returnId = this._activatedRoute?.snapshot?.params?.returnId;
|
|
const packageNumber = this._activatedRoute?.snapshot?.params?.packageNumber;
|
|
|
|
const crumbs = await this._breadcrumb
|
|
.getBreadcrumbsByKeyAndTags$(this._remissionListStore.processId, ['remission'])
|
|
.pipe(first())
|
|
.toPromise();
|
|
|
|
const params = { ...queryParams, scroll_position };
|
|
for (const crumb of crumbs) {
|
|
this._breadcrumb.patchBreadcrumb(crumb.id, {
|
|
params,
|
|
path: `/filiale/remission/${returnId ? returnId + '/' : ''}${packageNumber ? packageNumber + '/' : ''}list`,
|
|
});
|
|
}
|
|
}
|
|
|
|
async scrolledIndexChange(index: number) {
|
|
const items = await this.items$.pipe(first()).toPromise();
|
|
const hits = await this.hits$.pipe(first()).toPromise();
|
|
|
|
if (index > 0) {
|
|
this.showScrollArrow$.next(true);
|
|
} else {
|
|
this.showScrollArrow$.next(false);
|
|
}
|
|
|
|
if (items.length >= hits) {
|
|
return;
|
|
}
|
|
|
|
if (this._activatedRoute.snapshot.fragment === 'shipping-document') {
|
|
return;
|
|
}
|
|
|
|
if (index >= items.length - 10 && items.length - 10 > 0 && !this._remissionListStore.fetching) {
|
|
this._remissionListStore.search({});
|
|
}
|
|
}
|
|
|
|
scrollTop(scrollPos: number) {
|
|
setTimeout(() => this.scrollContainer.scrollTo({ top: scrollPos, behavior: 'smooth' }), 0);
|
|
}
|
|
|
|
setSupplier(supplier: SupplierDTO) {
|
|
this._remissionListStore.setSupplier(supplier);
|
|
}
|
|
|
|
setSource(source: string) {
|
|
this._remissionListStore.setSource(source);
|
|
}
|
|
|
|
async removeBreadcrumbs() {
|
|
await this._breadcrumb.removeBreadcrumbsByKeyAndTags(this._remissionListStore.processId, [
|
|
'remission',
|
|
'shipping-documents',
|
|
]);
|
|
await this._breadcrumb.removeBreadcrumbsByKeyAndTags(this._remissionListStore.processId, [
|
|
'remission',
|
|
'add-product',
|
|
]);
|
|
await this._breadcrumb.removeBreadcrumbsByKeyAndTags(this._remissionListStore.processId, ['remission', 'create']);
|
|
await this._breadcrumb.removeBreadcrumbsByKeyAndTags(this._remissionListStore.processId, [
|
|
'remission',
|
|
'finish-shipping-document',
|
|
]);
|
|
await this._breadcrumb.removeBreadcrumbsByKeyAndTags(this._remissionListStore.processId, [
|
|
'remission',
|
|
'finish-remission',
|
|
]);
|
|
}
|
|
|
|
shippingDocumentDeleted() {
|
|
this._router.navigate(['/filiale', 'remission', 'list']);
|
|
}
|
|
}
|