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/qas.sports-crowd.com/app/Http/Controllers/ProductController.php
<?php

namespace App\Http\Controllers;

use Datatables;
use DB;
use Excel;
use App\Brand;
use App\Category;
use App\Core\CorporateIdentity\Application\CorporateIdentityService;
use App\Core\Product\Application\ProductTagAssignService;
use App\Product;
use App\SizingUnit;
use App\Subcategories;
use App\SubcategoryProduct;
use App\Parameter;
use App\Sucursal;
use App\ProductImage;
use App\ProductAttribute;
use App\UserInformation;
use App\ProductTag;
use App\Tag;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Box\Spout\Reader\ReaderFactory;
use Box\Spout\Common\Type;
use App\Http\Controllers\ShopifyController;
use App\Http\Controllers\WoocommerceController;
use App\Http\Controllers\Exports\ReportProducts;
use App\Http\Controllers\Imports\ProductsImport;
use App\Http\Controllers\Imports\CategoriesImport;
use App\Http\Controllers\Exports\ReportCategories;
use App\Http\Controllers\UtilController;
use App\Models\Central\ServiceCity;
use App\ProductTagAssign;

class ProductController extends Controller
{
    private $util;
    private $productTagAssignService;

    public function __construct()
    {
        $this->util = new UtilController();
        $this->productTagAssignService = new ProductTagAssignService();
    }

    public function index($storeType = 'main')
    {
        $services = new ServiceCity();
        $servicesN = $services->where('active', 1)->get();
        $parameter = Parameter::first();

        if ($parameter->sucursal_products) {
            $sucursals = Sucursal::where('active', 1)->get();
        } else {
            $sucursals = null;
        }

        $corporateIdentity = CorporateIdentityService::get();
        return view('products.products')
            ->with('services', $servicesN)
            ->with('db_name', $parameter->db_name)
            ->with('sucursal_products', $parameter->sucursal_products)
            ->with('external_template', $parameter->external_template)
            ->with('sucursals', $sucursals)
            ->with('parameter', $parameter)
            ->with('storeType', $storeType)
            ->with('corporateIdentity', $corporateIdentity);
    }

    public function indexAdd()
    {
        $brands = Brand::where('active', 1)->get();
        $sub_categories = Subcategories::where('active', 1)->get();
        $parameter = Parameter::select('sucursal_products', 'sync_shopify', 'sync_woocommerce')->first();
        if ($parameter->sucursal_products) {
            $sucursals = Sucursal::where('active', 1)->get();
        } else {
            $sucursals = null;
        }
        $tags = Tag::select('id', 'name')->where('active', true)->get();
        return view('products.addProduct', compact('brands', 'sub_categories', 'sucursals', 'tags'));
    }

    public function create(Request $request, $sync = true)
    {
        $reference_id = null;
        $reference_shopify_id = null;

        $subcategory = "";
        if ($request["sub_categories"] && count($request["sub_categories"])) {
            $subcategory = Subcategories::where('id', $request["sub_categories"][0])->first();
            if ($subcategory) {
                $subcategory = $subcategory->name;
            }
        }

        if ($sync) {
            $woo = new WoocommerceController();

            $func = function ($id_subcategory) {
                if ($id_subcategory) {
                    $getSubcategory = Subcategories::where('id', $id_subcategory)->first();
                    $id_category = $getSubcategory->reference_woocommerce_category_id;
                    return [
                        'id' => intval($id_category),
                    ];
                }
            };

            $categories_woo = array_map($func, $request["sub_categories"]);

            $data = [
                'name'             => $request["name"],
                'price'            => $request["price"],
                'regular_price'    => $request["price"],
                'manage_stock'     => true,
                'stock_quantity'   => intval($request["available_units"]),
                'categories' => $categories_woo,
            ];

            $reference_id = $woo->createProduct($data);

            $parameters = Parameter::select('sync_shopify', 'sucursal_products')->find(1);
            if ($parameters && $parameters->sync_shopify) {
                $sho = new ShopifyController();
                $brand = Brand::where('id', $request["brand_id"])->first();
                $data_sho = array("product" => array(
                    "title" => $request["name"],
                    "vendor" => $brand->name,
                    "product_type" => $subcategory,
                    "status"    => "active",
                ));
                $reference_shopify_id = $sho->createProduct($data_sho, 'COP');
            }
        } else {
            $reference_id = $request["reference_woocommerce_product_id"];
            $reference_shopify_id = $request["reference_shopify_id"];
        }

        $product = new Product();
        $product->active = $request["active"];
        $product->name = $request["name"];
        $product->plu = $request["plu"];
        $product->bar_code = $request["bar_code"];
        $product->price = $request["price"];
        $product->available_units = $request["available_units"];
        $product->max_units_per_order = $request["max_units_per_order"];
        $product->max_units_per_product = $request["max_units_per_product"];
        $product->percentage_discount = $request["percentage_discount"];
        $product->start_discount = $request["start_discount"];
        $product->limit_discount = $request["limit_discount"];
        $product->limit_hour_discount = $request["limit_hour_discount"];
        $product->flash_price = $request["flash_price"];
        $product->start_flash_discount = $request["start_flash_discount"];
        $product->limit_flash_discount = $request["limit_flash_discount"];
        $product->limit_hour_flash_discount = $request["limit_hour_flash_discount"];
        $product->brand_id = $request["brand_id"];
        $product->order = $request["order"];
        $product->validate_age = $request["chkAgeProduct"];
        $product->sucursal_id = $request["sucursal_id"];
        $product->product_link = $request["product_link"];
        $product->reference_woocommerce_product_id = $reference_id;
        $product->reference_shopify_id = $reference_shopify_id;
        $product->store_type = $request['store_type'];
        $product->save();

        if ($product) {
            foreach ($request["sub_categories"] as $id_subcategory) {
                if ($id_subcategory) {
                    $subcategoryProduct = new SubcategoryProduct();
                    $subcategoryProduct->subcategory_id = $id_subcategory;
                    $subcategoryProduct->product_id = $product->id;
                    $subcategoryProduct->save();
                }
            }
            $tags = $request["tags"];
            $controller = new ProductTagController();
            $controller->assignProductTags($product->id, $tags, $request["special_price"]);

            $productTagAssigns = $request["tags_assigns"];
            $this->productTagAssignService->assignProductTags($product->id, $productTagAssigns);
            return array('r' => true, 'd' => array('id' => $product->id, 'plu' => $request["plu"]), 'm' => trans('messages.screen_products_tag34'));
        } else {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag35'));
        }
    }

