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

namespace App\Http\Controllers;

use DB;
use App\Brand;
use App\City;
use App\User;
use App\Order;
use App\State;
use App\Product;
use App\Parameter;
use App\BoPriceList;
use App\OrderProduct;
use App\ReturnHeader;
use GuzzleHttp\Client;
use App\BoSalesTaxCode;
use App\UserInformation;
use App\BoPaymentTermType;
use App\BoItemManualPrice;
use App\BoSpecialPrice;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Artisan;
use Symfony\Component\Console\Output\ConsoleOutput;


class SAPB1ServiceLayerController extends Controller {

    private $client;
    private $base_url;
    private $username;
    private $password;
    private $company;

    private $output;
    private $isConsole;

    const PAGE_SIZE = 20;
    const DEFAULT_BRAND = "IGT"; // Marca por defecto usada
    const REGULAR_LIST_PRICE_BASE = "1";

    const INVENTORY_QUERY_NAME = 'GetInventoryItem';
    const INVENTORY__WH_QUERY_NAME = 'GetInventoryItemWarehouse';
    const ITEM_MANUAL_PRICES_QUERY_NAME = 'GetManualPricesItem';

    private $listProducts;
    private $listPriceLists;
    private $listUsers;

    public function __construct() {
        $this->base_url = config('sapb1.base_url');
        $this->username = config('sapb1.user');
        $this->password = config('sapb1.pass');
        $this->company = config('sapb1.company');

        $options = [
            'base_uri'        => $this->base_url,
            'timeout'         => 0,
            'allow_redirects' => false
        ];

        $this->client = new Client($options);
        $this->isConsole = app()->runningInConsole();

        if ($this->isConsole) {
            $this->output = new ConsoleOutput();
            $this->output->writeln("<info>Initialization</info>");
        }
    }

    public function index(){
        
        return view('sapb1_sync.master_sync');
    }

    // public function onDemandSyncItems($b1Command, $sCity){
    //     if($b1Command == 'b1:sync-inventory'){
    //         Artisan::call("b1:on-demand", array('command_execute' => $b1Command, 'warehouse' => $sCity, 'param1' => $sCity));
    //     } else {
    //         Artisan::call("b1:on-demand", array('command_execute' => $b1Command, 'warehouse' => $sCity, 'param1' => $sCity));
    //     }
        
    // }
    
    public function onDemandSyncItems($b1Command, $sCity){

        header("Connection: Keep-alive");
        $projectPath = base_path();

        // Determine project to run
        // $explodeCityPath = explode("/", $projectPath);
        // $lastPartOfPath = end($explodeCityPath);

        // $explodeProjectName = explode("-", $lastPartOfPath);
        // end($explodeProjectName);
        // $lastProjectNamePathPartIndex = key($explodeProjectName);

        // // Replace city by correct city to execute
        // $explodeProjectName[$lastProjectNamePathPartIndex] = strtolower($sCity);
        
        // // Remove default city
        // array_pop($explodeCityPath);  
        // $projectName = implode("-", $explodeProjectName);
        // $projectBasePath = implode("/", $explodeCityPath);

        // // Merge path
        // $projectPath = $projectBasePath . "/" . $projectName;

        $command = "php $projectPath/artisan $b1Command";

        // El caso del comando para inventario requiere la Warehouse
        if($b1Command == 'b1:sync-inventory'){
            $command = "php $projectPath/artisan $b1Command $sCity";
        }
        

        $fp = popen($command, "r");
        while($b = fgets($fp, 2048)) {
            echo $b."<br>";
            flush();
        }

        pclose($fp);
    }

    public function logConsole($text){
        if ($this->isConsole) {
           $this->output->writeln("<info>{$text}</info>");
        }
    }

    public function buildCredentials(){
        return 'Basic ' .  base64_encode('{"UserName": "'. $this->username . '", "CompanyDB": "' . $this->company . '"}:' . $this->password);
    }

