<?php

final class Mercadolivre extends MercadolivreUtils
{

    public function setAtualizarEstoque(MktProduto $produto, $mkt_product_id)
    {
        $produtoRetorno = $this->getProduto($mkt_product_id);

        return $this->setAtualizarEstoqueFromProdutos($produto, $produtoRetorno);
    }

    public function setAtualizarEstoqueFromProdutos(MktProduto $produto, MktProdutoRetorno $produtoRetorno)
    {

        $paramestoque = Array();
        $mercaId = $produtoRetorno->getmktIntegrationId();

        if (($produtoRetorno->getParam('listing_type_id') == Type_MercadoLivremercaListType::Tp_Free) || ($produtoRetorno->getParam('condition') == Type_MercadoLivreCondition::Tp_Used)) {
            $quantity = 1;
        } else {
            $quantity = $produto->getQuantity();
        }
        if ($produto->hasVariations()) {
            foreach ($produto->getVariacao() as $variacao) {
                if ((!empty($produto->getParam('mercaId')) && (!empty($produtoRetorno->getmktVariations())))) {
                    $key = array_search($variacao->getMktVariation_id(), array_column($produtoRetorno->getmktVariations(), 'id'));
                }
                if((ftr_validacao::validaTipo($variacao->getStatus(), TypeProduct_Status::Tp_Desabilitado))){
                    if ((!empty($produto->getParam('mercaId'))) && (!empty($key)) && (!empty($produtoRetorno->getmktVariations()[$key]->item_relations))){
                        $quantity = 0;
                    } else {
                        continue;
                    }
                } else {
                    if (($variacao->getQuantity() <= 0)) {
                        //continue;//caso n tiver mais quantidade, não sincroniza, que acaba removendo a variação....
                        $quantity = 0;
                    } else {
                        $quantity = $variacao->getQuantity();
                    }
                }

                if (!empty($variacao->getMktVariation_id())) {
                    $aux['id'] = $variacao->getMktVariation_id();
                    $aux['available_quantity'] = $quantity;
                    $aux['price'] = $this->currency->format($variacao->getValor() + $produto->getParam('meli_price_ajust'), Type_CodigoMoeda::Tp_MoedReal, false, false);
                    $paramestoque['variations'][] = $aux;
                }

            }

            if (isset($paramestoque['variations']) && sizeof($paramestoque['variations']) <= 0) {//caso n tiver mais variação ativa, atualiza como um produto normal...
                $paramestoque['variations'] = Array();
                $paramestoque['available_quantity'] = $quantity;
            }

        } else {
            $price_final = $produto->getPrice() + $produto->getParam('meli_price_ajust');

            if ($price_final <= 0) {
                throw new exception("Não é possivel sincronizar produtos com o preço negativo ou igual a 0!");
            }

            $paramestoque['available_quantity'] = $quantity;
            $paramestoque['price'] = $this->currency->format($price_final, Type_CodigoMoeda::Tp_MoedReal, false, false);
        }

        $meli_prod = $this->updateProduct($paramestoque, $mercaId);
        if ($this->error !== "") {
            throw new exception("Erro ao atualizar estoque. Retorno: " . $this->error);
        }

        $produtoRetorno = $this->getProduto($mercaId, $meli_prod);

        if (($produtoRetorno->getmktQuantity() > 0) && ($produto->getStatus() == Type_Status::Tp_Habilitado) && ($produto->getQuantity() > 0)) {
            if ($produtoRetorno->getmktstatus() !== Type_MercadoLivreItemStatus::Tp_Active) {

                $produtoRetorno = $this->active($mercaId);
                if ($this->error !== "") {
                    return false;
                }

                $produtoRetorno = $this->getProduto($mercaId, $produtoRetorno);
            }
        } else {
            if ($produtoRetorno->getmktstatus() !== Type_MercadoLivreItemStatus::Tp_Paused) {
                $produtoRetorno = $this->paused($mercaId);
                if ($this->error !== "") {
                    return false;
                }

                $produtoRetorno = $this->getProduto($mercaId, $produtoRetorno);
            }
        }

        $produto->setMktRetorno($produtoRetorno);
        return $produto;
    }


