daily-progress-report
Generate automated daily progress reports from site data. Track work completed, labor hours, equipment usage, and weather conditions.
What this skill does
# Daily Progress Report Generator
## Business Case
### Problem Statement
Site managers spend hours creating daily reports:
- Manual data collection
- Inconsistent formats
- Delayed submissions
- Missing information
### Solution
Automated daily progress report generation from structured site data inputs.
## Technical Implementation
```python
import pandas as pd
from datetime import datetime, date
from typing import Dict, Any, List
from dataclasses import dataclass
from enum import Enum
class WeatherCondition(Enum):
CLEAR = "clear"
CLOUDY = "cloudy"
RAIN = "rain"
SNOW = "snow"
WIND = "wind"
EXTREME = "extreme"
class WorkStatus(Enum):
COMPLETED = "completed"
IN_PROGRESS = "in_progress"
DELAYED = "delayed"
NOT_STARTED = "not_started"
@dataclass
class WorkActivity:
activity_id: str
description: str
location: str
planned_qty: float
actual_qty: float
unit: str
status: WorkStatus
crew_size: int
hours_worked: float
notes: str = ""
@dataclass
class LaborEntry:
trade: str
company: str
workers: int
hours: float
overtime_hours: float = 0
@dataclass
class EquipmentEntry:
equipment_type: str
equipment_id: str
hours_used: float
status: str # active, idle, maintenance
operator: str = ""
@dataclass
class DailyReport:
report_date: date
project_name: str
project_number: str
weather: WeatherCondition
temperature_high: float
temperature_low: float
work_activities: List[WorkActivity]
labor: List[LaborEntry]
equipment: List[EquipmentEntry]
delays: List[str]
safety_incidents: int
visitors: List[str]
deliveries: List[str]
prepared_by: str
class DailyProgressReporter:
"""Generate daily progress reports."""
def __init__(self, project_name: str, project_number: str):
self.project_name = project_name
self.project_number = project_number
def create_report(self,
report_date: date,
weather: WeatherCondition,
temp_high: float,
temp_low: float,
prepared_by: str) -> DailyReport:
"""Create new daily report."""
return DailyReport(
report_date=report_date,
project_name=self.project_name,
project_number=self.project_number,
weather=weather,
temperature_high=temp_high,
temperature_low=temp_low,
work_activities=[],
labor=[],
equipment=[],
delays=[],
safety_incidents=0,
visitors=[],
deliveries=[],
prepared_by=prepared_by
)
def add_work_activity(self,
report: DailyReport,
activity_id: str,
description: str,
location: str,
planned_qty: float,
actual_qty: float,
unit: str,
crew_size: int,
hours_worked: float,
notes: str = ""):
"""Add work activity to report."""
# Determine status
if actual_qty >= planned_qty:
status = WorkStatus.COMPLETED
elif actual_qty > 0:
status = WorkStatus.IN_PROGRESS
elif actual_qty == 0 and planned_qty > 0:
status = WorkStatus.DELAYED
else:
status = WorkStatus.NOT_STARTED
activity = WorkActivity(
activity_id=activity_id,
description=description,
location=location,
planned_qty=planned_qty,
actual_qty=actual_qty,
unit=unit,
status=status,
crew_size=crew_size,
hours_worked=hours_worked,
notes=notes
)
report.work_activities.append(activity)
def add_labor(self,
report: DailyReport,
trade: str,
company: str,
workers: int,
hours: float,
overtime_hours: float = 0):
"""Add labor entry."""
report.labor.append(LaborEntry(
trade=trade,
company=company,
workers=workers,
hours=hours,
overtime_hours=overtime_hours
))
def add_equipment(self,
report: DailyReport,
equipment_type: str,
equipment_id: str,
hours_used: float,
status: str,
operator: str = ""):
"""Add equipment entry."""
report.equipment.append(EquipmentEntry(
equipment_type=equipment_type,
equipment_id=equipment_id,
hours_used=hours_used,
status=status,
operator=operator
))
def calculate_summary(self, report: DailyReport) -> Dict[str, Any]:
"""Calculate report summary metrics."""
total_workers = sum(l.workers for l in report.labor)
total_manhours = sum(l.workers * l.hours for l in report.labor)
total_overtime = sum(l.workers * l.overtime_hours for l in report.labor)
equipment_hours = sum(e.hours_used for e in report.equipment)
completed = sum(1 for a in report.work_activities if a.status == WorkStatus.COMPLETED)
in_progress = sum(1 for a in report.work_activities if a.status == WorkStatus.IN_PROGRESS)
delayed = sum(1 for a in report.work_activities if a.status == WorkStatus.DELAYED)
return {
'total_workers': total_workers,
'total_manhours': round(total_manhours, 1),
'total_overtime': round(total_overtime, 1),
'equipment_hours': round(equipment_hours, 1),
'activities_completed': completed,
'activities_in_progress': in_progress,
'activities_delayed': delayed,
'safety_incidents': report.safety_incidents,
'deliveries_count': len(report.deliveries)
}
def export_to_excel(self, report: DailyReport, output_path: str) -> str:
"""Export report to Excel."""
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
# Header
header_df = pd.DataFrame([{
'Project': report.project_name,
'Project #': report.project_number,
'Date': report.report_date,
'Weather': report.weather.value,
'High Temp': report.temperature_high,
'Low Temp': report.temperature_low,
'Prepared By': report.prepared_by
}])
header_df.to_excel(writer, sheet_name='Summary', index=False)
# Work Activities
if report.work_activities:
activities_df = pd.DataFrame([
{
'Activity ID': a.activity_id,
'Description': a.description,
'Location': a.location,
'Planned': a.planned_qty,
'Actual': a.actual_qty,
'Unit': a.unit,
'Status': a.status.value,
'Crew': a.crew_size,
'Hours': a.hours_worked,
'Notes': a.notes
}
for a in report.work_activities
])
activities_df.to_excel(writer, sheet_name='Work Activities', index=False)
# Labor
if report.labor:
labor_df = pd.DataFrame([
{
'Trade': l.trade,
'Company': l.company,
'Workers': l.workers,
'Hours': l.hours,
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.