    public function queryEntity(Request $request){
        $this->logConsole("Current DB: " . DB::connection()->getDatabaseName());
        $this->logConsole("Current Path: " . base_path());
        switch ($request->entity) {
            case 'GetAllQueries': // Ok
                return $this->getAllQueries();
                break;
            case 'DeleteQueryInventory': // Ok
                return $this->deleteQueryInventory();
                break;
            case 'CreateQueryInventory': // Ok
                return $this->createQueryInventory();
                break;
            case 'CreateQueryInventoryWarehouse': // Ok
                return $this->createQueryWarehouse();
                break;
            case 'executeQueryInventory': // Ok
                $this->logConsole('Begin Inventory process...');
                $this->logConsole('Warehouse: ' . $request->warehouse_code);
                $skip = 0;

                // Dejar todo los productos en 0
                Product::query()->update(['available_units' => 0]);

                $this->logConsole('executeQueryInventoryWarehouses');
                // Actualizar warehouses.
                do {
                    $this->logConsole('Processed: ' . $skip);
                    $inventory_items = json_decode($this->executeQueryInventoryWarehouseItem($request->warehouse_code, $skip)->getContents());
                    $this->logConsole('Total inventory_items for update warehouse: ' . count($inventory_items->value));
                    $this->updateInventoryWarehouse($inventory_items->value);
                    $skip = $skip + self::PAGE_SIZE;

                } while (count($inventory_items->value) > 0);

                $skip = 0;

                $this->logConsole('executeQueryInventory');
                // Actualizar bin locations
                do {
                    $this->logConsole('Processed: ' . $skip);
                    $inventory_items = json_decode($this->executeQueryInventoryItem($request->warehouse_code, $skip)->getContents());
                    $this->logConsole('Total inventory_items: ' . count($inventory_items->value));
                    $this->updateInventory($inventory_items->value);
                    $skip = $skip + self::PAGE_SIZE;
                } while (count($inventory_items->value) > 0);

                

                $this->logConsole('Fin');

                break;
            case 'CreateQueryItemManualPrices': // Ok
                return $this->createQueryItemManualPrices();
                break;
            case 'DeleteteQueryItemManualPrices': // Ok
                return $this->deleteQueryItemManualPrices();
                break;
            case 'executeQueryItemManualPrices': // Ok
                $this->logConsole('executeQueryItemManualPrices');
                $skip = 0;

                // Se cargan en memoria datos de Lista de precios y productos.
                $this->prefetchDataManualPrices();

                // Se eliminar los registros previos de precios manuales.
                $this->truncateManualPrices();

                do {
                    $this->logConsole('Processed: ' . $skip);
                    $query_items = json_decode($this->executeQueryItemManualPrice($skip)->getContents());
                    $this->updateItemManualPrices($query_items->value);
                    $skip = $skip + self::PAGE_SIZE;
                } while (count($query_items->value) > 0);

                break;
            case 'SpecialPrices':
                $this->logConsole('Special prices');
                $filter = ''; // Solo clientes
                $skip = 0;
                $top = self::PAGE_SIZE;
                $count = $this->countEntity('SpecialPrices', "");
                $pages = ceil($count/$top);

                $this->logConsole('Total registros: ' . $count);
                $this->logConsole('Total pages: ' . $pages);

                // Se dejan todas las listas de precio en 0%.
                BoSpecialPrice::query()->update(['percentage' => 0]);

                $this->prefetchData();

                for ($i=0; $i <= $pages; $i++) {
                    $this->logConsole('Page: ' . $i . ' de ' . $pages);
                    $this->logConsole('skip: ' . $skip . ' Top: ' . $top);
                    $o = $this->querySpecialPrices($filter, $top, $skip);
                    $this->storeInformationSpecialPrices($o, 'BoSpecialPrice');
                    $skip = $skip + $top;
                }

                $this->logConsole('Fin');

                break;

            case 'Items': // Ok
                $this->logConsole('Items');
                $filter = '$filter'; // Solo clientes
                $skip = 0;
                $top = self::PAGE_SIZE;
                $count = $this->countEntity('Items', "?$filter=SalesItem eq 'tYES' and InventoryItem eq 'tYES'");
                $pages = ceil($count/$top);

                $this->logConsole('Total registros: ' . $count);
                $this->logConsole('Total pages: ' . $pages);

                $filter = "SalesItem eq 'tYES' and InventoryItem eq 'tYES'"; // Solo clientes

                for ($i=0; $i <= $pages; $i++) {
                    $this->logConsole('Page: ' . $i . ' de ' . $pages);
                    $this->logConsole('skip: ' . $skip . ' Top: ' . $top);
                    $o = $this->queryItems($filter, $top, $skip);
                    $this->storeInformationItems($o);
                    $skip = $skip + $top;
                }

                $this->logConsole('Fin');

                break;
            case 'ItemGroups': // Categories // Ok
                $o = $this->queryItemGroups($request->filter, $request->top, $request->skip);
                $this->storeInformationItemGroups($o, 'Category');
                break;
            case 'CreditCards': // CreditCards // Ok
                $o = $this->queryCreditCards($request->filter, $request->top, $request->skip);
                $this->storeInformationCreditCards($o, 'BoCreditCard');
                break;
            case 'PriceLists': // Ok
                $o = $this->queryPriceLists($request->filter, $request->top, $request->skip);
                $this->storeInformationPriceLists($o, 'BoPriceList');
                break;
            case 'BusinessPartners': // Ok
                $filter = '$filter';
                // $count = $this->countEntity('BusinessPartners', "?$filter=CardType eq 'cCustomer' and Valid eq 'tYES'");
                $count = $this->countEntity('BusinessPartners', "");
                $orderby = "CardCode";
                $this->logConsole('Total BPs: ' . $count);
                $skip = 0;
                $top = self::PAGE_SIZE;
                $pages = ceil($count / $top);

                $this->logConsole('Total registros: ' . $count);
                $this->logConsole('Total Pages: ' . $pages);

                $filter = "CardType eq 'cCustomer' and Valid eq 'tYES'"; // Solo clientes
                User::where('document', 'like', 'C%')->orWhere('document', 'like', 'V%')->update(['active' => false]); // Inactiva todos los clientes para iniciar el proceso
                // $filter = ""; // Todos los tipos de clientes.

                $parameters = Parameter::first();
                for ($i=0; $i <= $pages; $i++) {
                    $this->logConsole('Page: ' . $i . ' dex  ' . $pages);
                    $this->logConsole('skip: ' . $skip . ' Top: ' . $top);
                    $o = $this->queryBusinessPartners($filter, $top, $skip, $orderby);
                    $this->storeInformationBusinessPartners($o, $parameters);
                    $skip = $skip + $top;
                }
                $this->logConsole('End Business Partners');
                break;
            case 'EmployeesInfo': // Ok
                $o = $this->queryEmployeesInfo($request->filter, $request->top, $request->skip);
                $this->storeEmployeesInfo($o, 'BoEmployeeInformation');
                break;
            case 'SalesPersons':
                $o = $this->querySalesPersons($request->filter, $request->top, $request->skip);
                $this->storeSalesPersons($o, 'BoSalesPerson');
                break;
            case 'ShippingTypes': // Ok
                $o = $this->queryShippingTypes($request->filter, $request->top, $request->skip);
                $this->storeInformationShippingType($o, 'BoShippingType');
                break;
            case 'BusinessPlaces': // Ok
                $o = $this->queryBusinessPlaces($request->filter, $request->top, $request->skip);
                $this->storeInformationBusinessPlace($o, 'BoBusinessPlace');
                break;
            case 'SalesTaxCodes': // Ok
                $o = $this->querySalesTaxCodes($request->filter, $request->top, $request->skip);
                $this->storeInformationSalesTaxCodes($o, 'BoSalesTaxCode');
                break;
            case 'PaymentTermsTypes': // Ok
                $o = $this->queryPaymentTermsTypes($request->filter, $request->top, $request->skip);
                $this->storeInformationPaymentTermsTypes($o, 'BoPaymentTermType');
                break;
            default:
                break;
        }
    }

    public function prefetchData(){
        $this->listPriceLists = BoPriceList::all();
        $this->listProducts = Product::all();
        $this->listUsers = User::all();
    }

    public function prefetchDataManualPrices(){
        $this->listPriceLists = BoPriceList::all();
        $this->listProducts = Product::all();
    }

