Unterstützung: Rechenregel und Abzug im Abo-Stundenkonto

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-09-30 15:01:57 +00:00
1 parent c4fab31603
commit 7c6b0c906b
5 files changed
+148 -5

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
import { test, after } from 'node:test'
import assert from 'node:assert/strict'
import { startAppwriteMock } from './support/appwriteMock.js'
import { startFakeStripe } from './support/fakeStripe.js'
import { useTestEnv } from './support/testEnv.js'
const aw = await startAppwriteMock()
const st = await startFakeStripe()
after(() => Promise.all([aw.close(), st.close()]))
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
const { listPlanUsage, computeLedger } = await import('../server/services/hourLedger.js')
const andrej = { employeeId: 'andrej', name: 'Andrej Stevanovski', task: 'Farbkonzept' }
aw.seed('workorders', { $id: 'wo1', customerId: 'c1', woid: '100200', topic: 'Startseite' })
const sheet = (id, over) => ({
$id: id, workorderId: 'wo1', woid: '100200', wsid: id, countsToPlan: true, totalTime: 60,
startDate: '30.09.2026', employeeName: 'Justin Klein', details: 'Arbeit', ...over,
})
aw.seed('worksheets', sheet('ws1', { supporters: JSON.stringify([andrej]) }))
aw.seed('worksheets', sheet('ws2', { supporters: 'kaputt', startDate: '29.09.2026' }))
test('Stundenkonto zieht die Unterstützung mit ab', async () => {
const usage = await listPlanUsage('c1')
const ws1 = usage.find((u) => u.id === 'ws1')
assert.equal(ws1.minutes, 90)
assert.equal(ws1.supportMinutes, 30)
const ws2 = usage.find((u) => u.id === 'ws2')
assert.equal(ws2.minutes, 60)
assert.equal(ws2.supportMinutes, 0)
})
test('90-min-Eintrag bei 60 min Guthaben: 30 min Mehraufwand', () => {
const credits = [{ $id: 'k1', minutes: 60, grantedAt: '2026-09-01T00:00:00Z', expiresAt: '2027-09-01T00:00:00Z' }]
const ledger = computeLedger(credits, [{ id: 'ws1', date: '2026-09-30T12:00:00Z', minutes: 90, supportMinutes: 30 }], { now: new Date('2026-09-30T13:00:00Z') })
assert.equal(ledger.entries?.[0]?.overageMinutes ?? ledger.usage?.[0]?.overageMinutes, 30)
})
+49
View File
@@ -0,0 +1,49 @@
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { supportMinutes, parseSupporters, worksheetMinutes, firstName } from '../server/services/worksheetMinutes.js'
// Gleiche Faelle wie WOMS tests/unit/support.test.mjs (Rechenregel muss in beiden Systemen gleich sein)
const andrej = { employeeId: 'a', name: 'Andrej Stevanovski', task: 'Farbkonzept' }
const nico = { employeeId: 'n', name: 'Nico Rech', task: 'Texte' }
test('supportMinutes: Hälfte, aufgerundet auf 15', () => {
const cases = [[15, 15], [30, 15], [45, 30], [60, 30], [75, 45], [70, 45], [0, 0], [-5, 0], ['60', 30], [null, 0]]
for (const [total, expected] of cases) assert.equal(supportMinutes(total), expected, `${total}`)
})
test('parseSupporters ist fehlertolerant', () => {
assert.deepEqual(parseSupporters('kaputt'), [])
assert.deepEqual(parseSupporters('{}'), [])
assert.deepEqual(parseSupporters(null), [])
assert.deepEqual(parseSupporters(''), [])
const raw = '[{"employeeId":"a","name":"Andrej S","task":" Farbe "},{"employeeId":"a","name":"x","task":"y"},{"employeeId":"b","name":"Nico"},null,"x"]'
assert.deepEqual(parseSupporters(raw), [{ employeeId: 'a', name: 'Andrej S', task: 'Farbe' }])
assert.equal(parseSupporters([{ employeeId: 'a', name: 'A', task: 'x'.repeat(250) }])[0].task.length, 200)
})
test('parseSupporters meldet kaputte Werte einmal mit Kontext', () => {
const warned = []
const orig = console.warn
console.warn = (...args) => warned.push(args.join(' '))
try {
parseSupporters('kaputt', 'ws9')
parseSupporters('[]', 'ws8')
} finally {
console.warn = orig
}
assert.equal(warned.length, 1)
assert.match(warned[0], /\[unterstuetzung\] supporters unlesbar ws9/)
})
test('worksheetMinutes: Arbeitszeit plus je Person die Unterstützung', () => {
assert.equal(worksheetMinutes({ totalTime: 60, supporters: JSON.stringify([andrej, nico]) }), 120)
assert.equal(worksheetMinutes({ totalTime: 70, supporters: JSON.stringify([andrej]) }), 115)
assert.equal(worksheetMinutes({ totalTime: 45 }), 45)
assert.equal(worksheetMinutes({ totalTime: 0, supporters: JSON.stringify([andrej]) }), 0)
assert.equal(worksheetMinutes({ totalTime: 60, supporters: 'kaputt' }), 60)
})
test('firstName', () => {
assert.equal(firstName('Andrej Stevanovski'), 'Andrej')
assert.equal(firstName(''), '')
})