Stichtag Timeline fuer Ausgaben und Finanzuebersicht
CI / Build and Deploy (push) Successful in 2m58s
CI / Build and Deploy (push) Successful in 2m58s
This commit is contained in:
@@ -51,6 +51,13 @@ import {
|
||||
requiresManualApproval
|
||||
} from "@/lib/domain";
|
||||
|
||||
type CutoffSelectionOption = {
|
||||
value: string;
|
||||
cutoffId: string;
|
||||
cutoffPhase: "PRE" | "POST";
|
||||
label: string;
|
||||
};
|
||||
|
||||
type BudgetColumnProps = {
|
||||
group: DashboardWorkingGroup;
|
||||
workingGroups: DashboardWorkingGroup[];
|
||||
@@ -141,6 +148,42 @@ function createDraft(budget: DashboardBudget): BudgetDraft {
|
||||
};
|
||||
}
|
||||
|
||||
function createCutoffSelectionValue(cutoffId: string, cutoffPhase: "PRE" | "POST") {
|
||||
return `${cutoffId}:${cutoffPhase}`;
|
||||
}
|
||||
|
||||
function parseCutoffSelectionValue(value: string) {
|
||||
const [cutoffId, cutoffPhase] = value.split(":");
|
||||
|
||||
return {
|
||||
cutoffId: cutoffId ?? "",
|
||||
cutoffPhase: cutoffPhase === "POST" ? "POST" : "PRE"
|
||||
} as const;
|
||||
}
|
||||
|
||||
function getCutoffSelectionOptions(cutoffs: DashboardPeriodCutoff[]): CutoffSelectionOption[] {
|
||||
if (cutoffs.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const options: CutoffSelectionOption[] = cutoffs.map((cutoff) => ({
|
||||
value: createCutoffSelectionValue(cutoff.id, "PRE"),
|
||||
cutoffId: cutoff.id,
|
||||
cutoffPhase: "PRE" as const,
|
||||
label: `Pre ${cutoff.name}`
|
||||
}));
|
||||
const lastCutoff = cutoffs[cutoffs.length - 1];
|
||||
|
||||
options.push({
|
||||
value: createCutoffSelectionValue(lastCutoff.id, "POST"),
|
||||
cutoffId: lastCutoff.id,
|
||||
cutoffPhase: "POST" as const,
|
||||
label: `Post ${lastCutoff.name}`
|
||||
});
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function StatusChips({
|
||||
expense,
|
||||
canEditDonations,
|
||||
@@ -1078,8 +1121,12 @@ export function BudgetColumn({
|
||||
const editGroup =
|
||||
workingGroups.find((entry) => entry.id === draft.agId) ?? workingGroups[0] ?? group;
|
||||
const editBudgets = editGroup.budgets;
|
||||
const selectedCutoff =
|
||||
cutoffs.find((cutoff) => cutoff.id === draft.cutoffId) ?? cutoffs[0] ?? null;
|
||||
const cutoffOptions = getCutoffSelectionOptions(cutoffs);
|
||||
const selectedCutoffValue = createCutoffSelectionValue(draft.cutoffId, draft.cutoffPhase);
|
||||
const selectedCutoffOption =
|
||||
cutoffOptions.find((option) => option.value === selectedCutoffValue) ??
|
||||
cutoffOptions[0] ??
|
||||
null;
|
||||
|
||||
return (
|
||||
<Stack spacing={1}>
|
||||
@@ -1143,38 +1190,24 @@ export function BudgetColumn({
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
<Stack direction={{ xs: "column", sm: "row" }} gap={1}>
|
||||
<TextField
|
||||
select
|
||||
label="Stichtag"
|
||||
size="small"
|
||||
value={draft.cutoffId}
|
||||
onChange={(event) => updateExpenseDraft(expense, { cutoffId: event.target.value })}
|
||||
fullWidth
|
||||
disabled={cutoffs.length === 0}
|
||||
>
|
||||
{cutoffs.map((cutoff) => (
|
||||
<MenuItem key={cutoff.id} value={cutoff.id}>
|
||||
{cutoff.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
<TextField
|
||||
select
|
||||
label="Zuordnung"
|
||||
size="small"
|
||||
value={draft.cutoffPhase}
|
||||
onChange={(event) =>
|
||||
updateExpenseDraft(expense, {
|
||||
cutoffPhase: event.target.value as "PRE" | "POST"
|
||||
})
|
||||
}
|
||||
fullWidth
|
||||
>
|
||||
<MenuItem value="PRE">{`Pre ${selectedCutoff?.name ?? "Open Air"}`}</MenuItem>
|
||||
<MenuItem value="POST">{`Post ${selectedCutoff?.name ?? "Open Air"}`}</MenuItem>
|
||||
</TextField>
|
||||
</Stack>
|
||||
<TextField
|
||||
select
|
||||
label="Stichtag-Zuordnung"
|
||||
size="small"
|
||||
value={selectedCutoffOption?.value ?? ""}
|
||||
onChange={(event) => {
|
||||
const next = parseCutoffSelectionValue(event.target.value);
|
||||
updateExpenseDraft(expense, next);
|
||||
}}
|
||||
fullWidth
|
||||
disabled={cutoffOptions.length === 0}
|
||||
>
|
||||
{cutoffOptions.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
<Stack direction="row" gap={1} useFlexGap flexWrap="wrap">
|
||||
<Button
|
||||
type="button"
|
||||
@@ -1182,7 +1215,11 @@ export function BudgetColumn({
|
||||
variant="contained"
|
||||
disabled={busy || !draft.budgetId}
|
||||
onClick={async () => {
|
||||
await onUpdateExpense(expense.id, draft);
|
||||
await onUpdateExpense(expense.id, {
|
||||
...draft,
|
||||
cutoffId: selectedCutoffOption?.cutoffId ?? draft.cutoffId,
|
||||
cutoffPhase: selectedCutoffOption?.cutoffPhase ?? draft.cutoffPhase
|
||||
});
|
||||
setEditingExpenseId(null);
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user