69 lines
3.0 KiB
TypeScript
69 lines
3.0 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
|
|
vi.mock('../../lib/prisma', () => ({
|
|
prisma: {
|
|
$transaction: vi.fn(),
|
|
contractSettings: { upsert: vi.fn() },
|
|
},
|
|
}))
|
|
|
|
import { buildReservationInvoiceLineItems, formatDocumentNumber } from './reservation.document.service'
|
|
|
|
describe('reservation document helpers', () => {
|
|
it('formats contract and invoice sequence numbers with stable padding', () => {
|
|
expect(formatDocumentNumber('CTR', 1)).toBe('CTR-000001')
|
|
expect(formatDocumentNumber('INV', 42)).toBe('INV-000042')
|
|
expect(formatDocumentNumber('INV', 1234567)).toBe('INV-1234567')
|
|
})
|
|
|
|
it('builds invoice line items from rental, insurance, additional drivers, pricing adjustments, discounts, and deposits', () => {
|
|
const result = buildReservationInvoiceLineItems({
|
|
dailyRate: 300,
|
|
totalDays: 4,
|
|
discountAmount: 120,
|
|
depositAmount: 1000,
|
|
pricingRulesApplied: [
|
|
{ name: 'Young driver fee', amount: 80, type: 'SURCHARGE' },
|
|
{ name: '', amount: -50, type: 'DISCOUNT' },
|
|
],
|
|
insurances: [
|
|
{ id: 'ins_1', policyName: 'Collision waiver', chargeType: 'PER_DAY', chargeValue: 20, totalCharge: 80 },
|
|
{ id: 'ins_2', policyName: 'Roadside assistance', chargeType: 'PER_RENTAL', chargeValue: 45, totalCharge: 45 },
|
|
],
|
|
additionalDrivers: [
|
|
{ id: 'driver_1', firstName: 'Sam', lastName: 'Driver', totalCharge: 70 },
|
|
{ id: 'driver_2', firstName: 'Free', lastName: 'Driver', totalCharge: 0 },
|
|
],
|
|
vehicle: { year: 2024, make: 'Toyota', model: 'Corolla' },
|
|
})
|
|
|
|
expect(result).toEqual([
|
|
{ description: '2024 Toyota Corolla', qty: 4, unitPrice: 300, total: 1200, category: 'RENTAL' },
|
|
{ description: 'Collision waiver', qty: 4, unitPrice: 20, total: 80, category: 'INSURANCE' },
|
|
{ description: 'Roadside assistance', qty: 1, unitPrice: 45, total: 45, category: 'INSURANCE' },
|
|
{ description: 'Additional driver - Sam Driver', qty: 1, unitPrice: 70, total: 70, category: 'ADDITIONAL_DRIVER' },
|
|
{ description: 'Young driver fee', qty: 1, unitPrice: 80, total: 80, category: 'PRICING_RULE' },
|
|
{ description: 'Pricing adjustment 2', qty: 1, unitPrice: -50, total: -50, category: 'PRICING_RULE' },
|
|
{ description: 'Discount', qty: 1, unitPrice: -120, total: -120, category: 'DISCOUNT' },
|
|
{ description: 'Security deposit', qty: 1, unitPrice: 1000, total: 1000, category: 'DEPOSIT' },
|
|
])
|
|
})
|
|
|
|
it('omits zero-value optional invoice lines', () => {
|
|
const result = buildReservationInvoiceLineItems({
|
|
dailyRate: 100,
|
|
totalDays: 2,
|
|
discountAmount: 0,
|
|
depositAmount: 0,
|
|
pricingRulesApplied: null,
|
|
insurances: [],
|
|
additionalDrivers: [{ id: 'driver_1', firstName: 'No', lastName: 'Charge', totalCharge: 0 }],
|
|
vehicle: { year: 2020, make: 'Dacia', model: 'Logan' },
|
|
})
|
|
|
|
expect(result).toEqual([
|
|
{ description: '2020 Dacia Logan', qty: 2, unitPrice: 100, total: 200, category: 'RENTAL' },
|
|
])
|
|
})
|
|
})
|