Talk:Delivery Policy

From ADempiere
Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.

Comments on Delivery Policy

Please enter arguments for or against inclusion of this feature enhancement in the 3.70 release.

Rational for the Enhancement

Currently Adempiere ships outbound orders as soon as they fulfill the delivery rule criteria of the order, not considering if there are other earlier but not fulfilled orders that should have had the items shipped if the order was fulfilled. This means that orders can be starved.

This rules that make up this behaviour in Adempiere is called Delivery Policy.

This article describes the technical aspects of Delivery Policy. To read how to set up and use Delivery policy see Delivery Policy.

The Delivery Policy implementation was first committed with revision 12757 (after release of 360LTS), Feature request 3004020

No hold

The current Delivery Policy I choose to call "No Hold" meaning that no items are held for a specific customer and orders are shipped as soon as they are fulfilled. This means that some orders might never be fulfilled and the risk of starvation increases the bigger the more items there are on the order.

Strict order

The Delivery Policy "Strict order" means that material must be allocated to the order before it is shipped. Only material on hand can be allocated. Material is allocated in the order defined by the orders which are:

  • Priority of the order
  • Date of the order line (ie when it was created)


Quantity allocated

In Compiere's version of their WMS they have added the following field to order line and storage:

  • QtyAllocated

QtyAllocated represents the number of physically available items (On Hand) that have been allocated to a specific order. The sum of QtyAllocated for all locators of a given product can never be more than what is physically on hand.

This is in contrast to the value "QtyReserved" which is the sum of all orders for a specific product that hasn't yet been delivered. If there's not enough in stock QtyReserved is more than what's in stock.

In this solution we add the field QtyAllocated to COrderLine and MStorage just as they have done in Compiere.

Allocation process

The allocation process would be a process that is run whenever the allocation of a product is changed. The allocation process will only run if Delivery Policy is "Strict order". Allocation process is run at the following points in time:

  • Order complete / voided
  • Receipt complete / voided
  • Inventory adjustment complete / voided

The process can be run either on just the products affected or in general (allocate all). Normally "allocate all" would only be required when switching Delivery Policy.

Allocation is done according to:

  • Order priority
  • Order (line)date

Delivery Policy

Delivery policy should be a setting on Client and Organizational level. The organizational level will override the client setting.

Shipment process

If delivery policy is "No hold", Adempiere will work as it always has (backwards compatible).

If delivery policy is set to "Strict order" only orders that have items allocated will be shipped and no more than what's allocated will be shipped. The allocation only applies to physical items that are stocked.

Use cases

This new functionality will have impact on the following scenarios:

Reserve stock

Reserve stock happens when the order is prepared. An order can always reserve stock whether or not there's enough material on hand. Allocating can only happen when there's enough material on hand. One option (which I will go for in this stage) is to not allocate stock at this point. If material is allocated at this point, it must also be unallocated if the order is cancelled.

Delete order line

If an order line is reserved (and possible allocated), the reservation and allocation must be cleared.

Increase quantity on order

If the quantity is increased, the allocation must be increased with the difference. This is no problem since it is covered by the regular allocation process.

Decrease quantity on order

This is not detected by the regular allocation process. It is also desireable to "release" the allocation as quick as possible so this should be done as soon as the order is prepared or completed. Release of allocation is done in the MOrder.reserveStock method.

Allocate Sales Orders

This is a process that considers all completed sales orders and allocates products on hand in a defined order. Highest priority and oldest orders gets allocated first. The reason why allocation is not done at the complete order step is that the complete order step only considers the order at hand at the moment. One possible solution could be that if there's no shortage of products, allocation will happen when the order is completed. So allocation could happen in these scenarios:

  • Start of allocation process.
  • When an order is completed (if there's no shortage of stock).
  • When a material receipt is completed.

Generate shipments

When shipments are generated, they will be generated based on what is allocated. I've put some effort into the view m_inout_candidate_v to make sure only true inout candidates show up on the list.

The inout candidate view now considers:

  • Delivery Rule of the order
  • Delivery Policy

Customer Shipment

When a shipment is shipped the number of allocated items in stock must decrease with the same amount that is delivered. If not, we'll have more allocated items than what is in stock.

File to modify: MInOut

Storage Cleanup

There's a process called StorageCleanup. It creates movement transactions for unbalanced inventory, ie to fill upp locations with negative on hand quantity. The best would be if we can prevent negative on hand quantity. This process doesn't work in 3.5.4a. When run it only creates empty move lines.

Files affected

org.adempiere.model.I_AD_ClientInfo - property DeliveryPolicy
org.adempiere.model.I_AD_OrgInfo - property DeliveryPolicy
org.adempiere.model.I_C_OrderLine - property QtyAllocated
org.adempiere.model.I_M_Storage - property QtyAllocated
org.adempiere.model.MInOut - update QtyAllocated on order when shipments completed
org.adempiere.model.MInventory - Adjust for change in MStorage.add
org.adempiere.model.MMovement - Adjust for change in MStorage.add
org.adempiere.model.MOrder - Adjust for change in MStorage.add (reserveStock)
org.adempiere.model.MOrderLine - new method allocateOnHand(toAllocate)
org.adempiere.model.MOrgInfo - property DeliveryPolicy
org.adempiere.model.MProjectIssue - Adjust for change in MStorage.add
org.adempiere.model.MStorage - property QtyAllocated / change in function add
org.adempiere.model.X_AD_ClientInfo - property DeliveryPolicy
org.adempiere.model.X_AD_OrgInfo - property DeliveryPolicy
org.adempiere.model.MClientInfo - added constants
org.adempiere.model.X_C_OrderLine - property QtyAllocated
org.adempiere.model.X_M_Storage - property QtyAllocated
org.adempiere.validator.MaterialReceiptModelValidator - Allocate at receipt
org.compiere.process.InOutGenerate - Consider delivery policy
org.compiere.process.M_Production_Run - Adjust for change in MStorage.add
org.compiere.process.StorageCleanup - Cleanup allocations
org.eevolution.model.MDDOrder - Adjust for change in MStorage.add
org.compiere.apps.form.Match - Adjust for change in MStorage.add

24 files.

Database objects affected

  • view m_product_stock_v
  • function isshippable(product_id numeric)
  • function get_delivery_policy(warehose_id numeric)
  • function is_inout_candidate_orderline
  • function is_inout_candidate_order
  • function get_allocated_on_order
  • view m_inout_candidate_v

Known issues

Delivery policy doesn't yet handle BOM:s.

Other solutions

There are other solutions developed to this problem.


Lieferdisposition is a solution developed by Metas. It's developed as a module that can be integrated with a standard Adempiere release. It replaces the current shipment generator with Metas shipment generator.

This solution don't work if you use shipment confirmations.

Libero Warehouse Management

Libero Warehouse Management supports delivery policy according to the documentation:

Libero Warehouse Management, Outbound Operation

If all you want is to make sure customer's orders are not starved (delivery policy = Strict order), the Libero WMS might be overkill.

See also