    public function truncateManualPrices(){
        BoItemManualPrice::truncate();
    }

    public function updateInventory($inventory){
        $itemCode = "";
        foreach ($inventory as $item) {
            try{
                $itemCode = $item->ItemCode;
                $this->logConsole('PLU: ' . $itemCode . ", BinLocation: " . $item->BinCode . ", T. Bin location: " . $item->TotalBin);
                $product = Product::where('plu', $itemCode)->first();
                if($product){
                    $product->bin_location = $item->BinCode;
                    $product->available_units = $item->TotalBin;   

                    $product->update();
                }
            }
            catch(\Exception $e){
                $this->logConsole('Item Error: '. $itemCode . " - " . $e->getMessage());
            }
        }
    }

    public function updateInventoryWarehouse($inventory){
        $itemCode = "";
        foreach ($inventory as $item) {
            try{
                $itemCode = $item->ItemCode;
                $this->logConsole('PLU: ' . $itemCode . ", T. Warehouse: " . $item->TotalWarehouse);
                $product = Product::where('plu', $itemCode)->first();
                if($product){
                    $product->available_warehouse = $item->TotalWarehouse;
                    $product->update();
                }
            }
            catch(\Exception $e){
                $this->logConsole('Item Error: '. $itemCode . " - " . $e->getMessage());
            }
        }
    }

    public function updateItemManualPrices($items_query){
        $itemCode = '';
        $listNum = '';
        foreach ($items_query as $o) {
            try{
                $itemCode = $o->ItemCode;
                $listNum = $o->ListNum;
                $currentProduct = $this->listProducts->where('plu', $itemCode)->first();
                $currentListPrice = $this->listPriceLists->where('list_num', $listNum)->first();

                $manualPrice = new BoItemManualPrice;
                $manualPrice->product_id = $currentProduct->id;
                $manualPrice->price = $o->Price;
                $manualPrice->bo_price_list_id = $currentListPrice->id;

                $manualPrice->save();
            }
            catch(\Exception $e){
                $this->logConsole('Error: '. $itemCode . " - Lista -  " . $listNum . ' - ' . $e->getMessage());
            }
        }
    }

    public function storeEmployeesInfo($data){
        $employeeInfoModel = 'App\\BoEmployeeInformation';

        $infoToStore = json_decode($data->getContents());

        foreach ($infoToStore->value as $o) {
            $e = $employeeInfoModel::updateOrCreate(
                ['id' => $o->EmployeeID],
                [
                    'first_name' => $o->FirstName,
                    'last_name' => $o->LastName,
                ]
            );
        }
    }

    public function storeSalesPersons($data){
        $employeeInfoModel = 'App\\BoSalesPerson';

        $infoToStore = json_decode($data->getContents());

        foreach ($infoToStore->value as $o) {
            if($o->SalesEmployeeCode < 0){
                continue;
            }

            $e = $employeeInfoModel::updateOrCreate(
                ['id' => $o->SalesEmployeeCode],
                [
                    'name' => $o->SalesEmployeeName,
                    'active' => $o->Active == 'tYES' ? true: false
                ]
            );
        }
    }

    public function storeInformationItems($data){
        $productModel = 'App\\Product';
        $subcategoryProductModel = 'App\\SubcategoryProduct';
        $categoryModel = 'App\\Category';
        $subcategoriesModel = 'App\\Subcategories';

        // Store brand
        $brand = Brand::updateOrCreate(
            ["name" => self::DEFAULT_BRAND],
            ["name" => self::DEFAULT_BRAND]
        );

        $infoToStore = json_decode($data->getContents());
        $count = 1;
        foreach($infoToStore->value as $o){
            $p = $productModel::updateOrCreate(
                ['plu' => $o->ItemCode],
                [
                    'quantity'                      => 0,
                    'max_units_per_order'           => 9999,
                    'price'                         => $this->getRegularPriceFromItem($o->ItemPrices),
                    'plu'                           => $o->ItemCode,
                    'name'                          => $o->ItemName,
                 // 'bin_location'                  => '',
                    'brand_id'                      => $brand->id,
                    'order'                         => $count,
                    'active'                        => true
                ]
            );

            $count;

            // Linkear product to category
            $category = $categoryModel::where('bo_code', $o->ItemsGroupCode)->first();
            $subcategory = $subcategoriesModel::where('name', $category->name)->first();
            $subcategoryProductModel::updateOrCreate(
                ['subcategory_id' => $subcategory->id , 'product_id' => $p->id],
                [
                    'subcategory_id' => $subcategory->id,
                    'product_id' => $p->id
                ]
                );
        }
    }

    public function getRegularPriceFromItem($itemPrices){
        foreach ($itemPrices as $ip) {
            if($ip->PriceList == self::REGULAR_LIST_PRICE_BASE){ // Lista de precios "Regular"
                return $ip->Price;
            }
        }
    }

