Recursion Therapy

Recursion Therapy

Every company needs a wannabe programmer in a non-engineering role to help bridge the gap between available software offerings and company needs. I’ve been lucky enough to fill that role at Uplogix for a while now, and most of that time has been spent fighting the “cloud-based business software CRM” behemoth known as Netsuite. In fact, almost every app I’ve written has come from a Netsuite shortcoming, from tracking customer information to managing RMAs and so on. Recently, we tried to use Netsuite to compile an order history for a customer. Long story short, I had to write some code.

Uplogix builds the most advanced console servers on the every planet that we know of, but hardware is hardware, and even the most robust SSD can fail given enough time. Because of the way we provide maintenance, it’s vital that we track what serial numbers have been purchased and, in the event of a hardware failure, have been replaced. This has always been a manual process, one that involved combing through every sales order and copying the relevant data in an Excel spreadsheet. At least, that’s how sales people have done it for years.

When I was tasked to do an order history, my reaction was yeah, no, I don’t want to do all that work. Now, when some managers hear that response, they think they’ve got a crappy employee on their hands, but I’m a firm believer that if a process can be automated, then it should be. Automated processes increase efficiency, reduce mistakes, and make sure all necessary data is collected. As the amount of data you’re managing grows, you’re gonna want that accuracy.

The Problem

As I saw it, the biggest problem with order histories is chasing down RMAs. Customer orders an Uplogix Local Manager with a serial number of 1234. Years later, they replace it with SN#5678. Thing is, the original order and the replacement data live in separate apps. So, for each original serial number ordered, someone would have to determine whether it has been replaced. And because we have such a lenient return policy (seriously, just say it was weird one time for like a second and we’ll send you a new one), there might be multiple RMAs for a single site. We could send a few boxes before figuring out it was a power issue at the site, or maybe the site is prone to lightning.

Either way, for each serial number, there is potentially an RMA train that needs to be followed to the end, because that final serial number is the one the customer should have.

The Solution

If you take RMAs out of the equation, a customer will never have more Local Managers than they originally purchased. Starting from there, the “order history” side of the equation should just be all of the original purchases, or anything that is a straight-up sale and not and RMA. (Funnily, original purchases and RMAs both create sales orders, which is confusing.)

So, all of the customer’s original purchases are put into the app. From there, the app is going to look into the RMA database and follow the RMA train to the very end for each of the original purchases. It will do this dynamically, every time the page is loaded, and when new RMAs are processed, the end result is updated automatically.

The Code

This project was fun because I got to write a recursive function. It had been a while, so it took a few attempts to visualize it. Recursion is weird; I don’t know how people see it so clearly. Anyway, here is the code I came up with:

function getLastSerial($serial = 0, $so = 0) {

   if(hasReplacement($serial,$so)) {

      $replacement = getReplacement($serial,$so);
      return getLastSerial($replacement['r_serial'],$replacement['so']);
   } else {

	$result['serial'] = $serial;
	$result['so'] = $so;

	return $result;

There is still a lot to clean up here, but the function works for now. You feed it a serial number and a sales order number. It uses that info to look up whether that serial number has been replaced. If yes, it gets the replacement’s serial number and sales order number and feeds it back into itself until finally, there are no more replacements, and it spits out the last checked serial and sales order number.

Once that was written, it was just a matter of pulling all of the original purchases and then stepping through each serial to check for replacements.

In Closing

If work were fun they’d call it fun, right? The last thing I want to do on a Monday morning is comb through Netsuite (where pages load in a snappy 3-12 seconds!) and create an order history and chase replacements. But write code to do it automatically? That’s what I love.

This project did require adding original sales order numbers and outgoing serial numbers to our RMA Tracker app, which we hadn’t been collecting for the last twelve years. Luckily, I had a team of people who could do data entry while watching YouTube and doing crossword puzzles.

Going forward, they will add this extra information to all RMAs, and I’ll update the app with new sales orders, and this final list of serial numbers a customer owns will essentially update itself.

Seriously, I live for this kind of stuff.

Nothing makes me feel better than sparing myself tedious work that we shouldn’t even have to do. Yeah, I’m looking at you, Netsuite.

Add comment

Leave a Reply

My Books

Latest Notes

Affiliate Disclaimer

When you buy through product links on this site, I may earn an affiliate commission. It’s not likely, but it could happen.

%d bloggers like this: