Par défaut dans la solution magento, il n’est pas possible d’annuler ni de supprimer les avoirs. ( C’est logique au niveau comptable )
Cette fonctionnalité peut toutefois être pratique dans le cas d’une erreur de manipulation

Nous allons donc voir comment faire pour ajouter cette fonctionnalité à Magento en créant un module.
Celui-ci va ajouter 2 boutons “Annuler” et “Supprimer” dans la page de gestion d’un avoir.

Credit Memo Cancel delete

Je ne vais détailler ici que le fonctionnement logique du module.
Vous pourrez trouver l’intégralité des sources et le module sur github : https://github.com/nenes25/magento_creditMemo

L’objectif de ce module étant de ne pas réaliser de surcharge, nous allons utiliser les observers.
Celui qui nous intéresse adminhtml_widget_container_html_before

Dans le fichier de configuration de notre module il faut donc ajouter un observer sur cet événement via le code suivant

<global>
..
 <events>
            <adminhtml_widget_container_html_before>
                <observers>
                    <add_creditmemo_buttons>
                        <class>hhennes_creditmemo/observer</class>
                        <method>addCreditMemoButtons</method>
                    </add_creditmemo_buttons>
                </observers>
            </adminhtml_widget_container_html_before>
 </events>
...
</global>

Passons au code de l’observer, dans lequel nous allons insérer ces nouveaux boutons sur la page, et leur ajouter un lien vers le controller de notre module

<?php
 
/**
 * Hhennes_CreditMemo : Observer
 */
class Hhennes_CreditMemo_Model_Observer
{
 
    /**
     * Ajout de boutons pour Annuler et Supprimer les avoir
     * @param Varien_Event_Obsever $observer
     */
    public function addCreditMemoButtons($observer)
    {
        $container = $observer->getBlock();
 
        //Ajout du boutons sur la page de visulalisation d'un avoir
        if ($container !== null && $container->getType() == 'adminhtml/sales_order_creditmemo_view') {
 
            //Ajout du bouton d'annulation
            $cancelButtonsDatas = array(
                'label' => Mage::helper('hhennes_creditmemo')->__('Cancel'),
                'onclick' => 'setLocation(\''.Mage::helper("adminhtml")->getUrl('hhennes_creditmemo/adminhtml_CreditMemo/cancel/',
                    array('id' => Mage::app()->getRequest()->getParam('creditmemo_id'))).'\')'
            );
 
            $container->addButton('creditmemo_cancel', $cancelButtonsDatas);
 
            //Ajout du bouton de suppression
            $deteleButtonsDatas = array(
                'label' => Mage::helper('hhennes_creditmemo')->__('Delete'),
                'class' => 'delete',
                'onclick' => 'deleteConfirm(\''.Mage::helper('hhennes_creditmemo')->__('delete Credit Memo ?').'\',\''.Mage::helper("adminhtml")->getUrl('hhennes_creditmemo/adminhtml_CreditMemo/delete/',
                    array('id' => Mage::app()->getRequest()->getParam('creditmemo_id'))).'\')'
            );
 
            $container->addButton('creditmemo_delete', $deteleButtonsDatas);
        }
    }
 
}
?>

Pour finir voici le code du controller qui va se charger d’annuler ou de supprimer notre avoir.
Mais également de supprimer les informations relatives à cet avoir de la commande.

<?php
/**
 * Hhennes_CreditMemo : Admin Controller
 */
class Hhennes_CreditMemo_Adminhtml_CreditMemoController extends Mage_Adminhtml_Controller_Action
{
 
    /**
     * Annulation d'un avoir
     */
    public function cancelAction()
    {
 
        //Récupération de l'avoir
        $creditMemoId = $this->getRequest()->getParam('id');
 
        //Chargement de l'avoir
        $creditMemo = Mage::getModel('sales/order_creditmemo')->load($creditMemoId);
 
        //Si l'avoir n'est pas encore annulé
        if ( $creditMemo->getState() != 3) {
 
            try {
                $creditMemo->cancel(); //Annulation des remboursements
                $creditMemo->setState(Mage_Sales_Model_Order_Creditmemo::STATE_CANCELED); //Changement du statut de l'avoir
                $creditMemo->save(); //Sauvegarde de l'avoir
                $this->_cancelRefundOrder($creditMemo->getOrder()); //Annulation des données de remboursement sur la commande
 
            } catch ( Exception $e) {
                Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
                $this->_redirect('adminhtml/sales_creditmemo/view',array('creditmemo_id'=> $creditMemoId));
            }
 
            Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Credit Memo successfully cancel'));
        }
        else {
            Mage::getSingleton('adminhtml/session')->addError($this->__('Credit Memo already cancel'));
        }
 
        $this->_redirect('adminhtml/sales_creditmemo/view',array('creditmemo_id'=> $creditMemoId));
    }
 
    /**
     * Suppression d'un avoir
     */
    public function deleteAction()
    {
        //Récupération de l'avoir
        $creditMemoId = $this->getRequest()->getParam('id');
 
        //Chargement de l'avoir
        $creditMemo = Mage::getModel('sales/order_creditmemo')->load($creditMemoId);
 
        //On annule l'avoir avant de le supprimer
        try {
            $creditMemo->cancel(); //Annulation des remboursements
            $this->_cancelRefundOrder($creditMemo->getOrder()); //Annulation des données de remboursement sur la commande
            $creditMemo->delete(); //Suppression de l'avoir
        } catch (Exception $e) {
            Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
            $this->_redirect('adminhtml/sales_creditmemo', array('creditmemo_id' => $creditMemoId));
        }
 
        Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Credit Memo successfully deleted'));
        $this->_redirect('adminhtml/sales_creditmemo', array('creditmemo_id' => $creditMemoId));
    }
 
    /**
     * Annulation des remboursement de la commande
     * @param type $order
     */
    protected function _cancelRefundOrder($order)
    {
        //On mets tous les champs relatifs au remboursement à NULL
        $order->setBaseDiscountRefunded(NULL);
        $order->setBaseShippingTaxRefunded(NULL);
        $order->setBaseSubtotalRefunded(NULL);
        $order->setBaseTaxRefunded(NULL);
        $order->setBaseTotalOfflineRefunded(NULL);
        $order->setBaseTotalOnlineRefunded(NULL);
        $order->setBaseTotalRefunded(NULL);
        $order->setBaseHiddenTaxRefunded(NULL);
 
        $order->setDiscountRefunded(NULL);
        $order->setShippingTaxRefunded(NULL);
        $order->setSubtotalRefunded(NULL);
        $order->setTaxRefunded(NULL);
        $order->setTotalOfflineRefunded(NULL);
        $order->setTotalOnlineRefunded(NULL);
        $order->setTotalRefunded(NULL);
        $order->setBaseHiddenTaxRefunded(NULL);
 
        $order->save();
    }
}