fix(frontend): order status button colors, delivery gate logic, partial delivery chips, and scheduled message form tweaks
This commit is contained in:
@@ -108,7 +108,11 @@ function MeineAnfragenTab() {
|
||||
<TableCell>{formatOrderId(r)}</TableCell>
|
||||
<TableCell>{r.bezeichnung || '-'}</TableCell>
|
||||
<TableCell><Chip label={AUSRUESTUNG_STATUS_LABELS[r.status]} color={AUSRUESTUNG_STATUS_COLORS[r.status]} size="small" /></TableCell>
|
||||
<TableCell>{r.im_haus ? <Chip label="Im Haus" color="success" size="small" /> : null}</TableCell>
|
||||
<TableCell>
|
||||
{r.im_haus && r.geliefert_count != null && r.positionen_count != null && r.geliefert_count < r.positionen_count
|
||||
? <Chip label="Teilweise im Haus" color="warning" size="small" />
|
||||
: r.im_haus ? <Chip label="Im Haus" color="success" size="small" /> : null}
|
||||
</TableCell>
|
||||
<TableCell>{r.positionen_count ?? r.items_count ?? '-'}</TableCell>
|
||||
<TableCell>
|
||||
{r.positionen_count != null && r.positionen_count > 0
|
||||
@@ -219,7 +223,11 @@ function AlleAnfragenTab() {
|
||||
<TableCell>{r.bezeichnung || '-'}</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.im_haus ? <Chip label="Im Haus" color="success" size="small" /> : null}</TableCell>
|
||||
<TableCell>
|
||||
{r.im_haus && r.geliefert_count != null && r.positionen_count != null && r.geliefert_count < r.positionen_count
|
||||
? <Chip label="Teilweise im Haus" color="warning" size="small" />
|
||||
: r.im_haus ? <Chip label="Im Haus" color="success" size="small" /> : null}
|
||||
</TableCell>
|
||||
<TableCell>{r.positionen_count ?? r.items_count ?? '-'}</TableCell>
|
||||
<TableCell>
|
||||
{r.positionen_count != null && r.positionen_count > 0
|
||||
|
||||
@@ -218,9 +218,13 @@ export default function AusruestungsanfrageDetail() {
|
||||
</Typography>
|
||||
{anfrage && (
|
||||
<>
|
||||
{detail?.im_haus && (
|
||||
<Chip label="Im Haus" color="success" />
|
||||
)}
|
||||
{detail?.im_haus && (() => {
|
||||
const total = detail.positionen.length;
|
||||
const delivered = detail.positionen.filter(p => p.geliefert).length;
|
||||
return total > 0 && delivered < total
|
||||
? <Chip label="Teilweise im Haus" color="warning" />
|
||||
: <Chip label="Im Haus" color="success" />;
|
||||
})()}
|
||||
<Chip
|
||||
label={AUSRUESTUNG_STATUS_LABELS[anfrage.status]}
|
||||
color={AUSRUESTUNG_STATUS_COLORS[anfrage.status]}
|
||||
|
||||
@@ -546,7 +546,8 @@ export default function BestellungDetail() {
|
||||
const canExport = hasPermission('bestellungen:export');
|
||||
const validTransitions = bestellung ? STATUS_TRANSITIONS[bestellung.status] : [];
|
||||
const allCostsEntered = positionen.length === 0 || positionen.every(p => p.einzelpreis != null && Number(p.einzelpreis) > 0);
|
||||
const allItemsReceived = positionen.length === 0 || positionen.every(p => Number(p.erhalten_menge) >= Number(p.menge));
|
||||
const allItemsReceived = positionen.length > 0 && positionen.every(p => Number(p.erhalten_menge) >= Number(p.menge));
|
||||
const anyItemReceived = positionen.some(p => Number(p.erhalten_menge) > 0);
|
||||
|
||||
// All statuses except current, for force override
|
||||
const ALL_STATUSES: BestellungStatus[] = ['entwurf', 'wartet_auf_genehmigung', 'bereit_zur_bestellung', 'bestellt', 'teillieferung', 'lieferung_pruefen', 'abgeschlossen'];
|
||||
@@ -1205,15 +1206,19 @@ export default function BestellungDetail() {
|
||||
})
|
||||
.map((s) => {
|
||||
const isReject = bestellung.status === 'wartet_auf_genehmigung' && s === 'entwurf';
|
||||
const isApprove = bestellung.status === 'wartet_auf_genehmigung' && s === 'bereit_zur_bestellung';
|
||||
const label = isReject ? 'Ablehnen' : BESTELLUNG_STATUS_LABELS[s];
|
||||
const color = isReject ? 'error' : 'primary';
|
||||
const color = isReject ? 'error' : isApprove ? 'success' : 'info';
|
||||
const isAbgeschlossen = s === 'abgeschlossen';
|
||||
return (
|
||||
<Button
|
||||
key={s}
|
||||
variant="contained"
|
||||
color={color as 'error' | 'primary'}
|
||||
disabled={isAbgeschlossen && (!allCostsEntered || !allItemsReceived)}
|
||||
color={color as 'error' | 'info' | 'success'}
|
||||
disabled={
|
||||
(isAbgeschlossen && (!allCostsEntered || !allItemsReceived)) ||
|
||||
(s === 'teillieferung' && !anyItemReceived)
|
||||
}
|
||||
onClick={() => { setStatusForce(false); setStatusConfirmTarget(s); }}
|
||||
>
|
||||
{label}
|
||||
|
||||
@@ -29,7 +29,7 @@ const MESSAGE_TYPE_LABELS: Record<MessageType, string> = {
|
||||
|
||||
const TRIGGER_LABELS: Record<string, string> = {
|
||||
day_of_week: 'Wochentag + Uhrzeit',
|
||||
days_before_month_start: 'N Tage vor Monatsbeginn',
|
||||
days_before_month_start: 'Tage vor Monatsbeginn',
|
||||
event: 'Ereignis',
|
||||
};
|
||||
|
||||
|
||||
@@ -224,11 +224,12 @@ export default function GeplanteMachrichtenForm({ ruleId }: GeplanteMachrichtenF
|
||||
<FormControl>
|
||||
<FormLabel>Auslöser</FormLabel>
|
||||
<RadioGroup
|
||||
row
|
||||
value={triggerMode}
|
||||
onChange={(e) => setTriggerMode(e.target.value as TriggerMode)}
|
||||
>
|
||||
<FormControlLabel value="day_of_week" control={<Radio />} label="Wochentag + Uhrzeit" />
|
||||
<FormControlLabel value="days_before_month_start" control={<Radio />} label="N Tage vor Monatsbeginn" />
|
||||
<FormControlLabel value="days_before_month_start" control={<Radio />} label="Tage vor Monatsbeginn" />
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
|
||||
@@ -263,6 +264,7 @@ export default function GeplanteMachrichtenForm({ ruleId }: GeplanteMachrichtenF
|
||||
value={daysBeforeMonthStart}
|
||||
onChange={(e) => setDaysBeforeMonthStart(Number(e.target.value))}
|
||||
size="small"
|
||||
sx={{ minWidth: 220 }}
|
||||
inputProps={{ min: 0, max: 28 }}
|
||||
/>
|
||||
</Box>
|
||||
@@ -276,6 +278,7 @@ export default function GeplanteMachrichtenForm({ ruleId }: GeplanteMachrichtenF
|
||||
<FormControl>
|
||||
<FormLabel>Zeitfenster</FormLabel>
|
||||
<RadioGroup
|
||||
row
|
||||
value={windowMode}
|
||||
onChange={(e) => setWindowMode(e.target.value as WindowMode)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user