diff --git a/CHANGELOG.md b/CHANGELOG.md index ebc335e..79df20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ Changelog --------- +3.11.0 +- Checkout sem endereço (para produtos do tipo 'virtual' e 'downloadable') +- Valida se o telefone do comprador foi configurado antes de tentar usar o telefone do endereço de entrega +- Habilitar/desabilitar recuperação de carrinho do PagSeguro via admin +- Atualizada versão da biblioteca PHP do PagSeguro usada no módulo +- Tela de listar transações no admin, permitindo ver detalhes da transação +- Estorno parcial +- Fix: Corrigido id dos itens do pedido (carrinho) enviados para o PagSeguro + 3.5.1 - Corrigido bug de incompatibilidade com PHP 5.4 no checkout diff --git a/README.md b/README.md index a442c9e..25fb0d1 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Com o módulo instalado e configurado, você pode pode oferecer o PagSeguro como - Certifique-se de que não há instalação de outros módulos para o PagSeguro em seu sistema; - Caso utilize a compilação do Magento, desative-a e limpe-a *(Sistema -> Ferramentas -> Compilação)*; -- Baixe a última versão do módulo **[nesse link](https://github.com/pagseguro/magento/raw/master/UOL_PagSeguro-3.5.1.tgz)** ou então baixe o repositório como arquivo zip através do botão do GitHub; +- Baixe a última versão do módulo **[nesse link](https://github.com/pagseguro/magento/raw/master/UOL_PagSeguro-3.11.0.tgz)** ou então baixe o repositório como arquivo zip através do botão do GitHub; - Na área administrativa do seu Magento, acesse o menu *Sistema/System -> Magento Connect -> Magento Connect Manager*. Caso tenha uma versão anterior do módulo instalada faça a remoção agora; - No Magento Connect Manger, dentro da seção Direct package file upload, clique em **Escolher arquivo/Choose file**, selecione o arquivo UOL_PagSeguro-x.x.x.tgz (baixado anteriormente), clique no botão de upload e acompanhe a instalação do módulo no console da página; - Caso utilize a compilação, volte para a área administrativa do Magento, ative-a e execute-a novamente; @@ -97,6 +97,7 @@ Para acessar e configurar o módulo acesse o menu PagSeguro -> Configurações. - **transações -> cancelamento**: esta pesquisa retornará todas as transações que estejam com status "em análise" e "aguardando pagamento", dentro da quantidade de dias definidos para a pesquisa. Desta forma você pode solicitar o cancelamento destas transações. - **transações -> conciliação**: permite consultar as transações efetivadas no PagSeguro nos últimos 30 dias. A pesquisa retornará um comparativo com o status das transações em sua base local e o status atual da transação no PagSeguro, desta forma você pode identificar e atualizar transações com status divergentes. - **transações -> estorno**: esta pesquisa retornará todas as transações que estejam com status "paga", "disponível" e "em disputa", dentro da quantidade de dias definidos para a pesquisa. Desta forma você pode solicitar o estorno dos valores pagos para seus compradores. + - **transações -> listar transações**: esta pesquisa retorna as últimas transações realizadas pela sua loja no PagSeguro, permitindo utilizar diversos filtros (data, id do pedido, do pagseguro, status) ao realizar uma consulta. A partir do resultado dessa consulta é possível ver os detalhes de cada pedido no PagSeguro através da ação "Ver detalhes transação". - **requisitos**: exibe se os pré-requisitos básicos para o correto funcionamento do módulo estão sendo atendidos > É aconselhável que antes de usar as funcionalidades de **estorno** ou **cancelamento** você faça a **conciliação** de suas transações para obter os status mais atuais. diff --git a/UOL_PagSeguro-3.11.0.tgz b/UOL_PagSeguro-3.11.0.tgz new file mode 100644 index 0000000..657a3c3 Binary files /dev/null and b/UOL_PagSeguro-3.11.0.tgz differ diff --git a/UOL_PagSeguro-3.5.1.tgz b/UOL_PagSeguro-3.5.1.tgz deleted file mode 100644 index aeb75db..0000000 Binary files a/UOL_PagSeguro-3.5.1.tgz and /dev/null differ diff --git a/app/code/community/UOL/PagSeguro/Helper/Data.php b/app/code/community/UOL/PagSeguro/Helper/Data.php index 445d122..b816426 100644 --- a/app/code/community/UOL/PagSeguro/Helper/Data.php +++ b/app/code/community/UOL/PagSeguro/Helper/Data.php @@ -49,6 +49,7 @@ class UOL_PagSeguro_Helper_Data extends Mage_Payment_Helper_Data 7 => "cancelada_ps", 8 => "chargeback_debitado_ps", 9 => "em_contestacao_ps", + 10 => "partially_refunded", ); /** @@ -456,7 +457,7 @@ final public function notificationModel() * * @throws Exception */ - public function updateOrderStatusMagento($class, $orderId, $transactionCode, $orderStatus) + public function updateOrderStatusMagento($class, $orderId, $transactionCode, $orderStatus, $refundValue = null) { try { if ( @@ -464,17 +465,24 @@ public function updateOrderStatusMagento($class, $orderId, $transactionCode, $or || $class == self::CANCELED_CLASS || $class == self::REFUND_CLASS ) { + $comment = null; if ($class == self::CANCELED_CLASS) { if ($this->webserviceHelper()->cancelRequest($transactionCode)->getResult() == 'OK') { $orderStatus = 'cancelada_ps'; } } if ($class == self::REFUND_CLASS) { - if ($this->webserviceHelper()->refundRequest($transactionCode)->getResult() == 'OK') { - $orderStatus = 'devolvida_ps'; + if ($this->webserviceHelper()->refundRequest($transactionCode, $refundValue)->getResult() == 'OK') { + /* if have refund value is an partially refund, so the status should be keeped */ + if ($refundValue) { + $comment = 'Estornado valor de R$' . $refundValue . ' do seu pedido.'; + $this->setPartiallyRefundedStatus($orderId); + } else { + $orderStatus = 'devolvida_ps'; + } } } - $this->notifyCustomer($orderId, $orderStatus); + $this->notifyCustomer($orderId, $orderStatus, $comment); Mage::helper('pagseguro/log')->setUpdateOrderLog($class, $orderId, $transactionCode, $orderStatus); } $this->setTransactionRecord($orderId, $transactionCode); @@ -499,10 +507,9 @@ protected function getLastStatusOrder($orderId) * @param $orderId * @param $orderStatus */ - private function notifyCustomer($orderId, $orderStatus) + private function notifyCustomer($orderId, $orderStatus, $comment = null) { $status = $orderStatus; - $comment = null; $notify = true; $order = Mage::getModel('sales/order')->load($orderId); $order->addStatusToHistory($status, $comment, $notify); @@ -811,4 +818,19 @@ public function getTransactionTypeName($transactionTypeCode) } } } + + /** + * Updates respective order partially refunded status to 1 in pagseguro_orders table + * + * @param string $orderId + * @return void + */ + public function setPartiallyRefundedStatus($orderId) + { + try { + Mage::helper('pagseguro/refund')->setPartiallyRefunded($orderId); + } catch (Exception $pse) { + throw $pse; + } + } } diff --git a/app/code/community/UOL/PagSeguro/Helper/Refund.php b/app/code/community/UOL/PagSeguro/Helper/Refund.php index 2475c6a..b996071 100644 --- a/app/code/community/UOL/PagSeguro/Helper/Refund.php +++ b/app/code/community/UOL/PagSeguro/Helper/Refund.php @@ -117,8 +117,13 @@ protected function getMagentoPayments() $date = $date->format("Y-m-d\TH:i:s"); $collection = Mage::getModel('sales/order')->getCollection() ->addAttributeToFilter('created_at', array('from' => $date, 'to' => date('Y-m-d H:i:s'))); + /** used to validate if an order is already refunded (could be refunded only one time) */ + $partiallyRefundedOrdersArray = $this->getPartiallyRefundedOrders(); + foreach ($collection as $order) { - $this->magentoPaymentList[] = $order->getId(); + if (! in_array($order->getId(), $partiallyRefundedOrdersArray)) { + $this->magentoPaymentList[] = $order->getId(); + } } } @@ -211,10 +216,14 @@ public function build($PagSeguroSummaryItem, $order) $config = " onclick='Modal.alertConciliation("" .$this->alertConciliation($this->__('estornar'))."")'"; } + //echo '
';print_r($PagSeguroSummaryItem);exit;
         $actionOrder = "";
         $actionOrder .= $this->__('Ver detalhes')."";
         $actionOrder .= "";
-        $actionOrder .= $this->__('Estornar')."";
+        $actionOrder .= $this->__('Estorno total')."";
+        $config = "class='action' data-config='".$order->getId().'/'.$PagSeguroSummaryItem->getCode().'/'.$this->getPaymentStatusFromKey($PagSeguroSummaryItem->getStatus()).'/'.$PagSeguroSummaryItem->getGrossAmount().'/'.$order->getIncrementId()."'";
+        $actionOrder .= "";
+        $actionOrder .= $this->__('Estorno parcial')."";
 
         return array(
             'date'           => $this->getOrderMagetoDateConvert($order->getCreatedAt()),
@@ -224,4 +233,54 @@ public function build($PagSeguroSummaryItem, $order)
             'action'         => $actionOrder,
         );
     }
+
+    /**
+     * Get all pagseguro partially refunded orders id
+     *
+     * @return array
+     */
+    private function getPartiallyRefundedOrders()
+    {
+        $pagseguroOrdersIdArray = array();
+        $resource = Mage::getSingleton('core/resource');
+        $read = $resource->getConnection('core_read');
+        $pagseguroTable = Mage::getConfig()->getTablePrefix().'pagseguro_orders';
+
+
+        $select = $read->select()
+            ->from(array('ps' => $pagseguroTable), array('order_id'))
+            ->where('ps.partially_refunded = ?', '1')
+        ;
+
+        if (!is_null(Mage::getSingleton('core/session')->getData("store_id"))) {
+            $select = $select->where('ps.store_id = ?', Mage::getSingleton('core/session')->getData("store_id"));
+        }
+
+        if (Mage::getStoreConfig('payment/pagseguro/environment')) {
+            $select = $select->where('ps.environment = ?', Mage::getStoreConfig('payment/pagseguro/environment'));
+        }
+
+        $read->prepare($select);
+
+        foreach ($read->fetchAll($select) as $value) {
+            $pagseguroOrdersIdArray[] = $value['order_id'];
+        }
+
+        return $pagseguroOrdersIdArray;
+    }
+
+    /**
+     * Set 1 to partially_refunded field in pagseguro_orders table
+     *
+     * @param string $orderId
+     * @return void
+     */
+    public function setPartiallyRefunded($orderId)
+    {
+        $pagseguroTable = Mage::getConfig()->getTablePrefix().'pagseguro_orders';
+        $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
+        $where = $connection->quoteInto('order_id = ?', $orderId);
+        $data = array('partially_refunded' => 1);
+        $connection->update($pagseguroTable, $data, $where);
+    }
 }
