353 lines
14 KiB
PHP
353 lines
14 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin\Api;
|
|
|
|
use App\Classes\Constant;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Admin;
|
|
use App\Models\Appointment;
|
|
use App\Models\Cart;
|
|
use App\Models\Item;
|
|
use App\Models\Lab;
|
|
use App\Models\MedicalHistoryAnswer;
|
|
use App\Models\Patient;
|
|
use App\Models\PatientRegActivity;
|
|
use App\Models\Plan;
|
|
use App\Models\PlanV1;
|
|
use App\Models\ProfileAnswer;
|
|
use App\Models\QuestionBuilder;
|
|
use App\Models\Telemedpro;
|
|
use App\Permissions\Permissions;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Ods\Settings;
|
|
use Illuminate\Routing\UrlGenerator;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Auth\Access\AuthorizationException;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class DashboardController extends Controller
|
|
{
|
|
|
|
protected $url;
|
|
protected $user;
|
|
public function __construct(UrlGenerator $url)
|
|
{
|
|
$this->url = $url;
|
|
$this->user = Auth::guard('admin')->user();
|
|
}
|
|
public function getStats()
|
|
{
|
|
|
|
|
|
$date = Carbon::now();
|
|
$startOfWeek = $date->startOfWeek(Carbon::MONDAY)->format("Y-m-d");
|
|
$endDate = Carbon::now()->format('Y-m-d');
|
|
$newPatients = self::getNewPatients($startOfWeek, $endDate);
|
|
$newProviders = self::getNewProviders($newPatients, $endDate);
|
|
$analytics = self::getAnalytics();
|
|
$upcomingMeetings = Appointment::where('appointment_date', '>=', $date->toDateString())->count();
|
|
return response()->json([
|
|
'upcoming_meetings' => $upcomingMeetings,
|
|
'new_customers' => $newPatients,
|
|
'new_providers' => $newProviders,
|
|
'analytics' => $analytics
|
|
]);
|
|
}
|
|
protected function getNewPatients($newPatients, $endOfWeek)
|
|
{
|
|
$upcomingMeetings = Patient::where('created_at', '>=', $newPatients)
|
|
->where('created_at', '<=', $endOfWeek)
|
|
->count();
|
|
return $upcomingMeetings;
|
|
}
|
|
protected function getNewProviders($newPatients, $endOfWeek)
|
|
{
|
|
$upcomingMeetings = Telemedpro::where('created_at', '>=', $newPatients)
|
|
->where('created_at', '<=', $endOfWeek)
|
|
->count();
|
|
return $upcomingMeetings;
|
|
}
|
|
protected function getAnalytics($filter = '12_months')
|
|
{
|
|
$currentMonth = Carbon::now();
|
|
|
|
// Filter logic
|
|
switch ($filter) {
|
|
case 'current_month':
|
|
$startDate = $currentMonth->copy()->startOfMonth();
|
|
break;
|
|
case '1_month':
|
|
$startDate = $currentMonth->copy()->subMonth()->startOfMonth();
|
|
break;
|
|
case '2_months':
|
|
$startDate = $currentMonth->copy()->subMonths(2)->startOfMonth();
|
|
break;
|
|
case '3_months':
|
|
$startDate = $currentMonth->copy()->subMonths(3)->startOfMonth();
|
|
break;
|
|
case '6_months':
|
|
$startDate = $currentMonth->copy()->subMonths(6)->startOfMonth();
|
|
break;
|
|
default: // Default to 12 months
|
|
$startDate = $currentMonth->copy()->subMonths(12)->startOfMonth();
|
|
}
|
|
|
|
$endDate = $currentMonth->endOfMonth();
|
|
|
|
|
|
$appointments = Appointment::with('patient')
|
|
->whereBetween('created_at', [$startDate, $endDate])
|
|
->get();
|
|
|
|
$totalSessions = $appointments->count();
|
|
$totalCallTime = 10; // Assuming you have some logic to calculate this
|
|
if ($totalSessions != 0) {
|
|
$avgSessionTime = $totalCallTime / $totalSessions;
|
|
$avgSessionTime = round(($avgSessionTime / 60), 2);
|
|
} else
|
|
$avgSessionTime = '';
|
|
|
|
|
|
$monthlyData = [];
|
|
|
|
// Loop through each month in the last 12 months
|
|
for ($date = $startDate->copy(); $date->lte($endDate); $date->addMonth()) {
|
|
$monthStart = $date->startOfMonth()->format('Y-m-d');
|
|
$monthEnd = $date->copy()->endOfMonth()->format('Y-m-d'); // Key change here!
|
|
|
|
$monthAppointments = Appointment::with('patient')
|
|
->whereBetween('created_at', [$monthStart, $monthEnd])
|
|
->get();
|
|
|
|
|
|
// Calculate any metrics you need from $monthAppointments
|
|
$monthlyData[] = [
|
|
'month' => $date->format('M'), // Example: Jan 2024
|
|
'appointment_count' => $monthAppointments->count()
|
|
// Add other metrics as needed
|
|
];
|
|
}
|
|
$monthsList = [];
|
|
$monthlySessionCount = [];
|
|
|
|
foreach ($monthlyData as $dataPoint) {
|
|
$monthsList[] = $dataPoint['month'];
|
|
$monthlySessionCount[] = $dataPoint['appointment_count'];
|
|
}
|
|
|
|
|
|
return [
|
|
// 'total_sessions' => $totalSessions,
|
|
'total_call_time' => $totalCallTime,
|
|
// 'avg_session_time' => $avgSessionTime,
|
|
'data' => array_values($monthlySessionCount),
|
|
'months_list' => $monthsList,
|
|
];
|
|
}
|
|
public function getAdminDetails(Request $request)
|
|
{
|
|
$user = Auth::guard('admin')->user();
|
|
$permissionManager = new Permissions($user->role->permissions);
|
|
$permissions = $permissionManager->permissionsApi();
|
|
if (isset($user->image_path))
|
|
$user->image_path = $this->url->to('/storage/profile_pictures/' . $user->image_path);
|
|
else
|
|
$user->image_path = Null;
|
|
return response()->json([
|
|
'admin_details' => $user,
|
|
'permissions'=>$permissions
|
|
]);
|
|
}
|
|
public function updateAdminDetails(Request $request)
|
|
{
|
|
$userId = Auth::guard('admin')->user()->id;
|
|
$user = Admin::find($userId);
|
|
|
|
if($request->get('image'))
|
|
{
|
|
$image = $request->get('image');
|
|
$fileName = 'profile-' . time();
|
|
|
|
$logo = base64_decode($image);
|
|
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
|
|
|
$imageName = $fileName . '.' . $ext;
|
|
Storage::disk('local')->put("/public/profile_pictures/" . $imageName, $logo);
|
|
}
|
|
|
|
$user->name = $request->get('first_name');
|
|
$user->last_name = $request->get('last_name');
|
|
$user->phone_no = $request->get('phone_no');
|
|
if ($request->get('image'))
|
|
$user->image_path = $imageName;
|
|
$user->save();
|
|
return response()->json([
|
|
'admin_details' => $user
|
|
]);
|
|
}
|
|
public function uploadImage($image, $fileName, $path)
|
|
{
|
|
$logo = base64_decode($image);
|
|
$filename = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[0]);
|
|
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
|
$imageName = $fileName . '.' . $ext;
|
|
$path = $path . $imageName;
|
|
file_put_contents($path, $logo);
|
|
return $imageName;
|
|
}
|
|
public function index(Request $request){
|
|
|
|
try{
|
|
$this->authorizeForUser($this->user,'DashboardData', new Admin);
|
|
$start_date = $request->get('start_date');
|
|
$end_date = $request->get('end_date');
|
|
$totalPatients = $this->getTotals($start_date,$end_date);
|
|
$graphData = $this->graphData($start_date,$end_date);
|
|
$patientActivity = $this->patientActivit($start_date,$end_date);
|
|
$ordersData = $this->ordersData($start_date,$end_date);
|
|
$completedMeetings = $this->completedMeetings($start_date,$end_date);
|
|
$orders = $this->productsData($start_date,$end_date);
|
|
return response()->json([
|
|
'totals' =>$totalPatients,
|
|
'graph_data'=>$graphData,
|
|
'patient_reg_activity'=>$patientActivity,
|
|
'orders_data'=>$ordersData,
|
|
'completed_meetings'=>$completedMeetings,
|
|
'products'=>$orders
|
|
]);
|
|
} catch (AuthorizationException $e) {
|
|
return $e->getMessage();
|
|
}
|
|
}
|
|
public function getTotals($start_date,$end_date)
|
|
{
|
|
$totalPatients = Patient::
|
|
where('created_at', '>=', $start_date." 00:00:00")
|
|
->where('created_at', '<=', $end_date." 23:59:59")
|
|
->count();
|
|
$totalOrders = Cart::select(
|
|
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")
|
|
)
|
|
->leftJoin('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')
|
|
->first();
|
|
|
|
return [
|
|
'total_patints'=>$totalPatients,
|
|
'total_orders'=>$totalOrders->total_sales,
|
|
'total_amount'=>$totalOrders->sales_amount,
|
|
'total_products_sold'=>$totalOrders->products_sold
|
|
];
|
|
}
|
|
public function graphData($start_date,$end_date)
|
|
{
|
|
$dates = [];
|
|
$sales =[];
|
|
$totalMeetingsData =[];
|
|
$startDate = Carbon::parse($start_date);
|
|
$endDate = Carbon::parse($end_date);
|
|
for ($date = $startDate; $date->lte($endDate); $date->addDay()) {
|
|
//get total sales data
|
|
$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();
|
|
// get total meetings
|
|
$totalMeetings = Appointment::
|
|
where('start_time', '>=', $date->format("Y-m-d")." 00:00:00")
|
|
->where('start_time', '<=', $date->format("Y-m-d")." 23:59:59")
|
|
->where('status', 'completed')
|
|
->count();
|
|
$dates[] = $date->format("M d/y");
|
|
if($graphsValues)
|
|
$sales[] = round($graphsValues->amount,2);
|
|
else
|
|
$sales[] = 0.00;
|
|
|
|
$totalMeetingsData[] = round($totalMeetings,2);
|
|
}
|
|
return [
|
|
'dates'=>$dates,
|
|
'data'=>
|
|
[
|
|
'total_sales'=>$sales,
|
|
'total_meetings'=>$totalMeetingsData
|
|
]
|
|
];
|
|
}
|
|
public function patientActivit($start_date,$end_date){
|
|
$patientActivity = PatientRegActivity::
|
|
where('created_at', '>=', $start_date." 00:00:00")
|
|
->where('created_at', '<=', $end_date." 23:59:59")
|
|
->get();
|
|
|
|
$activity = $patientActivity->map(function ($query,$key){
|
|
$patient = Patient::find($query->patient_id);
|
|
if($query->activity=='patient_registered')
|
|
{
|
|
$query->activity = $patient->first_name. " ". $patient->last_name. " Singed Up";
|
|
}
|
|
if($query->activity=='patient_appointment_booked')
|
|
{
|
|
$query->activity = $patient->first_name. " ". $patient->last_name. " Booked an appointment ";
|
|
}
|
|
return $query;
|
|
|
|
});
|
|
|
|
return $patientActivity;
|
|
}
|
|
public function ordersData($start_date,$end_date){
|
|
return Cart::select('carts.id as order_id','carts.total_amount as amount',
|
|
DB::raw("CONCAT(first_name,' ',last_name) as patient_name"),
|
|
'created_at as date')
|
|
->where('created_at', '>=', $start_date." 00:00:00")
|
|
->where('created_at', '<=', $end_date." 23:59:59")
|
|
->get();
|
|
}
|
|
public function completedMeetings($start_date,$end_date){
|
|
return Appointment::select(
|
|
'appointments.patient_id',
|
|
'appointments.appointment_time',
|
|
'appointments.appointment_date',
|
|
'appointments.start_time',
|
|
'appointments.end_time',
|
|
'appointments.timezone',
|
|
'telemed_pros.name as provider_name',
|
|
'telemed_pros_id as provider_id',
|
|
'carts.id as order_id',
|
|
'appointments.patient_name'
|
|
)
|
|
->Join('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
|
->Join("carts", "appointments.id","carts.appointment_id")
|
|
->where('appointments.status', "completed")
|
|
->where('appointments.end_time', '>=', $start_date." 00:00:00")
|
|
->where('appointments.end_time', '<=', $end_date." 23:59:59")
|
|
->get();
|
|
}
|
|
public function productsData($start_date,$end_date)
|
|
{
|
|
return Item::select(
|
|
DB::raw("sum(case when items.status='delivered' then items.quantity 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")
|
|
->groupby('plans_v1.title', 'items.plans_id')
|
|
->get();
|
|
// dd(Constant::getFullSql($products));
|
|
}
|
|
}
|