In Magento 2.3 EE Gift card account extension there is a collect method Magento\GiftCardAccount\Model\Total\Quote\Giftcardaccount
In this collect method the grand totals are calculated according to the gift card amount used and then the card amount used is updated in quote
public function collect(
\Magento\Quote\Model\Quote $quote,
\Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
\Magento\Quote\Model\Quote\Address\Total $total
) {
$baseAmountLeft = $quote->getBaseGiftCardsAmount() - $quote->getBaseGiftCardsAmountUsed();
$amountLeft = $quote->getGiftCardsAmount() - $quote->getGiftCardsAmountUsed();
if ($baseAmountLeft >= $total->getBaseGrandTotal()) {
$baseUsed = $total->getBaseGrandTotal();
$used = $total->getGrandTotal();
$total->setBaseGrandTotal(0);
$total->setGrandTotal(0);
} else {
$baseUsed = $baseAmountLeft;
$used = $amountLeft;
$total->setBaseGrandTotal($total->getBaseGrandTotal() - $baseAmountLeft);
$total->setGrandTotal($total->getGrandTotal() - $amountLeft);
}
$addressCards = [];
$usedAddressCards = [];
if ($baseUsed) {
$quoteCards = $this->_sortGiftCards($this->_giftCardAccountData->getCards($quote));
$skipped = 0;
$baseSaved = 0;
$saved = 0;
foreach ($quoteCards as $quoteCard) {
$card = $quoteCard;
if ($quoteCard[ModelGiftcardaccount::BASE_AMOUNT] + $skipped <=
$quote->getBaseGiftCardsAmountUsed()
) {
$baseThisCardUsedAmount = $thisCardUsedAmount = 0;
} elseif ($quoteCard[ModelGiftcardaccount::BASE_AMOUNT] + $baseSaved >
$baseUsed
) {
$baseThisCardUsedAmount = min(
$quoteCard[ModelGiftcardaccount::BASE_AMOUNT],
$baseUsed - $baseSaved
);
$thisCardUsedAmount = min(
$quoteCard[ModelGiftcardaccount::AMOUNT],
$used - $saved
);
$baseSaved += $baseThisCardUsedAmount;
$saved += $thisCardUsedAmount;
} elseif ($quoteCard[ModelGiftcardaccount::BASE_AMOUNT] + $skipped + $baseSaved >
$quote->getBaseGiftCardsAmountUsed()
) {
$baseThisCardUsedAmount = min(
$quoteCard[ModelGiftcardaccount::BASE_AMOUNT],
$baseUsed
);
$thisCardUsedAmount = min(
$quoteCard[ModelGiftcardaccount::AMOUNT],
$used
);
$baseSaved += $baseThisCardUsedAmount;
$saved += $thisCardUsedAmount;
} else {
$baseThisCardUsedAmount = $thisCardUsedAmount = 0;
}
// avoid possible errors in future comparisons
$card[ModelGiftcardaccount::BASE_AMOUNT] = round($baseThisCardUsedAmount, 4);
$card[ModelGiftcardaccount::AMOUNT] = round($thisCardUsedAmount, 4);
$addressCards[] = $card;
if ($baseThisCardUsedAmount) {
$usedAddressCards[] = $card;
}
$skipped += $quoteCard[ModelGiftcardaccount::BASE_AMOUNT];
}
}
$this->_giftCardAccountData->setCards($total, $usedAddressCards);
$total->setUsedGiftCards($total->getGiftCards());
$this->_giftCardAccountData->setCards($total, $addressCards);
$baseTotalUsed = $quote->getBaseGiftCardsAmountUsed() + $baseUsed;
$totalUsed = $quote->getGiftCardsAmountUsed() + $used;
$quote->setBaseGiftCardsAmountUsed($baseTotalUsed);
$quote->setGiftCardsAmountUsed($totalUsed);
$total->setBaseGiftCardsAmount($baseUsed);
$total->setGiftCardsAmount($used);
return $this;
}
The $quote->setGiftCardsAmountUsed($totalUsed)
sets the gift card amount used correctly in the first call to the collect method but in the subsequent calls it takes the updated amount.
For example, if I am using $25 gift card it is subracting the gift card amount as follows
$amountLeft = $quote->getGiftCardsAmount() - $quote->getGiftCardsAmountUsed();
Now both are 25 and hence the $amountLeft
sets to 0. Now the grand total is subtracted with 0 and hence the discount is never applied.
I would like to avoid this by setting some custom flag which avoids this re-calulations I tried setting $quote->setTotalsCollectedFlag(true)->save();
and then return if this flag is true. But this avoids correct calculation even before the order is placed.
from Active questions tagged magento-enterprise - Magento Stack Exchange