Skip to content

SourceItem Entity Extension

Igor Miniailo edited this page Mar 5, 2018 · 20 revisions

Table of Contents

Overview

This document describes general recommendations on how entities introduced in the scope of Magento MSI (Source, Stock, SourceItem, StockSourceLink etc.) could be extended with additional attributes via an example of the SourceItem entity representing a particular amount of Products in dedicated Source (warehouse).

Request for SourceItem Extension

Hi Igor. We had a meeting with your regarding MSI not long time ago. I have one general question In case we need to add some additional attributes to source items i.e. expected_date, item_location(aisle/shelve), etc What is preferable approach from your point of view:

  1. Add this columns to inventory_source_item table and extend existing interfaces
  2. Create new table inventory_source_item_attributes and create new interfaces that will work with that newly created entity

and also what will be preferable approach of import/export:

  1. separate CSV
  2. add new attributes into existing CSV for source items

SourceItem entity representation

First of all, let's look at the declaration of SourceItemInterface:

namespace Magento\InventoryApi\Api\Data;

use Magento\Framework\Api\ExtensibleDataInterface;

/**
 * Represents amount of product on physical storage
 * Entity id getter is missed because entity identifies by compound identifier (sku and source_code)
 *
 * Used fully qualified namespaces in annotations for proper work of WebApi request parser
 *
 * @api
 */
interface SourceItemInterface extends ExtensibleDataInterface
{
    /**#@+
     * Constants for keys of data array. Identical to the name of the getter in snake case
     */
    const SKU = 'sku';
    const SOURCE_CODE = 'source_code';
    const QUANTITY = 'quantity';
    const STATUS = 'status';
    /**#@-*/

    /**#@+
     * Source items status values
     */
    const STATUS_OUT_OF_STOCK = 0;
    const STATUS_IN_STOCK = 1;
    /**#@-*/

    /**
     * Get source item sku
     *
     * @return string|null
     */
    public function getSku();

    /**
     * Set source item sku
     *
     * @param string|null $sku
     * @return void
     */
    public function setSku($sku);

    /**
     * Get source code
     *
     * @return string|null
     */
    public function getSourceCode();

    /**
     * Set source code
     *
     * @param string|null $sourceCode
     * @return void
     */
    public function setSourceCode($sourceCode);

    /**
     * Get source item quantity
     *
     * @return float|null
     */
    public function getQuantity();

    /**
     * Set source item quantity
     *
     * @param float|null $quantity
     * @return void
     */
    public function setQuantity($quantity);

    /**
     * Get source item status (One of self::STATUS_*)
     *
     * @return int|null
     */
    public function getStatus();

    /**
     * Set source item status (One of self::STATUS_*)
     *
     * @param int|null $status
     * @return int
     */
    public function setStatus($status);

    /**
     * Retrieve existing extension attributes object
     *
     * Null for return is specified for proper work SOAP requests parser
     *
     * @return \Magento\InventoryApi\Api\Data\SourceItemExtensionInterface|null
     */
    public function getExtensionAttributes();

    /**
     * Set an extension attributes object
     *
     * @param \Magento\InventoryApi\Api\Data\SourceItemExtensionInterface $extensionAttributes
     * @return void
     */
    public function setExtensionAttributes(SourceItemExtensionInterface $extensionAttributes);
}

Here are attributes description:

  • SKU - represents product SKU
  • SourceCode - the reference to Source where the product located
  • Quantify - the number of products located on particular Source
  • Status - status per Source (In Stock / Out of Stock) describing whether we can fulfill orders from this Source.
  • getExtensionAttributes/setExtensionAttributes - methods preserved for extension Data Interface with custom attributes

Recommendation how to extend SourceItem entity

Here is I recommend you to keep a general recommendation for extending Magento entities:

  • From the code standpoint - to use Extension attributes, as \Magento\InventoryApi\Api\Data\SourceItemInterface provides two methods for these purposes
    /**
     * Retrieve existing extension attributes object
     *
     * Null for return is specified for proper work SOAP requests parser
     *
     * @return \Magento\InventoryApi\Api\Data\SourceItemExtensionInterface|null
     */
    public function getExtensionAttributes();

    /**
     * Set an extension attributes object
     *
     * @param \Magento\InventoryApi\Api\Data\SourceItemExtensionInterface $extensionAttributes
     * @return void
     */
    public function setExtensionAttributes(SourceItemExtensionInterface $extensionAttributes);
  • From DB standpoint - to introduce own table to store these fields. Usage of own table would help you to prevent possible backward incompatibilities in future. As in Magento 2.3 we are introducing Declarative schema for Magento entities. Thus, a way how DB table structure declared could be changed soon. Also, in general, Magento considers DB table structure as a private implementation which potentially could be changed in future. That's why Magento introduces additional abstraction layer on top of Data Schema creation.

Not sure whether you need to introduce a dedicated Data Interface for your needs. You may need it if you are really introducing the Interface which represents an entity from your business domain. Like The Space in your warehouse and you would like to provide an ability of space management (which is currently absent in MSI and may be added in future releases). Thus, you would like to specify particular place(-s) where products are located within the warehouse. And either you would like to introduce date of arrival and date of shipment as you know that some products will arrive soon and need some space to be allocated, but have not been delivered yet. On the other hand - some product already sold, but not yet shipped from the warehouse. For these purposes - you can introduce own Data Interface and some services which will provide you manipulation over these data. But if you just want to add an attribute which makes sense only in the scope of SourceItem entity - it’s better to inject one into the SourceItemInterface via ExtensionAttributes.

and also what will be preferable approach of import/export:

The same recommendation is applicable for import/export: if you consider that you are introducing new Entity - it’s better to introduce the independent Import/Export process for it. If it’s part of SourceItem - just extend existing Import/Export of SourceItems

Existing usages of Extension Attributes

Existing examples of Extension Attributes usages could be either found in Magento MSI codebase. For example, InventorySales module introduces Extension Attribute sales_channels injecting it to Stock entity Magento/InventorySales/etc/extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\InventoryApi\Api\Data\StockInterface">
        <attribute code="sales_channels" type="Magento\InventorySalesApi\Api\Data\SalesChannelInterface[]" />
    </extension_attributes>
</config>

Retrieval and persistence of this attribute implemented via 2 plugins:

MSI Documentation:

  1. Technical Vision. Catalog Inventory
  2. Installation Guide
  3. List of Inventory APIs and their legacy analogs
  4. MSI Roadmap
  5. Known Issues in Order Lifecycle
  6. MSI User Guide
  7. DevDocs Documentation
  8. User Stories
  9. User Scenarios:
  10. Technical Designs:
  11. Admin UI
  12. MFTF Extension Tests
  13. Weekly MSI Demos
  14. Tutorials
Clone this wiki locally