Fix subscription expiry logic and HTML entities in page titles

Subscription expiry (SubscriptionExpiryBackgroundService):
- Trials with no grace period now go directly Active -> Expired instead
  of briefly entering GracePeriod for a day, which was causing repeated
  'Grace Period Started' admin notification emails
- Remove redundant isTrial variable (query already filters to non-Stripe
  companies, so all processed companies are trials by definition)
- Save per-company inside the loop so a single SaveChangesAsync failure
  no longer discards all other companies' status changes and notification
  log entries (which was the other cause of repeated emails)

HTML entities in page titles (33 views):
- Replace – / — with plain ' - ' in ViewData["Title"] C#
  strings; Razor HTML-encodes these when rendering @ViewData["Title"],
  causing browsers to display the literal text '–' instead of a dash

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 09:43:41 -04:00
parent 04d16109ae
commit e4a256a6c4
33 changed files with 129 additions and 92 deletions
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep1Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Company Profile";
ViewData["Title"] = "Setup Wizard - Company Profile";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 1;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep9Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Team Members";
ViewData["Title"] = "Setup Wizard - Team Members";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 10;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep6Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Chart of Accounts";
ViewData["Title"] = "Setup Wizard - Chart of Accounts";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 11;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep10Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Vendors & Suppliers";
ViewData["Title"] = "Setup Wizard - Vendors & Suppliers";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 12;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep8Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Inventory / Powder Colors";
ViewData["Title"] = "Setup Wizard - Inventory / Powder Colors";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 13;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardOvensStepDto
@{
ViewData["Title"] = "Setup Wizard &mdash; Equipment & Ovens";
ViewData["Title"] = "Setup Wizard - Equipment & Ovens";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 14;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardPricingTiersStepDto
@{
ViewData["Title"] = "Setup Wizard &mdash; Pricing Tiers";
ViewData["Title"] = "Setup Wizard - Pricing Tiers";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 15;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardCatalogStepDto
@{
ViewData["Title"] = "Setup Wizard &mdash; Service Catalog";
ViewData["Title"] = "Setup Wizard - Service Catalog";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 16;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep7Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Notifications";
ViewData["Title"] = "Setup Wizard - Notifications";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 17;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep9Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Team Members";
ViewData["Title"] = "Setup Wizard - Team Members";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 18;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep2QbDto
@{
ViewData["Title"] = "Setup Wizard &mdash; QuickBooks Migration";
ViewData["Title"] = "Setup Wizard - QuickBooks Migration";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 2;
}
@@ -1,8 +1,8 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Core.Enums
@model WizardStep2Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Operating Costs";
ViewData["Title"] = "Setup Wizard - Operating Costs";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 3;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardOvensStepDto
@{
ViewData["Title"] = "Setup Wizard &mdash; Shop Equipment";
ViewData["Title"] = "Setup Wizard - Shop Equipment";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 4;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep3Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Document Numbering";
ViewData["Title"] = "Setup Wizard - Document Numbering";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 5;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep5Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Job Settings";
ViewData["Title"] = "Setup Wizard - Job Settings";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 6;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep4Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Payment Terms";
ViewData["Title"] = "Setup Wizard - Payment Terms";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 7;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardPricingTiersStepDto
@{
ViewData["Title"] = "Setup Wizard &mdash; Pricing Tiers";
ViewData["Title"] = "Setup Wizard - Pricing Tiers";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 8;
}
@@ -1,7 +1,7 @@
@using PowderCoating.Application.DTOs.Wizard
@using PowderCoating.Application.DTOs.Wizard
@model WizardStep7Dto
@{
ViewData["Title"] = "Setup Wizard &mdash; Notifications";
ViewData["Title"] = "Setup Wizard - Notifications";
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
int step = ViewBag.Step as int? ?? 5;
}