Commit Graph

28 Commits

Author SHA1 Message Date
spouliot be0a5b26e2 Update AI assistant and help docs for invoice and material logging changes
- HelpKnowledgeBase: invoice-from-job now mentions discount carried over,
  Discount Applied display row, and negative line items; new entry for
  PC-based Log Material modal on job details
- Help/Invoices.cshtml: from-job steps updated with discount/terms/due date
  pre-fill detail; sending section corrects due date source (quote/customer)
- Help/Jobs.cshtml: new "Logging Material Usage from a PC" section documenting
  the Log Material modal alongside the existing QR scan instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 12:15:20 -04:00
spouliot 1a44133a63 Remove ShopWorker entity and migrate worker identity to ApplicationUser
Removes the ShopWorker and ShopWorkerRoleCost entities, all related DTOs,
mappings, controllers, views, and import/export paths. Worker identity is
now handled entirely through ApplicationUser with per-user LaborCostPerHour.
ShopWorkerRoleCosts table remains in production pending manual data migration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 20:32:32 -04:00
spouliot 66231822af Update kiosk help article and AI knowledge base for output setting
- Help article: new "Kiosk Output Setting" section explaining Quote vs Job modes and
  the Company Settings → Kiosk tab; Overview updated; Reviewing Submissions now lists
  "View Quote" and "View Job" separately; notification label corrected (Remote vs Walk-in)
- AI knowledge base: CUSTOMER INTAKE KIOSK section updated — output setting documented,
  submission outcome reflects Quote/Job branch, notification labels corrected, workflow
  entries split into Quote-mode and Job-mode variants, troubleshooting updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 22:39:39 -04:00
spouliot d134dd51e5 Add Customer Intake Kiosk help article and knowledge base entry
- New Help article at /Help/CustomerIntakeKiosk covering setup, in-person
  and remote intake flows, what happens on submission, reviewing intakes,
  and troubleshooting (signature pad, connection issues, seed data)
- Add kiosk entry to _HelpNav under Operations
- Update HelpKnowledgeBase: nav overview, full kiosk section, two new
  common workflow entries (walk-in kiosk and remote intake)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 22:02:34 -04:00
spouliot dde66c807f Update help docs and AI knowledge base for Accountant role and new permissions
- Settings.cshtml: add Accountant to roles table with description; add
  Fine-Grained Permissions subsection with a full table of all 16 permissions
  including the new Can Manage Bills & AP and Can Manage Accounting entries
- HelpKnowledgeBase.cs: add Accountant to ROLE AWARENESS section at top;
  add Accountant to USER MANAGEMENT roles list with auto-checked permissions
  note; add Fine-grained permissions paragraph documenting CanManageBills,
  CanManageAccounting, and Accountant role defaults

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 19:44:09 -04:00
spouliot 59beba2e15 Update help docs and AI knowledge base for 4 new AI bookkeeping features
- Reports.cshtml: added AI Payment Risk Prediction, Ask Your Financials,
  and Bank Rec Auto-Match subsections under AI-Powered Reports; updated
  on-this-page nav with sub-links for all three
- AccountsPayable.cshtml: added Recurring Bill Detection section explaining
  pattern cards, frequency types, confidence badges, next expected date,
  and the 2-occurrence minimum
- HelpKnowledgeBase.cs: added Recurring Bill Detection to BILLS section;
  added AI Payment Risk Prediction and Ask Your Financials to REPORTS
  available-reports list; added features 12–15 to AI FEATURES section
  (Recurring Detection, Payment Risk, Financial Query, Bank Rec Auto-Match)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 19:30:39 -04:00
spouliot fde24b09c9 Phase F: Add Invoice Write-Off, Fixed Assets, Period Locking, and 1099 Tracking
- Invoice Write-Off: WriteOff POST action in InvoicesController posts bad-debt JE
  (DR bad debt expense / CR AR), reduces customer balance, marks invoice WrittenOff;
  write-off modal added to Invoice Details view with expense account selector
- Fixed Assets: FixedAsset + FixedAssetDepreciationEntry entities with straight-line
  depreciation; FixedAssetsController (Index/Create/Edit/Details/PostDepreciation/Delete);
  PostDepreciation auto-generates one JE per asset per period, skips already-posted,
  fully-depreciated, and disposed assets; full CRUD views + nav link
- Period Locking: Company.BookLockedThrough field; AccountingPeriodValidator static helper;
  lock check added to JE Post and Bill Create (blocks backdating into closed periods);
  SetPeriodLock action + date picker UI in Company Settings Accounting section
