Charge aufteilen: Teilmenge mit gleichem MHD an anderen Lagerort umlagern
Bisher liess sich nur die ganze Charge umlagern. Neu: POST /lots/{id}/split zweigt
eine Teilmenge (Basiseinheiten) als neue Charge mit gleichem MHD an einen anderen
Lagerort ab; der Rest bleibt. Reine Umbuchung ohne Bewegungseintrag, Gesamtbestand
unveraendert. Schutz gegen zu grosse Menge und gleichen Zielort.
Web: gemeinsamer SplitLotDialog (Menge in Artikeleinheit + Zielort, zeigt Rest),
Aufteilen-Knopf auf der Chargen-Seite und in der Chargen-Tabelle der Artikelseite.
Neues Split-Icon.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { api } from "../api";
|
||||
import { useAuth } from "../auth";
|
||||
import Icon from "../components/Icon";
|
||||
import DataTable from "../components/DataTable";
|
||||
import SplitLotDialog from "../components/SplitLotDialog";
|
||||
import { ProduktThumb } from "../components/ProduktBild";
|
||||
import { useSettings } from "../settings";
|
||||
import { locationOptions, locationPathById } from "../locationPath";
|
||||
@@ -34,6 +35,7 @@ export default function Charges() {
|
||||
const [bulkLoc, setBulkLoc] = useState("");
|
||||
const [selected, setSelected] = useState(() => new Set());
|
||||
const [visible, setVisible] = useState([]); // aktuell gefiltert sichtbare Chargen
|
||||
const [splitting, setSplitting] = useState(null); // Charge, die gerade aufgeteilt wird
|
||||
|
||||
async function load() {
|
||||
setLoading(true);
|
||||
@@ -130,6 +132,11 @@ export default function Charges() {
|
||||
{ key: "created", header: "Eingelagert", width: 130,
|
||||
sortValue: (l) => new Date(l.created_at).getTime(),
|
||||
render: (l) => <span className="muted">{new Date(l.created_at).toLocaleDateString("de-DE")}</span> },
|
||||
{ key: "split", header: "", label: "Aufteilen", fixed: true, width: 118, align: "num",
|
||||
render: (l) => (isAdmin ? (
|
||||
<button type="button" className="btn sm ghost" title="Charge aufteilen und Teil umlagern"
|
||||
onClick={() => setSplitting(l)}><Icon name="split" size={15} />Aufteilen</button>
|
||||
) : null) },
|
||||
{ key: "details", header: "", label: "Artikel", fixed: true, width: 84, align: "num",
|
||||
render: (l) => <Link to={`/products/${l.product_id}`}>Artikel</Link> },
|
||||
];
|
||||
@@ -192,6 +199,20 @@ export default function Charges() {
|
||||
}}
|
||||
getRowKey={(l) => l.id} empty="Keine Chargen im Bestand." />
|
||||
</div>
|
||||
|
||||
{splitting && (
|
||||
<SplitLotDialog
|
||||
lot={splitting}
|
||||
factor={artFactor(splitting)}
|
||||
labelFor={(q) => (splitting.package_size && splitting.package_size > 0
|
||||
? gebinde(q, splitting.package_label)
|
||||
: (splitting.unit_name || unitShort(splitting.base_unit)))}
|
||||
locations={locations}
|
||||
onClose={() => setSplitting(null)}
|
||||
onDone={load}
|
||||
onError={setError}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user