mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 08:29:36 +01:00
feat(tui): neue Backend-Features anbinden und Status-Werte korrigieren
TUI-Anbindung für Reservierung bestätigen (US-4.3), Produktionsauftrag
umterminieren und filtern (US-P17). Status-Werte CREATED→PLANNED und
IN_PRODUCTION→IN_PROGRESS korrigiert. Fehlenden GET /{id} Endpoint für
Produktionsaufträge im Backend ergänzt.
This commit is contained in:
parent
8a84bf5f25
commit
417f8fcdae
14 changed files with 467 additions and 27 deletions
|
|
@ -0,0 +1,29 @@
|
||||||
|
package de.effigenix.application.production;
|
||||||
|
|
||||||
|
import de.effigenix.domain.production.ProductionOrder;
|
||||||
|
import de.effigenix.domain.production.ProductionOrderError;
|
||||||
|
import de.effigenix.domain.production.ProductionOrderId;
|
||||||
|
import de.effigenix.domain.production.ProductionOrderRepository;
|
||||||
|
import de.effigenix.shared.common.Result;
|
||||||
|
|
||||||
|
public class GetProductionOrder {
|
||||||
|
|
||||||
|
private final ProductionOrderRepository productionOrderRepository;
|
||||||
|
|
||||||
|
public GetProductionOrder(ProductionOrderRepository productionOrderRepository) {
|
||||||
|
this.productionOrderRepository = productionOrderRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<ProductionOrderError, ProductionOrder> execute(String id) {
|
||||||
|
if (id == null || id.isBlank()) {
|
||||||
|
return Result.failure(new ProductionOrderError.ProductionOrderNotFound(ProductionOrderId.of(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return switch (productionOrderRepository.findById(ProductionOrderId.of(id))) {
|
||||||
|
case Result.Failure(var err) -> Result.failure(new ProductionOrderError.RepositoryFailure(err.message()));
|
||||||
|
case Result.Success(var opt) -> opt
|
||||||
|
.<Result<ProductionOrderError, ProductionOrder>>map(Result::success)
|
||||||
|
.orElseGet(() -> Result.failure(new ProductionOrderError.ProductionOrderNotFound(ProductionOrderId.of(id))));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import de.effigenix.application.production.AddRecipeIngredient;
|
||||||
import de.effigenix.application.production.CancelProductionOrder;
|
import de.effigenix.application.production.CancelProductionOrder;
|
||||||
import de.effigenix.application.production.CompleteProductionOrder;
|
import de.effigenix.application.production.CompleteProductionOrder;
|
||||||
import de.effigenix.application.production.CreateProductionOrder;
|
import de.effigenix.application.production.CreateProductionOrder;
|
||||||
|
import de.effigenix.application.production.GetProductionOrder;
|
||||||
import de.effigenix.application.production.ListProductionOrders;
|
import de.effigenix.application.production.ListProductionOrders;
|
||||||
import de.effigenix.application.production.ReleaseProductionOrder;
|
import de.effigenix.application.production.ReleaseProductionOrder;
|
||||||
import de.effigenix.application.production.RescheduleProductionOrder;
|
import de.effigenix.application.production.RescheduleProductionOrder;
|
||||||
|
|
@ -187,6 +188,11 @@ public class ProductionUseCaseConfiguration {
|
||||||
return new RescheduleProductionOrder(productionOrderRepository, authorizationPort, unitOfWork);
|
return new RescheduleProductionOrder(productionOrderRepository, authorizationPort, unitOfWork);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GetProductionOrder getProductionOrder(ProductionOrderRepository productionOrderRepository) {
|
||||||
|
return new GetProductionOrder(productionOrderRepository);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ListProductionOrders listProductionOrders(ProductionOrderRepository productionOrderRepository,
|
public ListProductionOrders listProductionOrders(ProductionOrderRepository productionOrderRepository,
|
||||||
AuthorizationPort authorizationPort) {
|
AuthorizationPort authorizationPort) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package de.effigenix.infrastructure.production.web.controller;
|
||||||
import de.effigenix.application.production.CancelProductionOrder;
|
import de.effigenix.application.production.CancelProductionOrder;
|
||||||
import de.effigenix.application.production.CompleteProductionOrder;
|
import de.effigenix.application.production.CompleteProductionOrder;
|
||||||
import de.effigenix.application.production.CreateProductionOrder;
|
import de.effigenix.application.production.CreateProductionOrder;
|
||||||
|
import de.effigenix.application.production.GetProductionOrder;
|
||||||
import de.effigenix.application.production.ListProductionOrders;
|
import de.effigenix.application.production.ListProductionOrders;
|
||||||
import de.effigenix.application.production.ReleaseProductionOrder;
|
import de.effigenix.application.production.ReleaseProductionOrder;
|
||||||
import de.effigenix.application.production.RescheduleProductionOrder;
|
import de.effigenix.application.production.RescheduleProductionOrder;
|
||||||
|
|
@ -45,6 +46,7 @@ public class ProductionOrderController {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ProductionOrderController.class);
|
private static final Logger logger = LoggerFactory.getLogger(ProductionOrderController.class);
|
||||||
|
|
||||||
private final CreateProductionOrder createProductionOrder;
|
private final CreateProductionOrder createProductionOrder;
|
||||||
|
private final GetProductionOrder getProductionOrder;
|
||||||
private final ReleaseProductionOrder releaseProductionOrder;
|
private final ReleaseProductionOrder releaseProductionOrder;
|
||||||
private final RescheduleProductionOrder rescheduleProductionOrder;
|
private final RescheduleProductionOrder rescheduleProductionOrder;
|
||||||
private final StartProductionOrder startProductionOrder;
|
private final StartProductionOrder startProductionOrder;
|
||||||
|
|
@ -53,6 +55,7 @@ public class ProductionOrderController {
|
||||||
private final ListProductionOrders listProductionOrders;
|
private final ListProductionOrders listProductionOrders;
|
||||||
|
|
||||||
public ProductionOrderController(CreateProductionOrder createProductionOrder,
|
public ProductionOrderController(CreateProductionOrder createProductionOrder,
|
||||||
|
GetProductionOrder getProductionOrder,
|
||||||
ReleaseProductionOrder releaseProductionOrder,
|
ReleaseProductionOrder releaseProductionOrder,
|
||||||
RescheduleProductionOrder rescheduleProductionOrder,
|
RescheduleProductionOrder rescheduleProductionOrder,
|
||||||
StartProductionOrder startProductionOrder,
|
StartProductionOrder startProductionOrder,
|
||||||
|
|
@ -60,6 +63,7 @@ public class ProductionOrderController {
|
||||||
CancelProductionOrder cancelProductionOrder,
|
CancelProductionOrder cancelProductionOrder,
|
||||||
ListProductionOrders listProductionOrders) {
|
ListProductionOrders listProductionOrders) {
|
||||||
this.createProductionOrder = createProductionOrder;
|
this.createProductionOrder = createProductionOrder;
|
||||||
|
this.getProductionOrder = getProductionOrder;
|
||||||
this.releaseProductionOrder = releaseProductionOrder;
|
this.releaseProductionOrder = releaseProductionOrder;
|
||||||
this.rescheduleProductionOrder = rescheduleProductionOrder;
|
this.rescheduleProductionOrder = rescheduleProductionOrder;
|
||||||
this.startProductionOrder = startProductionOrder;
|
this.startProductionOrder = startProductionOrder;
|
||||||
|
|
@ -105,6 +109,20 @@ public class ProductionOrderController {
|
||||||
return ResponseEntity.ok(responses);
|
return ResponseEntity.ok(responses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
@PreAuthorize("hasAuthority('PRODUCTION_ORDER_READ')")
|
||||||
|
public ResponseEntity<ProductionOrderResponse> getProductionOrder(@PathVariable String id) {
|
||||||
|
logger.info("Getting production order: {}", id);
|
||||||
|
|
||||||
|
var result = getProductionOrder.execute(id);
|
||||||
|
|
||||||
|
if (result.isFailure()) {
|
||||||
|
throw new ProductionOrderDomainErrorException(result.unsafeGetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity.ok(ProductionOrderResponse.from(result.unsafeGetValue()));
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@PreAuthorize("hasAuthority('PRODUCTION_ORDER_WRITE')")
|
@PreAuthorize("hasAuthority('PRODUCTION_ORDER_WRITE')")
|
||||||
public ResponseEntity<ProductionOrderResponse> createProductionOrder(
|
public ResponseEntity<ProductionOrderResponse> createProductionOrder(
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { SuccessDisplay } from '../shared/SuccessDisplay.js';
|
||||||
import { STOCK_BATCH_STATUS_LABELS, REFERENCE_TYPE_LABELS, RESERVATION_PRIORITY_LABELS } from '@effigenix/api-client';
|
import { STOCK_BATCH_STATUS_LABELS, REFERENCE_TYPE_LABELS, RESERVATION_PRIORITY_LABELS } from '@effigenix/api-client';
|
||||||
import type { StockBatchStatus, ReferenceType, ReservationPriority, ReservationDTO, StockBatchDTO } from '@effigenix/api-client';
|
import type { StockBatchStatus, ReferenceType, ReservationPriority, ReservationDTO, StockBatchDTO } from '@effigenix/api-client';
|
||||||
|
|
||||||
type Mode = 'view' | 'menu' | 'batch-actions' | 'block-reason' | 'remove-amount' | 'remove-unit' | 'reservation-actions' | 'confirm-release-reservation';
|
type Mode = 'view' | 'menu' | 'batch-actions' | 'block-reason' | 'remove-amount' | 'remove-unit' | 'reservation-actions' | 'confirm-release-reservation' | 'confirm-reservation-actions' | 'confirm-confirm-reservation';
|
||||||
|
|
||||||
const BATCH_STATUS_COLORS: Record<string, string> = {
|
const BATCH_STATUS_COLORS: Record<string, string> = {
|
||||||
AVAILABLE: 'green',
|
AVAILABLE: 'green',
|
||||||
|
|
@ -21,7 +21,7 @@ const BATCH_STATUS_COLORS: Record<string, string> = {
|
||||||
|
|
||||||
export function StockDetailScreen() {
|
export function StockDetailScreen() {
|
||||||
const { params, back, navigate } = useNavigation();
|
const { params, back, navigate } = useNavigation();
|
||||||
const { stock, loading, error, fetchStock, blockBatch, unblockBatch, removeBatch, releaseReservation, clearError } = useStocks();
|
const { stock, loading, error, fetchStock, blockBatch, unblockBatch, removeBatch, releaseReservation, confirmReservation, clearError } = useStocks();
|
||||||
const { articleName, locationName } = useStockNameLookup();
|
const { articleName, locationName } = useStockNameLookup();
|
||||||
const [mode, setMode] = useState<Mode>('view');
|
const [mode, setMode] = useState<Mode>('view');
|
||||||
const [menuIndex, setMenuIndex] = useState(0);
|
const [menuIndex, setMenuIndex] = useState(0);
|
||||||
|
|
@ -31,6 +31,7 @@ export function StockDetailScreen() {
|
||||||
const [removeAmount, setRemoveAmount] = useState('');
|
const [removeAmount, setRemoveAmount] = useState('');
|
||||||
const [removeUnit, setRemoveUnit] = useState('');
|
const [removeUnit, setRemoveUnit] = useState('');
|
||||||
const [reservationIndex, setReservationIndex] = useState(0);
|
const [reservationIndex, setReservationIndex] = useState(0);
|
||||||
|
const [confirmResIndex, setConfirmResIndex] = useState(0);
|
||||||
const [success, setSuccess] = useState<string | null>(null);
|
const [success, setSuccess] = useState<string | null>(null);
|
||||||
|
|
||||||
const stockId = params.stockId ?? '';
|
const stockId = params.stockId ?? '';
|
||||||
|
|
@ -43,6 +44,7 @@ export function StockDetailScreen() {
|
||||||
const selectedBatch = batches[batchIndex];
|
const selectedBatch = batches[batchIndex];
|
||||||
const reservations: ReservationDTO[] = (stock as { reservations?: ReservationDTO[] })?.reservations ?? [];
|
const reservations: ReservationDTO[] = (stock as { reservations?: ReservationDTO[] })?.reservations ?? [];
|
||||||
const selectedReservation = reservations[reservationIndex];
|
const selectedReservation = reservations[reservationIndex];
|
||||||
|
const selectedConfirmReservation = reservations[confirmResIndex];
|
||||||
|
|
||||||
const getBatchActions = () => {
|
const getBatchActions = () => {
|
||||||
if (!selectedBatch) return [];
|
if (!selectedBatch) return [];
|
||||||
|
|
@ -119,10 +121,21 @@ export function StockDetailScreen() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleConfirmReservation = async () => {
|
||||||
|
if (!selectedConfirmReservation?.id) return;
|
||||||
|
const result = await confirmReservation(stockId, selectedConfirmReservation.id);
|
||||||
|
if (result) {
|
||||||
|
setSuccess('Reservierung bestätigt – Material entnommen.');
|
||||||
|
setMode('view');
|
||||||
|
setConfirmResIndex(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const MENU_ITEMS = [
|
const MENU_ITEMS = [
|
||||||
{ label: 'Chargen verwalten', action: 'batches' },
|
{ label: 'Chargen verwalten', action: 'batches' },
|
||||||
{ label: 'Bestand reservieren', action: 'reserve' },
|
{ label: 'Bestand reservieren', action: 'reserve' },
|
||||||
...(reservations.length > 0 ? [{ label: 'Reservierung freigeben', action: 'release-reservation' }] : []),
|
...(reservations.length > 0 ? [{ label: 'Reservierung freigeben', action: 'release-reservation' }] : []),
|
||||||
|
...(reservations.length > 0 ? [{ label: 'Reservierung bestätigen', action: 'confirm-reservation' }] : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
useInput((input, key) => {
|
useInput((input, key) => {
|
||||||
|
|
@ -143,6 +156,24 @@ export function StockDetailScreen() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode === 'confirm-confirm-reservation') {
|
||||||
|
if (input.toLowerCase() === 'j') {
|
||||||
|
void handleConfirmReservation();
|
||||||
|
}
|
||||||
|
if (input.toLowerCase() === 'n' || key.escape) setMode('confirm-reservation-actions');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode === 'confirm-reservation-actions') {
|
||||||
|
if (key.upArrow) setConfirmResIndex((i) => Math.max(0, i - 1));
|
||||||
|
if (key.downArrow) setConfirmResIndex((i) => Math.min(reservations.length - 1, i + 1));
|
||||||
|
if (key.return && reservations[confirmResIndex]) {
|
||||||
|
setMode('confirm-confirm-reservation');
|
||||||
|
}
|
||||||
|
if (key.escape) setMode('view');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode === 'confirm-release-reservation') {
|
if (mode === 'confirm-release-reservation') {
|
||||||
if (input.toLowerCase() === 'j') {
|
if (input.toLowerCase() === 'j') {
|
||||||
void handleReleaseReservation();
|
void handleReleaseReservation();
|
||||||
|
|
@ -187,6 +218,9 @@ export function StockDetailScreen() {
|
||||||
} else if (action === 'release-reservation') {
|
} else if (action === 'release-reservation') {
|
||||||
setMode('reservation-actions');
|
setMode('reservation-actions');
|
||||||
setReservationIndex(0);
|
setReservationIndex(0);
|
||||||
|
} else if (action === 'confirm-reservation') {
|
||||||
|
setMode('confirm-reservation-actions');
|
||||||
|
setConfirmResIndex(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key.escape) setMode('view');
|
if (key.escape) setMode('view');
|
||||||
|
|
@ -281,7 +315,7 @@ export function StockDetailScreen() {
|
||||||
<Text color="gray" bold>Reserviert am</Text>
|
<Text color="gray" bold>Reserviert am</Text>
|
||||||
</Box>
|
</Box>
|
||||||
{reservations.map((r, i) => {
|
{reservations.map((r, i) => {
|
||||||
const isSelected = mode === 'reservation-actions' && i === reservationIndex;
|
const isSelected = (mode === 'reservation-actions' && i === reservationIndex) || (mode === 'confirm-reservation-actions' && i === confirmResIndex);
|
||||||
const textColor = isSelected ? 'cyan' : 'white';
|
const textColor = isSelected ? 'cyan' : 'white';
|
||||||
const refLabel = REFERENCE_TYPE_LABELS[(r.referenceType ?? '') as ReferenceType] ?? r.referenceType;
|
const refLabel = REFERENCE_TYPE_LABELS[(r.referenceType ?? '') as ReferenceType] ?? r.referenceType;
|
||||||
const prioLabel = RESERVATION_PRIORITY_LABELS[(r.priority ?? '') as ReservationPriority] ?? r.priority;
|
const prioLabel = RESERVATION_PRIORITY_LABELS[(r.priority ?? '') as ReservationPriority] ?? r.priority;
|
||||||
|
|
@ -393,6 +427,22 @@ export function StockDetailScreen() {
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{mode === 'confirm-reservation-actions' && (
|
||||||
|
<Box flexDirection="column" borderStyle="round" borderColor="cyan" paddingX={1}>
|
||||||
|
<Text color="cyan" bold>Reservierung zum Bestätigen auswählen</Text>
|
||||||
|
<Text color="gray" dimColor>↑↓ Reservierung wählen · Enter bestätigen · Escape zurück</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{mode === 'confirm-confirm-reservation' && selectedConfirmReservation && (
|
||||||
|
<Box flexDirection="column" borderStyle="round" borderColor="yellow" paddingX={1}>
|
||||||
|
<Text color="yellow" bold>Reservierung bestätigen – Material entnehmen?</Text>
|
||||||
|
<Text>Referenz: {selectedConfirmReservation.referenceType} / {selectedConfirmReservation.referenceId}</Text>
|
||||||
|
<Text>Menge: {selectedConfirmReservation.quantityAmount} {selectedConfirmReservation.quantityUnit}</Text>
|
||||||
|
<Text color="gray" dimColor>[J] Ja · [N] Nein</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box marginTop={1}>
|
<Box marginTop={1}>
|
||||||
<Text color="gray" dimColor>
|
<Text color="gray" dimColor>
|
||||||
[m] Aktionsmenü · Backspace Zurück
|
[m] Aktionsmenü · Backspace Zurück
|
||||||
|
|
|
||||||
|
|
@ -10,24 +10,25 @@ import { PRODUCTION_ORDER_STATUS_LABELS, PRIORITY_LABELS } from '@effigenix/api-
|
||||||
import type { ProductionOrderStatus, Priority } from '@effigenix/api-client';
|
import type { ProductionOrderStatus, Priority } from '@effigenix/api-client';
|
||||||
|
|
||||||
const STATUS_COLORS: Record<string, string> = {
|
const STATUS_COLORS: Record<string, string> = {
|
||||||
CREATED: 'gray',
|
PLANNED: 'gray',
|
||||||
RELEASED: 'yellow',
|
RELEASED: 'yellow',
|
||||||
IN_PRODUCTION: 'blue',
|
IN_PROGRESS: 'blue',
|
||||||
COMPLETED: 'green',
|
COMPLETED: 'green',
|
||||||
CANCELLED: 'red',
|
CANCELLED: 'red',
|
||||||
};
|
};
|
||||||
|
|
||||||
type Mode = 'view' | 'menu' | 'start-batch-input';
|
type Mode = 'view' | 'menu' | 'start-batch-input' | 'reschedule-input';
|
||||||
|
|
||||||
export function ProductionOrderDetailScreen() {
|
export function ProductionOrderDetailScreen() {
|
||||||
const { params, back } = useNavigation();
|
const { params, back } = useNavigation();
|
||||||
const {
|
const {
|
||||||
productionOrder, loading, error,
|
productionOrder, loading, error,
|
||||||
fetchProductionOrder, releaseProductionOrder, startProductionOrder, clearError,
|
fetchProductionOrder, releaseProductionOrder, rescheduleProductionOrder, startProductionOrder, clearError,
|
||||||
} = useProductionOrders();
|
} = useProductionOrders();
|
||||||
const [mode, setMode] = useState<Mode>('view');
|
const [mode, setMode] = useState<Mode>('view');
|
||||||
const [menuIndex, setMenuIndex] = useState(0);
|
const [menuIndex, setMenuIndex] = useState(0);
|
||||||
const [batchId, setBatchId] = useState('');
|
const [batchId, setBatchId] = useState('');
|
||||||
|
const [newDate, setNewDate] = useState('');
|
||||||
const [success, setSuccess] = useState<string | null>(null);
|
const [success, setSuccess] = useState<string | null>(null);
|
||||||
|
|
||||||
const orderId = params.orderId ?? '';
|
const orderId = params.orderId ?? '';
|
||||||
|
|
@ -39,11 +40,13 @@ export function ProductionOrderDetailScreen() {
|
||||||
const getMenuItems = () => {
|
const getMenuItems = () => {
|
||||||
const items: { label: string; action: string }[] = [];
|
const items: { label: string; action: string }[] = [];
|
||||||
const status = productionOrder?.status;
|
const status = productionOrder?.status;
|
||||||
if (status === 'CREATED') {
|
if (status === 'PLANNED') {
|
||||||
items.push({ label: 'Freigeben', action: 'release' });
|
items.push({ label: 'Freigeben', action: 'release' });
|
||||||
|
items.push({ label: 'Umterminieren', action: 'reschedule' });
|
||||||
}
|
}
|
||||||
if (status === 'RELEASED') {
|
if (status === 'RELEASED') {
|
||||||
items.push({ label: 'Produktion starten', action: 'start' });
|
items.push({ label: 'Produktion starten', action: 'start' });
|
||||||
|
items.push({ label: 'Umterminieren', action: 'reschedule' });
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
};
|
};
|
||||||
|
|
@ -68,9 +71,24 @@ export function ProductionOrderDetailScreen() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleReschedule = async () => {
|
||||||
|
if (!newDate.trim()) return;
|
||||||
|
const result = await rescheduleProductionOrder(orderId, newDate.trim());
|
||||||
|
if (result) {
|
||||||
|
setSuccess(`Umterminiert auf ${newDate.trim()}.`);
|
||||||
|
setMode('view');
|
||||||
|
setNewDate('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useInput((_input, key) => {
|
useInput((_input, key) => {
|
||||||
if (loading) return;
|
if (loading) return;
|
||||||
|
|
||||||
|
if (mode === 'reschedule-input') {
|
||||||
|
if (key.escape) setMode('menu');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode === 'start-batch-input') {
|
if (mode === 'start-batch-input') {
|
||||||
if (key.escape) setMode('menu');
|
if (key.escape) setMode('menu');
|
||||||
return;
|
return;
|
||||||
|
|
@ -82,6 +100,10 @@ export function ProductionOrderDetailScreen() {
|
||||||
if (key.return && menuItems[menuIndex]) {
|
if (key.return && menuItems[menuIndex]) {
|
||||||
const action = menuItems[menuIndex].action;
|
const action = menuItems[menuIndex].action;
|
||||||
if (action === 'release') void handleRelease();
|
if (action === 'release') void handleRelease();
|
||||||
|
if (action === 'reschedule') {
|
||||||
|
setMode('reschedule-input');
|
||||||
|
setNewDate('');
|
||||||
|
}
|
||||||
if (action === 'start') {
|
if (action === 'start') {
|
||||||
setMode('start-batch-input');
|
setMode('start-batch-input');
|
||||||
setBatchId('');
|
setBatchId('');
|
||||||
|
|
@ -175,6 +197,22 @@ export function ProductionOrderDetailScreen() {
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{mode === 'reschedule-input' && (
|
||||||
|
<Box flexDirection="column" borderStyle="round" borderColor="yellow" paddingX={1}>
|
||||||
|
<Text color="yellow" bold>Neues Datum (YYYY-MM-DD):</Text>
|
||||||
|
<Box>
|
||||||
|
<Text color="gray"> › </Text>
|
||||||
|
<TextInput
|
||||||
|
value={newDate}
|
||||||
|
onChange={setNewDate}
|
||||||
|
onSubmit={() => void handleReschedule()}
|
||||||
|
focus={true}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Text color="gray" dimColor>Enter bestätigen · Escape abbrechen</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box marginTop={1}>
|
<Box marginTop={1}>
|
||||||
<Text color="gray" dimColor>
|
<Text color="gray" dimColor>
|
||||||
{menuItems.length > 0 ? '[m] Aktionsmenü · ' : ''}Backspace Zurück
|
{menuItems.length > 0 ? '[m] Aktionsmenü · ' : ''}Backspace Zurück
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,25 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState, useCallback } from 'react';
|
||||||
import { Box, Text, useInput } from 'ink';
|
import { Box, Text, useInput } from 'ink';
|
||||||
import { useNavigation } from '../../state/navigation-context.js';
|
import { useNavigation } from '../../state/navigation-context.js';
|
||||||
import { useProductionOrders } from '../../hooks/useProductionOrders.js';
|
import { useProductionOrders } from '../../hooks/useProductionOrders.js';
|
||||||
import { LoadingSpinner } from '../shared/LoadingSpinner.js';
|
import { LoadingSpinner } from '../shared/LoadingSpinner.js';
|
||||||
import { ErrorDisplay } from '../shared/ErrorDisplay.js';
|
import { ErrorDisplay } from '../shared/ErrorDisplay.js';
|
||||||
import { PRODUCTION_ORDER_STATUS_LABELS, PRIORITY_LABELS } from '@effigenix/api-client';
|
import { PRODUCTION_ORDER_STATUS_LABELS, PRIORITY_LABELS } from '@effigenix/api-client';
|
||||||
import type { ProductionOrderStatus, Priority } from '@effigenix/api-client';
|
import type { ProductionOrderStatus, Priority, ProductionOrderFilter } from '@effigenix/api-client';
|
||||||
|
|
||||||
|
const STATUS_FILTER_KEYS: Record<string, { status?: ProductionOrderStatus; label: string }> = {
|
||||||
|
a: { label: 'Alle' },
|
||||||
|
p: { status: 'PLANNED', label: 'Geplant' },
|
||||||
|
f: { status: 'RELEASED', label: 'Freigegeben' },
|
||||||
|
i: { status: 'IN_PROGRESS', label: 'In Produktion' },
|
||||||
|
c: { status: 'COMPLETED', label: 'Abgeschlossen' },
|
||||||
|
x: { status: 'CANCELLED', label: 'Storniert' },
|
||||||
|
};
|
||||||
|
|
||||||
const STATUS_COLORS: Record<string, string> = {
|
const STATUS_COLORS: Record<string, string> = {
|
||||||
CREATED: 'gray',
|
PLANNED: 'gray',
|
||||||
RELEASED: 'yellow',
|
RELEASED: 'yellow',
|
||||||
IN_PRODUCTION: 'blue',
|
IN_PROGRESS: 'blue',
|
||||||
COMPLETED: 'green',
|
COMPLETED: 'green',
|
||||||
CANCELLED: 'red',
|
CANCELLED: 'red',
|
||||||
};
|
};
|
||||||
|
|
@ -19,6 +28,14 @@ export function ProductionOrderListScreen() {
|
||||||
const { navigate, back } = useNavigation();
|
const { navigate, back } = useNavigation();
|
||||||
const { productionOrders, loading, error, fetchProductionOrders, clearError } = useProductionOrders();
|
const { productionOrders, loading, error, fetchProductionOrders, clearError } = useProductionOrders();
|
||||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||||
|
const [activeFilter, setActiveFilter] = useState<{ status?: ProductionOrderStatus; label: string }>({ label: 'Alle' });
|
||||||
|
|
||||||
|
const loadWithFilter = useCallback((filter: { status?: ProductionOrderStatus; label: string }) => {
|
||||||
|
setActiveFilter(filter);
|
||||||
|
setSelectedIndex(0);
|
||||||
|
const f: ProductionOrderFilter | undefined = filter.status ? { status: filter.status } : undefined;
|
||||||
|
void fetchProductionOrders(f);
|
||||||
|
}, [fetchProductionOrders]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void fetchProductionOrders();
|
void fetchProductionOrders();
|
||||||
|
|
@ -35,7 +52,11 @@ export function ProductionOrderListScreen() {
|
||||||
if (order?.id) navigate('production-order-detail', { orderId: order.id });
|
if (order?.id) navigate('production-order-detail', { orderId: order.id });
|
||||||
}
|
}
|
||||||
if (input === 'n') navigate('production-order-create');
|
if (input === 'n') navigate('production-order-create');
|
||||||
if (input === 'r') void fetchProductionOrders();
|
if (input === 'r') loadWithFilter(activeFilter);
|
||||||
|
|
||||||
|
const filterDef = STATUS_FILTER_KEYS[input];
|
||||||
|
if (filterDef) loadWithFilter(filterDef);
|
||||||
|
|
||||||
if (key.backspace || key.escape) back();
|
if (key.backspace || key.escape) back();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -44,6 +65,7 @@ export function ProductionOrderListScreen() {
|
||||||
<Box gap={2}>
|
<Box gap={2}>
|
||||||
<Text color="cyan" bold>Produktionsaufträge</Text>
|
<Text color="cyan" bold>Produktionsaufträge</Text>
|
||||||
<Text color="gray" dimColor>({productionOrders.length})</Text>
|
<Text color="gray" dimColor>({productionOrders.length})</Text>
|
||||||
|
{activeFilter.status && <Text color="yellow">[{activeFilter.label}]</Text>}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{loading && <LoadingSpinner label="Lade Aufträge..." />}
|
{loading && <LoadingSpinner label="Lade Aufträge..." />}
|
||||||
|
|
@ -86,7 +108,7 @@ export function ProductionOrderListScreen() {
|
||||||
|
|
||||||
<Box marginTop={1}>
|
<Box marginTop={1}>
|
||||||
<Text color="gray" dimColor>
|
<Text color="gray" dimColor>
|
||||||
↑↓ nav · Enter Details · [n] Neu · [r] Aktualisieren · Backspace Zurück
|
↑↓ nav · Enter Details · [n] Neu · [r] Aktualisieren · [a]lle [p]lan [f]rei [i]n Prod [c]omp [x]storno · Bksp Zurück
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
import type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest } from '@effigenix/api-client';
|
import type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest, ProductionOrderFilter } from '@effigenix/api-client';
|
||||||
import { client } from '../utils/api-client.js';
|
import { client } from '../utils/api-client.js';
|
||||||
|
|
||||||
interface ProductionOrdersState {
|
interface ProductionOrdersState {
|
||||||
|
|
@ -21,10 +21,10 @@ export function useProductionOrders() {
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchProductionOrders = useCallback(async () => {
|
const fetchProductionOrders = useCallback(async (filter?: ProductionOrderFilter) => {
|
||||||
setState((s) => ({ ...s, loading: true, error: null }));
|
setState((s) => ({ ...s, loading: true, error: null }));
|
||||||
try {
|
try {
|
||||||
const productionOrders = await client.productionOrders.list();
|
const productionOrders = await client.productionOrders.list(filter);
|
||||||
setState((s) => ({ ...s, productionOrders, loading: false, error: null }));
|
setState((s) => ({ ...s, productionOrders, loading: false, error: null }));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
|
setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
|
||||||
|
|
@ -65,6 +65,18 @@ export function useProductionOrders() {
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const rescheduleProductionOrder = useCallback(async (id: string, newPlannedDate: string) => {
|
||||||
|
setState((s) => ({ ...s, loading: true, error: null }));
|
||||||
|
try {
|
||||||
|
const productionOrder = await client.productionOrders.reschedule(id, { newPlannedDate });
|
||||||
|
setState((s) => ({ ...s, productionOrder, loading: false, error: null }));
|
||||||
|
return productionOrder;
|
||||||
|
} catch (err) {
|
||||||
|
setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const startProductionOrder = useCallback(async (id: string, request: StartProductionOrderRequest) => {
|
const startProductionOrder = useCallback(async (id: string, request: StartProductionOrderRequest) => {
|
||||||
setState((s) => ({ ...s, loading: true, error: null }));
|
setState((s) => ({ ...s, loading: true, error: null }));
|
||||||
try {
|
try {
|
||||||
|
|
@ -87,6 +99,7 @@ export function useProductionOrders() {
|
||||||
fetchProductionOrder,
|
fetchProductionOrder,
|
||||||
createProductionOrder,
|
createProductionOrder,
|
||||||
releaseProductionOrder,
|
releaseProductionOrder,
|
||||||
|
rescheduleProductionOrder,
|
||||||
startProductionOrder,
|
startProductionOrder,
|
||||||
clearError,
|
clearError,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,19 @@ export function useStocks() {
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const confirmReservation = useCallback(async (stockId: string, reservationId: string) => {
|
||||||
|
setState((s) => ({ ...s, loading: true, error: null }));
|
||||||
|
try {
|
||||||
|
await client.stocks.confirmReservation(stockId, reservationId);
|
||||||
|
const stock = await client.stocks.getById(stockId);
|
||||||
|
setState((s) => ({ ...s, stock, loading: false, error: null }));
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const releaseReservation = useCallback(async (stockId: string, reservationId: string) => {
|
const releaseReservation = useCallback(async (stockId: string, reservationId: string) => {
|
||||||
setState((s) => ({ ...s, loading: true, error: null }));
|
setState((s) => ({ ...s, loading: true, error: null }));
|
||||||
try {
|
try {
|
||||||
|
|
@ -166,6 +179,7 @@ export function useStocks() {
|
||||||
unblockBatch,
|
unblockBatch,
|
||||||
reserveStock,
|
reserveStock,
|
||||||
releaseReservation,
|
releaseReservation,
|
||||||
|
confirmReservation,
|
||||||
clearError,
|
clearError,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -144,7 +144,7 @@ export type { RecipesResource, RecipeType, RecipeStatus, UoM } from './resources
|
||||||
export { RECIPE_TYPE_LABELS, UOM_VALUES, UOM_LABELS } from './resources/recipes.js';
|
export { RECIPE_TYPE_LABELS, UOM_VALUES, UOM_LABELS } from './resources/recipes.js';
|
||||||
export type { BatchesResource, BatchStatus } from './resources/batches.js';
|
export type { BatchesResource, BatchStatus } from './resources/batches.js';
|
||||||
export { BATCH_STATUS_LABELS } from './resources/batches.js';
|
export { BATCH_STATUS_LABELS } from './resources/batches.js';
|
||||||
export type { ProductionOrdersResource, Priority, ProductionOrderStatus } from './resources/production-orders.js';
|
export type { ProductionOrdersResource, Priority, ProductionOrderStatus, ProductionOrderFilter, RescheduleProductionOrderRequest } from './resources/production-orders.js';
|
||||||
export { PRIORITY_LABELS, PRODUCTION_ORDER_STATUS_LABELS } 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 { StocksResource, BatchType, StockBatchStatus, StockFilter, ReferenceType, ReservationPriority } from './resources/stocks.js';
|
||||||
export type { StockMovementsResource, MovementType, MovementDirection, StockMovementFilter } from './resources/stock-movements.js';
|
export type { StockMovementsResource, MovementType, MovementDirection, StockMovementFilter } from './resources/stock-movements.js';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/** Production Orders resource – Production BC. */
|
/** Production Orders resource – Production BC. */
|
||||||
|
|
||||||
import type { AxiosInstance } from 'axios';
|
import type { AxiosInstance } from 'axios';
|
||||||
import type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest } from '@effigenix/types';
|
import type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest, RescheduleProductionOrderRequest } from '@effigenix/types';
|
||||||
|
|
||||||
export type Priority = 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
|
export type Priority = 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
|
||||||
|
|
||||||
|
|
@ -12,24 +12,34 @@ export const PRIORITY_LABELS: Record<Priority, string> = {
|
||||||
URGENT: 'Dringend',
|
URGENT: 'Dringend',
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProductionOrderStatus = 'CREATED' | 'RELEASED' | 'IN_PRODUCTION' | 'COMPLETED' | 'CANCELLED';
|
export type ProductionOrderStatus = 'PLANNED' | 'RELEASED' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED';
|
||||||
|
|
||||||
export const PRODUCTION_ORDER_STATUS_LABELS: Record<ProductionOrderStatus, string> = {
|
export const PRODUCTION_ORDER_STATUS_LABELS: Record<ProductionOrderStatus, string> = {
|
||||||
CREATED: 'Erstellt',
|
PLANNED: 'Geplant',
|
||||||
RELEASED: 'Freigegeben',
|
RELEASED: 'Freigegeben',
|
||||||
IN_PRODUCTION: 'In Produktion',
|
IN_PROGRESS: 'In Produktion',
|
||||||
COMPLETED: 'Abgeschlossen',
|
COMPLETED: 'Abgeschlossen',
|
||||||
CANCELLED: 'Storniert',
|
CANCELLED: 'Storniert',
|
||||||
};
|
};
|
||||||
|
|
||||||
export type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest };
|
export interface ProductionOrderFilter {
|
||||||
|
status?: ProductionOrderStatus;
|
||||||
|
dateFrom?: string;
|
||||||
|
dateTo?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { ProductionOrderDTO, CreateProductionOrderRequest, StartProductionOrderRequest, RescheduleProductionOrderRequest };
|
||||||
|
|
||||||
const BASE = '/api/production/production-orders';
|
const BASE = '/api/production/production-orders';
|
||||||
|
|
||||||
export function createProductionOrdersResource(client: AxiosInstance) {
|
export function createProductionOrdersResource(client: AxiosInstance) {
|
||||||
return {
|
return {
|
||||||
async list(): Promise<ProductionOrderDTO[]> {
|
async list(filter?: ProductionOrderFilter): Promise<ProductionOrderDTO[]> {
|
||||||
const res = await client.get<ProductionOrderDTO[]>(BASE);
|
const params: Record<string, string> = {};
|
||||||
|
if (filter?.status) params.status = filter.status;
|
||||||
|
if (filter?.dateFrom) params.dateFrom = filter.dateFrom;
|
||||||
|
if (filter?.dateTo) params.dateTo = filter.dateTo;
|
||||||
|
const res = await client.get<ProductionOrderDTO[]>(BASE, { params });
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -52,6 +62,11 @@ export function createProductionOrdersResource(client: AxiosInstance) {
|
||||||
const res = await client.post<ProductionOrderDTO>(`${BASE}/${id}/start`, request);
|
const res = await client.post<ProductionOrderDTO>(`${BASE}/${id}/start`, request);
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async reschedule(id: string, request: RescheduleProductionOrderRequest): Promise<ProductionOrderDTO> {
|
||||||
|
const res = await client.post<ProductionOrderDTO>(`${BASE}/${id}/reschedule`, request);
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,10 @@ export function createStocksResource(client: AxiosInstance) {
|
||||||
async releaseReservation(stockId: string, reservationId: string): Promise<void> {
|
async releaseReservation(stockId: string, reservationId: string): Promise<void> {
|
||||||
await client.delete(`${BASE}/${stockId}/reservations/${reservationId}`);
|
await client.delete(`${BASE}/${stockId}/reservations/${reservationId}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async confirmReservation(stockId: string, reservationId: string): Promise<void> {
|
||||||
|
await client.post(`${BASE}/${stockId}/reservations/${reservationId}/confirm`);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -443,7 +443,7 @@ export interface paths {
|
||||||
path?: never;
|
path?: never;
|
||||||
cookie?: never;
|
cookie?: never;
|
||||||
};
|
};
|
||||||
get?: never;
|
get: operations["listProductionOrders"];
|
||||||
put?: never;
|
put?: never;
|
||||||
post: operations["createProductionOrder"];
|
post: operations["createProductionOrder"];
|
||||||
delete?: never;
|
delete?: never;
|
||||||
|
|
@ -468,6 +468,22 @@ export interface paths {
|
||||||
patch?: never;
|
patch?: never;
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/api/production/production-orders/{id}/reschedule": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get?: never;
|
||||||
|
put?: never;
|
||||||
|
post: operations["rescheduleProductionOrder"];
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/api/production/production-orders/{id}/release": {
|
"/api/production/production-orders/{id}/release": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
@ -484,6 +500,38 @@ export interface paths {
|
||||||
patch?: never;
|
patch?: never;
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/api/production/production-orders/{id}/complete": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get?: never;
|
||||||
|
put?: never;
|
||||||
|
post: operations["completeProductionOrder"];
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
|
"/api/production/production-orders/{id}/cancel": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get?: never;
|
||||||
|
put?: never;
|
||||||
|
post: operations["cancelProductionOrder"];
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/api/production/batches": {
|
"/api/production/batches": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
@ -612,6 +660,22 @@ export interface paths {
|
||||||
patch?: never;
|
patch?: never;
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/api/inventory/stocks/{stockId}/reservations/{reservationId}/confirm": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get?: never;
|
||||||
|
put?: never;
|
||||||
|
post: operations["confirmReservation"];
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/api/inventory/stocks/{stockId}/batches": {
|
"/api/inventory/stocks/{stockId}/batches": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
@ -984,6 +1048,22 @@ export interface paths {
|
||||||
patch?: never;
|
patch?: never;
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/api/production/production-orders/{id}": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get: operations["getProductionOrder"];
|
||||||
|
put?: never;
|
||||||
|
post?: never;
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/api/production/batches/{id}": {
|
"/api/production/batches/{id}": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
@ -1628,6 +1708,7 @@ export interface components {
|
||||||
plannedDate?: string;
|
plannedDate?: string;
|
||||||
priority?: string;
|
priority?: string;
|
||||||
notes?: string;
|
notes?: string;
|
||||||
|
cancelledReason?: string;
|
||||||
/** Format: date-time */
|
/** Format: date-time */
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
/** Format: date-time */
|
/** Format: date-time */
|
||||||
|
|
@ -1636,6 +1717,13 @@ export interface components {
|
||||||
StartProductionOrderRequest: {
|
StartProductionOrderRequest: {
|
||||||
batchId: string;
|
batchId: string;
|
||||||
};
|
};
|
||||||
|
RescheduleProductionOrderRequest: {
|
||||||
|
/** Format: date */
|
||||||
|
newPlannedDate: string;
|
||||||
|
};
|
||||||
|
CancelProductionOrderRequest: {
|
||||||
|
reason: string;
|
||||||
|
};
|
||||||
PlanBatchRequest: {
|
PlanBatchRequest: {
|
||||||
recipeId: string;
|
recipeId: string;
|
||||||
plannedQuantity: string;
|
plannedQuantity: string;
|
||||||
|
|
@ -2973,6 +3061,30 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
listProductionOrders: {
|
||||||
|
parameters: {
|
||||||
|
query?: {
|
||||||
|
dateFrom?: string;
|
||||||
|
dateTo?: string;
|
||||||
|
status?: "PLANNED" | "RELEASED" | "IN_PROGRESS" | "COMPLETED" | "CANCELLED";
|
||||||
|
};
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
/** @description OK */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"*/*": components["schemas"]["ProductionOrderResponse"][];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
createProductionOrder: {
|
createProductionOrder: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
@ -3023,6 +3135,32 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
rescheduleProductionOrder: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody: {
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["RescheduleProductionOrderRequest"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: {
|
||||||
|
/** @description OK */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"*/*": components["schemas"]["ProductionOrderResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
releaseProductionOrder: {
|
releaseProductionOrder: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
@ -3045,6 +3183,54 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
completeProductionOrder: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
/** @description OK */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"*/*": components["schemas"]["ProductionOrderResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
cancelProductionOrder: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody: {
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["CancelProductionOrderRequest"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: {
|
||||||
|
/** @description OK */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"*/*": components["schemas"]["ProductionOrderResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
listBatches: {
|
listBatches: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: {
|
query?: {
|
||||||
|
|
@ -3313,6 +3499,27 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
confirmReservation: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path: {
|
||||||
|
stockId: string;
|
||||||
|
reservationId: string;
|
||||||
|
};
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
/** @description OK */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content?: never;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
addBatch: {
|
addBatch: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
@ -3969,6 +4176,28 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
getProductionOrder: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody?: never;
|
||||||
|
responses: {
|
||||||
|
/** @description OK */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"*/*": components["schemas"]["ProductionOrderResponse"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
getBatch: {
|
getBatch: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
|
||||||
|
|
@ -31,3 +31,5 @@ export type CancelBatchRequest = components['schemas']['CancelBatchRequest'];
|
||||||
export type ProductionOrderDTO = components['schemas']['ProductionOrderResponse'];
|
export type ProductionOrderDTO = components['schemas']['ProductionOrderResponse'];
|
||||||
export type CreateProductionOrderRequest = components['schemas']['CreateProductionOrderRequest'];
|
export type CreateProductionOrderRequest = components['schemas']['CreateProductionOrderRequest'];
|
||||||
export type StartProductionOrderRequest = components['schemas']['StartProductionOrderRequest'];
|
export type StartProductionOrderRequest = components['schemas']['StartProductionOrderRequest'];
|
||||||
|
export type RescheduleProductionOrderRequest = components['schemas']['RescheduleProductionOrderRequest'];
|
||||||
|
export type CancelProductionOrderRequest = components['schemas']['CancelProductionOrderRequest'];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue