@model PowderCoating.Application.DTOs.Company.CompanySettingsDto @{ ViewData["Title"] = "Company Settings"; ViewData["PageIcon"] = "bi-building"; } @section Styles { }
@Html.AntiForgeryToken()
Company Information
Affects how financial reports (P&L, Balance Sheet, Cash Flow) present data. Switching does not re-post historical transactions.
Period Locking
@{ var lockThrough = ViewBag.BookLockedThrough as DateTime?; } @if (lockThrough.HasValue) {
@Html.AntiForgeryToken()
Entries dated on or before this date are blocked.
} else {
No period lock set — all dates are open.
}
@Html.AntiForgeryToken()
Prevents backdating any GL entry (bills, JEs) into closed periods.
Company Logo
@if (Model.HasLogo) { Company Logo } else {

No logo uploaded

}
@if (Model.HasLogo) { }
Allowed formats: JPG, PNG, GIF, WEBP
Maximum size: 10 MB
Operating Costs Configuration

Configure your operating costs for accurate job quoting calculations.

Rates & Costs
$ /hr
%
Labor % for each coat after the first
$ /sq ft
Default when no inventory item selected
%
%
Applied to materials/labor
Facility Overhead
$ /mo
$ /mo
Electricity, gas, water, internet
hrs
Typical: 160 hrs (4 wks × 40 hrs)
Added to quotes per estimated labor hour
Equipment Operating Costs
$ /hr
Used when no specific oven is selected on a quote.
$ /hr
$ /hr
Role-Based Labor Cost Rates

Used for job costing only — not shown to customers. Leave blank to use the Standard Labor Rate.

Role Cost Rate / hr Fallback if blank
Loading...
Pricing & Profit
@{ var currentPricingMode = (int)(Model.OperatingCosts?.PricingMode ?? PowderCoating.Core.Enums.PricingMode.MarkupOnMaterial); }
%
Added on top of material costs
%
% of selling price kept as profit
$
Minimum charge for any job/quote
Rush Charges
%
Percentage of subtotal added for rush jobs
$
Fixed dollar amount added for rush jobs
Part Complexity Multipliers

Percentage added to the calculated item price based on part intricacy. Applied to calculated items only (not catalog, generic, or labor items).

%
No added complexity
%
Some detail work
%
Intricate parts
%
Highly detailed/difficult
@if (Model.AiPhotoQuotesEnabled) {
AI Photo Quote Profile

Tell the AI about your shop so it produces better estimates for your specific work and pricing style.

Plain language — write it as if briefing a new estimator on your shop. @(Model.OperatingCosts?.AiContextProfile?.Length ?? 0)/2000
How AI Learning Works

Layer 1 — Pricing config: Your operating costs (labor, equipment, markup) are always injected automatically.

Layer 2 — Your shop profile: The description you write here is added to every AI analysis, guiding estimates toward your typical work.

Layer 3 — Automatic learning: Each time your team accepts an AI estimate without changing it, that item is silently added as a calibration example. The AI improves on its own the more you use it.

}
@{ var costs = Model.OperatingCosts; var tierVal = (int)(costs?.ShopCapabilityTier ?? PowderCoating.Core.Enums.ShopCapabilityTier.Small); }
Shop Profile

Tell the quoting engine what size shop you're running. This gives the AI context about your capacity when generating estimates and is used as a fallback when specific equipment rates aren't configured.

Used by the AI when estimating job complexity and throughput.
Named Blast Setups

Define each blast rig your shop uses (cabinet, pressure pot, blast room, etc.). When quoting, workers pick the rig they'll actually use so time estimates are accurate. Mark one as the Default to pre-select it in AI Photo Quotes.

Name Type CFM Derived Rate Status Actions
Named Ovens

Add each oven with its rate and capacity. The Oven Scheduler uses capacity and cycle time to plan batches; quotes use the per-hour rate. If no specific oven is selected on a quote, the Default Oven Rate from Operating Costs is used.

Label Rate/hr Capacity (sqft) Order Status Actions
Application Defaults

Default values used when creating new records.

Measurement System
When enabled, measurements throughout the application will use the metric system (square meters, kilograms) instead of imperial (square feet, pounds). This affects surface area calculations, inventory coverage, and all measurement displays.
Number Prefixes
Job & Workflow Defaults

Configure default behavior for jobs and the production workflow.

Customer Options
Notifications & Alerts

Control which events trigger email notifications and alert thresholds.

@if (ViewBag.SmsEnabled == true) {
SMS Notifications
@if (Model.SmsDisabledByAdmin) {
SMS has been disabled by an administrator. Contact support to re-enable.
} else if (!Model.AllowSms) {
SMS notifications are not included in your current plan. Upgrade to Pro or Enterprise to enable customer SMS alerts.
} else {

When enabled, customers who have given SMS consent will receive text alerts for job status changes (e.g. ready for pickup).

@if (!Model.HasCurrentSmsAgreement && !Model.SmsEnabled) {
You'll need to accept the SMS terms of service the first time you enable this.
} }
}
Email Sender
Leave blank to use the default configured in system settings.
The name customers see in their email client.
Notify On
Alert Thresholds
Automated Payment Reminders
Sends reminder emails to customers with overdue invoices.
Enter the number of days past the due date to send each reminder (e.g. 7,14,30).
Notification Templates
@foreach (var tmpl in Model.NotificationTemplates.Where(t => t.IsEmail || ViewBag.SmsEnabled == true)) { }
Template Channel Last Modified Actions
@tmpl.DisplayName @if (tmpl.IsEmail) { Email } else { SMS } @(tmpl.UpdatedAt?.ToString("MMM d, yyyy h:mm tt") ?? "Using defaults")
Data Retention

