Skip to content

SourceItem Entity Extension

Ievgen Shakhsuvarov edited this page Jul 16, 2019 · 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

Adding new Data interface representing Allocated Space

For example, according to business requirements merchant wants to manage the allocated space on each Source. What he can do is to introduce dedicated Entity responsible for this - SourceItemPlaceAllocation

interface SourceItemPlaceAllocation
{
    /**
     * Get Source Code
     *
     * @return string
     */
    public function getSourceCode();

    /**
     * Set Source Code
     *
     * @param string $sourceCode
     * @return void
     */
    public function setSourceCode(string $sourceCode);

    /**
     * Get SKU
     *
     * @return string
     */
    public function getSku();

    /**
     * Set Sku
     *
     * @param string $sku
     * @return void
     */
    public function setSku(string $sku);

    /**
     * Get date of arrival
     *
     * @return string
     */
    public function getDateOfArrival();

    /**
     * Get date of arrival
     *
     * @param string $date
     * @return void
     */
    public function setDateOfArrival(string $date);

    /**
     * Get date of shipment
     *
     * @return string
     */
    public function getDateOfShipment();

    /**
     * Get date of shipment
     *
     * @param string $date
     * @return void
     */
    public function setDateOfShipment(string $date);

    /**
     * Get Source Item location within Source
     *
     * @return string
     */
    public function getLocationWithinSource();

    /**
     * Set Source Item location within Source
     *
     * @param string $location
     * @return void
     */
    public function setLocationWithinSource(string $location);

    /**
     * Amount of Place Occupied by these SourceItems
     *
     * @return float
     */
    public function getOccupiedSpace();

    /**
     * Set Amount of Place Occupied by these SourceItems
     *
     * @param string $occupiedSpace
     * @return void
     */
    public function setOccupiedSpace(float $occupiedSpace);
}

And Service which will retrieve current entity.

interface GetAllocatedPlaceBySourceItem
{
    public function execute(string $sku, string $sourceCode) : SourceItemPlaceAllocation;
}

There, of course, could be other services introduced. For example, to calculate all occupied space per Source for specified Date, but the main idea is that extension developer is introducing own entities (stored in a dedicated table or even Data Storage) and manage linkage to existing SourceItem.

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. Doing this injection we introduce a linkage between Sales Channel (Magento Website) and Particulat Stock. This is how the declaration looks like: 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