File "AddonController.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/AddonController.php
File size: 18.45 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Http\Controllers;
use App\Models\PaymentConfiguration;
use App\Repositories\Addon\AddonInterface;
use App\Repositories\AddonSubscription\AddonSubscriptionInterface;
use App\Repositories\Feature\FeatureInterface;
use App\Repositories\PaymentTransaction\PaymentTransactionInterface;
use App\Repositories\Subscription\SubscriptionInterface;
use App\Services\BootstrapTableService;
use App\Services\CachingService;
use App\Services\FeaturesService;
use App\Services\ResponseService;
use App\Services\SubscriptionService;
use Auth;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
use Stripe\Stripe;
use Stripe\StripeClient;
use Stripe\Checkout\Session as StripeSession;
class AddonController extends Controller
{
private FeatureInterface $feature;
private AddonInterface $addon;
private SubscriptionInterface $subscription;
private AddonSubscriptionInterface $addonSubscription;
private CachingService $cache;
private SubscriptionService $subscriptionService;
private PaymentTransactionInterface $paymentTransaction;
private FeaturesService $featureSerive;
public function __construct(FeatureInterface $feature, AddonInterface $addon, SubscriptionInterface $subscription, AddonSubscriptionInterface $addonSubscription, CachingService $cachingService, SubscriptionService $subscriptionService, PaymentTransactionInterface $paymentTransaction, FeaturesService $featureSerive)
{
$this->feature = $feature;
$this->addon = $addon;
$this->subscription = $subscription;
$this->addonSubscription = $addonSubscription;
$this->cache = $cachingService;
$this->subscriptionService = $subscriptionService;
$this->paymentTransaction = $paymentTransaction;
$this->featureSerive = $featureSerive;
}
public function index()
{
ResponseService::noPermissionThenRedirect('addons-list');
$features = $this->feature->builder()->where('is_default', 0)->orderBy('name', 'ASC')->get();
return view('addons.index', compact('features'));
}
public function plan()
{
ResponseService::noRoleThenRedirect('School Admin');
$addons = $this->addon->builder()->with('feature')->where('status', 1)->get();
$settings = app(CachingService::class)->getSystemSettings();
$system_settings = $settings;
$features = $this->featureSerive->getFeatures();
$features = array_keys($features);
$subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id);
DB::setDefaultConnection('mysql');
$paymentConfiguration = PaymentConfiguration::where('school_id', null)->where('status', 1)->first();
DB::setDefaultConnection('school');
return view('addons.plan', compact('addons', 'settings', 'subscription', 'features', 'paymentConfiguration', 'system_settings'));
}
public function store(Request $request)
{
ResponseService::noPermissionThenSendJson('addons-create');
$request->validate([
'name' => 'required',
'price' => 'required|decimal:0,2',
'feature_id' => 'required|unique:addons'
], [
'feature_id.required' => trans('please_select_feature'),
'feature_id.unique' => trans('you_have_previously_created_an_addon_for_this_feature'),
]);
try {
DB::beginTransaction();
$data = [
...$request->all(),
'status' => 0
];
$this->addon->create($data);
DB::commit();
ResponseService::successResponse('Data Store Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> Store method');
ResponseService::errorResponse();
}
}
public function show()
{
ResponseService::noPermissionThenRedirect('addons-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'DESC');
$search = request('search');
$showDeleted = request('show_deleted');
$sql = $this->addon->builder()->with('feature')
->where(function ($q) use ($search) {
$q->when($search, function ($query) use ($search) {
$query->where(function ($query) use ($search) {
$query->where('id', 'LIKE', "%$search%")->orwhere('name', 'LIKE', "%$search%")->orwhere('price', 'LIKE', "%$search%");
});
});
})->when(!empty($showDeleted), function ($q) {
$q->onlyTrashed();
});
$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) {
if ($showDeleted) {
$operate = BootstrapTableService::restoreButton(route('addons.restore', $row->id));
$operate .= BootstrapTableService::trashButton(route('addons.trash', $row->id));
} else {
if ($row->status == 0) {
$operate = BootstrapTableService::button('fa fa-check', '#', ['change-addon-status', 'btn-gradient-success'], ['title' => trans("publish_addon"), 'data-id' => $row->id]);
} else {
$operate = BootstrapTableService::button('fa fa-times', '#', ['change-addon-status', 'btn-gradient-warning'], ['title' => trans("unpublished_addon"), 'data-id' => $row->id]);
}
$operate .= BootstrapTableService::editButton(route('addons.update', $row->id));
$operate .= BootstrapTableService::deleteButton(route('addons.destroy', $row->id));
}
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
$tempRow['price'] = number_format($row->price, 2);
$tempRow['operate'] = $operate;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
ResponseService::noPermissionThenSendJson('addons-edit');
$request->validate([
'name' => 'required',
'price' => 'required|decimal:0,2',
'feature_id' => 'required|unique:addons,feature_id,' . $id,
], [
'feature_id.unique' => trans('you_have_previously_created_an_addon_for_this_feature'),
'name.required' => 'The name is required',
'price.required' => 'The price is required',
]);
try {
DB::beginTransaction();
$data = [
...$request->all(),
];
$this->addon->update($id, $data);
DB::commit();
ResponseService::successResponse('Data updated successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> Update method');
ResponseService::errorResponse();
}
}
public function destroy($id)
{
ResponseService::noPermissionThenSendJson('addons-delete');
try {
DB::beginTransaction();
$this->addon->findById($id)->delete();
DB::commit();
ResponseService::successResponse('Data deleted successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> Delete method');
ResponseService::errorResponse();
}
}
public function restore($id)
{
ResponseService::noPermissionThenSendJson('addons-edit');
try {
DB::beginTransaction();
$this->addon->restoreById($id);
DB::commit();
ResponseService::successResponse('Data restore successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> Restore method');
ResponseService::errorResponse();
}
}
public function trash($id)
{
ResponseService::noPermissionThenSendJson('addons-delete');
try {
DB::beginTransaction();
$addon = $this->addon->findOnlyTrashedById($id);
if (count($addon->addon_subscription)) {
ResponseService::errorResponse('cannot_delete_because_data_is_associated_with_other_data');
} else {
$this->addon->permanentlyDeleteById($id);
}
DB::commit();
ResponseService::successResponse('Data deleted successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> Trash method');
ResponseService::errorResponse();
}
}
public function status($id)
{
ResponseService::noAnyPermissionThenSendJson(['addons-create', 'addons-edit']);
try {
DB::beginTransaction();
$addon = $this->addon->findById($id);
$addon = ['status' => $addon->status == 1 ? 0 : 1];
$this->addon->update($id, $addon);
DB::commit();
ResponseService::successResponse('Data Updated Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> Status method');
ResponseService::errorResponse();
}
}
public function subscribe($id, $type)
{
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();
$addon_id = $id;
$date = Carbon::now()->format('Y-m-d');
// $subscription = $this->subscription->builder()->with('package')->where('start_date', '<=', $date)->where('end_date', '>=', $date)->doesntHave('subscription_bill')->first();
$subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id);
$package_features = $subscription->subscription_feature->pluck('feature_id')->toArray();
// Check active plan
if (!$subscription) {
ResponseService::errorResponse('please_choose_a_plan_before_proceeding');
}
// Not Allowed in free trial subscription package
if ($subscription->package->is_trial == 1) {
ResponseService::errorResponse('Restricted in the free trial subscription');
}
$addon = $this->addon->findById($addon_id);
if (in_array($addon->feature_id, $package_features)) {
ResponseService::errorResponse('you_presently_have_access_to_this_functionality_as_part_of_your_current_subscription');
}
if ($type == 0) {
$paymentConfiguration = PaymentConfiguration::where('school_id', null)->where('status', 1)->first();
if (!$paymentConfiguration) {
ResponseService::errorResponse(trans('server_not_responding'));
}
}
$date = Carbon::now()->format('Y-m-d');
if ($type == 0) {
$addon_check = $this->addonSubscription->builder()->where('feature_id', $addon->feature_id)->where('subscription_id', $subscription->id)->whereHas('transaction', function ($q) {
$q->where('payment_status', 'succeed');
})->first();
} else {
$addon_check = $this->addonSubscription->builder()->where('feature_id', $addon->feature_id)->where('subscription_id', $subscription->id)->first();
}
if ($addon_check) {
ResponseService::errorResponse('this_addon_has_already_been_included_by_you');
}
$status = 0;
$upcoming_plan = $this->subscription->builder()->whereDate('start_date', '>', $subscription->end_date)
->whereHas('package.package_feature', function ($q) use ($addon) {
$q->where('feature_id', $addon->feature_id);
})
->first();
if (!$upcoming_plan) {
$status = 1;
}
$data = [
'feature_id' => $addon->feature_id,
'price' => $addon->price,
'start_date' => Carbon::now(),
'end_date' => $subscription->end_date,
'status' => $status,
'subscription_id' => $subscription->id
];
// createBulk
$addonSubscription = $this->addonSubscription->create($data);
DB::commit();
// If prepaid plan receive payment first
if ($type == 0) {
$response = [
'error' => false,
'message' => trans('prepaid_plan'),
'type' => 'prepaid',
'url' => url('addons/prepaid-package') . '/' . $addonSubscription->id
];
return response()->json($response);
}
$this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.FEATURES'));
// $this->addonSubscription->upsert($data,['school_id','addon_id'],['price','start_date','end_date']);
ResponseService::successResponse('Addon added successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> subscribe method');
ResponseService::errorResponse();
}
}
public function discontinue($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();
$this->addonSubscription->update($id, ['status' => 0]);
DB::commit();
ResponseService::successResponse('Addon discontinue successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Addon Controller -> Discontinue method');
ResponseService::errorResponse();
}
}
public function prepaid_package_addon($id)
{
if (env('DEMO_MODE')) {
return response()->json(array(
'error' => true,
'message' => "This is not allowed in the Demo Version.",
'code' => 112
));
}
try {
return $this->subscriptionService->prepaid_addon_payment($id);
} catch (\Throwable $th) {
DB::rollBack();
ResponseService::logErrorResponse($th, 'Addon Controller -> Prepaid Package Addon method');
ResponseService::errorResponse();
}
}
public function payment_success($check_out_session_id, $id)
{
$settings = app(CachingService::class)->getSystemSettings();
$currency = $settings['currency_code'];
DB::setDefaultConnection('mysql');
$paymentConfiguration = PaymentConfiguration::where('school_id', null)->first();
$currency = $paymentConfiguration->currency_code;
$addonSubscription = $this->addonSubscription->findById($id);
if ($paymentConfiguration->payment_method == 'Stripe') {
$stripe_secret_key = $paymentConfiguration->secret_key ?? null;
Stripe::setApiKey($stripe_secret_key);
$session = StripeSession::retrieve($check_out_session_id);
$status = "pending";
if ($session->payment_status == 'paid') {
$status = "succeed";
}
$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,
];
$paymentTransaction = $this->paymentTransaction->create($payment_data);
$addonSubscription = $this->addonSubscription->update($id, ['payment_transaction_id' => $paymentTransaction->id]);
$stripe = new StripeClient($stripe_secret_key);
$stripeData = $stripe->customers->create(
[
'metadata' => [
'user_id' => Auth::user()->id,
'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'), $addonSubscription->school_id);
return redirect()->route('addons.plan')->with('success', trans('the_payment_has_been_completed_successfully'));
}
public function payment_cancel()
{
return redirect()->route('addons.plan')->with('error', trans('the_payment_has_been_cancelled'));
}
public function payment_success_callback()
{
$request = request();
if ($request->trxref && $request->reference || ($request->status == 'successful' && $request->transaction_id)) {
return redirect()->route('addons.plan')->with('success', trans('the_payment_has_been_completed_successfully'));
} else {
return redirect()->route('addons.plan')->with('error', trans('the_payment_has_been_cancelled'));
}
}
public function payment_cancel_callback()
{
return redirect()->route('addons.plan')->with('error', trans('the_payment_has_been_cancelled'));
}
}