The Field, Part I
Published
I told you about what was happening in the “room”: The customer calls were received, D-guy announced them to the drivers in the field via wireless. I also told you how the applications I developed shaped this pipe. We are now at the part where actual pick up and delivery happens, on the streets, by the drivers who we all owe our pleasure of sending and receiving our packages.
The code
It is the year 2004. The database backend is Microsoft SQL Server, as was the whole company. The code on handhelds, Symbol PDT8056 I developed in C#, Compact Framework. Everything else, including the SOAP webservices and monitoring applications are in Delphi, as usual. Now you have the lay of the land.
I still have the code. It is not a screenshot or a listing somebody kept, the whole backup: one thousand six hundred twenty-nine files, one hundred eighty-six megabytes. Almost all of it is payload, installers and libraries and the runtime of the era. The application itself is a few hundred kilobytes of text. It fits in an email today. In 2004 it ran the Turkish operation of a multinational cargo company’s courier fleet. Many good things come in really small packages, pun fully intended.
The first version I found in the folders was an empty form for a “solution” named SDA1. It is what the New Solution wizard creates: one window and nothing behind it.
SDA2 was just a few UI elements on the main application page and a test of downloading some application parameters from a SOAP endpoint. It was very thin and only one version survives on disk. Looks like I was using the SDA2 generation as a true test development base.
The third version, SDA3 was a real program, a single Main.cs of 119 kilobytes with the dispatch work beginning to appear in it. Then the build dated April 21, 2004, Main.cs at 202 kilobytes and nine forms: Login, Teslimat (delivery), CagriWaybill (call waybill, the part that actually carried the barcode of the package),
CagriIptal (cancel), EC (exception, event that happened to that call), Soru (question, a generic “Yes/No” dialog), UzunBilgi (message, in the long form), ErrorLogging, and the web-service proxy.
It was thirteen releases later and on March 18, 2005, Main.cs grew to 288.6 kilobytes and fifteen modules. I remember being the sole developer, an emulator in my development desktop and a physical device on my desk. There were a couple of people “in the team” helping me gather feedback from the field, drivers used as test subjects.
The names of those forms are the job description.
Login records where the driver starts his day: the city and the branch he is going out to the field, the region he will be responsible that day, and asks him to confirm it if it changes. That way a driver can pickup any device and go out to any region. I remember this flexibility but it is not very appreciated by the drivers. Each driver felt “attached” to a particular device because he used it in a certain way, cleaned the screen and keys, was careful not to damage it.
Teslimat is the delivery record, and its fields tell you what a delivery was at that date and more: name, surname, phone of the consignee. If it is a freight collect (paid by the receiver) delivery, the driver created an invoice and handed it, if it is a customer with an account, a credit line. If not, money is collected and a receipt is produced. All these documents are recorded by their serial numbers.
CagriWaybill scans a dispatch call against a waybill or a tracking number (a barcode) so the two can be proven to belong together. All around Turkey, anybody querying that barcode number would see who delivered it when to whom.
CagriTransfer moves a call from one driver to another. The driver can reject a call and return it to D-guy, if it is assigned to him by mistake. If he knows whose responsibility it is (the region) he can directly transfer to that driver, himself.
EC is the exception code. Many things can happen and a pickup or delivery cannot be completed. For pickup, maybe the package is not ready yet. For a prepaid package, the customer may not have enough money to pay the cost. Driver may be late to the customer and maybe the company is closed for the day. For a delivery, same money problem if it is freight collect. The consignee may flatly refuse the delivery because of a change in his own contract with the sender. All these cases had 2 character codes called Exception Codes. It can be recorded with the tracking number so customer support can deal with it.
Soru is the generic dialog that asks the driver whether he is sure or not with an operation. There was also ErrorLogging, doing exactly what it sounds like.
The app downloads all data that it needs to run from the backend. That happens when the driver was still in the branch and connected to the local wifi network. The sync list is 14 items long: calls, messages, the active list, regions, exception codes, proximity codes, deliveries, parameters, branches, cities, zones, prices, price parameters, error logs. Fourteen, on a device that had no signal half the time. The design assumption is written in that list. The terminal can work offline and the network is a bonus.
All this connects to three web services.
The main one carries twenty-eight methods: four login variants, each with a security token and two device identifiers. Four numbered revisions of the parameter download, because a fleet cannot be updated by hand. A call to GetSistemZamani (GetSystemTime) during login hands the server’s clock to the device so that every timestamp in the field comes from the center. DoErrorLogKaydet (DoErrorLogRecord) which sends an error back carrying the terminal, the driver ID, the application version, the function and the sub-function and the dispatch call lifecycle end to end.
The second service handles device configuration. The third is the update agent. The client is C#, the payloads are SOAP, and the year is 2004.
There is a second program on the office side, written in Delphi, whose job was to watch the fleet. It has no socket, no host and no URL anywhere in its forty-three files. It watched the fleet by reading the rows the devices themselves had written. One column is called Son Login, (Last Login) and it goes red when a terminal has not reported that day. That was the whole monitoring story. The office looked at what the terminals had written down about themselves.
I see every versioned build folder carries a todo.txt, in Turkish. Eleven of them survive, from April 2004 to March 2005, and they are the most human thing in the backup. They chronicle the work I was on, probably based on feedback from the field. This is around the same time Linus Torvalds was “inventing” git and probably years before Github began operating. A running ledger of things to do and completed was all I had back then. I even see some marked with ”?”. Was I not sure if implementing it a good idea? Did I think it is not possible, in some fashion, maybe from a resource point of view? I really do not know. There are ones that surely came as ideas from the field: capture the signature at delivery, write the logged errors to the center, make all data flow courier-specific through the region, force the program to close at night if it did not close itself, ask the courier the branch and confirm it. I think the last one is a scar: Somebody’s terminal was pointed at the wrong branch. This was not a feature request.
Strangely, one item in that list is there in all versions across two years: capture the signature at delivery. There is no signature code in any of the seventeen builds. Not in Teslimat.cs, which is a text form with a name and a surname in it, and not anywhere else. The string imza appears in no source file in the backup at all. I cannot see it closed, I am disturbed by it and I am not going to invent the last status. I remember the device had a plastic, yellow stylus. The idea was physically feasible, at least.
Some tidbits from rest:
The sync bar is not a spinner. It works out its own denominator when the sync starts, seven fixed data types plus one for every price-list service, and then advances one step as each item lands. A sliver 32 pixels by 14 in the bottom corner, glanced at between taps, next to the clock the device takes from the server. Honest percentages over GPRS, in 2004. Not a guess, not a timer based incremental bar, waiting at 95% when the bar is almost done but the task it is showing progress is not.
Four buttons carry an asterisk in their labels: mark the visit, transfer the call, send the message, mark the message read. The asterisk means you need to be online for this one. It came with an oral rule that is in no document: do not press these in an elevator or inside a building. The drivers learned where connections go to die, and the labels told them which taps cost a connection.
The exception form has a proof field, “Kanıt” in Turkish, sixty-four characters. When a driver reports that nobody was home, he types something only somebody standing at that door could know. The electricity or gas registration number printed (usually a small plaque) on the meter or near the entrance. For a business, the landmarks: “two shops to the left, there is a McDonald’s”. Those devices had no GPS. The gas meter was the GPS.
The money side is the part I like most. The driver hand-writes the invoice for a prepaid shipment and the money receipt for freight collect, from pre-printed pads in his satchel and inputs into the application. The application prints nothing. Its job is memory: which document number was spent on which waybill. FaturaNo, MakbuzNo, BelgeTipi, BelgeNo (Invoice Number, Receipt Number, Document Type, Document Number, read all these “number”s as ID numbers), sent up with the delivery. The driver was a mobile cashier writing on paper, and the handheld was the ledger that made his handwriting reconcilable.
That is the code. What the drivers did with it is the next part.