Sales Order Mail Tasarımı

This commit is contained in:
Sedat Öztürk 2026-07-08 00:13:31 +03:00
parent cda9aa6a72
commit 3953498b8d

View file

@ -623,83 +623,199 @@ public class PublicAppService : PlatformAppService
}
}
private static string BuildOrderEmailBody(Order order)
private string BuildOrderEmailBody(Order order)
{
var itemRows = string.Join(string.Empty, order.Items.Select(item => $@"
<tr>
<td style=""padding:12px;border-bottom:1px solid #e5e7eb;font-weight:600;color:#111827;"">{Html(item.ProductName)}</td>
<td style=""padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;"">{item.Quantity}</td>
<td style=""padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;"">{BillingCycleLabel(item.BillingCycle)}</td>
<td style=""padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;"">%{item.VatRate * 100:0.##} / {FormatPrice(item.VatAmount)}</td>
<td style=""padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;font-weight:700;color:#111827;"">{FormatPrice(item.TotalPrice)}</td>
<td style=""padding:16px 14px;border-bottom:1px solid #e5e7eb;font-weight:700;color:#111827;line-height:20px;"">{Html(Translate(item.ProductName))}</td>
<td align=""right"" style=""padding:16px 14px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;white-space:nowrap;line-height:20px;"">{FormatPrice(item.Price)}</td>
<td align=""right"" style=""padding:16px 14px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;white-space:nowrap;line-height:20px;"">{item.Period}</td>
<td align=""right"" style=""padding:16px 14px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;white-space:nowrap;line-height:20px;"">{item.Quantity}</td>
<td align=""right"" style=""padding:16px 14px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;white-space:nowrap;line-height:20px;"">{BillingCycleLabel(item.BillingCycle)}</td>
<td align=""right"" style=""padding:16px 14px;border-bottom:1px solid #e5e7eb;text-align:right;color:#374151;white-space:nowrap;line-height:20px;"">%{item.VatRate * 100:0.##} / {FormatPrice(item.VatAmount)}</td>
<td align=""right"" style=""padding:16px 14px;border-bottom:1px solid #e5e7eb;text-align:right;font-weight:800;color:#111827;white-space:nowrap;line-height:20px;"">{FormatPrice(item.TotalPrice)}</td>
</tr>"));
return $@"
<!doctype html>
<html>
<body style=""margin:0;background:#f3f4f6;font-family:Arial,Helvetica,sans-serif;color:#111827;"">
<div style=""max-width:920px;margin:0 auto;padding:24px;"">
<div style=""background:#ffffff;border:1px solid #e5e7eb;border-radius:14px;overflow:hidden;"">
<div style=""display:flex;justify-content:space-between;gap:16px;padding:24px;background:#f9fafb;border-bottom:1px solid #e5e7eb;"">
<div>
<div style=""font-size:22px;font-weight:800;"">Sipariş Oluşturuldu</div>
<div style=""margin-top:6px;color:#4b5563;"">Sipariş No: <strong>#{order.Id}</strong></div>
</div>
<div style=""text-align:right;color:#4b5563;"">
<div style=""font-size:12px;text-transform:uppercase;letter-spacing:.08em;"">Invoice</div>
<div style=""font-weight:700;color:#111827;"">{FormatDate(DateTime.Now)}</div>
</div>
</div>
<div style=""padding:24px;"">
<div style=""display:grid;grid-template-columns:1fr 1fr;gap:20px;"">
<div style=""border:1px solid #e5e7eb;border-radius:12px;padding:18px;"">
<div style=""font-size:18px;font-weight:800;margin-bottom:14px;"">Customer Information</div>
<div style=""line-height:1.7;color:#374151;"">
<strong>{Html(order.OrganizationName)}</strong><br />
{Html(order.Email)}<br />
{Html(FormatPhoneNumber(order.PhoneNumber ?? order.MobileNumber))}<br />
{Html(order.Address1)}<br />
{Html(order.District)} / {Html(order.City)} / {Html(order.Country)}
</div>
</div>
<div style=""border:1px solid #e5e7eb;border-radius:12px;padding:18px;"">
<div style=""font-size:18px;font-weight:800;margin-bottom:14px;"">License Information</div>
<div style=""line-height:1.8;color:#374151;"">
<div><strong>License Start Time:</strong> {FormatDate(order.LicenseStartTime)}</div>
<div><strong>License End Time:</strong> {FormatDate(order.LicenseEndTime)}</div>
<div><strong>Billing Cycle:</strong> {BillingCycleLabel(order.BillingCycle)}</div>
<div><strong>Period:</strong> {order.Period}</div>
</div>
</div>
</div>
<table style=""width:100%;border-collapse:collapse;margin-top:24px;border:1px solid #e5e7eb;border-radius:12px;overflow:hidden;"">
<thead>
<tr style=""background:#f9fafb;color:#6b7280;font-size:12px;text-transform:uppercase;letter-spacing:.06em;"">
<th style=""padding:12px;text-align:left;"">Product</th>
<th style=""padding:12px;text-align:right;"">Qty</th>
<th style=""padding:12px;text-align:right;"">Cycle</th>
<th style=""padding:12px;text-align:right;"">VAT</th>
<th style=""padding:12px;text-align:right;"">Amount</th>
</tr>
</thead>
<tbody>{itemRows}</tbody>
</table>
<div style=""max-width:360px;margin:24px 0 0 auto;line-height:1.9;color:#374151;"">
<div style=""display:flex;justify-content:space-between;""><span>Subtotal</span><strong>{FormatPrice(order.Subtotal)}</strong></div>
<div style=""display:flex;justify-content:space-between;""><span>VAT</span><strong>{FormatPrice(order.VatTotal)}</strong></div>
<div style=""display:flex;justify-content:space-between;""><span>Commission</span><strong>{FormatPrice(order.Commission)}</strong></div>
<div style=""display:flex;justify-content:space-between;border-top:1px solid #e5e7eb;margin-top:8px;padding-top:10px;font-size:18px;color:#111827;""><span>Total</span><strong>{FormatPrice(order.Total)}</strong></div>
</div>
</div>
</div>
<head>
<meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8"" />
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"" />
<meta name=""x-apple-disable-message-reformatting"" />
</head>
<body bgcolor=""#f3f4f6"" style=""margin:0;padding:0;background-color:#f3f4f6;font-family:Arial,Helvetica,sans-serif;color:#111827;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;"">
<div style=""display:none;font-size:1px;color:#f3f4f6;line-height:1px;max-height:0;max-width:0;opacity:0;overflow:hidden;"">
{Html(Translate("Public.order.success.title"))} #{order.Id}
</div>
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" bgcolor=""#f3f4f6"" style=""width:100%;background-color:#f3f4f6;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td align=""center"" style=""padding:24px 12px;"">
<table role=""presentation"" width=""980"" cellpadding=""0"" cellspacing=""0"" border=""0"" align=""center"" bgcolor=""#ffffff"" style=""width:100%;max-width:980px;background-color:#ffffff;border:1px solid #e5e7eb;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td bgcolor=""#f9fafb"" style=""padding:24px;background-color:#f9fafb;border-bottom:1px solid #e5e7eb;"">
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td style=""vertical-align:middle;"">
<table role=""presentation"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td style=""width:46px;vertical-align:middle;"">
<table role=""presentation"" width=""40"" height=""40"" cellpadding=""0"" cellspacing=""0"" border=""0"" bgcolor=""#22c55e"" style=""width:40px;height:40px;background-color:#22c55e;border-collapse:collapse;"">
<tr>
<td align=""center"" valign=""middle"" style=""font-size:22px;line-height:40px;font-weight:800;color:#ffffff;"">&#10003;</td>
</tr>
</table>
</td>
<td style=""vertical-align:middle;"">
<table role=""presentation"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""border-collapse:collapse;"">
<tr>
<td style=""font-size:22px;line-height:28px;font-weight:800;color:#111827;"">{Html(Translate("Public.order.success.title"))}</td>
</tr>
<tr>
<td style=""padding-top:6px;color:#4b5563;font-size:14px;line-height:20px;"">{Html(Translate("Public.order.success.number"))} <strong style=""color:#2563eb;"">#{order.Id}</strong></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td align=""right"" style=""text-align:right;vertical-align:middle;color:#4b5563;"">
<table role=""presentation"" cellpadding=""0"" cellspacing=""0"" border=""0"" align=""right"" style=""border-collapse:collapse;"">
<tr>
<td align=""right"" style=""font-size:12px;line-height:16px;text-transform:uppercase;letter-spacing:.08em;color:#6b7280;"">Invoice</td>
</tr>
<tr>
<td align=""right"" style=""padding-top:4px;font-size:14px;line-height:20px;font-weight:700;color:#111827;"">{FormatDate(DateTime.Now)}</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style=""padding:24px;"">
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:separate;border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td width=""50%"" style=""vertical-align:top;padding:0 10px 20px 0;"">
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" bgcolor=""#ffffff"" style=""width:100%;background-color:#ffffff;border:1px solid #e5e7eb;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td style=""padding:18px;"">
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:collapse;"">
<tr>
<td style=""font-size:18px;line-height:24px;font-weight:800;color:#111827;padding-bottom:14px;"">Customer Information</td>
</tr>
<tr>
<td style=""line-height:24px;color:#374151;font-size:14px;"">
<strong style=""color:#111827;"">{Html(order.OrganizationName)}</strong><br />
<a href=""mailto:{Html(order.Email)}"" style=""color:#2563eb;text-decoration:none;"">{Html(order.Email)}</a><br />
{Html(FormatPhoneNumber(order.PhoneNumber ?? order.MobileNumber))}<br />
{Html(order.Address1)}<br />
{Html(order.Township)} / {Html(order.District)} / {Html(order.City)} / {Html(order.Country)}
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td width=""50%"" style=""vertical-align:top;padding:0 0 20px 10px;"">
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" bgcolor=""#ffffff"" style=""width:100%;background-color:#ffffff;border:1px solid #e5e7eb;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td style=""padding:18px;"">
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:collapse;"">
<tr>
<td style=""font-size:18px;line-height:24px;font-weight:800;color:#111827;padding-bottom:14px;"">License Information</td>
</tr>
</table>
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:collapse;font-size:14px;color:#374151;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td bgcolor=""#f9fafb"" style=""padding:8px;background-color:#f9fafb;color:#6b7280;line-height:20px;"">License Start Time</td>
<td bgcolor=""#f9fafb"" align=""right"" style=""padding:8px;background-color:#f9fafb;text-align:right;font-weight:700;color:#111827;line-height:20px;"">{FormatDate(order.LicenseStartTime)}</td>
</tr>
<tr>
<td style=""padding:8px;color:#6b7280;line-height:20px;"">License End Time</td>
<td align=""right"" style=""padding:8px;text-align:right;font-weight:700;color:#111827;line-height:20px;"">{FormatDate(order.LicenseEndTime)}</td>
</tr>
<tr>
<td bgcolor=""#f9fafb"" style=""padding:8px;background-color:#f9fafb;color:#6b7280;line-height:20px;"">Billing Cycle</td>
<td bgcolor=""#f9fafb"" align=""right"" style=""padding:8px;background-color:#f9fafb;text-align:right;font-weight:700;color:#111827;line-height:20px;"">{BillingCycleLabel(order.BillingCycle)}</td>
</tr>
<tr>
<td style=""padding:8px;color:#6b7280;line-height:20px;"">Period</td>
<td align=""right"" style=""padding:8px;text-align:right;font-weight:700;color:#111827;line-height:20px;"">{order.Period}</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:collapse;border:1px solid #e5e7eb;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<thead>
<tr style=""background:#f9fafb;color:#6b7280;font-size:12px;text-transform:uppercase;letter-spacing:.06em;"">
<th bgcolor=""#f9fafb"" style=""padding:12px 14px;text-align:left;background-color:#f9fafb;line-height:16px;"">Product</th>
<th bgcolor=""#f9fafb"" align=""right"" style=""padding:12px 14px;text-align:right;background-color:#f9fafb;line-height:16px;"">Price</th>
<th bgcolor=""#f9fafb"" align=""right"" style=""padding:12px 14px;text-align:right;background-color:#f9fafb;line-height:16px;"">Period</th>
<th bgcolor=""#f9fafb"" align=""right"" style=""padding:12px 14px;text-align:right;background-color:#f9fafb;line-height:16px;"">Qty</th>
<th bgcolor=""#f9fafb"" align=""right"" style=""padding:12px 14px;text-align:right;background-color:#f9fafb;line-height:16px;"">Cycle</th>
<th bgcolor=""#f9fafb"" align=""right"" style=""padding:12px 14px;text-align:right;background-color:#f9fafb;line-height:16px;"">VAT</th>
<th bgcolor=""#f9fafb"" align=""right"" style=""padding:12px 14px;text-align:right;background-color:#f9fafb;line-height:16px;"">Amount</th>
</tr>
</thead>
<tbody>{itemRows}</tbody>
</table>
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:collapse;margin-top:20px;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td style=""width:58%;"">&nbsp;</td>
<td style=""width:42%;vertical-align:top;"">
<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" border=""0"" style=""width:100%;border-collapse:collapse;color:#374151;font-size:14px;mso-table-lspace:0pt;mso-table-rspace:0pt;"">
<tr>
<td style=""padding:8px 0;text-align:left;line-height:20px;"">{Html(Translate("Public.payment.summary.subtotal"))}</td>
<td align=""right"" style=""padding:8px 0;text-align:right;font-weight:700;color:#111827;white-space:nowrap;line-height:20px;"">{FormatPrice(order.Subtotal)}</td>
</tr>
<tr>
<td style=""padding:8px 0;text-align:left;line-height:20px;"">{Html(Translate("Public.products.kdv"))}</td>
<td align=""right"" style=""padding:8px 0;text-align:right;font-weight:700;color:#111827;white-space:nowrap;line-height:20px;"">{FormatPrice(order.VatTotal)}</td>
</tr>
<tr>
<td style=""padding:8px 0;text-align:left;line-height:20px;"">{Html(Translate("Public.payment.installments.commission"))}</td>
<td align=""right"" style=""padding:8px 0;text-align:right;font-weight:700;color:#111827;white-space:nowrap;line-height:20px;"">{FormatPrice(order.Commission)}</td>
</tr>
<tr>
<td style=""padding:14px 0 0;border-top:1px solid #e5e7eb;text-align:left;font-size:18px;line-height:24px;font-weight:800;color:#111827;"">{Html(Translate("App.Listform.ListformField.Total"))}</td>
<td align=""right"" style=""padding:14px 0 0;border-top:1px solid #e5e7eb;text-align:right;font-size:18px;line-height:24px;font-weight:800;color:#2563eb;white-space:nowrap;"">{FormatPrice(order.Total)}</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>";
}
private string Translate(string key)
{
if (key.IsNullOrWhiteSpace())
{
return string.Empty;
}
var normalizedKey = key.StartsWith("::", StringComparison.Ordinal) ? key[2..] : key;
var text = L[normalizedKey];
return text.ResourceNotFound ? key : text.Value;
}
private static string BillingCycleLabel(string billingCycle)
{
return billingCycle == "monthly" ? "Aylık" : "Yıllık";