Hi buddies,
So after enjoying Easter and April Fool, we meet up again on Magento blog. Are you ready to be back with more Magento certificate tips? This week tutorial will refer to cancelation, which is an important operation since everyone can make a mistake sometime, right? It allows admin to cancel a wrong action while processing the order.

1. Order entities support cancel
Not all of order entities in Magento support cancelling operations (the shipment for example), and the cancelling operation is not always available.
The order allows to cancel but it checkscans cancelled order by using method canCancel() in the order model:

Hi buddies,

So after enjoying Easter and April Fool, we meet up again on Magento blog. Are you ready to be back with more Magento certificate tips? This week tutorial will refer to cancelation, which is an important operation since everyone can make a mistake sometime, right? It allows admin to cancel a wrong action while processing the order.

1. Order entities support cancel

Not all of order’s entities in Magento support cancelling operations (the shipment for example), and the cancelling operation is not always available.

The order allows to cancel but it checkscans cancelled order by using method canCancel() in the order model:

Hi buddies,

So after enjoying Easter and April Fool, we meet up again on Magento blog. Are you ready to be back with more Magento certificate tips? This week tutorial will refer to cancelation, which is an important operation since everyone can make a mistake sometime, right? It allows admin to cancel a wrong action while processing the order.

1. Order entities support cancel

Not all of order’s entities in Magento support cancelling operations (the shipment for example), and the cancelling operation is not always available.

The order allows to cancel but it checkscans cancelled order by using method canCancel() in the order model:

/**
* Retrieve order cancel availability
*
* @return bool
*/
publicfunctioncanCancel()
{
if($this->canUnhold()){// $this->isPaymentReview()
returnfalse;
}

$allInvoiced=true;
foreach($this->getAllItems()as$item){
if($item->getQtyToInvoice()){
$allInvoiced=false;
break;
}
}
if($allInvoiced){
returnfalse;
}

$state=$this->getState();
if($this->isCanceled()||$state=== self::STATE_COMPLETE ||$state=== self::STATE_CLOSED){
returnfalse;
}

if($this->getActionFlag(self::ACTION_FLAG_CANCEL)===false){
returnfalse;
}

returntrue;
}

When an order is called off, it cancels the order’s payment and item, and sets data of cancelation in order model. Magento dispatchs an event after the cancellation.

/**
* Cancel order
*
* @return Mage_Sales_Model_Order
*/
publicfunction cancel()
{
if($this->canCancel()){
$this->getPayment()->cancel();
$this-&gt;registerCancellation();</p>
Mage::dispatchEvent('order_cancel_after',array('order'=&gt;$this));
}

return$this;
}

The ordered item allows cancelation if that item did not cancel:

/**
* Cancel order item
*
* @return Mage_Sales_Model_Order_Item
*/
publicfunction cancel()
{
if($this->getStatusId()!== self::STATUS_CANCELED){
Mage::dispatchEvent('sales_order_item_cancel',array('item'=>$this));
$this->setQtyCanceled($this->getQtyToCancel());
$this->setTaxCanceled($this->getTaxCanceled()+$this->getBaseTaxAmount()*$this->getQtyCanceled()/$this->getQtyOrdered());
$this->setHiddenTaxCanceled($this->getHiddenTaxCanceled()+$this->getHiddenTaxAmount()*$this->getQtyCanceled()/$this->getQtyOrdered());
}
return$this;
}

Similar to order, the invoice and invoice items, the credit memo and credit memo items allow cancelation, too. However, you can’t cancel an invoice or a credit memo in backend, these operations are used for the online payment.

2. Void and cancel
Void operation is used for online payment methods. It will cancel the invoice and callback to online payment to void it. But not like the cancelation, the invoiced quantity will no longer be able to be invoiced again. You can see the void() method in the Invoice model:

/**
* Void invoice
*
* @return Mage_Sales_Model_Order_Invoice
*/
publicfunction void()
{
$this->getOrder()->getPayment()->void($this);
$this->cancel();
return$this;
}

And the _void() method in Payment model:

/**
* Authorize payment either online or offline (process auth notification)
* Updates transactions hierarchy, if required
* Prevents transaction double processing
* Updates payment totals, updates order status and adds proper comments
*
* @parambool $isOnline
* @param float $amount
* @return Mage_Sales_Model_Order_Payment
*/
protectedfunction _authorize($isOnline,$amount)
{
// update totals
$amount=$this->_formatAmount($amount,true);
$this->setBaseAmountAuthorized($amount);

// do authorization
$order=$this->getOrder();
$state=Mage_Sales_Model_Order::STATE_PROCESSING;
$status=true;
if($isOnline){
// invoke authorization on gateway
$this->getMethodInstance()->setStore($order->getStoreId())->authorize($this,$amount);
}else{
$message= Mage::helper('sales')->__(
'Registered notification about authorized amount of %s.',
$this->_formatPrice($amount)
);
}

// similar logic of "payment review" order as in capturing
if($this->getIsTransactionPending()){
$message= Mage::helper('sales')->__('Authorizing amount of %s is pending approval on gateway.',$this->_formatPrice($amount));
$state=Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
if($this->getIsFraudDetected()){
$status=Mage_Sales_Model_Order::STATUS_FRAUD;
}
}else{
$message= Mage::helper('sales')->__('Authorized amount of %s.',$this->_formatPrice($amount));
}

// update transactions, order state and add comments
$transaction=$this->_addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH);
if($order->isNominal()){
$message=$this->_prependMessage(Mage::helper('sales')->__('Nominal order registered.'));
}else{
$message=$this->_prependMessage($message);
$message=$this->_appendTransactionToMessage($transaction,$message);
}
$order->setState($state,$status,$message);

