line-gestao-api/Controllers/ChipsVirgensController.cs

199 lines
6.9 KiB
C#

using line_gestao_api.Data;
using line_gestao_api.Dtos;
using line_gestao_api.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Globalization;
using System.Text;
namespace line_gestao_api.Controllers
{
[ApiController]
[Route("api/chips-virgens")]
[Authorize]
public class ChipsVirgensController : ControllerBase
{
private readonly AppDbContext _db;
public ChipsVirgensController(AppDbContext db)
{
_db = db;
}
[HttpGet]
public async Task<ActionResult<PagedResult<ChipVirgemListDto>>> GetAll(
[FromQuery] string? search,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 20,
[FromQuery] string? sortBy = "item",
[FromQuery] string? sortDir = "asc")
{
page = page < 1 ? 1 : page;
pageSize = pageSize < 1 ? 20 : pageSize;
var q = _db.ChipVirgemLines.AsNoTracking();
if (!string.IsNullOrWhiteSpace(search))
{
var s = search.Trim();
var hasDateSearch = TryParseSearchDateUtcStart(s, out var searchDateStartUtc);
var searchDateEndUtc = hasDateSearch ? searchDateStartUtc.AddDays(1) : DateTime.MinValue;
q = q.Where(x =>
EF.Functions.ILike(x.NumeroDoChip ?? "", $"%{s}%") ||
EF.Functions.ILike(x.Observacoes ?? "", $"%{s}%") ||
EF.Functions.ILike(x.Item.ToString(), $"%{s}%") ||
(hasDateSearch &&
((x.CreatedAt >= searchDateStartUtc && x.CreatedAt < searchDateEndUtc) ||
(x.UpdatedAt >= searchDateStartUtc && x.UpdatedAt < searchDateEndUtc))));
}
var total = await q.CountAsync();
var sb = (sortBy ?? "item").Trim().ToLowerInvariant();
var desc = string.Equals((sortDir ?? "asc").Trim(), "desc", StringComparison.OrdinalIgnoreCase);
q = sb switch
{
"numerodochip" => desc ? q.OrderByDescending(x => x.NumeroDoChip ?? "").ThenBy(x => x.Item)
: q.OrderBy(x => x.NumeroDoChip ?? "").ThenBy(x => x.Item),
"observacoes" => desc ? q.OrderByDescending(x => x.Observacoes ?? "").ThenBy(x => x.Item)
: q.OrderBy(x => x.Observacoes ?? "").ThenBy(x => x.Item),
_ => desc ? q.OrderByDescending(x => x.Item) : q.OrderBy(x => x.Item)
};
var items = await q
.Skip((page - 1) * pageSize)
.Take(pageSize)
.Select(x => new ChipVirgemListDto
{
Id = x.Id,
Item = x.Item,
NumeroDoChip = x.NumeroDoChip,
Observacoes = x.Observacoes
})
.ToListAsync();
return Ok(new PagedResult<ChipVirgemListDto>
{
Page = page,
PageSize = pageSize,
Total = total,
Items = items
});
}
[HttpGet("{id:guid}")]
public async Task<ActionResult<ChipVirgemDetailDto>> GetById(Guid id)
{
var x = await _db.ChipVirgemLines.AsNoTracking().FirstOrDefaultAsync(a => a.Id == id);
if (x == null) return NotFound();
return Ok(ToDetailDto(x));
}
[HttpPost]
[Authorize(Roles = "admin,gestor")]
public async Task<ActionResult<ChipVirgemDetailDto>> Create([FromBody] CreateChipVirgemDto req)
{
var now = DateTime.UtcNow;
var item = req.Item ?? 0;
if (item <= 0)
{
var maxItem = await _db.ChipVirgemLines.MaxAsync(x => (int?)x.Item) ?? 0;
item = maxItem + 1;
}
var e = new ChipVirgemLine
{
Id = Guid.NewGuid(),
Item = item,
NumeroDoChip = NullIfEmptyDigits(req.NumeroDoChip),
Observacoes = string.IsNullOrWhiteSpace(req.Observacoes) ? null : req.Observacoes.Trim(),
CreatedAt = now,
UpdatedAt = now
};
_db.ChipVirgemLines.Add(e);
await _db.SaveChangesAsync();
return CreatedAtAction(nameof(GetById), new { id = e.Id }, ToDetailDto(e));
}
[HttpPut("{id:guid}")]
[Authorize(Roles = "admin")]
public async Task<IActionResult> Update(Guid id, [FromBody] UpdateChipVirgemRequest req)
{
var x = await _db.ChipVirgemLines.FirstOrDefaultAsync(a => a.Id == id);
if (x == null) return NotFound();
if (req.Item.HasValue) x.Item = req.Item.Value;
x.NumeroDoChip = NullIfEmptyDigits(req.NumeroDoChip);
x.Observacoes = string.IsNullOrWhiteSpace(req.Observacoes) ? null : req.Observacoes.Trim();
x.UpdatedAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
return NoContent();
}
[HttpDelete("{id:guid}")]
[Authorize(Roles = "admin")]
public async Task<IActionResult> Delete(Guid id)
{
var x = await _db.ChipVirgemLines.FirstOrDefaultAsync(a => a.Id == id);
if (x == null) return NotFound();
_db.ChipVirgemLines.Remove(x);
await _db.SaveChangesAsync();
return NoContent();
}
private static ChipVirgemDetailDto ToDetailDto(ChipVirgemLine x) => new()
{
Id = x.Id,
Item = x.Item,
NumeroDoChip = x.NumeroDoChip,
Observacoes = x.Observacoes,
CreatedAt = x.CreatedAt,
UpdatedAt = x.UpdatedAt
};
private static string? NullIfEmptyDigits(string? s)
{
var d = OnlyDigits(s);
return string.IsNullOrWhiteSpace(d) ? null : d;
}
private static string OnlyDigits(string? s)
{
if (string.IsNullOrWhiteSpace(s)) return "";
var sb = new StringBuilder();
foreach (var c in s)
{
if (char.IsDigit(c)) sb.Append(c);
}
return sb.ToString();
}
private static bool TryParseSearchDateUtcStart(string value, out DateTime utcStart)
{
utcStart = default;
if (string.IsNullOrWhiteSpace(value)) return false;
var s = value.Trim();
DateTime parsed;
if (DateTime.TryParse(s, new CultureInfo("pt-BR"), DateTimeStyles.None, out parsed) ||
DateTime.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsed))
{
utcStart = DateTime.SpecifyKind(parsed.Date, DateTimeKind.Utc);
return true;
}
return false;
}
}
}