merge: carry approval queue contract fields into decisions

This commit is contained in:
Alexandre Brandizzi 2026-09-16 22:32:35 -03:00
commit bd98ea5629
5 changed files with 38 additions and 3 deletions

View file

@ -88,6 +88,8 @@ namespace Data.SeaHavenIndustries
public string? RequestedByVendorName { get; set; } public string? RequestedByVendorName { get; set; }
public string? RequestedByFirstName { get; set; } public string? RequestedByFirstName { get; set; }
public string? RequestedByLastName { get; set; } public string? RequestedByLastName { get; set; }
public string? DecidedByFirstName { get; set; }
public string? DecidedByLastName { get; set; }
public decimal? CurrentNTE { get; set; } public decimal? CurrentNTE { get; set; }
public decimal RequestedNTE { get; set; } public decimal RequestedNTE { get; set; }
public string? VendorReason { get; set; } public string? VendorReason { get; set; }
@ -104,6 +106,8 @@ namespace Data.SeaHavenIndustries
public DateTime? ExpiresAt { get; set; } public DateTime? ExpiresAt { get; set; }
public string? NotificationStatus { get; set; } public string? NotificationStatus { get; set; }
public string? NotificationError { get; set; } public string? NotificationError { get; set; }
public int AttachmentCount { get; set; }
public bool WorkOrderClosed { get; set; }
} }
public class UpliftForWorkOrderData : UpliftForDispatchData public class UpliftForWorkOrderData : UpliftForDispatchData

View file