    public function setAtualizarProduto(MktProduto $produto, $data = array())
    {

        if (!empty($produto->getParam('mercaId'))) {
            $consultaProd = $this->getProduto($produto->getParam('mercaId'));
        }

        if ((!empty($produto->getParam('mercaId'))) && ($consultaProd->getmktStatus() == Type_MercadoLivreItemStatus::Tp_Closed)) {
            throw new ExceptionErrorShow('Esse produto está com status "fechado" e não pode ser sincronizado!');
        }

        if (!empty($produto->getParam('mercaId'))
            && !in_array($produto->getTipo(), [Type_ProdutoGrade::Tp_ProdutoAcabado, Type_ProdutoGrade::Tp_MercadoriaRevenda])
            && ($consultaProd->getProductType() == Type_ProdutoMkt::Tp_MktProd_Grade) && (count($produto->getVariacao()) > 1)) {
            throw new Exception('Este é um anúncio de grade que esta ligado a um produto normal no e-commerce');
        }

        //pré-validações para não precisar enviar para ver que da errado... by Matheus
        if (empty($produto->getParam('mercaId'))) {
            if ($produto->getStatus() == TypeProduct_Status::Tp_Desabilitado) {
                throw new ExceptionErrorShow("Não é possivel sincronizar produtos desabilitados");
            }

            if ($produto->getQuantity() <= 0) {
                throw new ExceptionErrorShow("Não é possivel sincronizar produtos com o estoque 0!");
            }
        }

        $price_final = $produto->getPrice() + $produto->getParam('meli_price_ajust');

        if ($price_final <= 0) {
            throw new exception("Não é possivel sincronizar produtos com o preço negativo ou igual a 0!");
        }

        $added_images = array();
        $list_images = array();

        if ((!$produto->hasVariations())) {
            $imagesProd = $produto->getPictures()->getImagens();
            if (Count($imagesProd) > 0) {
                foreach ($imagesProd as $key => $img) {
                    $list_images[] = array('source' => $this->url_encode($img->getLink()));
                }
            }
        }

        $title = $produto->getCustomTitle();
        if ((!isset($title)) || (empty($title))){
            $title = $produto->getName();
        }

        $jsonSend = array(
            'title' => $title,
            'video_id' => $produto->getIdYoutubeVideo(),
        );

        if ((!empty($produto->getParam('mercaId'))) && ($consultaProd->getmktQtdVendido() >= 1)) {
            unset($jsonSend['title']);
        }

        if ($produto->hasParam('attributes')) {
            $jsonSend['attributes'] = $produto->getParam('attributes');
        }

        if ($produto->hasParam('sale_terms')) {
            $jsonSend['sale_terms'] = $produto->getParam('sale_terms');
        }

        if (!$produto->hasVariations()) {
            if (($produto->getQuantity() > 0) && (empty($produto->getParam('mercaId')))) {

                if (($produto->getParam('mercaListType') == Type_MercadoLivremercaListType::Tp_Free) || ($produto->getParam('mercaCondition') == Type_MercadoLivreCondition::Tp_Used)) {
                    $jsonSend['available_quantity'] = 1;
                } else {
                    $jsonSend['available_quantity'] = $produto->getQuantity();
                }

            }

            $jsonSend['price'] = $this->currency->format($price_final, Type_CodigoMoeda::Tp_MoedReal, false, false);

        } else {
            $variationColor = $produto->getVariationColor();
            $variationSize = $produto->getVariationSize();
            $variationSpecification = $produto->getVariationSpecification();

            // compatibilizando com grades que ja existiam no mercado livre, antes de implementar as variações com templates
            if (!isset($variationColor) && !isset($variationSize) && !isset($variationSpecification)){
                $variationColor = 'COLOR';
                $variationSize  = 'SIZE';
                $variationSpecification = '';
            }

            $this->load->dmodel('mercadolivre/meliproduto');
            $variationsNotUsed = array_filter($this->mercadolivre->getAttributes($produto->getParam('category_id')));
            $variationsNotUsed[] = array('id' => 'CUSTOM', 'name' => 'Personalizado');
            $variationsNotUsed = array_filter($variationsNotUsed,
                function ($value) use ($variationColor, $variationSize, $variationSpecification){
                    return ! in_array(ftr_geral::removeAcentos(mb_strtolower($value['id'])),
                        array(ftr_geral::removeAcentos(mb_strtolower($variationColor)),
                            ftr_geral::removeAcentos(mb_strtolower($variationSize)),
                            ftr_geral::removeAcentos(mb_strtolower($variationSpecification))));
                });

            $addedVars = false;
            $imageMd5 = array();
            $this->load->model('mercadolivre/measure_manufacturer');

            foreach ($produto->getVariacao() as $variacao) {
                $bSizeGrid = 0;
                if ((!empty($produto->getParam('mercaId')) && (!empty($consultaProd->getmktVariations())))) {
                    $key = array_search($variacao->getMktVariation_id(), array_column($consultaProd->getmktVariations(), 'id'));
                }

                if((ftr_validacao::validaTipo($variacao->getStatus(), TypeProduct_Status::Tp_Desabilitado))){
                    if ((!empty($produto->getParam('mercaId'))) && (!empty($key)) && (!empty($consultaProd->getmktVariations()[$key]->item_relations))){
                        $quantity = 0;
                    } else {
                        continue;
                    }
                }else{
                    if ($variacao->getQuantity() <= 0) {

                        if (empty($produto->getParam('mercaId'))){
                            continue;
                        }else{
                            $quantity = 0;
                        }
                        //continue;//caso n tiver mais quantidade, não sincroniza, que acaba removendo a variação....
                    }else{
                        $quantity = $variacao->getQuantity();
                    }
                }

                $variationsItens = array();
                $attributes_var = array();
                $aux = array();

                //atributos automáticos pelo sistema...
                if (($variacao->getCodigoBarra() != "") && (!empty($variacao->getCodigoBarra()))) {
                    // antes era variável entre GTIN, EAN ou UPC, agora foi unificado como GTIN
                    $tipocod = 'GTIN';

                    if (in_array(substr($variacao->getCodigoBarra(), 0, 3), range(200, 299))) {
                        $attributes_var[] = array(
                            'id' => $tipocod,
                            'value_id' => null
                        );
                    } else {
                        $attributes_var[] = array(
                            'id' => $tipocod,
                            'value_name' => $variacao->getCodigoBarra()
                        );
                    }

                    //Inserção de tabela de Medidas para tamanhos.
                    $param = $produto->getParam('attributes');

                    foreach ($param as $key => $paramValue){
                        if($paramValue['id'] == 'SIZE_GRID_ID' AND $paramValue['value_name'] <> ''){

                            $codChart = $this->model_mercadolivre_measure_manufacturer->getChartSize($variacao->getTamanho(),$paramValue['value_name']);

                            $bSizeGrid = $codChart['BR_SIZE'];

                            if($codChart){
                                $attributes_var[] = array(
                                    'id' => 'SIZE_GRID_ROW_ID',
                                    'value_id' => "",
                                    'value_name' => $codChart['SIZE_GRID_ROW_ID']
                                );
                            }
                        }
                    }
                }

                $imagesProd = $variacao->getImagens()->getImagens();
                $added_images_variation = array();
                foreach ($imagesProd as $key => $img) {
                    $list_images[] = array('source' => $this->url_encode($img->getLink()));
                    $added_images_variation[] = $this->url_encode($img->getLink());
                }

                if (!empty($variacao->getCor())) {
                    $variationsItens[] = array(
                        "id" => $variationColor == 'CUSTOM' ? '' : $variationColor,
                        "name" => $variacao->getTemplateCor() ?? 'Cor',
                        "value_name" => $variacao->getCor()
                    );
                }

                if (!empty($variacao->getTamanho())) {
                    $variationsItens[] = array(
                        "id" => $variationSize == 'CUSTOM' ? '' : $variationSize,
                        "name" => $variacao->getTemplateTamanho() ?? 'Tamanho',
                        "value_name" => !$bSizeGrid ? $variacao->getTamanho() : $bSizeGrid. ' BR'
                    );
                }

                if (!empty($variacao->getEspecificacao())) {
                    $variationsItens[] = array(
                        "id" => $variationSpecification == 'CUSTOM' ? '' : $variationSpecification,
                        "name" => $variacao->getTemplateEspecificacao() ?? 'Especificacão',
                        "value_name" => $variacao->getEspecificacao()
                    );
                }

                // Limpa as variações que não serão usadas, senão fica lixo no mercado livre
                foreach ($variationsNotUsed as $value){
                    $variationsItens[] = array(
                        "id" => $value['id'],
                        "value_name" => null
                    );
                }

                $attribute_combinations = array_filter($variationsItens, function($array){
                    return !is_null($array['value_name']);
                });

                if ((!empty($produto->getParam('mercaId'))) && (!is_null($variacao->getMktVariation_id())) && ($variacao->getMktVariation_id() != '')
                && (!empty($consultaProd->getmktVariations())) ) {
                    $key = array_search($variacao->getMktVariation_id(), array_column($consultaProd->getmktVariations(), 'id'));

                    $produtoAttrCombinations  = array_column($attribute_combinations, 'id');
                    $consultaAttrCombinations = ((!empty($key)) ? array_column($consultaProd->getmktVariations()[$key]->attribute_combinations, 'id') : []);

                    if(count(array_diff($consultaAttrCombinations, $produtoAttrCombinations)) == 0){
                        $aux['id'] = $variacao->getMktVariation_id();
                    }
                }

                $aux['attribute_combinations'] = $attribute_combinations;
                $aux['price'] = $this->currency->format($variacao->getValor() + $produto->getParam('meli_price_ajust'), Type_CodigoMoeda::Tp_MoedReal, false, false);
                $aux['available_quantity'] = $quantity;
                $aux['attributes'] = $attributes_var;
                $aux['picture_ids'] = $added_images_variation;
                $aux['seller_custom_field'] = $variacao->getProductID();

                $jsonSend['variations'][] = $aux;
                $addedVars = true;
            }
        }

        if (($produto->hasVariations()) && (!$addedVars)) {
            $jsonSend['variations'] = array();
        }

        if (sizeof($list_images) > 0) {
            $jsonSend['pictures'] = $list_images;
        }

        $shipping = $produto->getParam('shipping');

        if ((in_array($produto->getParam('mercaShipping'), array(Type_MercadoLivreModoEnvio::Tp_NotSpecified, Type_MercadoLivreModoEnvio::Tp_MercadoEnvio20, Type_MercadoLivreModoEnvio::Tp_MercadoEnvio21))) &&
            ($price_final >= 120) && (empty($produto->getParam('mercaId')))) {
            $shipping['tags'] = array('mandatory_free_shipping');
        }

        $jsonSend['shipping'] = $shipping;

        $initial_description = $this->config->get('mercadolivre_initial_description') ?? '';
        $final_description   = $this->config->get('mercadolivre_final_description')   ?? '';

        trim($initial_description) != '' ? $initial_description = trim($initial_description) . "\n\n" : $initial_description =  '';
        trim($final_description)   != '' ? $final_description   = trim($final_description)            : $final_description   =  '';
        if (!empty($final_description) && !empty($produto->getDescription())){
            $final_description = "\n\n" . $final_description;
        }

        $description = $initial_description . $produto->getDescription() . $final_description;

        $desc = array();
        $desc['plain_text'] = $description;

        if (empty($produto->getParam('mercaId'))) {
            $jsonSend['currency_id'] = Type_CodigoMoeda::Tp_MoedReal;
            $jsonSend['buying_mode'] = Type_MercadoLivreMode::Tp_Buy_it_now;
            $jsonSend['listing_type_id'] = $produto->getParam('mercaListType');
            $jsonSend['condition'] = $produto->getParam('mercaCondition');
            $jsonSend['category_id'] = $produto->getParam('category_id');

            $proddata = $this->addProduct($jsonSend);

            if (!$proddata) {
                throw new exception($this->error);
            }
        } else {
            if ($consultaProd->getmktQtdVendido() == 0) {
                $jsonSend['category_id'] = $produto->getParam('category_id');
            }

            $proddata = $this->updateProduct($jsonSend, $produto->getParam('mercaId'));

            if (!$proddata) {
                throw new exception($this->error);
            }
        }

        if ((isset($jsonSend['variations'])) && (sizeof($jsonSend['variations']) > 0)) {
            if ((!isset($proddata->variations)) || (sizeof($proddata->variations) != sizeof($jsonSend['variations']))) {
                throw new exception('Erro ao enviar variações do produto, contate a futura sistemas!');
            }
        }

        //o campo seller_custom_field é utilizado na hora de enviar cada referencia, e fazermos referencia com os ids no nosso sistema...
        if ((isset($proddata->variations)) && (count($proddata->variations) > 0)) {
            $list_images_post['variations'] = Array();
            $aux = array();
            $imageMd5 = array();

            foreach ($proddata->variations as $key => $var_ml) {
                $variation = $produto->getVaricaoProductId($var_ml->seller_custom_field);
                if ($variation) {
                    $picture_ids = array();

                    $imagesVariacoes = $variation->getImagens()->getImagens();
                    foreach ($imagesVariacoes as $vimg) {
                        if (in_array($vimg->getImageMd5(), array_keys($imageMd5))) {
                            $picture_ids[] = $imageMd5[$vimg->getImageMd5()];
                        } else {
                            $imageMd5[$vimg->getImageMd5()] = $vimg->getLink();
                            $picture_ids[] = $vimg->getLink();
                        }
                    }

                    $aux[] = array(
                        'id' => $proddata->variations[$key]->id,
                        'picture_ids' => $picture_ids,
                    );

                    $variation->setMktVariation_id($proddata->variations[$key]->id);
                }
            }
            $list_images_post['pictures'] = $list_images;
            $list_images_post['variations'] = $aux;
        } else {
            $list_images_post = array('pictures' => $list_images);
        }


        if (!$this->updateProductDescription($desc, $proddata->id)) {
            throw new exception($this->error);
        }

        $pictures = $this->sendPictures($proddata->id, $list_images_post);
        if (!$pictures) {
            throw new exception($this->error);
        }

        $mktRetorno = $this->getProduto($proddata->id, $proddata);
        $produto->setMktRetorno($mktRetorno);

        return $produto;
    }


