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