From 665880ee807a47b67409908818f6e537ce9e2b49 Mon Sep 17 00:00:00 2001 From: Alexandre Brandizzi Date: Mon, 3 Aug 2026 10:41:10 -0300 Subject: [PATCH] fix(vendors): synchronize roster company fields --- .../VendorCompanyRosterDataServiceTests.cs | 227 ++++++++++++++++++ .../VendorCompanyRosterDataService.cs | 8 + 2 files changed, 235 insertions(+) diff --git a/Api.SeaHavenIndustries.Tests/VendorCompanyRosterDataServiceTests.cs b/Api.SeaHavenIndustries.Tests/VendorCompanyRosterDataServiceTests.cs index 8238bd4..d0f4bf4 100644 --- a/Api.SeaHavenIndustries.Tests/VendorCompanyRosterDataServiceTests.cs +++ b/Api.SeaHavenIndustries.Tests/VendorCompanyRosterDataServiceTests.cs @@ -265,4 +265,231 @@ public class VendorCompanyRosterDataServiceTests await act.Should().ThrowAsync(); } + + [Fact] + public async Task SaveRoster_PropagatesCompanyLocationAndPhoneToRetainedTechnician() + { + var dbName = Guid.NewGuid().ToString(); + int companyId, techId; + using (var seed = NewContext(dbName)) + { + var company = new VendorCompany + { + Name = "Loc Co", + NormalizedName = "loc co", + CompanyPhone = "(111) 111-0001", + Address = "Old Addr", + City = "OldCity", + State = "OS", + Zip = "00001", + GoogleMapsUrl = "https://old.example/map" + }; + seed.VendorCompanies.Add(company); + seed.Vendors.Add(new Vendor + { + CompanyName = "Loc Co", + ContactName = "Keeper", + IsActive = true, + IsDeleted = false, + Company = company, + CompanyPhone = "(111) 111-0001", + Address = "Old Addr", + City = "OldCity", + State = "OS", + Zip = "00001", + GoogleMapsUrl = "https://old.example/map" + }); + await seed.SaveChangesAsync(); + companyId = company.Id; + techId = seed.Vendors.First(v => v.CompanyId == companyId).Id; + } + + using (var act = NewContext(dbName)) + { + var service = new VendorCompanyRosterDataService(act); + await service.SaveRosterAsync(new VendorCompanyRosterWriteModel + { + CompanyId = companyId, + Name = "Loc Co", + CompanyPhone = "(222) 222-0002", + Address = "New Addr", + City = "NewCity", + State = "NS", + Zip = "00002", + GoogleMapsUrl = "https://new.example/map", + ActorUserId = "42", + Technicians = new List + { + new() { Id = techId, ContactName = "Keeper", IsActive = true } + } + }, CancellationToken.None); + } + + using var verify = NewContext(dbName); + var tech = verify.Vendors.Single(v => v.Id == techId); + tech.CompanyPhone.Should().Be("(222) 222-0002"); + tech.Address.Should().Be("New Addr"); + tech.City.Should().Be("NewCity"); + tech.State.Should().Be("NS"); + tech.Zip.Should().Be("00002"); + tech.GoogleMapsUrl.Should().Be("https://new.example/map"); + + var directory = new VendorDataService(verify); + var newCity = await directory.GetDirectoryPagedAsync(1, 10, search: "NewCity"); + newCity.Items.Should().ContainSingle(row => row.VendorId == techId); + + var oldCity = await directory.GetDirectoryPagedAsync(1, 10, search: "OldCity"); + oldCity.Items.Should().NotContain(row => row.VendorId == techId); + } + + [Fact] + public async Task SaveRoster_ClearsCompanyOwnedFieldsOnRetainedTechnicianWhenCompanyClearsThem() + { + var dbName = Guid.NewGuid().ToString(); + int companyId, techId; + using (var seed = NewContext(dbName)) + { + var company = new VendorCompany + { + Name = "Clear Co", + NormalizedName = "clear co", + CompanyPhone = "(333) 333-0003", + Address = "Keep Addr", + City = "KeepCity", + State = "KS", + Zip = "00003", + GoogleMapsUrl = "https://keep.example/map" + }; + seed.VendorCompanies.Add(company); + seed.Vendors.Add(new Vendor + { + CompanyName = "Clear Co", + ContactName = "Keeper", + IsActive = true, + IsDeleted = false, + Company = company, + CompanyPhone = "(333) 333-0003", + Address = "Keep Addr", + City = "KeepCity", + State = "KS", + Zip = "00003", + GoogleMapsUrl = "https://keep.example/map" + }); + await seed.SaveChangesAsync(); + companyId = company.Id; + techId = seed.Vendors.First(v => v.CompanyId == companyId).Id; + } + + using (var act = NewContext(dbName)) + { + var service = new VendorCompanyRosterDataService(act); + await service.SaveRosterAsync(new VendorCompanyRosterWriteModel + { + CompanyId = companyId, + Name = "Clear Co", + CompanyPhone = null, + Address = null, + City = null, + State = null, + Zip = null, + GoogleMapsUrl = null, + ActorUserId = "42", + Technicians = new List + { + new() { Id = techId, ContactName = "Keeper", IsActive = true } + } + }, CancellationToken.None); + } + + using var verify = NewContext(dbName); + var tech = verify.Vendors.Single(v => v.Id == techId); + tech.CompanyPhone.Should().BeNull(); + tech.Address.Should().BeNull(); + tech.City.Should().BeNull(); + tech.State.Should().BeNull(); + tech.Zip.Should().BeNull(); + tech.GoogleMapsUrl.Should().BeNull(); + } + + [Fact] + public async Task SaveRoster_NewTechnicianReceivesCompanyPhoneAndLocation() + { + var dbName = Guid.NewGuid().ToString(); + int companyId; + using (var seed = NewContext(dbName)) + { + var company = new VendorCompany + { + Name = "Add Co", + NormalizedName = "add co" + }; + seed.VendorCompanies.Add(company); + await seed.SaveChangesAsync(); + companyId = company.Id; + } + + int newTechId; + using (var act = NewContext(dbName)) + { + var service = new VendorCompanyRosterDataService(act); + await service.SaveRosterAsync(new VendorCompanyRosterWriteModel + { + CompanyId = companyId, + Name = "Add Co", + CompanyPhone = "(444) 444-0004", + Address = "Add Addr", + City = "AddCity", + State = "AS", + Zip = "00004", + GoogleMapsUrl = "https://add.example/map", + ActorUserId = "42", + Technicians = new List + { + new() { ContactName = "Fresh", IsActive = true } + } + }, CancellationToken.None); + newTechId = act.Vendors.First(v => v.CompanyId == companyId && v.ContactName == "Fresh").Id; + } + + using var verify = NewContext(dbName); + var tech = verify.Vendors.Single(v => v.Id == newTechId); + tech.CompanyPhone.Should().Be("(444) 444-0004"); + tech.Address.Should().Be("Add Addr"); + tech.City.Should().Be("AddCity"); + tech.State.Should().Be("AS"); + tech.Zip.Should().Be("00004"); + tech.GoogleMapsUrl.Should().Be("https://add.example/map"); + } + + [Fact] + public async Task CreateRoster_NewTechnicianReceivesCompanyPhoneAndLocation() + { + var dbName = Guid.NewGuid().ToString(); + using var context = NewContext(dbName); + var service = new VendorCompanyRosterDataService(context); + + var roster = await service.CreateRosterAsync(new VendorCompanyRosterWriteModel + { + Name = "Create Co", + CompanyPhone = "(555) 555-0005", + Address = "Create Addr", + City = "CreateCity", + State = "CS", + Zip = "00005", + GoogleMapsUrl = "https://create.example/map", + ActorUserId = "42", + Technicians = new List + { + new() { ContactName = "Brand", IsActive = true } + } + }, CancellationToken.None); + + var tech = context.Vendors.Single(v => v.CompanyId == roster.CompanyId); + tech.CompanyPhone.Should().Be("(555) 555-0005"); + tech.Address.Should().Be("Create Addr"); + tech.City.Should().Be("CreateCity"); + tech.State.Should().Be("CS"); + tech.Zip.Should().Be("00005"); + tech.GoogleMapsUrl.Should().Be("https://create.example/map"); + } } diff --git a/SeaHaven.DataServices/Implementation/VendorCompanyRosterDataService.cs b/SeaHaven.DataServices/Implementation/VendorCompanyRosterDataService.cs index 40e1793..be37058 100644 --- a/SeaHaven.DataServices/Implementation/VendorCompanyRosterDataService.cs +++ b/SeaHaven.DataServices/Implementation/VendorCompanyRosterDataService.cs @@ -171,6 +171,12 @@ namespace SeaHaven.DataServices.Implementation existing.TradeSpecialties = technician.TradeSpecialties; existing.IsActive = technician.IsActive; existing.CompanyName = trimmedName; + existing.CompanyPhone = company.CompanyPhone; + existing.Address = company.Address; + existing.City = company.City; + existing.State = company.State; + existing.Zip = company.Zip; + existing.GoogleMapsUrl = company.GoogleMapsUrl; existing.LastModificationTime = now; if (actorId.HasValue) existing.LastModifierUserId = actorId; @@ -187,6 +193,7 @@ namespace SeaHaven.DataServices.Implementation TradeSpecialties = technician.TradeSpecialties, IsActive = technician.IsActive, CompanyId = company.Id, + CompanyPhone = company.CompanyPhone, Address = company.Address, City = company.City, State = company.State, @@ -243,6 +250,7 @@ namespace SeaHaven.DataServices.Implementation TradeSpecialties = technician.TradeSpecialties, IsActive = technician.IsActive, Company = company, + CompanyPhone = company.CompanyPhone, Address = company.Address, City = company.City, State = company.State,