pie chart for food added

This commit is contained in:
2025-12-23 11:19:39 +03:30
parent 5bb18afa11
commit 4e1300c6b9
2 changed files with 65 additions and 3 deletions
@@ -14,7 +14,7 @@ import { UpdateOrderStatusDto } from '../dto/update-order-status.dto';
@ApiBearerAuth()
@Controller()
export class OrdersController {
constructor(private readonly ordersService: OrdersService) {}
constructor(private readonly ordersService: OrdersService) { }
@UseGuards(AuthGuard)
@Post('public/checkout')
@@ -98,8 +98,16 @@ export class OrdersController {
@UseGuards(AdminAuthGuard)
@ApiOperation({ summary: 'Get Stats for report page' })
@Get('admin/orders/stats')
findStats( @RestId() restId: string) {
@Get('admin/orders/stats')
findStats(@RestId() restId: string) {
return this.ordersService.getStats(restId);
}
@UseGuards(AdminAuthGuard)
@ApiOperation({ summary: 'Get food sales pie chart data for last month' })
@ApiHeader(API_HEADER_SLUG)
@Get('admin/orders/food-sales-pie-chart')
getFoodSalesPieChart(@RestId() restId: string) {
return this.ordersService.getFoodSalesPieChart(restId);
}
}
@@ -507,4 +507,58 @@ export class OrdersService {
};
});
}
async getFoodSalesPieChart(restId: string) {
return this.em.transactional(async em => {
// Calculate last month date range
const now = new Date();
const firstDayOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
const lastDayOfLastMonth = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999);
// Query order items from orders in the last month
// Only include completed orders (excluding canceled and pending)
const result = await em.execute(
`
SELECT
f.id as food_id,
f.title as food_title,
COALESCE(SUM(oi.quantity), 0)::int as total_quantity,
COALESCE(SUM(oi.total_price), 0)::numeric as total_revenue
FROM order_items oi
INNER JOIN orders o ON oi.order_id = o.id
INNER JOIN foods f ON oi.food_id = f.id
WHERE o.restaurant_id = ?
AND o.created_at >= ?
AND o.created_at <= ?
AND o.status NOT IN ('pendingPayment', 'canceled')
GROUP BY f.id, f.title
ORDER BY total_revenue DESC
`,
[restId, firstDayOfLastMonth, lastDayOfLastMonth],
);
// Calculate total revenue for percentage calculation
const totalRevenue = result.reduce((sum: number, item: any) => {
return sum + Number(item.total_revenue || 0);
}, 0);
// Format data for pie chart and calculate percentages
const chartData = result.map((item: any) => ({
foodId: item.food_id,
foodTitle: item.food_title || 'Unknown',
quantity: Number(item.total_quantity || 0),
revenue: Number(item.total_revenue || 0),
percentage: totalRevenue > 0 ? Number(((Number(item.total_revenue || 0) / totalRevenue) * 100).toFixed(2)) : 0,
}));
return {
period: {
startDate: firstDayOfLastMonth.toISOString(),
endDate: lastDayOfLastMonth.toISOString(),
},
totalRevenue,
data: chartData,
};
});
}
}