magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.53k stars 9.31k forks source link

Magento 2.4.6 Braintree Custom Discount not added in Total and customer charged total amount #39293

Open rahuldambare opened 1 day ago

rahuldambare commented 1 day ago

Summary

I am working on custom discount for Magento using this blog https://meetanshi.com/blog/add-custom-discount-in-magento-2/, but it is not adding that custom discount while sending request to payment Braintree Request not adding custom discount and customer charged full amount .

For Paypal I have made adjustment as per https://github.com/magento/magento2/issues/5735 , which is working fine . module-paypal/Model/Apiu/Nvp.php function callSetExpressCheckout at Line 812 add before "$response = $this->call(self::SET_EXPRESS_CHECKOUT, $request);" this snipped: $request['ITEMAMT'] = $request['AMT'] - $request['TAXAMT'] - $request['SHIPPINGAMT'];

Only facing issue with Braintree payment where custom discount is applied .

Magento version 2.4.6p3 PHP 8

Please check and provide solution for this as its affecting production sales. ` <?php

namespace MyModule\CoreCredit\Model\Quote\Address\Total;

class CustomDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal {

/**
* @var \Magento\Framework\Pricing\PriceCurrencyInterface
*/
protected $_priceCurrency;
protected $resourceConnection;
protected $helper;

/**
 * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency [description]
 */
public function __construct(
    \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
    \Magento\Framework\App\ResourceConnection $resourceConnection,
    \PartSimple\CoreCredit\Helper\Data $helper
) {
    $this->_priceCurrency = $priceCurrency;
    $this->resourceConnection = $resourceConnection;
    $this->helper = $helper;
}

public function collect(
    \Magento\Quote\Model\Quote $quote,
    \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
    \Magento\Quote\Model\Quote\Address\Total $total
) {
    parent::collect($quote, $shippingAssignment, $total);

    if($this->helper->isValidStore() && $this->helper->isRemanItemExistsInCart()){
        $address = $shippingAssignment->getShipping()->getAddress();
        if($address->getAddressType() == 'billing'){
            return $this;
        }

        $baseDiscount = (float)$this->helper->calculateCreditbalance();
        $discount = $this->_priceCurrency->convert($baseDiscount);

        $total->addTotalAmount('customdiscount', -$discount);
        $total->addBaseTotalAmount('customdiscount', -$baseDiscount);
        $quote->setCustomDiscount(-$discount);

        \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' .  $baseDiscount); 
        \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' . (print_r($total,true))); 

    }

    return $this;
}

/**
 * Assign subtotal amount and label to address object
 *
 * @param \Magento\Quote\Model\Quote $quote
 * @param Address\Total $total
 * @return array
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
{
    return [
        'code' => 'Custom_Discount',
        'title' => $this->getLabel(),
        'value' => -$this->helper->calculateCreditbalance()
    ];
}

/**
 * get label
 * @return string
 */
public function getLabel()
{
    return __('Custom Discount');
}

} `

Examples


<?php 

namespace PartSimple\CoreCredit\Model\Quote\Address\Total;

class CustomDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{

    /**
    * @var \Magento\Framework\Pricing\PriceCurrencyInterface
    */
    protected $_priceCurrency;
    protected $resourceConnection;
    protected $helper;

    /**
     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency [description]
     */
    public function __construct(
        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
        \Magento\Framework\App\ResourceConnection $resourceConnection,
        \PartSimple\CoreCredit\Helper\Data $helper
    ) {
        $this->_priceCurrency = $priceCurrency;
        $this->resourceConnection = $resourceConnection;
        $this->helper = $helper;
    }

    public function collect(
        \Magento\Quote\Model\Quote $quote,
        \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
        \Magento\Quote\Model\Quote\Address\Total $total
    ) {
        parent::collect($quote, $shippingAssignment, $total);

        if($this->helper->isValidStore() && $this->helper->isRemanItemExistsInCart()){
            $address = $shippingAssignment->getShipping()->getAddress();
            if($address->getAddressType() == 'billing'){
                return $this;
            }

            $baseDiscount = (float)$this->helper->calculateCreditbalance();
            $discount = $this->_priceCurrency->convert($baseDiscount);

            $total->addTotalAmount('customdiscount', -$discount);
            $total->addBaseTotalAmount('customdiscount', -$baseDiscount);
            $quote->setCustomDiscount(-$discount);

            \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' .  $baseDiscount); 
            \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' . (print_r($total,true))); 

        }

        return $this;
    }