    public function storeInformationBusinessPartners($data, $parameters){
        $userModel = 'App\\User';
        $userInfoModel = 'App\\UserInformation';
        $addressModel = 'App\\Address';
        $contactEmployeesModel = 'App\\BoContactEmployeesUser';


        $infoToStore = json_decode($data->getContents());
        foreach($infoToStore->value as $o){
            // $user = $userModel::where('document', $o->CardCode)->with("userInfo")->first();
            // Validacion de datos:
            if(!$o->CardName){
                continue;
            }

            $userMain = new User;
            $contactPerson = "";
            if($o->ContactEmployees && $o->ContactEmployees[0]){
                $contactPerson = $o->ContactEmployees[0]->FirstName . " " . $o->ContactEmployees[0]->MiddleName . " " . $o->ContactEmployees[0]->LastName;
                $contactPerson =  preg_replace('/\s+/', ' ', $contactPerson);
                $contactPerson = strtolower($contactPerson);
                $contactPerson = ucfirst($contactPerson);
            }

            $userInMain = $userMain::on("main-db")->updateOrCreate(
                ['document' => $o->CardCode],
                [
                    'first_name'  => $o->CardName,
                    'document'    => $o->CardCode,
                    'phone'       => $o->Phone1 ? $o->Phone1 : ($o->Phone2 ? $o->Phone2 : ($o->Cellular ? $o->Cellular : "N/A")),
                    'active'      => true,
                    'email'       => $o->EmailAddress,
                    'password'    => Hash::make($o->CardCode),
                    'rol_id'      => 4
                ]
            );

            $userInfoMain = new UserInformation;
            $userInfoInMain = $userInfoMain::on("main-db")->updateOrCreate(
                ['user_id' => $userInMain->id ],
                [
                    'user_id' => $userInMain->id,
                ]
            );

            $userLocal = new User;
            $userLocal = $userLocal::on($parameters->db_name)->updateOrCreate(
                ['id' => $userInMain->id],
                [
                    'id'         => $userInMain->id,
                    'first_name' => $o->CardName,
                    'document'   => $o->CardCode,
                    'phone'      => $o->Phone1 ? $o->Phone1 : ($o->Phone2 ? $o->Phone2 : ($o->Cellular ? $o->Cellular : "N/A")),
                    'active'     => true,
                    'email'      => $o->EmailAddress,
                    'password'   => Hash::make($o->CardCode),
                    'rol_id'     => 4,
                    'bo_price_list_id' => $this->getPriceList($o->PriceListNum),
                    'bo_contact_person' => $contactPerson,
                    'bo_account_balance' => $o->CurrentAccountBalance,
                    'bo_payment_term_type_id' => $this->getPaymentTermId($o->PayTermsGrpCode),
                    'bo_phone_1' => $o->Phone1,
                    'bo_phone_2' => $o->Phone2,
                    'bo_card_type' => $o->CardType,
                    'bo_valid' => $o->Valid == 'tYES' ? true : false,
                    'bo_tax_exempt' => $o->VatLiable == 'vExempted' ? true : false
                ]
            );

            $userInfoModel::on($parameters->db_name)->updateOrCreate(
                ['id' => $userInfoInMain->id ],
                [
                    'id' => $userInfoInMain->id,
                    'user_id' => $userInfoInMain->id,
                ]
            );

            if(($o->Valid == 'tNO') || ($o->CardType != 'cCustomer')){ // Si es un tipo diferente a Customer o no es valido no se crean el resto de data.
                continue;
            }

                foreach($o->BPAddresses as $bpaddress){
                    $existAddress = $addressModel::where('user_id', $userLocal->id)
                                                    ->where('direction', $bpaddress->AddressName)
                                                    ->first();

                    if(!$existAddress){
                        $addressModel::updateOrCreate(
                            [
                                'user_id' => $userLocal->id,
                                'tag' => $bpaddress->AddressType,
                                'direction' => $bpaddress->Street . ", " . $bpaddress->City . ", " . $bpaddress->State,
                            ],
                            [
                                'user_id' => $userLocal->id,
                                'tag' => $bpaddress->AddressType,
                                'direction' => $bpaddress->Street . ", " . $bpaddress->City . ", " . $bpaddress->State,
                                'active' => true,
                                // 'city_id' => $this->getCityId($bpaddress->State, $bpaddress->City),
                                'zip_code' => $bpaddress->ZipCode,
                                'last_used' => $bpaddress->AddressType == "bo_ShipTo" ? true : false,
                                'bo_sales_tax_code_id' => $bpaddress->AddressType == "bo_ShipTo" ? $this->getTaxCode($bpaddress->TaxCode, $o->CardCode) : null
                            ]
                        );
                    }
                }

                foreach($o->ContactEmployees as $bpContactEmployee){
                    $contactEmployeesModel::updateOrCreate(
                        [
                        "user_id" => $userLocal->id,
                         "name" => $bpContactEmployee->Name
                    ],
                    [
                        "user_id" => $userLocal->id,
                         "name" => $bpContactEmployee->Name,
                         "last_name" => $bpContactEmployee->LastName ? $bpContactEmployee->LastName : '',
                    ],
                    );
                }

        }
    }

    private function getCityId($state_code, $city_name){
        $state = State::where('code', $state_code)->first();
        $city = City::where('state_id', $state->id)->where('name', $city_name)->first();
        return $city->id;
    }

    private function getTaxCode($tax_code, $cardcode){
        try {
            $o = BoSalesTaxCode::where('code', $tax_code)->first();
            return $o->id;
        } catch(\Exception $e){
            return null;
        }

    }

    private function getPriceList($price_list_num){
        $o = BoPriceList::where('list_num', $price_list_num)->first();
        if($o){
            return $o->id;
        }
        return null;
    }

    private function getPaymentTermId($payment_group_number){
        $o = BoPaymentTermType::where('group_number', $payment_group_number)->first();
        if($o){
            return $o->id;
        }
        return null;
    }

    public function storeInformationSalesTaxCodes($data, $model){
        $appModel = 'App\\' . $model;

        $infoToStore = json_decode($data->getContents());
        foreach($infoToStore->value as $o){
            $appModel::updateOrCreate(
                ["code" => $o->Code],
                [
                    "code" => $o->Code,
                    "name" => $o->Name,
                    "rate" => $o->Rate,
                    "active" => ($o->Inactive == "tNO" ? true: false)
                ]);
        }
    }

    public function storeInformationBusinessPlace($data, $model){
        $appModel = 'App\\' . $model;

        $infoToStore = json_decode($data->getContents());
        foreach($infoToStore->value as $o){
            $appModel::updateOrCreate(
                ["bplid" => $o->BPLID],
                [
                    "bplid" => $o->BPLID,
                    "bplname" => $o->BPLName,
                    "address" => $o->Address,
                    "active" => ($o->Disabled == "tNO" ? true : false)
                ]);
        }
    }

    public function storeInformationPriceLists($data, $model){
        $appModel = 'App\\' . $model;

        $infoToStore = json_decode($data->getContents());
        foreach($infoToStore->value as $o){
            $appModel::updateOrCreate(
                ["list_num" => $o->PriceListNo],
                [
                    "base_num" => $o->PriceListName,
                     "list_num" => $o->PriceListNo,
                    "list_name" => $o->PriceListName,
                    "factor" => $o->Factor
                ]);
        }
    }

