Order Update Feature

Pacemaker supports the order update in several ways.

You can install all order update modules with all their dependencies using the Pacemaker Order Update component, which calls the entire order update.

Pacemaker Order Update is part of Pacemaker Enterprise Edition.

{
  "name": "pacemaker/component-order-update",
  "type": "metapackage",
  "require": {
    "php": "~7.2.0||~7.3.0||~7.4.0",
    "pacemaker/component-process-pipelines": "^1.5.4",
    "techdivision/order-update-notification-dispatcher": "^1.0.0",
    "techdivision/order-update-notification-dispatcher-api": "^1.0.5",
    "techdivision/order-update-file-system-observer": "^1.0.3",
    "techdivision/order-update-invoice": "^1.1.1",
    "techdivision/order-update-file-system-observer-invoice": "^1.0.1",
    "techdivision/order-update-shipment": "^1.1.1",
    "techdivision/order-update-file-system-observer-shipment": "^1.0.2",
    "techdivision/order-update-creditmemo": "^1.1.2",
    "techdivision/order-update-file-system-observer-creditmemo": "^1.0.2",
    "techdivision/order-update-cancelation": "^1.1.1",
    "techdivision/order-update-file-system-observer-cancellation": "^1.0.3"
  }
}

What can the Pacemaker Order Update component do?

Order Update File System Observer

The module takes care of all the logic of a job update file system, watching and reading the file located in the var/pacemaker/import directory.

class FileReaderProvider
{
    /**
     * @var array
     */
    private $readerGroupedByPatternKey = [];
 /**
     * configuration => [
     *      <key> => [
     *          [disabled] => bool,
     *          'pattern_key' => string
     *          'reader_instance' => instance of FileReaderInterface
     *      ]
     * ]
     *
     * @param array $configuration
     * @throws LocalizedException
     */
    public function __construct(
        array $configuration = []
    ) {
        foreach ($configuration as $key => $config) {
            if (isset($config['disabled']) && $config['disabled'] === true) {
                continue;
            }

            if (!isset($config['pattern_key'])) {
                throw new LocalizedException(__('"pattern_key" needs to be defined'));
            }

            if (!($config['reader_instance'] instanceof FileReaderInterface)) {
                throw new LocalizedException(
                    __(
                        '%class needs to implement %interface',
                        [
                            'class' => get_class($config['reader_instance']),
                            'interface' => FileReaderInterface::class
                        ]
                    )
                );
            }

            if (!isset($this->readerGroupedByPatternKey[$config['pattern_key']])) {
                $this->readerGroupedByPatternKey[$config['pattern_key']] = [];
            }

            $this->readerGroupedByPatternKey[$config['pattern_key']][$key] = $config['reader_instance'];
        }
    }

    /**
     * @param string $patternKey
     * @return FileReaderInterface[]
     */
    public function execute(string $patternKey): array
    {
        if (!isset($this->readerGroupedByPatternKey[$patternKey])) {
            return [];
        }

        return $this->readerGroupedByPatternKey[$patternKey];
    }

and creates pipelines for them

class PipelineInitializer implements InitializationDataFetcherInterface
{
....
    /**
     * @var ApplyFileReaders
     */
    private $applyFileReaders;
 /**
     * configuration => [
     *      <key> => [
     *          [disabled] => bool,
     *          'pattern_key' => string
     *          'reader_instance' => instance of FileReaderInterface
     *      ]
     * ]
     *
     * @param array $configuration
     * @throws LocalizedException
     */
    public function __construct(
        array $configuration = []
    ) {
        foreach ($configuration as $key => $config) {
            if (isset($config['disabled']) && $config['disabled'] === true) {
                continue;
            }

            if (!isset($config['pattern_key'])) {
                throw new LocalizedException(__('"pattern_key" needs to be defined'));
            }

            if (!($config['reader_instance'] instanceof FileReaderInterface)) {
                throw new LocalizedException(
                    __(
                        '%class needs to implement %interface',
                        [
                            'class' => get_class($config['reader_instance']),
                            'interface' => FileReaderInterface::class
                        ]
                    )
                );
            }

            if (!isset($this->readerGroupedByPatternKey[$config['pattern_key']])) {
                $this->readerGroupedByPatternKey[$config['pattern_key']] = [];
            }

            $this->readerGroupedByPatternKey[$config['pattern_key']][$key] = $config['reader_instance'];
        }
    }

