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

change-order-processor

Process and manage construction change orders. Track costs, approvals, and impact on schedule and budget.

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

SKILL.md

# Change Order Processor

## Business Case

### Problem Statement
Change orders cause project disruption:
- Delayed processing affects cash flow
- Unclear cost impact
- Lost documentation
- Schedule impacts not tracked

### Solution
Streamlined change order processing with cost analysis, approval workflow, and impact tracking.

### Business Value
- **Faster processing** - Reduce approval cycle time
- **Cost control** - Accurate change pricing
- **Documentation** - Complete audit trail
- **Impact visibility** - Schedule and budget effects

## Technical Implementation

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


class ChangeOrderStatus(Enum):
    """Change order status."""
    DRAFT = "draft"
    PENDING_REVIEW = "pending_review"
    PENDING_APPROVAL = "pending_approval"
    APPROVED = "approved"
    REJECTED = "rejected"
    VOID = "void"


class ChangeType(Enum):
    """Type of change."""
    OWNER_REQUESTED = "owner_requested"
    DESIGN_CHANGE = "design_change"
    FIELD_CONDITION = "field_condition"
    CODE_COMPLIANCE = "code_compliance"
    VALUE_ENGINEERING = "value_engineering"
    ERROR_OMISSION = "error_omission"


class ImpactType(Enum):
    """Impact categories."""
    COST_INCREASE = "cost_increase"
    COST_DECREASE = "cost_decrease"
    TIME_INCREASE = "time_increase"
    TIME_DECREASE = "time_decrease"
    NO_IMPACT = "no_impact"


@dataclass
class CostItem:
    """Change order cost item."""
    description: str
    quantity: float
    unit: str
    unit_cost: float
    total_cost: float
    category: str  # labor, material, equipment, subcontractor
    markup_percent: float = 0.0


@dataclass
class ApprovalRecord:
    """Approval workflow record."""
    approver_name: str
    approver_role: str
    action: str  # approved, rejected, returned
    action_date: datetime
    comments: str = ""


@dataclass
class ChangeOrder:
    """Change order record."""
    co_number: str
    title: str
    description: str
    change_type: ChangeType
    status: ChangeOrderStatus
    created_date: date
    created_by: str

    # Cost
    cost_items: List[CostItem] = field(default_factory=list)
    direct_cost: float = 0.0
    overhead_cost: float = 0.0
    profit_cost: float = 0.0
    total_cost: float = 0.0

    # Schedule
    schedule_impact_days: int = 0
    affected_activities: List[str] = field(default_factory=list)

    # Workflow
    approvals: List[ApprovalRecord] = field(default_factory=list)
    approved_date: Optional[date] = None
    approved_by: str = ""

    # References
    rfi_reference: str = ""
    spec_section: str = ""
    drawing_reference: str = ""
    location: str = ""

    def to_dict(self) -> Dict[str, Any]:
        return {
            'co_number': self.co_number,
            'title': self.title,
            'change_type': self.change_type.value,
            'status': self.status.value,
            'created_date': self.created_date.isoformat(),
            'direct_cost': self.direct_cost,
            'overhead_cost': self.overhead_cost,
            'profit_cost': self.profit_cost,
            'total_cost': self.total_cost,
            'schedule_impact': self.schedule_impact_days,
            'approved_date': self.approved_date.isoformat() if self.approved_date else None
        }


class ChangeOrderProcessor:
    """Process and manage change orders."""

    DEFAULT_OVERHEAD_RATE = 0.10
    DEFAULT_PROFIT_RATE = 0.10

    def __init__(self, project_name: str, original_contract: float,
                 overhead_rate: float = None, profit_rate: float = None):
        self.project_name = project_name
        self.original_contract = original_contract
        self.overhead_rate = overhead_rate or self.DEFAULT_OVERHEAD_RATE
        self.profit_rate = profit_rate or self.DEFAULT_PROFIT_RATE
        self.change_orders: Dict[str, ChangeOrder] = {}
        self._co_counter = 0

    def create_change_order(self,
                           title: str,
                           description: str,
                           change_type: ChangeType,
                           created_by: str,
                           rfi_reference: str = "",
                           location: str = "") -> ChangeOrder:
        """Create new change order."""
        self._co_counter += 1
        co_number = f"CO-{self._co_counter:04d}"

        co = ChangeOrder(
            co_number=co_number,
            title=title,
            description=description,
            change_type=change_type,
            status=ChangeOrderStatus.DRAFT,
            created_date=date.today(),
            created_by=created_by,
            rfi_reference=rfi_reference,
            location=location
        )

        self.change_orders[co_number] = co
        return co

    def add_cost_item(self, co_number: str,
                     description: str,
                     quantity: float,
                     unit: str,
                     unit_cost: float,
                     category: str,
                     markup_percent: float = 0.0):
        """Add cost item to change order."""
        if co_number not in self.change_orders:
            raise ValueError(f"Change order {co_number} not found")

        co = self.change_orders[co_number]

        total = quantity * unit_cost * (1 + markup_percent)
        item = CostItem(
            description=description,
            quantity=quantity,
            unit=unit,
            unit_cost=unit_cost,
            total_cost=total,
            category=category,
            markup_percent=markup_percent
        )

        co.cost_items.append(item)
        self._recalculate_totals(co)

    def _recalculate_totals(self, co: ChangeOrder):
        """Recalculate change order totals."""
        co.direct_cost = sum(item.total_cost for item in co.cost_items)
        co.overhead_cost = co.direct_cost * self.overhead_rate
        co