A bottling batch could only be corrected in four of its seven fields after creation: honey batch, jar size and jar count were frozen at creation time, an assigned product could not be cleared again, and there was no way to remove a record entered by mistake at all. A mistyped jar count is a data-entry error, not a fact of production, so it has to stay correctable. Backend: - UpdateBottlingBatchDto now covers every field. `productId: null` explicitly clears the product assignment; omitting it leaves it alone. - BottlingService.update rebalances the affected honey batch amounts: the previously bottled amount is given back before the corrected amount is taken again, so a correction never double-charges the source batch. Moving a batch to a different honey batch credits the old one and debits the new one in the same transaction. - New DELETE /bottling-batches/:id gives the bottled amount back to the honey batch and keeps the full record in the audit log (action DELETE, beforeData). The honey batch status is deliberately left untouched - the status it held before being bottled is not recoverable here. - New permission bottling:delete, checked server-side. The catalog sync grants it to system roles on the next boot. Frontend: - The edit dialog exposes all fields, offers "Kein Produkt" to clear the assignment, keeps a discontinued product selectable so opening the dialog cannot silently drop it, and shows backend errors inline. - The form is mounted only while the dialog is open, so a cancelled edit never leaks its values into the next one. - New delete button behind a confirmation that names the amount credited back and warns that the public origin page for the lot number stops resolving. - Edit and delete are additionally hidden without the matching permission. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
import { apiFetch } from "@/lib/auth/api-client";
|
|
import {
|
|
BottlingBatch,
|
|
BottlingBatchFilter,
|
|
CreateBottlingBatchInput,
|
|
UpdateBottlingBatchInput,
|
|
} from "./types";
|
|
|
|
export function fetchBottlingBatches(
|
|
filter: BottlingBatchFilter = {},
|
|
): Promise<BottlingBatch[]> {
|
|
const params = new URLSearchParams();
|
|
if (filter.honeyBatchId) params.set("honeyBatchId", filter.honeyBatchId);
|
|
const query = params.toString();
|
|
return apiFetch<BottlingBatch[]>(`/bottling-batches${query ? `?${query}` : ""}`);
|
|
}
|
|
|
|
export function fetchBottlingBatch(id: string): Promise<BottlingBatch> {
|
|
return apiFetch<BottlingBatch>(`/bottling-batches/${id}`);
|
|
}
|
|
|
|
export function createBottlingBatch(
|
|
input: CreateBottlingBatchInput,
|
|
): Promise<BottlingBatch> {
|
|
return apiFetch<BottlingBatch>("/bottling-batches", {
|
|
method: "POST",
|
|
body: JSON.stringify(input),
|
|
});
|
|
}
|
|
|
|
export function updateBottlingBatch(
|
|
id: string,
|
|
input: UpdateBottlingBatchInput,
|
|
): Promise<BottlingBatch> {
|
|
return apiFetch<BottlingBatch>(`/bottling-batches/${id}`, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(input),
|
|
});
|
|
}
|
|
|
|
export function deleteBottlingBatch(id: string): Promise<{ id: string }> {
|
|
return apiFetch<{ id: string }>(`/bottling-batches/${id}`, {
|
|
method: "DELETE",
|
|
});
|
|
}
|