Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
feat: add report order grown
Browse files Browse the repository at this point in the history
  • Loading branch information
foxminchan committed Jun 5, 2024
1 parent 731b5d8 commit d667ea5
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace RookieShop.ApiService.Endpoints.Reports;

public sealed class OrdersGrownByDayRequest
{
public DateTime? CurrentDate { get; set; }
}
32 changes: 32 additions & 0 deletions src/RookieShop.ApiService/Endpoints/Reports/OrdersGrownByDay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using MediatR;
using Microsoft.AspNetCore.Http.HttpResults;
using RookieShop.Application.Reports.DTOs;
using RookieShop.Application.Reports.Queries.OrdersGrownByDay;
using RookieShop.Infrastructure.Endpoints.Abstractions;
using RookieShop.Infrastructure.RateLimiter;

namespace RookieShop.ApiService.Endpoints.Reports;

public sealed class OrdersGrownByDay(ISender sender) : IEndpoint<Ok<OrdersGrownByDayDto>, OrdersGrownByDayRequest>
{
public void MapEndpoint(IEndpointRouteBuilder app) =>
app.MapGet("/reports/orders-grown-by-day", async (DateTime? currentDate) => await HandleAsync(new()
{
CurrentDate = currentDate ?? DateTime.UtcNow
}))
.Produces<Ok<OrdersGrownByDayDto>>()
.WithTags(nameof(Reports))
.WithName("Orders Grown By Day")
.MapToApiVersion(new(1, 0))
.RequirePerIpRateLimit();

public async Task<Ok<OrdersGrownByDayDto>> HandleAsync(OrdersGrownByDayRequest request,
CancellationToken cancellationToken = default)
{
OrdersGrownByDayQuery query = new(request.CurrentDate);

var result = await sender.Send(query, cancellationToken);

return TypedResults.Ok(result.Value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace RookieShop.Application.Reports.DTOs;

public sealed class OrdersGrownByDayDto
{
public long TodayCount { get; set; }
public long YesterdayCount { get; set; }
public long GrowthPercentage { get; set; }
public DateTime CurrentDate { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Ardalis.Result;
using Dapper;
using RookieShop.Application.Reports.DTOs;
using RookieShop.Domain.SharedKernel;
using RookieShop.Persistence;

namespace RookieShop.Application.Reports.Queries.OrdersGrownByDay;

public sealed class OrdersGrownByDayHandler(IDatabaseFactory factory)
: IQueryHandler<OrdersGrownByDayQuery, Result<OrdersGrownByDayDto>>
{
public async Task<Result<OrdersGrownByDayDto>> Handle(OrdersGrownByDayQuery request,
CancellationToken cancellationToken)
{
const string sql = $"""
WITH orders_by_day AS (
SELECT
DATE_TRUNC('day', o.created_date AT TIME ZONE 'UTC') AS order_date,
COUNT(*) AS order_count
FROM orders o
GROUP BY order_date
),
today_orders AS (
SELECT order_count AS today_count
FROM orders_by_day
WHERE order_date = DATE_TRUNC('day', @CurrentDate)
),
yesterday_orders AS (
SELECT order_count AS yesterday_count
FROM orders_by_day
WHERE order_date = DATE_TRUNC('day', @CurrentDate) - INTERVAL '1 day'
)
SELECT
COALESCE(today_orders.today_count, 0) AS {nameof(OrdersGrownByDayDto.TodayCount)},
COALESCE(yesterday_orders.yesterday_count, 0) AS {nameof(OrdersGrownByDayDto.YesterdayCount)},
CASE
WHEN COALESCE(yesterday_orders.yesterday_count, 0) = 0 THEN 0
ELSE (COALESCE(today_orders.today_count, 0) - COALESCE(yesterday_orders.yesterday_count, 0)) / COALESCE(yesterday_orders.yesterday_count, 0)::decimal * 100
END AS {nameof(OrdersGrownByDayDto.GrowthPercentage)},
DATE_TRUNC('day', @CurrentDate) AS {nameof(OrdersGrownByDayDto.CurrentDate)}
FROM
(SELECT 1) AS dummy
LEFT JOIN today_orders ON TRUE
LEFT JOIN yesterday_orders ON TRUE;
""";

using var conn = factory.GetOpenConnection();

var result = await conn.QueryAsync<OrdersGrownByDayDto>(sql,
new { request.CurrentDate });

return result.First();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Ardalis.Result;
using RookieShop.Application.Reports.DTOs;
using RookieShop.Domain.SharedKernel;

namespace RookieShop.Application.Reports.Queries.OrdersGrownByDay;

public sealed record OrdersGrownByDayQuery(DateTime? CurrentDate) : IQuery<Result<OrdersGrownByDayDto>>;
7 changes: 6 additions & 1 deletion ui/backoffice/app/(dashboard)/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import useGetDiffRevenueByMonth from "@/features/report/useGetDiffRevenueByMonth"
import useGetGrownCustomer from "@/features/report/useGetGrownCustomer"
import useGetOrderGrownByDay from "@/features/report/useGetOrderGrownByDay"
import useGetTodayRevenue from "@/features/report/useGetTodayRevenue"

import {
Expand Down Expand Up @@ -32,6 +33,8 @@ export default function Dashboard() {
year: new Date().getFullYear(),
})

const { data: OrderGrownByDay } = useGetOrderGrownByDay()

return (
<ScrollArea className="h-full">
<div className="flex-1 space-y-4 p-4 pt-6 md:p-8">
Expand Down Expand Up @@ -107,7 +110,9 @@ export default function Dashboard() {
<Icons.order className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">+573</div>
<div className="text-2xl font-bold">
{OrderGrownByDay?.growthPercentage ?? 0}%
</div>
</CardContent>
</Card>
</div>
Expand Down
5 changes: 5 additions & 0 deletions ui/backoffice/features/report/report.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DiffRevenueByMonthParams,
GrownCustomer,
GrownCustomerParams,
OrderGrownByDay,
TodayRevenue,
} from "./report.type"

Expand Down Expand Up @@ -43,6 +44,10 @@ class ReportService extends HttpService {
`/reports/customers-grown-by-month?${buildQueryString(options)}`
)
}

getOrderGrownByDay(): Promise<OrderGrownByDay> {
return this.get("/reports/orders-grown-by-day")
}
}

export default new ReportService()
9 changes: 9 additions & 0 deletions ui/backoffice/features/report/report.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,12 @@ export type GrownCustomerParams = {
month: number
year: number
}

// -- Order Grown By Day Report

export type OrderGrownByDay = {
todayCount: number
yesterdayCount: number
growthPercentage: number
currentDate: Date
}
10 changes: 10 additions & 0 deletions ui/backoffice/features/report/useGetOrderGrownByDay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { useQuery } from "@tanstack/react-query"

import reportService from "./report.service"

export default function useGetOrderGrownByDay() {
return useQuery({
queryKey: ["order-grown-by-day"],
queryFn: () => reportService.getOrderGrownByDay(),
})
}

0 comments on commit d667ea5

Please sign in to comment.