- 1099 Tracking: Is1099Vendor flag on Vendor entity + DTOs; checkbox in Create/Edit views;
  TaxReporting1099 report action + view lists payments by year, flags vendors >= $600;
  report card added to Reports Landing
- Migration AddFixedAssetsLockAnd1099 applied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 12:19:32 -04:00
spouliot d3a5d827f9 Phase F: Customer/Vendor Statements, Payment Terms Parser, Tax Rates
F1: GetCustomerStatementAsync/GetVendorStatementAsync on IFinancialReportService;
    StatementLineDto; CustomerStatementDto/VendorStatementDto; Statement action on
    CustomersController + VendorsController; Statement views + PDF download via
    StatementPdfHelper (QuestPDF); Statement button on Customer/Vendor Details pages.

F2: PaymentTermsParser static helper (CalculateDueDate, ParseEarlyPaymentDiscount);
    EarlyPaymentDiscountPercent/Days on Invoice entity; GetCustomerPaymentTerms AJAX
    endpoint on InvoicesController auto-populates Terms + due date on customer select;
    early payment discount notice on Invoice Create.

F3: TaxRate entity (Name/Rate/State/IsDefault/IsActive, tenant-filtered);
    IUnitOfWork.TaxRates + UnitOfWork + ApplicationDbContext; TaxRatesController
    (Index/Create/Edit/Delete/ToggleActive, CompanyAdminOnly); GetTaxRateForCustomer
    AJAX endpoint; Tax Rates in Settings gear menu.

Also fixes AddVendorCredits migration: VendorCreditApplications FKs changed from
CASCADE to NoAction to resolve SQL Server error 1785 (multiple cascade paths).
Migration: AddPaymentTermsAndTaxRates applied locally; 200/200 unit tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 10:55:22 -04:00
spouliot 379b0de885 Refactor: centralize accounting helpers, status constants, and query deduplication
- AccountingDropdownHelper: wired into BillsController and ExpensesController,
  replacing 35-40 lines of duplicated DB queries per controller
- AppConstants.StatusCodes: added Job.* and Quote.* constants to replace all
  magic status strings across Jobs, Quotes, Appointments, OvenScheduler,
  AiQuickQuote, QuoteApproval, and AccountingDropdownHelper
- AccountingRules: extracted IsNormalDebitBalance into shared Infrastructure
  helper; removed duplicate private method from AccountBalanceService and
  LedgerService (~50 lines deleted)
- AccountDataExportController: extracted 9 Fetch*Async methods (superset of
  includes) so Add*Sheet and Build*Csv no longer duplicate DB queries; each
  entity is queried once regardless of whether XLSX or CSV format is requested
- BillsController.Create and ExpensesController.Create wrapped in
  ExecuteInTransactionAsync; blob uploads moved after commit to keep
  financial data atomic and prevent orphaned blobs from rolling back
- Number generators (Appointments, CreditMemo, OvenBatch) fixed from full-table
  GetAllAsync to prefix-filtered FindAsync

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:42:39 -04:00
spouliot edd7389d7d Refactor: extract shared helpers, fix field drift, add assembly services
- IJobItemAssemblyService / IQuotePricingAssemblyService: centralize job item
  and quote pricing construction that was duplicated across create, rework copy,
  and quote-to-job conversion paths
- BlobFileHelper: single ValidateUpload/GetContentType/SanitizeFileName used by
  6 blob services (JobPhoto, QuotePhoto, ProfilePhoto, CompanyLogo, Equipment,
  Catalog) and BillsController + ExpensesController, removing 8 private copies
- PagedResult<T>.From(): static factory eliminates 6-line boilerplate in 11
  controllers (Appointments, Customers, Equipment, Inventory, Invoices, Jobs,
  Maintenance, CompanyUsers, PlatformUsers, Quotes, Vendors)
- AccountingDropdownHelper: single LoadAsync() call replaces duplicate
  vendor/account/job queries in BillsController and ExpensesController
- JobTemplateItem: add IsSalesItem + Sku fields with migration; propagate
  through JobTemplatesController snapshot copy and GetTemplatesJson projection,
  and JobsController template-application path
- Test assertions updated for standardized BlobFileHelper error messages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:12:33 -04:00
spouliot 9a52e7fae5 Ad-hoc quote email, accounting improvements, AI lookup fix, and misc service updates
- Quotes: ad-hoc email modal on Quote Details lets staff send to an address not on file;
  QuotesController passes overrideEmail through to NotificationService
