Pacemaker Dynamics BC Entity Export - Order Notification

Since order notification is not part of Dynamics BC’s standard REST-API, every installation will have specific needs in terms of data structure, field labels and required values. Yet, the task of notifying about a new order having been placed remains the same for all installations (if the installation has this need).

The package techdivision/pacemaker-dynamics-bc-entity-export-order-notification, based on the package techdivision/pacemaker-entity-export-order, provides a standardized workflow for notifying Dynamic BC about new orders, letting the developers focus on implementing the data objects that are needed to match the project’s needs.

Configuration

See page Configuration.

Requirements

Transformation

Prior to sending an order notification to Dynamics BC, the notification payload must be created for an existing order. Since your project specific endpoint will have its specific requirements (in terms of the data and structure it has to deliver), this module provides the interfaces \TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\OrderNotificationTransformerInterface and \TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\Data\OrderNotificationPayloadInterface which must be implemented in your project.

  1. \TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\OrderNotificationTransformerInterface The implementation of this interface is responsible for transforming an order into an order notification payload. A project has to provide an implementation of this interface and set it as the preferred implementation via di.xml.

  2. \TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\Data\OrderNotificationPayloadInterface Since every Dynamics BC installation define their own structure for order notifications, a project specific extension of this interface should be created (our interface here just provides the special type and is the anchor point for a factory but does not provide any special accessors / mutators). A preferred implementation of this interface must then be registered in your module’s di.xml.

Example

  1. Extend the specialized payload interface for the sake of type strictness:

    declare(strict_types=1);
    
    namespace MyVendor\MyModule\Api\Data;
    
    interface OrderNotificationPayloadInterface
        extends \TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\Data\OrderNotificationPayloadInterface (1)
    {
        (2)
        public function getOrderId(): ?int;
        public function setOrderId(int $orderId): self;
        public function getIncrementId(): ?string;
        public function setIncrementId(string $incrementId): self;
    }
    1 Extend the interface in order to fulfill the contract
    2 Add your own accessors and mutators to match your requirements
  2. Implement the project specific payload:

    declare(strict_types=1);
    
    namespace MyVendor\MyModule\Model\Data;
    
    use MyVendor\MyModule\Api\Data\OrderNotificationPayloadInterface;
    
    class OrderNotificationPayload implements OrderNotificationPayloadInterface
    {
       private const KEY_ORDER_ID     = 'order_id';
       private const KEY_INCREMENT_ID = 'order_no';
    
       private array $data = [];
    
       public function getOrderId(): ?int
       {
           return $this->data[self::KEY_ORDER_ID] ?? null;
       }
    
       public function setOrderId(int $orderId): OrderNotificationPayloadInterface
       {
           $this->data[self::KEY_ORDER_ID] = $orderId;
           return $this;
       }
    
       public function getIncrementId(): ?string
       {
           return $this->data[self::KEY_INCREMENT_ID] ?? null;
       }
    
       public function setIncrementId(string $incrementId): self
       {
           $this->data[self::KEY_INCREMENT_ID] = $orderId;
           return $this;
       }
    
       public function deserialize(array $payload): void
       {
           $this->data = [];
    
           if (isset($payload[self::KEY_ORDER_ID])) {
               $this->setOrderId($payload[self::KEY_ORDER_ID]);
           }
    
           if (isset($payload[self::KEY_INCREMENT_ID])) {
               $this->setIncrementId($payload[self::KEY_INCREMENT_ID]);
           }
       }
    
       public function serialize(): array
       {
           return array_filter(
               $this->data,
               static fn($value) => $value !== null
           );
       }
    }
  3. Register your implementation as the preferred payload in app/code/MyVendor/MyModule/etc/di.xml:

          <preference for="TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\Data\OrderNotificationPayloadInterface"
                      type="MyVendor\MyModule\Model\Data\OrderNotificationPayload"/>
  4. Implement the transformer interface:

    declare(strict_types=1);
    
    namespace MyVendor\MyModule\Model;
    
    use Magento\Sales\Api\Data\OrderInterface;
    use MyVendor\MyModule\Api\Data\OrderNotificationPayloadInterfaceFactory;
    use TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\Data\OrderNotificationPayloadInterface;
    use TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\OrderNotificationTransformerInterface;
    
    class OrderNotificationTransformer implements OrderNotificationTransformerInterface
    {
       private OrderNotificationPayloadInterfaceFactory $payloadFactory;
    
       public function __construct(OrderNotificationPayloadInterfaceFactory $payloadFactory)
       {
           $this->payloadFactory = $payloadFactory;
       }
    
       public function getPayload(OrderInterface $order) : OrderNotificationPayloadInterface
       {
           $payload = $this->payloadFactory->create();
    
           return $payload
               ->setOrderId($order->getEntityId())
               ->setIncrementId($order->getIncrementId());
       }
    }
  5. Register a preference for the transformer in app/code/MyVendor/MyModule/etc/di.xml:

          <preference for="TechDivision\PacemakerDynamicsBcEntityExportOrderNotification\Api\OrderNotificationTransformerInterface"
                            type="MyVendor\MyModule\Model\OrderNotificationTransformer"/>

Extension points

See page Extend.

Runtime view

Order notification flow

Order notification flow