shoc-backend/SeaHaven.Services/Implementation/UpliftNotificationMessage.cs

66 lines
4.2 KiB
C#
Raw Normal View History

using Data.SeaHavenIndustries;
using SeaHaven.DataServices.Helpers;
namespace SeaHaven.Services.Implementation
{
/// <summary>
/// Builds uplift notification email content. Shared by the synchronous request path
/// and the lifecycle sweep so content stays consistent without duplication.
/// </summary>
public static class UpliftNotificationMessage
{
public static (string Subject, string Body) BuildInitial(Dispatch dispatch, DispatchUpliftRequest req, string vendorName, string frontendBase)
{
var dispatchNum = System.Net.WebUtility.HtmlEncode(dispatch.DispatchNumber ?? "");
var vendor = System.Net.WebUtility.HtmlEncode(vendorName);
var reason = System.Net.WebUtility.HtmlEncode(req.VendorReason ?? "(no reason provided)");
var tierText = req.RequiredTier == 2 ? "Tier 2 (Manager approval required)" : "Tier 1";
var subject = $"[Uplift Request] {dispatch.DispatchNumber} — {vendorName} requests ${req.RequestedNTE:F2} (was ${req.CurrentNTE ?? 0m:F2})";
var body = $@"
<h2>Vendor Uplift Request</h2>
<p><strong>Dispatch:</strong> {dispatchNum}</p>
<p><strong>Vendor:</strong> {vendor}</p>
<table style='border-collapse:collapse;font-family:Arial,sans-serif;'>
<tr><td style='padding:4px 10px;'><strong>Current NTE</strong></td><td style='padding:4px 10px;'>${req.CurrentNTE ?? 0m:F2}</td></tr>
<tr><td style='padding:4px 10px;'><strong>Requested NTE</strong></td><td style='padding:4px 10px;'>${req.RequestedNTE:F2}</td></tr>
<tr><td style='padding:4px 10px;'><strong>Delta</strong></td><td style='padding:4px 10px;'>${UpliftAmount.Of(req):F2}</td></tr>
<tr><td style='padding:4px 10px;'><strong>Required Approval</strong></td><td style='padding:4px 10px;'>{tierText}</td></tr>
</table>
<h3>Vendor Reason</h3>
<p>{reason}</p>
{ReviewLink(dispatch, frontendBase)}";
return (subject, body);
}
public static (string Subject, string Body) BuildEscalation(Dispatch dispatch, DispatchUpliftRequest req, string vendorName, string frontendBase)
{
var dispatchNum = System.Net.WebUtility.HtmlEncode(dispatch.DispatchNumber ?? "");
var vendor = System.Net.WebUtility.HtmlEncode(vendorName);
var tierText = req.RequiredTier == 2 ? "Tier 2 (Manager approval required)" : "Tier 1";
var subject = $"[Escalation] Uplift request awaiting decision — {dispatch.DispatchNumber} ({vendorName})";
var body = $@"
<h2>Uplift Request Escalation</h2>
<p>An uplift request is still awaiting a decision and has passed the escalation threshold.</p>
<p><strong>Dispatch:</strong> {dispatchNum}</p>
<p><strong>Vendor:</strong> {vendor}</p>
<table style='border-collapse:collapse;font-family:Arial,sans-serif;'>
<tr><td style='padding:4px 10px;'><strong>Current NTE</strong></td><td style='padding:4px 10px;'>${req.CurrentNTE ?? 0m:F2}</td></tr>
<tr><td style='padding:4px 10px;'><strong>Requested NTE</strong></td><td style='padding:4px 10px;'>${req.RequestedNTE:F2}</td></tr>
<tr><td style='padding:4px 10px;'><strong>Required Approval</strong></td><td style='padding:4px 10px;'>{tierText}</td></tr>
</table>
{ReviewLink(dispatch, frontendBase)}";
return (subject, body);
}
private static string ReviewLink(Dispatch dispatch, string frontendBase)
{
var link = dispatch.WorkOrderId.HasValue
? $"{frontendBase.TrimEnd('/')}/workorders/{dispatch.WorkOrderId.Value}"
: frontendBase;
return $"<div style='margin:20px 0;'><a href='{link}' style='display:inline-block;padding:10px 22px;background:#2563eb;color:white;text-decoration:none;border-radius:6px;font-weight:bold;'>Review in SHOC</a></div>";
}
}
}