Viewing File: /home/ubuntu/vedadeals-backend-base/app/Http/Controllers/Api/OrderApiController.php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Helpers\Helper;
use DB, Exception, Setting, stdClass, Storage;
use Carbon\Carbon;
use App\Models\{ User, Order, UserWallet, UserCard, Product, OrderProduct, Cart, OrderPayment, OrderTracking };
use Illuminate\Validation\Rule;
use App\Http\Resources\{ OrderResource, ProductResource, OrderPaymentPreviewResource };
use Illuminate\Support\Facades\Cache;
use App\Services\{ PaymentService, OrderService, ProductService, EmailService };
use Barryvdh\DomPDF\Facade\Pdf;
use App\Jobs\{ SendInvoiceEmailJob, OrderNotificationJob };
class OrderApiController extends Controller
{
protected $loginUser;
protected $skip, $take;
public function __construct(Request $request) {
info(url()->current());
info("Request Data".print_r($request->all(), true));
$this->loginUser = User::find($request->id);
$this->skip = $request->skip ?: 0;
$this->take = $request->take ?: (Setting::get('admin_take_count') ?: TAKE_COUNT);
$this->timezone = $this->loginUser->timezone ?? "America/New_York";
$request->request->add(['timezone' => $this->timezone ? : "America/New_York"]);
}
/**
* @method orders_direct_checkout()
*
* @uses to complete the order process by cart checkout type.
*
* @created Karthick
*
* @updated
*
* @param
*
* @return success / failure message
*/
public function orders_direct_checkout(Request $request) {
try {
$rules = [
'product_id' => ['required', 'exists:products,id'],
'quantity' => ['required', 'numeric', "min:1"],
'delivery_address_id' => ['required', 'exists:delivery_addresses,id,user_id,'.$request->id],
'payment_mode' => ['required', Rule::in(PAYMENT_MODE_WALLET, PAYMENT_MODE_CARD)],
'user_card_id' => [Rule::requiredIf($request->payment_mode == PAYMENT_MODE_CARD), 'exists:user_cards,id,user_id,'.$request->id],
];
$custom_errors = [
'product_id.exists' => api_error(1009, strtolower(tr('product'))),
'delivery_address_id.exists' => api_error(123),
];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$checkout_data = new stdClass();
$checkout_data->payment_mode = $request->payment_mode; $checkout_data->quantity = $request->quantity;
$checkout_data->user_id = $request->id; $checkout_data->product_id = $request->product_id;
$checkout_data->user_card_id = $request->user_card_id ? : 0; $checkout_data->delivery_address_id = $request->delivery_address_id;
if($request->payment_mode == PAYMENT_MODE_WALLET) {
$result = OrderService::handle_direct_checkout($checkout_data);
} elseif($request->payment_mode == PAYMENT_MODE_CARD) {
$user_card = UserCard::firstWhere(['id' => $request->user_card_id, 'user_id' => $request->id]);
if(!$user_card) {
throw new Exception(api_error(125), 125);
}
$result = OrderService::handle_direct_checkout($checkout_data);
}
if(!$result['result']) {
throw new Exception($result['message']);
}
$data['order_unique_id'] = $result['order_unique_id'];
EmailService::order_status_email($data['order_unique_id']);
return $this->sendResponse(api_success(144), 144, $data);
} catch (Exception $e) {
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_cart_checkout()
*
* @uses to complete the order process by direct checkout type.
*
* @created Karthick
*
* @updated
*
* @param
*
* @return success / failure message
*/
public function orders_cart_checkout(Request $request) {
try {
$rules = [
'delivery_address_id' => ['required', 'exists:delivery_addresses,id,user_id,'.$request->id],
'payment_mode' => ['required', Rule::in(PAYMENT_MODE_WALLET, PAYMENT_MODE_CARD, PAYMENT_MODE_UPI, PAYMENT_MODE_COD)],
'user_card_id' => [Rule::requiredIf($request->payment_mode == PAYMENT_MODE_CARD), 'exists:user_cards,id,user_id,'.$request->id],
'payment_id' => [Rule::requiredIf($request->payment_mode == PAYMENT_MODE_UPI), 'unique:order_payments,payment_id'],
];
$custom_errors = [ 'delivery_address_id.exists' => api_error(123) ];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$checkout_data = new stdClass();
$checkout_data->payment_mode = $request->payment_mode; $checkout_data->quantity = $request->quantity;
$checkout_data->user_id = $request->id; $checkout_data->product_id = $request->product_id;
$checkout_data->user_card_id = $request->user_card_id ? : 0; $checkout_data->delivery_address_id = $request->delivery_address_id;
$checkout_data->payment_id = $request->payment_id ?? "";
if($request->payment_mode == PAYMENT_MODE_CARD) {
$user_card = UserCard::firstWhere(['id' => $request->user_card_id, 'user_id' => $request->id]);
if(!$user_card) {
throw new Exception(api_error(125), 125);
}
}
$result = OrderService::handle_cart_checkout($checkout_data);
if(!$result['result']) {
throw new Exception($result['message']);
}
$data['order_unique_id'] = $result['order_unique_id'];
EmailService::order_status_email($data['order_unique_id']);
return $this->sendResponse(api_success(144), 144, $data);
} catch (Exception $e) {
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_list()
*
* @uses to get all the orders list of an user
*
* @created Karthick
*
* @updated
*
* @param
*
* @return
*/
public function orders_list(Request $request) {
try {
$rules = [
'status' => ['nullable', Rule::in(ORDER_RECEIVED, ORDER_AWAITING_PICKUP, ORDER_AWAITING_SHIPMENT, ORDER_SHIPPED, ORDER_COMPLETED, ORDER_CANCELLED, ORDER_RETURN_INITIATED, ORDER_RETURN_REJECTED, ORDER_RETURN_ACCEPTED, ORDER_RETURN_USER_DAMAGE, ORDER_RETURN_SUCCESS, ORDER_REFUND_INITIATED, ORDER_REFUND_SUCCESS, ORDER_REFUND_FAILED)],
'order_status' => ['nullable', Rule::in(ORDER_STATUS_PENDING, ORDER_STATUS_CANCELLED, ORDER_STATUS_RETURNED, ORDER_STATUS_COMPLETED)]
];
Helper::custom_validator($request->all(), $rules, $custom_errors = []);
$base_query = Order::where(['user_id' => $request->id])
->with(['deliveryAddress', 'orderProducts', 'orderProducts.product.category'])
->with(['orderProducts.product' => fn($query) => $query->withTrashed()])
->withSum('orderProducts', 'discount_price')
->withSum('orderProducts', 'total')
->orderBy('updated_at', 'desc');
if($request->filled('status')) {
$base_query = $base_query->where('status', $request->status);
}
if($request->filled('order_status')) {
$base_query = $base_query->where('order_status', $request->order_status);
}
$data['total_orders'] = $base_query->count();
$orders = $base_query->skip($this->skip)->take($this->take)->get();
$data['orders'] = OrderResource::collection($orders);
return $this->sendResponse("", "", $data);
} catch (Exception $e) {
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_view()
*
* @uses to view a order details based on order_unique_id
*
* @created Karthick
*
* @updated
*
* @param
*
* @return
*/
public function orders_view(Request $request) {
try {
$rules = [ 'order_unique_id' => ['required', 'exists:orders,unique_id,user_id,'.$request->id] ];
$custom_errors = ['exists' => api_error(1009, strtolower(tr('order')))];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$order = Order::with(['deliveryAddress', 'orderPayment', 'orderProducts', 'orderProducts.product.category', 'orderTracking'])
->with(['orderProducts.product' => fn($query) => $query->withTrashed()])
->firstWhere(['unique_id' => $request->order_unique_id, 'user_id' => $request->id]);
if(!$order) {
throw new Exception(api_error(1009, strtolower(tr('order'))));
}
$data['order'] = new OrderResource($order);
return $this->sendResponse("", "", $data);
} catch (Exception $e) {
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_cancel()
*
* @uses to cancel a order
*
* @created Karthick
*
* @updated
*
* @param order_unique_id
*
* @return
*/
public function orders_cancel(Request $request) {
try {
$rules = [
'order_unique_id' => ['required', 'exists:orders,unique_id,user_id,'.$request->id],
'cancelled_reason' => 'nullable',
];
$custom_errors = ['exists' => api_error(1009, strtolower(tr('order')))];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$order = Order::firstWhere('unique_id', $request->order_unique_id);
if(!$order) {
throw new Exception(api_error(1009, strtolower(tr('order'))));
}
if($order->is_cancelled == YES && $order->status == ORDER_REFUND_INITIATED) {
throw new Exception(api_error(135), 135);
}
if($order->status == ORDER_COMPLETED) {
throw new Exception(api_error(134), 134);
}
$order_payment = OrderPayment::firstWhere(['order_id' => $order->id]);
DB::beginTransaction();
$order_result = $order->update(['is_cancelled' => YES, 'cancelled_reason' => $request->cancelled_reason ? : '', 'status' => ORDER_REFUND_INITIATED, 'order_status' => ORDER_STATUS_CANCELLED]);
$order_payment_result = $order_payment->update(['is_cancelled' => YES, 'cancelled_reason' => $request->cancelled_reason ? : '', 'cancelled_at' => now(), 'status' => CANCELLED]);
if(!$order_result || !$order_payment_result) {
throw new Exception(api_error(133), 133);
}
$order_products = OrderProduct::where(['order_id' => $order->id])->get(['product_id', 'quantity']);
foreach($order_products as $order_product) {
$update_product_inventory = ProductService::update_product_inventory($order_product->product_id, $order_product->quantity, PRODUCT_CANCELLED);
}
$amount = $order_payment->total;
$payment_data = new stdClass;
$payment_data->user_id = $request->id; $payment_data->amount = $amount;
$payment_data->amount_type = AMOUNT_TYPE_ADD; $payment_data->payment_type = WALLET_PAYMENT_TYPE_REFUND;
$payment_data->payment_mode = PAYMENT_MODE_WALLET; $payment_data->user_billing_account_id = 0;
$user_wallet_payment = PaymentService::user_wallet_payment_save($payment_data);
if(!$user_wallet_payment['result']) {
throw new Exception($user_wallet_payment['message']);
}
$user_wallet = UserWallet::firstOrCreate(['user_id' => $request->id]);
$user_wallet->remaining += $amount;
$user_wallet->total = $order_payment->payment_mode == PAYMENT_MODE_CARD ? $user_wallet->total + $amount : $user_wallet->total;
$user_wallet->used = $order_payment->payment_mode == PAYMENT_MODE_WALLET ? $user_wallet->used - $amount : $user_wallet->used;
$result = $user_wallet->save();
if(!$result) {
throw new Exception(api_error(133), 133);
}
DB::commit();
EmailService::order_status_email($order->order_unique_id);
return $this->sendResponse(api_success(150, formatted_amount($amount)), 150, []);
throw new Exception(api_error(104), 104);
} catch (Exception $e) {
DB::rollback();
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_invoice()
*
* @uses to download or get order invoice via email or download directly.
*
* @created Karthick
*
* @updated
*
* @param order_unique_id
*
* @return order payment invoice pdf
*/
public function orders_invoice(Request $request) {
try {
$rules = [
'order_unique_id' => ['required', 'exists:orders,unique_id,user_id,'.$request->id],
'invoice_via' => Rule::in(VIA_EMAIL, VIA_DOWNLOAD)
];
$custom_errors = ['exists' => api_error(1009, strtolower(tr('order')))];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$order = Order::with(['deliveryAddress:id,address,city,state,pincode', 'orderPayment:id,order_id,unique_id,paid_date,total,payment_mode,payment_id', 'orderProducts:id,order_id,product_id,quantity,total', 'orderProducts.product:id,name'])
->firstWhere(['unique_id' => $request->order_unique_id, 'user_id' => $request->id]);
if(!$order) {
throw new Exception(api_error(1009, strtolower(tr('order'))));
}
if($request->invoice_via == VIA_DOWNLOAD) {
$data['order'] = $order;
$data['timezone'] = $this->timezone;
$data['url'] = Setting::get('frontend_url').'orders/tracking/'.$request->order_unique_id;
$pdf = Pdf::loadView('pdf.invoice', $data)->setPaper('a4');
return $pdf->download("$order->unique_id.pdf");
} else {
EmailService::send_order_invoice_email($order);
return $this->sendResponse(api_success(151), 150, []);
}
throw new Exception(api_error(104), 104);
} catch (Exception $e) {
DB::rollback();
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_checkout()
*
* @uses to complete the order process.
*
* @created Karthick
*
* @updated
*
* @param
*
* @return success / failure message
*/
public function orders_checkout(Request $request) {
try {
$rules = [
'delivery_address_id' => ['required', 'exists:delivery_addresses,id,user_id,'.$request->id],
'payment_mode' => ['required', Rule::in(PAYMENT_MODE_CRYPTO, PAYMENT_MODE_ADMIN)],
'transaction_hash' => [Rule::requiredIf($request->payment_mode == PAYMENT_MODE_CRYPTO)],
'currency' => [Rule::requiredIf($request->payment_mode == PAYMENT_MODE_CRYPTO)],
'wallet_address' => [Rule::requiredIf($request->payment_mode == PAYMENT_MODE_CRYPTO)]
];
$custom_errors = [ 'delivery_address_id.exists' => api_error(123) ];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$checkout_data = new stdClass();
$checkout_data->payment_mode = $request->payment_mode; $checkout_data->user_id = $request->id;
$checkout_data->delivery_address_id = $request->delivery_address_id; $checkout_data->transaction_hash = $request->transaction_hash ? : null;
$checkout_data->currency = $request->currency ? : Setting::get('currency');
$checkout_data->wallet_address = $request->wallet_address ? : null;
$result = OrderService::handle_checkout($checkout_data);
if(!$result['result']) {
throw new Exception($result['message']);
}
$data['order_unique_id'] = $result['order_unique_id'];
OrderNotificationJob::dispatch($data['order_unique_id']);
EmailService::new_order_email_to_admin($data['order_unique_id']);
return $this->sendResponse(api_success(144), 144, $data);
} catch (Exception $e) {
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method order_payments_list()
*
* @uses to get all the order payments list of an user
*
* @created Karthick
*
* @updated
*
* @param
*
* @return
*/
public function order_payments_list(Request $request) {
try {
$base_query = OrderPayment::with(['order:id,unique_id'])->where(['user_id' => $request->id])->orderBy('updated_at', 'desc');
$data['total_order_payments'] = $base_query->count();
$order_payments = $base_query->skip($this->skip)->take($this->take)->get();
$data['order_payments'] = OrderPaymentPreviewResource::collection($order_payments);
return $this->sendResponse("", "", $data);
} catch (Exception $e) {
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_send_cancel_request()
*
* @uses to cancel a order
*
* @created Karthick
*
* @updated
*
* @param order_unique_id
*
* @return
*/
public function orders_send_cancel_request(Request $request) {
try {
$rules = [
'order_unique_id' => ['required', 'exists:orders,unique_id,user_id,'.$request->id],
'cancelled_reason' => 'nullable',
];
$custom_errors = ['exists' => api_error(1009, strtolower(tr('order')))];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$order = Order::with(['deliveryAddress', 'orderPayment', 'orderProducts', 'orderProducts.product', 'orderProducts.product.category', 'orderTracking'])
->firstWhere(['unique_id' => $request->order_unique_id, 'user_id' => $request->id]);
if(!$order) {
throw new Exception(api_error(1009, strtolower(tr('order'))));
}
$data['order'] = new OrderResource($order);
if(!$order) {
throw new Exception(api_error(1009, strtolower(tr('order'))));
}
if($order->is_cancelled == YES && $order->order_status == ORDER_STATUS_CANCELLED) {
throw new Exception(api_error(135), 135);
}
if($order->status == ORDER_COMPLETED) {
throw new Exception(api_error(134), 134);
}
$order_payment = OrderPayment::firstWhere(['order_id' => $order->id]);
$amount = $order_payment->total;
$order_tracking = OrderTracking::firstWhere(['order_id' => $order->id, 'user_id' => $order->user_id]);
DB::beginTransaction();
$now = now();
$order_result = $order->update(['is_cancelled' => YES, 'order_status' => ORDER_STATUS_CANCELLED, 'cancelled_reason' => $request->cancelled_reason ? : '', 'status' => ORDER_REFUND_INITIATED]);
$order_payment_result = $order_payment->update(['is_cancelled' => YES, 'cancelled_reason' => $request->cancelled_reason ? : '', 'cancelled_at' => $now, 'status' => CANCELLED]);
$order_tracking_result = $order_tracking->update(['cancelled_at' => $now, 'refund_initiated_at' => $now, 'status' => ORDER_REFUND_INITIATED]);
if(!$order_result || !$order_payment_result && !$order_tracking_result) {
throw new Exception(api_error(133), 133);
}
$order_products = OrderProduct::where(['order_id' => $order->id])->get(['product_id', 'quantity']);
foreach($order_products as $order_product) {
$update_product_inventory = ProductService::update_product_inventory($order_product->product_id, $order_product->quantity, PRODUCT_CANCELLED);
}
DB::commit();
OrderNotificationJob::dispatch($order->order_unique_id);
$data['order'] = new OrderResource($order->refresh());
return $this->sendResponse(api_success(150, formatted_amount($amount)), 150, $data);
throw new Exception(api_error(104), 104);
} catch (Exception $e) {
DB::rollback();
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_send_return_request()
*
* @uses to send return order request
*
* @created Karthick
*
* @updated
*
* @param order_unique_id
*
* @return
*/
public function orders_send_return_request(Request $request) {
try {
$rules = [
'order_unique_id' => ['required', 'exists:orders,unique_id,user_id,'.$request->id],
'cancelled_reason' => 'required',
];
$custom_errors = [
'exists' => api_error(1009, strtolower(tr('order'))),
'cancelled_reason.required' => api_error(141)
];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$order = Order::with(['deliveryAddress', 'orderPayment', 'orderProducts', 'orderProducts.product', 'orderProducts.product.category', 'orderTracking'])
->firstWhere(['unique_id' => $request->order_unique_id, 'user_id' => $request->id]);
if(!$order) {
throw new Exception(api_error(1009, strtolower(tr('order'))));
}
if($order->order_status == ORDER_STATUS_RETURNED) {
if($order->status == ORDER_RETURN_REJECTED) {
throw new Exception(api_error(142), 142);
}
if($order->status == ORDER_RETURN_USER_DAMAGE) {
throw new Exception(api_error(143), 143);
}
throw new Exception(api_error(140), 140);
}
$order_tracking = OrderTracking::firstWhere(['order_id' => $order->id, 'user_id' => $order->user_id]);
DB::beginTransaction();
$now = now();
$order_result = $order->update(['is_cancelled' => YES, 'order_status' => ORDER_STATUS_RETURNED, 'cancelled_reason' => $request->cancelled_reason ? : '', 'status' => ORDER_RETURN_INITIATED]);
$order_tracking_result = $order_tracking->update(['return_initiated_at' => $now, 'status' => ORDER_RETURN_INITIATED]);
if(!$order_result || !$order_tracking_result) {
throw new Exception(api_error(133), 133);
}
DB::commit();
OrderNotificationJob::dispatch($order->order_unique_id);
$data['order'] = new OrderResource($order->refresh());
return $this->sendResponse(api_success(153), 153, $data);
throw new Exception(api_error(104), 104);
} catch (Exception $e) {
DB::rollback();
return $this->sendError($e->getMessage(), $e->getCode());
}
}
/**
* @method orders_invoice_download()
*
* @uses to store the invoice file in storage.
*
* @created Karthick
*
* @updated
*
* @param order_unique_id
*
* @return order payment invoice pdf
*/
public function orders_invoice_download(Request $request) {
try {
$rules = [
'order_unique_id' => ['required', 'exists:orders,unique_id,user_id,'.$request->id]
];
$custom_errors = ['exists' => api_error(1009, strtolower(tr('order')))];
Helper::custom_validator($request->all(), $rules, $custom_errors);
$order = Order::with(['deliveryAddress:id,address,city,state,pincode', 'orderPayment:id,order_id,unique_id,paid_date,total,payment_mode,payment_id', 'orderProducts:id,order_id,product_id,quantity,total', 'orderProducts.product:id,name'])
->firstWhere(['unique_id' => $request->order_unique_id, 'user_id' => $request->id]);
if(!$order) {
throw new Exception(api_error(1009, strtolower(tr('order'))));
}
$invoice_location = ORDER_INVOICE_PATH."$order->unique_id.pdf";
$invoice['url'] = Storage::disk('public')->url($invoice_location);
if(Storage::disk('public')->exists($invoice_location)) {
return $this->sendResponse('', '' , $invoice);
}
$data['order'] = $order;
$data['timezone'] = $this->timezone;
$data['url'] = Setting::get('frontend_url').'orders/tracking/'.$request->order_unique_id;
$output = Pdf::loadView('pdf.invoice', $data)->setPaper('a4')->output();
Storage::disk('public')->put($invoice_location, $output);
return $this->sendResponse('', '' , $invoice);
} catch (Exception $e) {
DB::rollback();
return $this->sendError($e->getMessage(), $e->getCode());
}
}
}
Back to Directory
File Manager