4ec55e7290
The HTML entity sweep script had a bug where it wrote empty files for any
view that contained no target Unicode characters, zeroing out 215 view files.
All views restored from the pre-sweep commit (cefdf3e).
Bulk gift certificate feature:
- BulkCreateGiftCertificateDto with Quantity (1-500), Amount, Reason, Expiry, Notes
- GenerateBulkGiftCertificatePdfAsync on IPdfService / PdfService: one Letter page
per cert, reusing the same purple/gold branded ComposeGiftCertificateContent helper
- GiftCertificatesController: BulkCreate GET/POST, BulkResult GET, BulkDownloadPdf POST
- Views: BulkCreate.cshtml (form with live total preview), BulkResult.cshtml (table +
Download All PDF button that POSTs cert IDs to avoid URL length limits)
- gift-certificate-bulk.js: live preview + spinner/disable on submit
- Index.cshtml: Bulk Create button added alongside New Certificate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
108 lines
5.8 KiB
Plaintext
108 lines
5.8 KiB
Plaintext
@model PowderCoating.Application.DTOs.GiftCertificate.BulkCreateGiftCertificateDto
|
|
@using PowderCoating.Core.Enums
|
|
|
|
@{
|
|
ViewData["Title"] = "Bulk Create Gift Certificates";
|
|
ViewData["PageIcon"] = "bi-gift";
|
|
}
|
|
|
|
<div class="row justify-content-center">
|
|
<div class="col-lg-7">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-bottom py-3">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-collection me-2 text-primary"></i>Bulk Gift Certificate Generator
|
|
</h5>
|
|
<p class="text-muted small mb-0 mt-1">
|
|
Create a batch of certificates for car shows, events, or promotions. All certificates will have the same
|
|
face value and be generated with sequential codes ready to print.
|
|
</p>
|
|
</div>
|
|
<div class="card-body p-4">
|
|
<form asp-action="BulkCreate" method="post">
|
|
<div asp-validation-summary="ModelOnly" class="alert alert-danger" role="alert"></div>
|
|
|
|
<div class="row g-3">
|
|
|
|
<div class="col-md-5">
|
|
<label asp-for="Quantity" class="form-label fw-semibold">
|
|
<i class="bi bi-123 me-1 text-muted"></i>@Html.DisplayNameFor(m => m.Quantity)
|
|
</label>
|
|
<input asp-for="Quantity" type="number" class="form-control form-control-lg"
|
|
min="1" max="500" placeholder="25" />
|
|
<span asp-validation-for="Quantity" class="text-danger small"></span>
|
|
<div class="form-text">Max 500 per batch.</div>
|
|
</div>
|
|
|
|
<div class="col-md-7">
|
|
<label asp-for="Amount" class="form-label fw-semibold">
|
|
<i class="bi bi-currency-dollar me-1 text-muted"></i>@Html.DisplayNameFor(m => m.Amount)
|
|
</label>
|
|
<div class="input-group input-group-lg">
|
|
<span class="input-group-text">$</span>
|
|
<input asp-for="Amount" type="number" class="form-control"
|
|
min="1" max="9999.99" step="0.01" placeholder="50.00" />
|
|
</div>
|
|
<span asp-validation-for="Amount" class="text-danger small"></span>
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<label asp-for="IssuedReason" class="form-label fw-semibold">
|
|
<i class="bi bi-tag me-1 text-muted"></i>@Html.DisplayNameFor(m => m.IssuedReason)
|
|
</label>
|
|
<select asp-for="IssuedReason" class="form-select">
|
|
@foreach (var reason in Enum.GetValues<GiftCertificateIssuedReason>())
|
|
{
|
|
<option value="@reason">@reason</option>
|
|
}
|
|
</select>
|
|
<span asp-validation-for="IssuedReason" class="text-danger small"></span>
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<label asp-for="ExpiryDate" class="form-label fw-semibold">
|
|
<i class="bi bi-calendar-x me-1 text-muted"></i>@Html.DisplayNameFor(m => m.ExpiryDate)
|
|
</label>
|
|
<input asp-for="ExpiryDate" type="date" class="form-control" />
|
|
<span asp-validation-for="ExpiryDate" class="text-danger small"></span>
|
|
<div class="form-text">Leave blank for no expiration.</div>
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<label asp-for="Notes" class="form-label fw-semibold">
|
|
<i class="bi bi-chat-left-text me-1 text-muted"></i>@Html.DisplayNameFor(m => m.Notes)
|
|
</label>
|
|
<textarea asp-for="Notes" class="form-control" rows="2"
|
|
placeholder="e.g. Awarded at the 2026 Summer Car Show — thanks for attending!"></textarea>
|
|
<span asp-validation-for="Notes" class="text-danger small"></span>
|
|
<div class="form-text">Printed on every certificate in the batch.</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Preview summary -->
|
|
<div id="batchPreview" class="alert alert-primary mt-4 mb-0" style="display:none">
|
|
<i class="bi bi-info-circle me-2"></i>
|
|
You are about to create <strong id="prevQty"></strong> certificates worth
|
|
<strong id="prevAmt"></strong> each — total face value
|
|
<strong id="prevTotal"></strong>.
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mt-4 pt-3 border-top">
|
|
<a asp-action="Index" class="btn btn-outline-secondary">
|
|
<i class="bi bi-arrow-left me-1"></i>Cancel
|
|
</a>
|
|
<button type="submit" class="btn btn-primary btn-lg" id="submitBtn">
|
|
<i class="bi bi-plus-circle me-2"></i>Create Certificates
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<script src="~/js/gift-certificate-bulk.js" asp-append-version="true"></script>
|
|
}
|