#StackBounty: #magento2 #checkout #event-observer #customer-attribute #order-success-page Get a Custom Customer Attribute to Appear on …

Bounty: 100

I’ve recently created a customer attribute for my Magento ver. 2.3.5-p1 instance using the following blog:

https://www.blog.sashas.org/magento-2-1-3-how-to-make-customer-attribute-update.html

The module has worked properly and created a new customer attribute with the i.d. "trade_ordernumber".

I would now like to add this attribute to the checkout success page but I’m not sure how to do this, what I was thinking was something like the below:

    <?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

?>
<?php /** @var $block MagentoCheckoutBlockOnepageSuccess */ ?>
<div class="checkout-success">
    <?php if ($block->getOrderId()) :?>
        <?php if ($block->getCanViewOrder()) :?>
                <h1><?= $block->escapeHtml(__('Your order # is: <span>%1</span>.', $block->getOrderId()), ['span']) ?></h1>
    
            <p><?= $block->escapeHtml(__('Your order number is: %1.', sprintf('<a href="%s" class="order-number"><strong>%s</strong></a>', $block->escapeUrl($block->getViewOrderUrl()), $block->getOrderId())), ['a', 'strong']) ?></p>
        <?php  else :?>
            <p><?= $block->escapeHtml(__('Your order # is: <span>%1</span>.', $block->getOrderId()), ['span']) ?></p>
        <?php endif;?>
            <p><?= $block->escapeHtml(__('We'll email you an order confirmation with details and tracking info.')) ?></p>
    <?php endif;?>

    <?= $block->getAdditionalInfoHtml() ?>

    <div class="actions-toolbar">
        <div class="primary">
            <a class="action primary continue" href="<?= $block->escapeUrl($block->getContinueUrl()) ?>"><span><?= $block->escapeHtml(__('Continue Shopping')) ?></span></a>
        </div>
    </div>
</div>


<?php
    $objectManager =  MagentoFrameworkAppObjectManager::getInstance();        
    $storeManager  = $objectManager->get('MagentoStoreModelStoreManagerInterface');
    $storeID       = $storeManager->getStore()->getStoreId(); 
    $storeName     = $storeManager->getStore()->getName();
?>

<?php
    $customerSession = $objectManager->get('MagentoCustomerModelSession');
    if($customerSession->isLoggedIn()) {
        echo $customerSession->getAttribute('trade_ordernumber');
    }
?>


Get this bounty!!!

#StackBounty: #magento2 #checkout #tax #plugin Custom Tax Calculation infinite loop issue in Magento2

Bounty: 100

I am calculating custom Tax for the cart item, Used the following code.

Vendor/Module/etc/di.xml

<type name="MagentoQuoteModelQuoteAddressTotal">
    <plugin name="mbs_customtax_cart_item" type="VendorModulePluginCustomTaxTotal" />
</type>

Vendor/Module/Plugin/CustomTaxTotal.php

<?php

namespace VendorModulePlugin;

class CustomTaxTotal
{

private $logger;   
private $_productloader;  
private $_cart;
private $customTax = null;   
private $cartItemLoader;

public function __construct(
    PsrLogLoggerInterface $logger,
    VendorModuleModelProductCartItemLoader $cartItemLoader
) {
    $this->logger = $logger;
    $this->cartItemLoader = $cartItemLoader;
}

private function calculateCustomTaxForQuote()
{
    if (is_null($this->customTax)) {
        $this->logger->info('--total--');
        $this->customTax = $this->cartItemLoader->getCartItemWithTaxRates();
    }

    return $this->customTax;
}

public function beforeAddTotalAmount(
    MagentoQuoteModelQuoteAddressTotal $subject,
    $code,
    $amount
) {
    if ($code =='tax') {
        $amount += $this->calculateCustomTaxForQuote();
    }

    return [$code, $amount];
}

public function beforeAddBaseTotalAmount(
    MagentoQuoteModelQuoteAddressTotal $subject,
    $code,
    $amount
) {
    if ($code =='tax') {
        $amount += $this->calculateCustomTaxForQuote();
    }

    return [$code, $amount];
  }
 }

VendorModuleModelProductCartItemLoader.php

<?php
namespace VendorModuleModel;

class ProductCartItemLoader
{
 private $productFactory;

private $cart;

private $customerSession;

private $taxCalculation;

private $scopeConfig;

private $collectionFactory;

private $dataObjectFactory;

public function __construct(
    MagentoCatalogModelProductFactory $productFactory,
    MagentoCheckoutModelCart $cart,
    MagentoCustomerModelSession $customerSession,
    MagentoTaxModelCalculation $taxCalculation,
    MagentoFrameworkAppConfigScopeConfigInterface $scopeConfig,
    MagentoFrameworkDataCollectionFactory $collectionFactory,
    MagentoFrameworkDataObjectFactory $dataObjectFactory
) {
    $this->productFactory = $productFactory;
    $this->cart = $cart;
    $this->customerSession = $customerSession;
    $this->taxCalculation = $taxCalculation;
    $this->scopeConfig = $scopeConfig;
    $this->collectionFactory = $collectionFactory;
    $this->dataObjectFactory = $dataObjectFactory;
}

public function getCartItemWithTaxRates()
{
    $itemsCollection = $this->cart->getQuote()->getItemsCollection();
    $productCollection = $this->getProductWithExternalData($itemsCollection);

    $taxAmount = 0;
    foreach ($itemsCollection as $item) {
        $product = $productCollection->getItemByColumnValue('entity_id', $item->getProductId());

        if ($product and $product->getData('pod_image_id')!='') {
            $taxRate = $this->getRate($product);

            if ($taxRate > 0) {
                $taxAmount += ($product->getData('pod_price') * $taxRate)/100;
            }
        }
    }

    return $taxAmount;
}

private function getRate($product)
{
    $productTaxClassId = $product->getTaxClassId();
    $shippingAddress = $this->customerSession->getCustomer()->getDefaultShippingAddress();
    $countryCode =  (isset($shippingAddress['country_id']) && !empty($shippingAddress['country_id'])) ? $shippingAddress['country_id'] : 'GB';
    $rate = $this->taxCalculation->getRate(
        new MagentoFrameworkDataObject(
            [
                'country_id' => $countryCode,
                'customer_class_id' => $this->scopeConfig->getValue('tax/classes/default_customer_tax_class'),
                'product_class_id' => $productTaxClassId
            ]
        )
    );

    return $rate;
}


private function getProductWithExternalData($itemsCollection):MagentoFrameworkDataCollection
{
    $parsedCollection = $this->collectionFactory->create();

    if ($this->cart->getQuote()->getId()) {
        $productIds = [];
        foreach ($itemsCollection as $item) {
            $productIds[] = $item->getProductId();
        }

        $productCollection = $this->productFactory->create()->getCollection()
            ->addFieldToSelect('tax_class_id')
            ->addIdFilter($productIds);

        $productCollection->getSelect()->joinLeft(
            ['pod' => $productCollection->getSelect()->getConnection()->getTableName('pod_temp_cart')],
            'e.entity_id=pod.product_id and pod.quote_id=' . $this->cart->getQuote()->getId(),
            ['pod.image_id as pod_image_id', 'pod.price as pod_price']
        );

        $result = $productCollection->getSelect()->getConnection()->fetchAll($productCollection->getSelect());

        if (!empty($result)) {
            foreach ($result as $item) {
                $data = $this->dataObjectFactory->create();
                $data->setData($item);
                $parsedCollection->addItem($data);
            }
        }
    }

    return $parsedCollection;
   }
}

From the Above code I am getting the Correct Tax amount but once i click Place order getting the below error due to this unable to place the order.

Infinite loop detected,in exception file.

Please someone update me the working solution for this. Thanks


Get this bounty!!!

#StackBounty: #magento2 #checkout #cart #quote magento 2 move inactive quote to checkout

Bounty: 50

I want to move an inactive quote to the checkout page.

A customer searches for products and adds them in the cart but doesn’t want to checkout on that day.

Now on next day he wants to order some products which are not present in the current cart. He also wants to keep all the current product in the cart.

My solution to this is, the customer will make the current cart(quote) to inactive (By clicking some button on the cart page). This quote will be visible in my account section.

I need an ability to move this inactive cart to an active cart. That is when the customer wants to continue to do checkout of this quote.


Get this bounty!!!

#StackBounty: #magento2 #checkout #cart #redirect #varnish Magento 2 varnish Checkout to cart Redirect Problem

Bounty: 50

I am using Magento 2.3.4

Step To Produce issue:

1)add product to cart

2)go to the checkout page.

