Skip to main content
ClaudeWave
Skill173 estrellas del repoactualizado 3mo ago

cwicr-overhead-markup

Apply overhead, profit, and markup to CWICR estimates. Calculate indirect costs, general conditions, and contractor margins.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction /tmp/cwicr-overhead-markup && cp -r /tmp/cwicr-overhead-markup/1_DDC_Toolkit/CWICR-Database/cwicr-overhead-markup ~/.claude/skills/cwicr-overhead-markup
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# CWICR Overhead & Markup Calculator

## Business Case

### Problem Statement
Direct costs need additional markups:
- General overhead (office, insurance)
- Project overhead (site costs)
- Profit margins
- Bonds and insurance

### Solution
Systematic markup application to CWICR direct costs with configurable rates for overhead, profit, bonds, and other indirect costs.

### Business Value
- **Complete pricing** - From cost to selling price
- **Configurable rates** - By project/client type
- **Transparency** - Clear markup breakdown
- **Consistency** - Standard markup application

## Technical Implementation

```python
import pandas as pd
from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from enum import Enum


class MarkupType(Enum):
    """Types of markup."""
    OVERHEAD = "overhead"
    PROFIT = "profit"
    BOND = "bond"
    INSURANCE = "insurance"
    CONTINGENCY = "contingency"
    TAX = "tax"
    ESCALATION = "escalation"
    CUSTOM = "custom"


class MarkupMethod(Enum):
    """Markup calculation methods."""
    ON_COST = "on_cost"              # Markup on direct cost
    ON_COST_PLUS = "on_cost_plus"    # Markup on cost + previous markups
    FIXED = "fixed"                   # Fixed amount


@dataclass
class MarkupItem:
    """Single markup item."""
    name: str
    markup_type: MarkupType
    rate: float
    method: MarkupMethod
    base_amount: float
    markup_amount: float


@dataclass
class MarkupSchedule:
    """Complete markup schedule."""
    name: str
    markups: List[MarkupItem]

    def get_total_rate(self) -> float:
        """Get combined markup rate."""
        return sum(m.rate for m in self.markups)


@dataclass
class PricingResult:
    """Complete pricing with all markups."""
    direct_cost: float
    labor_cost: float
    material_cost: float
    equipment_cost: float
    subcontractor_cost: float
    markups: List[MarkupItem]
    total_markup: float
    total_price: float
    markup_percentage: float


# Standard markup templates
MARKUP_TEMPLATES = {
    'residential': {
        'overhead': 0.10,
        'profit': 0.10,
        'contingency': 0.05
    },
    'commercial': {
        'overhead': 0.12,
        'profit': 0.08,
        'bond': 0.015,
        'insurance': 0.02,
        'contingency': 0.05
    },
    'industrial': {
        'overhead': 0.15,
        'profit': 0.08,
        'bond': 0.02,
        'insurance': 0.025,
        'contingency': 0.08
    },
    'government': {
        'overhead': 0.12,
        'profit': 0.06,
        'bond': 0.025,
        'contingency': 0.05
    },
    'subcontractor': {
        'overhead': 0.08,
        'profit': 0.10
    }
}


class CWICROverheadMarkup:
    """Apply overhead and markup to CWICR estimates."""

    def __init__(self, cwicr_data: pd.DataFrame = None):
        self.cost_data = cwicr_data
        if cwicr_data is not None:
            self._index_data()

    def _index_data(self):
        """Index cost data."""
        if 'work_item_code' in self.cost_data.columns:
            self._code_index = self.cost_data.set_index('work_item_code')
        else:
            self._code_index = None

    def get_template(self, template_name: str) -> Dict[str, float]:
        """Get markup template."""
        return MARKUP_TEMPLATES.get(template_name, MARKUP_TEMPLATES['commercial'])

    def create_markup_schedule(self,
                                name: str,
                                markups: Dict[str, float],
                                method: MarkupMethod = MarkupMethod.ON_COST) -> MarkupSchedule:
        """Create markup schedule from rates."""

        items = []
        for markup_name, rate in markups.items():
            markup_type = MarkupType.CUSTOM
            for mt in MarkupType:
                if mt.value in markup_name.lower():
                    markup_type = mt
                    break

            items.append(MarkupItem(
                name=markup_name,
                markup_type=markup_type,
                rate=rate,
                method=method,
                base_amount=0,
                markup_amount=0
            ))

        return MarkupSchedule(name=name, markups=items)

    def apply_markups(self,
                      direct_cost: float,
                      schedule: MarkupSchedule,
                      cost_breakdown: Dict[str, float] = None) -> PricingResult:
        """Apply markup schedule to direct cost."""

        if cost_breakdown is None:
            cost_breakdown = {
                'labor': direct_cost * 0.40,
                'material': direct_cost * 0.45,
                'equipment': direct_cost * 0.10,
                'subcontractor': direct_cost * 0.05
            }

        markup_items = []
        running_total = direct_cost

        for markup in schedule.markups:
            if markup.method == MarkupMethod.ON_COST:
                base = direct_cost
            elif markup.method == MarkupMethod.ON_COST_PLUS:
                base = running_total
            else:  # FIXED
                base = 1

            amount = base * markup.rate

            markup_items.append(MarkupItem(
                name=markup.name,
                markup_type=markup.markup_type,
                rate=markup.rate,
                method=markup.method,
                base_amount=round(base, 2),
                markup_amount=round(amount, 2)
            ))

            running_total += amount

        total_markup = running_total - direct_cost
        markup_pct = (total_markup / direct_cost * 100) if direct_cost > 0 else 0

        return PricingResult(
            direct_cost=round(direct_cost, 2),
            labor_cost=round(cost_breakdown.get('labor', 0), 2),
            material_cost=round(cost_breakdown.get('material', 0), 2),
            equipment_cost=round(cost_breakdown.get('equipment', 0), 2),
            subcontractor_cost=round(cost_breakdown.get('subcontractor', 0), 2),
            markups=markup_items,