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/OrderController.php
<?php

namespace App\Http\Controllers;

use \Excel;
use App\Erp;
use App\City;
use App\User;
use DateTime;
use App\Order;
use Exception;
use App\ErpLog;
use Datatables;
use App\Address;
use App\Comment;
use App\Product;
use App\Coverage;
use App\Discount;
use App\Evidence;
use App\Sucursal;
use App\Transfer;
use App\OrderType;
use App\Parameter;
use Carbon\Carbon;
use App\OrderState;
use App\AcademyUser;
use App\AverageTime;
use App\PaymentType;
use App\AverageMonth;
use App\ErpParameter;
use App\LineBusiness;
use App\OrderProduct;
use App\SalesChannel;
use App\Subcategories;
use App\PaymentsHistory;
use App\UserInformation;
use App\ProductAttribute;
use App\CorporateIdentity;
use App\DiscountOrderUser;
use App\Mail\TransferMail;
use App\DiscountProductUser;
use App\Services\ErpService;
use Illuminate\Http\Request;
use App\Events\NewOrderEvent;
use App\Events\NewOrderCreate;
use App\Events\OrderStateEvent;
use App\OrderProductAttributes;
use App\Events\ChangeStateEvent;
use App\Events\OrderPendingEvent;
use Illuminate\Support\Facades\DB;
use App\Events\NewOrderCreateClient;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Cache;
use App\Events\OrderReassignmentEvent;
use App\Repositories\ERPLogRepository;
use App\Http\Controllers\UtilController;
use App\Http\Controllers\AddressController;
use App\Http\Controllers\ShopifyController;
use App\Core\Order\Application\OrderService;
use App\Http\Controllers\Exports\ReportOrders;
use App\Http\Controllers\PushNotificationController;
use App\Http\Controllers\IntegrationProvidersController;

class OrderController extends Controller implements ERPLogRepository
{
    private $ERPPrefix = 'AS';
    private $orderService;
    private $notificationsController;

    public function __construct()
    {
        $this->orderService = new OrderService();
        $this->notificationsController = new NotificationsController;
    }

    public function indexAdd($order_id = null)
    {
        $order = null;
        if ($order_id) {
            $order = Order::where('id', $order_id)->with('address.city')->with('sucursal', 'deliveryMan', 'client', 'orderProducts', 'paymentType')->first();
        }
        $order_types = OrderType::where('active', 1)->get();
        $parameter = Parameter::first();
        return view('orders.addOrder')
            ->with('types', $order_types)
            ->with('parameter', $parameter)
            ->with('order_id', $order_id)
            ->with('order', $order);
    }