    public function indexEdit($storeType = 'main', $id)
    {
        $product = Product::with('productImages')->find($id);
        $brands = Brand::where('active', 1)->get();
        $sub_categories = Subcategories::where('active', 1)->get();
        $subcategoryProduct = SubcategoryProduct::select('subcategory_id')->where('product_id', $id)->get();
        $parameter = Parameter::select('sucursal_products')->first();
        if ($parameter->sucursal_products) {
            $sucursals = Sucursal::where('active', 1)->get();
        } else {
            $sucursals = null;
        }

        // se crea array con solo el id de la subcategoria para poder
        // hacer in_array en el select del view y dejar selected las subcategorias del producto
        $arraySubcategorySelected = array();
        foreach ($subcategoryProduct as $subcatProduct) {
            $arraySubcategorySelected[] = $subcatProduct->subcategory_id;
        }

        $tags = Tag::select('id', 'name')->where('active', true)->get();
        $productTags = ProductTag::where('product_id', $id)->get();
        $assignedTags = $productTags->pluck('tag_id')->toArray();
        if ($assignedTags && count($assignedTags)) {
            $product->special_price = $productTags[0]->special_price;
        }
        $productTagAssigns = ProductTagAssign::where('product_id', $id)->pluck('tag_id')->toArray();

        return view('products.editProduct', compact('product', 'brands', 'sub_categories', 'arraySubcategorySelected', 'sucursals', 'tags', 'assignedTags', 'productTagAssigns', 'storeType'));
    }

    public function update(Request $request)
    {
        $product = Product::find($request["id"]);
        $woo = new WoocommerceController();

        $func = function ($id_subcategory) {
            if ($id_subcategory) {
                $getSubcategory = Subcategories::where('id', $id_subcategory)->first();
                $id_category = $getSubcategory->reference_woocommerce_category_id;
                return [
                    'id' => intval($id_category),
                ];
            }
        };

        if (!$request["sub_categories"]) {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag69'));
        }

        $categories_woo = array_map($func, $request["sub_categories"]);

        $data = [
            'name'              => $request["name"],
            'price'             => $request["price"],
            'regular_price'     => $request["price"],
            'manage_stock'      => true,
            'stock_quantity'    => intval($request["available_units"]),
            'categories'        => $categories_woo,
        ];
        $woo->updateProduct($product->reference_woocommerce_product_id, $data);


        $subcategory = "";
        if ($request["sub_categories"] && count($request["sub_categories"])) {
            $subcategory = Subcategories::where('id', $request["sub_categories"][0])->first();
            if ($subcategory) {
                $subcategory = $subcategory->name;
            }
        }

        $product->name = $request["name"];
        $product->plu = $request["plu"];
        $product->bar_code = $request["bar_code"];
        $product->price = $request["price"];
        $product->available_units = $request["available_units"];
        $product->max_units_per_order = $request["max_units_per_order"];
        $product->max_units_per_product = $request["max_units_per_product"];
        if ($request["percentage_discount"]) {
            $product->percentage_discount = $request["percentage_discount"];
        }
        if ($request["start_discount"]) {
            $product->start_discount = $request["start_discount"];
        }

        if ($request["limit_discount"]) {
            $product->limit_discount = $request["limit_discount"];
        }

        if ($request["limit_hour_discount"]) {
            $product->limit_hour_discount = $request["limit_hour_discount"];
        }

        $product->flash_price = $request["flash_price"];
        $product->start_flash_discount = $request["start_flash_discount"];
        $product->limit_flash_discount = $request["limit_flash_discount"];
        $product->limit_hour_flash_discount = $request["limit_hour_flash_discount"];
        $product->brand_id = $request["brand_id"];
        $product->order = $request["order"];
        $product->validate_age = $request["chkAgeProduct"];
        $product->sucursal_id = $request["sucursal_id"];
        $product->product_link = $request["product_link"];
        $product->store_type = $request['store_type'];
        $product->update();

        if ($product) {
            SubcategoryProduct::where('product_id', $request["id"])->delete();
            foreach ($request["sub_categories"] as $id_subcategory) {
                $subcategoryProduct = new SubcategoryProduct();
                $subcategoryProduct->subcategory_id = $id_subcategory;
                $subcategoryProduct->product_id = $product->id;
                $subcategoryProduct->save();
            }
            $tags = $request["tags"];
            $controller = new ProductTagController();
            $controller->assignProductTags($product->id, $tags, $request["special_price"]);

            $productTagAssigns = $request["tags_assigns"];
            $this->productTagAssignService->assignProductTags($product->id, $productTagAssigns);
            return array('r' => true, 'd' => array('id' => $product->id, 'plu' => $request["plu"]), 'm' => trans('messages.screen_products_tag39'));
        } else {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag40'));
        }
    }

