0

I have a custom attribute that is placed in the Billing Address section. Now there's a condition that I only need to save the first 200 character of my custom attribute text box. Is there an event or observer that will intercept this request before proceeding to save/place order? So basically on the checkout page after inputting the text in my custom attribute when user click the Place Order button I want to check this input first if it's beyond the limit then I will trim the text. How do I do this?

Update:

When I tried to intercept the request under Magento\Checkout\Api\GuestPaymentInformationManagementInterface I was able to view the personal_message custom attribute that I'm looking at. But when I try to save or change the value it didn't allow me. How can I override it?

<type name="Magento\Checkout\Api\GuestPaymentInformationManagementInterface">
    <plugin name="validate-billing-information" type="Vendor\Module\Plugin\Checkout\BillingValidation"/>
</type>

And this is the code I was trying to overwrite

public function beforeSavePaymentInformationAndPlaceOrder(
    \Magento\Checkout\Api\GuestPaymentInformationManagementInterface $subject,
        $cartId,
        $email,
        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
        \Magento\Quote\Api\Data\AddressInterface $billingAddress = null
) {
   $billingAddress->setPersonalMessage("This is an overwritten message");
   $billingAddress->save();
}

But doing this throws an error of

webapi-5f6f60228b3a3; Message: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`homestead_goodgifts`.`quote_address`, CONSTRAINT `QUOTE_ADDRESS_QUOTE_ID_QUOTE_ENTITY_ID` FOREIGN KEY (`quote_id`) REFERENCES 
    

enter image description here

enter image description here

1
  • You shouldn't call save in your plugin, just edit billing address property, and original savePaymentInformationAndPlaceOrder will take care of saving. Lastly, don't forget to check billingAddress is not empty! Some code is allowed to call this API without billing address, and your plugin will break things. – Roman Kabanov Sep 26 '20 at 21:53
0

You can observe the sales_order_place_before event.

Here is an example:

namespace [VendorName]\[ModuleName]\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Sales\Api\OrderAddressRepositoryInterface;

class [ObserverName] implements ObserverInterface
{
    private $orderAddressRepository;

    public function __construct(OrderAddressRepositoryInterface $orderAddressRepository)
    {
        $this->orderAddressRepository = $orderAddressRepository;
    }

    public function execute(Observer $observer)
    {
        $order = $observer->getEvent()->getOrder();
        $billingAddress = $order->getBillingAddress();
        if ($billingAddress) {
            $[yourCustomAttributeName] = $billingAddress->getCustomAttribute('[your_custom_attribute_name]');
            if (!empty($[yourCustomAttributeName]) && count($[yourCustomAttributeName]) > 200) {
                $[yourCustomAttributeName] = substr($[yourCustomAttributeName], 0, 200);
                $billingAddress->setCustomAttribute('your_custom_attribute_name', $[yourCustomAttributeName]);
                $this->orderAddressRepository->save($billingAddress);
            }
        }
    }

}

[updated answer]

Try observing the checkout_submit_before.

namespace [VendorName]\[ModuleName]\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class [ObserverName] implements ObserverInterface
{
    public function execute(Observer $observer)
    {
        $quote = $observer->getEvent()->getQuote();
        $billingAddress = $quote->getBillingAddress();
        if ($billingAddress) {
            $personalMessage = $billingAddress->getCustomAttribute('personal_message');
            if (!empty($personalMessage) && count($personalMessage) > 200) {
                $personalMessage = substr($personalMessage, 0, 200);
                $billingAddress->setCustomAttribute('personal_message', $personalMessage);
            }
        }
    }

}
10
  • This didn't work. I can't see the custom attributes that is inside the billing address. When I check the parameters sent in v1/guestt/{id}/payment-informatttion the customattributes is inside the billing address but when I access this using the function above it didn't work – MadzQuestioning Sep 26 '20 at 14:22
  • could you please share what are the items displayed when you hit the API? – Rendy Eko Prastiyo Sep 26 '20 at 18:05
  • Sure thing dude this is the screenshot of the request and payload I want to modify. Thanks for the reply. I have updated my question @Rendy – MadzQuestioning Sep 26 '20 at 19:06
  • @MadzQuestioning that's quote address, not order address. To get quote address, you should observe checkout_submit_all_after. I will update above answer. – Rendy Eko Prastiyo Sep 26 '20 at 19:21
  • @MadzQuestioning updated the answer by observing checkout_submit_all_before event. – Rendy Eko Prastiyo Sep 26 '20 at 19:34

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.