Thursday , 31 July 2014
Topic 9 – Part 5: Partial Operations

Topic 9 – Part 5: Partial Operations

Welcome back, Magento friends

It has been quite a long time since the last post in this category. How have you been lately? Are you still thirsty for more Magento knowledge? Today we are happy to continue our series with part 5: Partial Operations. Partial operation allows processing each part of order, and helps this process becoming more flexibility. Magento supports three partial operations: partial invoice, partial shipping and partial refund. Three operations are similar, so I will guide you through partial invoice in this post and you can apply on the two remaining operations.

1. Create a Partial Invoice

After making an order, you can create its invoice in backend. In the new invoice page, you need to select the quantity of item to invoice.

Choosing “submit invoice” to create a partial invoice for that order. Another method is using the following code:

$order;// Your order to create Invoice
if($order->canInvoice()){
$invoiceQtys=array(
// ItemID =>QtyOf Item to Invoice
);
$invoice= Mage::getModel('sales/service_order',$order)->prepareInvoice($invoiceQtys);
$invoice->register();
$invoice->getOrder()->setIsInProcess(true);
Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder())
->save();
}

2. Dummy Item

Dummy item is the item that does not involve in the calculation when you create an invoice (or refund, shipment). For example, you buy a bundle product and the price was calculated based on its components. That bundle product is a dummy item when you invoice or refund. Detail of method to check if an item is dummy:

/**
* This is Dummy item or not
* if $shipment is true then we checking this for shipping situation if not
* then we checking this for calculation
*
* @parambool $shipment
* @return bool
*/
publicfunctionisDummy($shipment=false){
if($shipment){
if($this->getHasChildren()&&$this->isShipSeparately()){
returntrue;
}
if($this->getHasChildren()&&!$this->isShipSeparately()){
returnfalse;
}
if($this->getParentItem()&&$this->isShipSeparately()){
returnfalse;
}
if($this->getParentItem()&&!$this->isShipSeparately()){
returntrue;
}
}else{
if($this->getHasChildren()&&$this->isChildrenCalculated()){
returntrue;
}
if($this->getHasChildren()&&!$this->isChildrenCalculated()){
returnfalse;
}
if($this->getParentItem()&&$this->isChildrenCalculated()){
returnfalse;
}
if($this->getParentItem()&&!$this->isChildrenCalculated()){
returntrue;
}
}
returnfalse;
}

3. Last Item

Because of some problems when calculate the total of invoice, Magento processes to separate between a normal item and the last item. It is very important when you create a Partial Invoice. For instant, the model to calculate discount for an invoice:

/**
* Resolve rounding problems
*/
if($item->isLast()){
$discount=$orderItemDiscount-$orderItem->getDiscountInvoiced();
$baseDiscount=$baseOrderItemDiscount-$orderItem->getBaseDiscountInvoiced();
}
else{
$discount=$orderItemDiscount*$item->getQty()/$orderItemQty;
$baseDiscount=$baseOrderItemDiscount*$item->getQty()/$orderItemQty;

$discount=$invoice->getStore()->roundPrice($discount);
$baseDiscount=$invoice->getStore()->roundPrice($baseDiscount);
}

And the method, which check if the current item is last, depends on the quantity of current item and the available item of order allow to invoice:

/**
* Checking if the item is last
*
* @return bool
*/
publicfunctionisLast()
{
if((string)(float)$this->getQty()==(string)(float)$this->getOrderItem()->getQtyToInvoice()){
returntrue;
}
returnfalse;
}

Well, I think that is enough for today. Actually, Magento is not that difficult when you truly understand about it and love the way it works. Practice makes perfect, so start now to see how improve you can!

Hope this post is helpful! See you next time!

About David

2 comments

  1. Hi David,
    thanks a lot for this helpful serie dedicated for MDC, I have some trouble to figure out how do partial order operations affect order state ?

    • Hi Sami,
      Regarding your question, order state depend on each operations that you take effect. When a partial operation was processed, order saved and Magento check and update order state by method _checkState() of order model (Mage_Sales_Model_Order). You can go to your source code to review it for more clearly. Hope it’s helpful for you!