- Quotes/Details view: SMS consent display, email/SMS send button state based on consent
- Accounting module: AccountingDisplayHelpers for consistent ledger formatting;
  AccountsController + Accounts views improvements; AccountingEnums additions
- Bills/Expenses: AI account categorization fixes in BillsController and ExpensesController
- InventoryAiLookupService: TDS cure fallback no longer fires on AiAugmentFromUrl path
  (LookupByUrlAsync already has it built in — was double-fetching)
- PdfService: quote/invoice PDF updates
- PricingCalculationService: minor pricing logic fix
- QuoteProfile: mapping updates for new quote fields
- ApplicationDbContextModelSnapshot: catches up to all 4 migrations in this branch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 20:48:00 -04:00
spouliot ca4fb959aa Add Sales Tax Liability report with PDF and CSV export
Invoice-basis report showing taxable vs non-taxable sales, tax billed
by GL account, monthly trend table/chart, and full invoice detail grid.
Non-taxable invoice rows shaded grey for easy scanning. Quick-preset
date buttons (This Month, Last Month, YTD, Last Year) for common filing
periods. CSV export formatted for accountants and tax-filing software.
Gated behind AllowAccounting() like other financial reports.

- SalesTaxReportDto + 3 supporting DTOs in FinancialReportDtos.cs
- GetSalesTaxReportAsync on IFinancialReportService + implementation
- GenerateSalesTaxReportPdfAsync on IPdfService + QuestPDF implementation
- SalesTax / SalesTaxPdf / SalesTaxCsv actions in ReportsController
- Views/Reports/SalesTax.cshtml with Chart.js monthly trend chart
- Landing page card added to Finance section
- HelpKnowledgeBase and Help/Reports.cshtml updated with full docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 12:27:08 -04:00
spouliot 2885bc1228 Update help docs and AI knowledge base for new features
GettingStarted: add 'Using on Mobile — Add to Home Screen' section covering
iOS Safari install flow, Android Chrome install, and PWA benefits (full-screen,
persistent camera permission). Includes Safari-required warning for iOS.

Inventory: add 'Catalog Lookup & Label Scanner' section covering smart catalog
search (filters out existing inventory, vendor-scoped with fallback), AI Lookup
fallback, camera label scanner (catalog-first then AI), and the add-stock prompt
when a scanned product is already in inventory.

HelpKnowledgeBase: sync both of the above for the AI Help Assistant, plus add
catalog lookup / label scanner detail to the INVENTORY section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 09:35:31 -04:00
spouliot 0b6a7a14c4 Add Quote Sent SMS template and fix consent confirmation wording
Adds a customizable QuoteSent SMS template to seed data and
DefaultTemplates so companies can edit the quote approval message
from Notification Templates. Wires NotifyQuoteSentSmsAsync to use
the template system instead of a hardcoded string. Updates
SmsConsentConfirmation wording to mention quote approvals alongside
job updates. Help docs and AI knowledge base updated to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 21:19:43 -04:00
spouliot 3ff6a96bc8 Add SMS START/re-subscribe handling to Twilio webhook
Customers who replied STOP by mistake can now reply START, YES, or
UNSTOP to automatically re-enable their SMS opt-in — no staff action
needed. Adds SmsInboundStart notification type, HandleStartAsync in
WebhooksController, and updates AI knowledge base and help docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 20:09:49 -04:00
spouliot c18b580ec9 Add SMS Agreements admin page and update help docs
- Add /SmsAgreements SuperAdmin page listing per-company SMS terms acceptance
  status, with stats cards, filter/search, and a full acceptance history modal
  (terms version, accepted by, timestamp, IP, user agent)
- Add SMS Agreements nav link under Tenants & Billing in the platform sidebar
- Update HelpKnowledgeBase and Help docs (Quotes, Settings) to document
  quote approval via SMS and the reuse of existing approval tokens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 10:17:11 -04:00
spouliot d9bf80cc9a Update help docs and AI knowledge base for SMS notifications
- Settings help article: add SMS Notifications subsection covering company opt-in, TCPA terms agreement, compose-before-send vs auto-send, and STOP opt-out
- Customers help article: add Mobile Phone and SMS Opt-In fields to the Adding a Customer field list
- HelpKnowledgeBase: remove stale "ready for pickup" SMS event, add company opt-in flow, customer opt-in requirement, compose modal for Admin/Manager, auto-send for ShopFloor, Send SMS button, and STOP opt-out behavior; remove SuperAdmin-only SMS Platform Setting content

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 22:32:55 -04:00
spouliot b1337d3b61 Update help docs and AI knowledge base for onboarding overhaul
GettingStarted.cshtml: updated Setup Wizard description from 10-step to
5-step, revised time estimate (5–10 min), added new "After the Wizard"
section explaining the guided activation first-workflow flow and the
progress widget (what it tracks, how the highlight works, when it
disappears, Admin-only visibility).