    public function saveImage(Request $request)
    {

        $id = $request->id;
        $plu = $request->plu;
        $extension = $request->file('image')->getClientOriginalExtension();
        // $imageresize = Image::make($request->file('image'))->fit(1300, 660);
        // $imageresize = Image::make($request->file('image'))->resize(1300, 660);
        $filenametostore = $plu . '.' . $extension;
        Storage::disk('s3')->put(config('s3.products') . $filenametostore, fopen($request->file('image'), 'r+'), 'public');

        $status = Product::where('id', $id)->update(['image' => $filenametostore]);

        if ($status) {
            return array('r' => true, 'd' => null, 'm' => trans('messages.screen_products_tag34'));
        } else {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag35'));
        }
    }

    public function uploadImageFromUrl($fileUrl, $fileName, $productId)
    {
        $path_info = pathinfo($fileUrl);
        $extension = explode("?", $path_info['extension'])[0];
        $filenametostore = $fileName . '.' . $extension;

        $client = new \GuzzleHttp\Client();
        $response = $client->get($fileUrl);

        $isSaved = Storage::disk('s3')->put(config('s3.products') . $filenametostore, $response->getBody(), 'public');

        if ($isSaved) {

            $data = [
                "name" => $filenametostore,
                "product_id" => $productId,
            ];
            ProductImage::updateOrCreate($data, $data);
        }
    }

    public function updateImage(Request $request)
    {
        $id = $request->id;
        $plu = $request->plu;
        $extension = $request->file('image')->getClientOriginalExtension();

        $filenametostore = $plu . '.' . $extension;
        Storage::disk('s3')->put(config('s3.products') . $filenametostore, fopen($request->file('image'), 'r+'), 'public');

        $status = Product::where('id', $id)->update(['image' => $filenametostore]);
        if ($status) {
            return array('r' => true, 'd' => null, 'm' => trans('messages.screen_products_tag39'));
        } else {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag40'));
        }
    }

    public function activateProduct(Request $request)
    {
        $id = $request['id'];
        $state = $request['state'];

        $product = Product::find($id);
        $product->active = $state;
        $product->update();

        $woo = new WoocommerceController();
        $data = [
            'catalog_visibility'    => $state ? 'visible' : 'hidden',
        ];
        $woo->updateProduct($product->reference_woocommerce_product_id, $data);

        $parameters = Parameter::select('sync_shopify', 'sucursal_products')->find(1);
        if ($parameters && $parameters->sync_shopify) {
            $sho = new ShopifyController();
            $data_sho = [
                "status"    => $state ? "active" : 'archived',
            ];
            $sho->updateProduct($product->reference_shopify_id, $data_sho, 'COP');
        }

        if ($product) {
            return array('r' => true, 'd' => null, 'm' => trans('messages.screen_products_tag27'));
        } else {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag28'));
        }
    }

    public function deleteProduct(Request $request)
    {
        $filenametostore = $request['product_name'];
        $product = Product::find($request['id']);
        $product->active = false;
        $product->delete();

        if ($product) {
            if ($product->reference_woocommerce_product_id) {
                $woo = new WoocommerceController();
                $woo->deleteProduct($product->reference_woocommerce_product_id);
            }
            if ($filenametostore) {
                Storage::disk('s3')->delete(config('s3.products') . $filenametostore);
                $image = ProductImage::where([['name', $filenametostore], ['product_id', $product->id]])->first();
                if ($image) {
                    $image->delete();
                }
            }
            $parameters = Parameter::select('sync_shopify', 'sucursal_products')->find(1);
            if ($parameters && $parameters->sync_shopify) {
                if ($product->reference_shopify_id) {
                    $sho = new ShopifyController();
                    $sho->deleteProduct($product->reference_shopify_id, 'COP');
                }
            }
            return array('r' => true, 'd' => null, 'm' => trans('messages.screen_products_tag29'));
        } else {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag30'));
        }
    }

    public function deleteProductImage(Request $request)
    {
        $productId = $request['id'];
        $filenametostore = $request['product_name'];
        try {
            if ($filenametostore) {
                $this->deleteImageWooCommerce($productId, $filenametostore);
                Storage::disk('s3')->exists(config('s3.products') . $filenametostore);
                ProductImage::where([['name', $filenametostore], ['product_id', $productId]])->delete();
            } else {
                $this->deleteImageWooCommerce($productId, $filenametostore);
                $images = ProductImage::where('product_id', $productId)->get();
                foreach ($images as $image) {
                    Storage::disk('s3')->exists(config('s3.products') . $image->name);
                    $image->delete();
                }
            }
            return array('r' => true, 'd' => $productId, 'm' => trans('messages.screen_products_tag66'));
        } catch (\Exception $e) {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag68'));
        }
    }

