feat: add transactions import, list and categories endpoints
This commit is contained in:
parent
fec96d7727
commit
1a13ee3453
@ -0,0 +1,92 @@
|
|||||||
|
using AccountTracking.Api.Data;
|
||||||
|
using AccountTracking.Api.Models.Dtos;
|
||||||
|
using AccountTracking.Api.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace AccountTracking.Api.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/transactions")]
|
||||||
|
[Authorize]
|
||||||
|
public class TransactionsController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly AppDbContext _db;
|
||||||
|
private readonly CsvImportService _importService;
|
||||||
|
|
||||||
|
public TransactionsController(AppDbContext db, CsvImportService importService)
|
||||||
|
{
|
||||||
|
_db = db;
|
||||||
|
_importService = importService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("import")]
|
||||||
|
public async Task<IActionResult> Import(IFormFile file)
|
||||||
|
{
|
||||||
|
if (file == null || file.Length == 0)
|
||||||
|
return BadRequest(new ErrorResult("Nebyl vybrán žádný soubor."));
|
||||||
|
|
||||||
|
string content;
|
||||||
|
using (var reader = new StreamReader(file.OpenReadStream(), System.Text.Encoding.UTF8))
|
||||||
|
content = await reader.ReadToEndAsync();
|
||||||
|
|
||||||
|
var result = await _importService.ImportAsync(content, file.FileName);
|
||||||
|
|
||||||
|
if (!result.IsSuccess)
|
||||||
|
return BadRequest(new ErrorResult(result.Error!));
|
||||||
|
|
||||||
|
return Ok(result.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> List(
|
||||||
|
[FromQuery] int year,
|
||||||
|
[FromQuery] int? month,
|
||||||
|
[FromQuery] string? category,
|
||||||
|
[FromQuery] string? search,
|
||||||
|
[FromQuery] int page = 1,
|
||||||
|
[FromQuery] int pageSize = 50)
|
||||||
|
{
|
||||||
|
pageSize = Math.Clamp(pageSize, 1, 200);
|
||||||
|
page = Math.Max(1, page);
|
||||||
|
|
||||||
|
var query = _db.Transactions.AsQueryable();
|
||||||
|
|
||||||
|
query = query.Where(t => t.BookingDate.Year == year);
|
||||||
|
if (month.HasValue)
|
||||||
|
query = query.Where(t => t.BookingDate.Month == month.Value);
|
||||||
|
if (!string.IsNullOrWhiteSpace(category))
|
||||||
|
query = query.Where(t => t.Category == category);
|
||||||
|
if (!string.IsNullOrWhiteSpace(search))
|
||||||
|
query = query.Where(t =>
|
||||||
|
(t.CounterPartyName != null && EF.Functions.Like(t.CounterPartyName, $"%{search}%")) ||
|
||||||
|
(t.Message != null && EF.Functions.Like(t.Message, $"%{search}%")));
|
||||||
|
|
||||||
|
var total = await query.CountAsync();
|
||||||
|
var items = await query
|
||||||
|
.OrderByDescending(t => t.BookingDate)
|
||||||
|
.ThenByDescending(t => t.Id)
|
||||||
|
.Skip((page - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.Select(t => new TransactionDto(
|
||||||
|
t.Id, t.BookingDate, t.CounterPartyName,
|
||||||
|
t.Category, t.Amount, t.Balance, t.Message))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Ok(new TransactionListResponse(items, total, page, pageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("categories")]
|
||||||
|
public async Task<IActionResult> Categories()
|
||||||
|
{
|
||||||
|
var cats = await _db.Transactions
|
||||||
|
.Where(t => t.Category != null)
|
||||||
|
.Select(t => t.Category!)
|
||||||
|
.Distinct()
|
||||||
|
.OrderBy(c => c)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Ok(cats);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user