1
0
Fork 0
mirror of https://github.com/s-frick/effigenix.git synced 2026-03-28 17:04:49 +01:00

feat(tui): Bestandsbewegungen und Produktionsaufträge anbinden

- StockMovement: API-Client, Hook, List/Detail/Record-Screens mit Typ-Filter
- ProductionOrder: list/getById/start im API-Client, List/Detail-Screens mit Freigabe- und Start-Aktion
- Inventar-Menü um Bestandsbewegungen erweitert
- Produktionsmenü zeigt jetzt Auftragsliste statt direkt Create
- OpenAPI-Typen regeneriert (StockMovementResponse, StartProductionOrderRequest, batchId in ProductionOrderResponse)
This commit is contained in:
Sebastian Frick 2026-02-25 12:36:42 +01:00
parent 0474b5fa93
commit 7d721f9ef0
18 changed files with 1279 additions and 9 deletions

View file

@ -27,6 +27,7 @@ export { createRecipesResource } from './resources/recipes.js';
export { createBatchesResource } from './resources/batches.js';
export { createProductionOrdersResource } from './resources/production-orders.js';
export { createStocksResource } from './resources/stocks.js';
export { createStockMovementsResource } from './resources/stock-movements.js';
export { createCountriesResource } from './resources/countries.js';
export {
ApiError,
@ -112,6 +113,9 @@ export type {
ReservationDTO,
StockBatchAllocationDTO,
ReserveStockRequest,
StockMovementDTO,
RecordStockMovementRequest,
StartProductionOrderRequest,
CountryDTO,
} from '@effigenix/types';
@ -140,9 +144,11 @@ export type { RecipesResource, RecipeType, RecipeStatus, UoM } from './resources
export { RECIPE_TYPE_LABELS, UOM_VALUES, UOM_LABELS } from './resources/recipes.js';
export type { BatchesResource, BatchStatus } from './resources/batches.js';
export { BATCH_STATUS_LABELS } from './resources/batches.js';
export type { ProductionOrdersResource, Priority } from './resources/production-orders.js';
export { PRIORITY_LABELS } from './resources/production-orders.js';
export type { ProductionOrdersResource, Priority, ProductionOrderStatus } from './resources/production-orders.js';
export { PRIORITY_LABELS, PRODUCTION_ORDER_STATUS_LABELS } from './resources/production-orders.js';
export type { StocksResource, BatchType, StockBatchStatus, StockFilter, ReferenceType, ReservationPriority } from './resources/stocks.js';
export type { StockMovementsResource, MovementType, MovementDirection, StockMovementFilter } from './resources/stock-movements.js';
export { MOVEMENT_TYPE_LABELS, MOVEMENT_DIRECTION_LABELS } from './resources/stock-movements.js';
export type { CountriesResource } from './resources/countries.js';
export { BATCH_TYPE_LABELS, STOCK_BATCH_STATUS_LABELS, REFERENCE_TYPE_LABELS, RESERVATION_PRIORITY_LABELS } from './resources/stocks.js';
@ -159,6 +165,7 @@ import { createRecipesResource } from './resources/recipes.js';
import { createBatchesResource } from './resources/batches.js';
import { createProductionOrdersResource } from './resources/production-orders.js';
import { createStocksResource } from './resources/stocks.js';
import { createStockMovementsResource } from './resources/stock-movements.js';
import { createCountriesResource } from './resources/countries.js';
import type { TokenProvider } from './token-provider.js';
import type { ApiConfig } from '@effigenix/config';
@ -186,6 +193,7 @@ export function createEffigenixClient(
batches: createBatchesResource(axiosClient),
productionOrders: createProductionOrdersResource(axiosClient),
stocks: createStocksResource(axiosClient),
stockMovements: createStockMovementsResource(axiosClient),
countries: createCountriesResource(axiosClient),
};
}

View file

