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/agile-selling-wpb/app/Http/Controllers/OrderController.php
<?php

namespace App\Http\Controllers;

use App\Address;
use App\AverageMonth;
use App\AverageTime;
use App\BoCashAccount;
use App\BoSpecialPrice;
use App\City;
use App\Comment;
use App\CorporateIdentity;
use App\Events\ChangeStateEvent;
use App\Events\NewOrderEvent;
use App\Events\OrderPendingEvent;
use App\Events\OrderReassignmentEvent;
use App\Events\OrderStateEvent;
use App\Events\NewOrderCreate;
use App\Evidence;
use App\GatewayPayment;
use App\Http\Controllers\AddressController;
use App\Http\Controllers\PushNotificationController;
use App\LineBusiness;
use App\Mail\TransferMail;
use App\Order;
use App\ProductAttribute;
use App\Product;
use App\OrderProduct;
use App\OrderState;
use App\OrderType;
use App\Parameter;
use App\PaymentType;
use App\TopTenProduct;
use App\SalesChannel;
use App\Subcategories;
use App\Sucursal;
use App\Transfer;
use App\User;
use App\Discount;
use App\DiscountOrderUser;
use App\DiscountProductUser;
use App\UserInformation;
use App\Coverage;
use App\PaymentsHistory;
use App\OrderProductAttributes;
use Carbon\Carbon;
use Datatables;
use DateTime;
use DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use \Excel;
use App\Http\Controllers\WorldPayController;
use App\Http\Controllers\Exports\ReportOrders;
use Illuminate\Support\Collection;
use App\Http\Controllers\ShopifyController;
use App\ReturnDetail;
use App\ReturnHeader;
use stdClass;
use Lang;
use Illuminate\Database\Eloquent\Builder;

class OrderController extends Controller
{
    public function __construct(Request $request)
    {
        $this->middleware('auth');
        // $this->middleware(function ($request, $next) {
        //     $this->user = Auth::user();
        //     if (Auth::user()->rol->id == 1 || Auth::user()->rol->id == 6) {
        //         $this->changeDbDefault($request);
        //     }
        //     return $next($request);
        // });
    }

