- GET /api/v1/orders/dashboard — POS dashboard stats (revenue, orders, items sold, popular items, payment breakdown, hourly revenue, recent orders) - GET /api/v1/reports/revenue — Revenue report grouped by daily/weekly/monthly - GET /api/v1/reports/top-products — Top selling products by quantity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77 lines
2.7 KiB
C#
77 lines
2.7 KiB
C#
// EN: Reports REST API Controller.
|
|
// VI: Controller REST API cho Reports.
|
|
|
|
using Asp.Versioning;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using OrderService.API.Application.Queries;
|
|
|
|
namespace OrderService.API.Controllers;
|
|
|
|
/// <summary>
|
|
/// EN: Reports API Controller for revenue and product analytics.
|
|
/// VI: Controller API Reports cho phân tích doanh thu và sản phẩm.
|
|
/// </summary>
|
|
[ApiController]
|
|
[ApiVersion("1.0")]
|
|
[Route("api/v{version:apiVersion}/reports")]
|
|
public class ReportsController : ControllerBase
|
|
{
|
|
private readonly IMediator _mediator;
|
|
private readonly ILogger<ReportsController> _logger;
|
|
|
|
public ReportsController(
|
|
IMediator mediator,
|
|
ILogger<ReportsController> logger)
|
|
{
|
|
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Get revenue report grouped by period (daily, weekly, monthly).
|
|
/// VI: Lấy báo cáo doanh thu theo kỳ (ngày, tuần, tháng).
|
|
/// </summary>
|
|
[HttpGet("revenue")]
|
|
[ProducesResponseType(typeof(RevenueReportDto), StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<RevenueReportDto>> GetRevenueReport(
|
|
[FromQuery] Guid shopId,
|
|
[FromQuery] string period = "daily",
|
|
[FromQuery] DateTime? fromDate = null,
|
|
[FromQuery] DateTime? toDate = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
_logger.LogInformation(
|
|
"EN: Getting revenue report for shop {ShopId}, period {Period} / VI: Lấy báo cáo doanh thu cho shop {ShopId}, kỳ {Period}",
|
|
shopId, period);
|
|
|
|
var query = new GetRevenueReportQuery(period, shopId, fromDate, toDate);
|
|
var result = await _mediator.Send(query, cancellationToken);
|
|
|
|
return Ok(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Get top selling products.
|
|
/// VI: Lấy sản phẩm bán chạy nhất.
|
|
/// </summary>
|
|
[HttpGet("top-products")]
|
|
[ProducesResponseType(typeof(List<TopProductDto>), StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<List<TopProductDto>>> GetTopProducts(
|
|
[FromQuery] Guid shopId,
|
|
[FromQuery] int limit = 10,
|
|
[FromQuery] DateTime? fromDate = null,
|
|
[FromQuery] DateTime? toDate = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
_logger.LogInformation(
|
|
"EN: Getting top {Limit} products for shop {ShopId} / VI: Lấy top {Limit} sản phẩm cho shop {ShopId}",
|
|
limit, shopId);
|
|
|
|
var query = new GetTopProductsQuery(shopId, limit, fromDate, toDate);
|
|
var result = await _mediator.Send(query, cancellationToken);
|
|
|
|
return Ok(result);
|
|
}
|
|
}
|