177 lines
7.1 KiB
JavaScript
177 lines
7.1 KiB
JavaScript
import { test } from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
import { istTag, naechte, plusTage, tageVon, formatTag } from '../server/services/unterkunft/datum.js'
|
||
import {
|
||
berechnePreis,
|
||
summiere,
|
||
pruefePosten,
|
||
formatEuro,
|
||
preiseVollstaendig,
|
||
} from '../server/services/unterkunft/preis.js'
|
||
|
||
const PREISE = {
|
||
staffeln: [
|
||
{ abNaechten: 1, preisProNachtCent: 6500 },
|
||
{ abNaechten: 7, preisProNachtCent: 5500 },
|
||
{ abNaechten: 28, preisProNachtCent: 4500 },
|
||
],
|
||
reinigungCent: 6000,
|
||
personenInklusive: 2,
|
||
aufpreisPersonNachtCent: 1000,
|
||
direktrabattProzent: 10,
|
||
steuerart: 'regel',
|
||
ustUebernachtung: 7,
|
||
ustReinigung: 7,
|
||
}
|
||
|
||
test('datum: istTag, naechte, plusTage, tageVon, formatTag', () => {
|
||
assert.equal(istTag('2026-10-24'), true)
|
||
assert.equal(istTag('2026-02-30'), false)
|
||
assert.equal(istTag('2026-1-24'), false)
|
||
assert.equal(istTag(null), false)
|
||
assert.equal(naechte('2026-10-24', '2026-10-26'), 2)
|
||
assert.equal(naechte('2026-12-30', '2027-01-02'), 3)
|
||
assert.equal(plusTage('2026-12-31', 1), '2027-01-01')
|
||
assert.equal(plusTage('2026-03-01', -1), '2026-02-28')
|
||
assert.deepEqual(tageVon('2026-12-30', '2027-01-02'), ['2026-12-30', '2026-12-31', '2027-01-01'])
|
||
assert.equal(formatTag('2026-11-12'), '12.11.2026')
|
||
})
|
||
|
||
test('berechnePreis: 7 Naechte, 2 Personen', () => {
|
||
const r = berechnePreis({ preise: PREISE, von: '2026-11-02', bis: '2026-11-09', personen: 2 })
|
||
assert.equal(r.naechte, 7)
|
||
assert.deepEqual(r.posten, [
|
||
{ text: 'Übernachtung, 7 Nächte', menge: 7, einzelCent: 5500, ustProzent: 7 },
|
||
{ text: 'Endreinigung', menge: 1, einzelCent: 6000, ustProzent: 7 },
|
||
{ text: 'Direktbuchungsrabatt 10 %', menge: 1, einzelCent: -3850, ustProzent: 7 },
|
||
])
|
||
assert.equal(r.summen.bruttoCent, 40650)
|
||
assert.deepEqual(r.summen.ust, [{ satz: 7, nettoCent: 37991, steuerCent: 2659 }])
|
||
})
|
||
|
||
test('berechnePreis: 30 Naechte, 3 Personen', () => {
|
||
const r = berechnePreis({ preise: PREISE, von: '2026-11-01', bis: '2026-12-01', personen: 3 })
|
||
assert.equal(r.posten[0].menge, 30)
|
||
assert.equal(r.posten[0].einzelCent, 4500)
|
||
assert.equal(r.posten[1].text, 'Zusatzperson (1), 30 Nächte')
|
||
assert.equal(r.posten[1].menge, 30)
|
||
assert.equal(r.posten[1].einzelCent, 1000)
|
||
assert.equal(r.posten[2].einzelCent, 6000)
|
||
assert.equal(r.posten[3].einzelCent, -16500)
|
||
assert.equal(r.summen.bruttoCent, 154500)
|
||
})
|
||
|
||
test('berechnePreis: 3 Naechte, 2 Personen', () => {
|
||
const r = berechnePreis({ preise: PREISE, von: '2026-11-02', bis: '2026-11-05', personen: 2 })
|
||
assert.equal(r.summen.bruttoCent, 23550)
|
||
})
|
||
|
||
test('berechnePreis: Mehrzahl Zusatzpersonen', () => {
|
||
const r = berechnePreis({ preise: PREISE, von: '2026-11-02', bis: '2026-11-05', personen: 4 })
|
||
assert.equal(r.posten[1].text, 'Zusatzpersonen (2), 3 Nächte')
|
||
assert.equal(r.posten[1].menge, 6)
|
||
})
|
||
|
||
test('berechnePreis: unterschiedliche Saetze', () => {
|
||
const r = berechnePreis({
|
||
preise: { ...PREISE, ustReinigung: 19 },
|
||
von: '2026-11-02',
|
||
bis: '2026-11-09',
|
||
personen: 2,
|
||
})
|
||
assert.equal(r.summen.ust.length, 2)
|
||
const summe = r.summen.ust.reduce((a, u) => a + u.nettoCent + u.steuerCent, 0)
|
||
assert.equal(summe, r.summen.bruttoCent)
|
||
})
|
||
|
||
test('berechnePreis/summiere: Kleinunternehmer', () => {
|
||
const r = berechnePreis({
|
||
preise: { ...PREISE, steuerart: 'kleinunternehmer' },
|
||
von: '2026-11-02',
|
||
bis: '2026-11-09',
|
||
personen: 2,
|
||
})
|
||
assert.deepEqual(r.summen.ust, [])
|
||
assert.equal(r.summen.nettoCent, r.summen.bruttoCent)
|
||
assert.ok(r.posten.every((p) => p.ustProzent === 0))
|
||
assert.ok(pruefePosten(r.posten, 'kleinunternehmer').posten)
|
||
})
|
||
|
||
test('berechnePreis: Rabatt 0 und Reinigung 0 ohne Posten', () => {
|
||
const r = berechnePreis({
|
||
preise: { ...PREISE, direktrabattProzent: 0, reinigungCent: 0 },
|
||
von: '2026-11-02',
|
||
bis: '2026-11-09',
|
||
personen: 2,
|
||
})
|
||
assert.equal(r.posten.length, 1)
|
||
})
|
||
|
||
test('summiere: direkt', () => {
|
||
const s = summiere([{ text: 'a', menge: 2, einzelCent: 500, ustProzent: 19 }], 'regel')
|
||
assert.equal(s.bruttoCent, 1000)
|
||
assert.deepEqual(s.ust, [{ satz: 19, nettoCent: 840, steuerCent: 160 }])
|
||
})
|
||
|
||
test('pruefePosten', () => {
|
||
const ok = { text: ' Miete ', menge: 2, einzelCent: 1000, ustProzent: 7 }
|
||
assert.ok(pruefePosten([], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, einzelCent: 0 }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, text: '' }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, text: 'x'.repeat(201) }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten(Array(31).fill(ok), 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([ok], 'kleinunternehmer').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, ustProzent: 5 }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, menge: 0 }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, menge: 1.5 }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten('nope', 'regel').fehler.posten)
|
||
const r = pruefePosten([ok], 'regel')
|
||
assert.equal(r.posten[0].text, 'Miete')
|
||
assert.equal(pruefePosten([{ ...ok, ustProzent: 0 }], 'kleinunternehmer').posten.length, 1)
|
||
})
|
||
|
||
test('formatEuro', () => {
|
||
assert.equal(formatEuro(123450), '1.234,50 €')
|
||
assert.equal(formatEuro(-3850), '−38,50 €')
|
||
assert.equal(formatEuro(5), '0,05 €')
|
||
})
|
||
|
||
test('preiseVollstaendig', () => {
|
||
assert.equal(preiseVollstaendig(PREISE), true)
|
||
assert.equal(preiseVollstaendig({ ...PREISE, staffeln: [] }), false)
|
||
assert.equal(preiseVollstaendig(null), false)
|
||
})
|
||
|
||
test('pruefePosten: negative Summe, Grenzen', () => {
|
||
const ok = { text: 'a', menge: 1, einzelCent: 1000, ustProzent: 7 }
|
||
assert.ok(pruefePosten([{ ...ok, einzelCent: -500 }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, menge: 20001 }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, menge: 20000 }], 'regel').posten)
|
||
assert.ok(pruefePosten([{ ...ok, einzelCent: 10_000_001 }], 'regel').fehler.posten)
|
||
assert.ok(pruefePosten([{ ...ok, menge: 2 ** 53 }], 'regel').fehler.posten)
|
||
})
|
||
|
||
test('preiseVollstaendig: strenge Faelle', () => {
|
||
const f = (o) => preiseVollstaendig({ ...PREISE, ...o })
|
||
const st = (ab) => ab.map((a) => ({ abNaechten: a, preisProNachtCent: 100 }))
|
||
assert.equal(f({ staffeln: st([1, 1]) }), false)
|
||
assert.equal(f({ staffeln: st([1, 0]) }), false)
|
||
assert.equal(f({ staffeln: st([1, 2.5]) }), false)
|
||
assert.equal(f({ ustUebernachtung: 5 }), false)
|
||
assert.equal(f({ ustReinigung: 5 }), false)
|
||
assert.equal(f({ reinigungCent: 0, ustReinigung: 5 }), true)
|
||
assert.equal(f({ steuerart: 'kleinunternehmer', ustUebernachtung: 5 }), true)
|
||
assert.equal(f({ reinigungCent: -1 }), false)
|
||
assert.equal(f({ aufpreisPersonNachtCent: 1.5 }), false)
|
||
assert.equal(f({ direktrabattProzent: 51 }), false)
|
||
assert.equal(f({ direktrabattProzent: -1 }), false)
|
||
assert.equal(f({ direktrabattProzent: 2.5 }), false)
|
||
assert.equal(f({ direktrabattProzent: 50 }), true)
|
||
})
|
||
|
||
test('berechnePreis: 20 Personen ueber 548 Naechte besteht pruefePosten', () => {
|
||
const r = berechnePreis({ preise: PREISE, von: '2026-11-01', bis: plusTage('2026-11-01', 548), personen: 20 })
|
||
assert.equal(r.posten[1].menge, 18 * 548)
|
||
assert.ok(pruefePosten(r.posten, 'regel').posten)
|
||
})
|