0

I am trying to create a new extension attribute for the order API but I keep getting "does not have accessor method getRepeatOrder" error when I call the API endpoint. This is how I currently have things setup.

Vendor/Module/etc/extension_attributes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
        <attribute code="repeat_order" type="Vendor\Module\Api\Data\RepeatOrderInterface"/>
    </extension_attributes>
</config>

Vendor/etc.di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Vendor\Module\Api\Data\RepeatOrderInterface" type="Vendor\Module\Model\Data\RepeatOrder"/>
</config>

Vendor/Module/Api/Data/RepeatOrderInterface

<?php

namespace Vendor\Module\Api\Data;

use Magento\Framework\Api\ExtensibleDataInterface;

interface RepeatOrderInterface extends ExtensibleDataInterface
{
    const REPEAT_ORDER = 'repeat_order';

    /**
     * Get repeat order value
     * 
     * @return string
     */ 
     public function getRepeatOrder();   
     
     /**
     * Set repeat order value
     * 
     * @param string $repeatOrder
     * @return $this
     */ 
     public function setRepeatOrder($repeatOrder);
}

Vendor/Module/Model/Data/RepeatOrder

<?php       
        
namespace Vendor\Module\Model\Data;     

use \Vendor\Module\Api\Data\RepeatOrderInterface;
use \Magento\Framework\Model\AbstractExtensibleModel;

class Items extends AbstractExtensibleModel implements RepeatOrderInterface
{       
    /**     
     * {@inheritdoc}        
     */     
    public function getRepeatOrder()        
    {       
        return $this->getData(self::REPEAT_ORDER);  
    }       
        
    /**     
     * {@inheritdoc}        
     */     
    public function setRepeatOrder($repeatOrder)        
    {       
        return $this->setData(self::REPEAT_ORDER, $repeatOrder);    
    }
}   

Vendor/Plugin/OrderRepositoryPlugin

<?php
namespace Vendor\Module\Plugin;
 
use Magento\Sales\Api\Data\OrderExtensionFactory;
use Magento\Sales\Api\Data\OrderExtensionInterface;
use Sons\API\Api\Data\RepeatOrderInterface;
use Magento\Sales\Api\Data\OrderSearchResultInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
 

class OrderRepositoryPlugin
{
    const REPEAT_ORDER = 'repeat_order';
 
    protected $extensionFactory;
 
    public function __construct(OrderExtensionFactory $extensionFactory)
    {
        $this->extensionFactory = $extensionFactory;
    }

    public function beforeSave(
        OrderRepositoryInterface $subject,
        RepeatOrderInterface $order
    ) {
        $extensionAttributes = $order->getExtensionAttributes(); 
        $extensionAttributes = $extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();

        $repeatOrderAttribute = $extensionAttributes->getRepeatOrder();

        if (!is_null($repeatOrderAttribute)) {
            $order->setData('repeat_order',$repeatOrderAttribute);
        }

        return $order;
    }
}

But whenever I make a call to {magento_api_url}/V1/orders using the following payload:

{
  "entity":{
    "entity_id":1557418,
    "repeat_order":"true"
  }
}

I get the following error: "message": "Property \"RepeatOrder\" does not have accessor method \"getRepeatOrder\" in class \"Magento\\Sales\\Api\\Data\\OrderInterface\".",

I'd really appreciate any help on this one, as it's been driving me crazy all day :D

Thanks everyone,

Best wishes

5
  • try rm -rf generated/* and php bin/magento s:d:c
    – Pawan
    Commented Sep 3, 2021 at 4:19
  • Pawan, I have tried that many times with no success :D i've even tried "rm -rf generated/ var/view_preprocessed && bin/magento s:upgrade && bin/magento s:d:c && bin/magento i:reindex && bin/magento c:f" just to make double sure, but still nothing changes :/
    – SNAFU
    Commented Sep 3, 2021 at 6:30
  • have you set the dependency inside the module.xml for Magento_Sales? Maybe it's a module loading issue <sequence> <module name="Magento_Sales"/> </sequence> Commented Sep 3, 2021 at 11:27
  • Alan - that's a good shout actually. I'll give that a go then I'll report back. Thank you.
    – SNAFU
    Commented Sep 3, 2021 at 11:34
  • @AlanZavagli Ah no, added in the Magento_Sales module dependency as suggested, reset the value in the setup_module table and ran bin/magento s:d:c && bin/magento setup:upgrade but still get the same error when calling the API
    – SNAFU
    Commented Sep 3, 2021 at 11:45

1 Answer 1

1

Ok I figured this one out. So it turns out instead of setting the payload like this:

{
  "entity":{
    "entity_id":1557418,
    "repeat_order":"true"
  }
}

I should have set it like this because it's an extension attribute:

{
  "entity":{
    "entity_id":1557418,
    "extension_attributes: {
        "repeat_order":"true"
    }
  }
}

otherwise the error message "Property "RepeatOrder" does not have accessor method "getRepeatOrder" in class "Magento\Sales\Api\Data\OrderInterface would ring true, as the actual order does not contain this method, it's an attribute extension method :)

After solving that one, the next error was one to say the first argument of the save() method is incorrect. Long story short, just remove the following line in the beforeSave() method to fix this, you don't need to return the order here:

return $order;

Now when I call the POST method for {magento_api_url}/V1/orders and set the payload correctly, the value is being saved as expected :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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