339 lines
11 KiB
PHP
Executable File
339 lines
11 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Http\Controllers\API;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Resources\CartResource;
|
|
use App\Models\PersonalAccessToken;
|
|
use Illuminate\Http\Request;
|
|
use App\Models\Cart;
|
|
use App\Models\Currency;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class CartController extends Controller
|
|
{
|
|
public function getCart()
|
|
{
|
|
$currency = Currency::latest()->first();
|
|
// add currency to cache
|
|
cache()->put('currency', $currency, now()->addMinutes(60));
|
|
|
|
$bearer = $this->getBearerToken();
|
|
|
|
if ($bearer) {
|
|
[$personalAccessTokenId, $token] = explode('|', $bearer, 2);
|
|
$personalAccessToken = PersonalAccessToken::find($personalAccessTokenId);
|
|
|
|
if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) {
|
|
// Authenticated
|
|
$cart = Cart::with('product')->whereHas('product', function ($product) {
|
|
$product->where('child_id', null);
|
|
})->where('user_id', $personalAccessToken->tokenable_id)->orderBy('id', 'desc')->get();
|
|
}
|
|
} else {
|
|
// Check for local token in request headers
|
|
$localToken = $this->getLocalToken();
|
|
if ($localToken) {
|
|
$cart = Cart::with('product')->whereHas('product', function ($product) {
|
|
$product->where('child_id', null);
|
|
})->where('token', $localToken)->get();
|
|
}
|
|
}
|
|
|
|
$price_solutions = 0;
|
|
$discount_solutions = 0;
|
|
$total_solutions = 0;
|
|
|
|
$price = 0;
|
|
$discount = 0;
|
|
$total = 0;
|
|
|
|
$getReadySolutionProductsCart = collect([]);
|
|
$getSingleProductsCart = collect([]);
|
|
|
|
if (isset($cart)) {
|
|
$getReadySolutionProductsCart = $cart->filter(function ($cart) {
|
|
return $cart->product->is_ready_solution == true;
|
|
});
|
|
|
|
$ready_solutions_count = 0;
|
|
$price_solutions = $getReadySolutionProductsCart->filter(function ($cart) {
|
|
return $cart->product->count >= $cart->count;
|
|
})->map(function ($cart) use (&$ready_solutions_count) {
|
|
$ready_solutions_count += $cart->count;
|
|
$cart->product->price_total = !empty($cart->product->price_discount) ? $cart->product->price_discount * $cart->count : $cart->product->price * $cart->count;
|
|
$cart->product->price_discount_total = !empty($cart->product->price_discount) ? ($cart->product->price - $cart->product->price_discount) * $cart->count : 0;
|
|
$cart->product->price_products = $cart->product->price * $cart->count;
|
|
return $cart;
|
|
});
|
|
|
|
$discount_solutions = $price_solutions->sum('product.price_discount_total');
|
|
$total_solutions = $price_solutions->sum('product.price_total');
|
|
$price_solutions = $price_solutions->sum('product.price_products');
|
|
|
|
$single_products_count = 0;
|
|
$getSingleProductsCart = collect($cart)->filter(function ($cart) {
|
|
return $cart->product->is_ready_solution == false;
|
|
});
|
|
|
|
$price = $getSingleProductsCart->filter(function ($cart) {
|
|
return $cart->product->count >= $cart->count;
|
|
})->map(function ($cart) use (&$single_products_count) {
|
|
$single_products_count += $cart->count;
|
|
$cart->product->price_total = !empty($cart->product->price_discount) ? $cart->product->price_discount * $cart->count : $cart->product->price * $cart->count;
|
|
$cart->product->price_discount_total = !empty($cart->product->price_discount) ? ($cart->product->price - $cart->product->price_discount) * $cart->count : 0;
|
|
$cart->product->price_products = $cart->product->price * $cart->count;
|
|
return $cart;
|
|
});
|
|
|
|
$discount = $price->sum('product.price_discount_total');
|
|
$total = $price->sum('product.price_total');
|
|
$price = $price->sum('product.price_products');
|
|
}
|
|
|
|
// get currency from cache
|
|
$currency = cache()->get('currency');
|
|
|
|
return [
|
|
'data' => [
|
|
'ready_solutions' => [
|
|
'products' => CartResource::collection($getReadySolutionProductsCart),
|
|
'price' => ceiling($price_solutions * $currency->dollar, 100),
|
|
'discount' => ceiling($discount_solutions * $currency->dollar, 100),
|
|
'total' => ceiling($total_solutions * $currency->dollar, 100),
|
|
],
|
|
'ready_solutions_count' => $ready_solutions_count,
|
|
'single_products' => [
|
|
'products' => CartResource::collection($getSingleProductsCart),
|
|
'price' => ceiling($price * $currency->dollar, 100),
|
|
'discount' => ceiling($discount * $currency->dollar, 100),
|
|
'total' => ceiling($total * $currency->dollar, 100),
|
|
],
|
|
'single_products_count' => $single_products_count
|
|
]
|
|
];
|
|
}
|
|
|
|
private function getUser()
|
|
{
|
|
$bearer = $this->getBearerToken();
|
|
|
|
$type = null;
|
|
$user = null;
|
|
$token = null;
|
|
|
|
if ($bearer) {
|
|
[$personalAccessTokenId, $token] = explode('|', $bearer, 2);
|
|
$personalAccessToken = PersonalAccessToken::find($personalAccessTokenId);
|
|
|
|
if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) {
|
|
// Authenticated
|
|
$type = 'user';
|
|
$user = User::findOrFail($personalAccessToken->tokenable_id);
|
|
$token = null;
|
|
}
|
|
} else {
|
|
// Check for local token in request headers
|
|
$localToken = $this->getLocalToken();
|
|
if ($localToken) {
|
|
$type = 'token';
|
|
$user = null;
|
|
$token = $localToken;
|
|
}
|
|
}
|
|
|
|
return [
|
|
'type' => $type,
|
|
'user' => $user,
|
|
'token' => $token
|
|
];
|
|
}
|
|
|
|
public function addToCart(Request $request)
|
|
{
|
|
try {
|
|
// Validate the request
|
|
$request->validate([
|
|
'product_id' => 'required|exists:products,id',
|
|
]);
|
|
|
|
// Retrieve the bearer token from the request
|
|
$bearer = $this->getBearerToken();
|
|
|
|
if ($bearer) {
|
|
[$personalAccessTokenId, $token] = explode('|', $bearer, 2);
|
|
$personalAccessToken = PersonalAccessToken::find($personalAccessTokenId);
|
|
|
|
if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) {
|
|
// Authenticated
|
|
$user = User::find($personalAccessToken->tokenable_id);
|
|
|
|
if ($user) {
|
|
$this->updateOrCreateCart($user, $request->product_id);
|
|
return response()->json(['status' => true, 'data' => null]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for local token in request headers
|
|
$localToken = $this->getLocalToken();
|
|
if (!$localToken) {
|
|
return response()->json(['message' => 'Unauthorized'], 401);
|
|
}
|
|
|
|
$this->updateOrCreateCartByToken($localToken, $request->product_id);
|
|
} catch (\Throwable $e) {
|
|
return response()->json([
|
|
'message' => $e->getMessage()
|
|
], 403);
|
|
}
|
|
|
|
return response()->json(['status' => true, 'data' => null]);
|
|
}
|
|
|
|
public function add(Cart $cart)
|
|
{
|
|
$user = $this->getUser();
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
if (empty($user['type']))
|
|
abort(403);
|
|
|
|
if ($user['type'] == 'token') {
|
|
if ($cart->token != $user['token'])
|
|
abort(403);
|
|
} else if ($user['type'] == 'user') {
|
|
if ($cart->user_id != $user['user']->id)
|
|
abort(403);
|
|
}
|
|
|
|
$cart->update([
|
|
'count' => $cart->count + 1
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
DB::rollBack();
|
|
return response()->json([
|
|
'message' => trans('errors.try_again')
|
|
])->setStatusCode(403);
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return $this->getCart();
|
|
}
|
|
|
|
public function decrease(Cart $cart)
|
|
{
|
|
$user = $this->getUser();
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
if (empty($user['type']))
|
|
abort(403);
|
|
|
|
if ($user['type'] == 'token') {
|
|
if ($cart->token != $user['token'])
|
|
abort(403);
|
|
} else if ($user['type'] == 'user') {
|
|
if ($cart->user_id != $user['user']->id)
|
|
abort(403);
|
|
}
|
|
|
|
if ($cart->count <= 1) {
|
|
$cart->delete();
|
|
} else {
|
|
$cart->update([
|
|
'count' => $cart->count - 1
|
|
]);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
DB::rollBack();
|
|
return response()->json([
|
|
'message' => trans('errors.try_again')
|
|
])->setStatusCode(403);
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return $this->getCart();
|
|
}
|
|
|
|
public function delete($cartId)
|
|
{
|
|
try {
|
|
DB::beginTransaction();
|
|
Cart::find($cartId)->delete();
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
DB::rollBack();
|
|
return response()->json([
|
|
'message' => trans('errors.try_again')
|
|
])->setStatusCode(403);
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return $this->getCart();
|
|
}
|
|
|
|
protected function updateOrCreateCart($user, $productId)
|
|
{
|
|
$cart = $user->cart()->where('product_id', $productId)->first();
|
|
|
|
try {
|
|
if ($cart) {
|
|
// Update the existing cart item
|
|
Cart::where('id', $cart->id)->update([
|
|
'count' => $cart->count + 1
|
|
]);
|
|
} else {
|
|
// Create a new cart item
|
|
$user->cart()->create([
|
|
'product_id' => $productId,
|
|
'count' => 1,
|
|
]);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
return response()->json([
|
|
'message' => trans('errors.try_again')
|
|
])->setStatusCode(403);
|
|
}
|
|
}
|
|
|
|
protected function updateOrCreateCartByToken($localToken, $productId)
|
|
{
|
|
$cart = Cart::where('token', $localToken)
|
|
->where('product_id', $productId)
|
|
->first();
|
|
|
|
if ($cart) {
|
|
// Update the existing cart item
|
|
Cart::where('id', $cart->id)->update([
|
|
'count' => $cart->count + 1
|
|
]);
|
|
} else {
|
|
// Create a new cart item
|
|
Cart::create([
|
|
'token' => $localToken,
|
|
'product_id' => $productId,
|
|
'count' => 1,
|
|
]);
|
|
}
|
|
}
|
|
|
|
private function getLocalToken()
|
|
{
|
|
return request()->header('X-Application-Token');
|
|
}
|
|
|
|
private function getBearerToken()
|
|
{
|
|
return request()->bearerToken();
|
|
}
|
|
}
|