    public function storeInformationSpecialPrices($data, $model){
        $appModel = 'App\\' . $model;

        $infoToStore = json_decode($data->getContents());
        $currentProduct = null;
        $currentListPrice = null;
        foreach($infoToStore->value as $o){
            $currentProduct = $this->listProducts->where('plu', $o->ItemCode)->first();
            $currentListPrice = $this->listPriceLists->where('list_num', $o->PriceListNum)->first();
            $percentage = $o->SpecialPriceDataAreas[0];
            $quantity = $o->SpecialPriceDataAreas[0];

            if(!$currentProduct || !$currentListPrice){
                continue;
            }

            if(!$percentage->SpecialPriceQuantityAreas){
                continue;
            }

            $quantity = $o->SpecialPriceDataAreas[0]->SpecialPriceQuantityAreas[0]->Quantity;
            $percentage = $o->SpecialPriceDataAreas[0]->SpecialPriceQuantityAreas[0]->Discountin;

            if (strpos($o->CardCode, '*') !== false) { // Es un precio para lista de precios
                $appModel::updateOrCreate(
                    ["product_id" => $currentProduct->id,
                     "bo_price_list_id" => $currentListPrice->id,
                     "user_id" => null
                    ],
                    [
                        "user_id" => null,
                        "product_id" => $currentProduct->id,
                        "bo_price_list_id" => $currentListPrice->id,
                        "percentage" => $percentage,
                        "quantity" => $quantity
                    ]);

            } else { // Es precio para un cliente específico
                $currentClient = $this->listUsers->where('document', $o->CardCode)->first();
                $appModel::updateOrCreate(
                    ["product_id" => $currentProduct->id,
                     "bo_price_list_id" => $currentListPrice->id,
                     "user_id" => $currentClient->id
                    ],
                    [
                        "user_id" => $currentClient->id,
                        "product_id" => $currentProduct->id,
                        "bo_price_list_id" => $currentListPrice->id,
                        "percentage" => $percentage,
                        "quantity" => $quantity
                    ]);
            }
        }
    }

    public function storeInformationCreditCards($data, $model){
        $appModel = 'App\\' . $model;

        $infoToStore = json_decode($data->getContents());
        $count = 0;
        foreach($infoToStore->value as $o) {
            $count++;
            $appModel::updateOrCreate(
                [ "code" => $o->CreditCardCode ],
                [
                    "code" => $o->CreditCardCode,
                    "name" => $o->CreditCardName,
                    "gl_account" => $o->GLAccount,
                ]);
        }
    }

    public function storeInformationItemGroups($data, $model){
        $appModel = 'App\\' . $model;
        $subcategoryModel = 'App\\Subcategories';

        $infoToStore = json_decode($data->getContents());
        $count = 0;
        foreach($infoToStore->value as $o){
            $count++;
            $c = $appModel::updateOrCreate(
                [ "bo_code" => $o->Number ],
                [
                    "bo_code" => $o->Number,
                    "name" => $o->GroupName,
                    "active" => true,
                    "order" => $count
                ]);

            $subcategoryModel::updateOrCreate(
                [ "category_id" => $c->id ],
                [
                    "name" => $o->GroupName,
                    "active" => true,
                    "category_id" => $c->id,
                    "order" => $count
                ]
            );

        }
    }

    public function storeInformationPaymentTermsTypes($data, $model){
        $appModel = 'App\\' . $model;

        $infoToStore = json_decode($data->getContents());
        $count = 0;
        foreach($infoToStore->value as $o){
            $count++;
            $c = $appModel::updateOrCreate(
                [ "group_number" => $o->GroupNumber ],
                [
                    "group_number" => $o->GroupNumber,
                    "name" => $o->PaymentTermsGroupName,
                    "additional_days" => $o->NumberOfAdditionalDays,
                    "start_from" => $o->StartFrom,
                    "price_list_no" => $o->PriceListNo
                ]);
        }
    }

    function createDeliveryOrder($form_params){
        // POST  /DeliveryNotes

        // {
        //     "CardCode": "C1001",
        //     "DocDueDate": "2021-07-27",
        //     "BPL_IDAssignedToInvoice": 3,
        //     "DocumentLines": [
        //         {
        //             "BaseType": 17,
        //             "BaseEntry": 166314,
        //             "BaseLine": 1
        //         }
        //     ]
        // }
        $url_entity = $this->base_url . 'DeliveryNotes';
        $response = $this->client->request('POST', $url_entity , [
            'json' => $form_params,
            'headers' => [
                'Authorization' => $this->buildCredentials()
                ]
            ]);

        return json_decode($response->getBody()->getContents());
    }

    function createInvoice($form_params){
        // POST  /Invoices

        // {
        //     "CardCode": "C1001",
        //     "DocDueDate": "2021-07-27",
        //     "BPL_IDAssignedToInvoice": 3,
        //     "DocumentLines": [
        //         {
        //             "BaseType": 17,
        //             "BaseEntry": 166314,
        //             "BaseLine": 1
        //         }
        //     ]
        // }
        $url_entity = $this->base_url . 'Invoices';
        $response = $this->client->request('POST', $url_entity , [
            'json' => $form_params,
            'headers' => [
                'Authorization' => $this->buildCredentials()
                ]
            ]);

        return json_decode($response->getBody()->getContents());
    }

    public function storeInformationShippingType($data, $model){
        $appModel = 'App\\' . $model;

        $infoToStore = json_decode($data->getContents());
        foreach($infoToStore->value as $o){
            $appModel::updateOrCreate(
                ["id" => $o->Code],
                [
                    "id" => $o->Code,
                    "name" => $o->Name,
                ]);
        }
    }

    public function countEntity($entity, $filter){
        $url_entity = $this->base_url . $entity .'/$count'. $filter;
        $response = $this->client->request('GET', $url_entity , [
            'headers' => [
                'Authorization' => $this->buildCredentials()
                ]
            ]);

        return $response->getBody()->getContents();
    }

