HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/vhost/disk-apps/demo.sports-crowd.com/app/Http/Controllers/Api/CartApiController.php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use DB;
use Illuminate\Http\Request;
use App\PaymentType;
use App\GatewayPayment;
use App\User;
use App\Order;
use App\Discount;
use App\DiscountOrderUser;
use App\DiscountProduct;
use App\Http\Controllers\ProductTagController;
use App\Http\Controllers\ServiceChargeController;
use App\Http\Controllers\OrderController;
use App\Http\Controllers\ProductController;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;

class CartApiController extends Controller
{
  public function paymentTypes()
  {
    if (!Cache::get('paymentTypes')) {
      $paymentTypes = PaymentType::where('active', true)->get();
      Cache::put('paymentTypes', $paymentTypes, config('cache.time'));
    } else {
      $paymentTypes = Cache::get('paymentTypes');
    }
    $data = array('status' => 'success', 'paymentTypes' => $paymentTypes);
    return response()->json($data, 200);
  }

  public function userCreateOrder(Request $request)
  {
    $order = new OrderController();
    return $order->create($request);
  }

  public function getPaymentGateway(Request $request)
  {
    $gw = GatewayPayment::where('name', 'wompi')->first();
    $user = User::find(Auth::user()->id);
    $order = Order::find($request->id);

    if ($gw->name == "PAYU") {
      $signature = "{$gw->api_key}~{$gw->merchant_id}~{$order->code}~{$order->total_price}~{$gw->currency}";
      $signature = hash('md5', $signature);
      $res = array('gw' => $gw, 'u' => $user, 'signature' => $signature, 'status' => 'success');
    }
    return $res;
  }

  public function discountList()
  {
    $user_id = Auth::user()->id;
    $discountList = Discount::where('active', true)->get();
    $productGift = DiscountProduct::with('product')
      ->join('discounts', 'discounts.id', '=', 'discount_products.discount_id')
      ->where('discounts.active', true)
      ->select('discount_products.*')
      ->get();

    if ($discountList) {
      foreach ($discountList as $discount) {
        if ($discount->discount_type_id === 1) {
          $discountOrderUsers = DiscountOrderUser::where([['user_id', $user_id], ['discount_id', $discount->id]])->whereNotNull('limit_discount')->first();
        } else {
          $discountOrderUsers = DiscountOrderUser::where([['user_id', $user_id], ['discount_id', $discount->id]])->first();
        }
        $discount->discountOrderUsers = $discountOrderUsers;
      }
    }
    $controller = new ServiceChargeController();
    $serviceCharge = 0;
    $serviceChargeEnabled = $controller->validateServiceCharge();
    if ($serviceChargeEnabled) {
      $request = new Request([
        'services'      => 'order',
      ]);
      $serviceCharge = $controller->calculateServiceCharge($request);
    }
    $data = array('status' => 'success', 'discountList' => $discountList, 'productGift' => $productGift, 'serviceCharge' => $serviceCharge, 'serviceChargeEnabled' => $serviceChargeEnabled);
    return response()->json($data, 200);
  }

  function productValidationCart(Request $request)
  {
    $controller = new ProductTagController();
    $productController = new ProductController();

    // Productos con atributos
    $productsAttributesCart = $request['productsAttributesCart'];
    $newProductsAttributesCart = [];
    foreach ($productsAttributesCart as $product) {
      $result = DB::table('product_attributes')
        ->select('product_attributes.available_units', 'product_attributes.price_additional', 'products.price')
        ->join('products', 'products.id', '=', 'product_attributes.product_id')
        ->where([['product_attributes.product_id', $product['product_id']], ['product_attributes.attribute_id', $product['attribute_id']], ['product_attributes.value', $product['value']]])
        ->first();

      $availableStock = $result->available_units >= $product['quantity'];
      $product['available']           = $availableStock;        // Para versiones del APP sin el ajuste de validaciones por stock y precio
      $product['availableStock']      = $availableStock;
      $product['validationMessage']   = !$availableStock ? 'No hay unidades disponibles' : '';

      $specialPrice = $controller->getSpecialPriceTag($product['product_id'], true);
      $flashPrice = $productController->getProductFlashPrice($product['product_id'], true);
      $discountPrice = $productController->getProductDiscountPrice($product['product_id'], true);

      if ($specialPrice) {
        $price = $specialPrice;
        $product['priceAfterSpecialPriceTag'] = $specialPrice;
      } else if ($flashPrice) {
        $price = $flashPrice;
        $product['priceAfterFlash'] = $flashPrice;
      } else if ($discountPrice) {
        $price = $discountPrice;
        $product['priceAfterDiscount'] = $discountPrice;
      } else {
        $price = $result->price + $result->price_additional;
        $product['newPrice'] = $price;
      }

      $availablePrice = floatval($price) == floatval($product['oldPrice']);
      $product['availablePrice'] = $availablePrice;
      $product['validationMessage'] = !$availablePrice ? 'El precio del producto ha cambiado: ' . $this->formatCurrency($price) : '';
      array_push($newProductsAttributesCart, $product);
    }

    // Productos sin atributos
    $productsCart = $request['productsCart'];
    $newProductsCart = [];
    foreach ($productsCart as $product) {
      $result = DB::table('products')
        ->select('available_units', 'price')
        ->where('id', $product['id'])
        ->first();

      $availableStock = $result->available_units >= $product['quantity'];
      $product['available']           = $availableStock;        // Para versiones del APP sin el ajuste de validaciones por stock y precio
      $product['availableStock']      = $availableStock;
      $product['validationMessage']   = !$availableStock ? 'No hay unidades disponibles' : '';

      $specialPrice = $controller->getSpecialPriceTag($product['id'], true);
      $flashPrice = $productController->getProductFlashPrice($product['id'], true);
      $discountPrice = $productController->getProductDiscountPrice($product['id'], true);

      if ($specialPrice) {
        $price = $specialPrice;
        $product['priceAfterSpecialPriceTag'] = $specialPrice;
      } else if ($flashPrice) {
        $price = $flashPrice;
        $product['priceAfterFlash'] = $flashPrice;
      } else if ($discountPrice) {
        $price = $discountPrice;
        $product['priceAfterDiscount'] = $discountPrice;
      } else {
        $price = $result->price;
        $product['newPrice'] = $price;
      }

      $availablePrice = floatval($price) == floatval($product['oldPrice']);
      $product['availablePrice'] = $availablePrice;
      $product['validationMessage'] = !$availablePrice ? 'El precio del producto ha cambiado: ' . $this->formatCurrency($price) : '';
      array_push($newProductsCart, $product);
    }
    $data = array_merge($newProductsAttributesCart, $newProductsCart);
    return response()->json($data, 200);
  }

