TransWikia.com

magento 2 order grid loading issue after data migration

Magento Asked by Nagaraju Kasa on November 25, 2021

  1. PHP Fatal error: Uncaught Error: Call to a member function getAdditionalInformation() on null in /var/www/magento/vendor/magento/module-sales/Model/OrderRepository.php:172

  2. Verified found that file method contains below code

/**
     * Set additional info to the order.
     *
     * @param OrderInterface $order
     * @return void
     */
    private function setPaymentAdditionalInfo(OrderInterface $order): void
    {
        $extensionAttributes = $order->getExtensionAttributes();
        $paymentAdditionalInformation = $order->getPayment()->getAdditionalInformation();

        $objects = [];
        foreach ($paymentAdditionalInformation as $key => $value) {
            /** @var PaymentAdditionalInfoInterface $additionalInformationObject */
            $additionalInformationObject = $this->paymentAdditionalInfoFactory->create();
            $additionalInformationObject->setKey($key);

            if (!is_string($value)) {
                $value = $this->serializer->serialize($value);
            }
            $additionalInformationObject->setValue($value);

            $objects[] = $additionalInformationObject;
        }
        $extensionAttributes->setPaymentAdditionalInfo($objects);
        $order->setExtensionAttributes($extensionAttributes);
    }
  1. Verified and understand that the issue sales_order records count is not matching with sales_order_payment count.

Ex: sales_order count is: 99999
sales_order_payment is: 88888

Here Could you please help me & advise.

4 Answers

You are missing payment detail of a specific order, check your source database table sales_order_payment check for the order which show you error and export it and import into your new database it will solve your issue!

Answered by Zuby on November 25, 2021

I got solution for this issue.

Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">    
     <preference for="MagentoSalesModelOrderRepository" type="VendorModuleModelOrderRepository"/>
    <type name="VendorModuleModelOrderRepository">
    <arguments>
        <argument name="metadata" xsi:type="object">orderMetadata</argument>
    </arguments>
    </type>
</config>

VendorModuleModelOrderRepository.php

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

namespace VendorModuleModel;

use MagentoFrameworkApiExtensionAttributeJoinProcessorInterface;
use MagentoFrameworkApiSearchCriteriaCollectionProcessorInterface;
use MagentoFrameworkAppObjectManager;
use MagentoFrameworkExceptionInputException;
use MagentoFrameworkExceptionNoSuchEntityException;
use MagentoSalesApiDataOrderExtensionFactory;
use MagentoSalesApiDataOrderExtensionInterface;
use MagentoSalesApiDataOrderInterface;
use MagentoSalesApiDataOrderSearchResultInterfaceFactory as SearchResultFactory;
use MagentoSalesApiDataShippingAssignmentInterface;
use MagentoSalesModelOrderShippingAssignmentBuilder;
use MagentoSalesModelResourceModelMetadata;
use MagentoTaxApiOrderTaxManagementInterface;
use MagentoPaymentApiDataPaymentAdditionalInfoInterface;
use MagentoPaymentApiDataPaymentAdditionalInfoInterfaceFactory;
use MagentoFrameworkSerializeSerializerJson as JsonSerializer;

