131 lines
4.4 KiB
TypeScript
131 lines
4.4 KiB
TypeScript
import type {
|
|
ICountryFeeScheduleCatalog,
|
|
IFeeSchedule,
|
|
IFeeScheduleData,
|
|
IFeeScheduleFeeRow,
|
|
IFeeScheduleRuleSection,
|
|
} from './feeschedules.types.js';
|
|
import { FEE_SCHEDULE_CATALOGS, FEE_SCHEDULE_DATA } from './feeschedules.data.js';
|
|
|
|
export class FeeSchedules {
|
|
private catalogs: ICountryFeeScheduleCatalog[];
|
|
private data: IFeeScheduleData[];
|
|
|
|
constructor(
|
|
catalogs: ICountryFeeScheduleCatalog[] = FEE_SCHEDULE_CATALOGS,
|
|
data: IFeeScheduleData[] = FEE_SCHEDULE_DATA,
|
|
) {
|
|
this.catalogs = catalogs;
|
|
this.data = data;
|
|
}
|
|
|
|
public getCountries(): ICountryFeeScheduleCatalog[] {
|
|
return this.catalogs;
|
|
}
|
|
|
|
public getByCountry(countryCode: string): IFeeSchedule[] {
|
|
const catalog = this.getCatalog(countryCode);
|
|
return catalog?.schedules || [];
|
|
}
|
|
|
|
public getById(id: string): IFeeSchedule | undefined {
|
|
return this.getAll().find((schedule) => schedule.id === id);
|
|
}
|
|
|
|
public getDataByScheduleId(scheduleId: string): IFeeScheduleData | undefined {
|
|
return this.data.find((scheduleData) => scheduleData.scheduleId === scheduleId);
|
|
}
|
|
|
|
public getFeeRows(scheduleId: string): IFeeScheduleFeeRow[] {
|
|
return this.getDataByScheduleId(scheduleId)?.feeRows || [];
|
|
}
|
|
|
|
public getFeeRow(scheduleId: string, code: string): IFeeScheduleFeeRow | undefined {
|
|
const normalizedCode = normalizeSearchValue(code);
|
|
return this.getFeeRows(scheduleId).find((row) => {
|
|
return row.code ? normalizeSearchValue(row.code) === normalizedCode : false;
|
|
});
|
|
}
|
|
|
|
public getRuleSections(scheduleId: string): IFeeScheduleRuleSection[] {
|
|
return this.getDataByScheduleId(scheduleId)?.ruleSections || [];
|
|
}
|
|
|
|
public findByAbbreviation(abbreviation: string, countryCode?: string): IFeeSchedule | undefined {
|
|
const normalizedAbbreviation = normalizeSearchValue(abbreviation);
|
|
return this.getSchedules(countryCode).find(
|
|
(schedule) => normalizeSearchValue(schedule.abbreviation) === normalizedAbbreviation,
|
|
);
|
|
}
|
|
|
|
public search(query: string, countryCode?: string): IFeeSchedule[] {
|
|
const normalizedQuery = normalizeSearchValue(query);
|
|
if (!normalizedQuery) {
|
|
return [];
|
|
}
|
|
|
|
return this.getSchedules(countryCode).filter((schedule) => {
|
|
return [schedule.id, schedule.area, schedule.abbreviation, schedule.description]
|
|
.map((value) => normalizeSearchValue(value))
|
|
.some((value) => value.includes(normalizedQuery));
|
|
});
|
|
}
|
|
|
|
public searchFeeRows(query: string, scheduleId?: string): IFeeScheduleFeeRow[] {
|
|
const normalizedQuery = normalizeSearchValue(query);
|
|
if (!normalizedQuery) {
|
|
return [];
|
|
}
|
|
|
|
return this.getScheduleData(scheduleId)
|
|
.flatMap((scheduleData) => scheduleData.feeRows)
|
|
.filter((row) => {
|
|
return [row.id, row.code, row.description, ...row.cells]
|
|
.filter((value): value is string => Boolean(value))
|
|
.map((value) => normalizeSearchValue(value))
|
|
.some((value) => value.includes(normalizedQuery));
|
|
});
|
|
}
|
|
|
|
public searchRuleSections(query: string, scheduleId?: string): IFeeScheduleRuleSection[] {
|
|
const normalizedQuery = normalizeSearchValue(query);
|
|
if (!normalizedQuery) {
|
|
return [];
|
|
}
|
|
|
|
return this.getScheduleData(scheduleId)
|
|
.flatMap((scheduleData) => scheduleData.ruleSections)
|
|
.filter((section) => {
|
|
return [section.reference, section.title, section.text]
|
|
.filter((value): value is string => Boolean(value))
|
|
.map((value) => normalizeSearchValue(value))
|
|
.some((value) => value.includes(normalizedQuery));
|
|
});
|
|
}
|
|
|
|
private getAll(): IFeeSchedule[] {
|
|
return this.catalogs.flatMap((catalog) => catalog.schedules);
|
|
}
|
|
|
|
private getSchedules(countryCode?: string): IFeeSchedule[] {
|
|
return countryCode ? this.getByCountry(countryCode) : this.getAll();
|
|
}
|
|
|
|
private getScheduleData(scheduleId?: string): IFeeScheduleData[] {
|
|
return scheduleId
|
|
? this.data.filter((scheduleData) => scheduleData.scheduleId === scheduleId)
|
|
: this.data;
|
|
}
|
|
|
|
private getCatalog(countryCode: string): ICountryFeeScheduleCatalog | undefined {
|
|
const normalizedCountryCode = countryCode.toUpperCase();
|
|
return this.catalogs.find((catalog) => catalog.countryCode === normalizedCountryCode);
|
|
}
|
|
}
|
|
|
|
export const feeSchedules = new FeeSchedules();
|
|
|
|
const normalizeSearchValue = (value: string): string => {
|
|
return value.trim().toLocaleLowerCase().replace(/\s+/g, ' ');
|
|
};
|