diff --git a/Api.SeaHavenIndustries.Tests/VendorPortalDocumentTests.cs b/Api.SeaHavenIndustries.Tests/VendorPortalDocumentTests.cs index 3e20aa3..9ca6a7e 100644 --- a/Api.SeaHavenIndustries.Tests/VendorPortalDocumentTests.cs +++ b/Api.SeaHavenIndustries.Tests/VendorPortalDocumentTests.cs @@ -423,6 +423,57 @@ public sealed class VendorPortalDocumentTests : IDisposable detail!.Documents.Should().BeEmpty(); } + [Fact] + public async Task GetDispatchDetail_ReturnsInvoicePaymentFieldsOnlyForOwningVendor() + { + using var context = NewContext(); + var (_, dispatch) = await SeedDispatch(context); + dispatch.InvoiceNumber = "INV-2048"; + dispatch.InvoiceStatus = "Confirmed"; + dispatch.PaymentStatus = "Scheduled"; + await context.SaveChangesAsync(); + + var service = NewService(context); + var ownerSession = await service.ResolveSessionAsync(Token, CancellationToken.None); + var ownerDetail = await service.GetDispatchDetailAsync(ownerSession!, dispatch.Id, CancellationToken.None); + + ownerDetail.Should().NotBeNull(); + ownerDetail!.InvoiceNumber.Should().Be("INV-2048"); + ownerDetail.InvoiceStatus.Should().Be("Confirmed"); + ownerDetail.PaymentStatus.Should().Be("Scheduled"); + + var ownerResult = await NewController(service).GetDispatch(dispatch.Id); + var ownerOk = ownerResult.Should().BeOfType().Subject; + var ownerResponse = ownerOk.Value.Should().BeOfType().Subject; + var ownerData = ((object)ownerResponse.Data) + .Should().BeOfType().Subject; + ownerData.InvoiceNumber.Should().Be("INV-2048"); + ownerData.InvoiceStatus.Should().Be("Confirmed"); + ownerData.PaymentStatus.Should().Be("Scheduled"); + + var otherVendor = new Vendor { CompanyName = "Other Vendor", IsActive = true }; + context.Vendors.Add(otherVendor); + await context.SaveChangesAsync(); + const string otherToken = "other-vendor-token"; + context.VendorAccessTokens.Add(new VendorAccessToken + { + VendorId = otherVendor.Id, + Token = otherToken, + IssuedAt = DateTime.UtcNow, + ExpiresAt = DateTime.UtcNow.AddDays(1) + }); + await context.SaveChangesAsync(); + + var otherSession = await service.ResolveSessionAsync(otherToken, CancellationToken.None); + var otherDetail = await service.GetDispatchDetailAsync(otherSession!, dispatch.Id, CancellationToken.None); + otherDetail.Should().BeNull(); + + var otherController = NewController(service); + otherController.Request.Headers["X-Vendor-Token"] = otherToken; + var otherResult = await otherController.GetDispatch(dispatch.Id); + otherResult.Should().BeOfType(); + } + public void Dispose() { if (Directory.Exists(_contentRoot)) diff --git a/SeaHaven.Services/DTOs/VendorPortalServiceDTOs.cs b/SeaHaven.Services/DTOs/VendorPortalServiceDTOs.cs index 0fe7040..3a4b5e7 100644 --- a/SeaHaven.Services/DTOs/VendorPortalServiceDTOs.cs +++ b/SeaHaven.Services/DTOs/VendorPortalServiceDTOs.cs @@ -97,6 +97,9 @@ namespace SeaHaven.Services.DTOs public string? DispatchNumber { get; set; } public string? PONumber { get; set; } public string? Status { get; set; } + public string? InvoiceNumber { get; set; } + public string? InvoiceStatus { get; set; } + public string? PaymentStatus { get; set; } public decimal? NTEAmount { get; set; } public string? Description { get; set; } public DateTime? ScheduledDate { get; set; } diff --git a/SeaHaven.Services/Implementation/VendorPortalService.cs b/SeaHaven.Services/Implementation/VendorPortalService.cs index 3606639..d0514c6 100644 --- a/SeaHaven.Services/Implementation/VendorPortalService.cs +++ b/SeaHaven.Services/Implementation/VendorPortalService.cs @@ -150,6 +150,9 @@ namespace SeaHaven.Services.Implementation DispatchNumber = dispatch.DispatchNumber, PONumber = dispatch.PONumber, Status = dispatch.Status, + InvoiceNumber = dispatch.InvoiceNumber, + InvoiceStatus = dispatch.InvoiceStatus, + PaymentStatus = dispatch.PaymentStatus, NTEAmount = dispatch.NTEAmount, Description = dispatch.Description, ScheduledDate = dispatch.ScheduledDate,