/**
 * Repository class
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class OrderRepository implements MagentoSalesApiOrderRepositoryInterface
{
    /**
     * @var Metadata
     */
    protected $metadata;

    /**
     * @var SearchResultFactory
     */
    protected $searchResultFactory = null;

    /**
     * @var OrderExtensionFactory
     */
    private $orderExtensionFactory;

    /**
     * @var ShippingAssignmentBuilder
     */
    private $shippingAssignmentBuilder;

    /**
     * @var CollectionProcessorInterface
     */
    private $collectionProcessor;

    /**
     * @var OrderInterface[]
     */
    protected $registry = [];

    /**
     * @var OrderTaxManagementInterface
     */
    private $orderTaxManagement;

    /**
     * @var PaymentAdditionalInfoFactory
     */
    private $paymentAdditionalInfoFactory;

    /**
     * @var JsonSerializer
     */
    private $serializer;

    /**
     * @var JoinProcessorInterface
     */
    private $extensionAttributesJoinProcessor;

    /**
     * Constructor
     *
     * @param Metadata $metadata
     * @param SearchResultFactory $searchResultFactory
     * @param CollectionProcessorInterface|null $collectionProcessor
     * @param MagentoSalesApiDataOrderExtensionFactory|null $orderExtensionFactory
     * @param OrderTaxManagementInterface|null $orderTaxManagement
     * @param PaymentAdditionalInfoInterfaceFactory|null $paymentAdditionalInfoFactory
     * @param JsonSerializer|null $serializer
     * @param JoinProcessorInterface $extensionAttributesJoinProcessor
     */
    public function __construct(
        Metadata $metadata,
        SearchResultFactory $searchResultFactory,
        CollectionProcessorInterface $collectionProcessor = null,
        MagentoSalesApiDataOrderExtensionFactory $orderExtensionFactory = null,
        OrderTaxManagementInterface $orderTaxManagement = null,
        PaymentAdditionalInfoInterfaceFactory $paymentAdditionalInfoFactory = null,
        JsonSerializer $serializer = null,
        JoinProcessorInterface $extensionAttributesJoinProcessor = null
    ) {
        $this->metadata = $metadata;
        $this->searchResultFactory = $searchResultFactory;
        $this->collectionProcessor = $collectionProcessor ?: ObjectManager::getInstance()
            ->get(MagentoFrameworkApiSearchCriteriaCollectionProcessorInterface::class);
        $this->orderExtensionFactory = $orderExtensionFactory ?: ObjectManager::getInstance()
            ->get(MagentoSalesApiDataOrderExtensionFactory::class);
        $this->orderTaxManagement = $orderTaxManagement ?: ObjectManager::getInstance()
            ->get(OrderTaxManagementInterface::class);
        $this->paymentAdditionalInfoFactory = $paymentAdditionalInfoFactory ?: ObjectManager::getInstance()
            ->get(PaymentAdditionalInfoInterfaceFactory::class);
        $this->serializer = $serializer ?: ObjectManager::getInstance()
            ->get(JsonSerializer::class);
        $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor
            ?: ObjectManager::getInstance()->get(JoinProcessorInterface::class);
    }

    /**
     * Load entity
     *
     * @param int $id
     * @return MagentoSalesApiDataOrderInterface
     * @throws MagentoFrameworkExceptionInputException
     * @throws MagentoFrameworkExceptionNoSuchEntityException
     */
    public function get($id)
    {
        if (!$id) {
            throw new InputException(__('An ID is needed. Set the ID and try again.'));
        }
        if (!isset($this->registry[$id])) {
            /** @var OrderInterface $entity */
            $entity = $this->metadata->getNewInstance()->load($id);
            if (!$entity->getEntityId()) {
                throw new NoSuchEntityException(
                    __("The entity that was requested doesn't exist. Verify the entity and try again.")
                );
            }
            $this->setOrderTaxDetails($entity);
            $this->setShippingAssignments($entity);
            $this->setPaymentAdditionalInfo($entity);
            $this->registry[$id] = $entity;
        }
        return $this->registry[$id];
    }

    /**
     * Set order tax details to extension attributes.
     *
     * @param OrderInterface $order
     * @return void
     */
    private function setOrderTaxDetails(OrderInterface $order)
    {
        $extensionAttributes = $order->getExtensionAttributes();
        $orderTaxDetails = $this->orderTaxManagement->getOrderTaxDetails($order->getEntityId());
        $appliedTaxes = $orderTaxDetails->getAppliedTaxes();

        $extensionAttributes->setAppliedTaxes($appliedTaxes);
        if (!empty($appliedTaxes)) {
            $extensionAttributes->setConvertingFromQuote(true);
        }

        $items = $orderTaxDetails->getItems();
        $extensionAttributes->setItemAppliedTaxes($items);

        $order->setExtensionAttributes($extensionAttributes);
    }

    /**
     * Set additional info to the order.
     *
     * @param OrderInterface $order
     * @return void
     */
    private function setPaymentAdditionalInfo(OrderInterface $order): void
    {
        $extensionAttributes = $order->getExtensionAttributes();

        $objects = [];
        try {
            if (! is_null($order->getPayment()) && ! is_null($order->getPayment()->getAdditionalInformation())) {
            $paymentAdditionalInformation = $order->getPayment()->getAdditionalInformation();
            foreach ($paymentAdditionalInformation as $key => $value) {
                /** @var PaymentAdditionalInfoInterface $additionalInformationObject */
                $additionalInformationObject = $this->paymentAdditionalInfoFactory->create();
                $additionalInformationObject->setKey($key);

                if (!is_string($value)) {
                    $value = $this->serializer->serialize($value);
                }
                $additionalInformationObject->setValue($value);

                $objects[] = $additionalInformationObject;
            }
            $extensionAttributes->setPaymentAdditionalInfo($objects);
          $order->setExtensionAttributes($extensionAttributes);
      }
        } catch(Exception $e) {
        }

    }

    /**
     * Find entities by criteria
     *
     * @param MagentoFrameworkApiSearchCriteriaInterface $searchCriteria
     * @return MagentoSalesApiDataOrderSearchResultInterface
     */
    public function getList(MagentoFrameworkApiSearchCriteriaInterface $searchCriteria)
    {
        /** @var MagentoSalesApiDataOrderSearchResultInterface $searchResult */
        $searchResult = $this->searchResultFactory->create();
        $this->extensionAttributesJoinProcessor->process($searchResult);
        $this->collectionProcessor->process($searchCriteria, $searchResult);
        $searchResult->setSearchCriteria($searchCriteria);
        foreach ($searchResult->getItems() as $order) {
            $this->setShippingAssignments($order);
            $this->setOrderTaxDetails($order);
            $this->setPaymentAdditionalInfo($order);
        }
        return $searchResult;
    }

    /**
     * Register entity to delete
     *
     * @param MagentoSalesApiDataOrderInterface $entity
     * @return bool
     */
    public function delete(MagentoSalesApiDataOrderInterface $entity)
    {
        $this->metadata->getMapper()->delete($entity);
        unset($this->registry[$entity->getEntityId()]);
        return true;
    }

    /**
     * Delete entity by Id
     *
     * @param int $id
     * @return bool
     */
    public function deleteById($id)
    {
        $entity = $this->get($id);
        return $this->delete($entity);
    }

    /**
     * Perform persist operations for one entity
     *
     * @param MagentoSalesApiDataOrderInterface $entity
     * @return MagentoSalesApiDataOrderInterface
     */
    public function save(MagentoSalesApiDataOrderInterface $entity)
    {
        /** @var  MagentoSalesApiDataOrderExtensionInterface $extensionAttributes */
        $extensionAttributes = $entity->getExtensionAttributes();
        if ($entity->getIsNotVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) {
            $shippingAssignments = $extensionAttributes->getShippingAssignments();
            if (!empty($shippingAssignments)) {
                $shipping = array_shift($shippingAssignments)->getShipping();
                $entity->setShippingAddress($shipping->getAddress());
                $entity->setShippingMethod($shipping->getMethod());
            }
        }
        $this->metadata->getMapper()->save($entity);
        $this->registry[$entity->getEntityId()] = $entity;
        return $this->registry[$entity->getEntityId()];
    }

    /**
     * Set shipping assignments to extension attributes.
     *
     * @param OrderInterface $order
     * @return void
     */
    private function setShippingAssignments(OrderInterface $order)
    {
        /** @var OrderExtensionInterface $extensionAttributes */
        $extensionAttributes = $order->getExtensionAttributes();

        if ($extensionAttributes === null) {
            $extensionAttributes = $this->orderExtensionFactory->create();
        } elseif ($extensionAttributes->getShippingAssignments() !== null) {
            return;
        }
        /** @var ShippingAssignmentInterface $shippingAssignment */
        $shippingAssignments = $this->getShippingAssignmentBuilderDependency();
        $shippingAssignments->setOrderId($order->getEntityId());
        $extensionAttributes->setShippingAssignments($shippingAssignments->create());
        $order->setExtensionAttributes($extensionAttributes);
    }

    /**
     * Get the new ShippingAssignmentBuilder dependency for application code
     *
     * @return ShippingAssignmentBuilder
     * @deprecated 100.0.4
     */
    private function getShippingAssignmentBuilderDependency()
    {
        if (!$this->shippingAssignmentBuilder instanceof ShippingAssignmentBuilder) {
            $this->shippingAssignmentBuilder = MagentoFrameworkAppObjectManager::getInstance()->get(
                MagentoSalesModelOrderShippingAssignmentBuilder::class
            );
        }
        return $this->shippingAssignmentBuilder;
    }

    /**
     * Helper function that adds a FilterGroup to the collection.
     *
     * @param MagentoFrameworkApiSearchFilterGroup $filterGroup
     * @param MagentoSalesApiDataOrderSearchResultInterface $searchResult
     * @return void
     * @deprecated 101.0.0
     * @throws MagentoFrameworkExceptionInputException
     */
    protected function addFilterGroupToCollection(
        MagentoFrameworkApiSearchFilterGroup $filterGroup,
        MagentoSalesApiDataOrderSearchResultInterface $searchResult
    ) {
        $fields = [];
        $conditions = [];
        foreach ($filterGroup->getFilters() as $filter) {
            $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
            $conditions[] = [$condition => $filter->getValue()];
            $fields[] = $filter->getField();
        }
        if ($fields) {
            $searchResult->addFieldToFilter($fields, $conditions);
        }
    }
}

Answered by Soundararajan m on November 25, 2021

This reason is that the table sales_order_payment is lacking in data. To resolve this error, you must only delete all and re-migrate data again.

Answered by LitExtension Magento Migration on November 25, 2021

We have tested this orders grid issue in the two ways

1. With the replication process
2. Without the replication process
  1. Using the database replication process, the sales_order table records count was not matching with the sales_order_payment table records count. So that vendor/magento/module-sales/Model/OrderRepository.php:172

(IMP Note !!!: sales_order count == sales_order_grid count == sales_order_payment count )

$order->getPayment() for old orders is returning null, so any function (eg. getAdditionalInformation()) is applying on getPayment() object is giving the error.

The solution is the Need to execute delta migration so that whatever the missing records in the sales_order_payment table those will create.

  1. Without the replication process, we didn't get any issue but after did a full migration we have to verify the sales records whether it is matching or not at the database level in m1 and m2

you can compare the sales_order table with the sales_order_payment table using this MySQL query::

SELECT * FROM sales_order WHERE entity_id NOT IN ( SELECT parent_id from sales_order_payment)

after running this query you will get the difference. It will shows empty if there is no difference

Answered by Nagaraju Kasa on November 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP