diff --git a/src/components/auftraege/AufwandAuswahl.jsx b/src/components/auftraege/AufwandAuswahl.jsx new file mode 100644 index 0000000..9a144bc --- /dev/null +++ b/src/components/auftraege/AufwandAuswahl.jsx @@ -0,0 +1,103 @@ +import { Field } from '../ui' +import { dateDe } from '../../lib/financeFormat' +import { stundenDe } from '../../lib/projektkontoView' +import { ausgewaehlteIds, blaetterSumme } from '../../lib/rechnungDialogView' + +/** + * Auswahl der offenen Arbeitsblätter für eine Rechnung nach Aufwand, dazu „Weiteres Ticket des Kunden hinzunehmen“. + * Rein darstellend. Props: blaetter (alle angebotenen Blätter), abgewaehlt (Kennungen), onToggle(id), satzInfo, + * ticketOptionen ([{ value, ticketId, woid, label }]), ticketsLaden, ticketsFehler, weitereTickets ([{ ticketId, woid, titel }]), + * weitereZustand ({ [ticketId]: { status, message } }), onAddTicket(option), onRemoveTicket(ticketId), disabled. + */ +export default function AufwandAuswahl({ + blaetter, + abgewaehlt, + onToggle, + satzInfo, + ticketOptionen, + ticketsLaden, + ticketsFehler, + weitereTickets, + weitereZustand, + onAddTicket, + onRemoveTicket, + disabled = false, +}) { + const liste = Array.isArray(blaetter) ? blaetter : [] + const summe = blaetterSumme(liste, ausgewaehlteIds(liste, abgewaehlt)) + const mehrereTickets = new Set(liste.map((b) => b.ticketId)).size > 1 + const optionen = Array.isArray(ticketOptionen) ? ticketOptionen : [] + const weitere = Array.isArray(weitereTickets) ? weitereTickets : [] + const zustand = weitereZustand || {} + + return ( +
+ ) +} diff --git a/src/components/auftraege/KontoZusammenfassung.jsx b/src/components/auftraege/KontoZusammenfassung.jsx new file mode 100644 index 0000000..782eec9 --- /dev/null +++ b/src/components/auftraege/KontoZusammenfassung.jsx @@ -0,0 +1,36 @@ +/** + * Zusammenfassung des Projektkontos im Rechnungsdialog: Vereinbart, Berechnet (darunter bezahlt), Noch offen, Zeit erfasst. + * Rein darstellend. Props: zeile (aus kontoZeile) und hinweis (aus stripeHinweis, leer = kein Hinweis). + */ +export default function KontoZusammenfassung({ zeile, hinweis }) { + return ( + <> ++ {hinweis} +
+ )} + > + ) +} diff --git a/src/components/auftraege/RechnungPositionen.jsx b/src/components/auftraege/RechnungPositionen.jsx new file mode 100644 index 0000000..44cf029 --- /dev/null +++ b/src/components/auftraege/RechnungPositionen.jsx @@ -0,0 +1,100 @@ +import { Button } from '../ui' +import { euro } from '../../lib/financeFormat' +import { INVOICE_LIMITS, lineTotalCents, invoiceTotalCents } from '../../lib/financeView' + +/** + * Positionszeilen des Rechnungsdialogs (Beschreibung, Menge, Einzelpreis, Summe, Entfernen) mit „+ Position“-Knopf. + * Rein darstellend, hält keinen Zustand. Props: legende, labelPrefix (z. B. „Position“ oder „Zusatzposition“), idPrefix, + * zeilen ([{ uid, description, quantity, price }]), minZeilen, onChange(uid, feld, wert), onAdd(), onRemove(uid), addLabel, + * zeigeSumme (Gesamtsumme und Hinweis zu § 19 UStG). + */ +export default function RechnungPositionen({ + legende, + labelPrefix, + idPrefix, + zeilen, + minZeilen = 0, + onChange, + onAdd, + onRemove, + addLabel, + zeigeSumme = false, +}) { + return ( + + ) +} diff --git a/src/components/auftraege/RechnungVorschau.jsx b/src/components/auftraege/RechnungVorschau.jsx new file mode 100644 index 0000000..2491fd9 --- /dev/null +++ b/src/components/auftraege/RechnungVorschau.jsx @@ -0,0 +1,69 @@ +import { euro } from '../../lib/financeFormat' +import { isNegText } from '../../lib/financeUi' +import { zeileTeilen, zeileBearbeitbar, maxVorn } from '../../lib/rechnungAnfrage' + +/** + * Vorschau der Rechnungszeilen, wie der Server sie baut. Zeigt immer alle Positionen der Antwort (eine Schlussrechnung hat + * bis zu 40). Rein darstellend. Props: positionen ([{ schluessel, beschreibung, menge, einzelpreisCents, betragCents }]), + * summeCents, bearbeitbar (Tages- und Wochenzeilen der Aufwandsrechnung lassen den Text vor dem letzten „ – “ ändern), + * zeilentexte ({ [schluessel]: Text }), onZeilentext(schluessel, text, original), abgeblendet (Vorschau wird gerade aktualisiert). + */ +export default function RechnungVorschau({ positionen, summeCents, bearbeitbar = false, zeilentexte = {}, onZeilentext, abgeblendet = false }) { + const liste = Array.isArray(positionen) ? positionen : [] + const mitEingabe = bearbeitbar && liste.some((p) => zeileBearbeitbar(p)) + return ( +| Position | +Betrag | +
|---|---|
|
+ {bearbeitbarEs ? (
+ <>
+ onZeilentext(p.schluessel, e.target.value, vorn)}
+ />
+ {hinten}
+ >
+ ) : (
+ <>
+ {p.beschreibung}
+ {p.menge > 1 && (
+
+ {p.menge} × {euro(p.einzelpreisCents)}
+
+ )}
+ >
+ )}
+ |
+ {betrag} | +
Gemäß § 19 UStG ohne Umsatzsteuer.
+ {mitEingabe &&Die Beschreibung der Zeilen lässt sich ändern, Stunden und Beträge stehen fest.
} +