@ -1,7 +1,7 @@
/** Production Orders resource Production BC. */
import type { AxiosInstance } from 'axios';
import type { ProductionOrderDTO, CreateProductionOrderRequest } from '@effigenix/types';
import type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest } from '@effigenix/types';
export type Priority = 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
@ -12,12 +12,32 @@ export const PRIORITY_LABELS: Record<Priority, string> = {
URGENT: 'Dringend',
};
export type { ProductionOrderDTO, CreateProductionOrderRequest };
export type ProductionOrderStatus = 'CREATED' | 'RELEASED' | 'IN_PRODUCTION' | 'COMPLETED' | 'CANCELLED';
export const PRODUCTION_ORDER_STATUS_LABELS: Record<ProductionOrderStatus, string> = {
CREATED: 'Erstellt',
RELEASED: 'Freigegeben',
IN_PRODUCTION: 'In Produktion',
COMPLETED: 'Abgeschlossen',
CANCELLED: 'Storniert',
};
export type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest };
const BASE = '/api/production/production-orders';
export function createProductionOrdersResource(client: AxiosInstance) {
return {
async list(): Promise<ProductionOrderDTO[]> {
const res = await client.get<ProductionOrderDTO[]>(BASE);
return res.data;
},
async getById(id: string): Promise<ProductionOrderDTO> {
const res = await client.get<ProductionOrderDTO>(`${BASE}/${id}`);
return res.data;
},
async create(request: CreateProductionOrderRequest): Promise<ProductionOrderDTO> {
const res = await client.post<ProductionOrderDTO>(BASE, request);
return res.data;
@ -27,6 +47,11 @@ export function createProductionOrdersResource(client: AxiosInstance) {
const res = await client.post<ProductionOrderDTO>(`${BASE}/${id}/release`);
return res.data;
},
async start(id: string, request: StartProductionOrderRequest): Promise<ProductionOrderDTO> {
const res = await client.post<ProductionOrderDTO>(`${BASE}/${id}/start`, request);
return res.data;
},
};
}

View file

@ -0,0 +1,73 @@
/** Stock Movements resource Inventory BC. */
import type { AxiosInstance } from 'axios';
import type { StockMovementDTO, RecordStockMovementRequest } from '@effigenix/types';
export type MovementType =
| 'GOODS_RECEIPT'
| 'PRODUCTION_OUTPUT'
| 'PRODUCTION_CONSUMPTION'
| 'SALE'
| 'RETURN'
| 'WASTE'
| 'ADJUSTMENT'
| 'INTER_BRANCH_TRANSFER';
export const MOVEMENT_TYPE_LABELS: Record<MovementType, string> = {
GOODS_RECEIPT: 'Wareneingang',
PRODUCTION_OUTPUT: 'Produktionsausstoß',
PRODUCTION_CONSUMPTION: 'Produktionsverbrauch',
SALE: 'Verkauf',
RETURN: 'Retoure',
WASTE: 'Ausschuss',
ADJUSTMENT: 'Korrektur',
INTER_BRANCH_TRANSFER: 'Filialumlagerung',
};
export type MovementDirection = 'IN' | 'OUT';
export const MOVEMENT_DIRECTION_LABELS: Record<MovementDirection, string> = {
IN: 'Eingang',
OUT: 'Ausgang',
};
export type { StockMovementDTO, RecordStockMovementRequest };
export interface StockMovementFilter {
stockId?: string;
articleId?: string;
movementType?: string;
batchReference?: string;
from?: string;
to?: string;
}
const BASE = '/api/inventory/stock-movements';
export function createStockMovementsResource(client: AxiosInstance) {
return {
async list(filter?: StockMovementFilter): Promise<StockMovementDTO[]> {
const params: Record<string, string> = {};
if (filter?.stockId) params.stockId = filter.stockId;
if (filter?.articleId) params.articleId = filter.articleId;
if (filter?.movementType) params.movementType = filter.movementType;
if (filter?.batchReference) params.batchReference = filter.batchReference;
if (filter?.from) params.from = filter.from;
if (filter?.to) params.to = filter.to;
const res = await client.get<StockMovementDTO[]>(BASE, { params });
return res.data;
},
async getById(id: string): Promise<StockMovementDTO> {
const res = await client.get<StockMovementDTO>(`${BASE}/${id}`);
return res.data;
},
async record(request: RecordStockMovementRequest): Promise<StockMovementDTO> {
const res = await client.post<StockMovementDTO>(BASE, request);
return res.data;
},
};
}
export type StockMovementsResource = ReturnType<typeof createStockMovementsResource>;