3)use a payment method that redirects magneto outside for payment.

4)click on proceed to pay.

5)on payment gateway don’t do the payment.

6)press back from the browser without payment.

7)Now Magento goes to the checkout page Because the session is clear no product is there and the user redirects to the cart page.

8)add one product to the cart.

9)now go to the checkout page. That goto checkout process redirects (302) me to cart page because of varnish.

I think varnish track step 7 and add in browser to redirect users when they come to the checkout page.

How can I stop that redirection? the issue only with varnish, When I use build-in cache is working fine.


Get this bounty!!!

#StackBounty: #magento2 #checkout #magento2.3 #onepage-checkout #billing-address Magento 2.3 – Move billing address below shipping addr…

Bounty: 400

I want to move the billing address form below the shipping address in the checkout, on the first page/step.

Therefore I created a custom module with the following LayoutProcessorPlugin.php.

But now the billing address field is displayed above the shipping address instead of below. And the default checkbox ‘My billing and shipping address are the same’ is now unchecked by default.

Also the line to remove the billing address on the billing step is not working. So now this is displayed on both places.

EDIT:

We also tried to use the Tigren method (https://www.tigren.com/billing-under-shipping-address-m2/) or the SR module (https://github.com/sohelrana09/modified-checkout). But these both have the same problem, the prefix is changed into an input field, instead of a select field. So it does not match the options from the backend anymore.

Image of the prefix input field (should be a select with values from backend):

enter image description here

Any idea how to solve this issue?

My LayoutProcessorPlugin.php code;

<?php

namespace RedableReorderBillingFormModelCheckout;

class LayoutProcessorPlugin
{

    /**
     * @param MagentoCheckoutBlockCheckoutLayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */

    public function afterProcess(
        MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
        array $jsLayout
    )
    {
        // get billing address form at billing step
        $billingAddressForm = $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form'];

        // move address form to shipping step
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['billing-address-form'] = $billingAddressForm;

        // remove form from billing step
        unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']);

        return $jsLayout;
    }
}


Get this bounty!!!

#StackBounty: #magento2 #checkout #error #custom-attributes #customer-address Magento 2 checkout address buttons are missing and the de…

Bounty: 150

We have recently upgraded to Magento ver. 2.3.4 and currently have an issue in Checkout for registered customers.

When they get to the shipping part of checkout they cannot see the buttons for selecting a different shipping address or editing an address:

enter image description here

Looking at the developer console we can also see an Uncaught error shich seems to relate to address:-

enter image description here

 Uncaught TypeError: Unable to process binding "foreach: function(){return {data:address().customAttributes,as:'element'} }"
 Message: Unable to process binding "text: function(){return $parent.getCustomAttributeLabel(element) }"
 Message: Cannot read property 'undefined' of undefined
     at UiClass.getCustomAttributeLabel (VM7680 default.js:68)
     at text (eval at createBindingsStringEvaluator (VM5344 knockout.js:1), <anonymous>:3:72)
     at update (VM5344 knockout.js:4659)
     at ko.dependentObservable.disposeWhenNodeIsRemoved (VM5344 knockout.js:3373)
     at Function.evaluateImmediate_CallReadThenEndDependencyDetection (VM5344 knockout.js:2173)
     at Function.evaluateImmediate_CallReadWithDependencyDetection (VM5344 knockout.js:2140)
     at Function.evaluateImmediate (VM5344 knockout.js:2101)
     at Object.ko.computed.ko.dependentObservable (VM5344 knockout.js:1954)
     at VM5344 knockout.js:3371
     at Object.arrayForEach (VM5344 knockout.js:159)

In addition we also get a similar error on the billing page

 Uncaught TypeError: Unable to process binding "if: function(){return isAddressDetailsVisible() && currentBillingAddress() }"
 Message: Unable to process binding "foreach: function(){return {data:currentBillingAddress().customAttributes,as:'element'} }"
 Message: Unable to process binding "text: function(){return  $parent.getCustomAttributeLabel(element) }"
 Message: Cannot read  property 'undefined' of undefined
     at UiClass.getCustomAttributeLabel (billing-address.js:258)
     at text (eval at createBindingsStringEvaluator (knockout.js:2982), <anonymous>:3:72)
     at update (knockout.js:4659)
     at ko.dependentObservable.disposeWhenNodeIsRemoved (knockout.js:3373)
     at Function.evaluateImmediate_CallReadThenEndDependencyDetection (knockout.js:2173)
     at Function.evaluateImmediate_CallReadWithDependencyDetection (knockout.js:2140)
     at Function.evaluateImmediate (knockout.js:2101)
     at Object.ko.computed.ko.dependentObservable (knockout.js:1954)
     at knockout.js:3371
     at Object.arrayForEach (knockout.js:159)

Could anyone please let me know why this is happening and what I need to to do resolve the issue please?

Thanks.


Get this bounty!!!

#StackBounty: #checkout #magento2.3 #onepage-checkout #billing-address Magento 2.3 – Move billing address below shipping address in che…

Bounty: 200

I want to move the billing address form below the shipping address in the checkout, on the first page/step.

Therefore I created a custom module with the following LayoutProcessorPlugin.php.

But now the billing address field is displayed above the shipping address instead of below. And the default checkbox ‘My billing and shipping address are the same’ is now unchecked by default.

Also the line to remove the billing address on the billing step is not working. So now this is displayed on both places.

How can I place this field below the shipping form and also set the checkbox to check by default again?

LayoutProcessorPlugin.php code;

<?php

namespace RedableReorderBillingFormModelCheckout;

class LayoutProcessorPlugin
{

    /**
     * @param MagentoCheckoutBlockCheckoutLayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */

    public function afterProcess(
        MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
        array $jsLayout
    )
    {
        // get billing address form at billing step
        $billingAddressForm = $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form'];

        // move address form to shipping step
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['billing-address-form'] = $billingAddressForm;

        // remove form from billing step
        unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']);

        return $jsLayout;
    }
}


Get this bounty!!!