Add BillingEmail field for commercial customers; support comma-separated multi-email
- Customer entity + DTO: new BillingEmail field (accounting/invoicing address) - Email fields now accept comma-separated lists; DTO validates each address individually - NotificationService: SendToEmailListAsync helper fans out to all addresses in a list; NotifyQuoteSentAsync accepts optional overrideEmail so staff can send to an ad-hoc address - Migration: AddCustomerBillingEmail - Customer Create/Edit/Details views updated to show Billing Email field - customer-billing-email.js: client-side helpers for billing email input Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,7 +74,7 @@
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label asp-for="Email" class="form-label">Email <span class="text-danger">*</span> <span class="text-muted fw-normal">(required if no phone number)</span></label>
|
||||
<input asp-for="Email" type="email" class="form-control" placeholder="name@example.com" />
|
||||
<input asp-for="Email" type="email" multiple class="form-control" placeholder="name@example.com (comma-separate multiple)" />
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
@@ -87,6 +87,14 @@
|
||||
<input asp-for="MobilePhone" type="tel" class="form-control" placeholder="(555) 123-4567" />
|
||||
<span asp-validation-for="MobilePhone" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="col-md-6" id="billingEmailRow" style="display:none;">
|
||||
<label asp-for="BillingEmail" class="form-label">Billing / Accounting Email
|
||||
<span class="text-muted fw-normal">(invoices sent here)</span>
|
||||
</label>
|
||||
<input asp-for="BillingEmail" type="email" multiple class="form-control" placeholder="accounting@company.com (comma-separate multiple)" />
|
||||
<span asp-validation-for="BillingEmail" class="text-danger"></span>
|
||||
<div class="form-text">When set, invoices are emailed here instead of the contact email.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -372,4 +380,5 @@
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
<script src="~/js/customer-billing-email.js"></script>
|
||||
}
|
||||
|
||||
@@ -97,11 +97,37 @@
|
||||
<div class="col-md-6">
|
||||
<label class="text-muted small mb-1">Email</label>
|
||||
<p class="mb-0">
|
||||
<a href="mailto:@Model.Email" class="text-decoration-none">
|
||||
<i class="bi bi-envelope me-1"></i>@Model.Email
|
||||
</a>
|
||||
@if (!string.IsNullOrEmpty(Model.Email))
|
||||
{
|
||||
<a href="mailto:@Model.Email" class="text-decoration-none">
|
||||
<i class="bi bi-envelope me-1"></i>@Model.Email
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-muted">Not provided</span>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
@if (Model.IsCommercial)
|
||||
{
|
||||
<div class="col-md-6">
|
||||
<label class="text-muted small mb-1">Billing / Accounting Email</label>
|
||||
<p class="mb-0">
|
||||
@if (!string.IsNullOrEmpty(Model.BillingEmail))
|
||||
{
|
||||
<a href="mailto:@Model.BillingEmail" class="text-decoration-none">
|
||||
<i class="bi bi-envelope-at me-1"></i>@Model.BillingEmail
|
||||
</a>
|
||||
<span class="badge bg-info bg-opacity-10 text-info ms-2 small">Invoices</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-muted">Not set — invoices go to contact email</span>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
<div class="col-md-6">
|
||||
<label class="text-muted small mb-1">Phone</label>
|
||||
<p class="mb-0">
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label asp-for="Email" class="form-label">Email</label>
|
||||
<input asp-for="Email" type="email" class="form-control" placeholder="name@example.com" />
|
||||
<input asp-for="Email" type="email" multiple class="form-control" placeholder="name@example.com (comma-separate multiple)" />
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
@@ -91,6 +91,14 @@
|
||||
<input asp-for="MobilePhone" type="tel" class="form-control" placeholder="(555) 123-4567" />
|
||||
<span asp-validation-for="MobilePhone" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="col-md-6" id="billingEmailRow" style="display:none;">
|
||||
<label asp-for="BillingEmail" class="form-label">Billing / Accounting Email
|
||||
<span class="text-muted fw-normal">(invoices sent here)</span>
|
||||
</label>
|
||||
<input asp-for="BillingEmail" type="email" multiple class="form-control" placeholder="accounting@company.com (comma-separate multiple)" />
|
||||
<span asp-validation-for="BillingEmail" class="text-danger"></span>
|
||||
<div class="form-text">When set, invoices are emailed here instead of the contact email.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -436,4 +444,5 @@
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
<script src="~/js/customer-billing-email.js"></script>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
(function () {
|
||||
var select = document.getElementById('IsCommercial');
|
||||
var row = document.getElementById('billingEmailRow');
|
||||
if (!select || !row) return;
|
||||
|
||||
function toggle() {
|
||||
row.style.display = select.value === 'true' ? '' : 'none';
|
||||
}
|
||||
|
||||
toggle();
|
||||
select.addEventListener('change', toggle);
|
||||
})();
|
||||
Reference in New Issue
Block a user