175 lines
5.0 KiB
TypeScript
175 lines
5.0 KiB
TypeScript
import catalogJson from '~/data/forms-catalog.json'
|
|
import fieldGroupsJson from '~/data/form-field-groups.json'
|
|
import type {
|
|
FormCatalogFile,
|
|
FormCatalogProductLine,
|
|
FormCatalogRow,
|
|
FormCatalogSelection
|
|
} from '~/types/form-catalog'
|
|
import type { FormFieldGroupDef, FormFieldGroupsFile } from '~/types/form-field-groups'
|
|
|
|
const catalog = catalogJson as FormCatalogFile
|
|
const fieldGroupsFile = fieldGroupsJson as FormFieldGroupsFile
|
|
|
|
const PRODUCT_LINE_LABELS: Record<FormCatalogProductLine, string> = {
|
|
life: 'Life',
|
|
health_local: 'Health · local',
|
|
health_international: 'Health · international',
|
|
auto_full_coverage: 'Auto · full coverage',
|
|
auto_dat_liability: 'Auto · DAT (liability)',
|
|
home: 'Home',
|
|
general_liability: 'General liability',
|
|
any: 'Any / not specified'
|
|
}
|
|
|
|
const ALL_PRODUCT_LINES: FormCatalogProductLine[] = [
|
|
'life',
|
|
'health_local',
|
|
'health_international',
|
|
'auto_full_coverage',
|
|
'auto_dat_liability',
|
|
'home',
|
|
'general_liability',
|
|
'any'
|
|
]
|
|
|
|
export function productLineLabel(line: FormCatalogProductLine | null | undefined): string {
|
|
if (line == null || line === 'any') return '—'
|
|
return PRODUCT_LINE_LABELS[line] ?? String(line)
|
|
}
|
|
|
|
function personMatches(row: FormCatalogRow, person: 'natural' | 'juridica'): boolean {
|
|
if (row.personKinds === 'both') return true
|
|
return row.personKinds === person
|
|
}
|
|
|
|
function productLineMatches(row: FormCatalogRow, sel: FormCatalogSelection): boolean {
|
|
const rowPl = row.productLine
|
|
const selPl = sel.productLine
|
|
|
|
if (selPl === null || selPl === 'any') {
|
|
return rowPl == null
|
|
}
|
|
if (rowPl == null) return true
|
|
return rowPl === selPl
|
|
}
|
|
|
|
function subRamoMatches(row: FormCatalogRow, subRamoKey: string | null): boolean {
|
|
if (!subRamoKey) return false
|
|
if (row.subRamoKey === 'any') return true
|
|
return row.subRamoKey === subRamoKey
|
|
}
|
|
|
|
export function filterRows(all: FormCatalogRow[], sel: FormCatalogSelection): FormCatalogRow[] {
|
|
if (!sel.insurerSlug || !sel.subRamoKey) return []
|
|
return all.filter((row) => {
|
|
if (!row.insurerSlugs.includes(sel.insurerSlug!)) return false
|
|
if (!subRamoMatches(row, sel.subRamoKey)) return false
|
|
if (!personMatches(row, sel.personKind)) return false
|
|
if (!productLineMatches(row, sel)) return false
|
|
return true
|
|
})
|
|
}
|
|
|
|
export function resolveFieldGroupsForRows(
|
|
matched: FormCatalogRow[],
|
|
groupMap: Map<string, FormFieldGroupDef>
|
|
): FormFieldGroupDef[] {
|
|
const ids = new Set<string>()
|
|
for (const r of matched) {
|
|
for (const id of r.fieldGroupIds ?? []) ids.add(id)
|
|
}
|
|
return [...ids]
|
|
.map((id) => groupMap.get(id))
|
|
.filter((g): g is FormFieldGroupDef => g != null)
|
|
}
|
|
|
|
export function buildFormMapIndex(rows: FormCatalogRow[]): Map<string, number[]> {
|
|
const m = new Map<string, number[]>()
|
|
for (const r of rows) {
|
|
for (const ins of r.insurerSlugs) {
|
|
const pl = r.productLine ?? ''
|
|
const key = `${ins}|${r.subRamoKey}|${pl}`
|
|
const list = m.get(key) ?? []
|
|
list.push(r.id)
|
|
m.set(key, list)
|
|
}
|
|
}
|
|
return m
|
|
}
|
|
|
|
function insurerSlugToLabel(slug: string): string {
|
|
return slug
|
|
.split('_')
|
|
.map((w) => w.slice(0, 1).toUpperCase() + w.slice(1))
|
|
.join(' ')
|
|
}
|
|
|
|
function buildInsurerItems(rows: FormCatalogRow[]) {
|
|
const set = new Set<string>()
|
|
for (const r of rows) {
|
|
for (const s of r.insurerSlugs) set.add(s)
|
|
}
|
|
return [...set]
|
|
.sort()
|
|
.map((value) => ({ label: insurerSlugToLabel(value), value }))
|
|
}
|
|
|
|
function buildSubRamoItems(rows: FormCatalogRow[], insurerSlug: string | null) {
|
|
if (!insurerSlug) return []
|
|
const map = new Map<string, string>()
|
|
for (const r of rows) {
|
|
if (!r.insurerSlugs.includes(insurerSlug)) continue
|
|
if (r.subRamoKey === 'any') continue
|
|
map.set(r.subRamoKey, r.subRamoLabel)
|
|
}
|
|
return [...map.entries()]
|
|
.sort((a, b) => a[1].localeCompare(b[1]))
|
|
.map(([value, label]) => ({ label, value }))
|
|
}
|
|
|
|
function productLineSelectOptions() {
|
|
return ALL_PRODUCT_LINES.map((value) => ({
|
|
label: PRODUCT_LINE_LABELS[value],
|
|
value
|
|
}))
|
|
}
|
|
|
|
export function useFormsCatalog() {
|
|
const rows = computed(() => catalog.rows)
|
|
const version = computed(() => catalog.version)
|
|
|
|
const groupById = computed(() => {
|
|
const m = new Map<string, FormFieldGroupDef>()
|
|
for (const g of fieldGroupsFile.groups) m.set(g.id, g)
|
|
return m
|
|
})
|
|
|
|
const insurerItems = computed(() => buildInsurerItems(catalog.rows))
|
|
|
|
function subRamoItems(insurerSlug: string | null) {
|
|
return buildSubRamoItems(catalog.rows, insurerSlug)
|
|
}
|
|
|
|
const productLineItems = productLineSelectOptions()
|
|
|
|
function fieldGroupsForMatched(matched: FormCatalogRow[]) {
|
|
return resolveFieldGroupsForRows(matched, groupById.value)
|
|
}
|
|
|
|
return {
|
|
catalog,
|
|
rows,
|
|
version,
|
|
fieldGroupsVersion: computed(() => fieldGroupsFile.version),
|
|
filterRows: (sel: FormCatalogSelection) => filterRows(catalog.rows, sel),
|
|
fieldGroupsForMatched,
|
|
buildFormMapIndex: () => buildFormMapIndex(catalog.rows),
|
|
insurerItems,
|
|
subRamoItems,
|
|
productLineItems,
|
|
productLineLabel,
|
|
insurerSlugToLabel
|
|
}
|
|
}
|