Define how long records are kept before archiving or deletion.

Record Retention
Auto-Maintenance
Archive completed jobs after this many days
Keep soft-deleted records for this many days
Manage Data Lookups

Customize dropdown values and workflow statuses for your company

0 Job Statuses
Display Name Status Code Color Category Flags Usage Actions
Loading...
0 Job Priorities
Display Name Priority Code Color Usage Actions
Loading...
0 Quote Statuses
Display Name Status Code Color Business Flags Usage Actions
Loading...
0 Appointment Types
Display Name Type Code Color Requires Job Active Usage Actions
Loading...
Loading appointment types...
0 Inventory Categories
Display Name Category Code Description Usage Actions
Loading...
0 Prep Services
Service Name Description Status Actions
Loading...

Customise how your printable and emailed quote PDFs look. After saving, open any quote and click Download PDF to preview the result.

Branding
@{ var qtColor = string.IsNullOrWhiteSpace(Model.Preferences?.QtAccentColor) ? "#374151" : Model.Preferences!.QtAccentColor; }
@foreach (var preset in new[] { ("#374151","Dark Slate"), ("#1e3a5f","Navy"), ("#14532d","Forest Green"), ("#7f1d1d","Burgundy"), ("#134e4a","Dark Teal"), ("#1f2937","Charcoal") }) { }
Used for section headings and company name text when no logo is uploaded.

Default Terms & Conditions
Automatically filled into the Terms field whenever you create a new quote. You can still edit it per quote before sending.

Page Footer Note
Appears at the bottom of every PDF page alongside the page number.

Customise how your printable and emailed invoice PDFs look. After saving, open any invoice and click Download PDF to preview the result.

Branding
@{ var inColor = string.IsNullOrWhiteSpace(Model.Preferences?.InAccentColor) ? "#374151" : Model.Preferences!.InAccentColor; }
@foreach (var preset in new[] { ("#374151","Dark Slate"), ("#1e3a5f","Navy"), ("#14532d","Forest Green"), ("#7f1d1d","Burgundy"), ("#134e4a","Dark Teal"), ("#1f2937","Charcoal") }) { }
Used for section headings and company name text when no logo is uploaded.

Default Payment Terms
Appears in the Payment Terms section of the invoice PDF when no per-invoice terms are set.

Page Footer Note
Appears at the bottom of every PDF page alongside the page number.

Customise the blank work order form your shop prints for walk-in or drop-off customers. After saving, click Print Blank Work Order from the Jobs page to preview.

Branding
@{ var woColor = string.IsNullOrWhiteSpace(Model.Preferences?.WoAccentColor) ? "#374151" : Model.Preferences!.WoAccentColor; }
@foreach (var preset in new[] { ("#374151","Dark Slate"), ("#1e3a5f","Navy"), ("#14532d","Forest Green"), ("#7f1d1d","Burgundy"), ("#134e4a","Dark Teal"), ("#1f2937","Charcoal") }) { }
Used for header rows on the work order table.

Terms & Conditions
Printed in italic at the bottom of every blank work order. Supports plain text — use * or ** for visual emphasis.
Preview Work Order
@if (Model.AllowOnlinePayments) {
Online Payments (Stripe)
@* ── Stripe Connect status ── *@ @if (!(bool)ViewBag.StripeConnectConfigured) {
Stripe Connect is not configured.

A platform administrator must set Stripe:ConnectClientId in appsettings.json before companies can connect their Stripe accounts. The value starts with ca_ and can be found in your Stripe Dashboard → Connect → Settings.

} else if (Model.StripeConnectStatus == PowderCoating.Core.Enums.StripeConnectStatus.Active) {
Stripe account connected.
Account ID: @Model.StripeAccountId
} else {
No Stripe account connected.

Connect your Stripe account to start accepting online payments from customers.

Connect with Stripe
} @* ── Surcharge settings (only editable when connected) ── *@
Online Payment Fee (Surcharge)

You may pass the Stripe transaction cost to customers as a convenience fee. Surcharges are capped at 3% per Visa/Mastercard network rules and may not apply to debit card transactions in all states.

%
Max 3% for percentage type.
}
Customer Intake Kiosk
Intake Output

When a customer completes the intake form, what should be created in the system?

Create a Quote

A draft quote is created and reviewed by staff before work begins. Best for shops that price after seeing the parts.

Create a Job

A job is created immediately on submission. Best for shops that price on the spot and want the work order ready right away.

@await Html.PartialAsync("_LookupModals")
@section Scripts { }