Automating my way to a king’s feast
This history starts with my friend Carlos. He’s an accountant and owns an accounting firm. Through is company, from time to time, something curious happens…
Every story has a beginning
A while ago, one of Carlo’s clients needed to sell his entire stock so he could close his business. He could not be bothered to make the invoice because he needed to add more than 3200 products to invoice. If each product takes 5 seconds to insert, then the entire stock would take 16000 seconds (almost 5hours) but I believe it would be more that that. I can’t think of anyone who would be excited to do this job, do you?
During a conversation with his client, Carlos did what any smart person would do to seize the opportunity: he told him that he knew someone who could create the invoice and it would cost 1000 euros. After thinking about it, his client agreed and since Carlos had bluffed, he now had to create a lovely invoice to create by hand.
I’m sure by now, someone reading this might be thinking: I know an app that could do that or at least speed p the process. I’m sure you do, but since this happened in Portugal, where any invoicing needs to be done with a software certified by the government, there aren’t that many alternatives…
For a while, during my time at the university, I lived with Carlos. We eventually went our separate ways but kept in touch through Whatsapp with a group chat with him, me and another friend who also lived with us. We usually talk about life, the universe, and pretty much everything else and so, two or three weeks ago, Carlos started talking about a certain invoice he needed to create with 3200 products. He had been postponing because he was not really excited by the work ahead.
During the conversation, I started to ask a couple of questions. Is started mostly out of curiosity, but eventually switched to check if I could help him in any way. I could but only because he got lucky for a couple of reasons... Firstly, Moloni, the invoicing software he was going to use to create the invoice was an online software and had an API (a way for the developers to communicate with the invoicing software without doing stuff by hand). Secondly, Moloni had a bulk import: to import all the products to the platform, all you had to do was upload a CSV with the information.
With everything looking good, I started to spend a couple of hours after work to write a script to do the job.
Like any good story, this one did not go well, at least not the first time…
On the first try, Carlos bulk imported all the products into Moloni and added them all to the same category. Meanwhile, I coded the script to create a new invoice with all the products from the inventory he just uploaded. Sadly, a mistake had slipped through while importing the prices of the products and so the total of the invoice was wrong… The first day ended with a loss, which gave Carlos some time to fix the prices for the following day.
After fixing the problem with the prices from the previous day, Carlos re-imported all the products into the platform. Sadly, the functionality to bulk attribute a category to all the products had disappeared (to this day, we have no idea why). This meant that he had to manually set the category for 3200 products or that I had to use the API to do the same.
I went ahead and added a bit more to the script. By now, the script could change the category of all the products, one by one, making a total of 3200 requests to Moloni to complete the job. It took less than 10 minutes to do something that would have taken hours to do by hand. With this completed, I created the new invoice, and since the total was correct, I called it a day!
When I created the invoice, I chose to create it with the status “open”. This would allow Carlos to do a final check before closing it. In Portugal, after an invoice is closed, you cannot change it anymore. I could have created the invoice in a closed state (or so I thought) but it would prevent us from fixing any mistakes.
So on the next day, Carlos reviewed the invoice and since all looked good, he clicked on the button to close the invoice but... nothing happened. He tried again. Still nothing… Wanting to understand what was happening, Carlos sent a support ticket to Moloni about the situation to which I got told that what he wanted to do was not possible because his browser was not powerful enough… It seemed fishy but still, I was right back to the start…
On the third day, I used my script to create an invoice in a closed state directly. Due to the portuguese legislation, when you close an invoice, the invoicing software needs to do a bunch of calculations and so when I tried to create the invoice with 3200 products, let’s just say the page kept processing for more than 30 minutes before getting an error from the server. Apparently the software (not the browser) could not handle an invoice so big and so we decided to split the invoice into 7 smaller ones for the next day.
By splitting the invoices into 7 smaller ones, I was finally able to generate all the invoices I needed but something happened. When Carlos went to fetch the 7 invoices, the invoice from the night before was there! Despite the error, I believe the server kept on processing the invoice until it was properly closed. So, we discarded the 7 new invoices and took only the first one. Job done!
Do you want to see the result? I certainly did! This is the result of printing the entire invoice, 53 A4 paper sheets, printed on both sides, giving a grand total of 106 pages:
The question that remains
So why did I bother? I’m a full-stack web developer with a couple of years of experience under my belt. I accumulated a nice set of skills and instead of using them to make a salary, I decided to help a friend for a couple of reasons:
- I could do it;
- It's awesome to help a someone out;
- I like a good challenge;
For those reasons, I didn’t take any money for my work, but let’s just say the next time we meet, we’ll dine like kings…
I hope you liked this story, and if you have similar ones about automation, I’d be love to read about them!