0

Using Magento 2.3, I'm trying to get a custom attribute from the order and save it to the invoice when the invoice is first created.

I already have the custom attributes setup and saving to the order when order is first placed, but can't seem to pass that variable and save it to the invoice once that's created.

I have an observer for the event sales_order_invoice_pay:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> 
    <event name="sales_order_invoice_pay">
        <observer name="salesrep_sales_order_invoice_pay" instance="Vendor\Module\Observer\Sales\Invoice\Salesrep"/>
    </event>
</config>

and my observer:

<?php
namespace Vendor\Module\Observer\Sales\Invoice;

use Magento\Framework\Event\ObserverInterface;

class Salesrep implements ObserverInterface
{

  protected $messageManager;

  public function __construct(
    \Magento\Framework\Message\ManagerInterface $messageManager
  ){
    $this->messageManager = $messageManager;
  }

  public function execute(\Magento\Framework\Event\Observer $observer)
  {
    try {
      $invoice = $observer->getEvent()->getInvoice();
      $order = $invoice->getOrder();
      $salesrep = $order->getData('salesrep');
      $invoice->setSalesrep($salesrep);
    } catch (\Exception $e) {
      $this->messageManager->addError(__($e->getMessage()));
      return null;
    }
  }
}

The custom order attribute that I'm trying to save to invoice is called salesrep, I've confirmed that the salesrep is saving properly to the Order but not saving to the invoice.


EDIT: Here is the code I'm using to save salesrep to the order initially.

events.xml

<event name="sales_order_place_after">
        <observer name="salesrep_sales_order_place_after" instance="Vendor\Module\Observer\Sales\Order\Salesrep"/>
    </event>

My observer:

<?php
namespace Vendor\Module\Observer\Sales\Order;

use Magento\Framework\Event\ObserverInterface;

class Salesrep implements ObserverInterface
{
  public function __construct(
    \Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface
  ){
    $this->_customerRepositoryInterface = $customerRepositoryInterface;
  }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
      $order = $observer->getEvent()->getOrder();

    try {
        $customer = $this->_customerRepositoryInterface->get($order->getCustomerEmail(), $websiteId = 1);
        $salesrep = $customer->getCustomAttribute('salesrep')->getValue();
        $order->setSalesrep($salesrep);
    } catch (\Magento\Framework\Exception\NoSuchEntityException $noSuchEntityException) {
        return null;
    }
    }
}
  • instead of retrieving order from sale repository you can retrieve order from $invoice object like this $order = $invoice->getOrder(); – Aman Alam Jan 13 '19 at 20:54
  • Thanks Aman, good call. I've updated my code which got rid of the ID NULL error, however now the order attribute isn't saving to the invoice. I've updated my question. Any idea? – AJK Jan 13 '19 at 20:58
  • You log $order->getSalesrep() and check its fetching from order or not. – Aman Alam Jan 13 '19 at 21:01
  • looks like $order->getSalesrep() is returning NULL, I'm using Braintree as payment processor, I'm wondering if it's creating the invoice before the order is completely done saving. – AJK Jan 13 '19 at 21:06
  • 1
    @AJ47 you are setting representative object after place order, seems salesrep_sales_order_place_after is running after salesrep_sales_order_invoice_pay, try setting it before place order in order object so that it will get retrieved by salesrep_sales_order_invoice_pay – Aman Alam Jan 14 '19 at 6:53
1

Try to use events

sales_model_service_quote_submit_before

To save data to order instead of sales_order_place_after

And

sales_order_invoice_register

To save data to invoice instead of sales_order_invoice_pay

Hope this help

| improve this answer | |
  • Thanks! Although I didn't test these, you were def pointing in the right direction. I ended up using sales_order_place_before to make sure salesrep was saved before the invoice was created. – AJK Jan 14 '19 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.