return$this;
}

3. Tax and discount processing
While cancelling, the data was calculated and stored in database.
Order cancelation calculates and stores canceled tax and canceled discount:

$this-&gt;setSubtotalCanceled($this-&gt;getSubtotal()-$this-&gt;getSubtotalInvoiced());
$this-&gt;setBaseSubtotalCanceled($this-&gt;getBaseSubtotal()-$this-&gt;getBaseSubtotalInvoiced());</p>
$this-&gt;setTaxCanceled($this-&gt;getTaxAmount()-$this-&gt;getTaxInvoiced());
$this-&gt;setBaseTaxCanceled($this-&gt;getBaseTaxAmount()-$this-&gt;getBaseTaxInvoiced());

$this-&gt;setShippingCanceled($this-&gt;getShippingAmount()-$this-&gt;getShippingInvoiced());
$this-&gt;setBaseShippingCanceled($this-&gt;getBaseShippingAmount()-$this-&gt;getBaseShippingInvoiced());

$this-&gt;setDiscountCanceled(abs($this-&gt;getDiscountAmount())-$this-&gt;getDiscountInvoiced());
$this-&gt;setBaseDiscountCanceled(abs($this-&gt;getBaseDiscountAmount())-$this-&gt;getBaseDiscountInvoiced());

The tax canceled equals the tax of order subtract the tax invoiced. Discount canceled equals the discount of order subtract the discount invoiced. Invoice and credit memo canceled will calculate and update tax, discount for order. See the invoice canceled code:

/**
* Cancel invoice action
*
* @return Mage_Sales_Model_Order_Invoice
*/
publicfunction cancel()
{
$order=$this-&gt;getOrder();
$order-&gt;getPayment()-&gt;cancelInvoice($this);
foreach($this-&gt;getAllItems()as$item){
$item-&gt;cancel();
}</p>
/**
* Unregister order totals only for invoices in state PAID
*/
$order-&gt;setTotalInvoiced($order-&gt;getTotalInvoiced()-$this-&gt;getGrandTotal());
$order-&gt;setBaseTotalInvoiced($order-&gt;getBaseTotalInvoiced()-$this-&gt;getBaseGrandTotal());

$order-&gt;setSubtotalInvoiced($order-&gt;getSubtotalInvoiced()-$this-&gt;getSubtotal());
$order-&gt;setBaseSubtotalInvoiced($order-&gt;getBaseSubtotalInvoiced()-$this-&gt;getBaseSubtotal());

$order-&gt;setTaxInvoiced($order-&gt;getTaxInvoiced()-$this-&gt;getTaxAmount());
$order-&gt;setBaseTaxInvoiced($order-&gt;getBaseTaxInvoiced()-$this-&gt;getBaseTaxAmount());

$order-&gt;setHiddenTaxInvoiced($order-&gt;getHiddenTaxInvoiced()-$this-&gt;getHiddenTaxAmount());
$order-&gt;setBaseHiddenTaxInvoiced($order-&gt;getBaseHiddenTaxInvoiced()-$this-&gt;getBaseHiddenTaxAmount());

$order-&gt;setShippingTaxInvoiced($order-&gt;getShippingTaxInvoiced()-$this-&gt;getShippingTaxAmount());
$order-&gt;setBaseShippingTaxInvoiced($order-&gt;getBaseShippingTaxInvoiced()-$this-&gt;getBaseShippingTaxAmount());

$order-&gt;setShippingInvoiced($order-&gt;getShippingInvoiced()-$this-&gt;getShippingAmount());
$order-&gt;setBaseShippingInvoiced($order-&gt;getBaseShippingInvoiced()-$this-&gt;getBaseShippingAmount());

$order-&gt;setDiscountInvoiced($order-&gt;getDiscountInvoiced()-$this-&gt;getDiscountAmount());
$order-&gt;setBaseDiscountInvoiced($order-&gt;getBaseDiscountInvoiced()-$this-&gt;getBaseDiscountAmount());
$order-&gt;setBaseTotalInvoicedCost($order-&gt;getBaseTotalInvoicedCost()-$this-&gt;getBaseCost());

if($this-&gt;getState()== self::STATE_PAID){
$this-&gt;getOrder()-&gt;setTotalPaid($this-&gt;getOrder()-&gt;getTotalPaid()-$this-&gt;getGrandTotal());
$this-&gt;getOrder()-&gt;setBaseTotalPaid($this-&gt;getOrder()-&gt;getBaseTotalPaid()-$this-&gt;getBaseGrandTotal());
}
$this-&gt;setState(self::STATE_CANCELED);
$this-&gt;getOrder()-&gt;setState(Mage_Sales_Model_Order::STATE_PROCESSING,true);
Mage::dispatchEvent('sales_order_invoice_cancel',array($this-&gt;_eventObject=&gt;$this));
return$this;
}

Well, it’s a long post with many codes, hope you guys have enough patience to read it. Thank you and see you next time!

Author

Why Magestore? We believe in building a meaningful & long-term relationship with you.

Write A Comment