MTO Enhancement Hooks¶
Last Updated: 2026-01-19
Overview¶
Three specialized hooks that enhance the Material Takeoff (MTO) and Estimation Master experience:
useLaborEnrichment- Enriches MTO items with calculated labor costsuseDataSourceToggle- Manages MTO vs uploaded estimation datauseKpiAggregation- Fetches KPI-based cost aggregation (Q-Flag system)
1. Labor Enrichment Hook¶
Location: frontend/src/hooks/mto/useLaborEnrichment.ts
Purpose¶
Fetches labor settings and service crews, provides enrichItem function for calculating labor costs on MTO items.
Usage¶
const { enrichItem, laborSettings, serviceCrews, isLoading } = useLaborEnrichment({
serviceId,
projectId,
subcontractors,
});
// Enrich items for display
const enrichedData = items.map(item => enrichItem(item));
Enriched Fields¶
| Field | Formula |
|---|---|
laborProdFactor |
Lookup by discipline |
hourlyCost |
Lookup by crewCode |
totalManhours |
quantity × manhourPerUnit × laborProdFactor |
laborUnitCost |
manhourPerUnit × laborProdFactor × hourlyCost |
totalLaborCost |
quantity × laborUnitCost |
totalEstimationUnitPrice |
Subcontractor rate OR (labor + material + equipment) |
totalCost |
totalEstimationUnitPrice × quantity |
2. Data Source Toggle Hook¶
Location: frontend/src/hooks/mto/useDataSourceToggle.ts
Purpose¶
Manages switching between two estimation data sources: - MTO Data - Derived from imported Material Takeoff - Upload Data - Pre-calculated estimation uploaded via Excel
Usage¶
const {
dataSource, // 'mto' | 'upload'
setDataSource,
hasMTO,
hasUpload,
isLoading,
} = useDataSourceToggle({ serviceId, projectId });
UI Component¶
import { DataSourceToggle } from '@/components/common/DataSourceToggle';
<DataSourceToggle
value={dataSource}
onChange={setDataSource}
hasMTO={hasMTO}
hasUpload={hasUpload}
/>
3. KPI Aggregation Hook¶
Location: frontend/src/hooks/mto/useKpiAggregation.ts
Purpose¶
Fetches aggregated costs by KPI code using the Q-Flag system for cost-per-unit calculations.
Usage¶
const { data, loading, error, refetch } = useKpiAggregation({
projectId,
serviceId,
dataSource: 'mto',
});
Response Structure¶
interface KPIAggregationResponse {
projectId: string;
aggregations: KPIAggregation[];
totalKpiGroups: number;
kpiGroupsWithQFlag: number;
}
interface KPIAggregation {
kpiCode: string;
totalLaborCost: number;
totalMaterialCost: number;
totalEquipmentCost: number;
totalSubcontractorCost: number;
totalCost: number;
totalHours: number;
qFlaggedQuantity?: number; // From Q-flagged item
costPerUnit?: number; // totalCost / qFlaggedQuantity
hoursPerUnit?: number;
hasQFlag: boolean;
}
Q-Flag System¶
Purpose¶
Designates which item in a KPI group provides the primary quantity for cost-per-unit calculations.
Formula¶
Rules¶
- One Q-Flag per KPI - Only one item per KPI code can have Q-flag
- Last One Wins - Enabling Q-flag auto-unflags existing item
- API Endpoint -
PATCH /mto/{id}/q-flag?projectId={pid}&enable={bool}
Backend Service¶
Location: backend/app/services/q_flag_aggregation_service.py
Methods:
- get_kpi_aggregations(project_id, service_id) - Aggregate costs by KPI
- set_q_flag(item_id, project_id, enable) - Toggle Q-flag
Data Flow¶
Labor Settings API ──┐
├──> useLaborEnrichment ──> Enriched MTO Items
Service Crews API ───┘
Data Sources API ──> useDataSourceToggle ──> DataSourceToggle Component
MTO/Upload API ──> useKpiAggregation ──> KPI Aggregation Table
Component Integration¶
| Component | Hooks Used |
|---|---|
| EstimationMasterTab | useLaborEnrichment, useDataSourceToggle |
| MTODisciplineTab | useLaborEnrichment |
| KPIAggregationTab | useKpiAggregation, useDataSourceToggle |