feat(client): add ViewModelMappingExtensions for Core<->Client mapping

Add extension methods to convert between Core and Client view models:
- SearchViewModel: Core (enum Status) <-> Client (string Status)
- SearchCriteria: Core (primitive lists) <-> Client (full ViewModels)
- JdeUserViewModel -> OperatorViewModel

Handles structural differences in criteria where Core uses primitive
lists (List<long>, List<string>) and Client uses full objects.
This commit is contained in:
Joseph Doherty
2026-01-06 10:14:09 -05:00
parent 0b50c03e44
commit ba88450feb
@@ -0,0 +1,140 @@
using JdeScoping.Client.Models;
using JdeScoping.Core.Models.Enums;
using JdeScoping.Core.Models.Search;
using CoreSearch = JdeScoping.Core.ViewModels.SearchViewModel;
using CoreItem = JdeScoping.Core.ViewModels.ItemViewModel;
using CoreWorkOrder = JdeScoping.Core.ViewModels.WorkOrderViewModel;
using CoreProfitCenter = JdeScoping.Core.ViewModels.ProfitCenterViewModel;
using CoreWorkCenter = JdeScoping.Core.ViewModels.WorkCenterViewModel;
using CoreLot = JdeScoping.Core.ViewModels.LotViewModel;
using CorePartOp = JdeScoping.Core.ViewModels.PartOperationViewModel;
using CoreJdeUser = JdeScoping.Core.ViewModels.JdeUserViewModel;
namespace JdeScoping.Client.Extensions;
/// <summary>
/// Extension methods for mapping between Core and Client view models.
/// </summary>
public static class ViewModelMappingExtensions
{
/// <summary>
/// Maps Core SearchViewModel to Client SearchViewModel.
/// </summary>
public static SearchViewModel ToClient(this CoreSearch vm) => new()
{
Id = vm.Id,
Name = vm.Name,
UserName = vm.UserName,
Status = vm.Status.ToString(),
SubmitDt = vm.SubmitDt,
StartDt = vm.StartDt,
EndDt = vm.EndDt,
Criteria = vm.Criteria?.ToClientCriteria() ?? new()
};
/// <summary>
/// Maps Client SearchViewModel to Core SearchViewModel.
/// </summary>
public static CoreSearch ToCore(this SearchViewModel vm) => new()
{
Id = vm.Id,
Name = vm.Name,
UserName = vm.UserName,
Status = Enum.TryParse<SearchStatus>(vm.Status, out var status) ? status : SearchStatus.New,
SubmitDt = vm.SubmitDt,
StartDt = vm.StartDt,
EndDt = vm.EndDt,
Criteria = vm.Criteria.ToCoreCriteria()
};
/// <summary>
/// Maps Core SearchCriteria to Client SearchCriteriaViewModel.
/// Core uses primitive lists; Client uses full view model objects.
/// </summary>
public static SearchCriteriaViewModel ToClientCriteria(this SearchCriteria criteria)
{
var client = new SearchCriteriaViewModel
{
MinimumDt = criteria.MinimumDt,
MaximumDt = criteria.MaximumDt,
ExtractMisData = criteria.ExtractMisData
};
// Map work orders (Core has just numbers, Client has full WorkOrderViewModel)
client.WorkOrders = criteria.WorkOrderNumbers
.Select(n => new CoreWorkOrder { WorkOrderNumber = n })
.ToList();
// Map items (Core has just item number strings, Client has full ItemViewModel)
client.Items = criteria.ItemNumbers
.Select(n => new CoreItem { ItemNumber = n })
.ToList();
// Map profit centers (Core has just code strings, Client has full ProfitCenterViewModel)
client.ProfitCenters = criteria.ProfitCenters
.Select(pc => new CoreProfitCenter { Code = pc })
.ToList();
// Map work centers (Core has just code strings, Client has full WorkCenterViewModel)
client.WorkCenters = criteria.WorkCenters
.Select(wc => new CoreWorkCenter { Code = wc })
.ToList();
// Map operators (Core has just user ID strings, Client has full OperatorViewModel)
client.Operators = criteria.OperatorIDs
.Select(id => new OperatorViewModel { UserId = id })
.ToList();
// Map component lots (Core uses LotViewModel, Client uses ComponentLotViewModel)
client.ComponentLots = criteria.ComponentLotNumbers
.Select(l => new ComponentLotViewModel { LotNumber = l.LotNumber, ItemNumber = l.ItemNumber })
.ToList();
// Map part operations (both use PartOperationViewModel from Core)
client.PartOperations = criteria.PartOperations.ToList();
return client;
}
/// <summary>
/// Maps Client SearchCriteriaViewModel to Core SearchCriteria.
/// Client uses full view model objects; Core uses primitive lists.
/// </summary>
public static SearchCriteria ToCoreCriteria(this SearchCriteriaViewModel criteria) => new()
{
MinimumDt = criteria.MinimumDt,
MaximumDt = criteria.MaximumDt,
ExtractMisData = criteria.ExtractMisData,
WorkOrderNumbers = criteria.WorkOrders.Select(wo => wo.WorkOrderNumber).ToList(),
ItemNumbers = criteria.Items.Select(i => i.ItemNumber).ToList(),
ProfitCenters = criteria.ProfitCenters.Select(pc => pc.Code).ToList(),
WorkCenters = criteria.WorkCenters.Select(wc => wc.Code).ToList(),
OperatorIDs = criteria.Operators.Select(o => o.UserId).ToList(),
ComponentLotNumbers = criteria.ComponentLots
.Select(l => new CoreLot { LotNumber = l.LotNumber, ItemNumber = l.ItemNumber })
.ToList(),
PartOperations = criteria.PartOperations.ToList()
};
/// <summary>
/// Maps Core JdeUserViewModel to Client OperatorViewModel.
/// </summary>
public static OperatorViewModel ToClientOperator(this CoreJdeUser vm) => new()
{
AddressNumber = (int)vm.AddressNumber,
UserId = vm.UserId,
FullName = vm.FullName
};
/// <summary>
/// Maps a collection of Core SearchViewModels to Client SearchViewModels.
/// </summary>
public static List<SearchViewModel> ToClientList(this IEnumerable<CoreSearch> list) =>
list.Select(s => s.ToClient()).ToList();
/// <summary>
/// Maps a collection of Core JdeUserViewModels to Client OperatorViewModels.
/// </summary>
public static List<OperatorViewModel> ToClientOperatorList(this IEnumerable<CoreJdeUser> list) =>
list.Select(u => u.ToClientOperator()).ToList();
}