Files
PowderCoatingLogix/src/PowderCoating.Application/DTOs/Company/CompanyPreferencesDtos.cs
T
spouliot d5ad9fa073 Add KioskIntakeOutput company setting and fix kiosk submission bugs
- New CompanyPreferences.KioskIntakeOutput setting ("Quote" default / "Job"): controls
  what the kiosk creates on submission; shown as a card-style radio toggle in
  Company Settings → Kiosk tab
- KioskSession.LinkedQuoteId added so quote-first sessions link back to the draft quote
- Migration AddKioskIntakeOutputSetting applies both schema changes
- ProcessSubmissionAsync branches on setting: creates Draft quote (quote-first) or
  Pending job (job-first); save order fixed (CompleteAsync before using DB-assigned Id as FK)
- Terms.cshtml pricing paragraph is now dynamic: "subject to formal quote" for Quote mode,
  "team member will reach out about pricing" for Job mode
- Customer Intakes list: "View Quote" button appears when LinkedQuoteId is set
- Notification label fixed: Remote sessions now say "Remote Intake", not "Walk-in Intake"
- Inactivity reset shortened to 45 s on intake steps
- Signature pad: hosted locally (no CDN), canvas resize deferred via requestAnimationFrame
- AI photo upload: client-side compression to ≤1200px + AbortController 120 s timeout
- Help article and AI knowledge base updated with kiosk feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 22:35:37 -04:00

150 lines
6.1 KiB
C#

