diff --git a/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs b/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs
index fa90a3a..82f871a 100644
--- a/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs
+++ b/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs
@@ -1031,10 +1031,13 @@ namespace Api.SeaHavenIndustries.Controllers
{
try
{
- var workOrder = await _db.workOrders.Include(w => w.Locations)
- .FirstOrDefaultAsync(w => w.Id == model.WorkOrderId);
- if (workOrder == null)
- return BadRequest(new Response { Status = "Error", Message = "Work order not found" });
+ var workOrders = await _db.workOrders.Include(w => w.Locations)
+ .Where(w => model.WorkOrderIds.Contains(w.Id))
+ .ToListAsync();
+ if (workOrders.Count == 0)
+ return BadRequest(new Response { Status = "Error", Message = "No work orders found" });
+
+ var primaryWO = workOrders.First();
var lastPO = await _db.Dispatches
.Where(d => d.PONumber != null)
@@ -1069,11 +1072,11 @@ namespace Api.SeaHavenIndustries.Controllers
var dispatchNumber = $"DSP-{nextDSP:D5}";
nextDSP++;
- var replyTo = $"wo-{workOrder.InternalWONumber}-{dispatchNumber}@int.seahaven.com";
+ var replyTo = $"wo-{primaryWO.InternalWONumber}-{dispatchNumber}@int.seahaven.com";
var dispatch = new Dispatch
{
- WorkOrderId = model.WorkOrderId,
+ WorkOrderId = primaryWO.Id,
VendorId = vendorId,
DispatchNumber = dispatchNumber,
PONumber = poNumber,
@@ -1082,50 +1085,60 @@ namespace Api.SeaHavenIndustries.Controllers
Status = "Sent",
ScheduledDate = model.ScheduledDate,
DispatchedAt = DateTime.UtcNow,
- ReplyToAddress = replyTo
+ ReplyToAddress = replyTo,
+ AcceptToken = Guid.NewGuid().ToString(),
+ DispatchWorkOrders = workOrders.Select(wo => new DispatchWorkOrder { WorkOrderId = wo.Id }).ToList()
};
- var subject = $"[WO-{workOrder.InternalWONumber}-{dispatchNumber}] {workOrder.WorkerOrderTitle}";
- var locationName = workOrder.Locations?.Name ?? "";
- var locationAddr = workOrder.Locations?.Address ?? "";
+ var woListHtml = string.Join("", workOrders.Select(wo =>
+ $"
| {wo.InternalWONumber} | " +
+ $"{wo.WorkerOrderTitle} | " +
+ $"{wo.Priority} | " +
+ $"{wo.DueDate?.ToString("yyyy-MM-dd") ?? "N/A"} |
"));
+
+ var locationName = primaryWO.Locations?.Name ?? "";
+ var locationAddr = primaryWO.Locations?.Address ?? "";
+ var subject = $"[{dispatchNumber}] {(workOrders.Count > 1 ? $"{workOrders.Count} Work Orders" : primaryWO.WorkerOrderTitle)} at {locationName}";
var html = $@"
- Work Order Dispatch
+ Work Order Dispatch — {dispatchNumber}
+ Location: {locationName} {locationAddr}
+ Vendor PO: {poNumber} NTE: ${model.NTEAmount?.ToString("F2") ?? "N/A"}
+ Work Orders
- | WO Number | {workOrder.InternalWONumber} |
- | Title | {workOrder.WorkerOrderTitle} |
- | Location | {locationName} {locationAddr} |
- | Priority | {workOrder.Priority} |
- | Due Date | {workOrder.DueDate?.ToString("yyyy-MM-dd") ?? "N/A"} |
- | Trade | {workOrder.Trade} |
- | Sub-Trade | {workOrder.SubTrade} |
- | Problem | {workOrder.Problem} |
- | NTE | ${model.NTEAmount?.ToString("F2") ?? "N/A"} |
- | Vendor PO | {poNumber} |
+
+ | WO # |
+ Title |
+ Priority |
+ Due Date |
+
+ {woListHtml}
Description
- {model.Description ?? workOrder.Description}
-
+ {model.Description ?? primaryWO.Description}
{senderName}
Sea Haven Industries
-
Reply to this email to communicate about this work order.
";
+
Reply to this email to communicate about this dispatch.
";
var emailSent = await _sendMessage.SendDispatchEmail(vendor.Email, subject, html, replyTo);
dispatch.EmailSent = emailSent;
_db.Dispatches.Add(dispatch);
- _db.WorkOrderAuditLogs.Add(new WorkOrderAuditLog
+ foreach (var wo in workOrders)
{
- WorkOrderId = model.WorkOrderId,
- UserId = userId,
- FieldName = "Dispatch",
- OldValue = "",
- NewValue = $"{vendor.CompanyName} ({poNumber})",
- Action = "dispatch",
- CreatedAt = DateTime.UtcNow
- });
+ _db.WorkOrderAuditLogs.Add(new WorkOrderAuditLog
+ {
+ WorkOrderId = wo.Id,
+ UserId = userId,
+ FieldName = "Dispatch",
+ OldValue = "",
+ NewValue = $"{vendor.CompanyName} ({dispatchNumber})",
+ Action = "dispatch",
+ CreatedAt = DateTime.UtcNow
+ });
+ }
- dispatches.Add(new { dispatch.Id, dispatchNumber, poNumber, vendorName = vendor.CompanyName, dispatch.Status });
+ dispatches.Add(new { dispatch.Id, dispatchNumber, poNumber, vendorName = vendor.CompanyName, dispatch.Status, workOrderCount = workOrders.Count });
}
await _db.SaveChangesAsync();
@@ -1140,8 +1153,21 @@ namespace Api.SeaHavenIndustries.Controllers
[HttpGet("GetDispatches/{workOrderId}")]
public async Task GetDispatches(int workOrderId)
{
- var data = await _db.Dispatches
+ var dispatchIds = await _db.DispatchWorkOrders
+ .Where(dwo => dwo.WorkOrderId == workOrderId)
+ .Select(dwo => dwo.DispatchId)
+ .Distinct()
+ .ToListAsync();
+
+ var directIds = await _db.Dispatches
.Where(d => d.WorkOrderId == workOrderId)
+ .Select(d => d.Id)
+ .ToListAsync();
+
+ var allIds = dispatchIds.Union(directIds).Distinct().ToList();
+
+ var data = await _db.Dispatches
+ .Where(d => allIds.Contains(d.Id))
.Include(d => d.Vendor)
.OrderByDescending(d => d.DispatchedAt)
.Select(d => new
@@ -1184,11 +1210,19 @@ namespace Api.SeaHavenIndustries.Controllers
x.DispatchedAt,
x.EmailSent,
x.WorkOrderId,
+ x.AcknowledgedAt,
woNumber = x.WorkOrder != null ? x.WorkOrder.InternalWONumber : "",
woTitle = x.WorkOrder != null ? x.WorkOrder.WorkerOrderTitle : "",
vendorName = x.Vendor != null ? x.Vendor.CompanyName : "",
vendorEmail = x.Vendor != null ? x.Vendor.Email : "",
vendorId = x.VendorId,
+ workOrders = _db.DispatchWorkOrders
+ .Where(dwo => dwo.DispatchId == x.Id)
+ .Select(dwo => new {
+ dwo.WorkOrderId,
+ woNumber = dwo.WorkOrder != null ? dwo.WorkOrder.InternalWONumber : "",
+ woTitle = dwo.WorkOrder != null ? dwo.WorkOrder.WorkerOrderTitle : ""
+ }).ToList(),
comments = _db.Comments
.Where(c => c.DispatchId == x.Id)
.OrderBy(c => c.CreatedDate)
@@ -1223,7 +1257,7 @@ namespace Api.SeaHavenIndustries.Controllers
{
_db.WorkOrderAuditLogs.Add(new WorkOrderAuditLog
{
- WorkOrderId = dispatch.WorkOrderId,
+ WorkOrderId = dispatch.WorkOrderId ?? 0,
UserId = userId,
FieldName = $"Dispatch {dispatch.DispatchNumber} Status",
OldValue = dispatch.Status ?? "",
diff --git a/Api.SeaHavenIndustries/DTOs/Dispatch_DTO.cs b/Api.SeaHavenIndustries/DTOs/Dispatch_DTO.cs
index 649150e..71a37ee 100644
--- a/Api.SeaHavenIndustries/DTOs/Dispatch_DTO.cs
+++ b/Api.SeaHavenIndustries/DTOs/Dispatch_DTO.cs
@@ -2,7 +2,7 @@ namespace Api.SeaHavenIndustries.DTOs
{
public class Dispatch_DTO
{
- public int WorkOrderId { get; set; }
+ public List WorkOrderIds { get; set; } = new();
public List VendorIds { get; set; } = new();
public decimal? NTEAmount { get; set; }
public DateTime? ScheduledDate { get; set; }
diff --git a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs
index 47ac9e8..043a732 100644
--- a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs
+++ b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs
@@ -41,6 +41,7 @@ namespace Data.SeaHavenIndustries
public DbSet DropdownOptions { get; set; }
public DbSet Vendors { get; set; }
public DbSet Dispatches { get; set; }
+ public DbSet DispatchWorkOrders { get; set; }
public DbSet TaskListTemplates { get; set; }
public DbSet TaskListTemplateItems { get; set; }
diff --git a/Data.SeaHavenIndustries/Migrations/20260417190743_MultiWODispatch.Designer.cs b/Data.SeaHavenIndustries/Migrations/20260417190743_MultiWODispatch.Designer.cs
new file mode 100644
index 0000000..3b4ebe5
--- /dev/null
+++ b/Data.SeaHavenIndustries/Migrations/20260417190743_MultiWODispatch.Designer.cs
@@ -0,0 +1,2657 @@
+//
+using System;
+using Data.SeaHavenIndustries;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Data.SeaHavenIndustries.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20260417190743_MultiWODispatch")]
+ partial class MultiWODispatch
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.8")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Accounts", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("About")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("CurrencyCode")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Email")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FacebookUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Importance")
+ .HasColumnType("int");
+
+ b.Property("IndustryId")
+ .HasColumnType("int");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("LinkedInUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("OwnerEmployeeId")
+ .HasColumnType("int");
+
+ b.Property("Phone")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PrivacySetting")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ServiceInstructions")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Tags")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TerritoryId")
+ .HasColumnType("int");
+
+ b.Property("TimeZone")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwitterUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Type")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Website")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Accounts");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Addresses", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AccountId")
+ .HasColumnType("int");
+
+ b.Property("Address1")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Address2")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AddressType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("City")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ContactId")
+ .HasColumnType("int");
+
+ b.Property("Country")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("County")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("State")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Zip")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AccountId");
+
+ b.HasIndex("ContactId");
+
+ b.ToTable("Addresses");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("int");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Contact")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("FirstName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Locations")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("bit");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumberConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("SecurityStamp")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwoFactorEnabled")
+ .HasColumnType("bit");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.Property("UniqueName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserImage")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex")
+ .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+ b.ToTable("AspNetUsers", (string)null);
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Assets", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AccountId")
+ .HasColumnType("int");
+
+ b.Property("AssetCode")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("LocationId")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AccountId");
+
+ b.HasIndex("LocationId");
+
+ b.ToTable("Assets");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Category", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Categories");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Comments", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CommentType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Commenter")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Commenttext")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("DispatchId")
+ .HasColumnType("int");
+
+ b.Property("Documents")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExternalCommentId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("RecordType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("WorkerOrderId")
+ .HasColumnType("int");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DispatchId");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("WorkerOrderId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.ContactDetails", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("About")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ContactId")
+ .HasColumnType("int");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateOfBirth")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("FacebookUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Gender")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("LinkedInUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PrivacySetting")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Tags")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Territory")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwitterUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ContactId");
+
+ b.ToTable("ContactDetails");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Contacts", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AccountId")
+ .HasColumnType("int");
+
+ b.Property("Address1")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Address2")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("City")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ContactType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Email")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FacebookUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("LastName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LinkedInUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LocationId")
+ .HasColumnType("int");
+
+ b.Property("MiddleName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Owner")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("State")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Title")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwitterUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Zip")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AccountId");
+
+ b.HasIndex("LocationId");
+
+ b.ToTable("Contacts");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Department", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Departments");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Dispatch", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AcceptToken")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AcknowledgedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CompletedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DeleterUserId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DispatchNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DispatchedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("EmailSent")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("NTEAmount")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("PONumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ReplyToAddress")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ScheduledDate")
+ .HasColumnType("datetime2");
+
+ b.Property("Status")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("VendorId")
+ .HasColumnType("int");
+
+ b.Property("WorkOrderId")
+ .HasColumnType("int");
+
+ b.Property("createdby")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("VendorId");
+
+ b.HasIndex("WorkOrderId");
+
+ b.ToTable("Dispatches");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.DispatchWorkOrder", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("DispatchId")
+ .HasColumnType("int");
+
+ b.Property("WorkOrderId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DispatchId");
+
+ b.HasIndex("WorkOrderId");
+
+ b.ToTable("DispatchWorkOrders");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.DropdownOption", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Category")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("ParentValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SortOrder")
+ .HasColumnType("int");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("DropdownOptions");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.Employee", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("About")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CanChangeProviderNumber")
+ .HasColumnType("bit");
+
+ b.Property("ConfirmUserName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateOfBirth")
+ .HasColumnType("datetime2");
+
+ b.Property("DepartmentId")
+ .HasColumnType("int");
+
+ b.Property("EmployeeNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FacebookUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Gender")
+ .HasColumnType("int");
+
+ b.Property("HireDate")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("JobTitleId")
+ .HasColumnType("int");
+
+ b.Property("LastLogin")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("LastModifierUserId")
+ .HasColumnType("int");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LinkedInUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("MiddleName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PermissionGroupId")
+ .HasColumnType("int");
+
+ b.Property("RegionId")
+ .HasColumnType("int");
+
+ b.Property("SMSAddress")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Status")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TimeZone")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwitterUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Website")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DepartmentId");
+
+ b.HasIndex("JobTitleId");
+
+ b.HasIndex("RegionId");
+
+ b.ToTable("Employees");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.EmployeeAddress", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("City")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CountryCode")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CountyId")
+ .HasColumnType("int");
+
+ b.Property("EmployeeId")
+ .HasColumnType("int");
+
+ b.Property("StateCode")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Street")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("StreetLineTwo")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Zip")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EmployeeId")
+ .IsUnique();
+
+ b.ToTable("EmployeeAddresses");
+ });
+
+ modelBuilder.Entity("Data.SeaHavenIndustries.EmployeeEmail", b =>
+ {
+ b.Property