url = $url; $this->user = Auth::guard('admin')->user(); } public function providerReportFilters() { $providers = Telemedpro::select( DB::raw("CONCAT(license_numbers.license_number,',',license_numbers.state) as provider_license_number"), 'appointments.patient_name', 'appointments.appointment_date', 'appointments.appointment_time', 'appointments.timezone', 'start_time', 'end_time', 'duration', DB::raw("CONCAT(patients.first_name,',',patients.last_name) as patient_name"), 'patients.phone_no', 'patients.email', 'patients.address', 'patients.city', 'patients.state', 'patients.zip_code', 'patients.country', 'patients.gender', 'patients.dob', 'patients.height', 'patients.weight' ) ->LeftJoin('license_numbers', 'provider_id', 'telemed_pros.id') ->LeftJoin('appointments', 'appointments.telemed_pros_id', 'telemed_pros.id') ->leftJoin('patients', 'appointments.patient_id', 'patients.id') ->whereNotNull('appointments.start_time') ->whereNotNull('appointments.end_time') ->get(); foreach ($providers as $provider) { $start_datetime = new DateTime($provider->start_time); $diff = $start_datetime->diff(new DateTime($provider->end_time)); $duration = $diff->h . " hours " . $diff->i . " Min"; // dd($providers->duration,$duration); $provider->duration = $duration; } return response()->json([ 'provider_list' => $providers, ]); } public function providerReportPost(Request $request) { return response()->json([ 'provider_list' => '' ]); } public function overviewReport(Request $request) { try { $this->authorizeForUser($this->user, 'overview_analytics', new ProfileQuestion); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $totalOrdersStats = Cart::select( DB::raw("sum(case when carts.status = 'completed' then 1 else 0 end) as total_sales"), DB::raw("sum(case when carts.status = 'completed' then carts.total_amount else 0 end) as sales_amount"), DB::raw("count(items.id) as products_sold") ) ->Join('items', 'items.cart_id', 'carts.id') ->where('carts.created_at', '>=', $start_date . " 00:00:00") ->where('carts.created_at', '<=', $end_date . " 23:59:59") ->where('carts.status', '=', 'completed') ->get(); $orderCollection = Cart::select( 'carts.id as order_id', 'carts.status', 'carts.email', 'carts.total_amount', 'carts.created_at as date', DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name") ) ->where('carts.created_at', '>=', $start_date . " 00:00:00") ->where('carts.created_at', '<=', $end_date . " 23:59:59") ->where('carts.status', '=', 'completed') ->get(); $orderData = $orderCollection->map(function ($query, $key) { $patientType = $query->where('email', $query->email)->count(); $itemSold = Item::select(DB::raw("GROUP_CONCAT(title SEPARATOR ', ') as items")) ->where('cart_id', $query->order_id) ->leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id'); $itemCount = $itemSold->count(); $products = $itemSold->first(); if ($patientType > 1) $query->customer_type = 'returning'; else $query->customer_type = 'new'; $query->products = $products->items ?? null; $query->item_sold = $itemCount ?? 0; $query->attribution = 'direct'; return $query; }); $dates = []; $sales = []; $startDate = Carbon::parse($start_date); $endDate = Carbon::parse($end_date); for ($date = $startDate; $date->lte($endDate); $date->addDay()) { $values = Cart::select( DB::raw('DATE(created_at) as date'), DB::raw("SUM(case when carts.status = 'completed' then carts.total_amount else 0 end) as amount") ) ->where('carts.created_at', '>=', $date->format("Y-m-d") . " 00:00:00") ->where('carts.created_at', '<=', $date->format("Y-m-d") . " 23:59:59") ->groupBy(DB::raw('DATE(created_at)')); $graphsValues = $values->first(); $dates[] = $date->format("M d/y"); if ($graphsValues) $sales[] = $graphsValues->amount; else $sales[] = 0; } $newUser = 0; $returnUser = 0; $newUsers = []; $returningUsers = []; //getting here unique rows for patient stats $uniqueKeys = array_map(function ($item) { return $item['email']; }, $orderCollection->toArray()); $uniqueRecords = array_intersect_key($orderCollection->toArray(), array_unique($uniqueKeys)); $uniqueRecords = array_values($uniqueRecords); foreach ($orderCollection as $userStats) { $userStatus = Cart::where('email', $userStats->email)->count(); if ($userStatus > 1) { $returnUser++; $returningUsers[] = $userStats; } else { $newUser++; $newUsers[] = $userStats; } }; $percentageReturning = 0; $percentageNewuser = 0; if ($returnUser > 0 || $newUser > 0) { $percentageReturning = ($returnUser / ($returnUser + $newUser)) * 100; $percentageNewuser = ($newUser / ($returnUser + $newUser)) * 100; } //check here users engagement $newUserEngagement = $this->calculateEngagement($newUsers); $returningUserEngagement = $this->calculateEngagement($returningUsers); return response()->json([ 'totals' => $totalOrdersStats, 'orders' => $orderData, 'chart' => [ 'chart_dates' => $dates, 'chart_data' => $sales ], 'patient_stats' => [ 'returning_users' => [$returnUser, round($percentageReturning, 0) . "%"], 'new_users' => [$newUser, round($percentageNewuser, 0) . "%"] ] ]); } catch (AuthorizationException $e) { return $e->getMessage(); } } public function ordersFilters() { $patient = Patient::select('id', DB::raw("CONCAT(first_name,' ',last_name) as patient_name"))->get(); return response()->json([ 'patients' => $patient ]); } public function initialPatients() { $patients = Patient::select('id', DB::raw("CONCAT(first_name,' ',last_name) as patient_name")) ->limit(100) ->orderBy('patient_name', 'asc') ->get(); return response()->json([ 'patients' => $patients ]); } public function searchPatients(Request $request) { $searchTerm = $request->input('term'); $patients = Patient::select('id', DB::raw("CONCAT(first_name,' ',last_name) as patient_name")) ->where(DB::raw("CONCAT(first_name,' ',last_name)"), 'LIKE', "%{$searchTerm}%") ->limit(500) ->orderBy('patient_name', 'asc') ->get(); return response()->json([ 'patients' => $patients ]); } // Function to calculate engagement metrics function calculateEngagement($users) { $totalUsers = count($users); $completedOrders = 0; $totalAmount = 0; foreach ($users as $user) { if ($user['status'] === 'delivered') { $completedOrders++; } $totalAmount += floatval($user['total_amount']); } $orderCompletionRate = $totalUsers > 0 ? ($completedOrders / $totalUsers) * 100 : 0; $averageOrderValue = $totalUsers > 0 ? $totalAmount / $totalUsers : 0; return [ 'total_users' => $totalUsers, 'completed_orders' => $completedOrders, 'order_completion_rate' => $orderCompletionRate, 'average_order_value' => $averageOrderValue ]; } public function ordersReport(Request $request) { try { $this->authorizeForUser($this->user, 'orders_analytics', new ProfileQuestion); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $status = $request->get('status'); $patient = $request->get('patient'); $query = Cart::select( 'carts.id as order_id', 'carts.status', 'carts.email', 'carts.total_amount', 'carts.created_at as date', DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name") ) ->where('carts.created_at', '>=', $start_date . " 00:00:00") ->where('carts.created_at', '<=', $end_date . " 23:59:59"); // Apply filters if ($status != 'all') { $query->where('carts.status', $status); } if ($patient != 'all') { $query->where('carts.patient_id', $patient); } $dates = []; $sales = []; $startDate = Carbon::parse($start_date); $endDate = Carbon::parse($end_date); for ($date = $startDate; $date->lte($endDate); $date->addDay()) { $values = Cart::select( DB::raw('DATE(created_at) as date'), DB::raw("SUM(carts.total_amount) as amount") ) ->where('carts.created_at', '>=', $date->format("Y-m-d") . " 00:00:00") ->where('carts.created_at', '<=', $date->format("Y-m-d") . " 23:59:59") ->groupBy(DB::raw('DATE(created_at)')); if ($status != 'all') { $values->where('carts.status', $status); } if ($patient != 'all') { $values->where('carts.patient_id', $patient); } $graphsValues = $values->first(); $dates[] = $date->format("M d/y"); if ($graphsValues) $sales[] = $graphsValues->amount; else $sales[] = 0; } // dd(Constant::getFullSql($query)); $orderCollection = $query->get(); $orderData = $orderCollection->map(function ($cart) { $patientType = Cart::where('email', $cart->email)->count(); $itemSold = Item::select(DB::raw("GROUP_CONCAT(plans_v1.title SEPARATOR ', ') as items")) ->where('cart_id', $cart->order_id) ->leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id'); $itemCount = $itemSold->count(); $products = $itemSold->first(); $cart->customer_type = $patientType > 1 ? 'returning' : 'new'; $cart->products = $products->items ?? null; $cart->item_sold = $itemCount ?? null; $cart->attribution = 'direct'; return $cart; }); $totalOrdersStats = Cart::select( // DB::raw("sum(case when carts.status = 'delivered' then 1 else 0 end) as total_sales"), DB::raw("count(carts.id) as total_sales"), DB::raw("sum(carts.total_amount ) as sales_amount"), DB::raw("count(items.id) as products_sold") ) ->Join('items', 'items.cart_id', 'carts.id') ->where('carts.created_at', '>=', $start_date . " 00:00:00") ->where('carts.created_at', '<=', $end_date . " 23:59:59"); if ($status != 'all') { $totalOrdersStats->where('carts.status', $status); } if ($patient != 'all') { $totalOrdersStats->where('carts.patient_id', $patient); } $totals = $totalOrdersStats->get(); return response()->json([ 'orders' => $orderData, 'totals' => $totals, 'chart' => [ 'chart_dates' => $dates, 'chart_data' => $sales ] ]); } catch (AuthorizationException $e) { return $e->getMessage(); } } public function productAnalytics(Request $request) { try { $this->authorizeForUser($this->user, 'orders_analytics', new ProfileQuestion); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $singleProduct = $request->get('single_product'); $patient = $request->get('patient'); $query = Item::select( DB::raw("sum(case when items.status='delivered' then items.quantity else 0 end) as total_item_sold"), DB::raw("sum(case when items.status='delivered' then 1 else 0 end) as total_orders"), DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as total_amount"), 'plans_v1.title as product_name', 'items.plans_id as product_id' ) ->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id') ->where('items.created_at', '>=', $start_date . " 00:00:00") ->where('items.created_at', '<=', $end_date . " 23:59:59") ->where('items.status', 'delivered') ->groupby('plans_v1.title', 'items.plans_id'); // Apply filters if ($singleProduct != 'all') { $query->where('items.plans_id', $singleProduct); } $dates = []; $sales = []; $startDate = Carbon::parse($start_date); $endDate = Carbon::parse($end_date); for ($date = $startDate; $date->lte($endDate); $date->addDay()) { $graphsValues = Item::select( DB::raw("sum(case when items.status='delivered' then 1 else 0 end) as total_orders"), DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as total_amount"), ) ->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id') ->where('items.created_at', '>=', $date->format("Y-m-d") . " 00:00:00") ->where('items.created_at', '<=', $date->format("Y-m-d") . " 23:59:59") ->where('items.status', 'delivered') ->groupby('plans_v1.title', 'items.plans_id'); if ($singleProduct != 'all') { $graphsValues->where('items.plans_id', $singleProduct); } $graphVal = $graphsValues->first(); $dates[] = $date->format("M d/y"); if ($graphVal) $sales[] = $graphVal->total_amount; else $sales[] = 0; } $orderData = $query->get(); $totalOrdersStats = Item::select( DB::raw("count(items.id) as total_orders"), DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as sales_amount"), DB::raw("sum(case when items.status='delivered' then items.quantity else 0 end) as products_sold") ) ->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id') ->where('items.created_at', '>=', $start_date . " 00:00:00") ->where('items.created_at', '<=', $end_date . " 23:59:59") ->where('items.status', 'delivered'); if ($singleProduct != 'all') { $totalOrdersStats->where('items.plans_id', $singleProduct); } $totals = $totalOrdersStats->get(); return response()->json([ 'orders' => $orderData, 'totals' => $totals, 'chart' => [ 'chart_dates' => $dates, 'chart_data' => $sales ] ]); } catch (AuthorizationException $e) { return $e->getMessage(); } } public function totalSales() { $start_date = request()->input('start_date'); $end_date = request()->input('end_date'); $startDate = Carbon::parse($start_date); $endDate = Carbon::parse($end_date); $sales = []; for ($date = $startDate; $date->lte($endDate); $date->addDay()) { $graphsValues = Item::select( DB::raw("sum(case when items.status='delivered' then 1 else 0 end) as total_orders"), DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as total_amount"), ) ->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id') ->where('items.created_at', '>=', $date->format("Y-m-d") . " 00:00:00") ->where('items.created_at', '<=', $date->format("Y-m-d") . " 23:59:59") ->where('items.status', 'delivered') ->groupby('plans_v1.title', 'items.plans_id'); $graphVal = $graphsValues->first(); $dates[] = $date->format("M d/y"); if ($graphVal) { $sales[$date->format("Y-m-d")] = ["total_amount" => $graphVal->total_amount, "order_count" => $graphVal->total_orders]; } else { $sales[$date->format("Y-m-d")] = ["total_amount" => 0, "order_count" => 0]; } } dd($dates, $sales); } public function ordersAnalytics(Request $request) { try { $this->authorizeForUser($this->user, 'orders_analytics', new ProfileQuestion); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $singleProduct = $request->get('single_product'); $query = Cart::select( 'carts.id as order_id', "carts.status as order_status", "carts.created_at as order_date", DB::raw("GROUP_CONCAT(plans_v1.title SEPARATOR ', ') as items"), DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name"), "carts.total_amount", DB::raw("sum(case when carts.status='completed' then 1 else 0 end) as item_sold") ) ->leftJoin('items', 'items.cart_id', 'carts.id') ->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id') ->where('carts.created_at', '>=', $start_date . " 00:00:00") ->where('carts.created_at', '<=', $end_date . " 23:59:59") ->where('carts.status', 'completed') ->groupby('carts.id', 'carts.status', 'carts.created_at', DB::raw("CONCAT(carts.first_name,' ',carts.last_name)"), "carts.total_amount"); $dates = []; $sales = []; $singleMonth = []; $current_month = null; $graphDates = null; $startDate = Carbon::parse($start_date); $endDate = Carbon::parse($end_date); for ($date = $startDate; $date->lte($endDate); $date->addDay()) { $graphsValues = Cart::select( DB::raw('DATE(created_at) as date'), DB::raw("SUM(carts.total_amount) as amount") ) ->where('carts.created_at', '>=', $date->format("Y-m-d") . " 00:00:00") ->where('carts.created_at', '<=', $date->format("Y-m-d") . " 23:59:59") ->where('carts.status', 'completed') ->groupBy(DB::raw('DATE(created_at)')); $graphVal = $graphsValues->first(); $month = $date->format('F Y'); if ($month != $current_month) { // Month has changed or it's the first iteration, echo the first day of the month $dates[] = $month; $current_month = $month; } else { $dates[] = " "; } $singleMonth[] = $date->format("M d/y"); if ($graphVal) $sales[] = $graphVal->amount; else $sales[] = 0; } // count if user select more then one month $dateIterate = $this->monthItrator($start_date, $end_date); if ($dateIterate == 1) $graphDates = $singleMonth; else $graphDates = $dates; $orderData = $query->get(); $totalOrdersStats = Item::select( DB::raw("count(items.id) as total_orders"), DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as sales_amount"), DB::raw("sum(case when items.status='delivered' then items.quantity else 0 end) as products_sold") ) ->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id') ->where('items.created_at', '>=', $start_date . " 00:00:00") ->where('items.created_at', '<=', $end_date . " 23:59:59") ->where('items.status', 'delivered'); $totals = $totalOrdersStats->get(); return response()->json([ 'orders' => $orderData, 'totals' => $totals, 'chart' => [ 'chart_dates' => $graphDates, 'chart_data' => $sales ] ]); } catch (AuthorizationException $e) { return $e->getMessage(); } } public function monthItrator($start_date, $end_date) { $start = (clone Carbon::parse($start_date))->modify('first day of this month'); $end = (clone Carbon::parse($end_date))->modify('first day of next month'); $interval = DateInterval::createFromDateString('1 month'); $period = new DatePeriod($start, $interval, $end); return iterator_count($period); } }