Fix 4 post-review issues found in accounting module audit
- Drop orphan VendorCreditId1 column from VendorCreditApplications (was scaffolded by EF because WithMany() lacked inverse navigation name; fixed WithMany() → WithMany(vc => vc.Applications) in ApplicationDbContext) - Wire EarlyPaymentDiscount fields through full data path: added EarlyPaymentDiscountPercent/Days to CreateInvoiceDto, hidden inputs to Invoice Create view, and JS to populate from customer AJAX response - Add missing [HttpGet] attribute to TaxRatesController.Index - Document GenerateNow architecture exception with XML rationale Migration DropOrphanVendorCreditId1 applied. Build: 0 errors, 168 warnings. Unit tests: 200/200 passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,15 @@ public class RecurringTemplatesController : Controller
|
||||
/// Forces immediate generation of the next occurrence and advances NextFireDate,
|
||||
/// regardless of the scheduled date. Useful for testing a new template or catching up
|
||||
/// after a configuration change.
|
||||
/// <para>
|
||||
/// INTENTIONAL EXCEPTION to the no-DbContext-in-controllers rule: this action must
|
||||
/// execute the same multi-step entity creation that <see cref="RecurringTransactionService"/>
|
||||
/// does in a background scope. Creating an inner DI scope here avoids duplicating that
|
||||
/// service's interface (which would require exposing a public synchronous Fire method on a
|
||||
/// singleton BackgroundService, which is unsafe). The scope is disposed after the action
|
||||
/// completes, so no DbContext leak occurs. This pattern mirrors how BackgroundService
|
||||
/// itself resolves scoped services.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
@@ -184,6 +193,8 @@ public class RecurringTemplatesController : Controller
|
||||
|
||||
try
|
||||
{
|
||||
// Intentional: create a fresh DI scope so the inner DbContext is isolated from the
|
||||
// request's IUnitOfWork context. See summary above for rationale.
|
||||
using var scope = HttpContext.RequestServices.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<PowderCoating.Infrastructure.Data.ApplicationDbContext>();
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ public class TaxRatesController : Controller
|
||||
}
|
||||
|
||||
/// <summary>Lists all tax rates for the current company.</summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
var rates = await _unitOfWork.TaxRates.GetAllAsync();
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
<input type="hidden" asp-for="PreparedById" />
|
||||
<input type="hidden" asp-for="JobId" />
|
||||
<input type="hidden" asp-for="CustomerId" id="hiddenCustomerId" />
|
||||
<input type="hidden" asp-for="EarlyPaymentDiscountPercent" id="EarlyPaymentDiscountPercent" />
|
||||
<input type="hidden" asp-for="EarlyPaymentDiscountDays" id="EarlyPaymentDiscountDays" />
|
||||
|
||||
<div class="row g-4">
|
||||
<!-- LEFT: Main form -->
|
||||
@@ -473,8 +475,10 @@
|
||||
// Trigger due date recalculation (invoice-due-date.js listens to 'change')
|
||||
termsSelect.dispatchEvent(new Event('change'));
|
||||
}
|
||||
// Show/hide early payment discount notice
|
||||
// Show/hide early payment discount notice and persist values
|
||||
const discountEl = document.getElementById('earlyPaymentDiscountNotice');
|
||||
const discountPctField = document.getElementById('EarlyPaymentDiscountPercent');
|
||||
const discountDaysField = document.getElementById('EarlyPaymentDiscountDays');
|
||||
if (discountEl) {
|
||||
if (data.earlyPaymentDiscountPercent > 0) {
|
||||
discountEl.textContent = `${data.earlyPaymentDiscountPercent}% discount if paid within ${data.earlyPaymentDiscountDays} days`;
|
||||
@@ -483,6 +487,8 @@
|
||||
discountEl.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
if (discountPctField) discountPctField.value = data.earlyPaymentDiscountPercent ?? 0;
|
||||
if (discountDaysField) discountDaysField.value = data.earlyPaymentDiscountDays ?? 0;
|
||||
}).catch(() => {});
|
||||
|
||||
// Fetch tax rate for the selected customer
|
||||
|
||||
Reference in New Issue
Block a user