feat: Add job and cutting tool API client methods

Add HTTP client methods for job CRUD, parts, stock, packing, and
cutting tool endpoints. Includes response DTOs for all job-related
API responses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 22:20:53 -05:00
parent 2fdf006a8e
commit 1f3eb67eb7

View File

@@ -109,6 +109,109 @@ public class ApiClient
#endregion
#region Jobs
public async Task<List<ApiJobDto>> GetJobsAsync()
{
return await _http.GetFromJsonAsync<List<ApiJobDto>>("api/jobs") ?? [];
}
public async Task<ApiJobDetailDto?> GetJobAsync(int id)
{
return await _http.GetFromJsonAsync<ApiJobDetailDto>($"api/jobs/{id}");
}
public async Task<ApiJobDetailDto?> CreateJobAsync(string? name, string? customer, int? cuttingToolId, string? notes)
{
var response = await _http.PostAsJsonAsync("api/jobs", new { Name = name, Customer = customer, CuttingToolId = cuttingToolId, Notes = notes });
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ApiJobDetailDto>();
}
public async Task<ApiJobDetailDto?> UpdateJobAsync(int id, string? name, string? customer, int? cuttingToolId, string? notes)
{
var response = await _http.PutAsJsonAsync($"api/jobs/{id}", new { Name = name, Customer = customer, CuttingToolId = cuttingToolId, Notes = notes });
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ApiJobDetailDto>();
}
public async Task DeleteJobAsync(int id)
{
var response = await _http.DeleteAsync($"api/jobs/{id}");
response.EnsureSuccessStatusCode();
}
public async Task<ApiJobPartDto?> AddJobPartAsync(int jobId, int materialId, string name, string length, int quantity)
{
var response = await _http.PostAsJsonAsync($"api/jobs/{jobId}/parts", new { MaterialId = materialId, Name = name, Length = length, Quantity = quantity });
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ApiJobPartDto>();
}
public async Task<ApiJobPartDto?> UpdateJobPartAsync(int jobId, int partId, int? materialId, string? name, string? length, int? quantity)
{
var response = await _http.PutAsJsonAsync($"api/jobs/{jobId}/parts/{partId}", new { MaterialId = materialId, Name = name, Length = length, Quantity = quantity });
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ApiJobPartDto>();
}
public async Task DeleteJobPartAsync(int jobId, int partId)
{
var response = await _http.DeleteAsync($"api/jobs/{jobId}/parts/{partId}");
response.EnsureSuccessStatusCode();
}
public async Task<ApiJobStockDto?> AddJobStockAsync(int jobId, int materialId, int? stockItemId, string length, int quantity, bool isCustomLength, int priority)
{
var response = await _http.PostAsJsonAsync($"api/jobs/{jobId}/stock", new
{
MaterialId = materialId,
StockItemId = stockItemId,
Length = length,
Quantity = quantity,
IsCustomLength = isCustomLength,
Priority = priority
});
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ApiJobStockDto>();
}
public async Task DeleteJobStockAsync(int jobId, int stockId)
{
var response = await _http.DeleteAsync($"api/jobs/{jobId}/stock/{stockId}");
response.EnsureSuccessStatusCode();
}
public async Task<ApiPackResponseDto?> PackJobAsync(int jobId, decimal? kerfOverride = null)
{
var response = await _http.PostAsJsonAsync($"api/jobs/{jobId}/pack", new { KerfOverride = kerfOverride });
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ApiPackResponseDto>();
}
#endregion
#region Cutting Tools
public async Task<List<ApiCuttingToolDto>> GetCuttingToolsAsync(bool includeInactive = false)
{
return await _http.GetFromJsonAsync<List<ApiCuttingToolDto>>($"api/cutting-tools?includeInactive={includeInactive}") ?? [];
}
public async Task<ApiCuttingToolDto?> GetDefaultCuttingToolAsync()
{
try
{
return await _http.GetFromJsonAsync<ApiCuttingToolDto>("api/cutting-tools/default");
}
catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return null;
}
}
#endregion
#region Offerings
public async Task<List<ApiOfferingDto>> GetOfferingsForSupplierAsync(int supplierId)
@@ -153,7 +256,134 @@ public class ApiConflictException : Exception
public ApiConflictException(string message) : base(message) { }
}
#region API Response DTOs
#region API Response DTOs Jobs & Cutting Tools
public class ApiJobDto
{
public int Id { get; set; }
public string JobNumber { get; set; } = string.Empty;
public string? Name { get; set; }
public string? Customer { get; set; }
public int? CuttingToolId { get; set; }
public string? CuttingToolName { get; set; }
public string? Notes { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public int PartCount { get; set; }
public int StockCount { get; set; }
}
public class ApiJobDetailDto : ApiJobDto
{
public List<ApiJobPartDto> Parts { get; set; } = new();
public List<ApiJobStockDto> Stock { get; set; } = new();
}
public class ApiJobPartDto
{
public int Id { get; set; }
public int JobId { get; set; }
public int MaterialId { get; set; }
public string MaterialName { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public decimal LengthInches { get; set; }
public string LengthFormatted { get; set; } = string.Empty;
public int Quantity { get; set; }
public int SortOrder { get; set; }
}
public class ApiJobStockDto
{
public int Id { get; set; }
public int JobId { get; set; }
public int MaterialId { get; set; }
public string MaterialName { get; set; } = string.Empty;
public int? StockItemId { get; set; }
public decimal LengthInches { get; set; }
public string LengthFormatted { get; set; } = string.Empty;
public int Quantity { get; set; }
public bool IsCustomLength { get; set; }
public int Priority { get; set; }
public int SortOrder { get; set; }
}
public class ApiCuttingToolDto
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal KerfInches { get; set; }
public bool IsDefault { get; set; }
public bool IsActive { get; set; }
}
public class ApiPackResponseDto
{
public List<ApiMaterialPackResultDto> Materials { get; set; } = new();
public ApiPackingSummaryDto Summary { get; set; } = new();
}
public class ApiMaterialPackResultDto
{
public int MaterialId { get; set; }
public string MaterialName { get; set; } = string.Empty;
public List<ApiPackedBinDto> InStockBins { get; set; } = new();
public List<ApiPackedBinDto> ToBePurchasedBins { get; set; } = new();
public List<ApiPackedItemDto> ItemsNotPlaced { get; set; } = new();
public ApiMaterialPackingSummaryDto Summary { get; set; } = new();
}
public class ApiPackedBinDto
{
public double LengthInches { get; set; }
public string LengthFormatted { get; set; } = string.Empty;
public double UsedInches { get; set; }
public string UsedFormatted { get; set; } = string.Empty;
public double WasteInches { get; set; }
public string WasteFormatted { get; set; } = string.Empty;
public double Efficiency { get; set; }
public List<ApiPackedItemDto> Items { get; set; } = new();
}
public class ApiPackedItemDto
{
public string Name { get; set; } = string.Empty;
public double LengthInches { get; set; }
public string LengthFormatted { get; set; } = string.Empty;
}
public class ApiPackingSummaryDto
{
public int TotalInStockBins { get; set; }
public int TotalToBePurchasedBins { get; set; }
public int TotalPieces { get; set; }
public double TotalMaterialInches { get; set; }
public string TotalMaterialFormatted { get; set; } = string.Empty;
public double TotalUsedInches { get; set; }
public string TotalUsedFormatted { get; set; } = string.Empty;
public double TotalWasteInches { get; set; }
public string TotalWasteFormatted { get; set; } = string.Empty;
public double Efficiency { get; set; }
public int TotalItemsNotPlaced { get; set; }
public List<ApiMaterialPackingSummaryDto> MaterialSummaries { get; set; } = new();
}
public class ApiMaterialPackingSummaryDto
{
public int MaterialId { get; set; }
public string MaterialName { get; set; } = string.Empty;
public int InStockBins { get; set; }
public int ToBePurchasedBins { get; set; }
public int TotalPieces { get; set; }
public double TotalMaterialInches { get; set; }
public double TotalUsedInches { get; set; }
public double TotalWasteInches { get; set; }
public double Efficiency { get; set; }
public int ItemsNotPlaced { get; set; }
}
#endregion
#region API Response DTOs Inventory
public class ApiSupplierDto
{