    public function deleteImageWooCommerce($product_id, $nameImage)
    {
        $woo = new WoocommerceController();
        $product = Product::find($product_id);
        $images = [];

        if ($product->reference_woocommerce_product_id) {
            $productImageWooCommerce = $woo->searchProductId(intval($product->reference_woocommerce_product_id));
            if (is_object($productImageWooCommerce) && isset($productImageWooCommerce->images)) {
                foreach ($productImageWooCommerce->images as $indice => $img) {
                    if ($product_id && $nameImage) {
                        if ($nameImage == $productImageWooCommerce->images[$indice]->name) {
                            unset($productImageWooCommerce->images[$indice]);
                        }
                    } else {
                        unset($productImageWooCommerce->images[$indice]);
                    }
                }

                foreach ($productImageWooCommerce->images as $imgUpdate) {
                    array_push($images, [
                        "src" => $imgUpdate->src,
                        "name" => $imgUpdate->name
                    ]);
                }
            }

            $data = ['images' => $images];
            $woo->updateProduct($product->reference_woocommerce_product_id, $data);
        }
    }

    public function tableFilter($db_database, $sucursal_id = false, $storeType = 'main')
    {
        $products = new Product();
        $products->setConnection($db_database);
        if ($sucursal_id && $sucursal_id == 'false')
            $sucursal_id = false;

        DB::statement("SET sql_mode = ''");
        $obj = $products::select(
            'products.*',
            DB::raw('GROUP_CONCAT(DISTINCT(brands.name)) AS nameBrands'),
            DB::raw('GROUP_CONCAT(DISTINCT(subcategories.name)) AS nameCategories'),
            DB::raw('GROUP_CONCAT(DISTINCT(tags.name)) AS nameTags'),
            DB::raw('MAX(product_tags.special_price) AS special_price'),
        )->with('productImages')
            ->leftJoin('brands', 'brands.id', '=', 'products.brand_id')
            ->leftJoin('subcategory_products', 'subcategory_products.product_id', '=', 'products.id')
            ->leftJoin('subcategories', 'subcategories.id', '=', 'subcategory_products.subcategory_id')
            ->leftJoin('product_tags', 'product_tags.product_id', '=', 'products.id')
            ->leftjoin('tags', function ($join) {
                $join->on('tags.id', '=', 'product_tags.tag_id')->where('tags.active', 1);
            })
            ->where(function ($query) use ($sucursal_id) {
                if ($sucursal_id) {
                    $query->where('products.sucursal_id', $sucursal_id);
                }
            })
            ->where('products.store_type', $storeType)
            ->whereNull('products.deleted_at')
            ->groupBy('products.id');
        DB::statement("SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");
        return Datatables::of($obj)
            ->addColumn('image', function ($obj) {
                $totalImages = count($obj->productImages);
                if ($totalImages) {
                    if ($totalImages == 1) {
                        return $this->util->generateImageColumn(config('filesystems.disks.s3.url') . '/products/' . $obj->productImages[0]->name, $obj->name, 'product' . $obj->productImages[0]->id);
                    }
                    $images = array();
                    foreach ($obj->productImages as $item) {
                        $images[] = $item->name;
                    }
                    $prefix = config('filesystems.disks.s3.url') . '/products/';
                    $name = $obj->name;
                    $id = $obj->id;
                    return $this->util->generateCarouselImagesProducts($images, $prefix, $name, $id);
                } else {
                    return $this->util->generateEmptyImageColumn();
                }
            })
            ->addColumn('actions', function ($obj) {
                $actions = '<i class="fa fa-tags iconMini" onClick="clickAttributes(' . $obj->id . ')" data-id="' . $obj->id . '" title="Atributos"></i>
                            <i class="fa fa-pencil iconMini" onClick="clickEditProduct(' . $obj->id . ')" data-id="' . $obj->id . '" title="Editar"></i>
                            <i class="fa fa-trash iconMini" onClick="clickDeleteProduct(' . $obj->id . ', \'' . (count($obj->productImages) ? $obj->productImages[0]->name : '') . '\')" data-id="' . $obj->id . '" title="Eliminar producto"></i>';
                if (count($obj->productImages)) {
                    $actions .= '<i class="fa fa-trash-o iconMini" onClick="clickDeleteProductImage(' . $obj->id . ', \'' . '\')" data-id="' . $obj->id . '" title="Eliminar imagenes producto"></i>';
                }
                $actions .= '<i class="fa fa-search iconMini" id="scraper' . $obj->id . '" data-text="' . $obj->name . '" onClick="clickScraper(' . $obj->id . ')" data-id="' . $obj->id . '" title="Comparar"></i>';
                return $actions;
            })
            ->editColumn('active', function ($obj) {
                if ($obj->active == 0) {
                    return '<div class="switch"><label><div class="checkbox checbox-switch switch-success"> <label> No <input type="checkbox" onChange="chkProduct(' . $obj->id . ')" data-id="' . $obj->id . '" id="Checkactive' . $obj->id . '" name="Checkactivo" /> <span></span>Si </label></div> </label> </div>';
                } else {
                    return '<div class="switch"><label> <div class="checkbox checbox-switch switch-success"> <label>   No <input type="checkbox" onChange="chkProduct(' . $obj->id . ')" data-id="' . $obj->id . '" id="Checkactive' . $obj->id . '" name="Checkactivo" checked="" />
                        <span></span> Si </label> </div>  </label> </div>';
                }
            })
            ->editColumn('created_at', function ($obj) {
                return \Carbon\Carbon::parse($obj->created_at)->format('Y-m-d h:i:s A');
            })
            ->editColumn('limit_hour_discount', function ($obj) {
                return \Carbon\Carbon::parse($obj->limit_hour_discount)->format('h:i A');
            })
            ->editColumn('limit_hour_flash_discount', function ($obj) {
                return \Carbon\Carbon::parse($obj->limit_hour_flash_discount)->format('h:i A');
            })
            ->rawColumns(['active', 'actions', 'image'])
            ->make(true);
    }

