mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 07:13:12 +00:00
Add multi-WO dispatch support with junction table
- DispatchWorkOrder junction table for 1:N dispatch-to-WO relationship - Make Dispatch.WorkOrderId nullable (backward compat) - Add AcceptToken and AcknowledgedAt to Dispatch model - Dispatch_DTO accepts WorkOrderIds array - DispatchToVendor creates junction rows, email lists all WOs in table - GetDispatches queries both junction table and direct FK - GetDispatchById includes workOrders list from junction table - Migration with DispatchWorkOrder table
This commit is contained in:
parent
1f4bd12cd7
commit
be190836a4
8 changed files with 2895 additions and 40 deletions
|
|
@ -1031,10 +1031,13 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var workOrder = await _db.workOrders.Include(w => w.Locations)
|
var workOrders = await _db.workOrders.Include(w => w.Locations)
|
||||||
.FirstOrDefaultAsync(w => w.Id == model.WorkOrderId);
|
.Where(w => model.WorkOrderIds.Contains(w.Id))
|
||||||
if (workOrder == null)
|
.ToListAsync();
|
||||||
return BadRequest(new Response { Status = "Error", Message = "Work order not found" });
|
if (workOrders.Count == 0)
|
||||||
|
return BadRequest(new Response { Status = "Error", Message = "No work orders found" });
|
||||||
|
|
||||||
|
var primaryWO = workOrders.First();
|
||||||
|
|
||||||
var lastPO = await _db.Dispatches
|
var lastPO = await _db.Dispatches
|
||||||
.Where(d => d.PONumber != null)
|
.Where(d => d.PONumber != null)
|
||||||
|
|
@ -1069,11 +1072,11 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
var dispatchNumber = $"DSP-{nextDSP:D5}";
|
var dispatchNumber = $"DSP-{nextDSP:D5}";
|
||||||
nextDSP++;
|
nextDSP++;
|
||||||
|
|
||||||
var replyTo = $"wo-{workOrder.InternalWONumber}-{dispatchNumber}@int.seahaven.com";
|
var replyTo = $"wo-{primaryWO.InternalWONumber}-{dispatchNumber}@int.seahaven.com";
|
||||||
|
|
||||||
var dispatch = new Dispatch
|
var dispatch = new Dispatch
|
||||||
{
|
{
|
||||||
WorkOrderId = model.WorkOrderId,
|
WorkOrderId = primaryWO.Id,
|
||||||
VendorId = vendorId,
|
VendorId = vendorId,
|
||||||
DispatchNumber = dispatchNumber,
|
DispatchNumber = dispatchNumber,
|
||||||
PONumber = poNumber,
|
PONumber = poNumber,
|
||||||
|
|
@ -1082,50 +1085,60 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
Status = "Sent",
|
Status = "Sent",
|
||||||
ScheduledDate = model.ScheduledDate,
|
ScheduledDate = model.ScheduledDate,
|
||||||
DispatchedAt = DateTime.UtcNow,
|
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 woListHtml = string.Join("", workOrders.Select(wo =>
|
||||||
var locationName = workOrder.Locations?.Name ?? "";
|
$"<tr><td style='padding:6px 8px;border:1px solid #ddd;'>{wo.InternalWONumber}</td>" +
|
||||||
var locationAddr = workOrder.Locations?.Address ?? "";
|
$"<td style='padding:6px 8px;border:1px solid #ddd;'>{wo.WorkerOrderTitle}</td>" +
|
||||||
|
$"<td style='padding:6px 8px;border:1px solid #ddd;'>{wo.Priority}</td>" +
|
||||||
|
$"<td style='padding:6px 8px;border:1px solid #ddd;'>{wo.DueDate?.ToString("yyyy-MM-dd") ?? "N/A"}</td></tr>"));
|
||||||
|
|
||||||
|
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 = $@"
|
var html = $@"
|
||||||
<h2>Work Order Dispatch</h2>
|
<h2>Work Order Dispatch — {dispatchNumber}</h2>
|
||||||
|
<p><strong>Location:</strong> {locationName} {locationAddr}</p>
|
||||||
|
<p><strong>Vendor PO:</strong> {poNumber} <strong>NTE:</strong> ${model.NTEAmount?.ToString("F2") ?? "N/A"}</p>
|
||||||
|
<h3>Work Orders</h3>
|
||||||
<table style='border-collapse:collapse;width:100%;font-family:Arial,sans-serif;'>
|
<table style='border-collapse:collapse;width:100%;font-family:Arial,sans-serif;'>
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>WO Number</td><td style='padding:8px;border:1px solid #ddd;'>{workOrder.InternalWONumber}</td></tr>
|
<tr style='background:#f5f5f5;'>
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Title</td><td style='padding:8px;border:1px solid #ddd;'>{workOrder.WorkerOrderTitle}</td></tr>
|
<th style='padding:6px 8px;border:1px solid #ddd;text-align:left;'>WO #</th>
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Location</td><td style='padding:8px;border:1px solid #ddd;'>{locationName} {locationAddr}</td></tr>
|
<th style='padding:6px 8px;border:1px solid #ddd;text-align:left;'>Title</th>
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Priority</td><td style='padding:8px;border:1px solid #ddd;'>{workOrder.Priority}</td></tr>
|
<th style='padding:6px 8px;border:1px solid #ddd;text-align:left;'>Priority</th>
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Due Date</td><td style='padding:8px;border:1px solid #ddd;'>{workOrder.DueDate?.ToString("yyyy-MM-dd") ?? "N/A"}</td></tr>
|
<th style='padding:6px 8px;border:1px solid #ddd;text-align:left;'>Due Date</th>
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Trade</td><td style='padding:8px;border:1px solid #ddd;'>{workOrder.Trade}</td></tr>
|
</tr>
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Sub-Trade</td><td style='padding:8px;border:1px solid #ddd;'>{workOrder.SubTrade}</td></tr>
|
{woListHtml}
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Problem</td><td style='padding:8px;border:1px solid #ddd;'>{workOrder.Problem}</td></tr>
|
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>NTE</td><td style='padding:8px;border:1px solid #ddd;'>${model.NTEAmount?.ToString("F2") ?? "N/A"}</td></tr>
|
|
||||||
<tr><td style='padding:8px;font-weight:bold;border:1px solid #ddd;'>Vendor PO</td><td style='padding:8px;border:1px solid #ddd;'>{poNumber}</td></tr>
|
|
||||||
</table>
|
</table>
|
||||||
<h3>Description</h3>
|
<h3>Description</h3>
|
||||||
<p>{model.Description ?? workOrder.Description}</p>
|
<p>{model.Description ?? primaryWO.Description}</p>
|
||||||
<hr/>
|
|
||||||
<br/><p style='color:#666;font-size:13px;'>{senderName}<br/>Sea Haven Industries</p>
|
<br/><p style='color:#666;font-size:13px;'>{senderName}<br/>Sea Haven Industries</p>
|
||||||
<hr/><p style='color:#999;font-size:12px;'>Reply to this email to communicate about this work order.</p>";
|
<hr/><p style='color:#999;font-size:12px;'>Reply to this email to communicate about this dispatch.</p>";
|
||||||
|
|
||||||
var emailSent = await _sendMessage.SendDispatchEmail(vendor.Email, subject, html, replyTo);
|
var emailSent = await _sendMessage.SendDispatchEmail(vendor.Email, subject, html, replyTo);
|
||||||
dispatch.EmailSent = emailSent;
|
dispatch.EmailSent = emailSent;
|
||||||
|
|
||||||
_db.Dispatches.Add(dispatch);
|
_db.Dispatches.Add(dispatch);
|
||||||
|
|
||||||
_db.WorkOrderAuditLogs.Add(new WorkOrderAuditLog
|
foreach (var wo in workOrders)
|
||||||
{
|
{
|
||||||
WorkOrderId = model.WorkOrderId,
|
_db.WorkOrderAuditLogs.Add(new WorkOrderAuditLog
|
||||||
UserId = userId,
|
{
|
||||||
FieldName = "Dispatch",
|
WorkOrderId = wo.Id,
|
||||||
OldValue = "",
|
UserId = userId,
|
||||||
NewValue = $"{vendor.CompanyName} ({poNumber})",
|
FieldName = "Dispatch",
|
||||||
Action = "dispatch",
|
OldValue = "",
|
||||||
CreatedAt = DateTime.UtcNow
|
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();
|
await _db.SaveChangesAsync();
|
||||||
|
|
@ -1140,8 +1153,21 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
[HttpGet("GetDispatches/{workOrderId}")]
|
[HttpGet("GetDispatches/{workOrderId}")]
|
||||||
public async Task<IActionResult> GetDispatches(int workOrderId)
|
public async Task<IActionResult> 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)
|
.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)
|
.Include(d => d.Vendor)
|
||||||
.OrderByDescending(d => d.DispatchedAt)
|
.OrderByDescending(d => d.DispatchedAt)
|
||||||
.Select(d => new
|
.Select(d => new
|
||||||
|
|
@ -1184,11 +1210,19 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
x.DispatchedAt,
|
x.DispatchedAt,
|
||||||
x.EmailSent,
|
x.EmailSent,
|
||||||
x.WorkOrderId,
|
x.WorkOrderId,
|
||||||
|
x.AcknowledgedAt,
|
||||||
woNumber = x.WorkOrder != null ? x.WorkOrder.InternalWONumber : "",
|
woNumber = x.WorkOrder != null ? x.WorkOrder.InternalWONumber : "",
|
||||||
woTitle = x.WorkOrder != null ? x.WorkOrder.WorkerOrderTitle : "",
|
woTitle = x.WorkOrder != null ? x.WorkOrder.WorkerOrderTitle : "",
|
||||||
vendorName = x.Vendor != null ? x.Vendor.CompanyName : "",
|
vendorName = x.Vendor != null ? x.Vendor.CompanyName : "",
|
||||||
vendorEmail = x.Vendor != null ? x.Vendor.Email : "",
|
vendorEmail = x.Vendor != null ? x.Vendor.Email : "",
|
||||||
vendorId = x.VendorId,
|
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
|
comments = _db.Comments
|
||||||
.Where(c => c.DispatchId == x.Id)
|
.Where(c => c.DispatchId == x.Id)
|
||||||
.OrderBy(c => c.CreatedDate)
|
.OrderBy(c => c.CreatedDate)
|
||||||
|
|
@ -1223,7 +1257,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
{
|
{
|
||||||
_db.WorkOrderAuditLogs.Add(new WorkOrderAuditLog
|
_db.WorkOrderAuditLogs.Add(new WorkOrderAuditLog
|
||||||
{
|
{
|
||||||
WorkOrderId = dispatch.WorkOrderId,
|
WorkOrderId = dispatch.WorkOrderId ?? 0,
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
FieldName = $"Dispatch {dispatch.DispatchNumber} Status",
|
FieldName = $"Dispatch {dispatch.DispatchNumber} Status",
|
||||||
OldValue = dispatch.Status ?? "",
|
OldValue = dispatch.Status ?? "",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ namespace Api.SeaHavenIndustries.DTOs
|
||||||
{
|
{
|
||||||
public class Dispatch_DTO
|
public class Dispatch_DTO
|
||||||
{
|
{
|
||||||
public int WorkOrderId { get; set; }
|
public List<int> WorkOrderIds { get; set; } = new();
|
||||||
public List<int> VendorIds { get; set; } = new();
|
public List<int> VendorIds { get; set; } = new();
|
||||||
public decimal? NTEAmount { get; set; }
|
public decimal? NTEAmount { get; set; }
|
||||||
public DateTime? ScheduledDate { get; set; }
|
public DateTime? ScheduledDate { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ namespace Data.SeaHavenIndustries
|
||||||
public DbSet<DropdownOption> DropdownOptions { get; set; }
|
public DbSet<DropdownOption> DropdownOptions { get; set; }
|
||||||
public DbSet<Vendor> Vendors { get; set; }
|
public DbSet<Vendor> Vendors { get; set; }
|
||||||
public DbSet<Dispatch> Dispatches { get; set; }
|
public DbSet<Dispatch> Dispatches { get; set; }
|
||||||
|
public DbSet<DispatchWorkOrder> DispatchWorkOrders { get; set; }
|
||||||
public DbSet<TaskListTemplate> TaskListTemplates { get; set; }
|
public DbSet<TaskListTemplate> TaskListTemplates { get; set; }
|
||||||
public DbSet<TaskListTemplateItem> TaskListTemplateItems { get; set; }
|
public DbSet<TaskListTemplateItem> TaskListTemplateItems { get; set; }
|
||||||
|
|
||||||
|
|
|
||||||
2657
Data.SeaHavenIndustries/Migrations/20260417190743_MultiWODispatch.Designer.cs
generated
Normal file
2657
Data.SeaHavenIndustries/Migrations/20260417190743_MultiWODispatch.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,96 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Data.SeaHavenIndustries.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class MultiWODispatch : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "WorkOrderId",
|
||||||
|
table: "Dispatches",
|
||||||
|
type: "int",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "AcceptToken",
|
||||||
|
table: "Dispatches",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "AcknowledgedAt",
|
||||||
|
table: "Dispatches",
|
||||||
|
type: "datetime2",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "DispatchWorkOrders",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
DispatchId = table.Column<int>(type: "int", nullable: false),
|
||||||
|
WorkOrderId = table.Column<int>(type: "int", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_DispatchWorkOrders", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_DispatchWorkOrders_Dispatches_DispatchId",
|
||||||
|
column: x => x.DispatchId,
|
||||||
|
principalTable: "Dispatches",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_DispatchWorkOrders_workOrders_WorkOrderId",
|
||||||
|
column: x => x.WorkOrderId,
|
||||||
|
principalTable: "workOrders",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_DispatchWorkOrders_DispatchId",
|
||||||
|
table: "DispatchWorkOrders",
|
||||||
|
column: "DispatchId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_DispatchWorkOrders_WorkOrderId",
|
||||||
|
table: "DispatchWorkOrders",
|
||||||
|
column: "WorkOrderId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "DispatchWorkOrders");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AcceptToken",
|
||||||
|
table: "Dispatches");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AcknowledgedAt",
|
||||||
|
table: "Dispatches");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "WorkOrderId",
|
||||||
|
table: "Dispatches",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int",
|
||||||
|
oldNullable: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -640,6 +640,12 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("AcceptToken")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("AcknowledgedAt")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
b.Property<DateTime?>("CompletedDate")
|
b.Property<DateTime?>("CompletedDate")
|
||||||
.HasColumnType("datetime2");
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
|
@ -691,7 +697,7 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
b.Property<int>("VendorId")
|
b.Property<int>("VendorId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<int>("WorkOrderId")
|
b.Property<int?>("WorkOrderId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("createdby")
|
b.Property<string>("createdby")
|
||||||
|
|
@ -706,6 +712,29 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
b.ToTable("Dispatches");
|
b.ToTable("Dispatches");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Data.SeaHavenIndustries.DispatchWorkOrder", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("DispatchId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("WorkOrderId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DispatchId");
|
||||||
|
|
||||||
|
b.HasIndex("WorkOrderId");
|
||||||
|
|
||||||
|
b.ToTable("DispatchWorkOrders");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Data.SeaHavenIndustries.DropdownOption", b =>
|
modelBuilder.Entity("Data.SeaHavenIndustries.DropdownOption", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
|
@ -2181,10 +2210,28 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
b.HasOne("Data.SeaHavenIndustries.WorkOrder", "WorkOrder")
|
b.HasOne("Data.SeaHavenIndustries.WorkOrder", "WorkOrder")
|
||||||
.WithMany("Dispatches")
|
.WithMany("Dispatches")
|
||||||
.HasForeignKey("WorkOrderId")
|
.HasForeignKey("WorkOrderId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.Navigation("Vendor");
|
||||||
|
|
||||||
|
b.Navigation("WorkOrder");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Data.SeaHavenIndustries.DispatchWorkOrder", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Data.SeaHavenIndustries.Dispatch", "Dispatch")
|
||||||
|
.WithMany("DispatchWorkOrders")
|
||||||
|
.HasForeignKey("DispatchId")
|
||||||
.OnDelete(DeleteBehavior.Restrict)
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("Vendor");
|
b.HasOne("Data.SeaHavenIndustries.WorkOrder", "WorkOrder")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("WorkOrderId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Dispatch");
|
||||||
|
|
||||||
b.Navigation("WorkOrder");
|
b.Navigation("WorkOrder");
|
||||||
});
|
});
|
||||||
|
|
@ -2542,6 +2589,8 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
modelBuilder.Entity("Data.SeaHavenIndustries.Dispatch", b =>
|
modelBuilder.Entity("Data.SeaHavenIndustries.Dispatch", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("Comments");
|
b.Navigation("Comments");
|
||||||
|
|
||||||
|
b.Navigation("DispatchWorkOrders");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Data.SeaHavenIndustries.Employee", b =>
|
modelBuilder.Entity("Data.SeaHavenIndustries.Employee", b =>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ namespace Data.SeaHavenIndustries
|
||||||
{
|
{
|
||||||
public class Dispatch : FullAuditEntity
|
public class Dispatch : FullAuditEntity
|
||||||
{
|
{
|
||||||
public int WorkOrderId { get; set; }
|
public int? WorkOrderId { get; set; }
|
||||||
[ForeignKey(nameof(WorkOrderId))]
|
[ForeignKey(nameof(WorkOrderId))]
|
||||||
public virtual WorkOrder? WorkOrder { get; set; }
|
public virtual WorkOrder? WorkOrder { get; set; }
|
||||||
|
|
||||||
|
|
@ -20,8 +20,11 @@ namespace Data.SeaHavenIndustries
|
||||||
public DateTime? ScheduledDate { get; set; }
|
public DateTime? ScheduledDate { get; set; }
|
||||||
public DateTime? CompletedDate { get; set; }
|
public DateTime? CompletedDate { get; set; }
|
||||||
public DateTime? DispatchedAt { get; set; }
|
public DateTime? DispatchedAt { get; set; }
|
||||||
|
public DateTime? AcknowledgedAt { get; set; }
|
||||||
public bool EmailSent { get; set; }
|
public bool EmailSent { get; set; }
|
||||||
public string? ReplyToAddress { get; set; }
|
public string? ReplyToAddress { get; set; }
|
||||||
|
public string? AcceptToken { get; set; }
|
||||||
public ICollection<Comments>? Comments { get; set; }
|
public ICollection<Comments>? Comments { get; set; }
|
||||||
|
public ICollection<DispatchWorkOrder>? DispatchWorkOrders { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
Data.SeaHavenIndustries/Models/DispatchWorkOrder.cs
Normal file
15
Data.SeaHavenIndustries/Models/DispatchWorkOrder.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Data.SeaHavenIndustries
|
||||||
|
{
|
||||||
|
public class DispatchWorkOrder
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int DispatchId { get; set; }
|
||||||
|
[ForeignKey(nameof(DispatchId))]
|
||||||
|
public virtual Dispatch? Dispatch { get; set; }
|
||||||
|
public int WorkOrderId { get; set; }
|
||||||
|
[ForeignKey(nameof(WorkOrderId))]
|
||||||
|
public virtual WorkOrder? WorkOrder { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue