2

I'm brand new to Magento 2 programming, although I have a number of years of PHP behind me.

I need to store an id from an external system alongside an order that that system creates.

I've got the code that creates the quote and turns it into an order working, alongside my custom payment method, but I can't get it to save my extra ID.

I've used and altered code found elsewhere on this site to create the order:

public function doCreate($dataArray, $order=null) {
    foreach($dataArray->Orders as $orderData) {
        $orderData=$orderData->Order;
    }
    $store=$this->storeManager->getStore();
    $websiteId = $this->storeManager->getStore()->getWebsiteId();
    $customer=$this->customerFactory->create();
    $customer->setWebsiteId($websiteId);
    $customer->loadByEmail($orderData->ShippingInfo->Email);// load customet by email address
    $customerName=explode(' ',(string)$orderData->ShippingInfo->RecipientName);
    $firstName=$customerName[0];
    $lastName=$customerName[count($customerName)-1];
    echo "First $firstName  Last $lastName \n";
    if(!$customer->getEntityId()){
        //If not avilable then create this customer
        $customer->setWebsiteId($websiteId)
                ->setStore($store)
                ->setFirstname($firstName)
                ->setLastname($lastName)
                ->setEmail((string)$orderData->ShippingInfo->Email)
                ->setPassword($orderData->ShippingInfo->Email);
        $customer->save();
    }
    $quote=$this->quote->create(); //Create object of quote
    $quote->setStore($store); //set store for which you create quote
    // if you have allready buyer id then you can load customer directly
    $customer= $this->customerRepository->getById($customer->getEntityId());
    $quote->setCurrency();
    $quote->assignCustomer($customer); //Assign quote to customer

    //add items in quote
    foreach($orderData->OrderItems as $item){
        $item=$item->Item;
        $product=$this->product->load($item->SKU);
        $product->setPrice($item->Price);
        $quote->addProduct(
            $product,
            intval($item->Quantity)
        );
    }

    //Set Address to quote
    $shippingInfo=$orderData->ShippingInfo;

    $address=array(     //address Details
        'firstname'     => (string)$firstName, 
        'lastname'      => (string)$lastName,
        'street'        => (string)$shippingInfo->Address1,
        'city'          => (string)$shippingInfo->City,
        'country_id'    => (string)$shippingInfo->Country,
        'region'        => (string)$shippingInfo->State,
        'postcode'      => (string)$shippingInfo->PostalCode,
        'telephone'     => (string)$shippingInfo->PhoneNumber,
        'save_in_address_book' => 0
    );

    $quote->getBillingAddress()->addData($address);
    $quote->getShippingAddress()->addData($address);

    // Collect Rates and Set Shipping & Payment Method

    $shippingAddress=$quote->getShippingAddress()
                    ->setCollectShippingRates(true)
                    ->collectShippingRates()
                    ->setShippingMethod('freeshipping_freeshipping'); //shipping method  $shippingInfo->Service
    $quote->setPaymentMethod('cpayment'); //payment method
    $quote->setInventoryProcessed(false); //not effetc inventory
    $quote->save(); //Now Save quote and your quote is ready

    // Set Sales Order Payment
    $quote->getPayment()->importData(['method' => 'cpayment']);

    // Collect Totals & Save Quote
    $quote->collectTotals()->save();

    // Create Order From Quote
    $order = $this->quoteManagement->submit($quote);
    $order->setEmailSent(0);
    $increment_id = $order->getRealOrderId();
    if($order->getEntityId()){
        $result['order_id']= $order->getRealOrderId();
        $order->addData('external_id',$dataArray->ExtId);//THIS IS THE ID I NEED TO SAVE
        $order->save();
    }else{
        $result=['error'=>1,'msg'=>'Your custom message'];
    }
    echo "Complete: Final result is\n";
    print_r($result);
    return $result;
}

If I add debugging near the end, eg echo $order->getData('external_id') then it shows up, but it's not saved in the database.

I guess I must be missing some XML somewhere, but as I said I'm brand new to Magento and finding the lack of documentation frustrating (mostly seems to be 'copy and paste this and it will work'!)

Thanks in advance...

  • You try to use $order->setData(). – Khoa TruongDinh Aug 5 '16 at 12:20
  • Sorry, yes I should point out I have already tried $order->setData() too. – boris_horis Aug 5 '16 at 13:31
  • In table sales_order has column external_id? – Khoa TruongDinh Aug 5 '16 at 15:44
  • No, that column doesn't exist. Do I have to do something to create it? (I'm writing a plugin by the way, so I can't just manually create a column in the DB - it would need to be done programatically). Thanks for your help on this by the way! – boris_horis Aug 5 '16 at 16:04
  • Bump... Can anybody shed light on how to do this with a plugin - ie not making changes to the core code? – boris_horis Aug 15 '16 at 8:07
0

From my experience:

First of all, we need to create a new column to two tables: quote and sales_order tables.

app/code/Vendor/SalesOrder/Setup/UpgradeSchema.php

<?php

namespace Vendor\SalesOrder\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;

class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * Upgrades DB schema for a module
     *
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        $quote = 'quote';
        $orderTable = 'sales_order';

        $setup->getConnection()
            ->addColumn(
                $setup->getTable($quote),
                'external_id',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' =>'External ID'
                ]
            );
        //Order Grid table
        $setup->getConnection()
            ->addColumn(
                $setup->getTable($orderTable),
                'external_id',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' =>'External ID'
                ]
            );

        $setup->endSetup();
    }
}

Second, create fieldset.xml

app/code/Vendor/SalesOrder/etc/fieldset.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd">
    <scope id="global">
        <fieldset id="sales_convert_quote">
            <field name="external_id">
                <aspect name="to_order" />
            </field>
        </fieldset>
    </scope>
</config>

Basically, this fieldset is used for defining the attribute which will be copied from quote object to order object automatically.

Don't forget to create registration.php, module.xml and run setup upgrade command.

After that, now we can create more functions to work with quote and order objects.

  • Hi, thank you very much for this. Apologies for the newbie questions! As I'm developing this plugin that will end up in the Magento store, how would I get this code into the Vendor/SalesOrder/Setup folder? I was under the impression that I could only provide code in my own module's folder? I did try creating a SalesOrder folder in my own module, but, predicatably, this didn't work! – boris_horis Aug 8 '16 at 11:52

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.