    public function buildClientRequest($entity, $method, $options){
        $url_entity = $this->base_url . $entity;
        $concat = "";


        if($options["filter"]){
            if($concat){
                $concat = $concat . '$filter=' . $options["filter"];
            }
            else{
                $concat = '?$filter=' . $options["filter"];
            }
        }

        if($options["top"]){
            if($concat){
                $concat = $concat . '&$top='. $options["top"];
            }
            else{
                $concat = '?$top=' . $options["top"];
            }
        }

        if($options["skip"]){
            if($concat){
                $concat = $concat . '&$skip='. $options["skip"];
            }
            else{
                $concat = '?$skip=' . $options["skip"];
            }
        }

        if(array_key_exists("orderby", $options)){
            if($options["orderby"]){
                if($concat){
                    $concat = $concat . '&$orderby='. $options["orderby"];
                }
                else{
                    $concat = '?$orderby=' . $options["orderby"];
                }
            }
        }

        if(array_key_exists("select", $options)){
            if($options["select"]){
                if($concat){
                    $concat = $concat . '&$select='. $options["select"];
                }
                else{
                    $concat = '?$select=' . $options["select"];
                }
            }
        }


        $url_entity = $url_entity . $concat;

        switch ($method) {
            case 'get':
                $response = $this->client->request('GET', $url_entity , [
                    'headers' => [
                        'Authorization' => $this->buildCredentials()
                        ]
                    ]);

                return $response;

                break;
            case 'post':
                return $this->client->post($url_entity);
                break;
            case 'put':
                return $this->client->put($url_entity);
                break;
            case 'delete':
                return $this->client->delete($url_entity);
                break;
            default:
                break;
        }
    }

