The code provided in the question is a good starting point. However, it needs some modifications to achieve the desired result. Here is a possible solution:
// First, we need to group the transactions by week and subscription type
$transactions = UserTransaction::query()
->join('patients', 'patients.id', '=', 'user_transactions.patient_id')
->join('services', 'services.id', '=', 'user_transactions.service_id')
->select([
'services.name as service_name',
'user_transactions.currency',
'patients.id as patient_id',
DB::raw('WEEK(user_transactions.created_at) as week'),
DB::raw('COUNT(*) as subscription_count'),
DB::raw('SUM(user_transactions.amount_paid) as total_amount'),
])
->groupBy('week', 'subscription_count', 'service_name', 'currency');
// Then, we can loop through the weeks and build the result array
$result = [];
foreach ($weeks as $week) {
$weekNumber = $week['week'];
$startDate = $week['startOfWeek'];
$endDate = $week['endOfWeek'];
$newSubscriptions = $transactions
->where('subscription_count', 1)
->whereBetween('user_transactions.created_at', [$startDate, $endDate])
->get();
$renewedSubscriptions = $transactions
->where('subscription_count', '>', 1)
->whereBetween('user_transactions.created_at', [$startDate, $endDate])
->get();
$result[$weekNumber] = [
'start_date' => $startDate,
'end_date' => $endDate,
'new_subscriptions' => $newSubscriptions,
'renewed_subscriptions' => $renewedSubscriptions,
];
}
// Finally, we can return the result
return $result;
This code assumes that $weeks is an array of week start and end dates, similar to what is used in the original code. The result is an array that contains the start and end dates of each week, as well as the new and renewed subscriptions for that week.