    public function getBrandId($name)
    {
        if ($brand = Brand::select('id')->where('name', '=', trim(ucfirst($name)))->first()) {
            return $brand->id;
        } elseif ($name != '') {
            $brand = Brand::create([
                'name' => trim(ucfirst($name)),
                'active' => 1,
            ]);
            return $brand->id;
        }
    }

    public function getSucursalId($name)
    {
        if ($sucursal = Sucursal::select('id')->where('name', '=', trim($name))->first()) {
            return $sucursal->id;
        } elseif ($name != '') {
            $sucursal = Sucursal::create([
                'code' => trim($name),
                'name' => trim($name),
                'mail' => trim($name),
                'phone' => trim($name),
                'active' => 1,
                'address_id' => 1,
                'city_id' => 1,
                'coverage_id' => 1,
            ]);
            return $sucursal->id;
        }
    }

    public function getSizingUnitsId($name)
    {
        if ($sizing = SizingUnit::select('id')->where('name', '=', trim(ucfirst($name)))->first()) {
            return $sizing->id;
        } elseif ($name != '') {
            $sizing = SizingUnit::create([
                'name' => trim(ucfirst($name)),
            ]);
            return $sizing->id;
        }
    }

    public function getProductId($plu, $sucursal_id = false)
    {
        if ($sucursal_id) {
            $product = Product::select('id')->where([['plu', '=', trim($plu)], ['sucursal_id', $sucursal_id]])->first();
        } else {
            $product = Product::select('id')->where('plu', '=', trim($plu))->first();
        }
        if ($product) {
            return $product->id;
        } else {
            return false;
        }
    }

    public function getSubCategoryId_rowCategory($name, $sucursal_id = false)
    {
        if ($sucursal_id) {
            $category = Category::select('id')->where([['name', '=', trim(ucfirst($name))], ['sucursal_id', $sucursal_id]])->first();
        } else {
            $category = Category::select('id')->where('name', '=', trim(ucfirst($name)))->first();
            $sucursal_id = null;
        }

        // valida si existe la categoria si no la crea
        if (isset($category->id)) {
            $subCategory = Subcategories::select('id')->where('category_id', '=', $category->id)->first();
            if ($subCategory) {
                $subCategory->active = true;
                $subCategory->update();
            } else {
                $subCategory = Subcategories::create([
                    'name' => trim(ucfirst($name)),
                    'active' => 1,
                    'order' => 1,
                    'category_id' => $category->id,
                ]);
            }
            $category->active = true;
            $category->update();
            return $subCategory->id;
        } elseif ($name != '') {
            $category = Category::create([
                'name' => trim(ucfirst($name)),
                'active' => 1,
                'order' => 100,
                'sucursal_id' => $sucursal_id,
            ]);
            if ($category) {
                $subCategory = Subcategories::create([
                    'name' => trim(ucfirst($name)),
                    'active' => 1,
                    'order' => 1,
                    'category_id' => $category->id,
                ]);
            }
            return $subCategory->id;
        }
    }

    public function getSubCategoryId_rowSubcategory($cat, $subCat, $sucursal_id = false)
    {
        if ($sucursal_id) {
            $category = Category::select('id')->where([['name', '=', trim(ucfirst($cat))], ['sucursal_id', $sucursal_id]])->first();
        } else {
            $category = Category::select('id')->where('name', '=', trim(ucfirst($cat)))->first();
            $sucursal_id = null;
        }
        if ($subCategory = Subcategories::select('id')
            ->where([['name', '=', trim(ucfirst($subCat))], ['category_id', '=', $category->id]])
            ->first()
        ) {
            $category->active = true;
            $category->update();
            $subCategory->active = true;
            $subCategory->update();
            return $subCategory->id;
        } elseif ($cat != '' && $subCat != '') {
            if ($category) {
                $subCategory = Subcategories::create([
                    'name' => trim(ucfirst($subCat)),
                    'active' => 1,
                    'order' => 2,
                    'category_id' => $category->id,
                ]);
            } else {
                $category = Category::create([
                    'name' => trim(ucfirst($cat)),
                    'active' => 1,
                    'order' => 100,
                    'sucursal_id' => $sucursal_id,
                ]);
                if ($category) {
                    $subCategory = Subcategories::create([
                        'name' => trim(ucfirst($subCat)),
                        'active' => 1,
                        'order' => 2,
                        'category_id' => $category->id,
                    ]);
                }
            }
            return $subCategory->id;
        }
    }

    public function export()
    {
        return Excel::download(new ReportProducts, trans('messages.screen_products_tag1') . '.xlsx');
    }

    public function exportCategories()
    {
        return Excel::download(new ReportCategories, trans('messages.screen_products_tag47') . '.xlsx');
    }