using System.ComponentModel.DataAnnotations;
namespace PowderCoating.Application.DTOs.Company;
public class CompanyPreferencesDto
{
public int Id { get; set; }
public int CompanyId { get; set; }
// Application Defaults
public string DefaultCurrency { get; set; } = "USD";
public string DefaultDateFormat { get; set; } = "MM/dd/yyyy";
public string DefaultTimeFormat { get; set; } = "12h";
public string DefaultPaymentTerms { get; set; } = "Net 30";
public int DefaultQuoteValidityDays { get; set; } = 30;
public string QuoteNumberPrefix { get; set; } = "QT";
public string JobNumberPrefix { get; set; } = "JOB";
public bool UseMetricSystem { get; set; } = false;
// Job / Workflow
public string DefaultJobPriority { get; set; } = "Normal";
public bool RequireCustomerPO { get; set; }
public bool AllowCustomerApproval { get; set; } = true;
public int DefaultTurnaroundDays { get; set; } = 7;
// Email Sender Identity
public string? EmailFromAddress { get; set; }
public string? EmailFromName { get; set; }
// Notifications
public bool EmailNotificationsEnabled { get; set; } = true;
public bool NotifyOnNewJob { get; set; } = true;
public bool NotifyOnNewQuote { get; set; } = true;
public bool NotifyOnJobStatusChange { get; set; } = true;
public bool NotifyOnQuoteApproval { get; set; } = true;
public bool NotifyOnPaymentReceived { get; set; } = true;
public int QuoteExpiryWarningDays { get; set; } = 3;
public int DueDateWarningDays { get; set; } = 2;
public int MaintenanceAlertDays { get; set; } = 7;
public bool PaymentRemindersEnabled { get; set; } = false;
public string PaymentReminderDays { get; set; } = "7,14,30";
// Data Retention
public int QuoteRetentionYears { get; set; } = 7;
public int JobRetentionYears { get; set; } = 7;
public int LogRetentionDays { get; set; } = 90;
public int AutoArchiveJobsDays { get; set; } = 365;
public int DeletedRecordRetentionDays { get; set; } = 30;
// Quote PDF Template
public string QtAccentColor { get; set; } = "#374151";
public string? QtDefaultTerms { get; set; }
public string? QtFooterNote { get; set; }
// Invoice PDF Template
public string InAccentColor { get; set; } = "#374151";
public string? InDefaultTerms { get; set; }
public string? InFooterNote { get; set; }
// Blank Work Order PDF Template
public string WoAccentColor { get; set; } = "#374151";
public string? WoTerms { get; set; }
// Kiosk settings
public string KioskIntakeOutput { get; set; } = "Quote";
}
public class UpdateAppDefaultsDto
{
[Required, StringLength(3)] public string DefaultCurrency { get; set; } = "USD";
[Required, StringLength(20)] public string DefaultDateFormat { get; set; } = "MM/dd/yyyy";
[Required] public string DefaultTimeFormat { get; set; } = "12h";
[Required, StringLength(50)] public string DefaultPaymentTerms { get; set; } = "Net 30";
[Range(1, 365)] public int DefaultQuoteValidityDays { get; set; } = 30;
[Required, StringLength(10)] public string QuoteNumberPrefix { get; set; } = "QT";
[Required, StringLength(10)] public string JobNumberPrefix { get; set; } = "JOB";
public bool UseMetricSystem { get; set; } = false;
}
public class UpdateJobDefaultsDto
{
[Required] public string DefaultJobPriority { get; set; } = "Normal";
public bool RequireCustomerPO { get; set; }
public bool AllowCustomerApproval { get; set; }
[Range(1, 365)] public int DefaultTurnaroundDays { get; set; } = 7;
}
public class UpdateNotificationsDto
{
[EmailAddress(ErrorMessage = "Invalid email address format.")]
[StringLength(100)]
[Display(Name = "From Email Address")]
public string? EmailFromAddress { get; set; }
[StringLength(100)]
[Display(Name = "From Display Name")]
public string? EmailFromName { get; set; }
public bool EmailNotificationsEnabled { get; set; }
public bool NotifyOnNewJob { get; set; }
public bool NotifyOnNewQuote { get; set; }
public bool NotifyOnJobStatusChange { get; set; }
public bool NotifyOnQuoteApproval { get; set; }
public bool NotifyOnPaymentReceived { get; set; }
[Range(0, 30)] public int QuoteExpiryWarningDays { get; set; } = 3;
[Range(0, 30)] public int DueDateWarningDays { get; set; } = 2;
[Range(0, 90)] public int MaintenanceAlertDays { get; set; } = 7;
public bool PaymentRemindersEnabled { get; set; } = false;
[StringLength(50)] public string PaymentReminderDays { get; set; } = "7,14,30";
}
public class UpdateDataRetentionDto
{
[Range(1, 99)] public int QuoteRetentionYears { get; set; } = 7;
[Range(1, 99)] public int JobRetentionYears { get; set; } = 7;
[Range(30, 3650)] public int LogRetentionDays { get; set; } = 90;
[Range(30, 3650)] public int AutoArchiveJobsDays { get; set; } = 365;
[Range(7, 365)] public int DeletedRecordRetentionDays { get; set; } = 30;
}
public class UpdateQuoteTemplateDto
{
[RegularExpression(@"^#[0-9A-Fa-f]{6}$", ErrorMessage = "Accent color must be a valid hex color (e.g. #374151)")]
public string QtAccentColor { get; set; } = "#374151";
[StringLength(3000)] public string? QtDefaultTerms { get; set; }
[StringLength(200)] public string? QtFooterNote { get; set; }
}
public class UpdateInvoiceTemplateDto
{
[RegularExpression(@"^#[0-9A-Fa-f]{6}$", ErrorMessage = "Accent color must be a valid hex color (e.g. #374151)")]
public string InAccentColor { get; set; } = "#374151";
[StringLength(3000)] public string? InDefaultTerms { get; set; }
[StringLength(200)] public string? InFooterNote { get; set; }
}
public class UpdateWorkOrderTemplateDto
{
[RegularExpression(@"^#[0-9A-Fa-f]{6}$", ErrorMessage = "Accent color must be a valid hex color (e.g. #374151)")]
public string WoAccentColor { get; set; } = "#374151";
[StringLength(2000)] public string? WoTerms { get; set; }
}
public class UpdateKioskSettingsDto
{
/// <summary>"Quote" (default) or "Job" — what the kiosk creates on submission.</summary>
[Required]
public string KioskIntakeOutput { get; set; } = "Quote";
}