using Data.SeaHavenIndustries; using Microsoft.EntityFrameworkCore; using SeaHaven.DataServices.Interfaces; namespace SeaHaven.DataServices.Implementation { public class VendorDocumentDataService : IVendorDocumentDataService { private readonly ApplicationDbContext _context; public VendorDocumentDataService(ApplicationDbContext context) { _context = context; } // Completion-document queries/version semantics exclude uplift evidence so that // supporting evidence never participates in completion versioning or replacement. private const string CompletionPurpose = "Completion"; public async Task> ListActiveContentTypesForWorkOrderAsync( int workOrderId, int? excludingDocumentId, CancellationToken cancellationToken) { // Uplift evidence also records the latest completion id in ReplacesDocumentId, so only // a newer completion version supersedes a document. return await _context.VendorCompletionDocuments .AsNoTracking() .Where(document => document.WorkOrderId == workOrderId && (document.IsDeleted == null || document.IsDeleted == false) && (excludingDocumentId == null || document.Id != excludingDocumentId) && !_context.VendorCompletionDocuments.Any(newer => newer.ReplacesDocumentId == document.Id && newer.Purpose == CompletionPurpose && (newer.IsDeleted == null || newer.IsDeleted == false))) .Select(document => document.ContentType) .ToListAsync(cancellationToken); } public async Task> ListActiveWorkOrderAttachmentUrlsAsync( int workOrderId, CancellationToken cancellationToken) { return await _context.workOrderAttachments .AsNoTracking() .Where(attachment => attachment.WorkorderId == workOrderId && attachment.IsDeleted != true && attachment.Attachments != null) .Select(attachment => attachment.Attachments!) .ToListAsync(cancellationToken); } public Task GetLatestForDispatchAsync(int dispatchId, CancellationToken cancellationToken) { return _context.VendorCompletionDocuments .Where(document => document.DispatchId == dispatchId && document.Purpose == CompletionPurpose) .OrderByDescending(document => document.Version) .FirstOrDefaultAsync(cancellationToken); } public Task GetForVendorDispatchAsync(int documentId, int dispatchId, int vendorId, CancellationToken cancellationToken) { return _context.VendorCompletionDocuments .FirstOrDefaultAsync(document => document.Id == documentId && document.DispatchId == dispatchId && document.VendorId == vendorId && document.Purpose == CompletionPurpose && (document.IsDeleted == null || document.IsDeleted == false), cancellationToken); } public Task GetMetadataForVendorDispatchAsync(int documentId, int dispatchId, int vendorId, CancellationToken cancellationToken) { return _context.VendorCompletionDocuments .AsNoTracking() .FirstOrDefaultAsync(document => document.Id == documentId && document.DispatchId == dispatchId && document.VendorId == vendorId && (document.IsDeleted == null || document.IsDeleted == false), cancellationToken); } public Task> ListForVendorDispatchAsync(int dispatchId, int vendorId, CancellationToken cancellationToken) { return _context.VendorCompletionDocuments .Where(document => document.DispatchId == dispatchId && document.VendorId == vendorId && document.Purpose == CompletionPurpose && (document.IsDeleted == null || document.IsDeleted == false)) .OrderByDescending(document => document.Version) .ToListAsync(cancellationToken); } // SH-101: an uplift request > current requires a same-vendor, same-dispatch, // nondeleted UpliftEvidence document whose scan passed. This lookup enforces all of those. public Task GetUpliftEvidenceAsync(int documentId, int dispatchId, int vendorId, CancellationToken cancellationToken) { return _context.VendorCompletionDocuments .FirstOrDefaultAsync(document => document.Id == documentId && document.DispatchId == dispatchId && document.VendorId == vendorId && document.Purpose == "UpliftEvidence" && document.ScanStatus == "Passed" && (document.IsDeleted == null || document.IsDeleted == false), cancellationToken); } public async Task AddAsync(VendorCompletionDocument document, CancellationToken cancellationToken) { await _context.VendorCompletionDocuments.AddAsync(document, cancellationToken); } public Task SaveChangesAsync(CancellationToken cancellationToken) { return _context.SaveChangesAsync(cancellationToken); } } }