    public function querySpecialPrices($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('SpecialPrices', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }


    public function queryEmployeesInfo($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('EmployeesInfo', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function querySalesPersons($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('SalesPersons', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryItemGroups($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('ItemGroups', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryCreditCards($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('CreditCards', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryItems($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('Items', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function querySalesTaxCodes($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('SalesTaxCodes', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryPriceLists($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('PriceLists', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryCustomers($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('Customers', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryOrders($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('Orders', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryBusinessPartners($filter = null, $top = null, $skip = null, $orderby = null, $select = null){
        $request = $this->buildClientRequest('BusinessPartners', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip, 'orderby' => $orderby, 'select' => $select));

        return $request->getBody();
    }

    public function queryShippingTypes($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('ShippingTypes', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryPaymentTermsTypes($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('PaymentTermsTypes', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function queryBusinessPlaces($filter = null, $top = null, $skip = null){
        $request = $this->buildClientRequest('BusinessPlaces', 'get', array('filter' => $filter, 'top' => $top, 'skip' => $skip));

        return $request->getBody();
    }

    public function createOrder($body){

        $url_entity = $this->base_url . 'Orders';
        $response = $this->client->request('POST', $url_entity , [
            'json' => $body,
            'headers' => [
                'Authorization' => $this->buildCredentials(),
                'Content-type' => 'application/json'
                ]
            ]);

        return json_decode($response->getBody()->getContents());
    }


    /**
     * createQueryInventory
     * Este método crea la Query en la base de datos de SAP B1.
     * Para seguir usando el API del Service Layer, y ser consumida posteriormente desde el propio ServiceLayer
     * Para los datos relacionados al inventario
     * @return void
     */
    public function createQueryInventory(){
        $url_entity = $this->base_url . 'SQLQueries';
        $request = $this->client->request('POST', $url_entity, [
            'json' => [
                "SqlCode" => self::INVENTORY_QUERY_NAME,
                "SqlName" => self::INVENTORY_QUERY_NAME,
                "SqlText"=> "SELECT T0.ItemCode, SUM(T2.OnHandQty) as TotalBin, T1.BinCode FROM OITW T0 INNER JOIN OBIN T1 ON T0.WhsCode = T1.WhsCode INNER JOIN OIBQ T2 ON ( T2.WhsCode = T0.WhsCode AND T1.AbsEntry = T2.BinAbs AND T0.ItemCode = T2.ItemCode )  INNER JOIN OITM T3 ON T0.ItemCode = T3.ItemCode  WHERE T3.SellItem = 'Y' AND T3.InvntItem = 'Y' AND T0.WhsCode = :WhsCode  AND T1.Disabled = 'N' AND T1.ReceiveBin = 'N' AND T1.RtrictResn IS NULL  AND T1.RtrictType =  0 AND T2.OnHandQty > 0 GROUP BY T0.ItemCode, T0.WhsCode, T1.BinCode ORDER BY T0.ItemCode"
            ],
            'headers' => [
                'Authorization' => $this->buildCredentials(),
                'Content-type' => 'application/json'
            ]
        ]);

        return $request->getBody();
    }

    /**
     * createQueryWarehouse
     * Este método crea la Query en la base de datos de SAP B1.
     * Para seguir usando el API del Service Layer, y ser consumida posteriormente desde el propio ServiceLayer
     * Para los datos relacionados al inventario
     * @return void
     */
    public function createQueryWarehouse(){
        $url_entity = $this->base_url . 'SQLQueries';
        $request = $this->client->request('POST', $url_entity, [
            'json' => [
                "SqlCode" => self::INVENTORY__WH_QUERY_NAME,
                "SqlName" => self::INVENTORY__WH_QUERY_NAME,
                "SqlText"=> "SELECT T0.ItemCode, SUM(T0.OnHand) AS TotalWarehouse FROM OITW T0  LEFT JOIN OITM T3 ON T0.ItemCode = T3.ItemCode  WHERE T0.WhsCode = :WhsCode AND T3.SellItem = 'Y' AND T3.InvntItem = 'Y' GROUP BY T0.ItemCode, T0.WhsCode ORDER BY T0.ItemCode"
            ],
            'headers' => [
                'Authorization' => $this->buildCredentials(),
                'Content-type' => 'application/json'
            ]
        ]);

        return $request->getBody();
    }

    /**
     * createQueryItemManualPrices
     * Este método crea la Query en la base de datos de SAP B1.
     * Para seguir usando el API del Service Layer, y ser consumida posteriormente desde el propio ServiceLayer
     * Relacionada a precios manuales del ITEM desde la tabla ITM1
     * @return void
     */
    public function createQueryItemManualPrices(){
        $url_entity = $this->base_url . 'SQLQueries';
        $request = $this->client->request('POST', $url_entity, [
            'json' => [
                "SqlCode" => self::ITEM_MANUAL_PRICES_QUERY_NAME,
                "SqlName" => self::ITEM_MANUAL_PRICES_QUERY_NAME,
                "SqlText"=> "SELECT T0.ItemCode, T1.Price, T1.Ovrwritten, T2.ListNum FROM OITM T0 INNER JOIN ITM1 T1 ON T0.ItemCode = T1.ItemCode INNER JOIN OPLN T2 ON T1.PriceList = T2.ListNum WHERE T1.Ovrwritten = 'Y'"
            ],
            'headers' => [
                'Authorization' => $this->buildCredentials(),
                'Content-type' => 'application/json'
            ]
        ]);

        return $request->getBody();
    }

    /**
     * deleteQueryInventory
     * elimina la Query en la base de datos de SAP B1.
     *
     * @return void
     */
    public function deleteQueryItemManualPrices(){
        try{
            $url_entity = $this->base_url . 'SQLQueries';
            $url_entity = $url_entity . "('" . self::ITEM_MANUAL_PRICES_QUERY_NAME . "')";
            $request = $this->client->request('DELETE', $url_entity, [
                'headers' => [
                    'Authorization'     => $this->buildCredentials()
                ]
            ]);

            return $request->getStatusCode();
        } catch(\Exception $ex){
            $this->logConsole("Error Deleting query item manual prices - " . $ex->getMessage());
        }

    }

    /**
     * deleteQueryInventory
     * elimina la Query en la base de datos de SAP B1.
     *
     * @return void
     */
    public function deleteQueryInventoryWarehouse(){
        try{
            $url_entity = $this->base_url . 'SQLQueries';
            $url_entity = $url_entity . "('" . self::INVENTORY__WH_QUERY_NAME . "')";
            $request = $this->client->request('DELETE', $url_entity, [
                'headers' => [
                    'Authorization'     => $this->buildCredentials()
                ]
            ]);

            return $request->getStatusCode();
        } catch(\Exception $ex){
            $this->logConsole("Error Deleting query item manual prices - " . $ex->getMessage());
        }

    }

    public function getAccountBalanceUser($user_id){
        $u = User::select('id', 'document', 'bo_account_balance')->where('id', $user_id)->first();
        $cardCode = $u->document;

        $filter = "CardCode eq '$cardCode'";
        $top = 1;
        $skip = 0;
        $orderby = null;
        $select = 'CardCode,CurrentAccountBalance';

        $o = $this->queryBusinessPartners($filter, $top, $skip, $orderby, $select);
        $infoReturned = json_decode($o->getContents());

        if(array_key_exists(0, $infoReturned->value)){
            $u->bo_account_balance = $infoReturned->value[0]->CurrentAccountBalance;
            $u->save();
        }

        return $u;
    }

    /**
     * executeQueryItemManualPrice
     * ejecuta el query de precios manuales del item
     */
    public function executeQueryItemManualPrice($skip){
        $url_entity = $this->base_url . "SQLQueries('" . self::ITEM_MANUAL_PRICES_QUERY_NAME  . "')/List?" . '$skip=' . $skip;

        $request = $this->client->get($url_entity, [
            'headers' => [
                'Authorization' => $this->buildCredentials()
            ]
        ]);

        return $request->getBody();
    }

    /**
     * deleteQueryInventory
     * Este método elimina la Query en la base de datos de SAP B1.
     *
     * @return void
     */
    public function deleteQueryInventory(){
        try {
            $url_entity = $this->base_url . 'SQLQueries';
            $url_entity = $url_entity . "('" . self::INVENTORY_QUERY_NAME . "')";
            $request = $this->client->request('DELETE', $url_entity, [
                'headers' => [
                    'Authorization'     => $this->buildCredentials()
                ]
            ]);

            return $request->getStatusCode();
        } catch(\Exception $ex){
            $this->logConsole("Error Deleting query item manual prices - " . $ex->getMessage());
        }
    }


    /**
     * getAllQueries
     * Obtiene las query Z creadas en el SAP B1
     * @return void
     */
    public function getAllQueries(){
        $url_entity = $this->base_url . 'SQLQueries';
        $request = $this->client->get($url_entity, [
            'headers' => [
                'Authorization'     => $this->buildCredentials()
            ]
        ]);

        $response = $request->getBody();
        $response = $response->getContents();
        $response = json_decode($response)->value;
        return $response;
    }

    public function createQueryInventoryItem(){
        $url_entity = $this->base_url . "SQLQueries";
        $request = $this->client->post($url_entity, [
            'form_params' => [
                "SqlCode" => self::INVENTORY_QUERY_NAME,
                "SqlName" => self::INVENTORY_QUERY_NAME,
                "SqlText"=> "SELECT T0.ItemCode, T0.WhsCode, SUM(T0.OnHand) AS TotalWarehouse, SUM(T2.OnHandQty) as TotalBin, T1.BinCode FROM OITW T0 INNER JOIN OBIN T1 ON T0.WhsCode = T1.WhsCode INNER JOIN OIBQ T2 ON ( T2.WhsCode = T0.WhsCode AND T1.AbsEntry = T2.BinAbs AND T0.ItemCode = T2.ItemCode ) WHERE T0.WhsCode = :WhsCode AND T1.Disabled = 'N' AND T1.ReceiveBin = 'N' AND T1.RtrictType =  0 AND T2.OnHandQty > 0  GROUP BY T0.ItemCode, T0.WhsCode, T1.BinCode"
            ],
            'headers' => [
                'Authorization' => $this->buildCredentials()
            ]
        ]);

        return $request->getBody();
    }

    public function executeQueryInventoryItem($warehouseCode, $skip){
        $url_entity = $this->base_url . "SQLQueries('" . self::INVENTORY_QUERY_NAME  . "')/List?WhsCode='" . $warehouseCode . '\'&$skip=' . $skip;

        $request = $this->client->get($url_entity, [
            'headers' => [
                'Authorization' => $this->buildCredentials()
            ]
        ]);

        return $request->getBody();
    }

    public function executeQueryInventoryWarehouseItem($warehouseCode, $skip){
        $url_entity = $this->base_url . "SQLQueries('" . self::INVENTORY__WH_QUERY_NAME  . "')/List?WhsCode='" . $warehouseCode . '\'&$skip=' . $skip;

        $request = $this->client->get($url_entity, [
            'headers' => [
                'Authorization' => $this->buildCredentials()
            ]
        ]);

        return $request->getBody();
    }

    public function cancelDelivery($internal_doument_b1) {
        $url_entity = $this->base_url . "DeliveryNotes({$internal_doument_b1})/Cancel";

        $request = $this->client->post($url_entity, [
            'headers' => [
                'Authorization' => $this->buildCredentials()
            ]
        ]);

        if($request->getStatusCode() == 200 || $request->getStatusCode() == 204) {
            return array('r' => true,  'd' => $request->getBody()->getContents());
        }

        return array('r' => false,  'd' => $request->getBody()->getContents());
    }

    public function postReturn($body, $return_id){

        try{
            $url_entity = $this->base_url . 'Returns';
            $response = $this->client->request('POST', $url_entity , [
                'json' => $body,
                'headers' => [
                    'Authorization' => $this->buildCredentials(),
                    'Content-type' => 'application/json'
                    ]
                ]);

            $response = json_decode($response->getBody()->getContents());
            $r = ReturnHeader::find($return_id);
            $r->bo_reference = $response->DocNum . '/' . $response->DocEntry;
            $r->is_open = false;
            $r->update();

            return array('r' => true,  'm' => 'Return succesfully created.', 'd' => $body, 'reference' => $response->DocEntry);
        }
        catch (\GuzzleHttp\Exception\ClientException $e) {
            $response = $e->getResponse();
            $responseBodyAsString = $response->getBody()->getContents();
            return array('r' => false, 'm' => $responseBodyAsString,  'd' => $body);
        }
        catch(\Exception $e){
            return array('r' => false, 'm' => $e->getMessage(),  'd' => $body);
        }
    }

    public function postCreditNote($body, $return_id){
        try{
            $url_entity = $this->base_url . 'CreditNotes';
            $response = $this->client->request('POST', $url_entity , [
                'json' => $body,
                'headers' => [
                    'Authorization' => $this->buildCredentials(),
                    'Content-type' => 'application/json'
                    ]
                ]);

            $response = json_decode($response->getBody()->getContents());
            $r = ReturnHeader::find($return_id);
            $r->bo_reference_credit_note = $response->DocNum . '/' . $response->DocEntry;

            $r->update();

            return array('r' => true,  'm' => 'Credit Note succesfully created.', 'd' => $body, 'reference' => $response->DocNum);
        }
        catch(\Exception $e){
            return array('r' => false, 'm' => $e->getMessage(),  'd' => $body);
        }
    }

    public function createReturn(Request $request){

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

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

        $sales_order = "";
        if($order->order_reference){
            $sales_order = explode("/", $order->order_reference);
            $sales_order = $sales_order[0];
        }

        $delivery_doc = "";
        if($order->bo_doc_delivery){
            $delivery_doc = explode("/", $order->bo_doc_delivery);
            $delivery_doc = $delivery_doc[0];
        }

        $body = [
            "CardCode" => $order->client->document,
            "BPL_IDAssignedToInvoice" => $order->bo_business_place_id,
            "SalesPersonCode" => Auth::user()->bo_sales_people_id,
            "Comments" => "Sales Order: " . $sales_order . " / Delivery: " . $delivery_doc,
            "DocumentLines" => [
                [
                    "ItemCode" => $order_item->product->plu,
                    "Quantity" => $order_item->quantity,
                    "TaxCode" => $order_item->bo_item_tax_code,
                    "UnitPrice" => $order_item->price,
                    "WarehouseCode" => $order_item->bo_warehouse_code,
                    "SalesPersonCode" => Auth::user()->bo_sales_people_id,
                ]
            ]
        ];

        try{
            $url_entity = $this->base_url . 'Returns';
            $response = $this->client->request('POST', $url_entity , [
                'json' => $body,
                'headers' => [
                    'Authorization' => $this->buildCredentials(),
                    'Content-type' => 'application/json'
                    ]
                ]);

            $response = json_decode($response->getBody()->getContents());
            $order_item->bo_return_state = true;
            $order_item->update();

            return array('r' => true,  'm' => 'Return succesfully created.', 'd' => $request);
        }
        catch(\Exception $e){
            return array('r' => false, 'm' => $e->getMessage(),  'd' => $body);
        }
    }

    public function getAbsEntryFromWarehouseCodeAndBinLocation($warehouseCode, $binLocation){
        $url_entity = $this->base_url . 'BinLocations?$filter=' . "Warehouse eq '$warehouseCode' and BinCode eq '$binLocation'";
        $response = $this->client->request('GET', $url_entity , [
            'headers' => [
                'Authorization' => $this->buildCredentials(),
                'Content-type' => 'application/json'
                ]
            ]);

        $return = json_decode($response->getBody()->getContents());
        return array('id' => $return->value[0]->AbsEntry);
    }

    public function postIncomingPayment($body, $o){
        try{
            $url_entity = $this->base_url . 'IncomingPayments';
            $response = $this->client->request('POST', $url_entity , [
                'json' => $body,
                'headers' => [
                    'Authorization' => $this->buildCredentials(),
                    'Content-type' => 'application/json'
                    ]
                ]);

            $response = json_decode($response->getBody()->getContents());
            $o->bo_incoming_payment = $response->DocNum . '/' . $response->DocEntry;

            $o->update();
            return array('r' => true,  'm' => 'Incoming payment succesfully created.', 'd' => $body);
        }
        catch(\Exception $e){
            return array('r' => false, 'm' => $e->getMessage(),  'd' => $body);
        }
    }

    function getCurrentWarehouse(){
        $parameters = Parameter::first();
        $warehouse = DB::connection('main-db')->table('service_cities')->where('name_database', $parameters->db_name)->first();

        return $warehouse->bo_default_warehouse;
    }
}