/home/brandsfa/public_html/app/Services/CartService.php
<?php
namespace App\Services;
use App\Enums\SessionKey;
use App\Traits\CalculatorTrait;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class CartService
{
use CalculatorTrait;
/**
* @param object $request
* @param object $product
* @param string|null $colorName
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getVariantData(object $request , object $product, string $colorName = null):array
{
$quantity = 0;
$price = 0;
$discount = 0;
$tax = 0;
$variation = $this->makeVariation(
request:$request,
colorName: $colorName,
choiceOptions: json_decode($product['choice_options'])
);
if ($variation != null) {
$count = count(json_decode($product->variation));
for ($i = 0; $i < $count; $i++) {
if (json_decode($product->variation)[$i]->type == $variation) {
$discount = $this->getDiscountAmount(price:json_decode($product->variation)[$i]->price,discount: $product['discount'],discountType: $product['discount_type']);
$tax = $product->tax_model=='exclude' ? $this->getTaxAmount(price: json_decode($product->variation)[$i]->price-$discount, tax: $product['tax']) : 0;
$price = json_decode($product->variation)[$i]->price - $discount + $tax;
$quantity = json_decode($product->variation)[$i]->qty;
}
}
} else {
$discount = $this->getDiscountAmount(price:$product['unit_price'],discount:$product['discount'],discountType:$product['discount_type']);
$tax = $product->tax_model=='exclude' ? $this->getTaxAmount(price:$product->unit_price-$discount, tax:$product['tax']) : 0;
$price = $product['unit_price'] - $discount + $tax;
$quantity = $product['current_stock'];
}
$requestQuantity = (int)$request['quantity'];
$inCartStatus = 0;
$cartData = session()->get(session(SessionKey::CURRENT_USER)) ?? [];
$inCartData = null;
foreach ($cartData as $cart) {
if(is_array($cart) && $cart['id'] == $product['id'] && $cart['variant'] == $variation){
$inCartStatus = 1;
if ($product['discount_type'] == 'percent') {
$discount = ($cart['price'] * $product['discount']) / 100;
} elseif ($product['discount_type'] == 'flat') {
$discount = $product['discount'];
}
$inCartData = [
'price' => usdToDefaultCurrency(amount:($cart['price']-$discount+$tax)*$cart['quantity']),
'discount' => $discount,
'quantity' => (int)$cart['quantity'],
'variant' => $cart['variant'],
'id' => $cart['id'],
];
$requestQuantity = (int)$request['quantity_in_cart'];
}
}
return [
'price' => usdToDefaultCurrency(amount: $price * $requestQuantity),
'discount' => $discount,
'tax' => $product->tax_model == 'exclude' ? setCurrencySymbol(amount: usdToDefaultCurrency(amount: $tax * $requestQuantity), currencyCode: getCurrencyCode()) : 'incl.',
'quantity' => $product['product_type'] == 'physical' ? $quantity : 100,
'inCartStatus' => $inCartStatus,
'inCartData' => $inCartData,
'requestQuantity' => $requestQuantity,
];
}
public function makeVariation(object $request , string|null $colorName ,array $choiceOptions):string
{
$variation = '';
if ($colorName) {
$variation = $colorName;
}
foreach ($choiceOptions as $key => $choice) {
if ($variation != null) {
$variation .= '-' . str_replace(' ', '', $request[$choice->name]);
} else {
$variation .= str_replace(' ', '', $request[$choice->name]);
}
}
return $variation;
}
public function getUserId():int
{
$userId = 0;
if(Str::contains(session(SessionKey::CURRENT_USER), 'saved-customer'))
{
$userId = explode('-',session(SessionKey::CURRENT_USER))[2];
}
return $userId;
}
public function getUserType():string
{
$userType = 'walking-customer';
if(Str::contains(session(SessionKey::CURRENT_USER), 'saved-customer'))
{
$userType = 'saved-customer';
}
return $userType;
}
public function getNewCartSession( string|int $cartId):Void
{
if(!session()->has(SessionKey::CURRENT_USER)){
session()->put(SessionKey::CURRENT_USER,$cartId);
}
if(!session()->has(SessionKey::CART_NAME))
{
if(!in_array($cartId,session(SessionKey::CART_NAME)??[]))
{
session()->push(SessionKey::CART_NAME, $cartId);
}
}
}
public function getCartKeeper():Void
{
$cartId = session(SessionKey::CURRENT_USER);
$cart = session($cartId);
$cartKeeper = [];
if (session()->has($cartId) && count($cart) > 0) {
foreach ($cart as $cartItem) {
$cartKeeper[] = $cartItem;
}
}
session()->put(session(SessionKey::CURRENT_USER) , $cartKeeper);
}
public function getVariationPrice(array $variation,string $variant):float
{
$count = count($variation);
$price = 0;
for ($i = 0; $i < $count; $i++) {
if ($variation[$i]->type == $variant) {
$price = $variation[$i]->price;
}
}
return $price;
}
public function getVariationQuantity(array $variation,string $variant):int
{
$count = count($variation);
$productQuantity = 0;
for ($i = 0; $i < $count; $i++) {
if ($variation[$i]->type == $variant) {
$productQuantity = $variation[$i]->qty;
}
}
return $productQuantity;
}
public function getCurrentQuantity($variation,$variant,$quantity):int
{
$productQuantity = $this->getVariationQuantity($variation,$variant);
return $productQuantity - $quantity;
}
public function addCartDataOnSession(object $product,int $quantity,float $price,float $discount,string $variant,array $variations):array
{
$cartId =session(SessionKey::CURRENT_USER);
$sessionData =[
'id' => $product['id'],
'customerId' => $this->getUserId(),
'customerOnHold' => false,
'quantity' => $quantity,
'price' => $price,
'name' => $product['name'],
'image'=> $product['thumbnail'],
'discount' => $discount,
'tax_model'=>$product['tax_model'],
'variant' => $variant,
'variations' => $variations,
];
if (session()->has($cartId)) {
$keeper = [];
foreach (session($cartId) as $item) {
$keeper[] = $item;
}
$keeper[] = $sessionData;
if(!isset(session()->get($cartId)['add_to_cart_time']))
{
$keeper += ['add_to_cart_time' => Carbon::now()];
}
session()->put($cartId, $keeper);
} else {
session()->put($cartId, [$sessionData]+['add_to_cart_time' => Carbon::now()]);
}
return $sessionData ;
}
public function getQuantityAndUpdateTime(object $request,object $product):int
{
$quantity = 0 ;
$cartId = session(SessionKey::CURRENT_USER);
$cart = session($cartId);
$keeper=[];
foreach ($cart as $item){
if (is_array($item)) {
$variantCheck = false;
if(!empty($item['variant']) && ($item['variant'] ==$request['variant']) && ($item['id'] == $request['key'])){
$variantCheck = true;
}elseif(empty($request['variant']) && $item['id'] == $request['key']){
$variantCheck = true;
}
if ($variantCheck) {
$variant = '';
if($item['variations'])
{
foreach($item['variations'] as $value)
{
if($variant!=null)
{
$variant .= '-' . str_replace(' ', '', $value);
}else{
$variant .= str_replace(' ', '', $value);
}
}
}
if ($variant != null) {
$productQuantity = $this->getVariationQuantity(json_decode($product['variation']),$variant);
} else
{
$productQuantity = $product['current_stock'];
}
$quantity = $productQuantity - $request['quantity'] ;
if($product['product_type'] =='physical' && $quantity < 0)
{
return $quantity ;
}
$item['quantity'] = $request['quantity'];
}
$keeper[] = $item;
}
}
$keeper += ['add_to_cart_time' => Carbon::now()];
session()->put($cartId, $keeper);
return $quantity;
}
public function getNewCartId():void
{
$cartId = 'walking-customer-'.rand(10,1000);
session()->put(SessionKey::CURRENT_USER,$cartId);
if(!in_array($cartId,session(SessionKey::CART_NAME)??[]))
{
session()->push(SessionKey::CART_NAME, $cartId);
}
}
public function getCartSubtotalCalculation(object $product,array $cartItem,array $calculation):array
{
$taxCalculate = $calculation['taxCalculate'] + ($this->getTaxAmount($cartItem['price']-$cartItem['discount'], $product['tax'])*$cartItem['quantity']);
$productSubtotal = (($cartItem['price']-$cartItem['discount']) * $cartItem['quantity']);
return [
'countItem' => $calculation['countItem']+1,
'taxCalculate' => $taxCalculate ,
'totalTaxShow' => $calculation['totalTaxShow'] + $taxCalculate,
'totalTax' => $calculation['totalTax'] + $taxCalculate,
'productSubtotal' => $productSubtotal,
'subtotal' => $calculation['subtotal'] + $productSubtotal - ($cartItem['tax_model'] == 'include'?$taxCalculate : 0 ),
'discountOnProduct' => $calculation['discountOnProduct'] + ($cartItem['discount'] * $cartItem['quantity']),
];
}
public function getTotalCalculation(array $subTotalCalculation, string $cartName):array
{
$total = $subTotalCalculation['subtotal'];
$extraDiscount = session()->get($cartName)['ext_discount'] ?? 0;
$extraDiscountType = session()->get($cartName)['ext_discount_type'] ?? 'amount';
if ($extraDiscountType == 'percent' && $extraDiscount > 0) {
$extraDiscount = (($subTotalCalculation['subtotal']+$subTotalCalculation['discountOnProduct']) * $extraDiscount) / 100;
}
if ($extraDiscount) {
$total -= $extraDiscount;
}
$couponDiscount = 0;
if (isset(session()->get($cartName)['coupon_discount'])) {
$couponDiscount = session()->get($cartName)['coupon_discount'];
}
return [
'total' => $total,
'couponDiscount' => $couponDiscount,
'extraDiscount' => $extraDiscount
];
}
public function customerOnHoldStatus($status):void
{
$cart = session(session(SessionKey::CURRENT_USER));
$cartKeeper = [];
if (session()->has(session(SessionKey::CURRENT_USER)) && count($cart) > 0) {
foreach ($cart as $cartItem) {
if (is_array($cartItem)) {
$cartItem['customerOnHold'] = $status;
}
$cartKeeper[] = $cartItem;
}
}
session()->put(session(SessionKey::CURRENT_USER) , $cartKeeper);
}
public function checkCurrentStock(string $variant,array $variation,int $productQty,int $quantity):int
{
if ($variant != null) {
$currentQty = $this->getCurrentQuantity(variation:$variation,variant: $variant,quantity: $quantity);
}else {
$currentQty = $productQty - $quantity;
}
return $currentQty;
}
}