When purchasing direct parts, materials move very quickly. In such an environment, it may be desirable to order in standard packs to meet or exceed the maximum stock defined for replenishment of an item. With slower moving items, this is not necessarily the case. While it is important to order a standard pack to optimize value, ordering an extra package to get at or above maximum quantity can be very, very bad when inventory may sit for weeks or months on end.
My employer manages indirect materials (and the MRO storeroom) as a service to other companies. These materials, by nature, tend to move in low volumes. To put focus on the issue, assume an item has a reorder point of 4 and a maximum qty of 10 with a standard pack (Vendor Lot Size) of 6. This means that the plan to replenish the storeroom optimally puts stock back to 10 when on hand reaches 4. Acumatica’s standard approach caught me by surprise when inventory fell to 3 before replenishment was prepared. When reaching an on hand of 3 before preparing replenishment, Acumatica drives replenishment to reach the maximum quantity. It also takes into account the standard package size for the supplier and forces ordering full standard packs to ensure maximum qty is met. In this case, instead of increasing inventory to 9 and falling short of the maximum of 10, Acumatica drives purchasing TWO standard packs, thus pushing inventory to 15… an excess of 5.
Before addressing how we can limit the order multiple of standard pack to stay at or below maximum, or at least only order 1 standard pack even if that pushes above maximum qty, let’s take a look at the method that causes this behavior in standard Acumatica.
Now for the override in a graph extension to replace the standard functionality. Keep in mind that if your requirements are to switch back and forth between which way this is calculated, just call the delegate to run and return from the original method when necessary.
Look for the commented out use of decimal.Ceiling that was replaced by Decimal.Truncate. Ceiling performs the math and rounds up if there is a fraction left over. Truncate drops the fraction entirely. Since it is possible to configure the item such that you would never order a full standard pack (for instance: on hand = 4 and max = 10, but standard pack is 12) then we need to ensure we come out to AT LEAST one standard pack. A little housekeeping… the Base graph defines FetchVendorSettings as private, so we need to copy it to our graph extension because it is not accessible from outside the Base graph, even with inheritance. This means both methods must be monitored during upgrades going forward, but the result lets you order at least 1 standard pack but otherwise not exceed maximum qty in replenishment.
I hope you find this interesting and useful.