diff --git a/app/code/community/UOL/PagSeguro/Helper/Transactions.php b/app/code/community/UOL/PagSeguro/Helper/Transactions.php
index cd3d5e0..ad9bb5a 100644
--- a/app/code/community/UOL/PagSeguro/Helper/Transactions.php
+++ b/app/code/community/UOL/PagSeguro/Helper/Transactions.php
@@ -70,6 +70,7 @@ private function getTransactionsDatabase($paramsFilter)
             ->join(array('ps' => $pagseguroTable), 'order.entity_id = ps.order_id')
             ->where('ps.transaction_code != ?', '')
             ->order('created_at DESC')
+            ->limit(400)
         ;
 
         if (!is_null(Mage::getSingleton('core/session')->getData("store_id"))) {
@@ -89,7 +90,9 @@ private function getTransactionsDatabase($paramsFilter)
         }
 
         if (isset($paramsFilter['status'])) {
-            $select = $select->where('order.status = ?', $this->getPaymentStatusFromKey($paramsFilter['status']));
+            $select =  ($this->getPaymentStatusFromKey($paramsFilter['status']) == 'partially_refunded')
+                ? $select->where('ps.partially_refunded = ?', 1)
+                : $select->where('order.status = ?', $this->getPaymentStatusFromKey($paramsFilter['status']));
         }
 
         if (isset($paramsFilter['startDate']) && isset($paramsFilter['endDate'])) {
diff --git a/app/code/community/UOL/PagSeguro/controllers/Adminhtml/RefundController.php b/app/code/community/UOL/PagSeguro/controllers/Adminhtml/RefundController.php
index 195253e..27c975b 100644
--- a/app/code/community/UOL/PagSeguro/controllers/Adminhtml/RefundController.php
+++ b/app/code/community/UOL/PagSeguro/controllers/Adminhtml/RefundController.php
@@ -46,12 +46,14 @@ public function doRefundAction()
         if ($this->getRequest()->getPost('data')) {
             $data = current($this->getRequest()->getPost('data'));
             try {
+                $refundValue = $data['refundValue'] ? number_format(floatval($data['refundValue']), 2, '.', '') : null;
                 $this->refund->updateOrderStatusMagento(get_class($this->refund), $data['id'], $data['code'],
-                    $data['status']);
+                    $data['status'], $refundValue);
             } catch (Exception $pse) {
+                $erro = simplexml_load_string($pse->getMessage());
                 print json_encode(array(
                         "status" => false,
-                        "err"    => trim($pse->getMessage()),
+                        "err"    => trim(current($erro->error->code)),
                     )
                 );
                 exit();
diff --git a/app/code/community/UOL/PagSeguro/etc/config.xml b/app/code/community/UOL/PagSeguro/etc/config.xml
index 75dc26f..6e79bed 100644
--- a/app/code/community/UOL/PagSeguro/etc/config.xml
+++ b/app/code/community/UOL/PagSeguro/etc/config.xml
@@ -19,7 +19,7 @@ limitations under the License.
 
     
         
-            3.5.1
+            3.11.0
         
     
     
diff --git a/app/code/community/UOL/PagSeguro/sql/uol_pagseguro_setup/mysql4-upgrade-3.5.1-3.6.0.php b/app/code/community/UOL/PagSeguro/sql/uol_pagseguro_setup/mysql4-upgrade-3.5.1-3.6.0.php
new file mode 100644
index 0000000..969435b
--- /dev/null
+++ b/app/code/community/UOL/PagSeguro/sql/uol_pagseguro_setup/mysql4-upgrade-3.5.1-3.6.0.php
@@ -0,0 +1,35 @@
+startSetup();
+/** 
+ * Add column to validate if a transaction has been already partially refunded
+*/
+$installer->getConnection()
+    ->addColumn($installer->getTable('pagseguro_orders'), 'partially_refunded', array(
+        'type' => Varien_Db_Ddl_Table::TYPE_BOOLEAN,
+        'nullable' => false,
+        'default' => 0,
+        'comment' => 'Show if order is already partially refunded',
+    )
+);
+
+$installer->endSetup();
diff --git a/app/design/adminhtml/default/default/template/uol/pagseguro/refund.phtml b/app/design/adminhtml/default/default/template/uol/pagseguro/refund.phtml
index 578fbde..79a0cb5 100644
--- a/app/design/adminhtml/default/default/template/uol/pagseguro/refund.phtml
+++ b/app/design/adminhtml/default/default/template/uol/pagseguro/refund.phtml
@@ -36,6 +36,14 @@ $html   = Mage::helper('pagseguro/html');
                     ?>
                 

+

+ __("Atenção: Ao realizar um Estorno total a transação será estornada e terá seu status alterado no PagSeguro para + \"Devolvida\". Ao realizar um Estorno parcial será estornado o valor inserido, contudo, o status da transação no PagSeguro não será + alterado (a transação manterá o seu último status)."); + ?> +

+
__("Transação estornada com sucesso!"); + $partialRefundSuccess = $helper->__("Estorno parcial realizado com sucesso!"); $refundError = $helper->__("Não foi possível executar esta ação. Utilize a conciliação de transações primeiro ou tente novamente mais tarde."); ?>

__('Somente transações geradas a partir da versão 2.3 do módulo serão listadas.'); ?>

+ +
@@ -82,6 +110,8 @@ $html = Mage::helper('pagseguro/html'); diff --git a/app/design/adminhtml/default/default/template/uol/pagseguro/transactions.phtml b/app/design/adminhtml/default/default/template/uol/pagseguro/transactions.phtml index 29f75fa..d6809ee 100644 --- a/app/design/adminhtml/default/default/template/uol/pagseguro/transactions.phtml +++ b/app/design/adminhtml/default/default/template/uol/pagseguro/transactions.phtml @@ -33,30 +33,38 @@ $url = $obj->getUrl('pagseguro/adminhtml_conciliation');

__('Lista de Transações'); ?>

conciliação de suas transações para obter os status mais atuais."; + $string .= "Com esta funcionalidade você poderá listar as suas transações. Caso não encontre uma transação + ou se o status de uma transação estiver desatualizado é aconselhável que você use a conciliação + de transações."; echo $helper->__($string); ?>

+

+ __("Atenção: Toda transação estornada de forma parcial não tem seu status alterado. Por isso, ao filtrar + por \"Estornada Parcialmente\" o pedido exibirá o seu status original."); + ?> +

+ - - + + - + - - + - +
__('Data'); ?>__('ID Magento'); ?>__('Data'); ?>__('ID Magento'); ?> __('ID PagSeguro'); ?>__('Ambiente'); ?>__('Ambiente'); ?> __('Status PagSeguro'); ?> __('Ação'); ?>
+ @@ -206,14 +215,7 @@ $url = $obj->getUrl('pagseguro/adminhtml_conciliation'); {"sClass": "tabela", 'aTargets': [0, 1, 2, 3]}, {"sType": "date-br", 'aTargets': [0]} ], - "aoColumns": [ - { "sType": 'date-br' }, - null, - null, - null, - null, - null - ], + "bDestroy": true, // Creates paging and notifies when there is no record "oLanguage": { @@ -365,7 +367,7 @@ $url = $obj->getUrl('pagseguro/adminhtml_conciliation'); } if(result.paymentLink != false){ - listPaymentLine1.append('
Link para pagamento:
' + '' + 'Clique aqui para acessar' +'' + '
'); + listPaymentLine1.append('
Link para pagamento:
' + '' + 'Clique aqui para acessar' +'' + '
'); } if(result.installmentCount != undefined && result.installmentCount != false){ diff --git a/skin/adminhtml/default/default/uol/pagseguro/css/pagseguro-module.css b/skin/adminhtml/default/default/uol/pagseguro/css/pagseguro-module.css index 61e4339..baf272c 100644 --- a/skin/adminhtml/default/default/uol/pagseguro/css/pagseguro-module.css +++ b/skin/adminhtml/default/default/uol/pagseguro/css/pagseguro-module.css @@ -87,7 +87,7 @@ limitations under the License. } /* Tables */ -.pagseguro-table { border: 1px solid #e5e5e5; border-bottom-width: 3px; border-collapse: collapse; color: #444; width: 100%; } +.pagseguro-table { border: 1px solid #e5e5e5; border-bottom-width: 3px; border-collapse: collapse; color: #444; width: 100% !important; } .pagseguro-table th { background: #eee no-repeat center right; border: 1px solid #dbdbdb; color: #515151; font-size: 0.85em; font-weight: normal; padding: 10px 5px; text-transform: uppercase; text-align:center; } .pagseguro-table th:first-child + th { cursor: pointer; } .pagseguro-table tfoot td { text-align:center; padding: 5px; } @@ -106,7 +106,14 @@ limitations under the License. .pagseguro-table tbody td i { margin: 0 0.4em; font-size: 0.9em; } .pagseguro-table thead .input-search { vertical-align: middle; } .pagseguro-table thead tr th .input-date { margin-top: 5px !important; } -#transaction-table thead tr:nth-child(2) th:nth-child(3) input { width: 255px; } +#transaction-table thead tr:nth-child(2) th:nth-child(1) input, +#transaction-table thead tr:nth-child(2) th:nth-child(2) input, +#transaction-table thead tr:nth-child(2) th:nth-child(3) input { width: 85%; } +#transaction-table thead tr:nth-child(2) th:nth-child(1) input, +#transaction-table thead tr:nth-child(2) th:nth-child(2) input { max-width: 110px; } +#transaction-table thead tr:nth-child(2) th:nth-child(3) input { max-width: 270px; } +#transaction-table a:hover {text-decoration: underline; font-weight: bold} + /* DataTable Sorting */ .dataTable .sorting { background-image: url("../images/dataTable/sort_both.png"); cursor:pointer; } @@ -262,3 +269,7 @@ i.icon-pagseguro-msg.large, .pagseguro-adminhtml-canceled-index table.pagseguro-table a.edit, .pagseguro-adminhtml-refund-index table.pagseguro-table a.edit { display: none !important; } .ps_msg_hidden { display: none !important; } + +#canceled-table a:hover {text-decoration: underline; font-weight: bold} +#refund-table a:hover {text-decoration: underline; font-weight: bold} +#conciliation-table a:hover {text-decoration: underline; font-weight: bold} diff --git a/skin/adminhtml/default/default/uol/pagseguro/js/pagseguro-module.js b/skin/adminhtml/default/default/uol/pagseguro/js/pagseguro-module.js index 7467afa..4cf4843 100644 --- a/skin/adminhtml/default/default/uol/pagseguro/js/pagseguro-module.js +++ b/skin/adminhtml/default/default/uol/pagseguro/js/pagseguro-module.js @@ -477,10 +477,11 @@ function dateMask (date, fieldName) { function dateVerifyOnLosesFocus(fieldName){ var mydate = ''; mydate = mydate + fieldName.value; - - if(mydate.length > 0 && mydate.length < 10){ + if(mydate.length > 0 && mydate.length < 10) { fieldName.classList.add('pagseguro-field-error'); - }else{ + } else if(mydate.length == 0) { + fieldName.classList.remove('pagseguro-field-error'); + } else { dateVerify(fieldName); } } @@ -550,8 +551,57 @@ function formatReal( int ) var tmp = int+''; tmp = tmp.replace(".", ""); tmp = tmp.replace(/([0-9]{2})$/g, ",$1"); - if( tmp.length > 6 ) - tmp = tmp.replace(/([0-9]{3}),([0-9]{2}$)/g, ".$1,$2"); - + if ( tmp.length > 6 ) { + tmp = tmp.replace(/([0-9]{3}),([0-9]{2}$)/g, ".$1,$2"); + } return tmp; +} + +function formatRealInput( field ) +{ + var tmp = field.value; + tmp = tmp.replace(",", ""); + tmp = tmp.replace(".", ""); + + valueIsNumber(tmp); + + tmp = tmp.replace(/([0-9]{2})$/g, ",$1"); + + if ( tmp.length > 6 ) { + tmp = tmp.replace(/([0-9]{3}),([0-9]{2}$)/g, ".$1,$2"); + } + field.value = tmp; +} + +function valueIsNumber(tmp){ + + if(tmp.indexOf(",") == 0){ + jQuery('#refund-value').addClass('pagseguro-field-error'); + jQuery('.error').text('Valor inválido.'); + return false; + } + + tmp = tmp.replace(",", ""); + tmp = tmp.replace(".", ""); + + if(isNaN(tmp)) { + jQuery('#refund-value').addClass('pagseguro-field-error'); + jQuery('.error').text('Valor inválido.'); + return false; + } else if(tmp.indexOf('-') != -1) { + jQuery('#refund-value').addClass('pagseguro-field-error'); + jQuery('.error').text('Valor não pode ser negativo.'); + return false; + } else { + jQuery('.error').text(''); + jQuery('#refund-value').removeClass('pagseguro-field-error'); + return true; + } +} + +function getMoney( strMoney ) +{ + strMoney = strMoney.replace(".", ""); + strMoney = strMoney.replace(",", "."); + return parseFloat(strMoney); } \ No newline at end of file