mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 20:03:11 +00:00
Org-wide create no longer depends on customer name. POST /workorders/board requires locationId and stamps WorkOrder.AccountId from Location.AccountId.
125 lines
4.7 KiB
C#
125 lines
4.7 KiB
C#
using FluentValidation;
|
|
using Data.SeaHavenIndustries.Enums;
|
|
using SeaHaven.Services.DTOs;
|
|
|
|
namespace SeaHaven.Services.Validation
|
|
{
|
|
public interface IWorkOrderBoardCreateValidation : IValidator<WorkOrderBoardCreateRequestDto>
|
|
{
|
|
}
|
|
|
|
public class WorkOrderBoardCreateValidation : AbstractValidator<WorkOrderBoardCreateRequestDto>, IWorkOrderBoardCreateValidation
|
|
{
|
|
public WorkOrderBoardCreateValidation()
|
|
{
|
|
RuleFor(x => x.WorkOrderType)
|
|
.IsInEnum().WithMessage("workOrderType is required and must be a valid value.")
|
|
.Must(t => t != WorkOrderType.AddOn)
|
|
.WithMessage("workOrderType AddOn is not allowed on create; use isAddOn with a real type.");
|
|
|
|
RuleFor(x => x.SiteCode)
|
|
.NotEmpty().WithMessage("siteCode is required.")
|
|
.MaximumLength(32);
|
|
|
|
RuleFor(x => x.TargetWeek)
|
|
.NotNull().WithMessage("targetWeek is required when scheduleWeekOnly is true.")
|
|
.When(x => x.ScheduleWeekOnly == true);
|
|
|
|
RuleFor(x => x.Description)
|
|
.MaximumLength(2000)
|
|
.When(x => !string.IsNullOrEmpty(x.Description));
|
|
|
|
RuleFor(x => x.Trade)
|
|
.MaximumLength(128)
|
|
.When(x => !string.IsNullOrEmpty(x.Trade));
|
|
|
|
RuleFor(x => x.PrimaryService)
|
|
.MaximumLength(128)
|
|
.When(x => !string.IsNullOrEmpty(x.PrimaryService));
|
|
|
|
RuleFor(x => x.ServiceNotes)
|
|
.MaximumLength(4000)
|
|
.When(x => !string.IsNullOrEmpty(x.ServiceNotes));
|
|
|
|
RuleFor(x => x.PocName)
|
|
.MaximumLength(200)
|
|
.When(x => !string.IsNullOrEmpty(x.PocName));
|
|
|
|
RuleFor(x => x.PocPhone)
|
|
.MaximumLength(50)
|
|
.When(x => !string.IsNullOrEmpty(x.PocPhone));
|
|
|
|
RuleFor(x => x.PocNotes)
|
|
.MaximumLength(2000)
|
|
.When(x => !string.IsNullOrEmpty(x.PocNotes));
|
|
|
|
RuleFor(x => x.TechPhone)
|
|
.MaximumLength(50)
|
|
.When(x => !string.IsNullOrEmpty(x.TechPhone));
|
|
|
|
RuleFor(x => x.VendorNotes)
|
|
.MaximumLength(2000)
|
|
.When(x => !string.IsNullOrEmpty(x.VendorNotes));
|
|
|
|
RuleFor(x => x.LocationId)
|
|
.NotNull().WithMessage("locationId is required.")
|
|
.GreaterThan(0).WithMessage("locationId is required.");
|
|
|
|
RuleFor(x => x.VendorId)
|
|
.GreaterThan(0)
|
|
.When(x => x.VendorId.HasValue);
|
|
|
|
RuleFor(x => x.PocContactId)
|
|
.GreaterThan(0)
|
|
.When(x => x.PocContactId.HasValue);
|
|
|
|
RuleFor(x => x)
|
|
.Must(HasPrimaryWhenExtras)
|
|
.WithMessage("primaryService (or trade) is required when extraServices is provided.")
|
|
.WithName("extraServices");
|
|
|
|
RuleForEach(x => x.ExtraServices)
|
|
.MaximumLength(128)
|
|
.When(x => x.ExtraServices != null);
|
|
|
|
RuleForEach(x => x.AdditionalContacts)
|
|
.ChildRules(contact =>
|
|
{
|
|
contact.RuleFor(c => c.Name)
|
|
.MaximumLength(200)
|
|
.When(c => !string.IsNullOrEmpty(c.Name));
|
|
contact.RuleFor(c => c.Phone)
|
|
.MaximumLength(50)
|
|
.When(c => !string.IsNullOrEmpty(c.Phone));
|
|
contact.RuleFor(c => c.Notes)
|
|
.MaximumLength(2000)
|
|
.When(c => !string.IsNullOrEmpty(c.Notes));
|
|
contact.RuleFor(c => c)
|
|
.Must(HasNameAndPhoneWhenPresent)
|
|
.WithMessage("Each additional contact must include a name and phone.");
|
|
})
|
|
.When(x => x.AdditionalContacts != null);
|
|
}
|
|
|
|
private static bool HasPrimaryWhenExtras(WorkOrderBoardCreateRequestDto request)
|
|
{
|
|
var hasExtras = request.ExtraServices != null
|
|
&& request.ExtraServices.Any(s => !string.IsNullOrWhiteSpace(s));
|
|
if (!hasExtras)
|
|
return true;
|
|
|
|
return !string.IsNullOrWhiteSpace(request.PrimaryService)
|
|
|| !string.IsNullOrWhiteSpace(request.Trade);
|
|
}
|
|
|
|
private static bool HasNameAndPhoneWhenPresent(WorkOrderAdditionalContactDto contact)
|
|
{
|
|
var hasName = !string.IsNullOrWhiteSpace(contact.Name);
|
|
var hasPhone = !string.IsNullOrWhiteSpace(contact.Phone);
|
|
if (!hasName && !hasPhone)
|
|
return true;
|
|
|
|
return hasName && hasPhone;
|
|
}
|
|
}
|
|
}
|