HelpKnowledgeBase.cs (AI assistant): updated Setup Wizard entry to 5 steps,
replaced old step list (removed steps 5–8, 10), updated new company
quick-start checklist to reference the 5-step wizard and the post-wizard
progress widget. Added new GUIDED ACTIVATION section covering the two
onboarding paths (Quote First / Job First), the Daily Board intro experience,
and how the banner auto-dismisses. Updated Common Workflows to reflect the
new onboarding order. Dashboard section now describes the progress widget
and its six tracked steps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 21:10:59 -04:00
spouliot 8aae30765f Onboarding overhaul: slim wizard, progress widget, guided activation UX
Setup Wizard: reduced from 10 steps to 5 (Company Info → QB Migration →
Pricing Defaults → Named Ovens → Notifications). Removed Doc Numbering,
Job Settings, Payment Terms, Pricing Tiers, and Team Members steps — these
all have sensible defaults and are accessible any time in Company Settings.
Wizard now completes in ~5 minutes instead of 15–20.

Dashboard progress widget (new): "Get the most out of your shop" checklist
appears for Company Admins after wizard completion. Tracks six post-setup
activation tasks with dynamic progress badge, motivating subtitle copy,
collapsed-state persistence via localStorage, and a full completion state
("Your shop is fully set up 🎉") that replaces the checklist at 100%.
The next recommended step is highlighted with a solid CTA button and a
subtle blue row tint. Completed steps show encouraging green subtext instead
of just "Done". Widget disappears from controller when AllDone would have
caused a silent vanish — now renders the completion state instead.

Guided activation (Daily Board): rewrote the BoardIntroStep callout to lead
with "This is your shop in real time" and a plain-English description of the
board's purpose. Added a separate InstructionText field to
GuidedActivationCalloutViewModel so the "Move this job to the next stage"
action prompt renders as a distinct bold line with an arrow icon rather than
being buried in the body copy. After the stage change, the confirmation
callout now reads "Nice — your workflow just updated" to reinforce what just
happened before prompting the invoice step.

All copy passes the "shop owner, not SaaS" test: no technical jargon,
benefit-driven descriptions, natural language throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 21:10:47 -04:00
spouliot 5631d1d57a Add WarningPermanent toast type and upgrade invoice failure notifications
Email delivery failures and PDF generation errors now show a permanent
warning/error toast that requires manual dismissal, so users cannot
accidentally miss critical action-blocking feedback.

- ToastHelper: WarningPermanent TempData key + Warning/WarningPermanent
  extension methods on both ITempDataDictionary and Controller
- SetNotificationResultToast: NotificationStatus.Failed now uses
  ToastWarningPermanent (previously auto-dismissed in 5 s)
- InvoicesController.Send: TempData["Warning"] → TempData["WarningPermanent"]
  when PDF generation or email dispatch fails
- InvoicesController.DownloadPdf: TempData["Error"] → TempData["ErrorPermanent"]
  with the actual exception message so root cause is visible
- _Layout.cshtml: WarningPermanent hidden div
- toast-notifications.js: WarningPermanent handler (timeOut: 0)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 16:02:16 -04:00
spouliot cad728ba66 Fix passkey login tracking, add email opt-out UI guards, and add Quick/Full quote mode toggle
- PasskeyController: set LastLoginDate on passkey sign-in so Company Health
  and audit pages show accurate last-login times (was always showing 'Never')
- Jobs/Index status modal: disable 'Notify customer' email toggle and show
  warning when customer has notifications turned off; CustomerNotifyByEmail
  added to JobListDto + JobProfile mapping + data-customer-notify attribute
- Quotes/Create: disable 'Send quote via email' checkbox with 'Notifications
  off' badge when selected customer has email opt-out; ViewBag.CustomerEmailOptOutIds
  added alongside existing CustomerTaxExemptIds pattern
- Quotes/Create: Quick Quote / Full Quote segmented toggle at top of form;
  hides non-essential fields (dates, notes, tags, oven, discount, photos) in
  Quick mode; selection persisted in localStorage
- InvoicesController Send action: improved error logging and user-facing
  warning when PDF generation or email dispatch fails after status is saved
- item-wizard.js: guard item restoration with try/catch; ensure writeHiddenFields
  always runs on form submit via capture-phase listener
