Case Study: Bill of Lading Edit Interface using AngularJS for Logistics Company


Our client is a market leader in oil field logistics and transload services.  They own and manage a nationwide network of transload terminals where they store and move millions of pounds of bulk sand, crude, and other materials to and from trucks, railcars, silos, and other containers.  Their services are a critical element in the energy supply chain in North America.

A silo installation at one of the client’s transload terminals. Product is brought in via rail, and loaded into the silos with a bucket elevator. Trucks drive under the silos to be loaded, before delivering proppant the last mile, to the actual well site.


The client runs transload facilities across the country, with an especially high concentration in the Southwest. At these facilities, they load, unload, and store bulk materials for their customers, primarily frac sand to be used in drilling oil wells. When material is loaded and shipped out from the terminal via truck, the driver is issued a bill of lading. The client manages all of the operations at their terminals with their custom terminal management application, which we helped them build.

A sand truck, waiting to be loaded.

All load actions are tracked in the application, arrival and departure weights for the trucks are captured from the on-site truck scales, and a signature is captured electronically from the driver. The application uses all this data to automatically generate a correct and accurate bill of lading, which is printed out and handed to the driver. A copy is also stored in the cloud as a PDF for later reference.

The bill of lading is automatically generated as a PDF, which can be printed. The driver’s signature is captured electronically and placed on the appropriate section of the document.

The process is highly efficient and allows them to quickly process trucks at their sites, and maintain uniform processes at every location across the company. In fact, the system worked so well that another company approached our client about licensing their system to manage their own terminals. However, the partner company had certain specific feature sets which they required before implementing the system at their own facilities.

The most significant feature request was an easier way to modify bills of lading after the fact, as well as tracking those modifications. The bill of lading contains a large assortment of data about the load: customer, service company, product, tare and gross weights, purchase order number, driver name, signature, etc. One strategy used in the terminal management system to eliminate data entry errors is to provide dedicated screens for different steps in the loading process. These dedicated screens only allow entering the specific data relevant to that step (entering order data, receiving a new truck, loading the truck, collecting the final weight and dispatching the truck), and a series of statuses ensures that only the trucks at a given step can be accessed on that screen.

While this structure is very effective at preventing errors, on the rare occasion that an error did occur, resolving the issue was a bit cumbersome. A user with administrative access would have to manually revert the statuses on the truck to edit the different fields. As the client’s business continued to grow, even a steady low error percentage inevitably grew to a larger administrative task, and for their partner, it was a non-starter. They needed a way to edit all the relevant details about a truck on a single page.


Making a single page form with all the relevant fields for a truck is trivial. However, the system provides numerous checks to make sure that the order matches the customer, the job matches the order, the product matches all these things, and so on. Additionally, the quantity for each draft (load event) needed to total up to match the net weight calculated from the gross and tare, and vice versa. Since every piece of data could be modified, every other piece of data needed to be checked in real-time to make sure things still added up. Additionally, there were a series of dependent select fields (drop-down menus), where the user’s choice in one menu would affect the available options in other menus.

The core terminal management system was built as a web application, running in the cloud, backed by a relational database, with the user interface rendered in the browser with HTML. Additional UI enhancements were implemented using JavaScript. However, the level of interactivity required for this page would have been an overly complex mess to implement. Instead, we opted to use Angular.

Angular is an open-source JavaScript UI framework built by Google and used by a wide range of organizations around the world. Angular allows you to define a scope, a set of JavaScript variables. You can then reference those scope variables in your page template, in functions you write to call on that page, and in event triggers. The variables in the scope are shared around the page, so any time the variable is updated, the references to it are automatically updated as well.

Weights are automatically recalculated based on user input.

We used these capabilities to automatically update the gross tare and net weights based on the total of the drafts, keeping the net weight matched to the sum of the drafts. We built a integration to allow Chosen.JS’s searchable select boxes to interact with Angular scope variables. Any time a value was updated in a drop-down menu (Customer, Order, Job, Product) we could automatically trigger updates elsewhere in the form. When a change in value caused the available options in another select box to be modified, we would pull an updated option list from the API via AJAX.

The entire truck loading process laid out on a single screen for easy editing.

One particularly challenging component was dealing with transient load sources. The system tracks which container is used to load each draft in the truck. That way, if there is a contamination or other quality issue with the material on that truck, the system can easily tell you where it loaded from, in order to locate and mitigate the source of the problem. However, trucks are often loaded directly from railcars, which by their nature are mobile. Every day, empty railcars are removed from the facility, and full ones arrive to replace them. The system provides a list of railcars, silos, and other containers that are available to load from and have the matching product for the truck. However, if you are editing a BOL from a truck that has already left, the current list of load sources may be different from the list at the time that truck was on site. And if you modify the arrival and departure timestamps for the truck, the list of available load sources will change again. We had to extend the load source API so that you could query based on timestamps and lookup which load sources were on-site during that window of time and contained the specific product at that time (because a container might be emptied of one product, and refilled with another). Any change to the truck’s arrival and departure times would trigger another query to this API, causing the list of available load sources to be updated in real-time.

Each draft (load event) is listed, along with quantity, timestamp, and load source (asset). All this data can be edited, and the system will handle the business logic seamlessly.

All of these changes are managed exclusively on the client-side, without modifying the database. Once the user is happy with their changes, they submit the edits to the system. A series of validation checks are run, to make sure the business rules are applied correctly, and the bill of lading is updated in the system. A new PDF is generated and stored in the cloud for future reference.

However, since this modified BOL is different from the document the driver signed, and was handed during dispatch, the modified BOL document does not bear the driver’s digital signature. Instead it contains a note indicating that the BOL has been modified, as well as an attached log, listing all the changes made to the document.

This BOL has been edited, so the driver’s signature is replaced with a note indicating the change.

The system stores the original BOL document, as well as every revised version, with the attached change log. Each version can be downloaded on demand from the application.

All revisions are kept for reference, allowing users to see the entire history of the BOL through each edit.


This project was a huge time saver for the administrative support team tasked with handling these BOL modifications. Changes that were once a considerable headache could be handled in a matter of seconds. Because there were fewer opportunities for error, much of this work was able to be delegated back to the terminal operations team, which dramatically reduced turn around time, since the fix could be made by a manager who was physically on-site, rather than submitted to a queue with a host of other issues to be resolved by the support team, who would previously have to call the terminal and investigate the issue to determine exactly what the correct data would be.

The revision history showing previous versions, and listing the corrections, provided traceability in case of any questions down the road.

Additionally, the same single-page interface also allowed us to implement a “Manual BOL” process. If a facility loses Internet access, they cannot access the terminal management system, since it is hosted in the cloud. However, trucks still need to be loaded and processed. Delaying loads could cause well site operations to stop, which can be extremely costly for our client’s customers, and might even lead to canceled contracts. Thus, if a facility’s Internet access is down, they must revert to a paper BOL form, a copy of which is kept in a file at the terminal. Once Internet access is restored, the paper BOL can be scanned, and the relevant data is entered on the “Manual BOL” screen. This screen is basically the same form as the BOL editing interface, except a new bill of lading is created, rather than modifying an existing one.

Finally, this feature was a non-negotiable requirement for our client’s partner who licensed the system, and implementing this allowed this strategic partnership to move forward. This lead to deploying the client’s custom terminal management system to over 40 locations across the US and Canada, and opening an entirely new revenue stream for the business. It also strengthened the partnership with that client, leading to additional future projects.

Posted in Case Studies and tagged , , , , , , , , , .