On my last post, I found BC had no option to split pickings by Special Equipment Code. Also found there was no option to split the pickings by Zone when creating the picking directly from the Warehouse Shipment. So I decided to create an extension and share it with you here.
Let me explain you the steps I followed to create it.
What changes were done?
I started adding a new field on the Location table.
This field will allow the user to have separate configurations for each Location. It is based on an Enum than can be found on a separate file:
Finally, the new field has been added to the Location Card:
The next step was to locate where the split by zone or bin happens on the base Create Pick codeunit to find what subscription events could be handled by my extension.
All seems to happen on the CreateWhseDocument procedure. This procedure is something so well done… a good example of how to create an interation that groups records without using any key.
The procedure receives a temporary record with all the warehouse activity lines (picking lines) to be created and it goes into an infinite loop which does not end until all lines have been placed under a picking header.
The next picture shows the most important parts of this procedure:
The code marked with number 1 is what is supposed to happen if we do not add any changes to the Base solution. On the other hand, the code marked with number 2 is what is going to be executed if we put our hands on it adding an extension.
So, the main point here is to set the CreateNewHeader and IsHandled variables to our choice with this meaning:
- IsHandled: Hey BC! I know what to do here! Let me decide how to split these lines.
- CreateNewHeader: When is True it will create a new picking header and add the current line into it. However, when it is False, it will add the current line into the existing header.
Also, it is important to note how it controls what was the last Zone, Bin, Location, etc. So, if I want to split by equipment code, I will need to do something like what it is done by zone. That needs to be under the OnCreateWhseDocumentOnAfterSaveOldValues event.
Once I have a clear idea of what the base method does, I start adding subscribers into a new codeunit:
OnCreateWhseDocumentOnAfterSetFiltersBeforeLoop:
This subscriber is called before the code gets into the loop. I use this method to check if the Location was configured to use this functionality and check there is no incompatibility like running the picking creation by zone while the location has been setup to use the split by special equipment. At the end of it, the method makes the filter by zone code or special equipment code if necessary, so each loop will take only lines with same zone or special equipment.
OnCreateWhseDocumentOnBeforeCreateDocAndLine:
This method returns the IsHandled and CreateNewHeader to the base codeunit, so it contains the logic to decide if my code handles the line split and, in case it handles this, it decides when to create a new header. Basically, it creates a new header every time the zone or the special equipment code changes compared to the last line.
OnCreateWhseDocumentOnAfterSaveOldValues:
This method makes a very basic task, but it is important: It saves what is the Special Equipment Code and the Zone Code used on the current line. These are the global variables tested on the last function to know if any of these fields have changed.
OnCreateWhseDocumentOnAfterSetFiltersAfterLoop:
This last method just removes the 2 filters I applied on the first method. After removing these filters, the base code will check if there are still lines to be processed and will keep the thread on the “infinite” loop if there are still lines to process.
Why SingleInstance?
As you can see, all these methods share global variables that are declared into the codeunit. In order get the value set by one method from another method, I had to declare this codeunit as SingleInstance. From the performance point of view this is not ideal, because this codeunit will remain into the user session memory until the session is closed. However, in this case, the amount of information it contains is low and any other solution would have a higher impact into the database.
Let’s do some tests
The first we are going to check is the Location card. Here, we can find the new field “Split Shipment Pickings by”. For this first test, we are going to set it up to split by special equipment. It is important to make sure the standard field “Special Equipment” is setup as something different than empty:
After that, I’ll change the Special Equipment Code on some items:
Item | Special Equipment Code |
1160 (Tire) | HT2 |
1170 (Tube) | HT1 |
1200 (Back Wheel) | LIFT |
1250 (Back Hub) | HT2 |
Once I’ve made these changes to each item and after doing some positive adjustments to ensure we have some units of each on the WHITE warehouse, I create an order and placed it into a warehouse shipment:
So, not it’s time to create picking and see how those lines with same special equipment goes together into the same picking while the other items were placed each on separate pickings.
Now, let’s delete these pickings and start over from the pick worksheet:
In this case, we have an standard option to split pickings by Zone. If you remember, we had a control to prevent split by zone when the split by special equipment was setup. So here is the result of it:
In order to test the next scenario, I created a new Zone Z99 and moved items 1170 and 1250 into this zone. Also, changed the location setup to default split by zone:
The result shows how these 2 products goes together into the same picking since they are going to be picked from the same zone:
The only difference is that this now happens by default without need to use the pick worksheet.
Do you want this?
Please, enjoy.