    public function setDesincronizarProduto($marketId, $id)
    {
        // finaliza os anuncios de catalogos linkados ao principal
        $this->load->dmodel('mercadolivre/meliproduto');
        $catalogAds = $this->dmodel_mercadolivre_meliproduto->getMercadolivreAdCatalogByAdId($id);
        if ($catalogAds){
            foreach ($catalogAds as $value){
                $delete = $this->delete($value['catalog_ad']);
                if (!$delete) {
                    throw new exception($this->error);
                }
            }
        }

        $delete = $this->delete($marketId);

        if (!$delete) {
            throw new exception($this->error);
        } else {
            return true;
        }
    }

    public function getOrder($mktOrderId)
    {
        $this->getAccess();
        $meli_pedido = $this->getmeliOrder($mktOrderId);

        $shippingid = $meli_pedido->shipping->id;
        $pack_id = isset($meli_pedido->pack_id) ? $meli_pedido->pack_id : null;
        $address_combinar = ((is_null($shippingid)) && (is_null($pack_id)));

        $buyer = new MktBuyer();
        $buyerSendAdd = new MktAddress();
        $pedido = new MktPedido();
        $meli_address = new stdClass;

        if ((!$address_combinar)) {
            $meli_address = $this->getShipments($shippingid);
            if (!$meli_address) {
                throw new exception($this->error);
            }
        }

        $hasShipping = (isset($meli_pedido->shipping) && $meli_pedido->shipping->id && isset($meli_address->destination->shipping_address) && $meli_address->destination->shipping_address->zip_code);
        if($hasShipping){
            $meli_pedido_billing = $this->getmeliOrderBillingInfo($mktOrderId);
        }

        $orderComment = '';
        $docType = null;
        $docnumber = null;
        if (isset($meli_pedido_billing) && $meli_pedido_billing) {
            $docType = $this->getPropery($meli_pedido_billing->billing_info, 'doc_type', false);
            $docnumber = $this->getPropery($meli_pedido_billing->billing_info, 'doc_number', false);
        }

        switch ($docType) {
            case 'CPF':
                $buyer->setTipoPessoa(Type_Pessoa::TpPess_fisica);
                $buyer->setDocumento($docnumber);
                break;

            case 'CNPJ':
                $buyer->setTipoPessoa(Type_Pessoa::TpPess_Juridica);
                $buyer->setDocumento($docnumber);
                break;

            default:
                $buyer->setTipoPessoa(Type_Pessoa::TpPess_naoInformado);
        }

        // 06/03/2020
        // futuramente será removido o telefone do comprador, tirar se for o caso - não estou tirando ainda, a pedido do matheus, para não parar de funcionar da forma atual
        $telefoneTemp = '';
        if (property_exists($meli_pedido->buyer, 'phone')) {
            $telefoneTemp = $this->getPropery($meli_pedido->buyer->phone, 'area_code', '');
            $telefoneTemp .= $this->getPropery($meli_pedido->buyer->phone, 'number', '');
            $telefoneTemp .= $this->getPropery($meli_pedido->buyer->phone, 'extension', '');
        }
        $telefone = $this->meli_formataphone($telefoneTemp);

        $meli_address_dest = new stdClass;
        if (!$address_combinar) {
            $meli_address_dest = $meli_address->destination->shipping_address;
        }

        $valcity = isset($meli_address_dest->city) ? $meli_address_dest->city : 'Mercadolivre';
        $city = $this->getPropery($valcity, 'name', 'Mercadolivre');
        $valState = isset($meli_address_dest->state) ? $meli_address_dest->state : '';
        $valNeightboorHood = isset($meli_address_dest->neighborhood) ? $meli_address_dest->neighborhood : 'Mercadolivre';

        $address_1 = $this->getPropery($meli_address_dest, 'street_name', 'Mercadolivre');
        $address_2 = $this->getPropery($valNeightboorHood, 'name', 'Mercadolivre');
        $numero = trim($this->getPropery($meli_address_dest, 'street_number', '0'));
        if (strlen($numero) > 6) {
            $orderComment .= 'Foi informado um valor inválido no campo número do endereço: ' . $numero;
            $numero = 0;
        } else {
            $numero = ($numero != 'SN') ? $numero : 0;
            //caso tenha letras no numero, inclui no complemento...
            $complementoNumero = (strlen(preg_replace("/[^0-9]/", "", $numero)) !== strlen($numero)) ? 'N:' . $numero : '';
            $complementoNumero = $this->getPropery($meli_address_dest, 'comment', '') . $complementoNumero;
            $numero = preg_replace("/[^0-9]/", "", $numero);
            if (empty($numero)){
                $numero = 0;
            }
        }
        $state_code = $this->getPropery($valState, 'id');
        $postcode = preg_replace('/([^0-9])/i', '', $this->getPropery($meli_address_dest, 'zip_code', '00000000'));

        if (!empty($state_code)) list($country_code, $state_code) = explode('-', $state_code);

        if ($address_combinar) {
            $country_code = Type_mktCountry::Tp_PaisBrasil;
        }

        if ($hasShipping){
            $buyerSendAdd
                ->setBairro($address_2)
                ->setCidade($city)
                ->setComplemento($complementoNumero)
                ->setLogradouro($address_1)
                ->setNumero($numero)
                ->setLogradouroTipo('')
                ->setPais($country_code)
                ->setPostCode($postcode)
                ->setUf($state_code);
        }

        $buyer
            ->setMktBuyerId($this->getPropery($meli_pedido->buyer, 'id'))
            ->setSendAddress($buyerSendAdd)
            ->setBillingAddress($buyerSendAdd)
            ->setPhone($telefone)
            ->setDocumento($docnumber)
            ->setFirstName($this->getPropery($meli_pedido->buyer, 'first_name'))
            ->setLastName($this->getPropery($meli_pedido->buyer, 'last_name') . '(Nick: ' . $this->getPropery($meli_pedido->buyer, 'nickname') . ')');

        if (!$address_combinar) {
            $meli_itens = $this->getShipmentsItems($shippingid);
            if (!$meli_itens) {
                throw new exception($this->error);
            }
        } else {
            $meli_itens[0] = new stdClass;
            $meli_itens[0]->order_id = $mktOrderId;
        }

        $resultPayments = array_filter($meli_pedido->payments, function ($item) {
            return in_array($item->status, ['approved', 'pending']);
        });
        foreach ($resultPayments as $payments) {
            $paymentObj = new MktPedidoPayment();

            $paymentObj
                ->setCode($payments->payment_type)
                ->setDate($payments->date_approved)
                ->setDescription($payments->payment_type)
                ->setParcels($payments->installments)
                ->setPaymentId($payments->id)
                ->setAuthorizationCode($payments->authorization_code)
                ->setValue($payments->total_paid_amount)
                ->setStatus($payments->status)
                ->setFlagText($payments->payment_method_id ?? '');

            $pedido->addPayments($paymentObj);
        }

        $sub_total = 0;
        $totalgeral = 0;
        foreach ($meli_itens as $meli_item) {
            $meli_orderid = $this->getPropery($meli_item, 'order_id', 0);

            if ($meli_orderid == 0) {
                throw new exception('Item de pedido não vinculado a nenhuma venda! Contate a futura sistemas!');
            }

            //dados do item, precisa pegar da venda, mercado livre maluco! :(
            $meli_pedido = $this->getmeliOrder($meli_orderid);
            if (!$meli_pedido) {
                throw new exception($this->error);
            }

            $meli_produto = $meli_pedido->order_items[0];
            $meli_product_id = $this->getPropery($meli_produto->item, 'id');
            $quantity = $this->getPropery($meli_produto, 'quantity', 1);
            $price = $this->getPropery($meli_produto, 'unit_price', 0);
            $totalgeral += $this->getPropery($meli_pedido, 'total_amount', 0);
            $sub_total += (float)$price * (float)$quantity;

            $product_info = $this->ml_getproduct($meli_product_id);
            if (!$product_info) {
                throw new exception($this->error);
            }

            $item = new MktPedidoItem();
            $item
                ->setMktId($meli_product_id)
                ->setQuantity($quantity)
                ->setProductName($this->getPropery($meli_produto->item, 'title'))
                ->setMktVariationId($this->getPropery($meli_produto->item, 'variation_id', null))
                ->setPrice($price)
                ->setMktIdOrderItem($meli_orderid)
                ->setParam('listing_type_id', $this->getPropery($product_info, 'listing_type_id', ''));

            $pedido->addItens($item);
        }

        if (!$address_combinar) {
            $meli_shipping_cost = $this->getShipmentsCosts($shippingid);
            if (!$meli_shipping_cost) {
                throw new exception($this->error);
            }
            $shipping_list_cost = $this->getPropery($meli_shipping_cost->senders[0], 'cost', 0);
        } else {
            //envio a combinar não tem informação...
            $shipping_list_cost = 0;
        }

        $valCost = isset($meli_shipping_cost->receiver) ? $meli_shipping_cost->receiver : 0;
        $shipping_cost = $this->getPropery($valCost, 'cost', 0);

        $shippingFull = ((isset($meli_address->logistic->type)) && ($meli_address->logistic->type == Type_MercadoLivreLogistic::Tp_Fulfillment));

        if ($shippingFull) {
            $shippingName = Type_MercadoLivreModule::getNickFromConstValue(Type_MercadoLivreModule::Tp_Shipping) . ' ' .
                            Type_MercadoLivreLogistic::getNickFromConstValue(Type_MercadoLivreLogistic::Tp_Fulfillment);
        } else {
            $shippingName = '';
        }

        $pedido
            ->setSubTotal($sub_total)
            ->setMktId($mktOrderId)
            ->setBuyer($buyer)
            ->setDateCreated($meli_pedido->date_created)
            ->setAddressCombinar($address_combinar)
            ->setmktIntegration(Type_MarketPlace::Tp_Mercadolivre)
            ->setMkTipo(Type_MarketplaceInt::Tp_Meli)
            ->setShippingCost($shipping_cost)
            ->setShippingName($shippingName)
            ->setComment($orderComment)
            ->setParam('shipping_fulfillment', $shippingFull)
            ->setParam('meli_pack_id', $pack_id)
            ->setParam('meli_shipping_id', $shippingid)
            ->setParam('mercadolivre_shipping_substatus', $this->getPropery($meli_address, 'substatus', null))
            ->setParam('shipping_list_cost', $shipping_list_cost)
            ->setParam('status', $meli_pedido->status)
            ->setParam('mercadolivre_shipping_status', $this->getPropery($meli_address, 'status', null))
            ->setParam('meli_shipping_code', isset($meli_address->logistic) ? $this->getPropery($meli_address->logistic, 'mode', null) : null );

        return $pedido;

    }

