mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-05 08:22:10 +00:00
fix(work-orders): scope legacy list/detail GETs by account [SH-221]
Close the remaining SH-221 read gap so Getworkorders, filtered lists, and GetWorkorderById enforce the same server-derived account boundary as board/media. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
bca2e0d50d
commit
62a4828e2f
6 changed files with 217 additions and 38 deletions
|
|
@ -193,10 +193,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var accountId = _accountResolver.ResolveAccountFilter(User);
|
||||||
var result = await _workOrderService.GetFilteredWorkOrdersAsync(
|
var result = await _workOrderService.GetFilteredWorkOrdersAsync(
|
||||||
assignto, location, priority, status, duedate, search, sort, sortby, page, pageSize);
|
assignto, location, priority, status, duedate, search, sort, sortby, page, pageSize, accountId);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
catch (WorkOrderBoardValidationException ex) when (ex.Code == "Forbidden")
|
||||||
|
{
|
||||||
|
return StatusCode(StatusCodes.Status403Forbidden, new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return StatusCode(500, "Internal Server Error");
|
return StatusCode(500, "Internal Server Error");
|
||||||
|
|
@ -207,10 +212,18 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
[HttpGet("GetWorkorderById")]
|
[HttpGet("GetWorkorderById")]
|
||||||
public async Task<IActionResult> GetWorkorderById(int id)
|
public async Task<IActionResult> GetWorkorderById(int id)
|
||||||
{
|
{
|
||||||
var detail = await _workOrderService.GetWorkOrderDetailAsync(id);
|
try
|
||||||
if (detail == null)
|
{
|
||||||
return BadRequest(new Response { Status = "Error", Message = "ID not found!" });
|
var accountId = _accountResolver.ResolveAccountFilter(User);
|
||||||
return Ok(detail);
|
var detail = await _workOrderService.GetWorkOrderDetailAsync(id, accountId);
|
||||||
|
if (detail == null)
|
||||||
|
return BadRequest(new Response { Status = "Error", Message = "ID not found!" });
|
||||||
|
return Ok(detail);
|
||||||
|
}
|
||||||
|
catch (WorkOrderBoardValidationException ex) when (ex.Code == "Forbidden")
|
||||||
|
{
|
||||||
|
return StatusCode(StatusCodes.Status403Forbidden, new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
|
@ -229,10 +242,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var accountId = _accountResolver.ResolveAccountFilter(User);
|
||||||
var result = await _workOrderService.GetFilteredWorkOrders2Async(
|
var result = await _workOrderService.GetFilteredWorkOrders2Async(
|
||||||
assignto, location, priority, status, duedate, search, sort, sortby, page, pageSize);
|
assignto, location, priority, status, duedate, search, sort, sortby, page, pageSize, accountId);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
catch (WorkOrderBoardValidationException ex) when (ex.Code == "Forbidden")
|
||||||
|
{
|
||||||
|
return StatusCode(StatusCodes.Status403Forbidden, new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
var totalCount = await _workOrderService.GetTotalWorkOrderCountAsync();
|
var totalCount = await _workOrderService.GetTotalWorkOrderCountAsync();
|
||||||
|
|
@ -352,16 +370,32 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
[Route("GetworkordersDD")]
|
[Route("GetworkordersDD")]
|
||||||
public async Task<IActionResult> GetworkordersDD()
|
public async Task<IActionResult> GetworkordersDD()
|
||||||
{
|
{
|
||||||
var data = await _workOrderService.GetWorkordersDDAsync();
|
try
|
||||||
return Ok(data);
|
{
|
||||||
|
var accountId = _accountResolver.ResolveAccountFilter(User);
|
||||||
|
var data = await _workOrderService.GetWorkordersDDAsync(accountId);
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
catch (WorkOrderBoardValidationException ex) when (ex.Code == "Forbidden")
|
||||||
|
{
|
||||||
|
return StatusCode(StatusCodes.Status403Forbidden, new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Getworkorders")]
|
[Route("Getworkorders")]
|
||||||
public async Task<IActionResult> Getworkorders()
|
public async Task<IActionResult> Getworkorders()
|
||||||
{
|
{
|
||||||
var data = await _workOrderService.GetWorkordersAsync();
|
try
|
||||||
return Ok(data);
|
{
|
||||||
|
var accountId = _accountResolver.ResolveAccountFilter(User);
|
||||||
|
var data = await _workOrderService.GetWorkordersAsync(accountId);
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
catch (WorkOrderBoardValidationException ex) when (ex.Code == "Forbidden")
|
||||||
|
{
|
||||||
|
return StatusCode(StatusCodes.Status403Forbidden, new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -373,10 +373,15 @@ namespace SeaHaven.DataServices.Implementation
|
||||||
return await _context.workOrders.CountAsync(w => w.LocationId == locationId);
|
return await _context.workOrders.CountAsync(w => w.LocationId == locationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<WorkOrder>> GetAllWithDetailsAsync()
|
public async Task<IEnumerable<WorkOrder>> GetAllWithDetailsAsync(int? accountId = null)
|
||||||
{
|
{
|
||||||
return await _context.workOrders
|
IQueryable<WorkOrder> query = _context.workOrders
|
||||||
.Where(w => w.istemplate != true)
|
.Where(w => w.istemplate != true);
|
||||||
|
|
||||||
|
if (accountId.HasValue)
|
||||||
|
query = WorkOrderBoardQueryFilters.ApplyAccountScope(query, accountId.Value);
|
||||||
|
|
||||||
|
return await query
|
||||||
.Include(w => w.Locations)
|
.Include(w => w.Locations)
|
||||||
.Include(w => w.AssignToUser)
|
.Include(w => w.AssignToUser)
|
||||||
.AsSplitQuery()
|
.AsSplitQuery()
|
||||||
|
|
@ -408,11 +413,16 @@ namespace SeaHaven.DataServices.Implementation
|
||||||
return ordered;
|
return ordered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id)
|
public async Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id, int? accountId = null)
|
||||||
{
|
{
|
||||||
return await _context.workOrders
|
var query = _context.workOrders
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(w => w.Id == id)
|
.Where(w => w.Id == id);
|
||||||
|
|
||||||
|
if (accountId.HasValue)
|
||||||
|
query = WorkOrderBoardQueryFilters.ApplyAccountScope(query, accountId.Value);
|
||||||
|
|
||||||
|
return await query
|
||||||
.Select(s => new WorkOrderDetailReadModel
|
.Select(s => new WorkOrderDetailReadModel
|
||||||
{
|
{
|
||||||
Id = s.Id,
|
Id = s.Id,
|
||||||
|
|
@ -509,10 +519,15 @@ namespace SeaHaven.DataServices.Implementation
|
||||||
}).FirstOrDefaultAsync();
|
}).FirstOrDefaultAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<WorkOrder>> GetNonTemplateWorkOrdersWithLocationsAsync()
|
public async Task<List<WorkOrder>> GetNonTemplateWorkOrdersWithLocationsAsync(int? accountId = null)
|
||||||
{
|
{
|
||||||
return await _context.workOrders
|
IQueryable<WorkOrder> query = _context.workOrders
|
||||||
.Where(w => w.istemplate != true)
|
.Where(w => w.istemplate != true);
|
||||||
|
|
||||||
|
if (accountId.HasValue)
|
||||||
|
query = WorkOrderBoardQueryFilters.ApplyAccountScope(query, accountId.Value);
|
||||||
|
|
||||||
|
return await query
|
||||||
.Include(w => w.Locations)
|
.Include(w => w.Locations)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ namespace SeaHaven.DataServices.Interfaces
|
||||||
Task<int> CountByStatusAsync(string status);
|
Task<int> CountByStatusAsync(string status);
|
||||||
Task<int> CountByPriorityAsync(string priority);
|
Task<int> CountByPriorityAsync(string priority);
|
||||||
Task<int> CountByLocationAsync(int locationId);
|
Task<int> CountByLocationAsync(int locationId);
|
||||||
Task<IEnumerable<WorkOrder>> GetAllWithDetailsAsync();
|
Task<IEnumerable<WorkOrder>> GetAllWithDetailsAsync(int? accountId = null);
|
||||||
|
|
||||||
// Batched lookup: server-filters the distinct requested ids, excludes templates,
|
// Batched lookup: server-filters the distinct requested ids, excludes templates,
|
||||||
// eagerly loads the location detail, deduplicates, and returns results in input order.
|
// eagerly loads the location detail, deduplicates, and returns results in input order.
|
||||||
|
|
@ -80,7 +80,7 @@ namespace SeaHaven.DataServices.Interfaces
|
||||||
CancellationToken cancellationToken);
|
CancellationToken cancellationToken);
|
||||||
|
|
||||||
// Complex read models
|
// Complex read models
|
||||||
Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id);
|
Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id, int? accountId = null);
|
||||||
Task<List<WorkOrder>> GetNonTemplateWorkOrdersWithLocationsAsync();
|
Task<List<WorkOrder>> GetNonTemplateWorkOrdersWithLocationsAsync(int? accountId = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,17 +138,17 @@ namespace SeaHaven.Services.Implementation
|
||||||
page, pageSize, search, status, assignee, locationId, sortBy, sortDir, accountId);
|
page, pageSize, search, status, assignee, locationId, sortBy, sortDir, accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id)
|
public async Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id, int? accountId = null)
|
||||||
{
|
{
|
||||||
return await _workOrderDataService.GetWorkOrderDetailAsync(id);
|
return await _workOrderDataService.GetWorkOrderDetailAsync(id, accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrdersAsync(
|
public async Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrdersAsync(
|
||||||
string[] assignto, int[]? location, string[]? priority,
|
string[] assignto, int[]? location, string[]? priority,
|
||||||
string[]? status, string[]? duedate, string search,
|
string[]? status, string[]? duedate, string search,
|
||||||
string sort, string sortby, int page, int pageSize)
|
string sort, string sortby, int page, int pageSize, int? accountId = null)
|
||||||
{
|
{
|
||||||
var allWorkOrders = await _workOrderDataService.GetNonTemplateWorkOrdersWithLocationsAsync();
|
var allWorkOrders = await _workOrderDataService.GetNonTemplateWorkOrdersWithLocationsAsync(accountId);
|
||||||
|
|
||||||
var data = allWorkOrders.AsEnumerable();
|
var data = allWorkOrders.AsEnumerable();
|
||||||
|
|
||||||
|
|
@ -230,7 +230,7 @@ namespace SeaHaven.Services.Implementation
|
||||||
public async Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrders2Async(
|
public async Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrders2Async(
|
||||||
string[] assignto, int[]? location, string[]? priority,
|
string[] assignto, int[]? location, string[]? priority,
|
||||||
string[]? status, string[]? duedate, string search,
|
string[]? status, string[]? duedate, string search,
|
||||||
string sort, string sortby, int page, int pageSize)
|
string sort, string sortby, int page, int pageSize, int? accountId = null)
|
||||||
{
|
{
|
||||||
location ??= Array.Empty<int>();
|
location ??= Array.Empty<int>();
|
||||||
priority ??= Array.Empty<string>();
|
priority ??= Array.Empty<string>();
|
||||||
|
|
@ -238,7 +238,7 @@ namespace SeaHaven.Services.Implementation
|
||||||
duedate ??= Array.Empty<string>();
|
duedate ??= Array.Empty<string>();
|
||||||
search ??= string.Empty;
|
search ??= string.Empty;
|
||||||
|
|
||||||
var allWorkOrders = await _workOrderDataService.GetNonTemplateWorkOrdersWithLocationsAsync();
|
var allWorkOrders = await _workOrderDataService.GetNonTemplateWorkOrdersWithLocationsAsync(accountId);
|
||||||
var totalCount = allWorkOrders.Count;
|
var totalCount = allWorkOrders.Count;
|
||||||
|
|
||||||
var currentDate = DateTime.UtcNow.Date;
|
var currentDate = DateTime.UtcNow.Date;
|
||||||
|
|
@ -505,15 +505,15 @@ namespace SeaHaven.Services.Implementation
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<WorkOrder>> GetWorkordersDDAsync()
|
public async Task<IEnumerable<WorkOrder>> GetWorkordersDDAsync(int? accountId = null)
|
||||||
{
|
{
|
||||||
var data = await _workOrderDataService.GetAllAsync();
|
var data = await _workOrderDataService.GetNonTemplateWorkOrdersWithLocationsAsync(accountId);
|
||||||
return data.Where(w => w.istemplate != true).ToList();
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<WorkorderFilterVM>> GetWorkordersAsync()
|
public async Task<IEnumerable<WorkorderFilterVM>> GetWorkordersAsync(int? accountId = null)
|
||||||
{
|
{
|
||||||
var workOrders = await _workOrderDataService.GetAllWithDetailsAsync();
|
var workOrders = await _workOrderDataService.GetAllWithDetailsAsync(accountId);
|
||||||
return workOrders.Select(s => new WorkorderFilterVM
|
return workOrders.Select(s => new WorkorderFilterVM
|
||||||
{
|
{
|
||||||
Id = s.Id,
|
Id = s.Id,
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,15 @@ namespace SeaHaven.Services.Interfaces
|
||||||
Task<(IEnumerable<WorkOrderListItemReadModel> Items, int TotalCount)> GetWorkOrderListPagedAsync(
|
Task<(IEnumerable<WorkOrderListItemReadModel> Items, int TotalCount)> GetWorkOrderListPagedAsync(
|
||||||
int page, int pageSize, string? search, string? status, string? assignee,
|
int page, int pageSize, string? search, string? status, string? assignee,
|
||||||
int? locationId, string? sortBy, string? sortDir, int? accountId = null);
|
int? locationId, string? sortBy, string? sortDir, int? accountId = null);
|
||||||
Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id);
|
Task<WorkOrderDetailReadModel?> GetWorkOrderDetailAsync(int id, int? accountId = null);
|
||||||
Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrdersAsync(
|
Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrdersAsync(
|
||||||
string[] assignto, int[]? location, string[]? priority,
|
string[] assignto, int[]? location, string[]? priority,
|
||||||
string[]? status, string[]? duedate, string search, string sort, string sortby, int page, int pageSize);
|
string[]? status, string[]? duedate, string search, string sort, string sortby, int page, int pageSize,
|
||||||
|
int? accountId = null);
|
||||||
Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrders2Async(
|
Task<FilteredWorkOrderPageDTO> GetFilteredWorkOrders2Async(
|
||||||
string[] assignto, int[]? location, string[]? priority,
|
string[] assignto, int[]? location, string[]? priority,
|
||||||
string[]? status, string[]? duedate, string search, string sort, string sortby, int page, int pageSize);
|
string[]? status, string[]? duedate, string search, string sort, string sortby, int page, int pageSize,
|
||||||
|
int? accountId = null);
|
||||||
Task<WorkOrderDTO?> ChangeStatusAsync(int id, string status, string userId);
|
Task<WorkOrderDTO?> ChangeStatusAsync(int id, string status, string userId);
|
||||||
Task<ChangeAssignmentResult?> ChangeAssignmentAsync(int id, string? assignTo, string userId);
|
Task<ChangeAssignmentResult?> ChangeAssignmentAsync(int id, string? assignTo, string userId);
|
||||||
Task<int> CreateWorkOrderWithDetailsAsync(CreateWorkOrderWithDetailsInput input, ClaimsPrincipal user, string userId);
|
Task<int> CreateWorkOrderWithDetailsAsync(CreateWorkOrderWithDetailsInput input, ClaimsPrincipal user, string userId);
|
||||||
|
|
@ -39,7 +41,7 @@ namespace SeaHaven.Services.Interfaces
|
||||||
Task<CommentResult> AddCommentJsonAsync(AddCommentInput input, string userId);
|
Task<CommentResult> AddCommentJsonAsync(AddCommentInput input, string userId);
|
||||||
Task<IEnumerable<CommentListItemReadModel>> GetCommentsAsync();
|
Task<IEnumerable<CommentListItemReadModel>> GetCommentsAsync();
|
||||||
Task<IEnumerable<CommentListItemReadModel>> GetCommentsByWorkorderIdAsync(int woid);
|
Task<IEnumerable<CommentListItemReadModel>> GetCommentsByWorkorderIdAsync(int woid);
|
||||||
Task<IEnumerable<WorkOrder>> GetWorkordersDDAsync();
|
Task<IEnumerable<WorkOrder>> GetWorkordersDDAsync(int? accountId = null);
|
||||||
Task<IEnumerable<WorkorderFilterVM>> GetWorkordersAsync();
|
Task<IEnumerable<WorkorderFilterVM>> GetWorkordersAsync(int? accountId = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -301,4 +301,132 @@ public class WorkOrderAccountScopeTests
|
||||||
|
|
||||||
Assert.Equal("Forbidden", ex.Code);
|
Assert.Equal("Forbidden", ex.Code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task LegacyList_ScopedUser_HidesOtherAccountAndNullAccountRows()
|
||||||
|
{
|
||||||
|
await using var context = CreateContext();
|
||||||
|
await SeedThreeAccountRowsAsync(context);
|
||||||
|
|
||||||
|
var data = new WorkOrderDataService(context);
|
||||||
|
var scoped = (await data.GetAllWithDetailsAsync(accountId: 1)).ToList();
|
||||||
|
var dd = await data.GetNonTemplateWorkOrdersWithLocationsAsync(accountId: 1);
|
||||||
|
|
||||||
|
Assert.Single(scoped);
|
||||||
|
Assert.Equal(1, scoped[0].Id);
|
||||||
|
Assert.Single(dd);
|
||||||
|
Assert.Equal(1, dd[0].Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task LegacyList_OrgWide_IncludesNullAccountRows()
|
||||||
|
{
|
||||||
|
await using var context = CreateContext();
|
||||||
|
await SeedThreeAccountRowsAsync(context);
|
||||||
|
|
||||||
|
var data = new WorkOrderDataService(context);
|
||||||
|
var orgWide = (await data.GetAllWithDetailsAsync(accountId: null)).ToList();
|
||||||
|
|
||||||
|
Assert.Equal(3, orgWide.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task LegacyDetail_CrossAccount_ReturnsNull()
|
||||||
|
{
|
||||||
|
await using var context = CreateContext();
|
||||||
|
await SeedThreeAccountRowsAsync(context);
|
||||||
|
|
||||||
|
var data = new WorkOrderDataService(context);
|
||||||
|
var detail = await data.GetWorkOrderDetailAsync(2, accountId: 1);
|
||||||
|
|
||||||
|
Assert.Null(detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task LegacyDetail_SameAccount_ReturnsRow()
|
||||||
|
{
|
||||||
|
await using var context = CreateContext();
|
||||||
|
await SeedThreeAccountRowsAsync(context);
|
||||||
|
|
||||||
|
var data = new WorkOrderDataService(context);
|
||||||
|
var detail = await data.GetWorkOrderDetailAsync(1, accountId: 1);
|
||||||
|
|
||||||
|
Assert.NotNull(detail);
|
||||||
|
Assert.Equal(1, detail!.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task LegacyDetail_OrgWide_CanReadNullAccountRow()
|
||||||
|
{
|
||||||
|
await using var context = CreateContext();
|
||||||
|
await SeedThreeAccountRowsAsync(context);
|
||||||
|
|
||||||
|
var data = new WorkOrderDataService(context);
|
||||||
|
var detail = await data.GetWorkOrderDetailAsync(3, accountId: null);
|
||||||
|
|
||||||
|
Assert.NotNull(detail);
|
||||||
|
Assert.Equal(3, detail!.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task LegacyFiltered_ScopedUser_HidesOtherAccountAndNullAccountRows()
|
||||||
|
{
|
||||||
|
await using var context = CreateContext();
|
||||||
|
await SeedThreeAccountRowsAsync(context);
|
||||||
|
|
||||||
|
var service = CreateLegacyReadService(context);
|
||||||
|
var page = await service.GetFilteredWorkOrdersAsync(
|
||||||
|
Array.Empty<string>(), null, null, null, null,
|
||||||
|
search: "", sort: "", sortby: "", page: 1, pageSize: 50, accountId: 1);
|
||||||
|
|
||||||
|
Assert.Equal(1, page.TotalCount);
|
||||||
|
Assert.Single(page.Data);
|
||||||
|
Assert.Equal(1, page.Data.First().Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WorkOrderService CreateLegacyReadService(ApplicationDbContext context)
|
||||||
|
{
|
||||||
|
return new WorkOrderService(
|
||||||
|
new WorkOrderDataService(context),
|
||||||
|
new CommentDataService(context),
|
||||||
|
new UserDataService(context),
|
||||||
|
new QuotesDataService(context),
|
||||||
|
fileStorage: null!,
|
||||||
|
new CreateWorkOrderValidation(),
|
||||||
|
new UpdateWorkOrderValidation(),
|
||||||
|
WorkOrderAccountTestHelpers.Resolver(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task SeedThreeAccountRowsAsync(ApplicationDbContext context)
|
||||||
|
{
|
||||||
|
await WorkOrderAccountTestHelpers.EnsureAccountAsync(context, 1, "A");
|
||||||
|
await WorkOrderAccountTestHelpers.EnsureAccountAsync(context, 2, "B");
|
||||||
|
|
||||||
|
context.workOrders.AddRange(
|
||||||
|
new WorkOrder
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
InternalWONumber = "00000000001",
|
||||||
|
AccountId = 1,
|
||||||
|
LifecycleStatus = LifecycleStatus.Scheduled,
|
||||||
|
istemplate = false
|
||||||
|
},
|
||||||
|
new WorkOrder
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
InternalWONumber = "00000000002",
|
||||||
|
AccountId = 2,
|
||||||
|
LifecycleStatus = LifecycleStatus.Scheduled,
|
||||||
|
istemplate = false
|
||||||
|
},
|
||||||
|
new WorkOrder
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
InternalWONumber = "00000000003",
|
||||||
|
AccountId = null,
|
||||||
|
LifecycleStatus = LifecycleStatus.Scheduled,
|
||||||
|
istemplate = false
|
||||||
|
});
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue