File "SubscriptionController-20260607162924.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/Controllers/SubscriptionController-20260607162924.php
File size: 70.18 KB
MIME-type: text/x-php
Charset: utf-8
<?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;
}
}
}