Magento связывает клиента с заказом по размещенному заказу

Мой пользовательский модуль наблюдает за событием sales_order_place_after и создает клиента и связывает клиента с заказом, устанавливая customerId для заказа.

Что работает?

  • Заказ размещен
  • Клиент создан
  • customerId обновляется в базе данных заказов

Что не работает?

  • customerId мгновенно возвращается к NULL другим скриптом

Как я могу узнать, какой скрипт обновляет customerId до NULL, после того, как мой наблюдатель запущен?

Ответ 1

У меня была та же проблема: я полагал, что вызов метода save в заказе вызвал то, что sales_order_save_before/after события sales_order_save_before/after, один из которых устанавливал идентификатор клиента обратно в null. Я работал над этим, сохраняя только те атрибуты, которые я хотел, вместо того, чтобы запускать сохранение всего заказа:

$order
    ->setCustomerId($customer->getId())
    ->setCustomerIsGuest(0)
    ->setCustomerGroupId($customer->getGroupId());

$order->getResource()
    ->saveAttribute($order, 'customer_id'      )
    ->saveAttribute($order, 'customer_is_guest')
    ->saveAttribute($order, 'customer_group_id');

Это позволило мне успешно связать клиента с заказом в Magento EE 1.14.3.10, используя событие sales_model_service_quote_submit_success.

Ответ 2

Вы должны изменить событие на sales_model_service_quote_submit_success

Пример кода (версия Magento 2): events.xml

<event name="sales_model_service_quote_submit_success">
        <observer name="quote_submit_success_observer" instance="Namespace\ModuleName\Observer\GenerateObserver" />
    </event>

GenerateObserver.php

 ...
 public function execute(\Magento\Framework\Event\Observer $observer)
 {
    /** @var \Magento\Sales\Model\Order $order */
        $order = $observer->getEvent()->getData('order');

    // Ensure customer is registered
    $this->registerCustomer($order);
    $order->getResource()->save($order);
 }

protected function registerCustomer(
    \Magento\Sales\Api\Data\OrderInterface $order
) {
    /** @var \Magento\Sales\Model\Order $order */

    if ($order->getCustomerId() === null) {
        // Load customer by email, create if not exists.
        try {
            $customerData = $this->customerRepository->get($order->getCustomerEmail());
        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
            $customerData = $this->orderCustomerManager->create($order->getId());
        }

        $order->setCustomerId($customerData->getId());
    }

    return $this;
}
 ...

Ответ 3

У меня недостаточно репутации, чтобы комментировать, но я смог использовать ответ @gregdev для достижения этой цели.

Config.xml добавить наблюдателя событий:

<sales_model_service_quote_submit_success>
            <observers>
                <your_observer_name_here>
                    <class>module/observer</class>
                    <method>checkOrderCustomer</method>
                </your_observer_name_here>
            </observers>
</sales_model_service_quote_submit_success>

В вашем Observer.php

public function checkOrderCustomer($observer){
    $order = $observer->getEvent()->getOrder();
    //however you want to check for customer
    $customerEmail = $order->getCustomerEmail();
    $customer = Mage::getModel('customer/customer')->loadByEmail($customerEmail);
        if($customer->getId()){
            //assign order to customer
            $order
                ->setCustomerId($customer->getId())
                ->setCustomerIsGuest(0)
                ->setCustomerGroupId($customer->getGroupId());

            $order->getResource()
                ->saveAttribute($order, 'customer_id'      )
                ->saveAttribute($order, 'customer_is_guest')
                ->saveAttribute($order, 'customer_group_id');
        }
    }
}

Я думаю, что проблема с sales_order_place_after связана со следующим: Mage/Sales/Model/Service/Quote.php

$transaction->addObject($order);
$transaction->addCommitCallback(array($order, 'place'));
$transaction->addCommitCallback(array($order, 'save'));

Я не уверен, получает ли переменная $order переданная второму sales_order_place_after вызову, какие-либо изменения клиента, которые были применены во время события sales_order_place_after.