Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
forbidals
/
admin_panel
/
app
/
Http
/
Controllers
/
Auth
:
SubscriptionController.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace App\Http\Controllers; use App\Models\AddonSubscription; use App\Models\Package; use App\Models\PaymentConfiguration; use App\Models\PaymentTransaction; use App\Models\SchoolSetting; use App\Models\Staff; use App\Models\Subscription; use App\Models\SubscriptionBill; use App\Models\SubscriptionFeature; use App\Models\User; use App\Repositories\AddonSubscription\AddonSubscriptionInterface; use App\Repositories\Feature\FeatureInterface; use App\Repositories\Package\PackageInterface; use App\Repositories\PaymentConfiguration\PaymentConfigurationInterface; use App\Repositories\PaymentTransaction\PaymentTransactionInterface; use App\Repositories\School\SchoolInterface; use App\Repositories\SchoolSetting\SchoolSettingInterface; use App\Repositories\Staff\StaffInterface; use App\Repositories\Subscription\SubscriptionInterface; use App\Repositories\SubscriptionBill\SubscriptionBillInterface; use App\Repositories\SubscriptionFeature\SubscriptionFeatureInterface; use App\Repositories\User\UserInterface; use App\Services\BootstrapTableService; use App\Services\CachingService; use App\Services\FeaturesService; use App\Services\ResponseService; use Barryvdh\DomPDF\Facade\Pdf; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Stripe\Checkout\Session as StripeSession; use Stripe\Exception\ApiErrorException; use App\Services\SubscriptionService; use Illuminate\Support\Facades\Config; use PhpParser\Node\Stmt\TryCatch; use Razorpay\Api\Api; use Stripe\Stripe; use Stripe\StripeClient; use Throwable; use App\Services\PaymentService; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; class SubscriptionController extends Controller { private PackageInterface $package; private FeatureInterface $feature; private SubscriptionInterface $subscription; private AddonSubscriptionInterface $addonSubscription; private UserInterface $user; private SchoolSettingInterface $schoolSettings; private SubscriptionBillInterface $subscriptionBill; private StaffInterface $staff; private PaymentTransactionInterface $paymentTransaction; private SchoolInterface $school; private SchoolSettingInterface $schoolSetting; private CachingService $cache; private SubscriptionFeatureInterface $subscriptionFeature; private PaymentConfigurationInterface $paymentConfiguration; private SubscriptionService $subscriptionService; public function __construct(PackageInterface $package, FeatureInterface $feature, SubscriptionInterface $subscription, AddonSubscriptionInterface $addonSubscription, UserInterface $user, SchoolSettingInterface $schoolSettings, StaffInterface $staff, SubscriptionBillInterface $subscriptionBill, PaymentTransactionInterface $paymentTransaction, SchoolInterface $school, SchoolSettingInterface $schoolSetting, CachingService $cachingService, SubscriptionFeatureInterface $subscriptionFeature, PaymentConfigurationInterface $paymentConfiguration, SubscriptionService $subscriptionService) { $this->package = $package; $this->feature = $feature; $this->subscription = $subscription; $this->addonSubscription = $addonSubscription; $this->user = $user; $this->schoolSettings = $schoolSettings; $this->subscriptionBill = $subscriptionBill; $this->staff = $staff; $this->paymentTransaction = $paymentTransaction; $this->school = $school; $this->schoolSetting = $schoolSetting; $this->cache = $cachingService; $this->subscriptionFeature = $subscriptionFeature; $this->paymentConfiguration = $paymentConfiguration; $this->subscriptionService = $subscriptionService; } public function index() { ResponseService::noRoleThenRedirect('School Admin'); $today_date = Carbon::now()->format('Y-m-d'); $current_plan = $this->subscriptionService->active_subscription(Auth::user()->school_id); $upcoming_package = ''; if ($current_plan) { $upcoming_package = $this->subscription->builder()->whereDate('start_date', '>=', $current_plan->end_date)->whereHas('subscription_bill.transaction', function ($q) { $q->where('payment_status', "succeed"); })->first(); } if (isset($current_plan) && count($current_plan->get())) { $packages = $this->package->builder()->with('package_feature.feature')->where('status', 1)->orderBy('rank', 'ASC')->where('is_trial', 0)->get(); } else { $subscription = $this->subscription->builder()->get(); if (count($subscription)) { $packages = $this->package->builder()->with('package_feature.feature')->where('status', 1)->orderBy('rank', 'ASC')->where('is_trial', 0)->get(); } else { $packages = $this->package->builder()->with('package_feature.feature')->where('status', 1)->orderBy('rank', 'ASC')->get(); } } $features = $this->feature->builder()->ActiveFeatures()->get(); $settings = app(CachingService::class)->getSystemSettings(); $system_settings = $settings; DB::setDefaultConnection('mysql'); $paymentConfiguration = PaymentConfiguration::on('mysql')->where('school_id', null)->where('status', 1)->first(); DB::setDefaultConnection('school'); return view('subscription.index', compact('packages', 'features', 'current_plan', 'settings', 'upcoming_package', 'paymentConfiguration', 'system_settings')); } public function store(Request $request) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } try { if ($request->payment_method == 'stripe') { return $this->subscriptionService->stripe_payment($request->id ?? null, $request->package_id, $request->type, null, null); } else if ($request->payment_method == 'paystack') { return $this->subscriptionService->paystack_payment(null, $request->package_id, $request->type, null, null); } else if ($request->payment_method == 'flutterwave') { return $this->subscriptionService->flutterwave_payment(null, $request->package_id, $request->type, null, null); } } catch (\Throwable $th) { return redirect()->back()->with('error', trans('server_not_responding')); } } public function plan($id, $type, $isCurrentPlan = null) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } // Store subscription plan ResponseService::noRoleThenRedirect('School Admin'); try { DB::beginTransaction(); $package_id = $id; // Check pending bills $subscriptionBill = $this->subscriptionService->subscriptionPendingBill(); if ($subscriptionBill) { ResponseService::errorResponse('Kindly settle any outstanding payments from before'); } $subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); // Check current active subscription if ($subscription) { // Check trial package if ($subscription->package->is_trial == 1) { $data = [ 'package_id' => $package_id, 'plan' => 'Trial' ]; } else { $data = [ 'package_id' => $package_id, 'plan' => 'Regular' ]; } $response = [ 'error' => false, 'message' => trans('data_fetch_successfully'), 'data' => $data, ]; return response()->json($response); } // Prepaid plan if ($type == 0) { if (isset($isCurrentPlan)) { $isCurrentPlan = $isCurrentPlan; } else { $isCurrentPlan = 1; } $response = [ 'error' => false, 'message' => trans('prepaid_plan'), 'type' => 'prepaid', 'url' => url('subscriptions/prepaid/package') . '/' . $package_id . '/0/' . $isCurrentPlan ]; return response()->json($response); } else { // Postpaid plans $subscription = $this->subscriptionService->createSubscription($package_id, null, null, 1); } DB::commit(); ResponseService::successResponse(trans('Package Subscription Successfully')); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, 'Subscription Controller -> Plan method'); ResponseService::errorResponse(); } } public function prepaid_plan($package_id, $type = null, $isCurrentPlan = null) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } try { DB::setDefaultConnection('mysql'); $paymentConfiguration = PaymentConfiguration::where('school_id', null)->where('status', 1)->first(); if (!$paymentConfiguration) { return redirect()->back()->with('error', trans('server_not_responding')); } if ($paymentConfiguration->payment_method == 'Stripe') { return $this->subscriptionService->stripe_payment(null, $package_id, $type, null, $isCurrentPlan); } else if ($paymentConfiguration->payment_method == 'Paystack') { return $this->subscriptionService->paystack_payment(null, $package_id, $type, null, $isCurrentPlan); } else if ($paymentConfiguration->payment_method == 'Flutterwave') { return $this->subscriptionService->flutterwave_payment(null, $package_id, $type, null, $isCurrentPlan); } } catch (\Throwable $th) { DB::rollBack(); ResponseService::logErrorResponse($th, 'Subscription Controller -> Prepaid Plan method'); ResponseService::errorResponse(); } } public function show() { ResponseService::noRoleThenRedirect('School Admin'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'id'); $order = request('order', 'DESC'); $search = $_GET['search']; DB::setDefaultConnection('mysql'); $settings = app(CachingService::class)->getSystemSettings()->toArray(); $paymentConfiguration = PaymentConfiguration::where('school_id', null)->first(); if ($paymentConfiguration) { $currency = $paymentConfiguration->currency_code; } else { $currency = $settings['currency_code']; } $sql = $this->subscriptionBill->builder()->with('transaction', 'subscription.addons.feature') ->with([ 'subscription.addons' => function ($q) { $q->withTrashed()->with('transaction'); } ]) ->where(function ($query) use ($search) { $query->when($search, function ($q) use ($search) { $q->where('id', 'LIKE', "%$search%") ->orwhere('description', 'LIKE', "%$search%") ->orwhere('amount', 'LIKE', "%$search%") ->orwhere('total_student', 'LIKE', "%$search%") ->orwhere('total_staff', 'LIKE', "%$search%") ->orwhere('due_date', 'LIKE', "%$search%") ->orWhereHas('subscription', function ($q) use ($search) { $q->where('name', 'LIKE', "%$search%"); }) ->Owner(); }); }); $total = $sql->count(); if ($offset >= $total && $total > 0) { $lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset $offset = $lastPage; } $sql = $sql->orderBy($sort, $order)->skip($offset)->take($limit); $res = $sql->get(); // dd(DB::getQueryLog()); $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; $settings = app(CachingService::class)->getSystemSettings(); foreach ($res as $row) { $payment_status = $transaction_id = null; $operate = BootstrapTableService::button('fa fa-dollar', '#', ['btn', 'btn-xs', 'btn-gradient-success', 'btn-rounded', 'btn-icon', 'edit-data'], ['data-id' => $row->id, 'title' => trans('view_bill'), "data-toggle" => "modal", "data-target" => "#editModal"]); $operate .= BootstrapTableService::button('fa fa-file-pdf-o', url('subscriptions/bill/receipt', $row->id), ['btn-gradient-info'], ['title' => 'Receipt', 'target' => '_blank']); if (isset($row->transaction)) { $payment_status = $row->transaction->payment_status; $transaction_id = $row->transaction->order_id; } $addons = $row->subscription->addons; $amount = number_format($row->amount, 2); $tempRow['no'] = $no++; $tempRow['id'] = $row->id; $end_date_format = date('Y-m-d', strtotime($row->subscription->end_date)); $start_date_format = date('Y-m-d', strtotime($row->subscription->start_date)); if ($row->subscription->package_type == 1) { $end_date_formatted = Carbon::parse($end_date_format)->addDay(); $tempRow['date'] = format_date($end_date_formatted); } else { $created_at_format = date('Y-m-d', strtotime($row->subscription->end_date)); $tempRow['date'] = format_date($created_at_format); } $tempRow['start_date'] = format_date($row->subscription->getRawOriginal('start_date')); $tempRow['end_date'] = format_date($row->subscription->getRawOriginal('end_date')); $tempRow['due_date'] = format_date($row->due_date); $tempRow['name'] = $row->subscription->name; $tempRow['description'] = $row->description; $tempRow['total_student'] = $row->total_student; $tempRow['total_staff'] = $row->total_staff; $tempRow['amount'] = $amount; $tempRow['subscription'] = $row->subscription; $tempRow['addons'] = $addons; $tempRow['payment_status'] = $payment_status; $tempRow['transaction_id'] = $transaction_id; $tempRow['currency_symbol'] = $settings['currency_symbol'] ?? ''; $tempRow['total_days'] = $settings['billing_cycle_in_days']; $start_date = Carbon::parse($start_date_format); $end_date = Carbon::parse($end_date_format); $tempRow['usage_days'] = $start_date->diffInDays($end_date) + 1; $tempRow['default_amount'] = $this->subscriptionService->checkMinimumAmount(strtoupper($currency), $amount); $tempRow['operate'] = $operate; $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function history() { ResponseService::noRoleThenRedirect('School Admin'); try { $data = [ 'students' => 0, 'staffs' => 0 ]; $today_date = Carbon::now()->format('Y-m-d'); $active_package = $this->subscriptionService->active_subscription(Auth::user()->school_id); DB::setDefaultConnection('mysql'); $paymentConfiguration = PaymentConfiguration::where('school_id', null)->where('status', 1)->first(); $upcoming_package = ''; if ($active_package) { $upcoming_package = $this->subscription->builder()->with('package.package_feature.feature', 'subscription_bill.transaction')->whereDate('start_date', '>', $active_package->end_date)->first(); if (!$upcoming_package) { /*TODO : this logic is problematic here*/ $upcoming_package = $active_package; } DB::setDefaultConnection('school'); // Check prepaid / postpaid plan if ($active_package->package_type == 1) { $students = $this->user->builder()->withTrashed()->where(function ($q) use ($active_package) { $q->whereBetween('deleted_at', [$active_package->start_date, $active_package->end_date]); })->orWhereNull('deleted_at')->Owner()->role('Student')->count(); $staffs = $this->staff->builder()->whereHas('user', function ($q) use ($active_package) { $q->where(function ($q) use ($active_package) { $q->withTrashed()->whereBetween('deleted_at', [$active_package->start_date, $active_package->end_date]) ->orWhereNull('deleted_at'); })->Owner(); })->count(); } else { $students = $this->user->builder()->where('status', 1)->role('Student')->where('school_id', $active_package->school_id)->count(); $staffs = $this->staff->builder()->whereHas('user', function ($q) use ($active_package) { $q->where('status', 1)->where('school_id', $active_package->school_id); })->count(); } $data = [ 'students' => $students, 'staffs' => $staffs ]; } $system_settings = app(CachingService::class)->getSystemSettings()->toArray(); $school_settings = app(CachingService::class)->getSchoolSettings()->toArray(); $system_settings['currency_symbol'] = $system_settings['currency_symbol'] ?? ''; $features = FeaturesService::getFeatures(); DB::setDefaultConnection('school'); return view('subscription.subscription', compact('active_package', 'upcoming_package', 'data', 'school_settings', 'system_settings', 'features', 'paymentConfiguration')); } catch (Throwable $e) { ResponseService::logErrorResponse($e, 'Subscription Controller -> History method'); ResponseService::errorResponse(); } } public function cancel_upcoming($id = null) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } ResponseService::noRoleThenRedirect('School Admin'); try { if ($id) { $subscription = $this->subscription->findById($id); // Remove addons first $this->addonSubscription->builder()->where('start_date', $subscription->start_date)->where('end_date', $subscription->end_date)->delete(); // Remove subscription $this->subscription->deleteById($id); } else { $data[] = [ 'name' => 'auto_renewal_plan', 'data' => 0, 'type' => 'integer' ]; $this->schoolSettings->upsert($data, ["name"], ["data"]); } $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.SETTINGS')); ResponseService::successResponse('Your upcoming plan has been canceled successfully'); } catch (\Throwable $e) { ResponseService::logErrorResponse($e, 'Subscription Controller -> Cancel Upcoming method'); ResponseService::errorResponse(); } } public function confirm_upcoming_plan($id) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } ResponseService::noRoleThenRedirect('School Admin'); try { DB::beginTransaction(); $message = 'Your Upcoming Billing Cycle Plan Has Been Added Successfully'; // $current_subscription = $this->subscription->default()->with('package')->first(); $current_subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); $subscription = $this->subscription->builder()->where('start_date', '>', $current_subscription->end_date)->first(); if ($subscription) { $response = [ 'error' => true, 'message' => trans('already_added'), 'data' => $subscription ]; return response()->json($response); } $package = $this->package->findById($id); // Create upcoming subscription $subscription = $this->subscriptionService->createSubscription($id, null, null, 0); // Add addons for upcoming plan $current_addons = $this->addonSubscription->default()->with('addon')->where('status', 1)->has('addon')->get(); $addon_data = array(); foreach ($current_addons as $current_addon) { if (!in_array($current_addon->addon->feature_id, $package->package_feature->pluck('feature_id')->toArray())) { $addon_data[] = [ 'feature_id' => $current_addon->feature_id, 'price' => $current_addon->addon->price, 'start_date' => $subscription->start_date, 'end_date' => $subscription->end_date, 'subscription_id' => $subscription->id ]; } else { $this->addonSubscription->update($current_addon->id, ['status' => 0]); } } $this->addonSubscription->createBulk($addon_data); $data[] = [ 'name' => 'auto_renewal_plan', 'data' => 1, 'type' => 'integer' ]; $this->schoolSettings->upsert($data, ["name"], ["data"]); $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.SETTINGS')); DB::commit(); ResponseService::successResponse($message); } catch (\Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, 'Subscription Controller -> Confirm Upcoming Plan method'); ResponseService::errorResponse(); } } /** * @throws ApiErrorException */ public function payment_success($check_out_session_id, $subscriptionBill_id = null, $package_id = null, $type = null, $subscription_id = null, $isCurrentPlan = null) { // check_out_session_id => Stripe check out session // subscriptionBill_id => If already bill generated Like postpaid plan run cron job and generate bill // package_id => required for prepaid plans if payment success then create all required entries like => subscriptions, subscription bill, subscription features and all. // type & subscription_id // Required when setting up next prepaid plan pay before current plan expires $settings = app(CachingService::class)->getSystemSettings(); $currency = $settings['currency_code']; DB::setDefaultConnection('mysql'); $paymentConfiguration = PaymentConfiguration::where('school_id', null)->first(); $stripe_secret_key = $paymentConfiguration->secret_key ?? null; $currency = $paymentConfiguration->currency_code; Stripe::setApiKey($stripe_secret_key); $session = StripeSession::retrieve($check_out_session_id); $status = "pending"; if ($session->payment_status == 'paid') { $status = "succeed"; } $id = ''; if ($type != -1) { if ($type == 1) { $subscription = $this->subscriptionService->createSubscription($package_id, NULL, $subscription_id); } elseif ($type == 0 && $isCurrentPlan == 1) { $subscription = $this->subscriptionService->createSubscription($package_id, null, null, 1); } else { $subscription = $this->subscriptionService->createSubscription($package_id); } $subscription_features = array(); foreach ($subscription->package->package_feature as $key => $feature) { $subscription_features[] = [ 'subscription_id' => $subscription->id, 'feature_id' => $feature->feature_id ]; } $this->subscriptionFeature->upsert($subscription_features, ['subscription_id', 'feature_id'], ['subscription_id', 'feature_id']); // Create bill if not if ($subscription->package_type == 1) { // Postpaid $this->subscriptionService->createSubscriptionBill($subscription, 1); } else { // Prepaid $subscription_bill[] = [ 'subscription_id' => $subscription->id, 'amount' => $subscription->charges, 'total_student' => $subscription->no_of_students, 'total_staff' => $subscription->no_of_staffs, 'due_date' => Carbon::now(), 'school_id' => $subscription->school_id ]; $this->subscriptionBill->upsert($subscription_bill, ['subscription_id', 'school_id'], ['amount', 'total_student', 'total_staff', 'due_date']); } $id = $subscription->subscription_bill->id; } else { if ($subscriptionBill_id != -1) { $id = $subscriptionBill_id; } if ($package_id != -1 && $id != '') { $subscription = $this->subscriptionService->createSubscription($package_id, null, null, 1); $id = $subscription->subscription_bill->id; } } $payment_data = [ 'user_id' => Auth::user()->id, 'amount' => ($session->amount_total / 100), 'payment_gateway' => 'Stripe', 'order_id' => $session->payment_intent, 'payment_id' => $session->id, 'payment_status' => $status, ]; DB::setDefaultConnection('mysql'); $paymentTransaction = $this->paymentTransaction->create($payment_data); $subscriptionBill = $this->subscriptionBill->update($id, ['payment_transaction_id' => $paymentTransaction->id]); $stripe = new StripeClient($stripe_secret_key); $stripeData = $stripe->customers->create( [ 'metadata' => [ 'amount' => $paymentTransaction->amount, 'transaction_id' => $paymentTransaction->id, 'order_id' => $paymentTransaction->order_id, 'payment_id' => $paymentTransaction->payment_id, 'payment_status' => $paymentTransaction->payment_status, ] ] ); $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.FEATURES'), $subscriptionBill->school_id); return redirect()->route('subscriptions.history')->with('success', trans('the_payment_has_been_completed_successfully')); } public function payment_cancel($subscriptionBillId = null) { DB::rollBack(); if ($subscriptionBillId != -1) { $subscriptionBill = $this->subscriptionBill->findById($subscriptionBillId, ['*'], ['subscription']); if ($subscriptionBill->subscription->package_type == 0) { $subscription_id = $subscriptionBill->subscription_id; $this->subscriptionFeature->builder()->where('subscription_id', $subscription_id)->delete(); $this->subscriptionBill->deleteById($subscriptionBillId); $this->subscription->deleteById($subscription_id); } } return redirect()->route('subscriptions.history')->with('error', trans('the_payment_has_been_cancelled')); } public function bill_receipt($id) { DB::setDefaultConnection('mysql'); $subscriptionBill = SubscriptionBill::with('subscription.addons.transaction', 'transaction', 'school')->with([ 'subscription.addons' => function ($q) { $q->withTrashed()->with('feature'); } ])->find($id); $settings = app(CachingService::class)->getSystemSettings()->toArray(); $settings['horizontal_logo'] = basename($settings['horizontal_logo'] ?? ''); $status = 3; $transaction_id = null; if ($subscriptionBill->transaction) { $status = $subscriptionBill->transaction->payment_status; $transaction_id = $subscriptionBill->transaction->order_id; } $paymentConfiguration = PaymentConfiguration::where('school_id', null)->first(); $currency = ''; if ($paymentConfiguration) { $currency = $paymentConfiguration->currency_code; } else { $currency = $settings['currency_code']; } $deafult_amount = $this->subscriptionService->checkMinimumAmount(strtoupper($currency), $subscriptionBill->amount); $start_date = Carbon::parse($subscriptionBill->subscription->start_date); $usage_days = $start_date->diffInDays(Carbon::parse($subscriptionBill->subscription->end_date)) + 1; DB::setDefaultConnection('school'); Config::set('database.connections.school.database', $subscriptionBill->school->database_name); DB::purge('school'); DB::connection('school')->reconnect(); DB::setDefaultConnection('school'); $school_settings = app(CachingService::class)->getSchoolSettings('*', $subscriptionBill->school_id)->toArray(); if (count($school_settings) == 0) { Cache::forget(config('constants.CACHE.SCHOOL.SETTINGS') . "_" . $subscriptionBill->school_id); $school_settings = app(CachingService::class)->getSchoolSettings('*', $subscriptionBill->school_id)->toArray(); } $pdf = Pdf::loadView('subscription.subscription_receipt', compact('settings', 'subscriptionBill', 'school_settings', 'status', 'transaction_id', 'deafult_amount', 'usage_days')); return $pdf->stream('subscription.pdf'); } public function subscription_report() { ResponseService::noPermissionThenRedirect('subscription-view'); $school = $this->school->builder(); $settings = app(CachingService::class)->getSystemSettings(); $packages = $this->package->builder()->where('is_trial', 0)->get()->pluck('package_with_type', 'id'); $over_due = $this->subscription->builder()->with('subscription_bill.transaction') ->whereHas('package', function ($q) { $q->where('is_trial', 0); })->get()->where('status', 'Over Due')->count(); $unpaid = $this->subscription->builder()->with('subscription_bill.transaction') ->whereHas('package', function ($q) { $q->where('is_trial', 0); })->get()->whereIn('status', ['Failed', 'Pending', 'Unpaid'])->count(); $paid = $this->subscription->builder()->with('subscription_bill.transaction') ->whereHas('package', function ($q) { $q->where('is_trial', 0); })->get()->where('status', 'Paid')->count(); $data = [ 'registration' => $school->count(), 'active' => $school->where('status', 1)->count(), 'deactivate' => $school->where('status', 0)->count(), 'over_due' => $over_due, 'unpaid' => $unpaid, 'paid' => $paid, ]; return view('schools.subscription', compact('data', 'settings', 'packages')); } public function subscription_report_show(Request $request, $status = null) { ResponseService::noPermissionThenRedirect('subscription-view'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'start_date'); $order = request('order', 'ASC'); $search = request('search'); $sql = $this->subscription->builder()->with('subscription_bill.transaction', 'school')->has('school') //search query ->when($search, function ($query) use ($search) { $query->where(function ($query) use ($search) { $query->orwhere('name', 'LIKE', "%$search%") ->orwhereHas('school', function ($q) use ($search) { $q->where('name', 'LIKE', "%$search%"); }); }); }); $total = $sql->count(); $sql->orderBy($sort, $order); $res = $sql->get(); if ($status) { $res = $res->whereIn('status', ['Over Due', 'Failed', 'Pending', 'Unpaid']); $total = count($res); $res = $res; } else { if ($request->status == 'Not Generated') { $res = $res->where('status', 'Not Generated'); $total = count($res); } else if ($request->status != 0) { $res = $res->where('status', $request->status); $total = count($res); } } if ($offset >= $total && $total > 0) { $lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset $offset = $lastPage; } $res = $res->skip($offset)->take($limit); $res = (object) $res; $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; foreach ($res as $row) { $operate = ''; // Update Current plan or Delete upconing plan if ($row->status == 'Current Cycle' || $row->status == 'Next Billing Cycle') { // Start immediate plan if ($row->status == 'Current Cycle') { $operate = BootstrapTableService::menuButton('update_current_plan', "#", ['update-current-plan'], ['data-toggle' => "modal", 'data-target' => "#update-current-plan"]); } // Remove next billing cycle and stop auto renewal if ($row->status == 'Next Billing Cycle') { $operate .= BootstrapTableService::menuButton('stop_auto_renewal_plan', "#", ['stop-auto-renewal-plan'], ['data-id' => $row->id]); } } // Change bill date if (($row->status == 'Over Due' || $row->status == 'Failed' || $row->status == 'Pending' || $row->status == 'Unpaid') && number_format($row->subscription_bill->amount, 2) != 0) { $operate .= BootstrapTableService::menuButton('change_bill_date', "#", ['change-bill'], ['data-toggle' => "modal", 'data-target' => "#change-bill"]); } // Generate bill if ($row->status == 'Bill Not Generated') { $operate .= BootstrapTableService::menuButton('generate_bill', "#", ['generate-bill'], []); } // Bill Receipt & Pay bill cash if (($row->status == 'Paid' || $row->status == 'Over Due' || $row->status == 'Failed' || $row->status == 'Pending' || $row->status == 'Unpaid' || $row->status == 'Bill Not Generated') && $row->subscription_bill) { if ($row->status != 'Paid') { $operate .= BootstrapTableService::menuButton('receive_payment', url('subscriptions/bill-payment', $row->subscription_bill->id), ['receive_payment'], []); } $operate .= BootstrapTableService::menuButton('Receipt', url('subscriptions/bill/receipt', $row->subscription_bill->id), [], ['target' => '_blank']); } // Delete payment [ cash / cheque ] receive if ($row->subscription_bill) { if ($row->subscription_bill->transaction) { if (in_array($row->subscription_bill->transaction->payment_gateway, ['Cash', 'Cheque'])) { // $operate .= BootstrapTableService::button('fa fa-dollar', url('subscriptions/bill-payment', $row->subscription_bill->id), ['btn-gradient-success receive_payment'], ['title' => trans("edit_payment")]); $operate .= BootstrapTableService::menuButton('edit_payment', url('subscriptions/bill-payment', $row->subscription_bill->id), ['receive_payment'], []); // $operate .= BootstrapTableService::deleteButton(url('subscriptions/bill-payment/destroy', $row->subscription_bill->payment_transaction_id)); $operate .= BootstrapTableService::menuDeleteButton('delete_payment', url('subscriptions/bill-payment/destroy', $row->subscription_bill->payment_transaction_id), ['receive_payment'], []); } } } if ($row->status == 'Unpaid' && $row->subscription_bill) { // delete subscription bill $operate .= BootstrapTableService::menuTrashButton('delete', route('subscriptions-bill.trash', $row->subscription_bill->id)); } $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['logo'] = $row->school->logo; $tempRow['school_name'] = $row->school->name; $tempRow['plan'] = $row->name; $tempRow['billing_cycle'] = format_date($row->start_date) . ' - ' . format_date($row->end_date); if ($row->subscription_bill) { $tempRow['amount'] = number_format(ceil($row->subscription_bill->amount * 100) / 100, 2); // $tempRow['amount'] = $row->subscription_bill->amount; $tempRow['due_date'] = $row->subscription_bill->due_date; $tempRow['subscription_bill_id'] = $row->subscription_bill->id; $tempRow['subscription_bill.due_date'] = format_date($row->subscription_bill->due_date); } // $tempRow['operate'] = $operate; $tempRow['operate'] = BootstrapTableService::menuItem($operate); $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function update_expiry(Request $request) { ResponseService::noPermissionThenRedirect('subscription-change-bills'); $request->validate([ 'end_date' => 'required', ]); try { DB::beginTransaction(); $subscription = $this->subscription->findById($request->id); $upcoming_package_start_date = Carbon::parse($subscription->end_date)->addDay()->format('Y-m-d'); $upcoming_package = $this->subscription->builder()->where('school_id', $request->school_id)->whereDate('start_date', $upcoming_package_start_date)->first(); $end_date = date('Y-m-d', strtotime($request->end_date)); // Update upcoming billing if found if ($upcoming_package) { $systemSettings = $this->cache->getSystemSettings(); $upcoming_package_end_date = Carbon::parse($end_date)->addDays($systemSettings['billing_cycle_in_days'])->format('Y-m-d'); $this->subscription->update($upcoming_package->id, ['start_date' => Carbon::parse($end_date)->addDay()->format('Y-m-d'), 'school_id' => $request->school_id, 'end_date' => $upcoming_package_end_date]); } $this->subscription->update((int) $request->id, ['end_date' => $end_date, 'school_id' => $request->school_id]); $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.FEATURES'), $request->school_id); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function change_bill_date(Request $request) { ResponseService::noPermissionThenRedirect('subscription-change-bills'); $request->validate([ 'due_date' => 'required', ]); try { DB::beginTransaction(); $due_date = date('Y-m-d', strtotime($request->due_date)); $this->subscriptionBill->update($request->id, ['due_date' => $due_date, 'school_id' => $request->school_id]); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function start_immediate_plan($id = null, $type = null) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } ResponseService::noRoleThenRedirect('School Admin'); try { DB::beginTransaction(); // Check previous pending bills $subscriptionBill = $this->subscriptionService->subscriptionPendingBill(); if ($subscriptionBill) { ResponseService::errorResponse('Kindly settle any outstanding payments from before'); } if ($type == 0) { $paymentConfiguration = PaymentConfiguration::where('school_id', null)->where('status', 1)->first(); if (!$paymentConfiguration) { ResponseService::errorResponse(trans('server_not_responding')); } } // Get current plan $subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); // Postpaid plan generate bill if ($subscription->package_type == 1) { // Create current subscription plan bill $this->subscriptionService->createSubscriptionBill($subscription, null); } // Update current plan end date & delete features $current_subscription_expiry = $this->subscription->update($subscription->id, ['end_date' => Carbon::now()->format('Y-m-d')]); $this->subscriptionFeature->builder()->where('subscription_id', $subscription->id)->delete(); // Delete upcoming $this->subscription->builder()->with('package')->whereDate('start_date', '>', $subscription->end_date)->delete(); // Delete addons $addons = $this->addonSubscription->builder()->where('subscription_id', $subscription->id)->get(); $soft_delete_addon = array(); foreach ($addons as $key => $addon) { $this->addonSubscription->update($addon->id, ['end_date' => $current_subscription_expiry->end_date]); $soft_delete_addon[] = $addon->id; } $this->addonSubscription->builder()->whereIn('id', $soft_delete_addon)->delete(); $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.FEATURES')); DB::commit(); // Create new subscription plan if ($type == 0) { // return json respons // isCurrentPlan $isCurrentPlan = 1; $response = [ 'error' => false, 'message' => 'Select prepaid plan', 'type' => 0, 'url' => url('subscriptions/prepaid/package') . '/' . $id . '/' . $type . '/' . $isCurrentPlan ]; ResponseService::successResponse('Data Fetched Successfully', $response); } else { $this->subscriptionService->createSubscription($id, null, null, 1); $response = [ 'error' => false, 'message' => 'Select prepaid plan', 'type' => 1, 'url' => null ]; } ResponseService::successResponse('Data Updated Successfully', $response); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function update_current_plan(Request $request) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } ResponseService::noPermissionThenRedirect('subscription-change-bills'); try { DB::beginTransaction(); // Get active plan $subscription = $this->subscription->builder()->where('id', $request->id)->first(); if ($subscription->package_type == 1) { // Create bill for current subscription plan $subscriptionBillData = $this->subscriptionService->createSubscriptionBill($subscription, null); } // Expiry current plan end date & delete features $this->subscription->update($subscription->id, ['end_date' => Carbon::now()->format('Y-m-d'), 'school_id' => $subscription->school_id]); $this->subscriptionFeature->builder()->where('subscription_id', $subscription->id)->delete(); // Create new subscription plan $new_subscription = $this->subscriptionService->createSubscription($request->package_id, $subscription->school_id, null, 1); // Change start and end date if upcoming plan found $upcoming_plan = $this->subscription->builder()->with('package')->where('school_id', $subscription->school_id)->whereDate('start_date', Carbon::parse($subscription->end_date)->addDay()->format('Y-m-d'))->first(); if ($upcoming_plan) { $upcoming_plan_data = [ 'start_date' => Carbon::parse($new_subscription->end_date)->addDay()->format('Y-m-d'), 'end_date' => Carbon::parse($new_subscription->end_date)->addDays($upcoming_plan->package->days)->format('Y-m-d'), 'school_id' => $upcoming_plan->school_id ]; $this->subscription->update($upcoming_plan->id, $upcoming_plan_data); } // Expiry addons $addons = $this->addonSubscription->builder()->where('subscription_id', $subscription->id)->where('school_id', $subscription->school_id)->get(); $soft_delete_addon = array(); foreach ($addons as $key => $addon) { $this->addonSubscription->update($addon->id, ['end_date' => $new_subscription->end_date, 'school_id' => $new_subscription->school_id]); $soft_delete_addon[] = $addon->id; } $this->addonSubscription->builder()->whereIn('id', $soft_delete_addon)->delete(); $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.FEATURES'), $new_subscription->school_id); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function destroy($id) { // ResponseService::noPermissionThenSendJson('subscription-change-bills'); try { DB::beginTransaction(); $subscription = $this->subscription->findById($id); // $school_settings = [ // 'name' => 'auto_renewal_plan', // 'data' => '0', // 'school_id' => $subscription->school_id, // 'type' => 'integer' // ]; $schoolSetting = SchoolSetting::where('name', 'auto_renewal_plan')->where('school_id', $subscription->school_id)->first(); if ($schoolSetting) { $schoolSetting->data = 0; $schoolSetting->save(); } $this->subscription->deleteById($id); $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.SETTINGS'), $subscription->school_id); DB::commit(); ResponseService::successResponse('Auto-renewal successfully canceled'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, 'Subscription Controller -> Destroy method'); ResponseService::errorResponse(); } } public function generate_bill($id) { ResponseService::noPermissionThenSendJson('subscription-change-bills'); if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } try { DB::beginTransaction(); $subscription = $this->subscription->findById($id); $today_date = Carbon::now()->format('Y-m-d'); $subscriptionBillData = $this->subscriptionService->createSubscriptionBill($subscription, 1); $addons = AddonSubscription::where('school_id', $subscription->school_id)->where('end_date', $subscription->end_date)->get(); $soft_delete_addon_ids = array(); foreach ($addons as $addon) { $soft_delete_addon_ids[] = $addon->id; } // Delete subscription features SubscriptionFeature::where('subscription_id', $subscription->id)->delete(); // Check auto-renew plan is enabled $auto_renewal_plan = SchoolSetting::where('name', 'auto_renewal_plan')->where('data', 1)->where('school_id', $subscription->school_id)->first(); if ($auto_renewal_plan) { $check_subscription = Subscription::whereDate('start_date', '<=', $today_date)->whereDate('end_date', '>=', $today_date)->where('school_id', $subscription->school_id)->first(); // Check if already set upcoming billing cycle or not if (!$check_subscription) { // Not set, add previous subscription and addons $previous_subscription = Subscription::where('school_id', $subscription->school_id)->orderBy('end_date', 'DESC')->first(); // Create subscription plan $new_subscription_plan = $this->subscriptionService->createSubscription($previous_subscription->package_id, $previous_subscription->school_id, null, 1); // Check addons $addons = AddonSubscription::where('school_id', $subscription->school_id)->where('subscription_id', $subscription->id)->where('status', 1)->get(); $addons_data = array(); foreach ($addons as $addon) { $addons_data[] = [ 'school_id' => $subscription->school_id, 'feature_id' => $addon->feature_id, 'price' => $addon->addon->price, 'start_date' => $today_date, 'end_date' => $new_subscription_plan->end_date, 'status' => 1, 'subscription_id' => $new_subscription_plan->id, ]; } AddonSubscription::upsert($addons_data, ['school_id', 'feature_id', 'end_date'], ['price', 'start_date', 'status', 'subscription_id']); } else { // Already set plan, update charges in subscription table $update_subscription = $this->subscriptionService->createSubscription($check_subscription->package_id, $check_subscription->school_id, $check_subscription->id, 1); // Create addon $addons = AddonSubscription::where('school_id', $subscription->school_id)->where('subscription_id', $subscription->id)->where('status', 1)->get(); $update_addons = array(); foreach ($addons as $addon) { $update_addons[] = [ 'school_id' => $subscription->school_id, 'feature_id' => $addon->feature_id, 'price' => $addon->addon->price, 'start_date' => $update_subscription->start_date, 'end_date' => $update_subscription->end_date, 'status' => 1, 'subscription_id' => $update_subscription->id, ]; } AddonSubscription::upsert($update_addons, ['school_id', 'feature_id', 'end_date'], ['price', 'start_date', 'status', 'subscription_id']); } AddonSubscription::whereIn('id', $soft_delete_addon_ids)->delete(); } DB::commit(); ResponseService::successResponse('bill generated successfully'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, 'Subscription Controller -> Generate bill method'); ResponseService::errorResponse(); } } public function transactions_log() { ResponseService::noPermissionThenRedirect('subscription-view'); return view('subscription.transaction_log'); } public function subscription_transaction_list(Request $request) { ResponseService::noPermissionThenRedirect('subscription-view'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'id'); $order = request('order', 'DESC'); $sql = $this->subscriptionBill->builder() ->with([ 'school:id,name,logo', 'transaction', 'addons', 'subscription.addons' ]) ->has('transaction') ->where('amount', '>', 0); if (!empty($request->search)) { $search = $request->search; $sql->where(function ($q) use ($search) { $q->where('amount', 'LIKE', "%$search%") ->orWhereHas('transaction', function ($q) use ($search) { $q->where('order_id', 'LIKE', "%$search%") ->orwhere('payment_id', 'LIKE', "%$search%") ->orWhere('payment_gateway', 'LIKE', "%$search%"); })->orWhereHas('school', function ($q) use ($search) { $q->where('name', 'LIKE', "%$search%"); }); }); } $currency = ''; $paymentConfiguration = ''; $settings = app(CachingService::class)->getSystemSettings()->toArray(); $paymentConfiguration = PaymentConfiguration::where('school_id', null)->first(); if ($paymentConfiguration) { $currency = $paymentConfiguration->currency_code; } else { $currency = $settings['currency_code']; } if (!empty($request->payment_status)) { $sql->whereHas('transaction', function ($q) use ($request) { $q->where('payment_status', $request->payment_status); }); } $total = $sql->count(); if ($offset >= $total && $total > 0) { $lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset $offset = $lastPage; } $sql->orderBy($sort, $order)->skip($offset)->take($limit); $res = $sql->get(); $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; foreach ($res as $row) { $tempRow = $row->toArray(); if (in_array($row->transaction->payment_gateway, ['Cash', 'Cheque'])) { $amount = number_format($row->amount, 2); } else { $amount = $this->subscriptionService->checkMinimumAmount(strtoupper($currency), number_format($row->amount, 2)); } $tempRow['amount'] = $amount; $tempRow['payment_gateway'] = $row->transaction->payment_gateway; $tempRow['order_id'] = $row->transaction->order_id; $tempRow['payment_id'] = $row->transaction->payment_id; $tempRow['payment_status'] = $row->transaction->payment_status; $tempRow['date'] = $row->transaction->created_at; $tempRow['no'] = $no++; // Add addons information $tempRow['addons'] = []; if ($row->addons) { foreach ($row->addons as $addon) { $tempRow['addons'][] = [ 'feature_name' => $addon->addon->name ?? '', 'price' => number_format($addon->price, 2), 'start_date' => $addon->start_date, 'end_date' => $addon->end_date, 'status' => $addon->status ]; } } $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function bill_payment($id) { ResponseService::noPermissionThenRedirect('subscription-bill-payment'); $subscriptionBill = $this->subscriptionBill->builder()->with('subscription.addons', 'school', 'transaction')->where('id', $id)->first(); $subscription = $subscriptionBill->subscription; $today_date = Carbon::now()->format('Y-m-d'); $start_date = Carbon::parse($subscription->start_date); $usage_days = $start_date->diffInDays($subscription->end_date) + 1; $bill_cycle_days = $subscription->billing_cycle; $student_charges = number_format((($usage_days * $subscription->student_charge) / $bill_cycle_days), 4); $staff_charges = number_format((($usage_days * $subscription->staff_charge) / $bill_cycle_days), 4); $package_type = $subscription->package_type; $systemSettings = $this->cache->getSystemSettings(); return view('subscription.subscription_bill', compact('subscriptionBill', 'student_charges', 'staff_charges', 'systemSettings', 'package_type')); } public function bill_payment_store(Request $request, $id) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } ResponseService::noPermissionThenRedirect('subscription-bill-payment'); $subscriptionBill = $this->subscriptionBill->findById($id); try { DB::beginTransaction(); $billData = [ 'user_id' => $subscriptionBill->school->admin_id, 'amount' => $request->amount, 'payment_gateway' => $request->subscription_transaction['payment_gateway'], 'order_id' => $request->subscription_transaction['payment_gateway'] == 'Cheque' ? $request->cheque_number : null, 'school_id' => $request->school_id, 'payment_status' => 'succeed' ]; if ($subscriptionBill->transaction) { $paymentTransaction = $this->paymentTransaction->update($subscriptionBill->payment_transaction_id, $billData); } else { $paymentTransaction = $this->paymentTransaction->create($billData); } $this->subscriptionBill->update($id, ['payment_transaction_id' => $paymentTransaction->id, 'school_id' => $request->school_id]); DB::commit(); ResponseService::successResponse('Data Stored Successfully'); } catch (\Throwable $th) { DB::rollBack(); ResponseService::logErrorResponse($th); ResponseService::errorResponse(); } } public function delete_bill_payment($id) { if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } ResponseService::noPermissionThenRedirect('subscription-bill-payment'); try { DB::beginTransaction(); $this->subscriptionBill->builder()->where('payment_transaction_id', $id)->update(['payment_transaction_id' => null]); $this->paymentTransaction->deleteById($id); DB::commit(); ResponseService::successResponse('Data Deleted Successfully'); } catch (\Throwable $th) { DB::rollBack(); ResponseService::logErrorResponse($th); ResponseService::errorResponse(); } } public function pay_prepaid_upcoming_plan($package_id, $type, $subscription_id) { // $type [ 0 => Create new subscription with payment, 1 => Already added, updated the records, generated bills, and made the necessary payments ] ResponseService::noRoleThenRedirect('School Admin'); if (env('DEMO_MODE')) { return response()->json(array( 'error' => true, 'message' => "This is not allowed in the Demo Version.", 'code' => 112 )); } try { // type, update/create DB::beginTransaction(); // if ($type == 1) { // // Update records // $subscription = $this->subscriptionService->createSubscription($subscription->package_id, NULL, $subscription->id); // } else { // // Create new // $subscription = $this->subscriptionService->createSubscription($subscription->package_id); // } // $subscription_features = array(); // foreach ($subscription->package->package_feature as $key => $feature) { // $subscription_features[] = [ // 'subscription_id' => $subscription->id, // 'feature_id' => $feature->feature_id // ]; // } // $this->subscriptionFeature->upsert($subscription_features, ['subscription_id', 'feature_id'], ['subscription_id', 'feature_id']); $paymentConfiguration = PaymentConfiguration::where('school_id', null)->where('status', 1)->first(); if ($paymentConfiguration->payment_method == 'Stripe') { return $this->subscriptionService->stripe_payment(null, $package_id, $type, $subscription_id); } else if ($paymentConfiguration->payment_method == 'Paystack') { return $this->subscriptionService->paystack_payment(null, $package_id, $type, $subscription_id); } else if ($paymentConfiguration->payment_method == 'Flutterwave') { return $this->subscriptionService->flutterwave_payment(null, $package_id, $type, $subscription_id); } // DB::commit(); // return $subscription = $this->prepaid_plan($package_id, $type, $subscription_id); return redirect()->route('dashboard')->with('error', trans('server_not_responding')); } catch (\Throwable $th) { DB::rollBack(); return redirect()->route('dashboard')->with('error', trans('server_not_responding')); ResponseService::logErrorResponse($th); ResponseService::errorResponse(); } } public function transaction($year) { try { $paymentTransaction = $this->paymentTransaction->builder()->has('subscription_bill') ->where('payment_status', "succeed") ->select( DB::raw('MONTH(created_at) as month'), DB::raw('YEAR(created_at) as year'), DB::raw('SUM(amount) as total_amount') ) ->groupBy(DB::raw('YEAR(created_at)'), DB::raw('MONTH(created_at)')) ->whereYear('created_at', $year) ->get(); $months = []; // Populate the array with all months for ($i = 1; $i <= 12; $i++) { $months[date("M", mktime(0, 0, 0, $i, 1))] = 0; } // Loop through payment transaction data foreach ($paymentTransaction as $dataPoint) { // Get the month abbreviation for the current data point $monthAbbreviation = date("M", mktime(0, 0, 0, $dataPoint['month'], 1, $dataPoint['year'])); // Update the total amount for the corresponding month $months[$monthAbbreviation] += $dataPoint['total_amount']; } ResponseService::successResponse('Data Fetched Successfully', $months); } catch (\Throwable $th) { ResponseService::logErrorResponse($th); ResponseService::errorResponse(); } } public function trash_bill($id) { try { $subscriptionBill = $this->subscriptionBill->findById($id); $subscriptionBill->delete(); ResponseService::successResponse('Data deleted successfully'); } catch (\Throwable $th) { ResponseService::logErrorResponse($th); ResponseService::errorResponse(); } } public function razorpay_order_id(Request $request) { //dd($request->all()); if ($request->type == 'package' && in_array($request->package_type, ['new', 'immediate'])) { $subscriptionBill = $this->subscriptionService->subscriptionPendingBill(); if ($subscriptionBill) { $response = [ 'error' => true, 'message' => trans('Kindly settle any outstanding payments from before'), 'data' => null ]; return response()->json($response); } } $schoolId = Auth::user()->school_id; DB::setDefaultConnection('mysql'); $paymentConfiguration = PaymentConfiguration::whereNull('school_id')->where(['payment_method' => 'Razorpay'])->where('status', 1)->first(); \Log::info('==========> ' . $paymentConfiguration); $api = new Api($paymentConfiguration->api_key, $paymentConfiguration->secret_key); $paymentTransactionData = $this->paymentTransaction->create([ 'user_id' => Auth::user()->id, 'amount' => $request->amount, 'payment_gateway' => 'Razorpay', 'payment_status' => 'Pending', 'school_id' => $schoolId, ]); // upcoming_plan_type // 1 => Already set upcoming plan update subscription // 0 => Set current subscription plan as upcoming $customMetaData = [ 'type' => $request->type, // Package, Addon 'package_type' => $request->package_type ?? '', 'package_id' => $request->package_id ?? 0, 'amount' => $request->amount, 'currency' => $request->currency ?? 'INR', 'payment_transaction_id' => $paymentTransactionData->id, 'upcoming_plan_type' => $request->upcoming_plan_type ?? 0, 'subscription_id' => $request->subscription_id ?? 0, 'school_id' => Auth::user()->school_id, 'feature_id' => $request->feature_id ?? '', 'end_date' => $request->end_date ?? '', ]; $amount = max(100, round($request->amount * 100)); // Ensure minimum ₹1.00 (100 paise) // dd($amount); $order = $api->order->create([ 'receipt' => time() . mt_rand(0, 999999), 'amount' => $amount, 'currency' => $request->currency ?? 'INR', 'notes' => $customMetaData, 'payment_capture' => 1 ]); $data = [ 'order' => $order->toArray(), 'paymentTransaction' => $paymentTransactionData ]; $response = [ 'error' => false, 'message' => 'data fetch successfully', 'data' => $data ]; return response()->json($response); } public function razorpay(Request $request) { try { $schoolId = Auth::user()->school_id; $systemSettings = $this->cache->getSystemSettings(); $currency_code = $systemSettings['currency_code'] ?? 'INR'; // $api = app(Api::class); DB::setDefaultConnection('mysql'); $paymentConfiguration = PaymentConfiguration::whereNull('school_id')->where('payment_method', 'Razorpay')->where('status', 1)->first(); $api = new Api($paymentConfiguration->api_key, $paymentConfiguration->secret_key); PaymentTransaction::find($request->paymentTransactionId)->update([ 'order_id' => $request->razorpay_order_id, 'payment_id' => $request->razorpay_payment_id ]); $customMetaData = [ 'type' => $request->type, // Package, Addon 'package_type' => $request->package_type ?? '', 'package_id' => $request->package_id ?? 0, 'amount' => $request->amount, 'payment_id' => $request->razorpay_payment_id, 'currency' => $currency_code, 'payment_transaction_id' => 0, 'upcoming_plan_type' => $request->upcoming_plan_type ?? 0, 'subscription_id' => $request->subscription_id ?? 0, 'school_id' => $schoolId, 'feature_id' => $request->feature_id ?? '', 'end_date' => $request->end_date ?? '', ]; $amount = max(100, round($request->amount * 100)); // Ensure minimum ₹1.00 (100 paise) $api->order->create([ 'receipt' => $request->razorpay_order_id, 'amount' => $amount, // amount in the smallest currency unit 'currency' => $currency_code, 'notes' => $customMetaData, 'payment_capture' => 1, ])->toArray(); return redirect()->back()->with('success', trans('the_payment_has_been_completed_successfully')); } catch (\Throwable $th) { return $th; } } }