Rechnungen: mapInvoice liefert Projekt, Art und Auftrag
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4f8e956574
commit
c116c3cb4f
3 files changed
+68
No files matched your search
@@ -3,6 +3,7 @@ import { config } from '../../config.js'
|
||||
import { getStripe, getOrCreateStripeCustomer, stripeCustomerFields, subscriptionIdOfInvoice } from '../stripeBilling.js'
|
||||
import { getDocument } from '../appwriteAdmin.js'
|
||||
import { addDays, berlinDate, daysBetween } from './dates.js'
|
||||
import { RECHNUNGS_ARTEN } from '../auftraege/konstanten.js'
|
||||
import { getSettings } from './settings.js'
|
||||
|
||||
/**
|
||||
@@ -87,6 +88,11 @@ export function mapInvoice(raw, { today }) {
|
||||
pdfUrl: raw.invoice_pdf || null,
|
||||
outOfBand: Boolean(metadata.bankTransactionId),
|
||||
bankTransactionId: metadata.bankTransactionId || '',
|
||||
projektId: metadata.projektId || '',
|
||||
projektName: metadata.projektName || '',
|
||||
art: RECHNUNGS_ARTEN.includes(metadata.art) ? metadata.art : subscriptionIdOfInvoice(raw) ? 'abo' : 'frei',
|
||||
auftragId: metadata.auftragId || '',
|
||||
auftragNummer: metadata.auftragNummer || '',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { test, after, beforeEach, mock } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { startAppwriteMock } from './support/appwriteMock.js'
|
||||
import { startFakeStripe } from './support/fakeStripe.js'
|
||||
import { schemaKeys } from './support/schema.js'
|
||||
import { useTestEnv } from './support/testEnv.js'
|
||||
import { AUFTRAEGE_DATETIMES } from '../server/services/auftraege/schema.js'
|
||||
|
||||
const aw = await startAppwriteMock({
|
||||
schema: { auftraege: schemaKeys('auftraege'), projektRechnungen: schemaKeys('projektRechnungen') },
|
||||
datetimes: AUFTRAEGE_DATETIMES,
|
||||
defaultLimit: 25,
|
||||
})
|
||||
const st = await startFakeStripe()
|
||||
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
|
||||
const { config } = await import('../server/config.js')
|
||||
const { seedRechnungsDaten, legeAuftragAn, leereRechnungsDaten } = await import('./auftraegeRechnungenHilfe.js')
|
||||
const {
|
||||
mapInvoice, createProjectInvoice, rechnungsVorschau, sendInvoiceNow, voidInvoice, deleteDraft, invalidateFinanceCache, resetInvoiceCreateGuardForTests,
|
||||
} = await import('../server/services/finance/stripeFinance.js')
|
||||
const { getProjektRechnung } = await import('../server/services/auftraege/projektRechnungenStore.js')
|
||||
const { getAuftrag } = await import('../server/services/auftraege/auftragStore.js')
|
||||
const { sperreAuftrag } = await import('../server/services/auftraege/konstanten.js')
|
||||
const { withLocks } = await import('../server/services/keyedLock.js')
|
||||
const { berlinDate, formatDe } = await import('../server/services/finance/dates.js')
|
||||
|
||||
after(() => Promise.all([aw.close(), st.close()]))
|
||||
seedRechnungsDaten(aw)
|
||||
config.auftraege.mode = 'on'
|
||||
beforeEach(async () => {
|
||||
mock.restoreAll()
|
||||
await leereRechnungsDaten(aw, st)
|
||||
invalidateFinanceCache()
|
||||
resetInvoiceCreateGuardForTests()
|
||||
})
|
||||
|
||||
const NBSP = String.fromCharCode(160) // geschütztes Leerzeichen U+00A0, wie euroDe es vor € setzt
|
||||
const POSTEN = [{ description: 'Domain', quantity: 1, unitAmountCents: 1200 }]
|
||||
const callsTo = (method, path) => st.calls.filter((c) => c.method === method && (path instanceof RegExp ? path.test(c.path) : c.path === path))
|
||||
const writes = () => st.calls.filter((c) => c.method !== 'GET')
|
||||
const wirft = (promise, status, message) =>
|
||||
assert.rejects(promise, (err) => {
|
||||
assert.equal(err.status, status, `Status ${err.status}: ${err.message}`)
|
||||
assert.equal(err.message, message)
|
||||
return true
|
||||
})
|
||||
|
||||
test('mapInvoice: Projektfelder aus den Metadaten, art mit Rückfall abo oder frei', () => {
|
||||
const roh = (over = {}) => ({ id: 'in_1', object: 'invoice', status: 'open', customer: 'cus_1', created: 1_790_000_000, total: 1000, metadata: {}, lines: { object: 'list', data: [] }, ...over })
|
||||
const felder = (r) => [r.projektId, r.projektName, r.art, r.auftragId, r.auftragNummer]
|
||||
const heute = { today: '2026-10-06' }
|
||||
assert.deepEqual(felder(mapInvoice(roh(), heute)), ['', '', 'frei', '', ''])
|
||||
assert.deepEqual(felder(mapInvoice(roh({ subscription: 'sub_1' }), heute)), ['', '', 'abo', '', ''])
|
||||
const metadata = { projektId: 'p1', projektName: 'Website Wolf', art: 'schluss', auftragId: 'a1', auftragNummer: 'AB-2026-0002' }
|
||||
assert.deepEqual(felder(mapInvoice(roh({ metadata }), heute)), ['p1', 'Website Wolf', 'schluss', 'a1', 'AB-2026-0002'])
|
||||
for (const art of ['quatsch', 'abo', '']) assert.equal(mapInvoice(roh({ metadata: { art } }), heute).art, 'frei', `art "${art}"`)
|
||||
})
|
||||
@@ -114,6 +114,11 @@ test('mapInvoice: Felder, Betraege in Cent und Berliner Kalendertage', () => {
|
||||
pdfUrl: 'https://invoice.stripe.test/i/in_1/pdf',
|
||||
outOfBand: false,
|
||||
bankTransactionId: '',
|
||||
projektId: '',
|
||||
projektName: '',
|
||||
art: 'frei',
|
||||
auftragId: '',
|
||||
auftragNummer: '',
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user