    public function indexAdmin($storeType = 'main')
    {
        $from = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - 7, date("Y")));
        $to = new DateTime();

        $parameter = Parameter::first();

        $orders = Order::orderBy('creation_date', 'DESC')->whereBetween('creation_date', [$from . " 00:00:00", $to])->get();
        $from = date("d/m/Y", mktime(0, 0, 0, date("m"), date("d") - 7, date("Y")));
        $to = $to->format('d/m/Y');

        $order_state = OrderState::all();
        return view('orders.orders')
            ->with('orders', $orders)
            ->with('order_state', $order_state)
            ->with('from', $from)
            ->with('to', $to)
            ->with('selectEstado', 'todos')
            ->with('parameter', $parameter)
            ->with('storeType', $storeType);
    }

    public function indexTransfer($id)
    {
        $order = Order::find($id);

        $transfers = Transfer::where('order_id', $id)->get();
        $sucursals = Sucursal::where('active', 1)->get();
        return view('orders.transfer_order')
            ->with('order', $order)
            ->with('transfers', $transfers)
            ->with('sucursals', $sucursals);
    }

    public function indexEvidence($id)
    {
        $order = Order::find($id);
        $parameter = Parameter::first();
        $evidences = Evidence::where('order_id', $id)->get();

        return view('orders.evidence')->with('evidences', $evidences)->with('order', $order)->with('parameter', $parameter);
    }

    public function tableFilter($storeType = 'main')
    {
        $obj = $obj = DB::table('orders')
            ->join('users', 'users.id', '=', 'orders.client_id')
            ->join('order_states', 'order_states.id', '=', 'orders.order_state_id')
            ->leftJoin('addresses', 'addresses.id', '=', 'orders.address_id')
            ->leftJoin('point_sales', 'point_sales.id', '=', 'orders.point_sale_id')
            ->leftJoin('cities', 'cities.id', '=', 'addresses.city_id')
            ->leftJoin('sucursals', 'sucursals.id', '=', 'orders.sucursal_id')
            ->leftJoin('users as m', 'm.id', '=', 'orders.delivery_man_id')
            ->leftJoin('comments', 'comments.order_id', '=', 'orders.id')
            ->select(
                'orders.id',
                'orders.code',
                'orders.is_change',
                'orders.order_reference',
                'orders.creation_date',
                'cities.name as city',
                'users.first_name as nameClient',
                'users.last_name as lastNClient',
                'users.document as documentClient',
                'users.email as emailClient',
                'm.first_name as nameDeliveryM',
                'm.last_name as lastNDeliveryM',
                'order_states.name as nameState',
                'order_states.id as idState',
                'sucursals.name as sucursal',
                'comments.admin_id as admin',
                'orders.gw_state',
                'orders.payment_type_id',
                'orders.gw_code_transaction',
                DB::raw('MD5(orders.gw_code_transaction) AS hashed_reference'),
                'orders.payment_transaction_id',
                'orders.purchase_origin',
                'orders.sync_with_erp'
            )
            ->where('orders.store_type', $storeType)
            ->whereNull('orders.deleted_at');

        return Datatables::of($obj)
            ->addColumn('actions', function ($obj) {
                if ($obj->idState == 5 || $obj->idState == 6) {
                    if ($obj->admin != null) {
                        return '<i class="fa fa-eye iconMini" onClick="clickInfoOrder(' . $obj->id . ')" name="btnEditar" data-id="' . $obj->id . '"  title="Información"></i>
                                <i class="fa fa-pencil iconMini" onClick="clickEditOrder(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Modificar"></i>
                                <i class="fa fa-file-picture-o iconMini" onClick="clickEvidence(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Evidencias"></i>
                                <i class="fa fa-copy iconMini" onClick="clickCopyOrder(' . $obj->id . ')" name="btnCopy" data-id="' . $obj->id . '"  title="Copiar"></i>
                                <i class="fa fa-print iconMini" onClick="clickCommand(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Imprimir"></i>
                                <i class="fa fa-star iconMini starGold" data-id="' . $obj->id . '" onclick="viewQualification(' . $obj->id . ')"  title="Calificación"></i>
                                <i class="fa fa-trash iconMini" onClick="clickDeleteOrder(' . $obj->id . ')" name="btnTrash" data-id="' . $obj->id . '"  title="Eliminar"></i>
                    ';
                    } else {
                        return '<i class="fa fa-eye iconMini" onClick="clickInfoOrder(' . $obj->id . ')" name="btnEditar" data-id="' . $obj->id . '"  title="Información"></i>
                                <i class="fa fa-pencil iconMini" onClick="clickEditOrder(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Modificar"></i>
                                <i class="fa fa-file-picture-o iconMini" onClick="clickEvidence(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Evidencias"></i>
                                <i class="fa fa-copy iconMini" onClick="clickCopyOrder(' . $obj->id . ')" name="btnCopy" data-id="' . $obj->id . '"  title="Copiar"></i>
                                <i class="fa fa-print iconMini" onClick="clickCommand(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Imprimir"></i>
                                <i class="fa fa-star  iconMini starGrey" data-id="' . $obj->id . '" onclick="doQualification(' . $obj->id . ')"  title="Calificación"></i>
                                <i class="fa fa-trash iconMini" onClick="clickDeleteOrder(' . $obj->id . ')" name="btnTrash" data-id="' . $obj->id . '"  title="Eliminar"></i>
                    ';
                    }
                } else {
                    return '<i class="fa fa-eye iconMini" onClick="clickInfoOrder(' . $obj->id . ')" name="btnEditar" data-id="' . $obj->id . '"  title="Información"></i>
                            <i class="fa fa-pencil iconMini" onClick="clickEditOrder(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Modificar"></i>
                            <i class="fa fa-file-picture-o iconMini" onClick="clickEvidence(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Evidencias"></i>
                            <i class="fa fa-copy iconMini" onClick="clickCopyOrder(' . $obj->id . ')" name="btnCopy" data-id="' . $obj->id . '"  title="Copiar"></i>
                            <i class="fa fa-trash iconMini" onClick="clickDeleteOrder(' . $obj->id . ')" name="btnTrash" data-id="' . $obj->id . '"  title="Eliminar"></i>
                    ';
                }
            })
            ->editColumn('gw_state', function ($obj) {
                if ($obj->payment_type_id == 5) {
                    return '<span class="label ' . ($obj->gw_state == 'CONFIRMED' ? 'label-success' : 'label-danger') . '">' . $obj->gw_state . '</span>';
                } else {
                    return "N/A";
                }
            })
            ->editColumn('nameClient', function ($obj) {
                if ($obj->lastNClient != null) {
                    return $obj->nameClient . " " . $obj->lastNClient;
                } else {
                    return $obj->nameClient;
                }
            })
            ->editColumn('nameDeliveryM', function ($obj) {
                if ($obj->nameDeliveryM != null) {
                    return $obj->nameDeliveryM . " " . $obj->lastNDeliveryM;
                } else {
                    return "N/A";
                }
            })
            ->editColumn('creation_date', function ($obj) {
                return \Carbon\Carbon::parse($obj->creation_date)->format('Y-m-d h:i:s A');
            })
            ->editColumn('sync_with_erp', function ($obj) {
                return $obj->sync_with_erp == 1 ? 'SI' : 'NO';
            })
            ->rawColumns(['actions', 'gw_state'])
            ->filterColumn('hashed_reference', function ($query, $keyword) {
                $query->whereRaw('MD5(orders.gw_code_transaction) LIKE ?', ['%' . $keyword . '%']);
            })
            ->make(true);
    }

    public function getForm(Request $request)
    {

        $type = OrderType::find($request["id"]);
        $parameter = Parameter::first();
        $sucursals = Sucursal::where('active', 1)->get();
        $deliveryMan = User::where('online', 1)->where('active', 1)->where('rol_id', 3)->get();
        $payment_types = PaymentType::where('active', 1)->get();
        $line_businesses = LineBusiness::where('active', 1)->get();
        $sales_channels = SalesChannel::where('active', 1)->get();
        $cities = City::where('active', 1)->orderBy('name', 'ASC')->get();

        switch ($request["id"]) {
            case 1:
                $code = "V-" . $this->getCode();

                return view('orders.sales.sales')->with('type', $type)
                    ->with('parameter', $parameter)
                    ->with('sucursals', $sucursals)
                    ->with('deliveryMan', $deliveryMan)
                    ->with('payment_types', $payment_types)
                    ->with('line_businesses', $line_businesses)
                    ->with('sales_channels', $sales_channels)
                    ->with('code', $code)
                    ->with('cities', $cities);

                break;
            case 2:
                $code = "C-" . $this->getCode();
                return view('orders.alliance.alliance')->with('type', $type)
                    ->with('parameter', $parameter)
                    ->with('sucursals', $sucursals)
                    ->with('deliveryMan', $deliveryMan)
                    ->with('payment_types', $payment_types)
                    ->with('line_businesses', $line_businesses)
                    ->with('sales_channels', $sales_channels)
                    ->with('code', $code);

                break;
            case 3:
                $code = "T-" . $this->getCode();
                return view('orders.transfer.transfer')->with('type', $type)
                    ->with('parameter', $parameter)
                    ->with('sucursals', $sucursals)
                    ->with('deliveryMan', $deliveryMan)
                    ->with('payment_types', $payment_types)
                    ->with('line_businesses', $line_businesses)
                    ->with('sales_channels', $sales_channels)
                    ->with('code', $code);
                break;
            case 4:
                $code = "D-" . $this->getCode();
                return view('orders.diligence.diligence')->with('type', $type)
                    ->with('parameter', $parameter)
                    ->with('sucursals', $sucursals)
                    ->with('deliveryMan', $deliveryMan)
                    ->with('payment_types', $payment_types)
                    ->with('line_businesses', $line_businesses)
                    ->with('sales_channels', $sales_channels)
                    ->with('code', $code);
                break;

            case 5:
                $code = "E-" . $this->getCode();
                $coverages = Coverage::where('active', 1)->orderBy('name', 'asc')->get();

                return view('orders.e_commerce.e_commerce')->with('type', $type)
                    ->with('parameter', $parameter)
                    ->with('sucursals', $sucursals)
                    ->with('deliveryMan', $deliveryMan)
                    ->with('payment_types', $payment_types)
                    ->with('line_businesses', $line_businesses)
                    ->with('sales_channels', $sales_channels)
                    ->with('code', $code)
                    ->with('cities', $cities)
                    ->with('coverages', $coverages);
                break;

            default:

                break;
        }
    }

    public function getCode()
    {
        return strtoupper(dechex(time()) . "-" . rand(1, 9) . rand(1, 5));
    }

    public function create(Request $request, $validateQuantity = true)
    {
        $type = $request->data;
        $response;
        switch ($type["order_type_id"]) {
            case 1:
                $response = $this->createOrderSale($request);
                break;
            case 2:
                $response = $this->createOrderAlliance($request);
                break;
            case 3:
                $response = $this->createOrderTransfer($request);
                break;
            case 4:
                $response = $this->createOrderDiligence($request);
                break;
            case 5:
            case 6:
                $response = $this->createOrderEcommerce($request, $validateQuantity);
                break;
        }
        return $response;
    }

    public function changeProductOrder(Request $request)
    {
        try {
            $order = Order::select('id', 'client_id', 'code', 'subtotal', 'total_price', 'order_state_id')->where('id', $request->order_id)->first();
            $client = User::select('pns_id')->where('id', $order->client_id)->first();

            $order->subtotal += ($request->product["priceTotal"] * $request->product["quantity"]);
            $order->total_price += ($request->product["priceTotal"] * $request->product["quantity"]);
            $order->update();

            if (isset($request->product["priceAfterDiscount"]) && $request->product["priceAfterDiscount"] > 0) {
                $valuePriceAfterDiscount = $request->product["percentage_discount"];
            } else {
                $valuePriceAfterDiscount = null;
            }

            if (isset($request->product["priceAfterFlash"]) && $request->product["priceAfterFlash"] > 0) {
                $valuePriceAfterFlash = $request->product["priceAfterFlash"];
            } else {
                $valuePriceAfterFlash = null;
            }

            $orderProduct = new OrderProduct();
            $orderProduct->quantity = $request->product["quantity"];
            $orderProduct->price_bruto = $request->product["price"];
            $orderProduct->price = $request->product["priceTotal"];
            $orderProduct->comments = isset($request->product["comments"]) ? $request->product["comments"] : null;
            $orderProduct->flash_price = $valuePriceAfterFlash;
            $orderProduct->percentage_discount = $valuePriceAfterDiscount;
            $orderProduct->max_units_per_order = isset($request->product["max_units_per_order"]) ? $request->product["max_units_per_order"] : null;
            $orderProduct->order_id = $request->order_id;
            $orderProduct->product_id = $request->product["id"];
            $orderProduct->save();

            if ($orderProduct && isset($request->product["product_attributes_selected"]) && count($request->product["product_attributes_selected"])) {
                foreach ($request->product["product_attributes_selected"] as $attribute) {
                    $orderProductAttribute = new OrderProductAttributes();
                    $orderProductAttribute->order_product_id    = $orderProduct->id;
                    $orderProductAttribute->attribute_id        = $attribute["attribute_id"];
                    $orderProductAttribute->value               = $attribute["value"];
                    $orderProductAttribute->price_additional    = $attribute["price_additional"];
                    $orderProductAttribute->quantity            = isset($attribute["quantity"]) ? $attribute["quantity"] : null;
                    $orderProductAttribute->save();
                }
            }

            $changeProduct = OrderProduct::where('id', $request->order_product_id)->first();
            $changeProduct->replace_by = $orderProduct->id;
            $changeProduct->update();

            $this->notificationsController->createSystemNotification(
                'Se ha reemplazado un producto de tu orden: ' . $order->code,
                $client->id
            );

            // se actualiza la unidades del inventario
            $order_product_attributes = OrderProductAttributes::where('order_product_id', $orderProduct->id)->get();
            $this->changeProductAvailable($order->order_state_id, true, $orderProduct, $order_product_attributes);

            $data = array('status' => 'success', 'message' => '');
            return response()->json($data, 200);
        } catch (Exception $e) {
            $data = array('status' => 'error', 'message' => $e->getMessage());
            return response()->json($data, 200);
        }
    }

    public function createOrderEcommerce($request, $validateQuantity = true)
    {
        // Validar la lógica del dia sin IVA
        $parameter = Parameter::select('sucursal_products', 'is_automatic_bag', 'automatic_bag_value', 'discount_inventory_state_id', 'is_dia_sin_iva', 'qty_products_dia_sin_iva')->first();
        $data = $request->data;

        if ($parameter->is_dia_sin_iva) { // Esta activa la lógica de día sin IVA
            $totalQuantityProducts = 0;
            // Contamos la cantidad que se tiene por cada producto.
            foreach ($data["products"] as $key => $product) {
                $totalQuantityProducts = $totalQuantityProducts + $product["quantity"];
            }

            if ($totalQuantityProducts >  $parameter->qty_products_dia_sin_iva) {
                $data = array('status' => 'error', 'm' => "La cantidad de productos en el carrito supera la cantidad de: " . $parameter->qty_products_dia_sin_iva . " máxima permitida en el día sin IVA.");
                return response()->json($data, 200);
            }
        }
        // fin de la lógica para el día sin IVA

        DB::beginTransaction();
        try {
            foreach ($data["products"] as $product) {
                $current_product = Product::where('id', $product["id"])->first();
                $quantity_products = intval($current_product->available_units) - intval($current_product->dispatched_units);
                if ($validateQuantity && (!$current_product->available_units || $current_product->available_units == 0 || $quantity_products < intval($product["quantity"]))) {
                    $data = array('status' => 'error', 'm' => "Lastimosamente ya no tenemos disponible la cantidad seleccionada del producto " . $current_product->name);
                    DB::rollback();
                    return response()->json($data, 200);
                }

                if (isset($product["product_attributes_selected"])) {
                    foreach ($product["product_attributes_selected"] as $attribute) {
                        $current_attribute = ProductAttribute::where([['product_id', $product["id"]], ['attribute_id', $attribute["attribute_id"]], ['value', $attribute["value"]]])->with('attribute')->first();
                        if ($current_attribute) {
                            $quantity_products_attributes = intval($current_attribute->available_units) - intval($current_attribute->dispatched_units);
                            if ($validateQuantity && (!$current_attribute->available_units || $current_attribute->available_units == 0 || $quantity_products_attributes < intval($product["quantity"]))) {
                                $data = array('status' => 'error', 'm' => "Lastimosamente ya no tenemos la cantidad seleccionada del item " . $current_attribute->attribute->display_name . " " . $current_attribute->value);
                                DB::rollback();
                                return response()->json($data, 200);
                            }
                        }
                    }
                }
            }

            $user_id = 15;
            $rol = 10;
            if (Auth::user()) {
                $user_id = Auth::user()->id;
                $rol = Auth::user()->rol_id;
            } else if (isset($data["origin"]) && $data["origin"] == 'pos') {
                $user_id = $data["user_id"];
                $rol = $data["rol_id"];
            }

            $editUser = User::where('id', $user_id)->first();
            if ($editUser && isset($data["confirmOrder"]["cellphone"]) && $data["confirmOrder"]["cellphone"] != "") {
                $editUser->phone = $data["confirmOrder"]["cellphone"];
                $editUser->update();
            }

            $address_id = null;
            $point_sale_id = null;
            // if ($data["confirmOrder"]["address"] == 0 && $rol == 1 || $rol == 2 || $rol == 6) {
            if ($rol != 4) {
                if ($data["client_id"] == "") {
                    $idClient = $this->createClient($data);
                    if (!$idClient) {
                        DB::rollback();
                        return array('r' => false);
                    }
                } else {
                    $idClient = $data["client_id"];
                }
                if (isset($data["confirmOrder"]["address"]) && $data["confirmOrder"]["address"] == 0) {
                    $address = new AddressController;
                    $address_id = $address->create($data["confirmOrder"]["address_new"]["direction"], $data["confirmOrder"]["address_new"]["direction"], $data["confirmOrder"]["address_new"]["district"], $data["confirmOrder"]["address_new"]["instru"], $data["confirmOrder"]["address_new"]["lat"], $data["confirmOrder"]["address_new"]["lng"], $data["city_id"], $idClient);
                    $address->lastUsedDirection($idClient, $address_id);
                } else {
                    $address_id = $data["confirmOrder"]["address"];
                }
            } else {
                $idClient = $user_id;
                if (isset($data["confirmOrder"]["address"])) {
                    $address_id = $data["confirmOrder"]["address"];
                } else {
                    $point_sale_id = $data["confirmOrder"]["point_sale_id"];
                }
            }



            $code = $data['code'] ?? "E-" . $this->getCode();
            $order = new Order();
            $order->code = $code;
            $order->instructions = isset($data["confirmOrder"]["observations"]) ? $data["confirmOrder"]["observations"] : null;
            $order->money = isset($data["confirmOrder"]["effectivePayment"]) ? $data["confirmOrder"]["effectivePayment"] : null;
            $order->subtotal = $data["subtotal"];
            $order->service_charge = isset($data["serviceCharge"]) ? $data["serviceCharge"] : 0;
            $order->total_price = $data["total"];
            $order->order_reference = isset($data["order_reference"]) ? $data["order_reference"] : null;
            $order->sucursal_id = isset($data["sucursal"]) ? $data["sucursal"] : null;
            $order->cost_delivery = is_array($data["priceDomicile"]) ? 0 : $data["priceDomicile"];
            $order->discount_price = isset($data["discount"]) ? $data["discount"] : null;
            $order->discount_delivery = isset($data["discountDelivery"]) ? $data["discountDelivery"] : null;
            $order->not_found = $data["productsNotFound"];
            $order->phone = $data["confirmOrder"]["cellphone"];
            $order->creation_date = Carbon::now();
            $order->order_state_id = 1;

            if (isset($data["order_type_id"]) && $data["order_type_id"] === 6) {
                $order->order_state_id = 2;
                $order->gw_state = 'CONFIRMED';
            }

            if (isset($data["purchase_origin"])) {
                $order->purchase_origin = $data["purchase_origin"];
            }

            if (isset($data["payment_transaction_id"])) {
                $order->payment_transaction_id = $data["payment_transaction_id"];
                $order->gw_code_transaction = $data["payment_transaction_id"];
                $order->order_state_id = 2;
                $order->status_notification_email_client = 'pending';
                $order->gw_state = 'CONFIRMED';
            }

            if (isset($data["status_notification_email_client"])) {
                $order->status_notification_email_client = $data["status_notification_email_client"];
            }

            $order->payment_type_id = $data["confirmOrder"]["wayPay"];
            // $order->order_type_id = $data["order_type_id"];
            $order->order_type_id = 5;
            $order->address_id = $address_id;
            $order->is_change = isset($data["is_change"]) ? $data["is_change"] : 'Normal';
            $order->point_sale_id = $point_sale_id;
            $order->delivery_man_id = isset($data["delivery_man_id"]) ? $data["delivery_man_id"] : null;

            if ($parameter->sucursal_products) {
                // if ($rol == 1 || $rol == 2 || $rol == 6) {
                if ($rol != 4) {
                    $order->current_sucursal_id = $data["sucursal"];
                } else {
                    $sucursal = UserInformation::where('user_id', $user_id)->select('current_sucursal_id')->first();
                    $order->current_sucursal_id = $sucursal->current_sucursal_id;
                }
            }

            if ($rol != 4) { // si es creado desde el panel
                $order->client_id = $idClient;
                $order->admin_id = $user_id;
                $dReferred = $data["dReferred"];
                $dCoupone = $data["dCoupone"];
                $dCampana = $data["dCampana"];
            } else { // si es creado desde el app
                $order->client_id = $user_id;
            }

            if (isset($data["storeType"])) {
                $order->store_type = $data["storeType"];
            }

            $extraParams = array();
            if (isset($data["currentAcademyUserId"])) {
                $extraParams['academyUserId'] = $data["currentAcademyUserId"];
            }

            if (count($extraParams)) {
                $order->extra_params = json_encode($extraParams);
            }

            $order->save();
            $logObj = $order;

            // Pago online.
            if ($order->payment_type_id == 4) {
                if ($data["confirmOrder"]["tdc"] != 0) {
                    $order->payment_online = 1;
                    $order->update();
                }

                $paymentsHistory = PaymentsHistory::where('id', $data["paymentHistory_id"])->first();
                $paymentsHistory->order_id = $order->id;
                $paymentsHistory->update();
            }
            if (!count($data["products"])) {
                DB::rollback();
                $data = array('status' => 'error', 'm' => "Tu pedido no tiene productos, agrega e intenta de nuevo");
                return response()->json($data, 200);
            }

            if ($order) {
                if (isset($data["confirmOrder"]["address"])) {
                    Address::where('user_id', $user_id)->update(['last_used' => 0]);
                    Address::where('id', $data["confirmOrder"]["address"])->update(['last_used' => 1]);
                }

                if ($parameter->is_automatic_bag) {
                    $order->subtotal = $order->subtotal + $parameter->automatic_bag_value;
                    $order->total_price = $order->total_price + $parameter->automatic_bag_value;
                    $order->update();
                }
                foreach ($data["products"] as $key => $product) {
                    if ($parameter->discount_inventory_state_id != 1) {
                        //Actualiza unidades a despachar
                        $this->modifyQuantityProductDispatched($product["id"], $product["quantity"], 'sum');

                        if (isset($product["product_attributes_selected"])) {
                            //Actualiza las unidades con atributos a despachar
                            $current_attributes = collect($product["product_attributes_selected"])->map(function ($item) {
                                return (object) $item;
                            });
                            $this->modifyQuantityProductAttributesDispatched($current_attributes, $product["quantity"], 'sum', $product["id"]);
                        }
                    }
                    if (isset($product["priceAfterDiscount"]) && $product["priceAfterDiscount"] > 0) {
                        $valuePriceAfterDiscount = $product["percentage_discount"];
                    } else {
                        $valuePriceAfterDiscount = null;
                    }

                    if (isset($product["priceAfterFlash"]) && $product["priceAfterFlash"] > 0) {
                        $valuePriceAfterFlash = $product["priceAfterFlash"];
                    } else {
                        $valuePriceAfterFlash = null;
                    }

                    $orderProduct = new OrderProduct();
                    $orderProduct->quantity = $product["quantity"];
                    $orderProduct->price_bruto = $product["price"];
                    $orderProduct->price = $product["priceTotal"];
                    $orderProduct->comments = isset($product["comments"]) ? $product["comments"] : null;
                    $orderProduct->flash_price = $valuePriceAfterFlash;
                    $orderProduct->percentage_discount = $valuePriceAfterDiscount;
                    $orderProduct->max_units_per_order = isset($product["max_units_per_order"]) ? $product["max_units_per_order"] : null;
                    $orderProduct->order_id = $order->id;
                    $orderProduct->product_id = $product["id"];
                    $orderProduct->save();

                    if ($orderProduct && isset($product["product_attributes_selected"]) && count($product["product_attributes_selected"])) {
                        foreach ($product["product_attributes_selected"] as $attribute) {
                            $orderProductAttribute = new OrderProductAttributes();
                            $orderProductAttribute->order_product_id    = $orderProduct->id;
                            $orderProductAttribute->attribute_id        = $attribute["attribute_id"];
                            $orderProductAttribute->value               = $attribute["value"];
                            $orderProductAttribute->price_additional    = $attribute["price_additional"];
                            $orderProductAttribute->quantity            = isset($attribute["quantity"]) ? $attribute["quantity"] : null;
                            $orderProductAttribute->save();
                        }
                    }
                }

                if (isset($data["activeDiscount"]) && $data["activeDiscount"]) {
                    foreach ($data["discountsApplied"] as $discount) {
                        if ($discount["discount_type_id"] == 3 || $discount["discount_type_id"] == 4 || $discount["discount_type_id"] == 1) {
                            $this->createDiscountOrderUser($user_id, $order->id, $discount["discount_id"]);
                        } else if ($discount["discount_type_id"] == 10) {
                            $this->createDiscountOrderUser($user_id, $order->id, $discount["discount_id"], $data["products"]);
                        }
                    }
                }

                $infoOrder = Order::where('id', $order->id)->with('address', 'point_sale', 'discountOrderUser', 'orderState', 'client')->first();
                $infoProducts = OrderProduct::where('order_id', $order->id)->with('products')->with('products.brand')->get();
                $infoOrder->products = $infoProducts;

                $data = array('status' => 'success', 'order' => $infoOrder, 'order_id' => $order->id, 'id' => $order->id);

                // envio de notificaciones
                $this->registerLog($user_id, 'Creó pedido', json_encode($logObj), "Create", 3);

                // if ($rol == 1 || $rol == 2 || $rol == 6) {
                if ($rol != 4) {
                    //registro de los descuentos

                    if ($dCampana != null) {
                        $this->createDiscountOrderUser($idClient, $order->id, $dCampana);
                    }

                    if ($dCoupone != null) {
                        $this->createDiscountOrderUser($idClient, $order->id, $dCoupone);
                    }

                    if ($dReferred != null) {
                        $userReferedInfo = UserInformation::where('user_id', $dReferred)->first();
                        $userReferedInfo->referred_user_code = null;
                        $userReferedInfo->update();
                    }

                    $response = array('r' => true, 'id' => $order->id, 'code' => $order->code);
                } else {
                    $response = response()->json($data, 200);
                }

                DB::commit();

                // actualizacion de inventario
                if ($parameter->discount_inventory_state_id == 1) {
                    $this->runInventory($order->id, 'res', 'res');
                }

                $this->sendNotifications($order);

                return $response;
            }
            DB::rollback();
            $data = array('status' => 'error', 'm' => 'Error al crear el pedido, intenta más tarde.', 'order' => null);
            return response()->json($data, 200);
        } catch (\Throwable $th) {
            DB::rollback();
            $data = array('status' => 'error', 'm' => 'Error al crear el pedido, intenta más tarde.' . $th->getLine(), 'order' => null, 'data' => $th->getMessage());
            return response()->json($data, 400);
        }
    }


    private function sendNotifications($order)
    {
        $parameters = Parameter::select('id', 'db_city', 'email_notification')->first();
        try {
            $current_order = $this->getOrder($order->id);
            event(new NewOrderCreate($parameters->email_notification, $current_order));
            $this->notificationByMailClientOrder($order->id, $current_order);
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
            event(new OrderPendingEvent($order->code, $order->id));
        } catch (Exception $e) {
            $error = [
                'order'                 => $order,
                'message'               => $e->getMessage(),
                'getFile'               => $e->getFile(),
                'getLine'               => $e->getLine(),
            ];
            $util = new UtilController();
            $util->logFile(json_encode($error));
        }
    }

    public function modifyQuantityProduct($product_id, $quantity, $action)
    {
        $current_product = Product::select('id', 'available_units')->where('id', $product_id)->first();
        if ($action == 'res') {
            $current_product->available_units = $current_product->available_units - intval($quantity);
        } else {
            $current_product->available_units = $current_product->available_units + intval($quantity);
        }
        $current_product->update();
    }

    public function modifyQuantityProductDispatched($product_id, $quantity, $action)
    {
        $current_product = Product::select('id', 'dispatched_units')->where('id', $product_id)->first();
        if ($action == 'res') {
            if ($current_product->dispatched_units > 0) {
                $current_product->dispatched_units = $current_product->dispatched_units - intval($quantity);
            }
        } else {
            $current_product->dispatched_units = $current_product->dispatched_units + intval($quantity);
        }
        $current_product->update();
    }

    public function updateQuantityShopify($reference_shopify_variation_id, $quantity)
    {

        $parameters = Parameter::select('sync_shopify', 'sucursal_products')->find(1);
        if ($parameters && $parameters->sync_shopify) {
            $sho = new ShopifyController();
            $sho->updateInventoryLevel($reference_shopify_variation_id, $quantity, 'TI108', 'COP');
        }
    }

    public function updateQuantityWoocommerce($product_id, $sku, $quantity, $action)
    {
        $woo = new WoocommerceController();
        $variation_woo = $woo->searchProductVariation($sku);
        $current_product = Product::select('reference_woocommerce_product_id')->where('id', $product_id)->first();
        $reference_woo_variation_id = intval($current_product->reference_woocommerce_product_id);
        if ($reference_woo_variation_id && $variation_woo) {
            foreach ($variation_woo as $value) {
                $variation_id = $value->id;
            }
            if ($action == 'res') {
                $numQuantity = $variation_woo[0]->stock_quantity - $quantity;
            } else {
                $numQuantity = $variation_woo[0]->stock_quantity + $quantity;
            }
            $inventory_management_woo = [
                'manage_stock' => true,
                'stock_quantity'   => $numQuantity,
            ];
            $result = $woo->updateProductVariation($reference_woo_variation_id, $variation_id, $inventory_management_woo);
        }
    }

    public function modifyQuantityProductAttributes($attributes, $quantity, $action, $product_id, $updateExternalECInventory = false)
    {
        $is_integration = new IntegrationProvidersController();
        foreach ($attributes as $key => $attribute) {
            $current_product_attribute = ProductAttribute::select('id', 'available_units', 'reference_shopify_variation_id', 'sku')
                ->where('product_id', $product_id)
                ->where('attribute_id', $attribute->attribute_id)
                ->where('value', $attribute->value)
                ->first();

            if ($current_product_attribute) {
                if ($action == 'res') {
                    $sho_quantity = "-" . $quantity;
                    $current_product_attribute->available_units = $current_product_attribute->available_units - intval($quantity);
                } else {
                    $sho_quantity = "+" . $quantity;
                    $current_product_attribute->available_units = $current_product_attribute->available_units + intval($quantity);
                }

                if ($is_integration->validateActiveIntegrationWoocommerce()) {
                    $this->updateQuantityWoocommerce($product_id, $current_product_attribute->sku, $quantity, $action);
                } elseif ($is_integration->validateActiveIntegrationShopify()) {
                    $this->updateQuantityShopify($current_product_attribute->reference_shopify_variation_id, $sho_quantity);
                }
                $current_product_attribute->update();
            }
        }
    }

    public function modifyQuantityProductAttributesDispatched($attributes, $quantity, $action, $product_id)
    {
        foreach ($attributes as $key => $attribute) {
            $current_product_attribute = ProductAttribute::select('id', 'dispatched_units')
                ->where('product_id', $product_id)
                ->where('attribute_id', $attribute->attribute_id)
                ->where('value', $attribute->value)
                ->first();

            if ($current_product_attribute) {
                if ($action == 'res') {
                    if ($current_product_attribute->dispatched_units > 0) {
                        $current_product_attribute->dispatched_units = $current_product_attribute->dispatched_units - intval($quantity);
                    }
                } else {
                    $current_product_attribute->dispatched_units = $current_product_attribute->dispatched_units + intval($quantity);
                }
                $current_product_attribute->update();
            }
        }
    }

    public function createDiscountOrderUser($idUser, $idOrder, $idDiscount, $productsDiscount = false)
    {

        $discount = Discount::find($idDiscount);
        $discount->current_winners += 1;
        $discount->update();

        $DiscountOrderUser = new DiscountOrderUser();
        $DiscountOrderUser->user_id = $idUser;
        $DiscountOrderUser->order_id = $idOrder;
        $DiscountOrderUser->discount_id = $idDiscount;
        $DiscountOrderUser->save();

        if ($productsDiscount) {
            $this->createDiscountProductUsers($discount, $productsDiscount, $idUser, $idOrder);
        }
    }

    public function createDiscountProductUsers($discount, $products, $user_id, $order_id)
    {
        if ($discount->discount_type_id == 10) {
            foreach ($products as $product) {
                if ($discount->category_id == $product["category"]["id"]) {
                    $discountProductUsers = new DiscountProductUser();
                    $discountProductUsers->quantity = $product["quantity"];
                    $discountProductUsers->price = $product["price"];
                    $discountProductUsers->plu = $product["plu"];
                    $discountProductUsers->user_id = $user_id;
                    $discountProductUsers->order_id = $order_id;
                    $discountProductUsers->product_id = $product["id"];
                    $discountProductUsers->discount_id = $discount->id;
                    $discountProductUsers->save();
                }
            }
        }
    }

    public function createOrderAlliance(Request $request)
    {

        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        //verificar que no exista otro order con el mismo codigo
        $orderVerif = Order::where('code', $data["code"])->get()->first();
        if ($orderVerif) {
            return array('r' => false, 'm' => trans('messages.controller_order_tag1'));
        }

        if ($data["delivery_man_id"] != '') {
            $deliveryMan = User::find($data["delivery_man_id"]);

            if ($deliveryMan->online == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
            }
            if ($deliveryMan->active == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
            }
        }

        $client = User::where('email', Auth::user()->userInfo->sucursal->mail)->with('userInfo.sucursal.address')->first();

        $idClient = $client->id;
        $dir = Address::where("user_id", $client->id)->first();
        $idDirection = $dir->id;

        $order = new Order();
        $order->client_id = $idClient;
        $order->order_state_id = 1;
        $order->payment_type_id = 1;
        $order->subtotal = 0;
        $order->total_price = 0;
        $order->cost_delivery = 0;
        $order->address_id = $idDirection;
        $order->order_type_id = $data["order_type_id"];
        $order->code = $data["code"];
        $order->admin_id = Auth::user()->id;
        $order->sucursal_id = $data["sucursal_id"];
        $order->express_products = $data["express_products"];
        $order->creation_date = $current;
        if ($data["delivery_man_id"] != '') {
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();
        $logObj = $order;
        $this->registerLog(
            Auth::user()->id,
            'Creó pedido',
            json_encode($logObj),
            "Create",
            3
        );

        //pusher y onesignal
        if ($data["delivery_man_id"] == '') {
            $dataPusher = $order->code;
            $parameters = Parameter::select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
            event(new OrderPendingEvent($order->code, $order->id));
        } else {
            $deliveryMan = User::find($data["delivery_man_id"]);
            if ($sucursalsT == 'App') {
                Order::where('id', $order->id)->update(array('creation_delivery_man_id' => $deliveryMan->id));
                return array('r' => true, 'd' => $order->id);
            } else if ($deliveryMan->pns_id != null) {
                $push = new PushNotificationController();
                $deliveryMan = User::find($data["delivery_man_id"]);
                $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');

                event(new NewOrderEvent($order->code, $order->id, $deliveryMan->id));
            }
        }

        //crear transferencias
        if ($order) {

            if (count($sucursalsT[0]) > 0) {
                //llamar metodo
                $this->createTransferOrder($sucursalsT, $productsT, $order->id, $idSucursal, $order->code);
            }
            return array('r' => true, 'id' => $order->id);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }

    public function createOrderTransfer($request)
    {

        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        //verificar que no exista otro pedido con el mismo codigo
        $orderVerif = Order::where('code', $data["code"])->get()->first();
        if ($orderVerif) {
            return array('r' => false, 'm' => trans('messages.controller_order_tag1'));
        }

        if ($data["delivery_man_id"] != '') {
            $deliveryMan = User::find($data["delivery_man_id"]);

            if ($deliveryMan->online == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
            }
            if ($deliveryMan->active == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
            }
        }
        $client = User::where('email', Auth::user()->userInfo->sucursal->mail)->with('userInfo.sucursal.address')->first();

        $idClient = $client->id;
        $dir = Address::where("user_id", $client->id)->first();
        $idDirection = $dir->id;

        $order = new Order();
        $order->client_id = $idClient;
        $order->order_state_id = 1;
        $order->payment_type_id = 1;
        $order->subtotal = 0;
        $order->total_price = 0;
        $order->cost_delivery = 0;
        $order->address_id = $idDirection;
        $order->order_type_id = $data["order_type_id"];
        $order->code = $data["code"];
        $order->admin_id = Auth::user()->id;
        $order->sucursal_origin_id = $data["sucursal_origin_id"];
        $order->sucursal_id = $data["sucursal_id"];
        $order->express_products = $data["express_products"];
        $order->creation_date = $current;

        if ($data["delivery_man_id"] != '') {
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();
        $logObj = $order;
        $this->registerLog(
            Auth::user()->id,
            'Creó pedido',
            json_encode($logObj),
            "Create",
            3
        );

        //pusher y onesignal
        if ($data["delivery_man_id"] == '') {
            $dataPusher = $order->code;
            $parameters = Parameter::select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
            event(new OrderPendingEvent($order->code, $order->id));
        } else {
            $deliveryMan = User::find($data["delivery_man_id"]);
            if ($sucursalsT == 'App') {
                Order::where('id', $order->id)->update(array('creation_delivery_man_id' => $deliveryMan->id));
                return array('r' => true, 'd' => $order->id);
            } else if ($deliveryMan->pns_id != null) {
                $push = new PushNotificationController();
                $deliveryMan = User::find($data["delivery_man_id"]);
                $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');

                event(new NewOrderEvent($order->code, $order->id, $deliveryMan->id));
            }
        }
        //crear transferencias
        if ($order) {

            if (count($sucursalsT[0]) > 0) {
                //llamar metodo
                $this->createTransferOrder($sucursalsT, $productsT, $order->id, $idSucursal, $order->code);
            }

            return array('r' => true, 'id' => $order->id);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }

    public function createOrderDiligence($request)
    {

        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        //verificar que no exista otro pedido con el mismo codigo
        $orderVerif = Order::where('code', $data["code"])->get()->first();
        if ($orderVerif) {
            return array('r' => false, 'm' => trans('messages.controller_order_tag1'));
        }

        if ($data["delivery_man_id"] != '') {
            $deliveryMan = User::find($data["delivery_man_id"]);

            if ($deliveryMan->online == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
            }
            if ($deliveryMan->active == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
            }
        }

        $client = User::where('email', Auth::user()->userInfo->sucursal->mail)->with('userInfo.sucursal.address')->first();

        $idClient = $client->id;
        $dir = Address::where("user_id", $client->id)->first();
        $idDirection = $dir->id;

        $order = new Order();
        $order->client_id = $idClient;
        $order->order_state_id = 1;
        $order->payment_type_id = 1;
        $order->subtotal = 0;
        $order->total_price = 0;
        $order->cost_delivery = 0;
        $order->address_id = $idDirection;
        $order->order_type_id = $data["order_type_id"];
        $order->code = $data["code"];
        $order->admin_id = Auth::user()->id;
        $order->sucursal_id = $data["sucursal_id"];
        $order->express_products = $data["express_products"];
        $order->creation_date = $current;

        if ($data["delivery_man_id"] != '') {
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();

        $logObj = $order;
        $this->registerLog(
            Auth::user()->id,
            'Creó pedido',
            json_encode($logObj),
            "Create",
            3
        );

        //pusher y onesignal
        if ($data["delivery_man_id"] == '') {
            $dataPusher = $order->code;
            $parameters = Parameter::select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
            event(new OrderPendingEvent($order->code, $order->id));
        } else {
            $deliveryMan = User::find($data["delivery_man_id"]);
            if ($sucursalsT == 'App') {
                Order::where('id', $order->id)->update(array('creation_delivery_man_id' => $deliveryMan->id));
                return array('r' => true, 'd' => $order->id);
            } else if ($deliveryMan->pns_id != null) {
                $push = new PushNotificationController();
                $deliveryMan = User::find($data["delivery_man_id"]);
                $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');

                event(new NewOrderEvent($order->code, $order->id, $deliveryMan->id));
            }
        }

        //crear transferencias
        if ($order) {
            return array('r' => true, 'id' => $order->id);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }

    public function createOrderSale($request)
    {

        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        //verificar que no exista otro pedido con el mismo codigo
        $orderVerif = Order::where('code', $data["code"])->get()->first();
        if ($orderVerif) {
            return array('r' => false, 'm' => trans('messages.controller_order_tag1'));
        }

        if ($data["delivery_man_id"] != '') {
            $deliveryMan = User::find($data["delivery_man_id"]);

            if ($deliveryMan->online == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
            }
            if ($deliveryMan->active == 0) {
                return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
            }
        }

        if (empty($data["client_id"])) {

            $verifClient = User::where('document', $data["document"])->get()->first();

            if (!empty($verifClient->document)) {
                $idClient = $verifClient->id;
                $address = new AddressController;
                $idAddress = $address->create("", $data["direction"], $data["district"], $data["indications"], $data["lat"], $data["long"], $data["city_id"], $idClient);
            } else {
                $idClient = $this->createClient($data);
                $address = new AddressController;
                $idAddress = $address->create("", $data["direction"], $data["district"], $data["indications"], $data["lat"], $data["long"], $data["city_id"], $idClient);
            }
        } else {
            $idClient = $data["client_id"];
            $client = User::find($idClient);
            $client->phone = $data["phone"];
            $client->update();
            if (empty($data["direction_id"])) {
                $address = new AddressController;
                $idAddress = $address->create("", $data["direction"], $data["district"], $data["indications"], $data["lat"], $data["long"], $data["city_id"], $idClient);
                $address->lastUsedDirection($data["client_id"], $idAddress);
            } else {
                $idAddress = $data["direction_id"];
                // $dir = Address::find($data["direction_id"]);
                // $dir->indications = $data["indications"];
                // $dir->district = $data["district"];
                // $dir->city_id = $data["city_id"];
                // $dir->update();
            }
        }

        $order = new Order();
        $order->client_id = $idClient;
        $order->order_state_id = 1;
        $order->payment_type_id = $data["payment_type_id"];
        $order->total_price = $data["total_price"];
        $order->address_id = $idAddress;
        $order->order_type_id = $data["order_type_id"];
        $order->code = $data["code"];
        $order->admin_id = Auth::user()->id;
        $order->sucursal_id = $data["sucursal_id"];
        $order->express_products = $data["express_products"];
        $order->creation_date = $current;
        $order->instructions = $data["indications"];
        if ($data['line_businesses_id'] != null) {
            $order->line_businesses_id = $data["line_businesses_id"];
        }
        if ($data["sales_channel_id"] != null) {
            $order->sales_channel_id = $data["sales_channel_id"];
        }

        if ($data["delivery_man_id"] != '') {
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        if ($data["total_price"] < $data["minimum_order_price"]) {
            $order->cost_delivery = $data["cost_delivery"];
        } else {
            $order->cost_delivery = 0;
        }

        if (empty($data["discount"])) {
            $order->discount = 0;
        } else {
            $order->discount = $data["discount"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();

        $logObj = $order;
        $this->registerLog(
            Auth::user()->id,
            'Creó pedido',
            json_encode($logObj),
            "Create",
            3
        );

        //pusher y onesignal
        if ($data["delivery_man_id"] == '') {
            $parameters = Parameter::select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
            event(new OrderPendingEvent($order->code, $order->id));
        } else {
            $deliveryMan = User::find($data["delivery_man_id"]);
            if ($sucursalsT == 'App') {
                Order::where('id', $order->id)->update(array('creation_delivery_man_id' => $deliveryMan->id));
                return array('r' => true, 'd' => $order->id);
            } else if ($deliveryMan->pns_id != null) {
                $push = new PushNotificationController();
                $deliveryMan = User::find($data["delivery_man_id"]);
                $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');
                event(new NewOrderEvent($order->code, $order->id, $deliveryMan->id));
            }
        }

        // crear transferencias
        if ($order) {
            if (count($sucursalsT[0]) > 0) {
                //llamar metodo
                $this->createTransferOrder($sucursalsT, $productsT, $order->id, $idSucursal, $order->code);
            }
            return array('r' => true, 'id' => $order->id);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }

    public function createClient($request)
    {
        $parameters = Parameter::select('id', 'db_city', 'db_name', 'sucursal_products')->first();
        $sucursal_id = null;
        if ($parameters->sucursal_products) {
            $sucursal_id = $request["sucursal"];
        }
        $accountInfo = array(
            'rol'           => $this->__CLIENT_ROL,
            'name_database' => $parameters->db_name,
            'accountInfo'   => array(
                'name'                  => $request["first_name"],
                'lastName'              => $request["last_name"],
                'cellPhone'             => $request["phone"],
                'email'                 => isset($request["email"]) ? $request["email"] : null,
                'password'              => $request["document"],
                'document'              => $request["document"],
                'sucursal_id'           => $sucursal_id,
            ),
        );

        // Peticion a Central para crear el "Cliente"
        $client = new \GuzzleHttp\Client([
            'base_uri' => config('app.central_url'),
            'defaults' => [
                'exceptions' => false,
            ],
        ]);


        if ($request["order_type_id"] == 1) {
            $responseGuzzle = $client->post('/api/central/user/signup/admin/sale', [
                \GuzzleHttp\RequestOptions::JSON => $accountInfo,
                'headers' => [
                    'Accept' => 'application/json',
                ],
            ]);
        } else {
            $responseGuzzle = $client->post('/api/central/user/signup/admin', [
                \GuzzleHttp\RequestOptions::JSON => $accountInfo,
                'headers' => [
                    'Accept' => 'application/json',
                ],
            ]);
        }


        $body = (string) $responseGuzzle->getBody();
        $remoteUser = json_decode($body);

        if ($remoteUser->status == "email_already_exists") {
            $user = User::where('email', $request["email"])->first();
            return $user->id;
        }

        if ($remoteUser->status != "success") {
            return array('r' => false);
        }

        $logObj = $remoteUser;
        $this->registerLog(Auth::user()->id, 'Creó cliente', json_encode($logObj), "Create", 3);
        return $remoteUser->user->id;
    }

    public function createTransferOrder($sucursalsT, $productsT, $idOrder, $idSucursal, $code)
    {
        $current = Carbon::now();
        for ($i = 0; $i < count($sucursalsT[0]); $i++) {

            $transfer = new Transfer();
            $transfer->order_id = $idOrder;
            $transfer->sucursal_id = (int) $sucursalsT[0][$i];
            $transfer->description = (string) $productsT[0][$i];
            $transfer->creation_date = $current;
            $transfer->save();
            $logObj = $transfer;
            // Log
            $this->registerLog(
                Auth::user()->id,
                'Creo transferencia',
                json_encode($logObj),
                "Create",
                2
            );

            if ($transfer) {
                $sucurOrigin = Sucursal::find($idSucursal);
                $sucur = Sucursal::find($transfer->sucursal_id);
                $mail = new \stdClass();

                $mail->products = (string) $productsT[0][$i];
                $mail->destination = $sucur->name;
                $mail->origin = $sucurOrigin->name;
                $mail->order = $code;

                // Mail::to($sucur->mail)->queue((new TransferMail($mail))->delay($i+1));
                Mail::to($sucur->mail)->queue(new TransferMail($mail));
            }
        }
    }

    public function edit($id)
    {
        $order = Order::where('id', $id)->with('address', 'point_sale')->first();

        $states = OrderState::all();
        $deliveryMan = User::where('active', 1)->where('online', 1)->where('rol_id', 3)->get();
        $transfers = Transfer::where('order_id', $id)->get();
        $sucursals = Sucursal::where('active', 1)->get();
        $payment_types = PaymentType::all();
        $line_businesses = LineBusiness::where('active', 1)->get();
        $sales_channels = SalesChannel::where('active', 1)->get();
        $cities = City::where('active', 1)->orderBy('name', 'ASC')->get();
        $parameter = Parameter::first();

        $accepted = " ";
        $received = " ";
        $all_deactivated = " ";

        if ($order->order_state_id == 2) {
            $accepted = "disabled";
        }
        if ($order->order_state_id == 3) {
            $accepted = "disabled";
            $received = "disabled";
        }
        if ($order->order_state_id == 4) {
            $accepted = "disabled";
            $received = "disabled";
        }
        if ($order->order_state_id == 5 || $order->order_state_id == 6 || $order->order_state_id == 7) {
            $accepted = "disabled";
            $received = "disabled";
            // $all_deactivated = "disabled";
        }
        switch ($order->order_type_id) {
            case 1:
                return view('orders.sales.editSale')->with('states', $states)->with('deliveryMan', $deliveryMan)->with('transfers', $transfers)->with('sucursals', $sucursals)->with('payment_types', $payment_types)->with('accepted', $accepted)->with('received', $received)->with('all_deactivated', $all_deactivated)->with('order', $order)
                    ->with('line_businesses', $line_businesses)
                    ->with('sales_channels', $sales_channels)
                    ->with('cities', $cities);
                break;
            case 2:
                return view('orders.alliance.editAlliance')->with('states', $states)->with('deliveryMan', $deliveryMan)->with('transfers', $transfers)->with('sucursals', $sucursals)->with('payment_types', $payment_types)->with('accepted', $accepted)->with('received', $received)->with('all_deactivated', $all_deactivated)->with('order', $order);

                break;
            case 3:
                return view('orders.transfer.editTransfer')->with('states', $states)->with('deliveryMan', $deliveryMan)->with('transfers', $transfers)->with('sucursals', $sucursals)->with('payment_types', $payment_types)->with('accepted', $accepted)->with('received', $received)->with('all_deactivated', $all_deactivated)->with('order', $order);
                break;
            case 4:
                return view('orders.diligence.editDiligence')->with('states', $states)->with('deliveryMan', $deliveryMan)->with('transfers', $transfers)->with('sucursals', $sucursals)->with('payment_types', $payment_types)->with('accepted', $accepted)->with('received', $received)->with('all_deactivated', $all_deactivated)->with('order', $order);
                break;
            case 5:
                $products = OrderProduct::where('order_id', $id)->with('orderProductAttributes')->get();
                foreach ($products as $key => $product) {
                    if ($product->percentage_discount != null) {
                        $product->percentage_discount = $product->price_bruto - ($product->price_bruto * $product->percentage_discount) / 100;
                    } else {
                        $product->percentage_discount = 0;
                    }
                }
                return view('orders.e_commerce.editE_commerce')->with('states', $states)->with('deliveryMan', $deliveryMan)
                    ->with('transfers', $transfers)->with('sucursals', $sucursals)->with('payment_types', $payment_types)
                    ->with('accepted', $accepted)->with('received', $received)->with('all_deactivated', $all_deactivated)
                    ->with('order', $order)->with('products', $products)->with('line_businesses', $line_businesses)
                    ->with('sales_channels', $sales_channels)->with('cities', $cities)
                    ->with('parameter', $parameter);

                break;
        }
        //hacer un swtich y segun el tipo de pedido asi mismo mandar la vista
    }

    public function update(Request $request)
    {
        $type = $request->data;
        $order = Order::find($type["id"]);

        $response;
        switch ($order->order_type_id) {
            case 1:
                $response = $this->updateSale($request);
                break;
            case 2:
                $response = $this->updateAlliance($request);
                break;
            case 3:
                $response = $this->updateTransfer($request);
                break;
            case 4:
                $response = $this->updateDiligence($request);
                break;
            case 5:
                $response = $this->updateECommerce($request);
                break;
        }
        return $response;
    }

    public function updateSale($request)
    {
        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        $order = Order::find($data["id"]);
        $logObj = $order;

        //verificar que el mensajero asignado este en linea
        if ($data["delivery_man_id"] != null) {

            if ($order->delivery_man_id != $data["delivery_man_id"]) {
                $deliveryMan = User::find($data["delivery_man_id"]);

                if ($deliveryMan->online == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
                }
                if ($deliveryMan->active == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
                }
            }
        }

        if ($order->client_id != $data["user_id"]) {
            if (empty($data["user_id"])) {
                $verifClient = User::where('document', $data["document"])->get()->first();

                if (!empty($verifClient->document)) {
                    $idClient = $verifClient->id;
                    $address = new AddressController;
                    $idAddress = $address->create("", $data["direction"], $data["district"], $data["indications"], $data["lat"], $data["long"], $data["city_id"], $idClient);
                } else {
                    $idClient = $this->createClient($data);
                    $address = new AddressController;
                    $idAddress = $address->create("", $data["direction"], $data["district"], $data["indications"], $data["lat"], $data["long"], $data["city_id"], $idClient);
                }
            } else {
                $idClient = $data["user_id"];
                $client = User::find($idClient);
                $client->phone = $data["phone"];
                $client->update();
                if (empty($data["direction_id"])) {

                    $address = new AddressController;
                    $idAddress = $address->create("", $data["direction"], $data["district"], $data["indications"], $data["lat"], $data["long"], $data["city_id"], $idClient);
                    $address->lastUsedDirection($data["user_id"], $idAddress);
                } else {

                    $idAddress = $data["direction_id"];
                    $dir = Address::find($data["direction_id"]);
                    $dir->indications = $data["indications"];
                    $dir->district = $data["district"];
                    $dir->city_id = $data["city_id"];
                    $dir->update();
                }
            }
        } else {
            $client = User::find($data['user_id']);
            $idClient = $data["user_id"];
            $client->phone = $data['phone'];
            $client->first_name = $data['first_name'];
            $client->last_name = $data['last_name'];

            $client->update();

            if ($order->address_id != $data["direction_id"]) {
                $address = new AddressController;
                $idAddress = $address->create("", $data["direction"], $data["district"], $data["indications"], $data["lat"], $data["long"], $data["city_id"], $idClient);
            } else {
                $dir = Address::find($data["direction_id"]);
                $dir->district = $data["district"];
                $dir->indications = $data["indications"];
                $dir->city_id = $data["city_id"];
                $idAddress = $dir->id;
                $dir->update();
            }
        }

        $order->client_id = $idClient;
        $order->payment_type_id = $data["payment_type_id"];
        $order->total_price = $data["total_price"];
        $order->address_id = $idAddress;
        $order->sucursal_id = $data["sucursal_id"];
        $order->express_products = $data["express_products"];
        $order->order_state_id = $data["order_state_id"];
        $order->line_businesses_id = $data["line_businesses_id"];
        $order->sales_channel_id = $data["sales_channel_id"];

        $this->updateState($order->id, $data["order_state_id"], Auth::user()->id);

        if (empty($data["discount"])) {
            $order->discount = 0;
        } else {
            $order->discount = $data["discount"];
        }

        /// REASIGNAR MENSAJERO
        if ($order->delivery_man_id != $data["delivery_man_id"]) {
            // se manda notificacion al mensajero anterior
            if ($order->delivery_man_id != null) {
                $deliveryMan = User::find($order->delivery_man_id);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('El pedido ' . $order->code . ' ha sido reasignado ', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new OrderReassignmentEvent($order->code, $order->id, $order->delivery_man_id));
                }
            }
            //se manda notificacion a nuevo mensajero
            if ($data["delivery_man_id"] == '') {
                $dataPusher = $order->code;
                $parameters = Parameter::select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
                event(new OrderPendingEvent($order->code, $order->id));
            } else {
                $deliveryMan = User::find($data["delivery_man_id"]);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new NewOrderEvent($order->code, $order->id, $data["delivery_man_id"]));
                }
            }
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();

        $this->registerLog(
            Auth::user()->id,
            'Actualizó pedido',
            json_encode($logObj),
            "Update",
            3
        );

        // crear transferencias
        if ($order) {

            if (count($sucursalsT[0]) > 0) {
                //llamar metodo
                $this->createTransferOrder($sucursalsT, $productsT, $order->id, $idSucursal, $order->code);
            }
            return array('r' => true);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }

    public function updateTransfer($request)
    {
        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        $order = Order::find($data["id"]);
        $logObj = $order;
        //verificar que no exista otro pedido con el mismo codigo

        if ($data["delivery_man_id"] != null) {
            if ($order->delivery_man_id != $data["delivery_man_id"]) {
                $deliveryMan = User::find($data["delivery_man_id"]);

                if ($deliveryMan->online == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
                }
                if ($deliveryMan->active == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
                }
            }
        }
        $order->order_state_id = $data["order_state_id"];
        $this->updateState($order->id, $data["order_state_id"], Auth::user()->id);
        $order->sucursal_id = $data["sucursal_id"];
        $order->sucursal_origin_id = $data["sucursal_origin_id"];
        $order->express_products = $data["express_products"];

        /// REASIGNAR MENSAJERO
        if ($order->delivery_man_id != $data["delivery_man_id"]) {
            // se manda notificacion al mensajero anterior
            if ($order->delivery_man_id != null) {
                $deliveryMan = User::find($order->delivery_man_id);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('El pedido ' . $order->code . ' ha sido reasignado ', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new OrderReassignmentEvent($order->code, $order->id, $order->delivery_man_id));
                }
            }
            //se manda notificacion a nuevo mensajero
            if ($data["delivery_man_id"] == '') {
                $dataPusher = $order->code;
                $parameters = Parameter::select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
                event(new OrderPendingEvent($order->code, $order->id));
            } else {
                $deliveryMan = User::find($data["delivery_man_id"]);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new NewOrderEvent($order->code, $order->id, $data["delivery_man_id"]));
                }
            }
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();
        $this->registerLog(
            Auth::user()->id,
            'Actualizó pedido',
            json_encode($logObj),
            "Update",
            3
        );

        //crear transferencias
        if ($order) {

            if (count($sucursalsT[0]) > 0) {
                //llamar metodo
                $this->createTransferOrder($sucursalsT, $productsT, $order->id, $idSucursal, $order->code);
            }
            return array('r' => true, 'id' => $order->id);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }
    public function updateAlliance($request)
    {

        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        $order = Order::find($data["id"]);
        $logObj = $order;
        //verificar que no exista otro pedido con el mismo codigo

        if ($data["delivery_man_id"] != null) {
            if ($order->delivery_man_id != $data["delivery_man_id"]) {
                $deliveryMan = User::find($data["delivery_man_id"]);

                if ($deliveryMan->online == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
                }
                if ($deliveryMan->active == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
                }
            }
        }
        $order->order_state_id = $data["order_state_id"];
        $this->updateState($order->id, $data["order_state_id"], Auth::user()->id);
        $order->sucursal_id = $data["sucursal_id"];
        $order->express_products = $data["express_products"];

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();

        $this->registerLog(
            Auth::user()->id,
            'Actualizó pedido',
            json_encode($logObj),
            "Update",
            3
        );

        /// REASIGNAR MENSAJERO
        if ($order->delivery_man_id != $data["delivery_man_id"]) {
            // se manda notificacion al mensajero anterior
            if ($order->delivery_man_id != null) {
                $deliveryMan = User::find($order->delivery_man_id);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('El pedido ' . $order->code . ' ha sido reasignado ', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new OrderReassignmentEvent($order->code, $order->id, $order->delivery_man_id));
                }
            }
            //se manda notificacion a nuevo mensajero
            if ($data["delivery_man_id"] == '') {
                $dataPusher = $order->code;
                $parameters = Parameter::select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
                event(new OrderPendingEvent($order->code, $order->id));
            } else {
                $deliveryMan = User::find($data["delivery_man_id"]);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new NewOrderEvent($order->code, $order->id, $data["delivery_man_id"]));
                }
            }
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();

        //crear transferencias
        if ($order) {

            if (count($sucursalsT[0]) > 0) {
                //llamar metodo
                $this->createTransferOrder($sucursalsT, $productsT, $order->id, $idSucursal, $order->code);
            }
            return array('r' => true, 'id' => $order->id);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }
    public function updateDiligence($request)
    {

        $data = $request->data;
        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $current = Carbon::now();
        $order = Order::find($data["id"]);
        $logObj = $order;
        //verificar que no exista otro pedido con el mismo codigo

        if ($data["delivery_man_id"] != null) {
            if ($order->delivery_man_id != $data["delivery_man_id"]) {
                $deliveryMan = User::find($data["delivery_man_id"]);

                if ($deliveryMan->online == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
                }
                if ($deliveryMan->active == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
                }
            }
        }
        $order->order_state_id = $data["order_state_id"];
        $this->updateState($order->id, $data["order_state_id"], Auth::user()->id);
        $order->sucursal_id = $data["sucursal_id"];
        $order->express_products = $data["express_products"];

        /// REASIGNAR MENSAJERO
        if ($order->delivery_man_id != $data["delivery_man_id"]) {
            // se manda notificacion al mensajero anterior
            if ($order->delivery_man_id != null) {
                $deliveryMan = User::find($order->delivery_man_id);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('El pedido ' . $order->code . ' ha sido reasignado ', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new OrderReassignmentEvent($order->code, $order->id, $order->delivery_man_id));
                }
            }
            //se manda notificacion a nuevo mensajero
            if ($data["delivery_man_id"] == '') {
                $dataPusher = $order->code;
                $parameters = Parameter::select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
                event(new OrderPendingEvent($order->code, $order->id));
            } else {
                $deliveryMan = User::find($data["delivery_man_id"]);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new NewOrderEvent($order->code, $order->id, $data["delivery_man_id"]));
                }
            }
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $idSucursal = (int) $data["sucursal_id"];
        $order->save();

        $this->registerLog(
            Auth::user()->id,
            'Actualizó pedido',
            json_encode($logObj),
            "Update",
            3
        );

        //crear transferencias
        if ($order) {

            if (count($sucursalsT[0]) > 0) {
                //llamar metodo
                $this->createTransferOrder($sucursalsT, $productsT, $order->id, $idSucursal, $order->code);
            }
            return array('r' => true, 'id' => $order->id);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }

    public function addProductOrder($request)
    {
        try {
            $order = Order::select('id', 'client_id', 'code', 'subtotal', 'total_price')->where('id', $request->data["id"])->first();
            $client = User::select('pns_id')->where('id', $order->client_id)->first();

            foreach ($request->addProducts as $product) {
                $order->subtotal += ($product["priceTotal"] * $product["quantity"]);
                $order->total_price += ($product["priceTotal"] * $product["quantity"]);
                $order->update();

                if (isset($product["priceAfterDiscount"]) && $product["priceAfterDiscount"] > 0) {
                    $valuePriceAfterDiscount = $product["percentage_discount"];
                } else {
                    $valuePriceAfterDiscount = null;
                }

                if (isset($product["priceAfterFlash"]) && $product["priceAfterFlash"] > 0) {
                    $valuePriceAfterFlash = $product["priceAfterFlash"];
                } else {
                    $valuePriceAfterFlash = null;
                }

                $orderProduct = new OrderProduct();
                $orderProduct->quantity = $product["quantity"];
                $orderProduct->price_bruto = $product["price"];
                $orderProduct->price = $product["priceTotal"];
                $orderProduct->comments = isset($product["comments"]) ? $product["comments"] : null;
                $orderProduct->flash_price = $valuePriceAfterFlash;
                $orderProduct->percentage_discount = $valuePriceAfterDiscount;
                $orderProduct->max_units_per_order = isset($product["max_units_per_order"]) ? $product["max_units_per_order"] : null;
                $orderProduct->order_id = $request->data["id"];
                $orderProduct->product_id = $product["id"];
                $orderProduct->save();

                if ($orderProduct && isset($product["product_attributes_selected"]) && count($product["product_attributes_selected"])) {
                    foreach ($product["product_attributes_selected"] as $attribute) {
                        $orderProductAttribute = new OrderProductAttributes();
                        $orderProductAttribute->order_product_id    = $orderProduct->id;
                        $orderProductAttribute->attribute_id        = $attribute["attribute_id"];
                        $orderProductAttribute->value               = $attribute["value"];
                        $orderProductAttribute->price_additional    = $attribute["price_additional"];
                        $orderProductAttribute->quantity            = isset($attribute["quantity"]) ? $attribute["quantity"] : null;
                        $orderProductAttribute->save();
                    }
                }
            }

            if ($client->pns_id != null) {
                $this->notificationsController->createSystemNotification(
                    'Se han agregado productos a tu orden: ' . $order->code,
                    $client->id
                );
            }

            $data = array('status' => 'success', 'message' => '');
            return response()->json($data, 200);
        } catch (Exception $e) {
            $data = array('status' => 'error', 'message' => $e->getMessage());
            return response()->json($data, 200);
        }
    }

    public function updateECommerce($request)
    {
        $data = $request->data;
        $order = Order::find($data["id"]);
        $logObj = $order;

        if ($data["address_id"] != null && $data["address_id"] != $order->address_id) {
            $order->address_id = $data["address_id"];
        }
        //verificar que el mensajero asignado este en linea
        if ($data["delivery_man_id"] != null) {
            if ($order->delivery_man_id != $data["delivery_man_id"]) {
                $deliveryMan = User::find($data["delivery_man_id"]);

                if ($deliveryMan->online == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag2'));
                }
                if ($deliveryMan->active == 0) {
                    return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
                }
            }
        }

        if (count($request->addProducts)) {
            $this->addProductOrder($request);
        }

        $update_state = $this->updateState($order->id, $data["order_state_id"], Auth::user()->id);
        if (!$update_state["r"]) {
            return $update_state;
        }

        /// REASIGNAR MENSAJERO
        if ($order->delivery_man_id != $data["delivery_man_id"]) {
            // se manda notificacion al mensajero anterior
            if ($order->delivery_man_id != null) {
                $deliveryMan = User::find($order->delivery_man_id);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('El pedido ' . $order->code . ' ha sido reasignado ', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new OrderReassignmentEvent($order->code, $order->id, $order->delivery_man_id));
                }
            }
            //se manda notificacion a nuevo mensajero
            if ($data["delivery_man_id"] == '') {
                $parameters = Parameter::select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . config('app.client'), null, null, null, null, 'D');
                event(new OrderPendingEvent($order->code, $order->id));
            } else {
                $deliveryMan = User::find($data["delivery_man_id"]);
                if ($deliveryMan->pns_id != null) {
                    $push = new PushNotificationController();
                    $push->sendToUser('Nuevo pedido asignado', $deliveryMan->pns_id, null, null, null, null, 'D');
                    event(new NewOrderEvent($order->code, $order->id, $data["delivery_man_id"]));
                }
            }
            $order->delivery_man_id = $data["delivery_man_id"];
        }

        $order->update();
        $this->registerLog(Auth::user()->id, 'Actualizó pedido', json_encode($logObj), "Update", 3);
        // crear transferencias
        if ($order) {
            return array('r' => true);
        } else {
            return array('r' => false, 'm' => trans('messages.controller_order_tag3'));
        }
    }

    public function getOrderInProcess(Request $request)
    {
        $idDeliveryMan = $request->delivery_id;
        $pending = Order::where('delivery_man_id', $idDeliveryMan)
            ->where('order_state_id', '!=', 5)
            ->where('order_state_id', '!=', 6)
            ->where('order_state_id', '!=', 7)
            ->with('client', 'admin', 'deliveryMan', 'sucursal', 'orderState', 'paymentType', 'orderType', 'sucursalOrigin', 'comment', 'address', 'point_sale', 'transferences', 'channel', 'line')
            ->orderBy('creation_date', 'desc')
            ->get();

        return response()->json(['pending' => $pending]);
    }

    public function asc_sort($array1, $array2)
    {
        $on = 'subcategory_id';
        if ($array1[$on] == $array2[$on]) {
            return 0;
        }
        return ($array1[$on] < $array2[$on]) ? -1 : 1;
    }

    public function getOrder($id)
    {
        $order = Order::with('address.city.state.country', 'discountOrderUser', 'point_sale', 'paymentType', 'client')->findOrFail($id);
        $transfers = Transfer::where('order_id', $id)->get();
        $products = OrderProduct::where('order_id', $id)->with('product', 'orderProductAttributes')->get();
        $parameter = Parameter::first();

        $transfer = array();
        foreach ($transfers as $key => $trans) {
            $trans = array('id' => $trans->id, 'sucursal' => $trans->sucursal->name, 'description' => $trans->description, 'date' => $trans->collected_date);
            array_push($transfer, $trans);
        }

        $productsOrder = array();
        foreach ($products as $key => $product) {
            $subcategory = Subcategories::where('id', $product->products->subcategoryProduct[0]['subcategory_id'])->first();
            if ($product->percentage_discount != null) {
                $discountPrice = $product->price_bruto - ($product->price_bruto * $product->percentage_discount) / 100;
            } else {
                $discountPrice = null;
            }
            $product = array('id' => $product->products->id, 'name' => $product->products->name, 'plu' => $product->products->plu, 'price' => $product->price, 'discount' => $discountPrice, 'flash_price' => $product->flash_price, 'quantity' => $product->quantity, 'product_images' => $product->products->productImages, 'brand' => $product->products->brand, 'available' => $product->available, 'recolected' => $product->is_recolected, 'subcategory_id' => $subcategory->id, 'subcategory_name' => $subcategory->name, 'bar_code' => $product->products->bar_code, 'order_product_attributes' => $product->orderProductAttributes, 'comments' => $product->comments, 'order_product_id' => $product->id, 'price_bruto' => $product->price_bruto, 'replace_by' => $product->replace_by);
            array_push($productsOrder, $product);
        }
        usort($productsOrder, array($this, "asc_sort"));
        $city = "N/A";
        $order->client_id = $order->client->first_name . " " . $order->client->last_name;
        if ($order->delivery_man_id != null) {
            $order->delivery_man_id = $order->deliveryMan->first_name . " " . $order->deliveryMan->last_name;
        } else {
            $order->delivery_man_id = "Sin " . $parameter->name_delivery_man;
        }
        if ($order->admin_id != null) {
            $order->admin_id = $order->admin->first_name . " " . $order->admin->last_name;
        } else {
            $order->admin_id = "NA";
        }
        if ($order->sucursal_id != null) {
            $order->sucursal_id = $order->sucursal->name;
        } else {
            $order->sucursal_id = "NA";
        }

        if ($order->address_id != null && $order->address) {
            $order->address_id = $order->address->direction;
        }
        $order->order_state_id = $order->orderState->name;
        $order->payment_type_id = $order->paymentType->name;

        if ($order->sucursal_origin_id != null) {
            $order->sucursal_origin_id = $order->sucursalOrigin->name;
        } else {
            $order->sucursal_origin_id = "NA";
        }

        if ($order->deliver_date != null) {
            $t1 = new DateTime($order->creation_date);
            $t2 = new DateTime($order->deliver_date);
            $time1 = $t1->diff($t2);
            $time = $time1->format('%H horas %i minutes');
        } else {
            $time = "Fecha de entrega no asignada";
        }

        if ($order->current_sucursal_id) {
            $current_sucursal_id = Sucursal::where('id', $order->current_sucursal_id)->select('id', 'name')->first();
        } else {
            $current_sucursal_id = null;
        }

        $qualification = "Sin calificación";
        $comment = Comment::where('order_id', $order->id)->first();

        if ($comment) {
            if ($comment->qualification_delivery_man != null) {
                $qualification = $comment->qualification_delivery_man;
            }
        }
        $order_type = $order->orderType->name;

        $identity = CorporateIdentity::all()->first();
        $nameCompany = $identity->platform_name;
        return array('order' => $order, 'transfers' => $transfer, 'parameter' => $parameter, 'time' => $time, 'qualification' => $qualification, 'order_type' => $order_type, 'nameCompany' => $nameCompany, 'products' => $productsOrder, 'city' => $city, 'current_sucursal_id' => $current_sucursal_id);
    }

    public function addTransfer(Request $request)
    {

        $sucursalsT = $request->sucursalsTransf;
        $productsT = $request->productsTransf;
        $order = Order::find($request["id"]);

        if (count($sucursalsT[0]) > 0) {

            $this->createTransferOrder($sucursalsT, $productsT, $order->id, $order->sucursal_id, $order->code);
        }
        return array('r' => true, 'id' => $order->id);
    }

    public function report(Request $request)
    {
        $file = new ReportOrders;
        $file->request = $request;
        return Excel::download($file, 'Reporte pedidos.xlsx');
    }

    public function qualificationAdmin(Request $request)
    {
        $comment = Comment::where('order_id', $request["id"])->first();

        if ($comment) {
            $comment->admin_id = Auth::user()->id;
            $comment->qualification_admin = $request['qualification'];
            $comment->observations_admin = $request['observation'];
            $this->updateState($request["id"], 6, Auth::user()->id);
            //llamar metodo aqui para modificar estados el estado finalizado
            $comment->update();

            return array('r' => true);
        } else {
            $comment = new Comment();
            $comment->admin_id = Auth::user()->id;
            $comment->qualification_admin = $request['qualification'];
            $comment->observations_admin = $request['observation'];
            $comment->order_id = $request["id"];
            //llamar metodo aqui para modificar estados el estado finalizado
            $this->updateState($request["id"], 6, Auth::user()->id);
            $comment->save();
            return array('r' => true);
        }
    }

    public function viewQualificationAdmin($id)
    {
        $comment = Comment::where('order_id', $id)->first();
        return response()->json($comment);
    }

    // @changeProduct = si se hace el llamado desde cambio de producto

    public function changeProductAvailable($order_state_id, $available, $orderProduct, $orderProductAttributes)
    {
        $parameter = Parameter::select('discount_inventory_state_id')->where('id', 1)->first();
        if ($available) {
            if ($parameter->discount_inventory_state_id <= $order_state_id) {
                $this->modifyQuantityProduct($orderProduct->product_id, $orderProduct->quantity, 'res');
                $this->modifyQuantityProductAttributes($orderProductAttributes, $orderProduct->quantity, 'res', $orderProduct->product_id);
            } else {
                $this->modifyQuantityProductDispatched($orderProduct->product_id, $orderProduct->quantity, 'sum');
                $this->modifyQuantityProductAttributesDispatched($orderProductAttributes, $orderProduct->quantity, 'sum', $orderProduct->product_id);
            }
        } else {
            if ($parameter->discount_inventory_state_id <= $order_state_id) {
                $this->modifyQuantityProduct($orderProduct->product_id, $orderProduct->quantity, 'sum');
                $this->modifyQuantityProductAttributes($orderProductAttributes, $orderProduct->quantity, 'sum', $orderProduct->product_id);
            } else {
                $this->modifyQuantityProductDispatched($orderProduct->product_id, $orderProduct->quantity, 'res');
                $this->modifyQuantityProductAttributesDispatched($orderProductAttributes, $orderProduct->quantity, 'res', $orderProduct->product_id);
            }
        }
    }

    public function updateState($id, $id_state, $id_user)
    {
        $user = User::find($id_user);
        $rol = $user->rol_id;
        $logObj = Order::find($id);
        $current = Carbon::now();
        $client = User::find($logObj->client_id);
        $parameters = Parameter::select('discount_inventory_state_id')->where('id', 1)->first();
        $state = OrderState::find($id_state);
        $sendNotificationToUser = true;

        if ($rol == 4 && $id_state == 7 && $logObj->order_state_id != 1) {
            return array('r' => false, 'm' => 'No es posible cancelarlo, El pedido no se encuentra en estado pendiente.');
        }
        if ($logObj->order_state_id == 7) {
            if ($id_state != 2) {
                return array('r' => false, 'm' => 'Para cambiar el estado de un pedido cancelado, debes seleccionar el estado aceptado.');
            }
            if ($parameters->discount_inventory_state_id == 1) {
                $products = OrderProduct::where('order_id', $id)->get();
                foreach ($products as $key => $product) {
                    $this->modifyQuantityProduct($product->product_id, $product->quantity, 'res');
                    $order_product_attributes = OrderProductAttributes::where('order_product_id', $product->id)->get();
                    if ($order_product_attributes) {
                        $this->modifyQuantityProductAttributes($order_product_attributes, $product->quantity, 'res', $product->product_id, true);
                    }
                }
            } else {
                $products = OrderProduct::where('order_id', $id)->get();
                foreach ($products as $key => $product) {
                    //Actualiza unidades a despachar
                    $this->modifyQuantityProductDispatched($product->product_id, $product->quantity, 'sum');
                    $order_product_attributes = OrderProductAttributes::where('order_product_id', $product->id)->get();
                    if ($order_product_attributes) {
                        //Actualiza las unidades con atributos a despachar
                        $this->modifyQuantityProductAttributesDispatched($order_product_attributes, $product->quantity, 'sum', $product->product_id);
                    }
                }
            }
        }
        switch ($id_state) {
            case 2:
                //Aceptado
                if ($rol == 3) {
                    Order::where('id', $id)->update(array('accepted_delivery_man_id' => $user->id, 'delivery_man_id' => $user->id));
                    if ($logObj->order_type_id == 5) {
                        if ($client->pns_id != null) {
                            $this->notificationsController->createSystemNotification(
                                'El pedido ha sido aceptado por el mensajero ' . $user->first_name . ' ' . $user->last_name,
                                $client->id
                            );
                            $sendNotificationToUser = false;
                        }
                        event(new ChangeStateEvent($id));
                    }
                }
                $order = Order::where('id', $id)->update(array('accepted_date' => $current, 'order_state_id' => $id_state));
                if ($parameters->discount_inventory_state_id == 2) {
                    $this->runInventory($id, 'res', 'res');
                }
                break;
            case 3:
                //Recolectado
                if ($rol == 3) {
                    Order::where('id', $id)->update(array('collected_delivery_man_id' => $user->id, 'delivery_man_id' => $user->id));
                    if ($logObj->order_type_id == 5) {

                        if ($client->pns_id != null) {
                            $this->notificationsController->createSystemNotification(
                                'Se han recolectado los productos de tu pedido',
                                $client->id
                            );
                            $sendNotificationToUser = false;
                        }
                        event(new ChangeStateEvent($id));
                    }
                }
                $order = Order::where('id', $id)->update(array('collected_date' => $current, 'order_state_id' => $id_state));
                if ($parameters->discount_inventory_state_id == 3) {
                    $this->runInventory($id, 'res', 'res');
                }
                break;
            case 4:
                //En ruta
                if ($rol == 3) {
                    if ($logObj->order_type_id == 5) {
                        if ($client->pns_id != null) {
                            $this->notificationsController->createSystemNotification(
                                'El mensajero va en camino con tu pedido',
                                $client->id
                            );
                            $sendNotificationToUser = false;
                        }
                        event(new ChangeStateEvent($id));
                    }
                }

                $order = Order::where('id', $id)->update(array('order_state_id' => $id_state, 'delivery_man_id' => $user->id));
                if ($parameters->discount_inventory_state_id == 4) {
                    $this->runInventory($id, 'res', 'res');
                }
                break;
            case 5:
                //Entregado
                if ($rol == 3) {
                    Order::where('id', $id)->update(array('deliver_delivery_man_id' => $user->id, 'delivery_man_id' => $user->id));

                    if ($logObj->order_type_id == 5) {
                        $this->notificationsController->createSystemNotification(
                            'Tu pedido fue entregado con exito!',
                            $client->id
                        );

                        $sendNotificationToUser = false;
                        event(new ChangeStateEvent($id));
                    }
                }
                $order = Order::where('id', $id)->update(array('deliver_date' => $current, 'order_state_id' => $id_state));
                // if ($logObj->order_type_id != 5) {
                $this->calculationAverage($id);
                // }
                if ($parameters->discount_inventory_state_id == 5) {
                    $this->runInventory($id, 'res', 'res');
                }
                break;
            case 6:
                // Finalizado
                $this->stateFinished($id, $id_state, $rol, $current);
                if ($parameters->discount_inventory_state_id == 6) {
                    $this->runInventory($id, 'res', 'res');
                }
                break;
            case 7:
                // Se vuelven a sumar al inventario del producto las cantidades compradas
                if ($logObj->order_state_id > $parameters->discount_inventory_state_id) {
                    $this->runInventory($id, 'sum', 'res', true);
                } else {
                    $this->runInventory($id, 'sum', '', true);
                }
                if ($rol == 4) {
                    Order::where('id', $id)->update(array('order_state_id' => $id_state));
                } else {
                    $order = Order::where('id', $id)->update(array('deliver_date' => $current, 'order_state_id' => $id_state));
                }
                break;
            case 8:
                //  $order = Order::where('id', $id)->update(array('' => $current,'order_state_id' => $id_state));
                break;
            case 9:
                // Se vuelven a sumar al inventario del producto las cantidades compradas
                if ($logObj->order_state_id > $parameters->discount_inventory_state_id) {
                    $this->runInventory($id, 'sum', 'res');
                } else {
                    $this->runInventory($id, 'sum', '');
                }
                $order = Order::where('id', $id)->update(array('deliver_date' => $current, 'order_state_id' => $id_state));
                break;
            default:
        }
        if ($sendNotificationToUser) {
            $this->sendOrderStatusChangeNotificationToUser($logObj, $client, $state);
        }
        event(new OrderStateEvent($id, $id_state));
        return array('r' => true);
    }

    public function runInventory($order_id, $operation_available, $operation_dispatched, $updateExternalECInventory = false)
    {
        //Se resta la cantidad de unidades en despacho en products y products attributes
        $products = OrderProduct::where('order_id', $order_id)->get();
        foreach ($products as $key => $product) {
            if ($product->available) {
                if ($operation_available != '') {
                    $this->modifyQuantityProduct($product->product_id, $product->quantity, $operation_available);
                }
                if ($operation_dispatched != '') {
                    $this->modifyQuantityProductDispatched($product->product_id, $product->quantity, $operation_dispatched);
                }
                $order_product_attributes = OrderProductAttributes::where('order_product_id', $product->id)->get();
                if ($order_product_attributes) {
                    if ($operation_available != '') {
                        $this->modifyQuantityProductAttributes($order_product_attributes, $product->quantity, $operation_available, $product->product_id, $updateExternalECInventory);
                    }
                    if ($operation_dispatched != '') {
                        $this->modifyQuantityProductAttributesDispatched($order_product_attributes, $product->quantity, $operation_dispatched, $product->product_id);
                    }
                }
            }
        }
    }

    public function stateFinished($id, $id_state, $rol, $current)
    {

        switch ($rol) {
            case 1:
                //superadmin
                $order = Order::where('id', $id)->update(array('finished_admin_date' => $current, 'order_state_id' => $id_state));
                break;
            case 2:
                //admin
                $order = Order::where('id', $id)->update(array('finished_admin_date' => $current, 'order_state_id' => $id_state));
                break;
            case 3:
                //mensajero
                $order = Order::where('id', $id)->update(array('finished_delivery_man_date' => $current, 'order_state_id' => $id_state));
                break;
            case 4:
                //cliente
                $order = Order::where('id', $id)->update(array('finished_client_date' => $current, 'order_state_id' => $id_state));
                break;

            default:

                break;
        }
    }

    public function calculationAverage($id)
    {
        $order = Order::find($id);
        $date1 = $order->creation_date;
        $date2 = $order->deliver_date;
        $minutes = (strtotime($date1) - strtotime($date2)) / 60;
        $minutes = abs($minutes);
        $minutes = floor($minutes);
        $currentMonth = date("n");
        $currentYear = date("Y");
        $currentDay = date("j");
        $id_s = $order->sucursal_id;
        //promedio por year
        if ($order->order_type_id == 5) {
            $average = AverageTime::where('month_number', $currentMonth)->where('year', $currentYear)->whereNull('sucursal_id')->first();
        } else {
            $average = AverageTime::where('month_number', $currentMonth)->where('year', $currentYear)->where('sucursal_id', $id_s)->first();
        }

        if ($average) {
            $average->amount_time = ($average->amount_time) + $minutes;
            $average->order_quantity = ($average->order_quantity) + 1;
            $average->average_time = ($average->amount_time) / ($average->order_quantity);
            $average->update();
        } else {
            $newCoverage = new AverageTime();
            $newCoverage->month_number = $currentMonth;
            $newCoverage->year = $currentYear;
            $newCoverage->amount_time = $minutes;
            $newCoverage->order_quantity = 1;
            $newCoverage->average_time = $minutes;

            if ($order->order_type_id != 5) {
                $newCoverage->sucursal_id = $id_s;
            }

            $newCoverage->save();
        }

        /// filtro promedio por mes
        if ($order->order_type_id == 5) {
            $averageMonth = AverageMonth::where('number_month', $currentMonth)->where('day', $currentDay)->where('year', $currentYear)->whereNull('sucursal_id')->first();
        } else {
            $averageMonth = AverageMonth::where('number_month', $currentMonth)->where('day', $currentDay)->where('year', $currentYear)->where('sucursal_id', $id_s)->first();
        }


        if ($averageMonth) {
            $averageMonth->sum_time = ($averageMonth->sum_time) + $minutes;
            $averageMonth->quantity_orders = ($averageMonth->quantity_orders) + 1;
            $averageMonth->average_times = ($averageMonth->sum_time) / ($averageMonth->quantity_orders);
            $averageMonth->update();
        } else {
            $newAverageMonth = new AverageMonth();
            $newAverageMonth->number_month = $currentMonth;
            $newAverageMonth->day = $currentDay;
            $newAverageMonth->year = $currentYear;
            $newAverageMonth->sum_time = $minutes;
            $newAverageMonth->quantity_orders = 1;
            $newAverageMonth->average_times = $minutes;
            if ($order->order_type_id != 5) {
                $newAverageMonth->sucursal_id = $id_s;
            }
            $newAverageMonth->save();
        }
    }

    public function notAccepted()
    {
        $countOrders = Order::where('order_state_id', 1)->where('gw_state', 'CONFIRMED')->where('store_type', 'academy')->count();

        if ($countOrders) {
            return array('r' => true, 'c' => $countOrders);
        } else {
            return array('r' => false);
        }
    }

    public function testPusher()
    {
        event(new NewOrderEvent("traslado app 2", 5, 4));
    }

    public function clickDeleteOrder(Request $request)
    {
        $order = Order::where('id', $request["id"])->first();
        $order->gw_state = 'CONFIRMED';
        $order->update();

        if ($order->order_state_id == 7) {
            $order->delete();
            $data = array('status' => 'success', 'id' => $request["id"]);
            return response()->json($data);
        } else {
            $data = array('status' => 'El pedido debe estar Cancelado para poder eliminarse', 'id' => $request["id"]);
            return response()->json($data);
        }
    }

    public function deleteOrder($code)
    {
        if ($order = Order::where('code', $code)->first()) {
            $order->delete();
        }
    }

    public function sendOrderStatusChangeNotificationToUser($order, $client, $state)
    {
        if (!$client) {
            $client = User::find($order->client_id);
        }
        if (!$state) {
            $state = OrderState::find($order->order_state_id);
        }
        if ($order && $client && $state && $order->order_type_id == 5 && $client->pns_id != null) {
            if (Cache::get($order->code . '_' . strtolower($state->name) . '_notified')) {
                return;
            }
            $message = __('messages.screen_orders_tag23', ['fullname' => $client->first_name . ' ' . $client->last_name, 'store' => config('app.name'), 'code' => $order->code, 'state' => $state->name]);
            $this->notificationsController->createSystemNotification(
                $message,
                $client->id
            );

            Cache::put($order->code . '_' . strtolower($state->name) . '_notified', true, config('cache.time'));
        }
    }

    public function updatePendingStatusOrder($order, $short_order_id = false, $add_time = false)
    {
        $add_time_text = $add_time ? '_' . microtime(true) : '';
        $order->gw_code_transaction = strtoupper(hash("md5", $order->id)) . '_' . $order->code . $add_time_text;

        if ($short_order_id) {
            $order->gw_code_transaction = $order->code;
        }

        $order->gw_state = 'PENDING';
        $order->update();
    }

    public function updateOrderByPaymentReference(
        $paymentReference,
        $paymentState,
        $orderStateId,
        $paymentComment,
        $paymentTransactionId
    ) {
        $order = Order::with('client', 'client.documentType', 'client.userInfo')
            ->when($paymentReference, function ($query) use ($paymentReference) {
                return $query->where('gw_code_transaction', $paymentReference);
            })
            ->when($paymentTransactionId, function ($query) use ($paymentTransactionId) {
                return $query->orWhere('payment_transaction_id', $paymentTransactionId);
            })
            ->first();

        if ($order == null || $order->gw_state == $paymentState) {
            return false;
        }

        $order->gw_state = $paymentState;
        $order->order_state_id = $orderStateId;
        $order->payment_comment .= ($order->payment_comment ? ', ' : '') . $paymentComment;
        $order->payment_transaction_id = $paymentTransactionId;
        $order->gw_code_transaction = $paymentReference;
        $order->update();

        if ($paymentState == 'CONFIRMED') {
            $this->orderService->dispatchOrderProcesses($order);
            $this->syncERP($order);
        } else if ($paymentState != 'PENDING') {
            $this->runInventory($order->id, 'sum', '', true);
        }

        $this->sendOrderStatusChangeNotificationToUser($order, null, null);

        return true;
    }


    public function getOrderByPaymentReference($payment_reference)
    {
        return Order::where('gw_code_transaction', $payment_reference)->first();
    }

    public function validatePayments($validateHistoricalPayments = false)
    {
        $confirmedOrders = Order::where([['gw_state', 'CONFIRMED'], ['order_state_id', 1]])->get();
        Order::where([['gw_state', 'CONFIRMED'], ['order_state_id', 1]])->update(['order_state_id' => 2]);

        foreach ($confirmedOrders as $order) {
            $this->sendOrderStatusChangeNotificationToUser($order, null, null);
        }

        $now = Carbon::now();
        $ordersPending = Order::where('gw_state', '!=', 'CONFIRMED')->whereNotNull('gateway_payments_id')
            ->where(function ($query) use ($validateHistoricalPayments, $now) {
                if ($validateHistoricalPayments) {
                    $query->where('creation_date', '>', $now->subDays(3)->startOfDay());
                } else {
                    $query->where(function ($query) use ($now) {
                        $query->where('payment_attempts', '<', config('payment_gateway.attempts'))
                            ->orWhere('creation_date', '>', $now->subHours(3));
                    });
                }
            })
            ->get();

        foreach ($ordersPending as $order) {
            try {
                $this->orderService->validatePayment($order);
            } catch (\Throwable $th) {
                $error = [
                    'order'                 => $order,
                    'message'               => $th->getMessage(),
                    'getFile'               => $th->getFile(),
                    'getLine'               => $th->getLine(),
                ];
                $util = new UtilController;
                $util->logFile(json_encode($error));
            }
        }

        return array(
            'r' => true,
            'data' => null,
            'm' => 'Se validaron ' . count($ordersPending) . ' pagos pendientes.'
        );
    }

    public function validatePayment($order)
    {
        $order->payment_attempts = $order->payment_attempts + 1;
        $order->update();
        $this->orderService->validatePayment($order);
    }

    public function notificationByMailClientOrder($order_id, $myOrder)
    {
        $order = Order::with('client')->find($order_id);
        if ($order->gw_state == 'CONFIRMED' && $order->status_notification_email_client == 'pending') {
            // ENVIO EMAIL A CLIENTE
            $email = $order->client->email;
            $emailDeliveryStatus = $this->sendOrderMailClient($email, $myOrder);
            if ($emailDeliveryStatus) {
                $order->status_notification_email_client = 'send';
                $order->update();
            }
        }
    }

    private function sendOrderMailClient($email, $order)
    {
        try {
            event(new NewOrderCreateClient($email, $order));
            return true;
        } catch (Exception $e) {
            $error = [
                'email'                 => $email,
                'order'                 => $order,
                'message'               => $e->getMessage(),
                'getFile'               => $e->getFile(),
                'getLine'               => $e->getLine(),
            ];
            $util = new UtilController();
            $util->logFile(json_encode($error));
            return false;
        }
    }

    public function confirmSyncERP($order_reference)
    {
        $order = Order::where('order_reference', $order_reference)->first();
        if ($order) {
            $order->sync_with_erp = true;
            $order->update();
        }
    }

    public function confirmSyncERPWithId($orderId)
    {
        $order = Order::where('id', $orderId)->first();
        if ($order) {
            $order->sync_with_erp = true;
            $order->update();
        }
    }

    public function validateSyncWithERPPayment($code)
    {
        $order = Order::select('sync_with_erp')->where('code', $code)->first();
        if (!$order) {
            return true;
        }

        return !$order->sync_with_erp;
    }

    public function validateSyncWithERPPaymentWithId($orderId)
    {
        $order = Order::select('sync_with_erp')->where('id', $orderId)->first();
        if (!$order) {
            return true;
        }

        return !$order->sync_with_erp;
    }

    public function getOrderByReference($order_reference)
    {
        return Order::where('order_reference', $order_reference)->first();
    }


    public function syncERP($order, $action = null)
    {
        try {
            $erps = Erp::select('id', 'class')->where('active', true)->get();
            foreach ($erps as $index => $erp) {
                $classPath = $erp->class;
                $ERPRepository = new $classPath($erp->id);

                $reference = $this->ERPPrefix . $order->id;
                $erpService = new ErpService;

                //Si la orden ya esta sincronizada con el ERP no se sincroniza
                if (!$this->validateSyncWithERPPaymentWithId($order->id)) {
                    return;
                }

                //Si la sincronización esta deshabilitada no se sincroniza y guarda el log
                $erpSync = ErpParameter::where('key', 'academy_sync')->first();
                if (!$erpSync || $erpSync->value == 'false') {
                    $this->saveERPLog($order->id, 'Sinc ERP deshabilitada', 'syncERP');
                    return;
                }

                //Si la orden ya se esta procesando no se sincroniza y guarda el log
                if ($erpService->isSynchronizingWithERP($reference)) {
                    $this->saveERPLog($order->id, 'Sincronizando en otro proceso', 'syncERP');
                    return;
                }

                //validar si ya tiene una factura en el ERP
                $previousBill = $ERPRepository->hasPreviousBill($reference);
                if ($previousBill['r']) {

                    $this->confirmSyncERPWithId($order->id);
                    continue;
                }

                $erpService->synchronizing($reference);

                switch ($action) {
                    case 'createOrder':
                        $this->createOrderERP($order, $ERPRepository);
                        break;
                    case 'createRC':
                        $this->createRCERP($order, $ERPRepository);
                        break;
                    case 'createBill':
                        $this->createBillERP($order, $ERPRepository);
                        break;
                    default:
                        $this->createThirdClientERP($order, $ERPRepository);
                        break;
                }
            }
        } catch (Exception $e) {
            $error = [
                'message'               => $e->getMessage(),
                'getFile'               => $e->getFile(),
                'getLine'               => $e->getLine(),
            ];
            $this->saveERPLog($order->id, json_encode($error), 'syncERP');
        }
    }

    private function createThirdClientERP($order, $ERPRepository)
    {
        $addressObj = Address::with('city')->where('id', $order->address_id)->first();
        if (!$addressObj) {
            $address   = 'Calle 90 #19-41';
            $shortAddress  = $address;
            $country    = 'Colombia';
            $province   = 'Bogotá';
            $city       = 'Bogotá, D.C.';
        } else {
            $address   = $addressObj->direction . ' | ' . $addressObj->district;
            $shortAddress  = $addressObj->direction;

            if ($addressObj->city) {
                $country    = $addressObj->city->state->country->name;
                $province   = $addressObj->city->state->name;
                $city       = $addressObj->city->name;
            }
        }

        $user = $order->client;
        $siesaThirdClient = $ERPRepository->thirdClientValidate($user->document);

        $params = new \stdClass();
        $third  = new \stdClass();
        $client = new \stdClass();

        $third->document            = $user->document;
        $third->firstName           = $user->first_name;
        $third->lastName            = $user->last_name;
        $third->contact             = $user->last_name . ' ' . $user->first_name;
        $third->phone               = $user->phone;
        $third->email               = $user->email;
        $third->isNew               = count($siesaThirdClient) == 0;
        $third->documentType        = $ERPRepository->mapDocumentType($user->documentType->alias);
        $third->birthDate           = Carbon::parse($user->userInfo->dob)->format('Ymd');
        $third->typeThird           = 'NATURAL_PERSON';
        $third->gender              = $ERPRepository->mapGender($user->userInfo->sex);
        $third->socialReason        = $third->contact;
        $third->establishmentName   = $third->contact;
        $third->ciiu                = null;

        $academyUser = AcademyUser::where('user_id', $order->client_id)->first();
        $client->document       = $academyUser->identification;
        $client->contact        = $academyUser->student_last_name . ' ' . $academyUser->student_name;
        $client->phone          = $academyUser->phone;
        $client->email          = $academyUser->mail;

        $params->third          = $third;
        $params->client         = $client;
        $params->address        = $address;
        $params->shortAddress   = $shortAddress;
        $params->country        = $country ?? null;
        $params->province       = $province ?? null;
        $params->city           = $city ?? null;
        $params->sucursal       = '002';
        $params->price_list     = '012';
        $params->typeClient     = 'CACD';
        $params->postal         = '';
        $params->hasTaxes       = '1';
        $params->createThirdPos = true;
        $params->idCriteria     = '101';
        $params->criteria       = '1012';
        $params->currency       = 'COP';
        $params->latitude       = $addressObj ? $addressObj->lat : null;
        $params->longitude       = $addressObj ? $addressObj->long : null;

        $response = $ERPRepository->createThirdClient($params);

        if (!$response['r']) {
            $this->saveERPLog($order->id, json_encode($response['d']), 'createThirdClient');
            return;
        }
        $this->createOrderERP($order, $ERPRepository);
    }

    private function createOrderERP($order, $ERPRepository)
    {
        $response = $ERPRepository->getOrder('AS' . $order->id);
        if ($response['r']) {
            $previousOrders = array_filter($response['d']->detalle->Table, function ($siesaOrder) use ($order) {
                return str_contains($siesaOrder->Notas, $order->gw_code_transaction);
            }, ARRAY_FILTER_USE_BOTH);

            if (count($previousOrders)) {
                $this->createRCERP($order, $ERPRepository);
                return;
            }
        }

        $orderParams                    = new \stdClass();
        $orderParams->operationCenter   = '017';
        $orderParams->document          = $order->client->document;
        $orderParams->sucursal          = '002';
        $orderParams->date              = Carbon::parse($order->creation_date)->format('Ymd');
        $orderParams->customerType      = 'CACD';
        $orderParams->note              = $order->gw_code_transaction;
        $orderParams->priceDiscount     = 0;
        $orderParams->discount          = 0;
        $orderParams->reference         = 'AS' . $order->id;

        $orderProducts = OrderProduct::with('orderProductAttributes', 'product', 'product.productAttributes')
            ->where('order_id', $order->id)
            ->get();

        $items = [];
        $discounts = [];
        foreach ($orderProducts as $index => $item) {
            if (count($item->orderProductAttributes) > 0) {
                $orderProductAttribute =  $item->orderProductAttributes[0];
                $productAttribute = ProductAttribute::select('sku')
                    ->where('product_id', $item->product_id)
                    ->where('attribute_id', $orderProductAttribute->attribute_id)
                    ->where('value', $orderProductAttribute->value)
                    ->first();
            } else {
                $productAttribute = $item->product->productAttributes[0];
            }

            if (!$productAttribute || !$productAttribute->sku) {
                $this->saveERPLog(
                    $order->id,
                    'El producto ' . $item->products->name . ' no tiene referencia',
                    'createOrder'
                );
                return;
            }

            $orderItem = array(
                'f431_id_co'                => $orderParams->operationCenter,
                'f431_consec_docto'         => '1',
                'f431_nro_registro'         => ($index + 1),
                'f431_referencia_item'      => '',
                'f431_codigo_barras'        => $productAttribute->sku,
                'f431_id_bodega'            => 'AC017',
                'f431_id_motivo'            => '06',
                'f431_id_co_movto'          => $orderParams->operationCenter,
                'f431_id_un_movto'          => '100',
                'f431_id_ccosto_movto'      => '3001',
                'f431_fecha_entrega'        => $orderParams->date,
                'f431_id_lista_precio'      => '022',
                'f431_id_unidad_medida'     => 'UND',
                'f431_cant_pedida_base'     => $item['quantity'],
                'f431_precio_unitario'      => $item->product->price,
                'f431_ind_precio'           => '2',
                'f431_ind_obsequio'         => '0',
                'f431_ind_impto_asumido'    => '0'
            );

            array_push($items, $orderItem);

            if ($item->product->percentage_discount) {
                $discount = array(
                    'f430_id_co'                => $orderParams->operationCenter,
                    'f430_consec_docto'         => '1',
                    'f431_nro_registro'         => ($index + 1),
                    'f432_tasa'                 => $item->product->percentage_discount,
                    'f432_vlr_uni'              => 0,
                );
                array_push($discounts, $discount);
            }
        }

        $orderParams->items = $items;
        $orderParams->discounts = $discounts;

        $response = $ERPRepository->createOrder($orderParams);
        if (!$response['r']) {
            $this->saveERPLog($order->id, json_encode($response['d']), 'createOrder');
            return;
        }
        $inventoryController = new AcademyStoreInventoryController;
        $inventoryController->sync();
        $this->createRCERP($order, $ERPRepository);
    }

    private function createRCERP($order, $ERPRepository)
    {
        $response = $ERPRepository->getOrder('AS' . $order->id);
        if (!$response['r']) {
            $this->saveERPLog($order->id, json_encode($response['d']), 'createRC');
            return;
        }

        foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
            $response = $ERPRepository->getRC($order->client->document, '017');
            if ($response['r']) {
                $previousRC = array_filter($response['d']->detalle->Table, function ($item) use ($order) {
                    return str_contains($item->Notas, $order->gw_code_transaction) && $item->TotalRecibo == $order->total_price;
                }, ARRAY_FILTER_USE_BOTH);

                if (count($previousRC)) {
                    $this->createBillERP($order, $ERPRepository);
                    continue;
                }
            }

            $parameters = new \stdClass();
            $parameters->paymentDate = Carbon::parse($order->creation_date)->format('Ymd');
            $parameters->idThird = $order->client->document;
            $parameters->currency = 'COP';
            $parameters->siesaOrder = $siesaOrder;
            $parameters->fe = '1105';
            $parameters->note = $order->gw_code_transaction;
            $parameters->assistant = '28050502';
            $parameters->sucursal = '002';
            $parameters->paymetMethod = 'WAC';
            $parameters->UN = '100';
            $parameters->price = $order->total_price;

            $response = $ERPRepository->createRC($parameters);
            if (!$response['r']) {
                $this->saveERPLog($order->id, json_encode($response['d']), 'createRC');
                return;
            }
            $this->createBillERP($order, $ERPRepository);
        }
    }

    private function createBillERP($order, $ERPRepository)
    {
        $response = $ERPRepository->getOrder('AS' . $order->id);
        if (!$response['r']) {
            $this->saveERPLog($order->id, json_encode($response['d']), 'createBill');
            return;
        }

        foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
            $parameters = new \stdClass();
            $parameters->siesaOrder     = $siesaOrder;
            $parameters->thirdDocument  = $order->client->document;
            $parameters->note           = $order->gw_code_transaction;
            $parameters->price          = $order->total_price;
            $parameters->typeDocument   = 'FE1';

            $response = $ERPRepository->createBill($parameters);
            if (!$response['r']) {
                $this->saveERPLog($order->id, json_encode($response['d']), 'createBill');
                return;
            }
        }
        $this->confirmSyncERPWithId($order->id);
    }

    public function saveERPLog($data, $message, $action)
    {
        $transactionId = $data;
        ErpLog::updateOrCreate(
            [
                'origin'         => 'shop_sportscrowd',
                'transaction_id' => $transactionId,
                'resolved'       => false
            ],
            [
                'origin'         => 'shop_sportscrowd',
                'action'         => $action,
                'origin_class'   => get_class($this),
                'data'           => $data,
                'transaction_id' => $transactionId,
                'message'        => $message,
            ]
        );
    }

    public function retrySyncERP($data, $action)
    {
        $this->syncERP(Order::find($data), $action);
    }

    function syncInventoryWithOutStock($siesaInventory, $storeType)
    {
        $productAttributes = ProductAttribute::select(
            'product_attributes.id',
            'product_attributes.sku',
            'product_attributes.available_units'
        )
            ->join('products', 'products.id', '=', 'product_attributes.product_id')
            ->where('products.store_type', $storeType)
            ->where('product_attributes.available_units', '>', 0)
            ->get();

        foreach ($productAttributes as $index => $item) {
            if (!$item->sku) {
                continue;
            }

            $siesaProducts = array_filter($siesaInventory, function ($productVariant) use ($item) {
                return $productVariant->CodigoDeBarras == $item->sku;
            }, ARRAY_FILTER_USE_BOTH);

            if (!count($siesaProducts)) {
                $item->available_units = 0;
                $item->update();
            }
        }
    }

    public function validateMails()
    {
        $parameters = Parameter::select('id', 'mailing_inventory')->first();
        if ($parameters->mailing_inventory) {
            $orders = Order::select('id', 'code')
                ->where('status_notification_email_client', 'pending')
                ->where('creation_date', '>', Carbon::now()->subDays(3))
                ->get();
            foreach ($orders as $order) {
                $this->sendNotifications($order);
            }
        }
    }
}