76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import type { Modifier, EstimateItem } from '../types';
|
|
|
|
export interface ModifierModule {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
defaultLabel: string;
|
|
defaultValue: number;
|
|
defaultValueType: 'percent' | 'amount' | 'unit';
|
|
defaultUnitLabel?: string;
|
|
calculate: (modifier: Modifier, subScopeTotalWithMarkup: number, subScopeItems: EstimateItem[]) => number;
|
|
calculateDisplay?: (modifier: Modifier, subScopeTotalWithMarkup: number, subScopeItems: EstimateItem[]) => number;
|
|
}
|
|
|
|
const TaxModule: ModifierModule = {
|
|
id: 'tax',
|
|
name: 'Tax',
|
|
description: 'Calculates percentage tax on the sub-scope total.',
|
|
defaultLabel: 'Sales Tax',
|
|
defaultValue: 0,
|
|
defaultValueType: 'percent',
|
|
calculate: (m, base) => {
|
|
if (m.valueType === 'percent') return base * (m.value / 100);
|
|
return m.value;
|
|
}
|
|
};
|
|
|
|
const ManHoursModule: ModifierModule = {
|
|
id: 'man-hours',
|
|
name: 'Man-Hours',
|
|
description: 'Calculates labor hours by dividing the sub-scope subtotal by a production factor.',
|
|
defaultLabel: 'Estimated Hours',
|
|
defaultValue: 30,
|
|
defaultValueType: 'unit',
|
|
defaultUnitLabel: 'factor',
|
|
calculate: () => 0,
|
|
calculateDisplay: (m, base) => {
|
|
const factor = m.value || 1;
|
|
return base / factor;
|
|
}
|
|
};
|
|
|
|
const SimpleAdjustmentModule: ModifierModule = {
|
|
id: 'adjustment',
|
|
name: 'Fixed adjustment',
|
|
description: 'Adds or subtracts a fixed amount or percentage.',
|
|
defaultLabel: 'Adjustment',
|
|
defaultValue: 0,
|
|
defaultValueType: 'amount',
|
|
calculate: (m, base) => {
|
|
if (m.valueType === 'percent') return base * (m.value / 100);
|
|
return m.value;
|
|
}
|
|
};
|
|
|
|
export const MODIFIER_MODULES: ModifierModule[] = [
|
|
TaxModule,
|
|
ManHoursModule,
|
|
SimpleAdjustmentModule
|
|
];
|
|
|
|
export const ModifierRegistry = {
|
|
getModule: (id: string) => MODIFIER_MODULES.find(m => m.id === id) || SimpleAdjustmentModule,
|
|
|
|
calculate: (modifier: Modifier, baseTotal: number, items: EstimateItem[]) => {
|
|
const module = ModifierRegistry.getModule(modifier.moduleId);
|
|
return module.calculate(modifier, baseTotal, items);
|
|
},
|
|
|
|
calculateDisplay: (modifier: Modifier, baseTotal: number, items: EstimateItem[]) => {
|
|
const module = ModifierRegistry.getModule(modifier.moduleId);
|
|
if (module.calculateDisplay) return module.calculateDisplay(modifier, baseTotal, items);
|
|
return module.calculate(modifier, baseTotal, items);
|
|
}
|
|
};
|