Fix two production billing bugs: invoice missing oven cost, quote stuck in Draft after send
Bug 1 — Invoice total didn't match job total for direct jobs: - Root cause: all three item-save paths in JobsController passed null for ovenCostId, so FinalPrice/ShopSuppliesAmount were stored without oven cost while the Details page recalculated live with OvenCostId and showed higher. - Add OvenBatchCost stored field to Job entity (migration AddJobOvenBatchCost, default 0 for existing rows). - Fix Create, Edit, and UpdateItems to pass job.OvenCostId and save OvenBatchCost. - Fix InvoicesController.Create GET for direct jobs to use stored OvenBatchCost and ShopSuppliesAmount as separate labeled lines instead of recalculating shop supplies from scratch (which excluded the oven cost base). Bug 2 — Quote status stayed Draft after "Send Quote via Email": - ResendQuote advanced the approval token and sent the email but never updated the status. Added Draft → Sent advancement (same guard used by the SMS send path) so the status updates on successful email send. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3059,6 +3059,18 @@ public class QuotesController : Controller
|
||||
quote.ApprovalTokenExpiresAt = DateTime.UtcNow.AddDays(
|
||||
int.TryParse(await _platformSettings.GetAsync(PlatformSettingKeys.QuoteApprovalTokenDays), out var tokenDays) ? tokenDays : 30);
|
||||
quote.ApprovalTokenUsedAt = null;
|
||||
|
||||
// Advance from Draft → Sent (mirrors the Create and SendSms paths)
|
||||
var resendCompanyId = _tenantContext.GetCurrentCompanyId() ?? 0;
|
||||
var resendStatuses = await _lookupCache.GetQuoteStatusLookupsAsync(resendCompanyId);
|
||||
var resendSentStatus = resendStatuses.FirstOrDefault(s => s.StatusCode == AppConstants.StatusCodes.Quote.Sent);
|
||||
var resendDraftStatus = resendStatuses.FirstOrDefault(s => s.StatusCode == AppConstants.StatusCodes.Quote.Draft);
|
||||
if (resendSentStatus != null && quote.QuoteStatusId == (resendDraftStatus?.Id ?? 0))
|
||||
{
|
||||
quote.QuoteStatusId = resendSentStatus.Id;
|
||||
quote.SentDate ??= DateTime.UtcNow;
|
||||
}
|
||||
|
||||
await _unitOfWork.Quotes.UpdateAsync(quote);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user