    public function updateNumberPackage($id, $id_state, $number_Package)
    {
        $logObj = Order::find($id);

        if ($logObj->order_state_id == 7) {

            return array('r' => false, 'm' => 'El pedido se encuentra cancelado, no es posible continuar con la operación.');
        } else {
            Order::where('id', $id)->update(array('number_packages' =>$number_Package));
            event(new OrderStateEvent($id, $id_state));
            return array('r' => true);
        }
    }

    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::find(1);
        return view('orders.addOrder')
            ->with('types', $order_types)
            ->with('parameter', $parameter)
            ->with('order_id', $order_id)
            ->with('order', $order);
    }

    public function indexAdmin($code_client = '0',$code_plu = '0')
    {
        $sucursal = Auth::user()->userInfo->sucursal->id;
        $rol = Auth::user()->rol->id;
        $from = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - 7, date("Y")));
        $to = new DateTime();

        $parameter = Parameter::all();
        $parameter = $parameter->last();

        // if ($rol == 1 || $rol == 6) {
            $orders = Order::orderBy('creation_date', 'DESC')->whereBetween('creation_date', [$from . " 00:00:00", $to])->get();
        // } else {
        //     $orders = Order::where('sucursal_id', $sucursal)->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('code_client', $code_client)
            ->with('code_plu', $code_plu);
    }

    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::all();
        $parameter = $parameter->last();

        $evidences = Evidence::where('order_id', $id)->get();

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

    public function tableFilter($code_client,$code_plu)
    {
        $obj = Order::with(['client','orderState','address','sucursal','deliveryMan','orderProducts'])
                    ->whereNull('deleted_at')
                    ->orderBy('creation_date', 'desc');
        if($code_client != '0' && $code_plu != '0'){
            $product = Product::select('id')->where('plu', $code_plu)->first();
            $obj = $obj->whereHas('client', function (Builder $query) use($code_client) {
                $query->where('document', $code_client);
            });

            $obj = $obj->whereHas('orderProducts', function (Builder $query) use($product) {
                $query->where('product_id', $product->id);
            });
        }
        return Datatables::of($obj)
        ->addColumn('actions', function ($obj) {
            if(Auth::user()->rol_id == 1 || Auth::user()->rol_id == 2 || Auth::user()->rol_id == 8){
                if ($obj->orderState->id == 5 || $obj->orderState->id == 6) {
                    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-print iconMini " onClick="clickCommand(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Imprimir"></i>
                            <i class="fa fa-file-picture-o iconMini " onClick="clickEvidence(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Evidencias"></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>';
                }
            } else if(Auth::user()->rol_id == 7){
                if ($obj->orderState->id == 5 || $obj->orderState->id == 6) {
                    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-print iconMini " onClick="clickCommand(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Imprimir"></i>
                            <i class="fa fa-file-picture-o iconMini " onClick="clickEvidence(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Evidencias"></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-file-picture-o iconMini " onClick="clickEvidence(' . $obj->id . ')" data-id="' . $obj->id . '"  title="Evidencias"></i>';
                }
            }
        })
        ->editColumn('gw_state', function($obj){
            if($obj->payment_type_id == 5){
                if($obj->gw_state == 'CONFIRMED'){
                    return '<span class="label label-success">Pago REF:' . $obj->gw_code_transaction . '</span>';
                }else{
                    return '<span class="label label-danger">PENDIENTE REF:' . $obj->gw_code_transaction . '</span>';
                }
            }else{
                return "N/A";
            }
        })
        ->rawColumns(['actions', 'gw_state'])
        ->make(true);
    }

    public function getForm(Request $request)
    {

        $type = OrderType::find($request["id"]);
        $parameter = Parameter::all();
        $parameter = $parameter->last();
        $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)->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 dechex(time()) . "-" . rand(1, 9) . rand(1, 5);
    }

    public function create(Request $request)
    {
        $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:
                $response = $this->createOrderEcommerce($request);
                break;
        }
        return $response;
    }

    public function changeProductOrder(Request $request)
    {
        try {
            $order = Order::select('id','client_id','code','subtotal','total_price')->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();

            if ($client->pns_id != null) {
                $push = new PushNotificationController();
                $push->sendToUser('Se ha reemplazado un producto de tu orden: ' . $order->code, $client->pns_id, null, null, null, null, 'U');
            }

            $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);
        }
    }

    // Proceso para generar la orden tipo ecommerce de Agile Selling
    public function createOrderEcommerce($request)
    {
        DB::beginTransaction();
        try {
            $data = $request->data;
            foreach ($data["products"] as $key => $product) {
                $current_product = Product::where('id', $product["id"])->first();
                $current_product_attribute = ProductAttribute::where('product_id', $product["id"])->with('attribute')->get();
                $quantity_products = intval($current_product->available_units) - intval($current_product->dispatched_units);
                if(!$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 $key3 => $attribute) {
                        foreach ($current_product_attribute as $key2 => $current_attribute) {
                            if($current_attribute->id == $attribute["id"]){
                                $quantity_products_attributes = intval($current_attribute->available_units) -intval($current_attribute->dispatched_units);
                                if(!$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() && !isset($data["origin"])){
                $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"];
            }

            $parameter = Parameter::where('id', 1)->select('sucursal_products','is_automatic_bag','automatic_bag_value','discount_inventory_state_id', 'prefix_code')->first();

            $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 = $parameter->prefix_code . $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 = number_format($data["subtotal"], 2, '.', '');
            $order->tax = number_format($data["tax"], 2, '.', '');
            $order->total_price =  number_format($data["total"], 2, '.', '');
            $order->cost_delivery = number_format($data["priceDomicile"], 2, '.', '');
            $order->discount_price = isset($data["discount"]) ? number_format($data["discount"], 2, '.', '') : null;
            $order->discount_delivery = isset($data["discountDelivery"]) ? number_format($data["discountDelivery"], 2, '.', '') : null;
            $order->order_reference = isset($data["order_reference"]) ? $data["order_reference"] : null;
            $order->sucursal_id = isset($data["sucursal"]) ? $data["sucursal"] : null;
            $order->not_found = $data["productsNotFound"];
            $order->phone = $data["confirmOrder"]["cellphone"];
            $order->creation_date = Carbon::now();
            $order->order_state_id = 1;
            $order->payment_type_id = $data["confirmOrder"]["wayPay"];
            $order->order_type_id = $data["order_type_id"];
            $order->bo_shipping_type_id = $data["bo_shipping_type_id"];
            $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;
            $order->bo_business_place_id = $data["bo_business_place_id"];
            $order->admin_id = $data['origin'] == 'pos' ? Auth::user()->id : null;
            $order->bo_purchase_order = isset($data["purchase_order_customer"]) ? $data["purchase_order_customer"] : '';

            if($data["bo_shipping_type_id"] == 2){
                $order->bo_delivery_date = $data["delivery_date"];
            }

            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 == 1 || $rol == 2 || $rol == 6) { // si es creado desde el panel
            if ($rol != 4) { // si es creado desde el panel
                $order->client_id = $idClient;
                $order->admin_id = $data['origin'] == 'pos' ? Auth::user()->id : null;
                $dReferred = $data["dReferred"];
                $dCoupone = $data["dCoupone"];
                $dCampana = $data["dCampana"];
            } else { // si es creado desde el app
                $order->client_id = $user_id;

                // Valido si usa balance
                if($data["useAccountBalance"]){
                    $returnInfoBalance = $this->determineValueToPay($order->total_price, $user_id, $order->payment_type_id);
                    $order->instructions = $order->instructions . " " . $returnInfoBalance['msg'];
                    $order->bo_balance_used = $returnInfoBalance["balance_used"];
                }
            }

            if($order->paymnent_type_id == 6){
                $order->bo_check_number = $data['check_number'];
            }

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

            // Pago online.
            if ($order->payment_type_id == 4) {
                // Buscar pasarela activa.
                // $gw = GatewayPayment::where('active', true)->select('id', 'name')->first();
                //
                // if (!$gw) {
                //     $r = array('m' => 'No se encuentra disponible nuestra pasarela de pago en el momento, por favor intenta mas tarde.');
                //     return response()->json($r, 500);
                // }
                //
                // $order->gw_state = 'PENDING';
                // $order->gw_name = $gw->name;

                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){
                    // $bag = Product::where('plu', '123456789')->first();
                    // $orderProduct = new OrderProduct();
                    // $orderProduct->quantity = 1;
                    // $orderProduct->price_bruto = $bag->price;
                    // $orderProduct->price = $bag->price;
                    // $orderProduct->comments = null;
                    // $orderProduct->flash_price = null;
                    // $orderProduct->percentage_discount = null;
                    // $orderProduct->max_units_per_order = null;
                    // $orderProduct->order_id = $order->id;
                    // $orderProduct->product_id = $bag->id;
                    // $orderProduct->save();

                    $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->modifyQuanityProductDispatched($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->modifyQuanityProductAttributesDispatched($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 = number_format($product["price"], 2, '.', '');
                    $orderProduct->price = number_format($product["priceTotal"], 2, '.', '');
                    $orderProduct->flash_price = number_format($valuePriceAfterFlash, 2, '.', '');
                    $orderProduct->percentage_discount = $valuePriceAfterDiscount;
                    $orderProduct->comments = isset($product["comments"]) ? $product["comments"] : null;
                    $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->bo_item_code = $product["plu"];
                    $orderProduct->bo_warehouse_code = $data["bo_warehouse_code"];
                    $orderProduct->bo_item_tax_code = $data["bo_item_tax_code"];
                    $orderProduct->save();

                    $inTopTen = new TopTenProduct();
                    $inTopTen->setConnection("global-db");
                    $topTenUpdate = $inTopTen->where([['plu', $product["plu"]],['user_id', $order->client_id]])->first();

                    if(isset($topTenUpdate->id)){
                        $topTenUpdate->quantity = $topTenUpdate->quantity + $product["quantity"];
                        $topTenUpdate->update();
                    }else{
                        $topTenProduct = new TopTenProduct();
                        $topTenProduct->setConnection("global-db");
                        $topTenProduct->quantity = $product["quantity"];
                        $topTenProduct->product_id = $product["id"];
                        $topTenProduct->user_id = $order->client_id;
                        $topTenProduct->plu = $product["plu"];
                        $topTenProduct->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 ($order->payment_type_id == 4) {
                //     if ($data["confirmOrder"]["tdc"] != 0) {
                //       $worldpay = new WorldPayController;
                //       $worldpay->authorizeChargeUser($order);
                //     }
                // }

                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')->first();
                $infoProducts = OrderProduct::where('order_id', $order->id)->with('products')->with('products.brand')->get();
                $infoOrder->products = $infoProducts;

                // Validar pago con Ebiz si es tarjeta de credito.
                if($data['cc_payment_method_id']){
                    $order->bo_reference_number_pay   = $data['RefNum'];
                    $order->bo_authorization_code_pay = $data['AuthCode'];
                    $order->bo_result_code_transaction = $data['ResultCode'];
                    $order->bo_state_transaction = "authonly-" . date('Y-m-d H:i:s');

                    $order->bo_credit_card_number = $data['cc_number'];
                    $order->bo_credit_card_expiration = $data['cc_expiration'];
                    $order->bo_credit_card_type = $data['cc_card_type'];
                    $order->update();
                }

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

                // Envio de notificaciones
                $parameters = Parameter::where('id', 1)->select('id', 'db_city')->first();
                $push = new PushNotificationController();

                // Se cambia el envío por segmentos
                // $push->sendToSegments(Lang::get('messages.delivery_message'), 'delivery-' . strtolower($parameters->db_city) . '-' . env('APP_CLIENT'), null, null, null, null, 'D');
                $tags = array(
                    ["field" => "tag", "key" => "rol", "relation" => "=", "value" => "3"],
                    ["field" => "tag", "key" => "city", "relation" => "=", "value" => $parameters->db_city],
                    ["field" => "tag", "key" => "client", "relation" => "=", "value" => env("ONESIGNAL_LAMBDA_NAME")]
                );
                $push->sendToSegment(Lang::get('messages.delivery_message'), $tags, null, null, null, null, "D");

                // event(new OrderPendingEvent($order->code, $order->id));
                $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();
                    }
                    $this->successCreateOrder($order->id,$parameter->discount_inventory_state_id);
                    return array('r' => true, 'id' => $order->id, 'code' => $order->code);
                } else {
                    $this->successCreateOrder($order->id,$parameter->discount_inventory_state_id);
                    return response()->json($data, 200);
                }
            }
            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.', 'order' => null, 'data' => $th->getMessage());
            return response()->json($data, 400);
        }
    }

    public function object_to_array($data)
    {
        if (is_array($data) || is_object($data))
        {
            $result = [];
            foreach ($data as $key => $value)
            {
                $result[$key] = (is_array($data) || is_object($data)) ? $this->object_to_array($value) : $value;
            }
            return $result;
        }
        return $data;
    }

    public function getAuthorizeFoundsToOrder(Request $request)
    {
        // Si se envia tarjeta y token del cliente, validar pago con Ebiz.
        if($request['cc_payment_method_id'] && $request['cc_customer_id']){
            $forceValue = null;
            if($request['useAccountBalance']){
                $returnInfoBalance = $this->determineValueToPay($request["order"]["total_price"], $request["user_id"], $request["payment_type_id"]);
                $request->merge(['order.bo_balance_used' => $returnInfoBalance["balance_used"]]);
                $forceValue = $returnInfoBalance['to_pay'];
            }
            $resultTransaction = $this->authorizeFoundsToOrder(null, $request['cc_payment_method_id'], $request['cc_customer_id'], $forceValue, $request["order"]);

            if(!$resultTransaction['status']){
                DB::rollback();
                $data = array('status' => 'error_ebiz', 'm' => 'Error authorizing funds.', 'order' => null, 'data' => $resultTransaction);
                return response()->json($data, 200);
            }

            // Validar estado de la transacción siempre debe ser A.
            if($resultTransaction['o']->result->ResultCode != "A"){
                DB::rollback();
                $data = array('status' => 'error_ebiz', 'm' => 'Error transaction invalid for this credit card', 'order' => null, 'data' => $resultTransaction);
                return response()->json($data, 200);
            }


            if(isset($resultTransaction['o'])){ // Para el caso en que se pague con TC pero no sea neceario autorizar fondos, si se paga con account balance del usuario.
                $data = array('status' => 'success', 'm' => '', 'data' => $resultTransaction);
                return response()->json($data, 200);
            }
        }
        $data = array('status' => 'error_ebiz', 'm' => 'Error validating credit card funds');
        return response()->json($data, 200);
    }

    public function successCreateOrder($order_id,$discount_inventory_state_id){
        DB::commit();
        // Enviar email de nuevo pedido
        $current_order = $this->getOrder($order_id);
        // event(new NewOrderCreate($current_order));

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

    public function authorizeFoundsToOrder($order_id, $payment_method_id, $customer_token, $force_value, $custom_order = null)
    {
        $ebizController = new EbizChargeController;
        $data = new stdClass();
        $data->type_transaction = "authonly";
        $data->payment_method_id = $payment_method_id;
        $data->customer_token = $customer_token;
        if($order_id !== null){
            $data->order = Order::where('id', $order_id)->with('orderProducts')->first();
        }else{
            $data->order =  Order::make($custom_order);
        }

        return $ebizController->runTransaction($data, $force_value);
    }

    public function modifyQuanityProduct($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 modifyQuanityProductDispatched($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){
        $sho = new ShopifyController();
        $sho->updateInventoryLevel($reference_shopify_variation_id,$quantity);
    }

    public function modifyQuanityProductAttributes($attributes,$quantity,$action,$product_id,$updateExternalECInventory = false)
    {
        foreach ($attributes as $key => $attribute) {
            $current_product_attribute = ProductAttribute::select('id','available_units','reference_shopify_variation_id')
                                ->where('product_id', $product_id)
                                ->where('attribute_id', $attribute->attribute_id)
                                ->where('value', $attribute->value)
                                ->first();
            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($updateExternalECInventory){
                $this->updateQuantityShopify($current_product_attribute->reference_shopify_variation_id,$sho_quantity);
            }
            $current_product_attribute->update();
        }
    }

    public function modifyQuanityProductAttributesDispatched($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($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::where('id', 1)->select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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'));
            }
        }
        // dd(Auth::user()->userInfo->sucursal->mail);
        $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::where('id', 1)->select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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::where('id', 1)->select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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::where('id', 1)->select('id', 'db_city')->first();
            $push = new PushNotificationController();
            $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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::where('id', 1)->select('id', 'db_city', 'db_name','sucursal_products')->first();
        $sucursal_id = null;
        if($parameters->sucursal_products){
            $sucursal_id = $request["sucursal"];
        }
        $accountInfo = array(
            'rol'           => 4, // Rol para cliente
            '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"],
                'identificationCard'    => $request["document"],
                'sucursal_id'           => $sucursal_id,
            ),
        );

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

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

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

        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', 'orderState')->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)->get();
        $parameter = Parameter::find(1);

        $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::where('id', 1)->select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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::where('id', 1)->select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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::where('id', 1)->select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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::where('id', 1)->select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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) {
                $push = new PushNotificationController();
                $push->sendToUser('Se han agregado productos a tu orden: ' . $order->code, $client->pns_id, null, null, null, null, 'U');
            }

            $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;
        $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(count($request->addProducts)){
            $this->addProductOrder($request);
        }

        // $order->order_state_id = $data["order_state_id"];
        $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"] == '') {
                $dataPusher = $order->code;
                $parameters = Parameter::where('id', 1)->select('id', 'db_city')->first();
                $push = new PushNotificationController();
                $push->sendToSegments('Nuevo pedido disponible', 'delivery-' . strtolower($parameters->db_city) . '-' . env('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->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::where('id', $id)->with('address.city.state.country')->with('discountOrderUser','point_sale','paymentType','client', 'orderType', 'orderProducts', 'deliveryManAccepted', 'deliveryManCollected', 'deliveryManDeliver')->first();
        $transfers = Transfer::where('order_id', $id)->get();
        $products = OrderProduct::where('order_id', $id)->with('product','orderProductAttributes')->get();
        $parameter = Parameter::all();
        $parameter = $parameter->last();

        $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, 'bin_location' => $product->products->bin_location, 'highlight' => $product->products->highlight, '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, 'return_state' => $product->bo_return_state, '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->accepted_delivery_man_id != null) {
            $order->accepted_delivery_man_id = substr($order->deliveryManAccepted->first_name, 0, 1) . " " . $order->deliveryManAccepted->last_name;
        } else {
            $order->accepted_delivery_man_id = "Sin " . $parameter->name_delivery_man;
        }
        if ($order->collected_delivery_man_id != null) {
            $order->collected_delivery_man_id = substr($order->deliveryManCollected->first_name, 0, 1) . " " . $order->deliveryManCollected->last_name;
        } else {
            $order->collected_delivery_man_id = "Sin " . $parameter->name_delivery_man;
        }
        if ($order->deliver_delivery_man_id != null) {
            $order->deliver_delivery_man_id = substr($order->deliveryManDeliver->first_name, 0, 1) . " " . $order->deliveryManDeliver->last_name;
        } else {
            $order->deliver_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_id = $order->address->direction;
            if($order->address->city){
                $city = $order->address->city->name;
            }
        }
        $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->boShippingType->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);
    }

    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', 'b1_activate')->where('id', 1)->first();

        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->modifyQuanityProduct($product->product_id,$product->quantity,'res');
                    $order_product_attributes = OrderProductAttributes::where('order_product_id', $product->id)->get();
                    if($order_product_attributes){
                        $this->modifyQuanityProductAttributes($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->modifyQuanityProductDispatched($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->modifyQuanityProductAttributesDispatched($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) {
                            $push = new PushNotificationController();
                            $push->sendToUser('El pedido ha sido aceptado por el mensajero ' . $user->first_name . ' ' . $user->last_name, $client->pns_id, null, null, null, null, 'U');
                        }
                        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) {
                            $push = new PushNotificationController();
                            $push->sendToUser('Se han recolectado los productos de tu pedido', $client->pns_id, null, null, null, null, 'U');
                        }
                        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
                $resultCapture = $this->captureTransactionFromEbiz($id);
                $orderB1Result = null;
                if(!$resultCapture['status']){
                    return array('r' => false, 'm' => 'Error capture from auth code', 'd' => $resultCapture);
                }

                if ($rol == 3) {
                    if($parameters->b1_activate){
                        $orderB1Result = $this->createOrderBusinessOne($id);
                        if(!$orderB1Result['r']){
                            return $orderB1Result;
                        }
                    }

                    if ($logObj->order_type_id == 5) {
                        if ($client->pns_id != null) {
                            $push = new PushNotificationController();
                            $push->sendToUser('El mensajero va en camino con tu pedido', $client->pns_id, null, null, null, null, 'U');
                        }
                        event(new ChangeStateEvent($id));
                    }


                    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');
                    }

                    return array('r' => true, 'd' => $orderB1Result);
                }

                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) {

                        if ($client->pns_id != null) {
                            $push = new PushNotificationController();
                            $push->sendToUser('Tu pedido fue entregado con exito!', $client->pns_id, null, null, null, null, 'U');
                        }
                        event(new ChangeStateEvent($id));
                    }

                    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');
                    }

                    // return array('r' => true, 'd' => $orderB1Result);
                    return array('r' => true);
                }
                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:
                // Cancelled
                if($parameters->b1_activate){
                    $orderToReject = Order::select('id', 'bo_doc_delivery')->where('id', $id)->first();
                    if($orderToReject->bo_doc_delivery){
                        $bo_delivery_data = explode('/',$orderToReject->bo_doc_delivery);
                        $bo_doc_delivery_ref = $bo_delivery_data[0];
                        $bo_doc_delivery_id  = $bo_delivery_data[1];
                        $resultCancelDelivery = $this->b1_delivery_reject($bo_doc_delivery_id);
                        if(!$resultCancelDelivery['r']){
                            return array('r' => false, 'm' => json_encode($resultCancelDelivery['m']));
                        }
                    }
                }

                // 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;
            case 10:
                $order = Order::where('id', $id)->update(array('deliver_date' => $current,'order_state_id' => $id_state));
            break;
            default:
        }
        event(new OrderStateEvent($id, $id_state));
        return array('r' => true);
    }

    public function b1_delivery_reject($bo_doc_delivery_id) {
        $c = new SAPB1ServiceLayerController();
        return $c->cancelDelivery($bo_doc_delivery_id);
    }

    public function captureTransactionFromEbiz($order_id){
        $order = Order::select('id', 'bo_authorization_code_pay', 'bo_reference_number_pay', 'payment_type_id', 'bo_balance_used', 'bo_state_transaction', 'total_price')
                        ->where('id', $order_id)
                        ->first();

        if($order->payment_type_id != 3) // Si no es payment_type = 3 no aplica
        {
            return  array('status' => true);
        }

        if(($order->total_price - $order->bo_balance_used) == 0){ // Se uso balance, validar que se deba capturar
            return  array('status' => true);
        }

        $ebizController = new EbizChargeController;
        $data = new stdClass();
        $data->type_transaction = "capture";
        $data->bo_reference_number_pay = $order->bo_reference_number_pay;
        $data->bo_authorization_code_pay = $order->bo_authorization_code_pay;

        $resultTransaction = $ebizController->runTransaction($data);

        if($resultTransaction['status']){
            $order->bo_state_transaction = $order->bo_state_transaction . '| captured-' . date('Y-m-d H:i:s');
            $order->update();

            return array('status' => true, 'o' => $resultTransaction);
        }

        return array('status' => false, 'o' => $resultTransaction);
    }

    public function createOrderBusinessOne($order_id){
        $o = Order::where('id', $order_id)
                        ->with('client')
                        ->with('paymentType')
                        ->with('orderProducts')
                        ->first();

        $c = new SAPB1ServiceLayerController();
        $admin = User::select('id', 'bo_sales_people_id')->where('id', $o->admin_id)->first();
        // Send to BO.
        $order = [
            'CardCode' => $o->client->document,
            'DocDueDate' => $o->creation_date,
            // 'U_CAC_PPNOTES' => $o->paymentType->name . '/$' . $o->total_price . '',
            'U_CAC_PPNOTES' => $o->instructions . ' --AgileSelling #' . $o->code,
            'BPL_IDAssignedToInvoice' => $o->bo_business_place_id,
            'ShippingMethod' => $o->bo_shipping_type_id,
            'TransportationCode' => $o->bo_shipping_type_id,
            'SalesPersonCode' => $admin->bo_sales_people_id,
            'OwnerCode' => 9, // Counter, Sales
            'NumAtCard' => $o->bo_purchase_order,
            'DocumentLines' => []
        ];

        if($o->bo_shipping_type_id == 2){ // Es Delivery
            $order["DocDueDate"] = $o->bo_delivery_date . " 00:00:00";
            $order["RequriedDate"] = $o->bo_delivery_date;
        }

        $documentLines = [];
        foreach($o->orderProducts as $op){
            $itemLine = [
                'ItemCode' => $op->bo_item_code,
                'Quantity' => $op->quantity,
                'ShipDate' => Carbon::now()->format('Y-m-d'),
                'WarehouseCode' => $op->bo_warehouse_code,
                'ShippingMethod' => $o->bo_shipping_type_id,
                'PackageQuantity' => $o->number_packages ? $o->number_packages : 0,
                'SalesPersonCode' => $admin->bo_sales_people_id,
                'OwnerCode' => 9, // Counter, Sales
            ];

            if($o->bo_shipping_type_id == 2){ // Es Delivery
                $itemLine["ShipDate"] = $o->bo_delivery_date;
            }

            array_push($documentLines, $itemLine);
        }

        $order['DocumentLines'] = $documentLines;

        // Add DocumentAdditionExpenses
        if($o->cost_delivery > 0){
            $order = $this->addDocumentAdditionalExpensesToOrder($order, $o->bo_shipping_type_id, $o->cost_delivery);
        }

        try{
            // Se envia a crear en Business one
            $order_bo = $c->createOrder($order);

        } catch (\Exception $ex){
            return array('r' => false, 'm' => 'Error Creating Sales Order SAP B1: ' . $ex->getMessage(), 'd' => $ex, 'o' => $order);
        }

        $delivery_bo = new stdClass();
        // Si se creo correctamente se marca con la referencia y documento.
        if($order_bo->DocNum){
            $o->order_reference = $order_bo->DocNum . '/' . $order_bo->DocEntry;
            $o->bo_doc_entry    = $order_bo->DocEntry;
            $o->bo_doc_num      = $order_bo->DocNum;
            $o->save();

            try {
                // Crear nota entrega en Business One.
                $delivery_bo = $this->createDelivery($o, $order_bo->DocEntry, $c);
            } catch(\Exception $ex){
                return array('r' => false, 'm' => 'Error creating Delivery SAP B1: ' . $ex->getMessage());
            }
        } else {
            return array('r' => false, 'm' => 'Error create order', 'd' => $order_bo);
        }

        // Crear Invoice
        if($delivery_bo->DocNum){
            try{
                $invoice_bo = $this->createInvoice($o, $delivery_bo->DocEntry, $c);
                return array('r' => true, 'm' => 'Sales Order / Delivery created', 'd' => $order_bo, 'd2' => $invoice_bo);
            } catch(\Exception $ex){

            }
        }
        else{
            return array('r' => false, 'm' => 'Error create invoice', 'd' => $order_bo);
        }
    }

    function addDocumentAdditionalExpensesToReferenceObjects($order, $orderDB, $doc_type_reference, $line_num = null){

        switch ($orderDB->bo_shipping_type_id) {
            case 2: // Delivery
                $order["DocumentAdditionalExpenses"] = [[
                    "BaseDocEntry" => $this->getDocEntryFromTypeObject($orderDB, $doc_type_reference),
                    "BaseDocLine" => $line_num !== null ? $line_num : 1,
                    "BaseDocType" => $doc_type_reference
                ]];

                break;
            case 3: // Freight
                $order["DocumentAdditionalExpenses"] = [[
                    "BaseDocEntry" => $this->getDocEntryFromTypeObject($orderDB, $doc_type_reference),
                    "BaseDocLine" => $line_num !== null ? $line_num : 4,
                    "BaseDocType" => $doc_type_reference
                ]];

                break;
            case 4: // UPS
                $order["DocumentAdditionalExpenses"] = [[
                    "BaseDocEntry" => $this->getDocEntryFromTypeObject($orderDB, $doc_type_reference),
                    "BaseDocLine" => $line_num !== null ? $line_num : 6,
                    "BaseDocType" => $doc_type_reference
                ]];

                break;
            case 5: // Fedex
                $order["DocumentAdditionalExpenses"] = [[
                    "BaseDocEntry" => $this->getDocEntryFromTypeObject($orderDB, $doc_type_reference),
                    "BaseDocLine" => $line_num !== null ? $line_num : 3,
                    "BaseDocType" => $doc_type_reference
                ]];

                break;
            default:
                break;
        }

        return $order;
    }

    function getDocEntryFromTypeObject($order, $doc_type_reference){
        switch ($doc_type_reference) {
            case 17: // From Sales order
                $reference = $order->order_reference;
                $reference = explode("/", $reference);

                return $reference[1];
                break;

            case 15: // From delivery
                $reference = $order->bo_doc_delivery;
                $reference = explode("/", $reference);

                return $reference[1];
                break;
            default:
                # code...
                break;
        }
    }

    function addDocumentAdditionalExpensesToOrder($order, $shipping_type_id, $cost_delivery){
        if($cost_delivery <= 0){
            return $order;
        }
        switch ($shipping_type_id) { // Verificar si se incluye el DocumentAdditionalExpenses
            case 2: // Delivery
                $order["DocumentAdditionalExpenses"] = [[
                    "ExpenseCode" => 3,
                    "LineTotal" => $cost_delivery
                ]];
                break;
            case 3: // Freight
                $order["DocumentAdditionalExpenses"] = [[
                    "ExpenseCode" => 6,
                    "LineTotal" => $cost_delivery
                ]];
                break;
            case 4: // UPS
                $order["DocumentAdditionalExpenses"] = [[
                    "ExpenseCode" => 2,
                    "LineTotal" => $cost_delivery
                ]];
                break;
            case 5: // Fedex
                $order["DocumentAdditionalExpenses"] = [[
                    "ExpenseCode" => 1,
                    "LineTotal" => $cost_delivery
                ]];
                break;
            default:
                break;
        }

        return $order;
    }

    function createInvoice($order, $doc_entry, $controller){

        try {
            $invoice = [
                'CardCode' => $order->client->document,
                'BPL_IDAssignedToInvoice' => $order->bo_business_place_id,
                'DocumentLines' => []
            ];

            $i = 0;
            $documentLines = [];
            foreach($order->orderProducts as $o){
                array_push($documentLines, [
                    'BaseType' => 15, // 15 - Delivery object
                    'BaseEntry' => $doc_entry,
                    'BaseLine' => $i
                ]);
                $i++;
            }

            $invoice['DocumentLines'] = $documentLines;

            // Add DocumentAdditionExpenses
            if($order->cost_delivery > 0){
                $invoice = $this->addDocumentAdditionalExpensesToReferenceObjects($invoice, $order, 15, 0);
            }

            $invoiceBO = $controller->createInvoice($invoice);

            if($invoiceBO->DocEntry){
                $order->bo_invoice = $invoiceBO->DocNum . '/' . $invoiceBO->DocEntry;
                $order->save();
            }

            // Si se usa el balance credit y hay un saldo que entre por otro medio de pago se genera Incoming Payment. Y que el tipo de pago no sea blank BLANK = 8.
            if(($order->total_price - $order->bo_balance_used) > 0 && $order->payment_type_id != 8){
                // Post IncomingPayment
                $incomingPayment = $this->postIncomingPayment($invoiceBO, $order, $controller);
            }

            return array('i' => $invoiceBO, 'ip' => $incomingPayment);
        } catch(\Exception $e){
            return array('e' => $e->getMessage(), 'l' => $e->getLine());
        }
    }

    function createDelivery($order, $doc_entry, $controller){
        $deliveryNote = [
            'CardCode' => $order->client->document,
            'DocDueDate' => $order->creation_date,
            'BPL_IDAssignedToInvoice' => $order->bo_business_place_id,
            'DocumentLines' => []
        ];

        $i = 0;
        $documentLines = [];
        foreach($order->orderProducts as $o){
            array_push($documentLines, [
                'BaseType' => 17, // 17 - Sales order object
                'BaseEntry' => $doc_entry,
                'BaseLine' => $i
            ]);
            $i++;
        }

        $deliveryNote['DocumentLines'] = $documentLines;

        // Add DocumentAdditionExpenses
        if($order->cost_delivery > 0){
            $deliveryNote = $this->addDocumentAdditionalExpensesToReferenceObjects($deliveryNote, $order, 17, 0);
        }
        $deliveryNoteBO = $controller->createDeliveryOrder($deliveryNote);

        if($deliveryNoteBO->DocEntry){
            $order->bo_doc_delivery = $deliveryNoteBO->DocNum . '/' . $deliveryNoteBO->DocEntry;
            $order->save();
        }

        return $deliveryNoteBO;
    }

    public function postIncomingPayment($invoiceBO, $order, $controller){
        $bo_cash_account = BoCashAccount::where('payment_type_id',$order->payment_type_id)
                                        ->where('bo_branch_id', $order->bo_business_place_id)
                                        ->first();

        switch ($order->payment_type_id) {
            case '1': // Cash
                $data = [
                    "CardCode" => $order->client->document,
                    "BPLID" => $order->bo_business_place_id,
                    "CashAccount" => $bo_cash_account->cash_account,
                    "CashSum" => ($order->total_price - $order->bo_balance_used),
                    "PaymentInvoices" => [[
                        "DocEntry" => $invoiceBO->DocEntry,
                        "SumApplied" => ($order->total_price - $order->bo_balance_used)
                    ]]
                ];
                break;
            case '3': // Debit / Credit

                $data = [
                    "CardCode" => $order->client->document,
                    "BPLID" => $order->bo_business_place_id,
                    "PaymentCreditCards" => [
                        [
                            "CreditCard" => $this->determineFranchiseFromCreditCard($order->bo_credit_card_type), // Franquicia
                            "CreditAcct" => $bo_cash_account->cash_account,
                            "CreditSum" => ($order->total_price - $order->bo_balance_used),
                            "CreditCardNumber" => str_replace('X', '', $order->bo_credit_card_number), // Clear credit card number
                            "CardValidUntil" => $order->bo_credit_card_expiration . '-01',
                            "VoucherNum" => $order->bo_reference_number_pay

                        ]
                    ],
                    "PaymentInvoices" => [
                        [
                            "DocEntry" => $invoiceBO->DocEntry,
                            "SumApplied" => ($order->total_price - $order->bo_balance_used)
                        ]
                    ]
                ];

                break;
            case '6': // Check
                $data = [
                    "CardCode" => $order->client->document,
                    "BPLID" => $order->bo_business_place_id,
                    "HandWritten" => "tNO",
                    "Printed" => "tNO",
                    "PaymentChecks" => [
                        [
                            "CheckAccount" => $bo_cash_account->cash_account,
                            "CheckSum" => ($order->total_price - $order->bo_balance_used),
                            "DueDate" => $order->creation_date,
                            "CheckNumber" => $order->bo_check_number,
                            "BankCode" => "",
                            "CountryCode" => "US",
                            "Currency" => "$"

                        ]
                    ],
                    "PaymentInvoices" => [
                        [
                            "DocEntry" => $invoiceBO->DocEntry,
                            "SumApplied" => ($order->total_price - $order->bo_balance_used)
                        ]
                    ]
                ];
                break;
            default:
                break;
        }

        if($data){
           return  $controller->postIncomingPayment($data, $order);
        }
    }

    public function determineFranchiseFromCreditCard($creditCardType){
        // Determine from bo_credit_cards table
        switch($creditCardType){
            case "V":
                return 1;
            case "M":
                return 2;
            case "A":
                return 3;
            case "DS":
                return 4;
        }
    }

    public function runInventory($order_id,$operation_available,$operation_dispatched,$updateExternalECInventory = false)
    {
        //Se resta la cantidad de unidades dispobibles en products y products attributes
        //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($operation_available != ''){
                $this->modifyQuanityProduct($product->product_id,$product->quantity,$operation_available);
            }
            if($operation_dispatched != ''){
                $this->modifyQuanityProductDispatched($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->modifyQuanityProductAttributes($order_product_attributes,$product->quantity,$operation_available,$product->product_id,$updateExternalECInventory);
                }
                if($operation_dispatched != ''){
                    $this->modifyQuanityProductAttributesDispatched($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()
    {

        $sucursal = Auth::user()->userInfo->sucursal->id;
        // $rol = Auth::user()->rol->id;
        // if ($rol == 1 ||  $rol == 6) {
            $orders = Order::where('order_state_id', 1)->get();
        // } else {
        //     $orders = Order::where('sucursal_id', $sucursal)->where('order_state_id', 1)->get();
        // }

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

    public function clickDeleteOrder(Request $request)
    {
        $order = Order::where('id',$request["id"])->first();
        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->comment()->delete();
            // $order->discountOrderUser()->delete();
            // $order->orderProducts()->delete();
            $order->delete();
        }
    }

    public function deleteProduct(Request $request)
    {
        $order = Order::where('id', $request->order_id)->with('address.boSalesTaxCode')->with('client')->first();
        $products = OrderProduct::where('order_id', $request->order_id)->get();
        if($products->count() == 1){
            $order->order_state_id = 7;
            $order->finished_admin_date = Carbon::now();
            $order->update();
            return array('status' => 'cancelled', 'response' => $order);
        }else{
            $product = OrderProduct::where('id', $request->order_product_id)->first();
            $product->delete();
            $products_new = OrderProduct::where('order_id', $request->order_id)->get();
            $parameter = Parameter::first();

            // Calcula subtotal
            $subtotal = 0;
            foreach ($products_new as $product_new){
                $subtotal += $product_new->price * $product_new->quantity;
            }
            // Calcula taxes
            $taxes = 0;
            if($order->client->bo_tax_exempt == 0){
                $taxes = ($subtotal * $order->address->boSalesTaxCode->rate) / 100;
            }
            // Calcula delivery
            $delivery = 0;
            if($subtotal < 200){
                $delivery = $parameter->cost_delivery;
            }
            // Calcula total
            $total = $subtotal + $taxes + $delivery;

            $order->subtotal = $subtotal;
            $order->tax = $taxes;
            $order->total_price = $total;
            $order->cost_delivery = $delivery;
            $order->update();

            return array('status' => 'deleted', 'response' => $total);
        }
    }

    public function deleteReturn(Request $request)
    {
        if($return = ReturnHeader::where('id', $request->id)->with('returnDetails')->first()){
            $return->returnDetails()->delete();
            $return->delete();
            return array('r' => true, 'm' => '');
        }
        return array('r' => false, 'm' => 'It was not possible to delete');
    }

    public function saveCurrentReturn(Request $request)
    {
        $returnCurrent = ReturnHeader::where([['is_open', true],['admin_id', Auth::user()->id]])->first();
        if($returnCurrent){
            $returnCurrent->is_open = false;
            $returnCurrent->pick_notes = $request->pick_notes;
            $returnCurrent->save();
            return array('r' => true, 'm' => '');
        }

        return array('r' => false, 'm' => 'There is no valid return');
    }

    public function getCurrentReturn(Request $request){
        $returnData = ReturnHeader::with('returnDetails')
                            ->with('user')
                            ->where('is_open', true)
                            ->where('admin_id', Auth::user()->id)
                            ->first();

        $returnData = $this->calculatePriceReturn($returnData);

        return $returnData;
    }

    public function calculatePriceReturn($returnData){
        $user = User::find($returnData->user_id);
        $parameters = Parameter::first();

        foreach ($returnData->returnDetails as $rd) {
            $orderProductsOriginal = $rd->order->orderProducts;
            $bo_special_price = BoSpecialPrice::where('product_id', $rd->orderProduct->product_id)->where('bo_price_list_id', $user->bo_price_list_id)->first();

            if(!$bo_special_price){
                continue;
            }

            $unit_price = $rd->orderProduct->product->price; // Precio original
            $discount_price = round($unit_price - (($unit_price * $bo_special_price->percentage)/100),2 );
            $qty_discount = $bo_special_price->quantity;
            $qty_bought = $orderProductsOriginal->firstWhere('product_id', $rd->orderProduct->product_id)->quantity;
            $qty_kept = $qty_bought - $rd->quantity;
            $qty_returned = $qty_bought - $qty_kept;

           // dd($unit_price, $discount_price, $qty_bought, $qty_discount, $qty_kept, $rd->orderProduct->order->creation_date, $parameters);

            $message = $this->calculateCredit($unit_price, $discount_price, $qty_bought, $qty_discount, $qty_kept, $rd->orderProduct->order->creation_date, $parameters);
            $rd->message = $message["m"];
            $rd->fee_applied = (100 - $message["fee"]) . "%";
            $rd->after_30 = $message["after_30"];
            $rd->price = round($message["price_bought"] / $qty_returned, 2);
        }

        return $returnData;
    }

    private function calculateCredit($unit_price, $discount_price, $qty_bought, $qty_discount, $qty_kept, $order_date_created, $parameters){
        $is_after_30_days = $this->checkDaysForReturn($order_date_created);
        $fee = 0;
        $returnedUnits = $qty_bought - $qty_kept;
        if($is_after_30_days){
            $fee = 100 - $parameters->bo_fee_after_30_days;
        } else {
            $fee = 100 - $parameters->bo_fee_before_30_days;
        }

        if ($qty_bought < $qty_discount) {
            $amountSpent = $qty_bought * $unit_price;
            $creditInCaseOfReturn = ($returnedUnits * $unit_price * $fee) / 100;
          } else {
            if ($qty_kept < $qty_discount) {
              $amountSpent = $discount_price * $qty_bought;
              $totalAmountWithoutDiscount = $unit_price * $qty_bought;
              $creditInCaseOfReturn = $amountSpent - $qty_kept * $discount_price - ($totalAmountWithoutDiscount - $amountSpent);
              if ($creditInCaseOfReturn < 0) {
                $creditInCaseOfReturn = $creditInCaseOfReturn * -1;
                $message = "(he owes $creditInCaseOfReturn)";
                $creditInCaseOfReturn = $message;
              }
            } else {
              $amountSpent = $discount_price * $qty_bought;
              $creditInCaseOfReturn = $returnedUnits * $discount_price;
            }
          }

          $sResult2 = "Amount initially spent: $<b>$amountSpent</b>, Credit in case the client keeps <i>$qty_kept</i> of the <i>$qty_bought</i> units he bought is: <b>$$creditInCaseOfReturn</b>";
          return ["m" => $sResult2, "after_30" => $is_after_30_days, "price_bought" => $creditInCaseOfReturn, "fee" => $fee];
    }

    function checkDaysForReturn($order_date_created){
        $current_date = Carbon::now();
        $order_date = Carbon::parse($order_date_created);

        $diffDays = $current_date->diffInDays($order_date);

        if($diffDays > 30){
            return true;
        }

        return false;
    }

    public function postReturn(Request $request){
        $obj = ReturnHeader::with('returnDetails')
                            ->with('user')
                            ->where('id', $request->id)
                            ->first();

        $bo_business_place_id = $obj->returnDetails[0]->order->bo_business_place_id;

        $body = [
            "CardCode" => $obj->user->document,
            "BPL_IDAssignedToInvoice" => $bo_business_place_id,
            "SalesPersonCode" => Auth::user()->bo_sales_people_id,
            "Comments" => $obj->pick_notes,
            "DocumentLines" => []
        ];

        $documentLines = [];
        foreach ($obj->returnDetails as $rd) {
            $absEntry = $this->getAbsEntry($rd->orderProduct->bo_warehouse_code, $rd->orderProduct->product->bin_location);
            $documentLines[] = [
                "ItemCode" => $rd->plu,
                "Quantity" => $rd->quantity,
                "TaxCode" => $rd->orderProduct->bo_item_tax_code,
                "UnitPrice" => $rd->price,
                "WarehouseCode" => $rd->orderProduct->bo_warehouse_code,
                "SalesPersonCode" => Auth::user()->bo_sales_people_id,
                "DocumentLinesBinAllocations" => [[
                    "BinAbsEntry" => $absEntry["id"],
                    "Quantity" => $rd->quantity
                ]]
            ];
        }


        $body["DocumentLines"] = $documentLines;

        $controller = new SAPB1ServiceLayerController();

        $returnResult = $controller->postReturn($body, $obj->id);

        if($returnResult['r']){
            $returnCreditNote = $this->postCreditNote($request, $returnResult['reference']);
            if(!$returnCreditNote['r']){
                return array('r' => false, 'm' => 'Error creating credit note', 'd' => $returnCreditNote);
            }
        } else {
            return array('r' => false, 'm' => 'Error creating return', 'd' => $returnResult, 'r' => $body);
        }

        return $returnResult;
    }

    public function getAbsEntry($warehouse_code, $bin_location){
        $controller = new SAPB1ServiceLayerController();
        return $controller->getAbsEntryFromWarehouseCodeAndBinLocation($warehouse_code, $bin_location);

    }

    public function postCreditNote(Request $request, $return_reference){
        $obj = ReturnHeader::with('returnDetails')
        ->with('user')
        ->where('id', $request->id)
        ->first();

        $bo_business_place_id = $obj->returnDetails[0]->order->bo_business_place_id;

        $body = [
            "CardCode" => $obj->user->document,
            "BPL_IDAssignedToInvoice" => $bo_business_place_id,
            "SalesPersonCode" => Auth::user()->bo_sales_people_id,
            "U_CAC_PPNOTES" => $obj->pick_notes,
            "DocumentLines" => []
        ];

        $documentLines = [];
        $cont = 0;
        foreach ($obj->returnDetails as $rd) {
            $documentLines[] = [
                "BaseType" => 16,
                "BaseEntry" => $return_reference,
                "BaseLine" => $cont,
                "ItemCode" => $rd->plu,
                "Quantity" => $rd->quantity
            ];

            $cont++;
        }

        $body["DocumentLines"] = $documentLines;

        $controller = new SAPB1ServiceLayerController();

        return $controller->postCreditNote($body, $obj->id);
    }

    public function discardReturn($id){
        ReturnDetail::where('return_header_id', $id)->delete();
        ReturnHeader::where('id', $id)->delete();
    }

    public function deleteReturnItemDetail($id){
        ReturnDetail::where('id', $id)->delete();
    }

    public function addItemToReturns(Request $request){
        if(!$request->order_id){
            return array('r' => false, 'm' => 'Please send a order id');
        }

        if(!$request->quantity){
            return array('r' => false, 'm' => 'Please send a valid quantity');
        }

        $order = Order::where('id', $request->order_id)
                        ->with('client')
                        ->first();

        $order_item = OrderProduct::where('id', $request->item_id)
                                    ->with('product')
                                    ->first();

        if($order_item->bo_return_state){
            return array('r' => false, 'm' => 'This position has been returned.');
        }

        DB::beginTransaction();
        try {
            $currentReturn = ReturnHeader::with('returnDetails')
                                            ->where('user_id', $order->client_id)
                                            ->where('admin_id', Auth::user()->id)
                                            ->where('is_open', true)
                                            ->first();

            // Si existe el return agregar el item.
            if($currentReturn){
                $existItem = ReturnDetail::where('return_header_id', $currentReturn->id)
                                            ->where('plu', $order_item->product->plu)
                                            ->first();

                if($existItem){
                    $existItem->quantity = $existItem->quantity + $request->quantity;
                    $existItem->update();
                } else {
                    $newItemReturn = new ReturnDetail;
                    $newItemReturn->plu = $order_item->product->plu;
                    $newItemReturn->quantity = $request->quantity;
                    $newItemReturn->price = $order_item->price;
                    $newItemReturn->return_header_id = $currentReturn->id;
                    $newItemReturn->order_id = $order->id;
                    $newItemReturn->order_product_id = $order_item->id;

                    $newItemReturn->save();
                }
            }
            // Si el cliente no tiene retorno en curso, se crea.
            else {
                $returnHeader = new ReturnHeader;
                $returnHeader->user_id = $order->client_id;
                $returnHeader->admin_id = Auth::user()->id;

                $returnHeader->save();

                $newItemReturn = new ReturnDetail;
                $newItemReturn->plu = $order_item->product->plu;
                $newItemReturn->quantity = $request->quantity;
                $newItemReturn->price = $order_item->price;
                $newItemReturn->return_header_id = $returnHeader->id;
                $newItemReturn->order_id = $order->id;
                $newItemReturn->order_product_id = $order_item->id;

                $newItemReturn->save();
            }


            $order_item->bo_return_state = true;
            $order_item->update();

            DB::commit();
            return array('status' => true, 'm' => 'Return item stored succesfully');

        } catch(\Exception $e) {
            DB::rollback();
            return array('status' => false, 'm' => 'An error has been ocurred. ', 'd' => $e->getMessage());
        }
    }

    function determineValueToPay($total_price, $user_id, $pay_way_id){
        $u = User::find($user_id);
        $p = PaymentType::find($pay_way_id);
        $currentBalance = abs($u->bo_account_balance);
        $paymentTypeText = "";

        if($p->id == 3){ // Credit
            $paymentTypeText = "Ebiz";
        }
         else {
            $paymentTypeText = $p->name;
         }

        if($currentBalance > $total_price){
            return array('msg' => 'Used Credit: ' .  ( $total_price ), 'to_pay' => 0, 'balance_used' => $total_price) ;
        }
        else if($currentBalance < $total_price){
            $value = $total_price - $currentBalance;
            return array('msg' => "Used Credit: " .  $currentBalance . "," .  $paymentTypeText . ": " .  $value, 'to_pay' => $total_price - $currentBalance, 'balance_used' => $currentBalance) ;
        } else if($currentBalance = $total_price){
            return array('msg' => "Used ALL Credit: " . $currentBalance, 'to_pay' => 0, 'balance_used' => $total_price) ;
        }
    }
}