pie chart for food added
This commit is contained in:
@@ -14,7 +14,7 @@ import { UpdateOrderStatusDto } from '../dto/update-order-status.dto';
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Controller()
|
@Controller()
|
||||||
export class OrdersController {
|
export class OrdersController {
|
||||||
constructor(private readonly ordersService: OrdersService) {}
|
constructor(private readonly ordersService: OrdersService) { }
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@Post('public/checkout')
|
@Post('public/checkout')
|
||||||
@@ -99,7 +99,15 @@ export class OrdersController {
|
|||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@ApiOperation({ summary: 'Get Stats for report page' })
|
@ApiOperation({ summary: 'Get Stats for report page' })
|
||||||
@Get('admin/orders/stats')
|
@Get('admin/orders/stats')
|
||||||
findStats( @RestId() restId: string) {
|
findStats(@RestId() restId: string) {
|
||||||
return this.ordersService.getStats(restId);
|
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,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user