    public function getProduto($MktProdId, $mkt_produto = null)
    {

        if (($mkt_produto == null) || (!$mkt_produto)) {
            $mkt_produto = $this->ml_getproduct($MktProdId);

            if ($this->error!='') {
                throw new exception($this->error);
            }
        }

        $retorno = new MktProdutoRetorno();
        $retorno->setmktIntegrationId($mkt_produto->id);
        $retorno->setmktStatus($mkt_produto->status);
        $retorno->setmktLink($mkt_produto->permalink);
        $retorno->setmktQuantity($mkt_produto->available_quantity);
        $retorno->setmktPrice($mkt_produto->price);
        $retorno->setmktName($mkt_produto->title);
        $retorno->setmktIdVIdeoYoutube($mkt_produto->video_id);
        $retorno->setmktQuantity($mkt_produto->available_quantity);
        $retorno->setmktQtdVendido($mkt_produto->sold_quantity);
        $retorno->setmktTipo(Type_MarketPlace::Tp_Mercadolivre);

        if ($mkt_produto->variations) {
            $retorno->setmktVariations($mkt_produto->variations);
            $retorno->setProductType(Type_ProdutoMkt::Tp_MktProd_Grade);
        } else {
            $retorno->setProductType(Type_ProdutoMkt::Tp_MktProd_Normal);
        }

        foreach ($mkt_produto as $key => $value) {
            $retorno->setParam($key, $value);
        }

        return $retorno;
    }

}