    /**
     * @param string $patternKey
     * @return FileReaderInterface[]
     */
    public function execute(string $patternKey): array
    {
        if (!isset($this->readerGroupedByPatternKey[$patternKey])) {
            return [];
        }

        return $this->readerGroupedByPatternKey[$patternKey];
    }
....

Order Update File System Observer CreditMemo

  • The TechDivision_OrderUpdateFileSystemObserverCreditmemo module does the job of observe a creditmemo.

  • The module creates the pipelines for the creditmemo file.

  • The filename of the resulting JSON file must start with creditmemo, and then any character creditmemo*.json under the directory var/pacemaker/import using order-update-file-system-observer-creditmemo

Order Update File System Observer Invoice

  • The TechDivision_OrderUpdateFileSystemObserverInvoice module does the job of observe a creditmemo.

  • The module creates the pipelines for the invoice file.

  • The filename of the resulting JSON file must start with invoice, and then any character invoice*.json under the directory var/pacemaker/import using order-update-file-system-observer-invoice

Order Update File System Observer Shipment

  • The TechDivision_OrderUpdateFileSystemObserverShipment module does the job of observe a creditmemo.

  • The module creates the pipelines for the shipment file.

  • The filename of the resulting JSON file must start with shipment, and then any character shipment*.json under the directory var/pacemaker/import using order-update-file-system-observer-shipment

Order Update File System Observer Cancelation

  • The TechDivision_OrderUpdateFileSystemObserverCancelation module does the job of observe a creditmemo.

  • The module creates the pipelines for the cancelation file.

  • The filename of the resulting JSON file must start with cancelation, and then any character cancelation*.json under the directory var/pacemaker/import using order-update-file-system-observer-cancelation

Order Update CreditMemo

Handles notification and Reads the steps and executes them to create a creditmemo order-update-creditmemo

Order Update Shipment

It processes the notifications, reads the steps, and executes them to create a shipment. order-update-shipment

Order Update cancelation

It processes the notifications, reads the steps, and executes them to create a cancelation order-update-cancelation

Order Update Invoice

It processes the notifications, reads the steps, and executes them to create a Invoice order-update-invoice

In this example, we can see the PROCESS method that executes the step
class InvoiceCreator extends AbstractExecutor
{
......
    /**
     * @param StepInterface $step
     * @return int|void
     * @throws ExecutorException
     */
    public function process(StepInterface $step)
    {
        $notificationId = (string)$step->getArgumentValueByKey('notification_identifier');
        $notification = $this->loadNotification->execute($notificationId);
        $creationDocument = $notification->getDocument();

        if (!($creationDocument instanceof InvoiceCreationInterface)) {
            throw new ExecutorException(
                __('Notification document is not instanceof %1', InvoiceCreationInterface::class)
            );
        }

        $externalId = (string)$step->getArgumentValueByKey('external_order_id');
        $order = $this->resolveExternalId->execute($externalId);
        if (empty($order)) {
            throw new ExecutorException(
                __('Can not resolve order for external id: %1', $externalId)
            );
        }

        $invoice = $this->invoiceCreator->execute($order, $creationDocument);
        $invoice->setIncrementId($creationDocument->getTargetIncrementId());
        $this->invoiceRepository->save($invoice);

        $this->logger->info(
            sprintf(
                'Invoice Increment Id was updated to %s',
                $invoice->getIncrementId()
            )
        );
    }
}
.....