@ -1,5 +1,6 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using Data.SeaHavenIndustries; using Data.SeaHavenIndustries;
using Data.SeaHavenIndustries.Enums;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using SeaHaven.DataServices.Interfaces; using SeaHaven.DataServices.Interfaces;
@ -28,9 +29,11 @@ namespace SeaHaven.DataServices.Implementation
from wo in workOrders.DefaultIfEmpty() from wo in workOrders.DefaultIfEmpty()
join reqUser in _context.Users on u.createdby equals reqUser.Id into requestUsers join reqUser in _context.Users on u.createdby equals reqUser.Id into requestUsers
from reqUser in requestUsers.DefaultIfEmpty() from reqUser in requestUsers.DefaultIfEmpty()
join decUser in _context.Users on u.DecidedByUserId equals decUser.Id into decisionUsers
from decUser in decisionUsers.DefaultIfEmpty()
where (u.IsDeleted == null || u.IsDeleted == false) where (u.IsDeleted == null || u.IsDeleted == false)
&& (d.IsDeleted == null || d.IsDeleted == false) && (d.IsDeleted == null || d.IsDeleted == false)
select new { u, d, v, ev, wo, reqUser }; select new { u, d, v, ev, wo, reqUser, decUser };
if (!string.IsNullOrWhiteSpace(status)) if (!string.IsNullOrWhiteSpace(status))
query = query.Where(x => x.u.Status == status); query = query.Where(x => x.u.Status == status);
@ -70,6 +73,8 @@ namespace SeaHaven.DataServices.Implementation
RequestedByVendorName = x.u.RequestedByVendorName, RequestedByVendorName = x.u.RequestedByVendorName,
RequestedByFirstName = x.reqUser != null ? x.reqUser.FirstName : null, RequestedByFirstName = x.reqUser != null ? x.reqUser.FirstName : null,
RequestedByLastName = x.reqUser != null ? x.reqUser.LastName : null, RequestedByLastName = x.reqUser != null ? x.reqUser.LastName : null,
DecidedByFirstName = x.decUser != null ? x.decUser.FirstName : null,
DecidedByLastName = x.decUser != null ? x.decUser.LastName : null,
CurrentNTE = x.u.CurrentNTE, CurrentNTE = x.u.CurrentNTE,
RequestedNTE = x.u.RequestedNTE, RequestedNTE = x.u.RequestedNTE,
VendorReason = x.u.VendorReason, VendorReason = x.u.VendorReason,
@ -84,13 +89,29 @@ namespace SeaHaven.DataServices.Implementation
EvidenceSizeBytes = x.ev != null ? x.ev.SizeBytes : null, EvidenceSizeBytes = x.ev != null ? x.ev.SizeBytes : null,
ExpiresAt = x.u.ExpiresAt, ExpiresAt = x.u.ExpiresAt,
NotificationStatus = x.u.NotificationStatus, NotificationStatus = x.u.NotificationStatus,
NotificationError = x.u.NotificationError NotificationError = x.u.NotificationError,
AttachmentCount = _context.VendorCompletionDocuments.Count(document =>
document.DispatchId == x.d.Id
&& (document.IsDeleted == null || document.IsDeleted == false)),
WorkOrderClosed = x.wo != null
&& (x.wo.LifecycleStatus == LifecycleStatus.Completed
|| x.wo.LifecycleStatus == LifecycleStatus.Canceled)
}) })
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
return (total, items); return (total, items);
} }
public Task<decimal> GetPendingExposureAsync(CancellationToken cancellationToken)
{
return _context.DispatchUpliftRequests
.Where(u => (u.IsDeleted == null || u.IsDeleted == false)
&& u.Status == "Pending")
.SumAsync(u => u.createdby == null
? u.RequestedNTE - (u.CurrentNTE ?? 0m)
: u.RequestedNTE, cancellationToken);
}
public async Task<IReadOnlyList<UpliftForDispatchData>> GetForDispatchAsync(int dispatchId, CancellationToken cancellationToken) public async Task<IReadOnlyList<UpliftForDispatchData>> GetForDispatchAsync(int dispatchId, CancellationToken cancellationToken)
{ {
return await (from u in _context.DispatchUpliftRequests return await (from u in _context.DispatchUpliftRequests

View file

@ -6,6 +6,7 @@ namespace SeaHaven.DataServices.Interfaces
{ {
Task<(int TotalCount, IReadOnlyList<UpliftListItemData> Items)> GetPagedAsync( Task<(int TotalCount, IReadOnlyList<UpliftListItemData> Items)> GetPagedAsync(
string? status, int? tier, int page, int pageSize, CancellationToken cancellationToken); string? status, int? tier, int page, int pageSize, CancellationToken cancellationToken);
Task<decimal> GetPendingExposureAsync(CancellationToken cancellationToken);
Task<IReadOnlyList<UpliftForDispatchData>> GetForDispatchAsync(int dispatchId, CancellationToken cancellationToken); Task<IReadOnlyList<UpliftForDispatchData>> GetForDispatchAsync(int dispatchId, CancellationToken cancellationToken);
Task<IReadOnlyList<UpliftForWorkOrderData>> GetForWorkOrderAsync(int workOrderId, CancellationToken cancellationToken); Task<IReadOnlyList<UpliftForWorkOrderData>> GetForWorkOrderAsync(int workOrderId, CancellationToken cancellationToken);
Task<DispatchUpliftRequest?> GetByIdAndWorkOrderAsync(int requestId, int workOrderId, CancellationToken cancellationToken); Task<DispatchUpliftRequest?> GetByIdAndWorkOrderAsync(int requestId, int workOrderId, CancellationToken cancellationToken);

View file

@ -13,6 +13,7 @@ namespace SeaHaven.Services.DTOs
public string? WorkOrderSite { get; set; } public string? WorkOrderSite { get; set; }
public string? WorkOrderService { get; set; } public string? WorkOrderService { get; set; }
public string? RequestedByName { get; set; } public string? RequestedByName { get; set; }
public string? DecidedByName { get; set; }
public decimal? CurrentNTE { get; set; } public decimal? CurrentNTE { get; set; }
public decimal RequestedNTE { get; set; } public decimal RequestedNTE { get; set; }
public decimal Delta { get; set; } public decimal Delta { get; set; }
@ -31,6 +32,8 @@ namespace SeaHaven.Services.DTOs
public DateTime? ExpiresAt { get; set; } public DateTime? ExpiresAt { get; set; }
public string? NotificationStatus { get; set; } public string? NotificationStatus { get; set; }
public string? NotificationError { get; set; } public string? NotificationError { get; set; }
public int AttachmentCount { get; set; }
public bool WorkOrderClosed { get; set; }
// Approved-on-WO exposure totals for this item's work order: auto-approved and // Approved-on-WO exposure totals for this item's work order: auto-approved and
// admin-approved amounts; pending, rejected, cancelled/withdrawn, and revoked // admin-approved amounts; pending, rejected, cancelled/withdrawn, and revoked
// requests are excluded. // requests are excluded.
@ -44,6 +47,7 @@ namespace SeaHaven.Services.DTOs
public int Total { get; set; } public int Total { get; set; }
public int Page { get; set; } public int Page { get; set; }
public int PageSize { get; set; } public int PageSize { get; set; }
public decimal PendingExposureTotal { get; set; }
public IEnumerable<UpliftListItemDTO> Items { get; set; } = Enumerable.Empty<UpliftListItemDTO>(); public IEnumerable<UpliftListItemDTO> Items { get; set; } = Enumerable.Empty<UpliftListItemDTO>();
} }

View file

@ -36,6 +36,7 @@ namespace SeaHaven.Services.Implementation
public async Task<UpliftListResultDTO> ListAsync(ClaimsPrincipal user, string? status, int? tier, int page, int pageSize, CancellationToken cancellationToken) public async Task<UpliftListResultDTO> ListAsync(ClaimsPrincipal user, string? status, int? tier, int page, int pageSize, CancellationToken cancellationToken)
{ {
var (total, items) = await _upliftData.GetPagedAsync(status, tier, page, pageSize, cancellationToken); var (total, items) = await _upliftData.GetPagedAsync(status, tier, page, pageSize, cancellationToken);
var pendingExposureTotal = await _upliftData.GetPendingExposureAsync(cancellationToken);
var mapped = items.Select(r => new UpliftListItemDTO var mapped = items.Select(r => new UpliftListItemDTO
{ {
@ -49,6 +50,7 @@ namespace SeaHaven.Services.Implementation
WorkOrderSite = r.WorkOrderSiteCode, WorkOrderSite = r.WorkOrderSiteCode,
WorkOrderService = r.WorkOrderService, WorkOrderService = r.WorkOrderService,
RequestedByName = ResolveRequestedByName(r.RequestedByVendorName, r.RequestedByFirstName, r.RequestedByLastName), RequestedByName = ResolveRequestedByName(r.RequestedByVendorName, r.RequestedByFirstName, r.RequestedByLastName),
DecidedByName = ResolveRequestedByName(null, r.DecidedByFirstName, r.DecidedByLastName),
CurrentNTE = r.CurrentNTE, CurrentNTE = r.CurrentNTE,
RequestedNTE = r.RequestedNTE, RequestedNTE = r.RequestedNTE,
Delta = r.RequestedNTE - (r.CurrentNTE ?? 0m), Delta = r.RequestedNTE - (r.CurrentNTE ?? 0m),
@ -65,7 +67,9 @@ namespace SeaHaven.Services.Implementation
EvidenceSizeBytes = r.EvidenceSizeBytes, EvidenceSizeBytes = r.EvidenceSizeBytes,
ExpiresAt = r.ExpiresAt, ExpiresAt = r.ExpiresAt,
NotificationStatus = r.NotificationStatus, NotificationStatus = r.NotificationStatus,
NotificationError = r.NotificationError NotificationError = r.NotificationError,
AttachmentCount = r.AttachmentCount,
WorkOrderClosed = r.WorkOrderClosed
}).ToList(); }).ToList();
// Approved-on-WO exposure totals are aggregated once for the whole page // Approved-on-WO exposure totals are aggregated once for the whole page
@ -93,6 +97,7 @@ namespace SeaHaven.Services.Implementation
Total = total, Total = total,
Page = page, Page = page,
PageSize = pageSize, PageSize = pageSize,
PendingExposureTotal = pendingExposureTotal,
Items = mapped Items = mapped
}; };
} }