/** * Set refunded reward amount order and update reward points balance if need * * @param Varien_Event_Observer $observer * @return Enterprise_Reward_Model_Observer */ public function creditmemoSaveAfter(Varien_Event_Observer $observer) { /* @var $creditmemo Mage_Sales_Model_Order_Creditmemo */ $creditmemo = $observer->getEvent()->getCreditmemo(); /* @var $order Mage_Sales_Model_Order */ $order = $creditmemo->getOrder(); /* @var $helper Enterprise_Reward_Helper_Data */ $helper = Mage::helper('enterprise_reward'); $allowRewardPointsRefund = true; if ($creditmemo->getAutomaticallyCreated()) { if ($helper->isAutoRefundEnabled()) { $creditmemo->setRewardPointsBalanceToRefund($creditmemo->getRewardPointsBalance()); } else { $allowRewardPointsRefund = false; } } if ($creditmemo->getBaseRewardCurrencyAmount() && $allowRewardPointsRefund) { $order->setRewardPointsBalanceRefunded($order->getRewardPointsBalanceRefunded() + $creditmemo->getRewardPointsBalance()); $order->setRewardCurrencyAmountRefunded($order->getRewardCurrencyAmountRefunded() + $creditmemo->getRewardCurrencyAmount()); $order->setBaseRewardCurrencyAmountRefunded($order->getBaseRewardCurrencyAmountRefunded() + $creditmemo->getBaseRewardCurrencyAmount()); $order->setRewardPointsBalanceToRefund($order->getRewardPointsBalanceToRefund() + $creditmemo->getRewardPointsBalanceToRefund()); if ((int) $creditmemo->getRewardPointsBalanceToRefund() > 0) { Mage::getModel('enterprise_reward/reward')->setCustomerId($order->getCustomerId())->setStore($order->getStoreId())->setPointsDelta((int) $creditmemo->getRewardPointsBalanceToRefund())->setAction(Enterprise_Reward_Model_Reward::REWARD_ACTION_CREDITMEMO)->setActionEntity($order)->save(); } } // Void reward points granted for refunded amount if there was any $customerId = $order->getCustomerId(); $websiteId = Mage::app()->getStore($order->getStoreId())->getWebsiteId(); // @var $rewardHistoryCollection Enterprise_Reward_Model_Resource_Reward_History_Collection $rewardHistoryCollection = Mage::getModel('enterprise_reward/reward_history')->getCollection(); $rewardHistoryCollection->addCustomerFilter($customerId)->addWebsiteFilter($websiteId)->addFilter('main_table.is_expired', 0)->addFilter('main_table.action', Enterprise_Reward_Model_Reward::REWARD_ACTION_ORDER_EXTRA); $isOrderRewardedWithPoints = false; /* @var $rewardHistoryRecord Enterprise_Reward_Model_Reward */ foreach ($rewardHistoryCollection as $rewardHistoryRecord) { $additionalData = $rewardHistoryRecord->getAdditionalData(); if (isset($additionalData['increment_id']) && $additionalData['increment_id'] == $order->getIncrementId() && isset($additionalData['rate']['direction']) && $additionalData['rate']['direction'] == Enterprise_Reward_Model_Reward_Rate::RATE_EXCHANGE_DIRECTION_TO_POINTS && isset($additionalData['rate']['points']) && isset($additionalData['rate']['currency_amount'])) { $isOrderRewardedWithPoints = true; break; } } unset($rewardHistoryCollection); if ($isOrderRewardedWithPoints) { /* * Calculating amount of funds from total refunded amount for which reward points were acquired * @see Enterprise_Reward_Model_Action_OrderExtra::getPoints() */ $rewardedAmountForWholeOrder = $order->getBaseGrandTotal() - $order->getBaseTaxAmount() - $order->getBaseShippingAmount(); $rewardedAmountRefunded = $order->getBaseTotalRefunded() - $order->getBaseTaxRefunded() - $order->getBaseShippingRefunded(); $rewardedAmountAfterRefund = $rewardedAmountForWholeOrder - $rewardedAmountRefunded; /** * Modify amount for which reward points should not be voided at refund */ $result = new Varien_Object(); $result->setRewardedAmountAfterRefund($rewardedAmountAfterRefund); Mage::dispatchEvent('rewarded_amount_after_refund_calculation', array('creditmemo' => $creditmemo, 'result' => $result)); $rewardedAmountAfterRefund = $result->getRewardedAmountAfterRefund(); /** * Calculating amount of points to void considering reward points exchange rate when they were granted * @see Enterprise_Reward_Model_Reward_Rate::calculateToPoints() */ $estimatedRewardPointsAfterRefund = (int) ((string) $rewardedAmountAfterRefund / (string) $additionalData['rate']['currency_amount']) * $additionalData['rate']['points']; $rewardPointsVoided = $rewardHistoryRecord->getPointsVoided(); $acquiredRewardPointsAvailableForVoid = $rewardHistoryRecord->getPointsDelta() - $rewardPointsVoided; /* * It's not allowed to void more points then were granted per this order. * Used points at current history record are not taken into consideration - * allowed to void from total amount if it's needed to void more then left at selected history record. */ if ($acquiredRewardPointsAvailableForVoid > $estimatedRewardPointsAfterRefund) { $rewardPointsAmountToVoid = $acquiredRewardPointsAvailableForVoid - $estimatedRewardPointsAfterRefund; } else { $rewardPointsAmountToVoid = 0; } if ($rewardPointsAmountToVoid > 0) { /* @var $reward Enterprise_Reward_Model_Reward */ $reward = Mage::getModel('enterprise_reward/reward')->setWebsiteId($websiteId)->setCustomerId($order->getCustomerId())->loadByCustomer(); $rewardPointsBalance = $reward->getPointsBalance(); if ($rewardPointsBalance > 0) { // It's not allowed to void more points then is available for current customer if ($rewardPointsAmountToVoid > $rewardPointsBalance) { $rewardPointsAmountToVoid = $rewardPointsBalance; } if ($helper->getGeneralConfig('deduct_automatically')) { $reward->setPointsDelta(-$rewardPointsAmountToVoid)->setAction(Enterprise_Reward_Model_Reward::REWARD_ACTION_CREDITMEMO_VOID)->setActionEntity($order)->updateRewardPoints(); if ($reward->getRewardPointsUpdated()) { $order->addStatusHistoryComment($helper->__('%s was deducted because of refund.', $helper->formatReward($rewardPointsAmountToVoid))); } } /* * Config option deduct_automatically is not considered here because points for refunded amount that * were not been voided automatically need to be counted in possible future automatic deductions. */ $rewardHistoryRecord->getResource()->updateHistoryRow($rewardHistoryRecord, array('points_voided' => $rewardPointsVoided + $rewardPointsAmountToVoid)); } } } return $this; }