    public function import(Request $request)
    {
        try {
            $file = new ProductsImport;
            $file->request = $request;
            Excel::import($file, $request->importProducts);
            return array('r' => true, 'd' => null, 'm' => trans('messages.screen_products_tag45') . ' ' . $file->edit['creados'] . ' creados, ' . $file->edit['editados'] . ' editados, ' . $file->edit['inactivados'] . ' inactivados.');
        } catch (\Exception $e) {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag46') . $e->getMessage());
        }
    }

    //  importa las categorias y subcategorias de los productos
    public function importCategoriesAndSubcategories(Request $request)
    {
        try {
            $file = new CategoriesImport;
            $file->request = $request;
            Excel::import($file, $request->importCategories);
            return array('r' => true, 'd' => null, 'm' => trans('messages.screen_products_tag45') . ' ' . $file->edit['creados'] . ' creados ');
        } catch (\Exception $e) {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag46') . $e->getMessage());
        }
    }

    public function importExternal(Request $request)
    {
        try {
            $this->edit = [
                'creados' => 0,
                'editados' => 0,
            ];

            $this->historySucursal = [];

            DB::table('subcategory_products')->truncate();
            DB::table('subcategory_products')->delete();

            $reader = ReaderFactory::create(Type::XLSX); // for XLSX files
            $reader->open($request->importProductsExternal);
            $cnt = 0;
            foreach ($reader->getSheetIterator() as $sheet) {
                foreach ($sheet->getRowIterator() as $row) {
                    if ($cnt > 6) {
                        // se valida si esta activa la logica sucursal por productos y se busca en el array si ya se consulto el id de la sucursal para no volver a consultar la bd
                        if ($row[2] != "" && $row[3] != "") {
                            if ($request->sucursal_id) {
                                if (array_key_exists($row[2], $this->historySucursal)) {
                                    $sucursal_id = trim($this->historySucursal[$row[2]]);
                                    $current_product = Product::where([['plu', $row[3]], ['sucursal_id', $sucursal_id]])->first();
                                } else {
                                    $id = $this->getSucursalId($row[2]);
                                    $this->historySucursal[$row[2]] = $id;
                                    $sucursal_id = $id;
                                    $current_product = Product::where([['plu', $row[3]], ['sucursal_id', $sucursal_id]])->first();
                                }
                            } else {
                                $sucursal_id = null;
                                $current_product = Product::where('plu', $row[3])->first();
                            }
                        } else {
                            $sucursal_id = null;
                            $current_product = null;
                        }

                        if ($current_product) { // Existe, Actualizar
                            $current_product->active = true;
                            $current_product->name = trim($row[4]);
                            $current_product->plu = trim($row[3]);
                            $current_product->price = floatval($row[6]);
                            $current_product->sucursal_id = $sucursal_id;
                            $current_product->update();
                            $this->createRelationship($row[9], $current_product->id, $sucursal_id);
                            $this->edit['editados'] += 1;
                        } else {
                            if ($row[3] != null || $row[3] != "") {
                                $new_product = Product::create([
                                    'active' => 1,
                                    'name' => trim($row[4]),
                                    'plu' => trim($row[3]),
                                    'price' => intval($row[6]),
                                    'order' => 1,
                                    'image' => trim($row[3]) . ".jpg",
                                    'sucursal_id' => $sucursal_id,
                                ]);
                                $new_product->save();
                                $this->createRelationship($row[9], $new_product->id, $sucursal_id);
                                $this->edit['creados'] += 1;
                            }
                        }
                    }
                    $cnt++;
                }
            }

            $reader->close();
            return array('r' => true, 'd' => null, 'm' => trans('messages.screen_products_tag45') . $this->edit['creados'] . ' creados, ' . $this->edit['editados'] . ' editados. ');
        } catch (\Exception $e) {
            return array('r' => false, 'd' => null, 'm' => trans('messages.screen_products_tag46') . $e->getMessage());
        }
    }

    // funcion para crear la categoria, subcategoria y la relacion con los productos cuando se importa con una plantilla externa
    public function createRelationship($category_name, $product_id, $sucursal_id)
    {
        $this->historySubCategory = [];
        $this->historySubCategoryProduct = [];

        //verificar si la categoria existe y retorna el id de la subcategoria correspondiente, validando logica de sucursal_productos
        if ($category_name != '' && $sucursal_id) {
            //valida en el array si ya se consulto la categoria en la bd y se guarda con el index: categoria mas el id de la sucursal ya que pueden haber categorias con el mismo nombre pero diferente sucursal
            if (array_key_exists($category_name . '_' . $sucursal_id, $this->historySubCategory)) {
                $subcategory_id = trim($this->historySubCategory[$category_name . '_' . $sucursal_id]);
            } else {
                $subcategory_id = $this->getSubCategoryId_rowCategory($category_name, $sucursal_id);
                $this->historySubCategory[$category_name . '_' . $sucursal_id] = $subcategory_id;
            }
        } else if ($category_name != '') {
            //valida en el array si ya se consulto la categoria en la bd
            if (array_key_exists($category_name, $this->historySubCategory)) {
                $subcategory_id = trim($this->historySubCategory[$category_name]);
            } else {
                $subcategory_id = $this->getSubCategoryId_rowCategory($category_name);
                $this->historySubCategory[$category_name] = $subcategory_id;
            }
        } else {
            return false;
        }

        if (isset($subcategory_id) && !array_key_exists($subcategory_id . $product_id, $this->historySubCategoryProduct)) {
            SubcategoryProduct::create([
                'subcategory_id' => $subcategory_id,
                'product_id' => $product_id,
            ]);
            $this->historySubCategoryProduct[$subcategory_id . $product_id] = true;
            return true;
        } else {
            return false;
        }
    }