- Help docs and AI knowledge base updated for all new features

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 13:32:34 -04:00
spouliot fa9fa76231 Document AI Catalog Price Check in knowledge base and help article
- HelpKnowledgeBase: full AI price check section (verdicts, confidence,
  category paths, run limit, how to use, common questions)
- Inventory help article: new 'AI Catalog Price Check' section with
  verdicts, step-by-step instructions, caveats, and on-page nav link

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 22:55:05 -04:00
spouliot 90a5a028ad Update docs and AI assistant for passkey biometric login
- HelpKnowledgeBase: passkey entry under USER PROFILE section with
  full how-it-works detail (setup, login flow, browser requirements,
  account-lock enforcement, per-device management)
- UserProfile help article: new Passkeys & Biometrics section between
  Two-Factor Auth and Appearance, with setup steps, login steps,
  browser compatibility note, and lost-device warning
- TOC nav link added to UserProfile article sidebar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 15:08:46 -04:00
spouliot 4f976b1332 Require auth on all work order QR codes and add top view QR
- StatusBump (GET + POST) now requires authentication; routes by job ID
  instead of anonymous ShopAccessCode GUID; records actual user name in
  status history instead of anonymous token string
- WorkOrder action generates a second "View Job" QR in the header linking
  to the authenticated Details page (for verifying specs and seeing catalog
  images on mobile); status bump QR updated to ID-based URL
- WorkOrder view: top QR added to header alongside job number; status bump
  label updated (removed "no login required" copy)
- StatusBump view: updated form routing from asp-route-token to asp-route-id
- HelpKnowledgeBase and Jobs help article updated with two-tier QR docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 13:27:43 -04:00
spouliot 00bf8a4cd0 Add catalog item images with thumbnail preview in wizard
Each catalog item now supports one optional image (jpg/jpeg/png/gif/webp,
max 10 MB). Uploading generates a 200x200 JPEG thumbnail automatically via
SixLabors.ImageSharp. Images are stored in Azure Blob Storage under a new
catalogimages container, keyed by {companyId}/catalog/{itemId}/.

- CatalogItem entity: ImagePath + ThumbnailPath (nullable string fields)
- Migration: AddCatalogItemImages applied
- ICatalogImageService / CatalogImageService: upload, thumbnail generation,
  delete; old blobs replaced atomically on re-upload
- CatalogItemsController: Create/Edit accept optional IFormFile image;
  Image(id, thumbnail) action serves blobs with [Authorize] so wizard users
  can load thumbnails without CanManageProducts policy
- Catalog index (_CategoryNode): 40x40 thumbnail (or placeholder icon)
  left of each item name
- Details view: image card in right column with click-to-full-size link
- Create/Edit views: file picker with live preview; Edit shows current
  thumbnail with Remove checkbox
- Wizard (item-wizard.js): thumbnails in product list with hover preview
  that follows the cursor (showCatalogPreview / moveCatalogPreview);
  fixed Bootstrap d-flex !important bug that broke the filter box by
  moving flex layout to an inner wrapper div

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 09:33:59 -04:00
spouliot 4153acf3aa Add facility overhead (rent + utilities) to operating costs and pricing engine
Adds MonthlyRent, MonthlyUtilities, and MonthlyBillableHours to CompanyOperatingCosts so fixed shop occupancy costs are recovered on every quote. The pricing engine converts these into a per-hour rate and applies it as a transparent "Facility Overhead" line between oven batch cost and shop supplies. UI added in Company Settings Operating Costs tab and Setup Wizard Step 3; migration AddFacilityOverheadFields applied. Help docs and AI knowledge base updated to cover the new fields and the revised quote pricing calculation order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 19:35:00 -04:00
spouliot 8d94013895 Add AI Quick Quote widget and inline customer reassignment
- New AI Quick Quote floating button: staff type a verbal description to
  get an instant price estimate for phone/walk-in customers; detected
  color names are fuzzy-matched against inventory for stock status;
  saves draft quote under a Walk-In / Phone customer with one click
- Inline customer change on Quote Details and Job Details: always-visible
  native select with inline confirmation banner (no TomSelect dependency);
  ChangeCustomer AJAX endpoints on QuotesController and JobsController
- Quote Edit page: customer dropdown is now editable (lock removed)
- Fix AutoMapper missing CatalogCategory -> UpdateCategoryDto mapping
  that caused a crash on the catalog category Edit page
- Help docs and AI knowledge base updated for all three features

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 17:02:03 -04:00
spouliot 63e12a9636 Initial commit 2026-04-23 21:38:24 -04:00