rework internal order system

This commit is contained in:
Matthias Hochmeister
2026-03-24 14:02:16 +01:00
parent 90944ca5f6
commit abb337c683
9 changed files with 261 additions and 75 deletions

View File

@@ -529,10 +529,14 @@ function DetailModal({ requestId, onClose, showAdminActions, showEditButton, can
<>
{/* Meta info */}
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1.5 }}>
{anfrage!.anfrager_name && (
{(anfrage!.anfrager_name || anfrage!.fuer_benutzer_name) && (
<Box>
<Typography variant="caption" color="text.secondary">Anfrage für</Typography>
<Typography variant="body2" fontWeight={500}>{anfrage!.anfrager_name}</Typography>
<Typography variant="body2" fontWeight={500}>
{anfrage!.fuer_benutzer_name
? `${anfrage!.fuer_benutzer_name} (erstellt von ${anfrage!.anfrager_name || 'Unbekannt'})`
: anfrage!.anfrager_name}
</Typography>
</Box>
)}
<Box>
@@ -987,7 +991,7 @@ function MeineAnfragenTab() {
const [createDialogOpen, setCreateDialogOpen] = useState(false);
const [newBezeichnung, setNewBezeichnung] = useState('');
const [newNotizen, setNewNotizen] = useState('');
const [newFuerBenutzer, setNewFuerBenutzer] = useState<{ id: string; name: string } | null>(null);
const [newFuerBenutzer, setNewFuerBenutzer] = useState<{ id: string; name: string } | string | null>(null);
const [newItems, setNewItems] = useState<AusruestungAnfrageFormItem[]>([{ bezeichnung: '', menge: 1 }]);
// Track loaded eigenschaften per item row (by artikel_id)
const [itemEigenschaften, setItemEigenschaften] = useState<Record<number, AusruestungEigenschaft[]>>({});
@@ -1016,8 +1020,8 @@ function MeineAnfragenTab() {
});
const createMut = useMutation({
mutationFn: (args: { items: AusruestungAnfrageFormItem[]; notizen?: string; bezeichnung?: string; fuer_benutzer_id?: string }) =>
ausruestungsanfrageApi.createRequest(args.items, args.notizen, args.bezeichnung, args.fuer_benutzer_id),
mutationFn: (args: { items: AusruestungAnfrageFormItem[]; notizen?: string; bezeichnung?: string; fuer_benutzer_id?: string; fuer_benutzer_name?: string }) =>
ausruestungsanfrageApi.createRequest(args.items, args.notizen, args.bezeichnung, args.fuer_benutzer_id, args.fuer_benutzer_name),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['ausruestungsanfrage'] });
showSuccess('Anfrage erstellt');
@@ -1085,7 +1089,8 @@ function MeineAnfragenTab() {
items: allItems,
notizen: newNotizen || undefined,
bezeichnung: newBezeichnung || undefined,
fuer_benutzer_id: newFuerBenutzer?.id,
fuer_benutzer_id: typeof newFuerBenutzer === 'object' && newFuerBenutzer ? newFuerBenutzer.id : undefined,
fuer_benutzer_name: typeof newFuerBenutzer === 'string' ? newFuerBenutzer : undefined,
});
};
@@ -1181,11 +1186,27 @@ function MeineAnfragenTab() {
/>
{canOrderForUser && (
<Autocomplete
freeSolo
options={orderUsers}
getOptionLabel={o => o.name}
getOptionLabel={o => typeof o === 'string' ? o : o.name}
value={newFuerBenutzer}
onChange={(_, v) => setNewFuerBenutzer(v)}
renderInput={params => <TextField {...params} label="Für wen (optional)" InputLabelProps={{ ...params.InputLabelProps, shrink: true }} placeholder="Mitglied auswählen..." />}
onInputChange={(_, value, reason) => {
if (reason === 'input') {
// If user types a custom value that doesn't match any option, store as string
const match = orderUsers.find(u => u.name === value);
if (!match && value) {
setNewFuerBenutzer(value);
} else if (!value) {
setNewFuerBenutzer(null);
}
}
}}
isOptionEqualToValue={(option, value) => {
if (typeof option === 'string' || typeof value === 'string') return option === value;
return option.id === value.id;
}}
renderInput={params => <TextField {...params} label="Für wen (optional)" InputLabelProps={{ ...params.InputLabelProps, shrink: true }} placeholder="Mitglied auswählen oder Name eingeben..." />}
/>
)}
<TextField
@@ -1391,7 +1412,7 @@ function AlleAnfragenTab() {
<TableRow key={r.id} hover sx={{ cursor: 'pointer' }} onClick={() => setDetailId(r.id)}>
<TableCell>{formatOrderId(r)}</TableCell>
<TableCell>{r.bezeichnung || '-'}</TableCell>
<TableCell>{r.anfrager_name || r.anfrager_id}</TableCell>
<TableCell>{r.fuer_benutzer_name || r.anfrager_name || r.anfrager_id}</TableCell>
<TableCell><Chip label={AUSRUESTUNG_STATUS_LABELS[r.status]} color={AUSRUESTUNG_STATUS_COLORS[r.status]} size="small" /></TableCell>
<TableCell>{r.positionen_count ?? r.items_count ?? '-'}</TableCell>
<TableCell>