Files
pos-system/services/order-service-net/src/OrderService.API/Controllers/ReportsController.cs
Ho Ngoc Hai 9b44e88a6a feat(order-service): add dashboard and reporting endpoints
- 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>
2026-03-04 10:36:09 +07:00

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);
}
}