Chargen: Anzeige und Bearbeitung in derselben Einheit + Zweitangabe
- Chargen werden in der Produkteinheit angezeigt, darunter die Zweitangabe (Basiseinheit falls abweichend und/oder Packungen). - Bearbeiten laeuft jetzt ebenfalls in der Produkteinheit (mit Einheit neben dem Feld) und rechnet beim Speichern in die Basiseinheit um - vorher zeigte die Bearbeitung einen anderen Wert als die Anzeige. - Produktkopf zeigt den Bestand zusaetzlich in Packungen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -206,6 +206,7 @@ export default function ProductForm() {
|
|||||||
{!isNew && product && (
|
{!isNew && product && (
|
||||||
<div className="sub">
|
<div className="sub">
|
||||||
Bestand: {fmt(product.stock / (product.unit_factor || 1))} {product.unit_name}
|
Bestand: {fmt(product.stock / (product.unit_factor || 1))} {product.unit_name}
|
||||||
|
{product.package_size ? ` · ${fmt(product.stock / product.package_size)} Pkg` : ""}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -287,7 +288,7 @@ export default function ProductForm() {
|
|||||||
|
|
||||||
{!isNew && (
|
{!isNew && (
|
||||||
<LotsCard
|
<LotsCard
|
||||||
productId={id}
|
product={product}
|
||||||
lots={lots}
|
lots={lots}
|
||||||
baseShort={baseShort}
|
baseShort={baseShort}
|
||||||
warnDays={warnDays}
|
warnDays={warnDays}
|
||||||
@@ -305,20 +306,31 @@ export default function ProductForm() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Chargen-Karte mit Bearbeiten/Löschen. */
|
/** Chargen-Karte mit Bearbeiten/Löschen. Bearbeitet wird in der Produkteinheit. */
|
||||||
function LotsCard({ productId, lots, baseShort, warnDays, isAdmin, imageUrl, onChanged, onError }) {
|
function LotsCard({ product, lots, baseShort, warnDays, isAdmin, imageUrl, onChanged, onError }) {
|
||||||
const [editId, setEditId] = useState(null);
|
const [editId, setEditId] = useState(null);
|
||||||
const [draft, setDraft] = useState({ quantity: "", best_before: "" });
|
const [draft, setDraft] = useState({ quantity: "", best_before: "" });
|
||||||
|
|
||||||
|
const factor = product?.unit_factor || 1;
|
||||||
|
const unitName = product?.unit_name || baseShort;
|
||||||
|
const pkgSize = product?.package_size || 0;
|
||||||
|
// Zweitangabe: Basiseinheit (falls abweichend) und/oder Packungen.
|
||||||
|
function secondary(qty) {
|
||||||
|
const parts = [];
|
||||||
|
if (factor !== 1) parts.push(`${fmt(qty)} ${baseShort}`);
|
||||||
|
if (pkgSize > 0) parts.push(`${fmt(qty / pkgSize)} Pkg`);
|
||||||
|
return parts.join(" · ");
|
||||||
|
}
|
||||||
|
|
||||||
function startEdit(l) {
|
function startEdit(l) {
|
||||||
setEditId(l.id);
|
setEditId(l.id);
|
||||||
setDraft({ quantity: l.quantity, best_before: l.best_before || "" });
|
setDraft({ quantity: l.quantity / factor, best_before: l.best_before || "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveEdit(l) {
|
async function saveEdit(l) {
|
||||||
try {
|
try {
|
||||||
await api.updateLot(l.id, {
|
await api.updateLot(l.id, {
|
||||||
quantity: Number(draft.quantity),
|
quantity: Number(draft.quantity) * factor,
|
||||||
best_before: draft.best_before || null,
|
best_before: draft.best_before || null,
|
||||||
});
|
});
|
||||||
setEditId(null);
|
setEditId(null);
|
||||||
@@ -361,11 +373,19 @@ function LotsCard({ productId, lots, baseShort, warnDays, isAdmin, imageUrl, onC
|
|||||||
<tr key={l.id} className={cls}>
|
<tr key={l.id} className={cls}>
|
||||||
<td className="num">
|
<td className="num">
|
||||||
{editing ? (
|
{editing ? (
|
||||||
|
<div className="field-inline" style={{ justifyContent: "flex-end" }}>
|
||||||
<input type="number" step="any" min="0" value={draft.quantity}
|
<input type="number" step="any" min="0" value={draft.quantity}
|
||||||
onChange={(e) => setDraft({ ...draft, quantity: e.target.value })}
|
onChange={(e) => setDraft({ ...draft, quantity: e.target.value })}
|
||||||
style={{ maxWidth: 100, marginTop: 0 }} />
|
style={{ maxWidth: 90, marginTop: 0 }} />
|
||||||
|
<span className="muted small">{unitName}</span>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>{fmt(l.quantity)} {baseShort}</>
|
<>
|
||||||
|
{fmt(l.quantity / factor)} {unitName}
|
||||||
|
{secondary(l.quantity) && (
|
||||||
|
<div className="muted small">{secondary(l.quantity)}</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -406,7 +426,10 @@ function LotsCard({ productId, lots, baseShort, warnDays, isAdmin, imageUrl, onC
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<p className="muted small">Mengen sind in der Basiseinheit ({baseShort}) angegeben.</p>
|
<p className="muted small">
|
||||||
|
Mengen in {unitName}
|
||||||
|
{pkgSize > 0 ? `; 1 Packung = ${fmt(pkgSize)} ${baseShort}` : ""}.
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user