cwicr-historical-cost
Track and analyze historical cost data using CWICR. Compare actual vs estimated costs, build project cost database, and improve future estimates.
git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction /tmp/cwicr-historical-cost && cp -r /tmp/cwicr-historical-cost/1_DDC_Toolkit/CWICR-Database/cwicr-historical-cost ~/.claude/skills/cwicr-historical-costSKILL.md
# CWICR Historical Cost Tracker
## Business Case
### Problem Statement
Improving estimates requires:
- Actual cost feedback
- Historical comparisons
- Trend analysis
- Lessons learned
### Solution
Track actual costs against CWICR estimates, build historical database, and use data to improve future estimating accuracy.
### Business Value
- **Accuracy improvement** - Learn from actuals
- **Benchmarking** - Project comparisons
- **Trend analysis** - Cost movement patterns
- **Organizational knowledge** - Cost database
## Technical Implementation
```python
import pandas as pd
import numpy as np
from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import datetime, date
from enum import Enum
import json
class ProjectStatus(Enum):
"""Project status."""
ESTIMATED = "estimated"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
CANCELLED = "cancelled"
@dataclass
class CostRecord:
"""Historical cost record."""
project_id: str
project_name: str
work_item_code: str
quantity: float
estimated_cost: float
actual_cost: float
variance: float
variance_percent: float
completion_date: date
notes: str = ""
@dataclass
class ProjectCostSummary:
"""Project cost summary."""
project_id: str
project_name: str
project_type: str
location: str
status: ProjectStatus
estimated_total: float
actual_total: float
variance: float
variance_percent: float
start_date: date
completion_date: Optional[date]
item_count: int
class CWICRHistoricalCost:
"""Track historical costs using CWICR data."""
def __init__(self, cwicr_data: pd.DataFrame = None):
self.cwicr = cwicr_data
self._projects: Dict[str, ProjectCostSummary] = {}
self._records: List[CostRecord] = []
if cwicr_data is not None:
self._index_cwicr()
def _index_cwicr(self):
"""Index CWICR data."""
if 'work_item_code' in self.cwicr.columns:
self._cwicr_index = self.cwicr.set_index('work_item_code')
else:
self._cwicr_index = None
def add_project(self,
project_id: str,
project_name: str,
project_type: str,
location: str,
estimated_total: float,
start_date: date) -> str:
"""Add new project to historical database."""
summary = ProjectCostSummary(
project_id=project_id,
project_name=project_name,
project_type=project_type,
location=location,
status=ProjectStatus.ESTIMATED,
estimated_total=estimated_total,
actual_total=0,
variance=0,
variance_percent=0,
start_date=start_date,
completion_date=None,
item_count=0
)
self._projects[project_id] = summary
return project_id
def record_actual_cost(self,
project_id: str,
work_item_code: str,
quantity: float,
actual_cost: float,
completion_date: date = None,
notes: str = "") -> CostRecord:
"""Record actual cost for work item."""
# Get estimated cost from CWICR
estimated_unit_cost = 0
if self._cwicr_index is not None and work_item_code in self._cwicr_index.index:
item = self._cwicr_index.loc[work_item_code]
labor = float(item.get('labor_cost', 0) or 0)
material = float(item.get('material_cost', 0) or 0)
equipment = float(item.get('equipment_cost', 0) or 0)
estimated_unit_cost = labor + material + equipment
estimated_cost = estimated_unit_cost * quantity
variance = actual_cost - estimated_cost
variance_pct = (variance / estimated_cost * 100) if estimated_cost > 0 else 0
record = CostRecord(
project_id=project_id,
project_name=self._projects.get(project_id, {}).project_name if project_id in self._projects else "",
work_item_code=work_item_code,
quantity=quantity,
estimated_cost=round(estimated_cost, 2),
actual_cost=round(actual_cost, 2),
variance=round(variance, 2),
variance_percent=round(variance_pct, 1),
completion_date=completion_date or date.today(),
notes=notes
)
self._records.append(record)
# Update project summary
if project_id in self._projects:
proj = self._projects[project_id]
proj.actual_total += actual_cost
proj.variance = proj.actual_total - proj.estimated_total
proj.variance_percent = (proj.variance / proj.estimated_total * 100) if proj.estimated_total > 0 else 0
proj.item_count += 1
proj.status = ProjectStatus.IN_PROGRESS
return record
def complete_project(self, project_id: str, completion_date: date = None):
"""Mark project as completed."""
if project_id in self._projects:
self._projects[project_id].status = ProjectStatus.COMPLETED
self._projects[project_id].completion_date = completion_date or date.today()
def get_work_item_history(self, work_item_code: str) -> Dict[str, Any]:
"""Get historical data for specific work item."""
records = [r for r in self._records if r.work_item_code == work_item_code]
if not records:
return {'work_item_code': work_item_code, 'records': 0}
variances = [r.variance_percent for r in records]
actual_costs = [r.actual_cost / r.quantity if r.quantity > 0 else 0 for r in records]
return {
'work_item_code': work_item_code,
'records': len(records),
'average_vGenerate automated daily progress reports from site data. Track work completed, labor hours, equipment usage, and weather conditions.
Analyze labor productivity from site data. Compare planned vs actual, identify trends, benchmark against industry standards.
Create interactive KPI dashboards for construction projects. Track schedule, cost, quality, and safety metrics in real-time.
Detect and analyze geometric clashes in BIM models. Identify MEP, structural, and architectural conflicts before construction.
Classify BIM elements using AI and standard classification systems. Map elements to UniFormat, MasterFormat, OmniClass, and CWICR codes.
Generate comprehensive BIM model validation reports. Check data quality, completeness, and compliance with standards.
Calculate CO2 emissions and carbon footprint from BIM model data. Analyze embodied carbon by material, element, and building system.
Extract quantities from IFC/Revit models for quantity takeoff. Uses DDC converters to get element counts, areas, volumes, lengths with grouping and reporting.