  function validationOrderForPayment(Request $request)
  {
    $orderId = $request['orderId'];

    $order = DB::table('orders')->select('updated_at')->where('id', $orderId)->first();

    if (!$order) {
        return response()->json(['status' => false, 'message' => 'Orden no encontrada.'], 404);
    }

    if (!is_null($order->updated_at)) {
        $updatedAt = Carbon::parse($order->updated_at);
        $now = Carbon::now();
        $diffMinutes = $updatedAt->diffInMinutes($now);

        if ($diffMinutes < 20) {
            $minutesToWait = 20 - $diffMinutes;
            return response()->json([
                'status' => false,
                'message' => "Debes esperar {$minutesToWait} minuto" . ($minutesToWait > 1 ? 's' : '') . " para poder realizar el pago nuevamente."
            ], 200);
        }
    }
    
    $orderDetails = DB::table('orders as o')
      ->select(
        'op.quantity',
        DB::raw('IF(pa.available_units IS NULL, p.available_units, pa.available_units) AS available_units'),
        DB::raw('IF(pa.value IS NULL, p.name, CONCAT(p.name, " - ", pa.value)) AS description'),
        'op.product_id',
        'opa.attribute_id',
        'opa.value',
        'p.start_flash_discount',
        'p.limit_flash_discount',
        'p.limit_hour_flash_discount',
        'p.flash_price AS product_flash_price',
        'op.price_bruto',
        'op.price',
        'op.flash_price'
      )
      ->leftJoin('order_products as op', 'op.order_id', '=', 'o.id')
      ->leftJoin('order_product_attributes as opa', 'op.id', '=', 'opa.order_product_id')
      ->leftJoin('products as p', 'op.product_id', '=', 'p.id')
      ->leftJoin('product_attributes as pa', function ($join) {
        $join->on('op.product_id', '=', 'pa.product_id')
          ->on('opa.attribute_id', '=', 'pa.attribute_id')
          ->on('opa.value', '=', 'pa.value');
      })
      ->where('o.id', $orderId)
      ->get();

    $valid = true;
    $message = '';
    foreach ($orderDetails as $product) {
      // unidades disponible
      if ($product->quantity > $product->available_units) {
        $quantity = DB::table('orders as o')
          ->select(DB::raw('IFNULL(SUM(op.quantity), 0) AS quantity'))
          ->leftJoin('order_products as op', 'op.order_id', '=', 'o.id')
          ->leftJoin('order_product_attributes as opa', 'op.id', '=', 'opa.order_product_id')
          ->where('o.order_state_id', 1)
          ->where('op.product_id', $product->product_id)
          ->where('opa.attribute_id', $product->attribute_id)
          ->where('opa.value', $product->value)
          ->groupBy('op.product_id', 'opa.attribute_id', 'opa.value')
          ->limit(1)
          ->first();

        if (!$quantity || ($product->quantity > $quantity->quantity)) {
          $valid = false;
          $message .= ($product->description . ', ');
        }
      }

      if (!is_null($product->flash_price) && ($product->flash_price == $product->price)) {
        if ($product->start_flash_discount) {

          // oferta relampago
          $start_flash_discount = $product->start_flash_discount;
          $limit_hour_flash_discount = $product->limit_hour_flash_discount;
          $limit_flash_discount = $product->limit_flash_discount;

          $current_date = date('Y-m-d H:i:s'); //actual del descuento
          $discount_start_date = date($start_flash_discount . ' 00:00:00'); //inicial del descuento
          $discount_end_date = date($limit_flash_discount . ' ' . $limit_hour_flash_discount); //final del descuento

          if (($current_date >= $discount_start_date) && ($current_date <= $discount_end_date)) {
            $valid = true;
          } else {
            $valid = false;
            $message .= ('El descuento expiró, tu pedido ha sido eliminado.');
          }
        }
      }
    }
    $data = array('status' => $valid, 'message' => rtrim($message, ', '));
    return response()->json($data, 200);
  }
}