fix(budget): name the category parking and file parking bookings in it

The key was 'parkings', which is not a word and does not match the 'parking'
the reservation type uses everywhere else. The shared trip page prints the
stored category verbatim, so a share link would have shown "parkings" in every
language.

The category also had no relationship to the booking type of the same name:
RESERVATION_TYPE_TO_COST_CATEGORY still sent a parking booking's auto-expense
to Transport, so the new bucket sat empty next to the costs that belong in it
while a manually typed "parking" resolved into it. Both paths agree now.
This commit is contained in:
Maurice Böe
2026-08-21 14:14:23 +02:00
committed by Maurice
parent 999236f944
commit 942e1932c9
27 changed files with 53 additions and 35 deletions
@@ -1,9 +1,9 @@
import { describe, it, expect } from 'vitest'
import { COST_CATEGORIES } from '@trek/shared'
import { COST_CATEGORIES, typeToCostCategory } from '@trek/shared'
import { COST_CAT_META, COST_CATEGORY_LIST, catMeta } from './costsCategories'
describe('COST_CAT_META', () => {
it('has metadata for every fixed category, including fuel and parkings', () => {
it('has metadata for every fixed category, including fuel and parking', () => {
for (const key of COST_CATEGORIES) {
expect(COST_CAT_META[key]).toBeDefined()
expect(COST_CAT_META[key].key).toBe(key)
@@ -16,15 +16,21 @@ describe('COST_CAT_META', () => {
})
describe('catMeta', () => {
it('resolves fuel and parkings directly', () => {
it('resolves fuel and parking directly', () => {
expect(catMeta('fuel').key).toBe('fuel')
expect(catMeta('parkings').key).toBe('parkings')
expect(catMeta('parking').key).toBe('parking')
})
it('maps legacy/free-text aliases to the new categories', () => {
expect(catMeta('gas').key).toBe('fuel')
expect(catMeta('petrol').key).toBe('fuel')
expect(catMeta('parking').key).toBe('parkings')
expect(catMeta('Parking').key).toBe('parking')
expect(catMeta('car park').key).toBe('parking')
})
it('resolves a parking booking the same way whichever path created the expense', () => {
expect(catMeta(typeToCostCategory('parking')).key).toBe('parking')
expect(catMeta('parking').key).toBe(typeToCostCategory('parking'))
})
it('falls back to other for unknown categories', () => {
@@ -28,7 +28,7 @@ export const COST_CAT_META: Record<CostCategory, CostCategoryMeta> = {
health: { key: 'health', labelKey: 'costs.cat.health', Icon: HeartPulse, color: '#dc2626' },
tips: { key: 'tips', labelKey: 'costs.cat.tips', Icon: Coins, color: '#d97706' },
fuel: { key: 'fuel', labelKey: 'costs.cat.fuel', Icon: Fuel, color: '#f59e0b' },
parkings: { key: 'parkings', labelKey: 'costs.cat.parkings', Icon: ParkingCircle, color: '#3b82f6' },
parking: { key: 'parking', labelKey: 'costs.cat.parking', Icon: ParkingCircle, color: '#3b82f6' },
other: { key: 'other', labelKey: 'costs.cat.other', Icon: MoreHorizontal, color: '#6b7280' },
}
@@ -54,7 +54,7 @@ const LEGACY_CATEGORY_MAP: Record<string, CostCategory> = {
health: 'health', medical: 'health',
tip: 'tips', tips: 'tips',
gas: 'fuel', fuel: 'fuel', petrol: 'fuel',
parking: 'parkings', parkings: 'parkings',
parking: 'parking', parkings: 'parking', 'car park': 'parking',
other: 'other', misc: 'other',
}