Orders & Inventory DDD - Where should allocation/reservation be handled?

Viewed 1900

I am trying to refactor a legacy order handling and stock system with into a cleaner service oriented event-driven architecture. However, I am having some difficulty deciding what service should be responsible for the reservation/allocation of stock.

A brief overview of the current system

  1. Sales orders are placed with us via third party system but we do not necessarily have all order lines in stock.

    • If an order item is in stock then we allocate/reserve the stock for that order straight away.
    • However, if we do not have enough stock then we procure the stock from our suppliers via a purchasing system.
  2. When the item arrives from the supplier, the system will search through all open sales orders for the item and reserve/allocate the available stock to them, prioritising by sales order date. ***

I have already identified two services that I think need to be developed

  • Sales - Responsible for receiving the sales order and inserting into the database. Has domain entities such as Order, OrderLine etc.

  • Inventory - Responsible for keeping track of how much stock is available in our warehouse. Has domain entities such as StockItem.

However, as the allocation/reservation of stock concerns both inventory and sales I am not sure where the behaviour in point 2 above should be put.

I welcome any help or thoughts on this.

4 Answers

I think you have 2 BCs (bounded contexts): Inventory and Sales. For the integration between them I would probably go for domain events approach.

When a new item arrives at the warehouse, the Inventory BC increments the stock for the item, and publish an event.

Sales BC subscribes to the event, and it updates the opened sales that are waiting for the stock item.

So, behaviour of "point 2" are shared by both BC:

  • Sales BC search for opened orders waiting for that item. And then it asks Inventory BC to get the number of items it needs (this request is synchronous) and close the order.

  • Inventory BC receives the request and decrements the stock for the item.

However, as the allocation/reservation of stock concerns both inventory and sales I am not sure where the behaviour in point 2 above should be put.

I've been thinking about this problem (purely academically), and my current conclusion is that reservation management belongs with the inventory system. That keeps the stock source (the loading of items procured from your suppliers) and the stock sink (fulfillment of orders) together.

So the inventory system caches its own copy of the data required to fill the order (allowing it to work autonomously). It should be able to make progress as soon as it is informed that the suppliers have provided new inventory, even if the sales system happens to be down for maintenance.

You mentioned SOA and NServiceBus, so my initial thought was that you've attended Udi Dahan his ADSD training? I'll assume you have. With that, I'll try to answer your question.

So far I don't have a lot of information. But with what we have, I figured we need these properties to store all that you mentioned.

  • ProductId, one for each available product
  • InventoryTotal, attached to a ProductId. This number goes up and down
  • OrderId, to create an order
  • OrderDate, to make sure we can find the order that should receive incoming stock first.

If you have an OrderId, you can attach one or more ProductId to create an actual order. Different ways of storing this technically. Maybe in a relational database with Order and OrderLine tables, or possibly in a DocumentDb where everything is stored in a single document. That's totally irrelevant at this point.

Assuming we need 4 attributes, I'm not sure why we would create more than 1 service to split this up? This might change when we have more information, but at this moment I don't see the need.

If you want to discuss this, contact us at support@particular.net, mention my name and we can continue the conversation.

You are talking about loosely coupled domain apps, managing your sales orders, managing your inventory and managing your purchase orders. Inventory must always be up to date, in order to not sell what you can't deliver. So PO en SO app should both talk to inventory via synchronous (inventory) services. To keep everything consistent, events on purchasing side, like receiving less than you expected for a PO, will have an impact on any SO already assigning quantity of that PO, as persisted in inventory. So the same PO pcs for example, in which the event of receiving less as expected, is registered, should synchronously update inventory, to update the quantity available for SOs to assign from, and publish an event, to be picked up, asynchronously, in the So app, so that the user can be notified and talk relevant action. Etc.

Related