    // metodo para filtrar el producto por el nombre o plu desde el pedido e-commerce
    public function autocomplete(Request $request)
    {
        $term = $request->input('term');
        $results = array();
        $parameters = Parameter::first();

        $user_sucursal_id = UserInformation::where('user_id', Auth::user()->id)->first();

        // realiza la busqueda en la bd
        // $queries = DB::table('products')
        //     ->where('name', 'LIKE', '%' . $term . '%')
        //     ->orWhere('plu', 'LIKE', '%' . $term . '%')
        //     ->take(5)->get();

        $queries = Product::with('subcategory_products', 'productImages')
            ->where('active', 1)
            ->where('name', 'like', '%' . $term . '%')
            ->orWhere('plu', 'like', '%' . $term . '%')
            ->has('subcategory_products')
            ->take(5);

        if ($parameters->sucursal_products) {
            $queries = $queries->where('sucursal_id', $user_sucursal_id->sucursal_id)->get();
        } else {
            $queries = $queries->get();
        }

        // se recorre el array para obtener los datos necesarios y mandarlos al js
        foreach ($queries as $query) {
            $query->product_attributes = ProductAttribute::where('product_id', $query->id)->with('attribute')->get()->groupBy('attribute_id')->toArray();
            $results[] = [
                'id' => $query->id,
                'plu' => $query->plu,
                'value' => $query->name . ' - ' . $query->plu . ' - $' . $query->price,
                'price' => $query->price,
                'max_units_per_order' => $query->max_units_per_order,
                'flash_price' => $query->flash_price,
                'percentage_discount' => $query->percentage_discount,
                'limit_discount' => $query->limit_discount,
                'limit_flash_discount' => $query->limit_flash_discount,
                'limit_hour_discount' => $query->limit_hour_discount,
                'start_discount' => $query->start_discount,
                'start_flash_discount' => $query->start_flash_discount,
                'limit_hour_flash_discount' => $query->limit_hour_flash_discount,
                'product_attributes' => $query->product_attributes,
                'data' => json_encode($query),
            ];
        }
        return json_encode($results);
    }