    /**
     * Assign subtotal amount and label to address object
     *
     * @param \Magento\Quote\Model\Quote $quote
     * @param Address\Total $total
     * @return array
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
    {
        return [
            'code' => 'Custom_Discount',
            'title' => $this->getLabel(),
            'value' => -$this->helper->calculateCreditbalance()
        ];
    }

    /**
     * get label
     * @return string
     */
    public function getLabel()
    {
        return __('Custom Discount');
    }
}

Briantree Request from payment log - 

'request' =>
  array (
    'customer' =>
    array (
      'firstName' => 'Rahul',
      'lastName' => 'Dambare',
      'company' => 'A-UNIVERSAL APPLIANCE SERVICE LLC',
      'phone' => '123-789-7889',
      'email' => 'john@test.com',
    ),
    'amount' => '151.98',
    'paymentMethodNonce' => 'tokencc_bh_v7b36gb_97fk8g_qb4vkf_qjsvwgv_pr3',
    'orderId' => '1000641943',
    'merchantAccountId' => 'johndoe',
    'channel' => 'Magento2GeneBT',
    'options' =>
    array (
      'skipAdvancedFraudChecking' => false,
      'submitForSettlement' => true,
    ),
    'customFields' =>
    array (
    ),
    'billing' =>
    array (
      'firstName' => 'TEST',
      'lastName' => 'TEST',
      'company' => '',
      'streetAddress' => '224120 NW 110th ST',
      'extendedAddress' => '',
      'locality' => 'GAINESVILLE ',
      'region' => 'FL',
      'postalCode' => '326w09',
      'countryCodeAlpha2' => 'US',
    ),
    'shipping' =>
    array (
      'firstName' => 'TEST',
      'lastName' => 'TEST',
      'company' => 'C',
      'streetAddress' => '224120 NW 110th ST',
      'extendedAddress' => '',
      'locality' => 'GAINESVILLE ',
      'region' => 'FL',
      'postalCode' => '32609',
      'countryCodeAlpha2' => 'US',
      'countryCodeAlpha3' => 'USA',
    ),
    'deviceData' => '{"correlation_id":"c419f951f95saf0f23072222dbc16b38de"}',
    'purchaseOrderNumber' => '1000641943',
    'taxAmount' => '0',
    'discountAmount' => '0',
    'lineItems' =>
    array (
      0 =>
      array (
        'name' => 'Kenmore  Frigidaire 807024701 Dish',
        'kind' => 'debit',
        'quantity' => '1',
        'unitAmount' => '126',
        'unitOfMeasure' => 'simple',
        'totalAmount' => '126',
        'taxAmount' => '0',
        'discountAmount' => '0',
        'productCode' => 'ken-80702470',
        'commodityCode' => 'ken-80702470',
        'description' => '',
      ),
      1 =>
      array (
        'name' => 'Optional Inbound Shipping',
        'kind' => 'debit',
        'quantity' => '1',
        'unitAmount' => '12',
        'unitOfMeasure' => 'virtual',
        'totalAmount' => '12',
        'taxAmount' => '0',
        'discountAmount' => '0',
        'productCode' => 'inbound-ship',
        'commodityCode' => 'inbound-ship',
        'description' => '',
      ),
    ),
    'shippingAmount' => '13.98',
    'shipsFromPostalCode' => '60188',
  ),

Proposed solution

Custom Discount should add in braintree request or in discount field for Braintree request and final total should be minus of that discount

Release note

No response

Triage and priority

m2-assistant[bot] commented 1 day ago

Hi @rahuldambare. Thank you for your report. To speed up processing of this issue, make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce.

rahuldambare commented 22 hours ago

I have one observer which add this custom amount item in cart, I think that is not working for magento 2.4.6

<event name="payment_cart_collect_items_and_amounts">
            <observer name="paymentfee" instance="MyModule\CoreCredit\Observer\AddCustomAmountItem" />
        </event>

public function execute(Observer $observer)
    {
        /** @var \Magento\Payment\Model\Cart $cart */
        $cart = $observer->getEvent()->getCart();
        $customAmount = -(float)$this->helper->calculateCreditbalance();

        \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check PartSimple\CoreCredit\Plugin >>>  ' .  $customAmount); 

        $cart->addCustomItem(__('Credit Amount'), 1, $customAmount, 'creditamount');
    }