Finanzen: Vorschau, Steuer und Aufgaben genauer (Fixkosten ohne ESt, verspaetete Auszahlungen, Abos nicht ladbar)

M6: fixkosten30Cents zaehlt nur Fixkosten, die ESt-Vorauszahlung bleibt sicherer Posten.
M7: verspaetete Auszahlung (Ankunftstag vorbei, noch nicht bezahlt) kommt heute.
M8: ohne Stripe sind Kleinunternehmer-Zaehler und Anteil unbekannt (null), keine Warnung daraus.
M12: Verbindungsdokument ohne Sitzung zaehlt als keine Verbindung.
M13: Buchungen privat/fixkosten gehen nicht in die Fixkosten-Vorschlaege.
M14: Vorjahresumsatz ueber 25.000 EUR ist eine hohe Aufgabe.
M15: scheitert das Laden der Abos, meldet abos.fehler statt die ganze Uebersicht zu kippen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-01 15:42:06 +00:00
1 parent 83ee9d5a25
commit 039fdcaf27
6 files changed
+295 -20

No files matched your search

+46 -1
View File
@@ -9,7 +9,7 @@ const NOW = new Date('2026-10-01T10:00:00.000Z')
const HOUR = 3_600_000
const ago = (hours) => new Date(NOW.getTime() - hours * HOUR).toISOString()
const connection = (extra = {}) => ({ status: 'aktiv', validUntil: '2027-03-29T00:00:00.000Z', lastSyncAt: ago(1), lastSyncOk: true, lastError: '', ...extra })
const connection = (extra = {}) => ({ sessionId: 'sess-1', status: 'aktiv', validUntil: '2027-03-29T00:00:00.000Z', lastSyncAt: ago(1), lastSyncOk: true, lastError: '', ...extra })
const invoice = (extra = {}) => ({
id: 'in_1', number: 'WK-2026-0001', status: 'ueberfaellig', customerName: 'Muster GmbH', createdDate: '2026-08-01', dueDate: addDays(TODAY, -5),
remainingCents: 50000, paidCents: 0, paidDate: null, overdueDays: 5, source: 'projekt', hostedUrl: 'https://pay.example/in_1', ...extra,
@@ -51,6 +51,19 @@ test('bank-zugang: keine Verbindung -> „Bankkonto verbinden“ hoch', () => {
}
})
test('bank-zugang: Verbindungsdokument ohne Sitzung (erste Freigabe nie abgeschlossen) zählt als keine Verbindung (M12)', () => {
for (const abandoned of [{ sessionId: undefined }, { sessionId: null }, { sessionId: '' }, { sessionId: ' ' }]) {
// sonst kaeme "Bankabruf veraltet", weil es nie einen Abruf gab: es bleibt bei der einen Aufgabe
const list = todos({ connection: { authState: 'abc', authStartedAt: '2026-10-01T09:00:00.000Z', ...abandoned } })
assert.equal(list.length, 1, JSON.stringify(list))
assert.equal(list[0].titel, 'Bankkonto verbinden')
assert.equal(list[0].dringlichkeit, 'hoch')
assert.deepEqual(list[0].aktion, { typ: 'bank-verbinden' })
}
// mit Sitzung ist es ein Zugang (hier ruhig)
assert.deepEqual(todos({ connection: connection({ sessionId: 'sess-x' }) }), [])
})
test('bank-zugang: Zugang gültig bis 20.10. (19 Tage) -> mittel, bis 10.10. (9 Tage) -> hoch', () => {
const mid = only(todos({ connection: connection({ validUntil: '2026-10-20T00:00:00.000Z' }) }), 'bank-zugang')
assert.equal(mid.length, 1)
@@ -358,6 +371,38 @@ test('kleinunternehmer: über 100.000 Euro nennt die harte Grenze', () => {
)
})
test('kleinunternehmer: Vorjahresumsatz über 25.000 € -> hoch mit festem Titel und Text (M14)', () => {
const list = only(todos({ settings: { previousYearRevenueCents: 2_600_050 } }), 'kleinunternehmer')
assert.equal(list.length, 1)
assert.deepEqual(list[0], {
art: 'kleinunternehmer',
dringlichkeit: 'hoch',
titel: 'Vorjahresumsatz über 25.000 €',
text: `Im Vorjahr lagen die Einnahmen bei ${euroDe(2_600_050)}. Damit gilt die Kleinunternehmerregelung (§ 19 UStG) in diesem Jahr nicht. Bitte Rechnungen und Rechnungsfuß mit der Steuerberatung klären.`,
datum: TODAY,
aktion: { typ: 'einstellungen' },
})
assert.match(list[0].text, /26\.000,50/)
})
test('kleinunternehmer: Vorjahresumsatz genau 25.000 €, darunter, fehlend oder unlesbar -> keine Vorjahres-Aufgabe (M14)', () => {
for (const previousYearRevenueCents of [2_500_000, 100, 0, null, undefined, '3000000', 30_000.5]) {
assert.deepEqual(only(todos({ settings: { previousYearRevenueCents } }), 'kleinunternehmer'), [], String(previousYearRevenueCents))
}
assert.deepEqual(only(todos({ settings: null }), 'kleinunternehmer'), [])
assert.deepEqual(only(todos(), 'kleinunternehmer'), [])
// 25.000,01 € ist darüber
assert.equal(only(todos({ settings: { previousYearRevenueCents: 2_500_001 } }), 'kleinunternehmer').length, 1)
})
test('kleinunternehmer: Vorjahres-Aufgabe und Aufgabe zum laufenden Jahr stehen nebeneinander, hoch vor mittel (M14)', () => {
const list = only(todos({ tax: tax(0.72), settings: { previousYearRevenueCents: 3_000_000 } }), 'kleinunternehmer')
assert.deepEqual(list.map((t) => [t.dringlichkeit, t.titel]), [
['hoch', 'Vorjahresumsatz über 25.000 €'],
['mittel', 'Kleinunternehmer-Grenze rückt näher'],
])
})
test('kleinunternehmer: ohne tax oder mit unlesbarem Anteil keine Aufgabe', () => {
assert.deepEqual(only(todos({ tax: null }), 'kleinunternehmer'), [])
assert.deepEqual(only(todos({ tax: {} }), 'kleinunternehmer'), [])