    function human_filesize($bytes, $decimals = 0)
    {
        $sz = 'BKMGTP';
        $factor = floor((strlen($bytes) - 1) / 3);
        return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor));
    }

    public function uploadMassivePhoto(Request $request)
    {
        if ($this->human_filesize(filesize($request->file('file'))) < 2000) {
            $filenametostore = $request->file('file')->getClientOriginalName();
            $extension = $request->file('file')->getClientOriginalExtension();
            $listName = explode(".", $filenametostore);
            $isMoreOne = explode("_", $listName[0]);
            $current_plu = "";
            if (count($isMoreOne) > 1) {
                $product = Product::select('id', 'reference_woocommerce_product_id', 'reference_shopify_id')->where('plu', $isMoreOne[0])->first();
                $current_plu = $isMoreOne[0];
            } else {
                $product = Product::select('id', 'reference_woocommerce_product_id', 'reference_shopify_id')->where('plu', $listName[0])->first();
                $current_plu = $listName[0];
            }
            if ($product) {
                $image = ProductImage::where([['name', $filenametostore], ['product_id', $product->id]])->first();
                if (!$image) {
                    ProductImage::updateOrCreate([
                        "name"          => $filenametostore,
                        "product_id"    => $product->id,
                    ]);
                }

                if ($extension == "jpg" || $extension == "png" || $extension == "mp4") {
                    Storage::disk('s3')->put(config('s3.products') . $filenametostore, fopen($request->file('file'), 'r+'), 'public');
                    $woo = new WoocommerceController();
                    $productImageWooCommerce = $woo->searchProductId(intval($product->reference_woocommerce_product_id));

                    $images = array();
                    if ($productImageWooCommerce) {
                        if ($productImageWooCommerce->images) {
                            foreach ($productImageWooCommerce->images as $img) {
                                array_push($images, array("src" => $img->src, "name" => $img->name));
                            }
                        }
                    }
                    array_push($images, array("src" => config('filesystems.disks.s3.url') . '/products/' . $filenametostore, "name" => $filenametostore));

                    $data = [
                        'images' => $images
                    ];

                    $woo->updateProduct($product->reference_woocommerce_product_id, $data);

                    $parameters = Parameter::select('sync_shopify', 'sucursal_products')->find(1);
                    if ($parameters && $parameters->sync_shopify) {
                        $sho = new ShopifyController();
                        $data_sho = [
                            'src' => config('filesystems.disks.s3.url') . '/products/' . $filenametostore
                        ];
                        $sho->addImageProduct($product->reference_shopify_id, $data_sho, 'COP');
                    }
                    return array('r' => 200);
                }
            } else {
                return response('El plu: ' . $current_plu . ' no existe')->setStatusCode(500);
            }
        } else {
            return response('TamaƱo del archivo superior a 2MB')->setStatusCode(500);
        }
        return response('Error')->setStatusCode(500);
    }

    public function getProductFlashPrice($productId, $returnNull = false)
    {
        $product = Product::select('flash_price', 'start_flash_discount', 'limit_flash_discount', 'limit_hour_flash_discount')->where('id', $productId)->first();

        if ($product->flash_price && $product->start_flash_discount && $product->limit_flash_discount && $product->limit_hour_flash_discount) {
            $start_flash_discount = $product->start_flash_discount;
            $limit_flash_discount = $product->limit_flash_discount;
            $limit_hour_flash_discount = $product->limit_hour_flash_discount;

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

            if (($current_date >= $discount_start_date) && ($current_date <= $discount_end_date))
                return $product->flash_price;
        }
        return ($returnNull ? null : 0);
    }

    public function getProductDiscountPrice($productId, $returnNull = false)
    {
        $product = Product::select('price', 'percentage_discount', 'start_discount', 'limit_discount', 'limit_hour_discount')->where('id', $productId)->first();

        if ($product->price && $product->start_discount && $product->limit_discount && $product->limit_hour_discount) {
            $start_discount = $product->start_discount;
            $limit_discount = $product->limit_discount;
            $limit_hour_discount = $product->limit_hour_discount;

            $current_date = date('Y-m-d H:i:s');                                                    // Fecha actual
            $discount_start_date = date($start_discount . ' 00:00:00');                             // Inicio del descuento
            $discount_end_date = date($limit_discount . ' ' . $limit_hour_discount);                // Fin del descuento

            if (($current_date >= $discount_start_date) && ($current_date <= $discount_end_date))
                return $product->price * (1 - ($product->percentage_discount / 100));
        }
        return ($returnNull ? null : 0);
    }

    public function activateProductWithImage($productId)
    {
        $activate_product = ProductImage::where('product_id', $productId)->get();
        if (count($activate_product) == 1) {
            $product = Product::find($productId);
            $product->active = true;
            $product->update();
        }
    }

    public function saveProductFromSiesa($item, $storeType = 'main')
    {
        $brandController = new BrandsController();
        $categoryController = new CategoryController();
        $parametersController = new ParameterController;
        $attribute_controller = new AttributeController();
        $productAttribute_controller = new ProductAttributeController();

        $default_sucursal_id = 2;
        if (Auth::user()) {
            $default_sucursal_id = Auth::user()->userInfo->sucursal_id;
        }

        $sucursal_products = $parametersController->getParameter('sucursal_products')->sucursal_products;
        $sucursal_id = $sucursal_products ? $default_sucursal_id : null;
        $brand_id = null;

        $c_brand = $brandController->create(new Request(['name' => $item->Marca, 'store_type' => $storeType]));
        if ($c_brand) {
            $brand_id = $c_brand["d"]["id"];
        }

        $subcategory_id = null;
        $data_category = [
            'name'        => $item->Linea,
            'sucursal_id' => $sucursal_id,
            'priority'    => 1,
            'store_type' => $storeType
        ];

        $c_category = $categoryController->create(new Request($data_category), false);
        $subcategory_id = $c_category["s"];

        $data_product = [
            'name' => $item->Descripcion,
            'plu' => $item->Referencia,
            'bar_code' => $item->Referencia,
            'price' => $item->Precio,
            'available_units' => $item->productAmount,
            'max_units_per_order' => 100,
            'percentage_discount' => null,
            'start_discount' => null,
            'limit_discount' => null,
            'limit_hour_discount' => null,
            'flash_price' => null,
            'start_flash_discount' => null,
            'limit_flash_discount' => null,
            'limit_hour_flash_discount' => null,
            'brand_id' => $brand_id,
            'order' => 1,
            'chkAgeProduct' => false,
            'sucursal_id' => $sucursal_id,
            'sub_categories' => [$subcategory_id],
            'reference_shopify_id' => null,
            'store_type' => $storeType,
            'active' => false
        ];

        $current_product = Product::where('bar_code', $item->Referencia)->first();

        if ($current_product) {
            $product_id = $current_product->id;
            $data_product['id'] = $product_id;
            $data_product['store_type'] = $storeType;
            $data_product['price'] = $item->Precio;
            $data_product['available_units'] = $item->productAmount;
            $cproduct = $this->update(new Request($data_product));
        } else {
            $cproduct = $this->create(new Request($data_product), false);
            $product_id = $cproduct['d']['id'];
        }


        $data_attribute = [
            "name" => 'Color / Talla',
            "display_name" => 'Color / Talla',
            "is_more_one" => false,
            "required" => true,
            "attribute_type_id" => 2,
            "active" => true,
        ];

        $catrribute = $attribute_controller->store(new Request($data_attribute), false);
        if ($catrribute) {
            $data_productAttribute = [
                "product_id" => $product_id,
                "attribute_id" => $catrribute["d"],
                "value" => $item->Color . ' / ' . $item->Talla,
                "price_additional" => 0,
                "sku" => $item->CodigoDeBarras,
                "available_units" => $item->Existencias,
                "pmi" => 0,
                "packaging" => 0,
                "weight" => 0,
                "ean" => 0,
                "width" => 0,
                "length" => 0,
                "high" => 0,
                "observation" => 0,
                "main_position" => 0,
                "stowage_pattern" => 0,
                "reference_shopify_variation_id" => '',
                "reference_shopify_id" => '',
            ];

            $productAttribute_controller->store(new Request($data_productAttribute), $product_id, false);
        }
    }
}