Email Generation for Construction
Overview
Generate professional construction emails with proper formatting, context, and attachments handling. Templates for common construction communication workflows.
Construction Use Cases
1. RFI Response Email
Generate professional RFI response emails.
from dataclasses import dataclass
from datetime import datetime
from typing import Optional, List
@dataclass
class RFIResponse:
rfi_number: str
project_name: str
subject: str
question: str
response: str
responder_name: str
responder_title: str
attachments: List[str] = None
cc_list: List[str] = None
def generate_rfi_response_email(rfi: RFIResponse) -> dict:
"""Generate RFI response email."""
subject = f"RE: RFI #{rfi.rfi_number} - {rfi.subject}"
body = f"""Dear Project Team,
Please find below our response to RFI #{rfi.rfi_number}.
**Project:** {rfi.project_name}
**RFI Number:** {rfi.rfi_number}
**Subject:** {rfi.subject}
**Date:** {datetime.now().strftime('%B %d, %Y')}
---
**QUESTION:**
{rfi.question}
---
**RESPONSE:**
{rfi.response}
---
Please proceed accordingly. If you have any questions regarding this response, please contact us.
{"**Attachments:**" + chr(10) + chr(10).join(f"- {a}" for a in rfi.attachments) if rfi.attachments else ""}
Best regards,
{rfi.responder_name}
{rfi.responder_title}
"""
return {
'subject': subject,
'body': body,
'cc': rfi.cc_list or [],
'attachments': rfi.attachments or []
}
2. Submittal Transmittal Email
Generate submittal transmittal emails.
@dataclass
class SubmittalTransmittal:
submittal_number: str
project_name: str
spec_section: str
description: str
items: List[dict]
action_required: str
due_date: str
sender_name: str
sender_company: str
def generate_submittal_email(submittal: SubmittalTransmittal) -> dict:
"""Generate submittal transmittal email."""
subject = f"Submittal {submittal.submittal_number} - {submittal.spec_section} - {submittal.description}"
items_list = "\n".join(
f" {i+1}. {item['description']} ({item.get('copies', 1)} copies)"
for i, item in enumerate(submittal.items)
)
body = f"""Dear Design Team,
Please find attached Submittal {submittal.submittal_number} for your review.
**Project:** {submittal.project_name}
**Submittal No:** {submittal.submittal_number}
**Spec Section:** {submittal.spec_section}
**Description:** {submittal.description}
**Items Transmitted:**
{items_list}
**Action Required:** {submittal.action_required}
**Response Requested By:** {submittal.due_date}
Please review and return with your comments at your earliest convenience.
If you have any questions, please don't hesitate to contact us.
Best regards,
{submittal.sender_name}
{submittal.sender_company}
"""
return {
'subject': subject,
'body': body,
'priority': 'normal'
}
3. Meeting Notice Email
Generate meeting invitation emails.
@dataclass
class MeetingNotice:
meeting_type: str # 'OAC', 'Subcontractor', 'Safety', 'Coordination'
project_name: str
date: str
time: str
location: str
virtual_link: Optional[str]
agenda_items: List[str]
attendees: List[str]
organizer_name: str
def generate_meeting_notice(meeting: MeetingNotice) -> dict:
"""Generate meeting notice email."""
subject = f"{meeting.meeting_type} Meeting - {meeting.project_name} - {meeting.date}"
agenda = "\n".join(f" {i+1}. {item}" for i, item in enumerate(meeting.agenda_items))
location_info = meeting.location
if meeting.virtual_link:
location_info += f"\n Virtual Option: {meeting.virtual_link}"
body = f"""Dear Team,
You are invited to the {meeting.meeting_type} Meeting for {meeting.project_name}.
**Meeting Details:**
- **Date:** {meeting.date}
- **Time:** {meeting.time}
- **Location:** {location_info}
**Agenda:**
{agenda}
**Attendees:**
{', '.join(meeting.attendees)}
Please confirm your attendance by replying to this email.
If you cannot attend, please send a delegate and notify the organizer.
Regards,
{meeting.organizer_name}
Project Manager
"""
return {
'subject': subject,
'body': body,
'to': meeting.attendees,
'calendar_invite': {
'start': f"{meeting.date} {meeting.time}",
'duration': 60,
'location': meeting.location
}
}
4. Change Order Notification
Generate change order notification emails.
@dataclass
class ChangeOrderNotification:
co_number: str
project_name: str
description: str
amount: float
schedule_impact: str
reason: str
status: str # 'Pending', 'Approved', 'Rejected'
sender_name: str
sender_title: str
def generate_change_order_email(co: ChangeOrderNotification) -> dict:
"""Generate change order notification email."""
subject = f"Change Order #{co.co_number} - {co.status} - {co.project_name}"
amount_str = f"${co.amount:,.2f}"
if co.amount < 0:
amount_str = f"(${abs(co.amount):,.2f}) Credit"
body = f"""Dear Project Team,
This email is to notify you of Change Order #{co.co_number} for {co.project_name}.
**Change Order Details:**
- **CO Number:** {co.co_number}
- **Status:** {co.status}
- **Description:** {co.description}
**Financial Impact:**
- **Amount:** {amount_str}
**Schedule Impact:**
- {co.schedule_impact}
**Reason for Change:**
{co.reason}
{"Please review the attached documentation and provide your approval." if co.status == 'Pending' else ""}
{"This change order has been approved. Please proceed accordingly." if co.status == 'Approved' else ""}
If you have any questions, please contact the project team.
Best regards,
{co.sender_name}
{co.sender_title}
"""
return {
'subject': subject,
'body': body,
'priority': 'high' if co.status == 'Pending' else 'normal',
'flag': co.status == 'Pending'
}
5. Daily Report Email
Generate daily report distribution email.
@dataclass
class DailyReportEmail:
project_name: str
report_date: str
report_number: int
weather: str
workforce_total: int
work_summary: List[str]
issues: List[str]
sender_name: str
def generate_daily_report_email(report: DailyReportEmail) -> dict:
"""Generate daily report distribution email."""
subject = f"Daily Report #{report.report_number} - {report.project_name} - {report.report_date}"
work_items = "\n".join(f"• {item}" for item in report.work_summary)
issues_text = "\n".join(f"• {issue}" for issue in report.issues) if report.issues else "None"
body = f"""Daily Construction Report
**Project:** {report.project_name}
**Date:** {report.report_date}
**Report #:** {report.report_number}
---
**Weather:** {report.weather}
**Total Workforce:** {report.workforce_total} workers on-site
---
**Work Completed:**
{work_items}
---
**Issues/Delays:**
{issues_text}
---
Full report attached. Please contact the site office with any questions.
{report.sender_name}
Site Superintendent
"""
return {
'subject': subject,
'body': body,
'attachments': [f'Daily_Report_{report.report_number}.pdf']
}
6. Delay Notice Email
Generate formal delay notification.
@dataclass
class DelayNotice:
project_name: str
contract_number: str
delay_type: str # 'Excusable', 'Non-Excusable', 'Compensable'
cause: str
affected_activities: List[str]
original_completion: str
revised_completion: str
days_impacted: int
mitigation_plan: str
sender_name: str
sender_title: str
def generate_delay_notice_email(delay: DelayNotice) -> dict:
"""Generate formal delay notice email."""
subject = f"NOTICE OF DELAY - {delay.project_name} - {delay.days_impacted} Days"
activities = "\n".join(f" - {a}"