Many, years ago (2001) I wrote a small application in Delphi that would allow a user to print thermal labels to a Zebra or Eltron EPL or ZPL language printer. It also supported printing to dotmatrix labels. That shows how long ago it must have been.
the labels were based on information drawn out of Dynamics GP. Thus warehouse bin location, item description etc was pulled through from GP allowing the goods in department to quickly print off labels for goods they were bagging or stocking.
As we have recently added another company to our premesis it is now desireable for the application to automatically detect which company the part number entered belongs to and print a label with the correct layout for that company out. The applicaiton originally written in Delphi is overdue for a rewrite into .NET.
There was no hours available in work time to write this applicaiton so I took it home to write in the evenings. The following posts show you how I got on. I had, as usual forgotten about some of the nice features I had encorporated into the original application.
Part II to follow....
I have been wanting to get to Cedar Point, Ohio for about ten years, I followed the construction of Millennium Force through the snow of winter using the internet, via the Cedar Point Diary found on the Cedar Point website. I call it diary as it was before the term blogs emerged. We finally got over there this summer, we got to take in Canada’s Wonderland in Toronto and Kings Island, Cincinnati on the trip too. As we were travelling with a five year old I was delighted to find out that Cedar Point and Kings Island were both running a Parent Swap scheme. I will explain for those of you making the transition from visiting theme parks without kids and who now find you have small feet following you around the park. These schemes make the difference between an adrenalin filled amazing experience riding all the big rides and getting on a couple or rides and everyone falling out causing the day to prematurely end. The problem visiting the parks is that only the adults can ride the many of the rides due to safety height restrictions. Kids get bored easily and when they do they turn on you, making life a misery. You quickly find that if your young child has to wait outside each ride for forty or more minutes while both the parents go on the ride, the day will plummet quickly. The other important point is that having paid the admittance fee at the gate you want to all get the most out of every hour at the park, there are lots of great rides that they are allowed on that they could be riding while the parents are on rides. In fact Cedar point had three descrete areas for young kids. More...
A few months ago we kept hitting our seventy five concurrent user limit on our GP server. Rather than rushing out to buy some more licences it was time to investigate how it was getting used.
In order to do this a SQL job was set up sample the current concurrent users on the system throughout the working day, logging the results into a SQL server table for later analysis.
I was not too interested at this point in the detail of who and where people were logged in, merely how many, thus a few mins later we have created a table in the BI database, UserConcurentCount that has two columns, UserCount and TimeDate.
The sql job created had one step running every 10 mins that did the following:
/* Insert into the monitot table how many users visiting */
Insert into BI.dbo.UserConcurentCount
(select Count(*) as UserCount, getdate() as SampleTimestamp from dynamics..activity)
This results in a table that can be used to build a histogram using a bit of TSQL and excel of the number of users in the system through the day. The problem seems to be with the changing patterns of work in a small number of the part time staff in some departments causing a pinch point when change over half way though the day occurrs and both sets of staff are in the system. The problem now seems to be resolved and we hover under the user limit now.
Take care to put a clean up script on a weekly job clean old entries out of this log table, no need to build up excessive records unless it is useful to you.
This implementation of Dynamics GP had some new challenges. The company have a trade counter at the front of the warehouse, thus they needed a solution to allow entering of orders, picking and fulfilling them and presenting an invoice to the customer all as the customer waits. As this was trade, customers need invoices to take away with the goods.
The workflow has ended up like this;
- Customer goes to trade counter
- Trade counter staff work with customer to enter the items they require on to an invoice SOP type document in Dynamics GP. There is no need for a sales order as the items will not be back ordered. If this is required the back ordered items can be pushed through to an order.
- Send the invoice to the warehouse batch to allow the warehouse pick printing service to print off the pick list and maintain the integrity of the pick by locking access to the document.
- Staff pick the items for the invoice.
- Goods arrive at the counter, customer agrees it is all they want - customers have an annoying tendency to change their mind or want to add stuff to the invoice.
If they add stuff or change stuff on the order, the invoice is recalled from the warehouse batch, changes made and a new edition of the pick list is printed by submitting it to the warehouse batch again.
- Once everyone is happy, the sales order processing fulfilment module I wrote fulfills the order, recording it is of collect type, defaults the picker, packer and checker names and prints delivery notes, one for the customer to sign the other for the counter records, it also prints invoices as required for the customer to take away.
PDF versions of all the documents invoice, pick lists, despatch notes, as usual are all automatically stored on the document server for later viewing or reprinting or web server serving as required.
Often the telesales team or the website will take orders that are for customer collect, these are dealt with by transferring them to invoice as the customer arrives at the counter, and otherwise the process remains the same.
Order intake statistics
This concept of receiving sales orders in to invoice type documents breaks one of the business rules that our reporting uses for establishing order intake. Previously this analysis was done merely on sales orders. Thus some work on the Business Intelligence was required to work out what constituted a genuine order intake document, indeed line and what was just part of the process document flow. i.e. don't count an invoice created from a sales order as order intake, unless any lines were added to the invoice by editing the invoice after the transfer, in this case they need to be counted. I've avoided having to write this report, frankly that is great as I can get on with some more process improvements.
Quick and smooth picking of goods
This solution seems to be an improvement on the previous ERP system that was in use and I intend to make some more changes to the fulfilment software to improve it further.
Reporting services used to produce invoices via XML web services
I used reporting services, in an attempt to move away from the Crystal that comes with .NET. I had to call the report from a windows service and from the .NET application but as the invoice can be subject to many changes during the early days while things are settling in, I chose to use a reporting services server to print the invoices. This ensures that any changes to the report end up reflected on both the invoices produced automatically from the fulfilment software and those produced in batches for other orders where the invoices are posted. I used the web services API to invoke printing of the report. More about that in the next blog post. The speed of invoice printing is not quite what I would like at the moment by using this method, but we have not looked at all at optomising the server or code yet so I am confident improvements will soon follow.