How to extend

Order workflow

Add custom export format

Create an own module:
  • As first step, we must introduce a custom module

  • See how to create a new Module at the Magento developer documentation

In the following example, we create the module MyModule_CustomOrderExportFormat:
mkdir -p app/code/MyModule/CustomOrderExportFormat/etc (1)
touch app/code/MyModule/CustomOrderExportFormat/etc/module.xml (2)
touch app/code/MyModule/CustomOrderExportFormat/registration.php (3)
1 Create the folder structure MyModule
2 Create the required module.xml
3 Create the required registration.php
app/code/MyModule/CustomOrderExportFormat/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="MyModule_CustomOrderExportFormat" setup_version="1.0.0">
        <sequence>
            <module name="TechDivision_PacemakerOrderExport"/>
        </sequence>
    </module>
</config>
app/code/MyModule/CustomOrderExportFormat/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'MyModule_CustomOrderExportFormat',
    __DIR__
);

We need to specify the TechDivision_PacemakerOrderExport module in the sequence of our new module.xml to be able to overwrite the existing pipeline configuration

Add an executor, which transforms your order to your desired format.

To register your executor, you must add the following entry to the di.xml of your module:
app/code/MyModule/CustomOrderExportTransformAdapter/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="TechDivision\PacemakerOrderExport\Model\ExportFormatProvider">
        <arguments>
            <argument name="formatList" xsi:type="array">
                <item name="default_open_trans" xsi:type="array">
                    <item name="code" xsi:type="string">my_custom_transform_adapter</item>
                    <item name="label" xsi:type="string">My Custom Transform Adapter</item>
                    <item name="type" xsi:type="string">MyModule\CustomOrderExportTransformAdapter\Model\MyExecutor</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

Add custom transport adapter

Add an executor, which transports your transformed order to a target destination in the same way as described for custom export formatter.

To register your executor, you must add the following entry to the di.xml of your module:
app/code/MyModule/CustomOrderExportTransportAdapter/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="TechDivision\PacemakerOrderExport\Model\TransportAdapterProvider">
        <arguments>
            <argument name="transportAdapterList" xsi:type="array">
                <item name="my_custom_transport_adapter" xsi:type="array">
                    <item name="code" xsi:type="string">my_custom_transport_adapter</item>
                    <item name="label" xsi:type="string">My Custom Transport Adapter</item>
                    <item name="type" xsi:type="string">MyModule\CustomOrderExportTransportAdapter\Model\MyExecutor</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

Add custom order response handler

Add an executor, which handles the order export response, in the same way as described for custom export formatter.

To register your executor you need to add following entry to the di.xml of your module:
app/code/MyModule/CustomOrderExportResponseHandler/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="TechDivision\PacemakerOrderExport\Model\ResponseHandlerProvider">
        <arguments>
            <argument name="handlerList" xsi:type="array">
                <item name="my_custom_response_handler" xsi:type="array">
                    <item name="code" xsi:type="string">my_custom_response_handler</item>
                    <item name="label" xsi:type="string">My Custom Response Handler</item>
                    <item name="type" xsi:type="string">MyModule\CustomOrderExportResponseHandler\Model\MyExecutor</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

Add custom notification handler

Add an executor, which sends a (or multiple) notification, in the same way as described for custom export formatter.

To register your executor you need to add following entry to the di.xml of your module:
app/code/MyModule/CustomOrderExportNotification/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="TechDivision\PacemakerOrderExport\Model\NotificationHandlerProvider">
        <arguments>
            <argument name="notificationHandlerList" xsi:type="array">
                <item name="my_custom_notification" xsi:type="array">
                    <item name="code" xsi:type="string">my_custom_notification</item>
                    <item name="label" xsi:type="string">My Custom Notification</item>
                    <item name="type" xsi:type="string">MyModule\CustomOrderExportNotification\Model\MyExecutor</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

Entity Export

Add new modifier

Modifiers can be used to make further additions to the export.

Modifiers are used to define the conditions under which a specific entity (customer, order, …​) should be exported (or re-exported in case of an error).

These must also get registered in the DI, named in the ReschedulableErroredEntitiesModifierComposite and the ScheduledEntitiesModifierComposite.

The modifier must then implement the ModifierInterface. Then you have access to the complete SQL statement and can add various joins, new where conditions, etc. as needed.

Example for a di.xml
<virtualType name= "TechDivision\PacemakerEntityExport\Virtual\ScheduledEntitiesModifierComposite">
    <arguments>
        <argument name="modifiers" xsi:type="array">
            <item name="your.name" xsi:type="object">yourModifier</item>
        </argument>
    </arguments>
</virtualType>
<virtualType name= "TechDivision\PacemakerEntityExport\Virtual\ReschedulableErroredEntitiesModifierComposite">
    <arguments>
        <argument name="modifiers" xsi:type="array">
            <item name="your.name" xsi:type="object">yourModifier</item>
        </argument>
    </arguments>
</virtualType>

Add new entity definition

A definition must get created so that Pacemaker knows when to process an export.

This definition implements the `ExportEntityDefinitionInterface'.

This must get registered in the `ExportEntityDefinitionList' in the DI.

Example for a di.xml
<type name= "TechDivision\PacemakerEntityExportInitializer\Model\ExportEntityDefinitionList">
    <arguments>
        <argument name="exportEntityDefinitions" xsi:type="array">
            <item name="your.name" xsi:type="object">YourDefinition</item>
        </argument>
    </arguments>
</type>

Compatibility AttemptsLimit vs. RescheduleErroredEntitiesForExport

The Pacemaker Process Pipelines and the Entity Export have certain retry mechanisms which may not be compatible under certain circumstances.

The AttemptsLimit condition can be used to re-execute steps up to the number specified via the DI in the event of errors. The entity export recognises errors based on export attempts. By default, three are configured here. This means that no further export is attempted after three export failures (export step).

It is now possible that the export step also contains an AttemptsLimit condition.

To make the two mechanisms compatible with each other, the executor must contain the following code.

Example for a retry compatibility exception handling
<?php
public function process(StepInterface $step)
{
    try {
        $entityId = (int)$step->getArgumentValueByKey(ScheduleEntitiesForExport::ARGUMENT_IDENTIFIER);
        $entityCode = (string)$step->getArgumentValueByKey(ScheduleEntitiesForExport::ARGUMENT_ENTITY_CODE);
        // Custom code
        // Export functionality
    } catch (Exception $e) {
        $this->logger->error(
            sprintf("Something went wrong when processing the response for order id %s", $entityId)
        );
        /** @var IsLastAttemptInterface $this->isLastAttempt */
        if ($this->isLastAttempt->execute($step)) {
            /** @var CommitExportErrorInterface $this->commitExportError */
            $this->commitExportError->execute($entityCode, $entityId);
        }
        throw $e;
    }
}