initial commit
This commit is contained in:
192
backend/API/Controllers/MaterialModifiersController.cs
Normal file
192
backend/API/Controllers/MaterialModifiersController.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using Extrudex.API.DTOs.Materials;
|
||||
using Extrudex.Domain.Entities;
|
||||
using Extrudex.Infrastructure.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Extrudex.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing material modifiers — optional additives or
|
||||
/// fillers for a material (e.g., "Carbon Fiber", "Wood Fill", "Glow-in-the-Dark").
|
||||
/// Not every spool has a modifier.
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/material-modifiers")]
|
||||
public class MaterialModifiersController : ControllerBase
|
||||
{
|
||||
private readonly ExtrudexDbContext _dbContext;
|
||||
private readonly ILogger<MaterialModifiersController> _logger;
|
||||
|
||||
public MaterialModifiersController(
|
||||
ExtrudexDbContext dbContext,
|
||||
ILogger<MaterialModifiersController> logger)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all material modifiers, optionally filtered by material base.
|
||||
/// </summary>
|
||||
/// <param name="materialBaseId">Optional filter: return modifiers for this material base only.</param>
|
||||
/// <returns>A list of material modifiers ordered by base material name, then modifier name.</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<MaterialModifierResponse>), StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<IEnumerable<MaterialModifierResponse>>> GetMaterialModifiers(
|
||||
[FromQuery] Guid? materialBaseId)
|
||||
{
|
||||
_logger.LogDebug("Getting material modifiers, filter: {MaterialBaseId}", materialBaseId);
|
||||
|
||||
var query = _dbContext.MaterialModifiers
|
||||
.Include(mm => mm.MaterialBase)
|
||||
.AsQueryable();
|
||||
|
||||
if (materialBaseId.HasValue)
|
||||
query = query.Where(mm => mm.MaterialBaseId == materialBaseId.Value);
|
||||
|
||||
var modifiers = await query
|
||||
.OrderBy(mm => mm.MaterialBase.Name)
|
||||
.ThenBy(mm => mm.Name)
|
||||
.Select(mm => MapToResponse(mm))
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(modifiers);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specific material modifier by ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the modifier.</param>
|
||||
/// <returns>The material modifier details.</returns>
|
||||
[HttpGet("{id:guid}")]
|
||||
[ProducesResponseType(typeof(MaterialModifierResponse), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult<MaterialModifierResponse>> GetMaterialModifier(Guid id)
|
||||
{
|
||||
_logger.LogDebug("Getting material modifier {Id}", id);
|
||||
|
||||
var mm = await _dbContext.MaterialModifiers
|
||||
.Include(mm => mm.MaterialBase)
|
||||
.FirstOrDefaultAsync(mm => mm.Id == id);
|
||||
|
||||
if (mm is null)
|
||||
{
|
||||
_logger.LogWarning("Material modifier {Id} not found", id);
|
||||
return NotFound(new { error = $"Material modifier with ID '{id}' not found." });
|
||||
}
|
||||
|
||||
return Ok(MapToResponse(mm));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new material modifier.
|
||||
/// </summary>
|
||||
/// <param name="request">The material modifier creation request.</param>
|
||||
/// <returns>The created material modifier.</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(MaterialModifierResponse), StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<MaterialModifierResponse>> CreateMaterialModifier(
|
||||
[FromBody] CreateMaterialModifierRequest request)
|
||||
{
|
||||
_logger.LogInformation("Creating material modifier: {Name} for base {MaterialBaseId}",
|
||||
request.Name, request.MaterialBaseId);
|
||||
|
||||
var materialBase = await _dbContext.MaterialBases.FindAsync(request.MaterialBaseId);
|
||||
if (materialBase is null)
|
||||
{
|
||||
return BadRequest(new { error = $"MaterialBase with ID '{request.MaterialBaseId}' not found." });
|
||||
}
|
||||
|
||||
var entity = new MaterialModifier
|
||||
{
|
||||
Name = request.Name,
|
||||
MaterialBaseId = request.MaterialBaseId
|
||||
};
|
||||
|
||||
_dbContext.MaterialModifiers.Add(entity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
// Reload with navigation for response mapping
|
||||
await _dbContext.Entry(entity).Reference(e => e.MaterialBase).LoadAsync();
|
||||
|
||||
var response = MapToResponse(entity);
|
||||
return CreatedAtAction(nameof(GetMaterialModifier), new { id = entity.Id }, response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an existing material modifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the modifier to update.</param>
|
||||
/// <param name="request">The material modifier update request.</param>
|
||||
/// <returns>The updated material modifier.</returns>
|
||||
[HttpPut("{id:guid}")]
|
||||
[ProducesResponseType(typeof(MaterialModifierResponse), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<MaterialModifierResponse>> UpdateMaterialModifier(
|
||||
Guid id, [FromBody] UpdateMaterialModifierRequest request)
|
||||
{
|
||||
_logger.LogInformation("Updating material modifier {Id}", id);
|
||||
|
||||
var entity = await _dbContext.MaterialModifiers.FindAsync(id);
|
||||
if (entity is null)
|
||||
{
|
||||
_logger.LogWarning("Material modifier {Id} not found for update", id);
|
||||
return NotFound(new { error = $"Material modifier with ID '{id}' not found." });
|
||||
}
|
||||
|
||||
var materialBase = await _dbContext.MaterialBases.FindAsync(request.MaterialBaseId);
|
||||
if (materialBase is null)
|
||||
{
|
||||
return BadRequest(new { error = $"MaterialBase with ID '{request.MaterialBaseId}' not found." });
|
||||
}
|
||||
|
||||
entity.Name = request.Name;
|
||||
entity.MaterialBaseId = request.MaterialBaseId;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
// Reload with navigation for response mapping
|
||||
await _dbContext.Entry(entity).Reference(e => e.MaterialBase).LoadAsync();
|
||||
|
||||
return Ok(MapToResponse(entity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a material modifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the modifier to delete.</param>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> DeleteMaterialModifier(Guid id)
|
||||
{
|
||||
_logger.LogInformation("Deleting material modifier {Id}", id);
|
||||
|
||||
var entity = await _dbContext.MaterialModifiers.FindAsync(id);
|
||||
if (entity is null)
|
||||
{
|
||||
_logger.LogWarning("Material modifier {Id} not found for deletion", id);
|
||||
return NotFound(new { error = $"Material modifier with ID '{id}' not found." });
|
||||
}
|
||||
|
||||
_dbContext.MaterialModifiers.Remove(entity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
// ── Mapping helper ──────────────────────────────────────────
|
||||
|
||||
private static MaterialModifierResponse MapToResponse(MaterialModifier mm) => new()
|
||||
{
|
||||
Id = mm.Id,
|
||||
Name = mm.Name,
|
||||
MaterialBaseId = mm.MaterialBaseId,
|
||||
MaterialBaseName = mm.MaterialBase?.Name ?? string.Empty,
|
||||
CreatedAt = mm.CreatedAt,
|
||||
UpdatedAt = mm.UpdatedAt
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user