Cash, Checks & Reconciling (Sep 27)

TurtleSoft staff is still working on Pay Bills, Deposit Funds, and the other action dialogs in our new accounting software. It probably will take a few more weeks to finish them.

All the action dialogs were already set up, back in November 2021. They looked good and showed proper data. However, they didn’t do the necessary tricks: handling clicks, typing and buttons, posting payments. That’s what we are finishing now.

Some of the extra work is because of bank deregulation.

In the early days of Goldenseal accounting, banks were on a tight leash. It was a legacy of the Great Depression. Checking accounts wrote checks, and didn’t do much else. Credit card accounts only had cards. Loans and savings accounts had neither. Goldenseal accounting software was built around the differences.

Then, everything smooshed. You could write a check, swipe a card, and get cash from almost every type of account. More types of accounts could go negative. We gradually updated Goldenseal to cope, but it was a losing battle.

The new accounting software has plain bank accounts. There still is a cash/checking/credit card/loan/savings split, but it’s just a popup field rather than different account classes. Investments still need their own class because they can be job costed. Escrows have to be separate because it’s not your money.

Banking transactions show up in many, many places. It’s taking a while to root them all out, and switch things to the new system. However, the change is not all bad. New bank accounts store some extra info that makes it very fast to fetch running totals. The old system was complicated, and still buggy even after 20 years of repairs. Now it’s much simpler.

Even better, Reconcile is 100x faster now. When you change the period, it fills the table almost instantly.

Last week, our staff started to test the Reconcile command. It ran OK for TurtleSoft’s data, but the numbers were wrong. Not surprising, since we did a total rewrite of the calculations. New code is rarely perfect on the first go.

We tried Reconcile on the Sample File, since it is smaller and easier to debug. It froze up with an infinite loop somewhere. That led to a couple days of problem solving. I’ll describe the events here, just so you know what it’s like to design and build complex software.

First of all, the freeze was easy to locate: it happened when the popup list of reconcile periods filled in. Problem was, early versions of Goldenseal didn’t have dates attached to the periods. It’s something we added in 2006. Our code uses the C++ standard library to sort the list, and it got confused when asked to sort a list of identical bad dates. Switching to a different sort method solved that problem.

The next problem was, how do we handle old reconcile periods without dates? Some long-time users will have them. Early on, we added a button to fill in a year’s worth of periods. That uses month-year format (e.g. Jan-22). Could we convert it to a date? Sure, but it meant a dive into the complicated, mid-1990s code that translates text to dates. It didn’t handle month-year, but we added a branch to make it work.

When you open an existing Goldenseal file with TurtleSoft Pro, it already converts all the data to the new format, and saves it into a new file. We added the same text-conversion there. Now, if a Reconcile Period doesn’t have a valid date, the code tries hard to give it one before you even use it.

The Sample File now works great. Your Goldenseal file probably will, too.

Dennis Kolva
Programming Director
TurtleSoft.com

 

Bank Transactions & Onwards (Sep 19)

Our accounting software handles both accrual and cash accounting. It’s a distinction that confuses many people. Fortunately, you don’t need to know anything about them when you use Goldenseal. Ditto for the upcoming TurtleSoft Pro.

Job costing usually comes from the accrual transactions: material purchases, subcontractor & other invoices, labor & equipment hours. They have all the details needed for accurate estimate vs actual tracking. Usually, they also are the first time you find out about expenses.

Most cash transactions happen automatically. If you buy something and pay with cash/check/credit card, the app makes an instant payment to handle the money. If not, the expense becomes Accounts Payable, which you pay with the Pay Bills command.

Last week, our staff moved on to bank transactions, which handle the cash accounting. They are harder than the accrual stuff, because we made big changes. Goldenseal had separate cash, checking, credit card, loan, and savings accounts. The new accounting software merges them all into just plain old bank accounts. Transaction layouts are simpler. We also made it possible to see many different accounts at the same time.

The new setup is a big improvement, but it took a few days to get past the bugs and error messages caused by the changes. Most are now fixed, though it’s likely a few more will pop up in later testing.

We also moved on to the action commands (Pay Bills, Write Payroll, Deposit Funds, Project/Sales Billing, Job Costing, Reconcile). For large projects like this, it’s easy to forget what is already finished, and what isn’t. It was a pleasant surprise to find out that those already work. They aren’t perfect, but the remaining bugs will shake out during final testing.

Payroll and Estimating are last on the to-do list, because they are the most complicated. We also jumped ahead and started work on those. They don’t look all that bad.

It’s almost at the punch-list phase of the project. Down to loose ends.

Dennis Kolva
Programming Director
TurtleSoft.com

Technical Debt (Sept 12)

Smart fields are a big part of our estimating/accounting software. They let you choose from a list of customers, suppliers or whatever. Breakdown tables are also important. They show details for estimates, purchases or sales. Both of them are complicated, especially when there’s a smart field inside a table.

Most complex of all? The Item column. It is bonkers, especially in estimate breakdowns. The cell may show a smart field to choose something: a list of materials, labor, construction assemblies, subcontractor bids, etc. Or, it may just let you type in some text: for a random material, a percentage adjustment, or a comment. Each option has different impacts on the rest of the table.

Last week, our staff got into an infinite loop while fixing a problem in Item cells. Sometimes they were empty, but every time we fixed it for one case, it broke for something else. That’s a sign that code is just too danged complicated. Time for a better design.

Each row in a breakdown table is stored as a breakdown object inside the database. To fill the table row, we loop through the columns, fetch a chunk of text from the object, and pop it into the cell. The process works great for most things, but some cells need to know more than just their text.

The current Goldenseal code gets the extra info from other columns in the row. We have to be careful about their order, since we fill from left to right. It may also mean converting text back to numbers. One of those probably caused all the problems.

While trying to rewrite it, our staff had a d’oh moment. Why not just get everything all at once from the object? That would make it a one step process, instead of two.

We whipped up some trial code to make a one-step transfer for the Item column. It worked great. The new approach is simpler. It will be easier to maintain.

For now, the new system only applies to the one column. However, if anything else misbehaves, it can get the same fix. Some day we may rewrite everything with the new code.

In programming, there’s something called “technical debt”. It’s all the hacks, bugs, and bad design decisions that staff made years ago. It’s code that works, but it ain’t great. It’s the door framing without headers, the joist that the plumber cut to a ribbon, the gap that got a dab of caulk.

Sometimes TurtleSoft has the chance to fix technical debt. This was one of them. The code base will never be perfect, but at least it can improve with time.

Dennis Kolva
Programming Director
TurtleSoft.com

 

Exceptions (Sep 5)

Bill Atkinson was one of the bright lights in the early days at Apple Computer. He designed much of the human interface for the Mac. Then he wrote MacPaint. Then HyperCard.

In a 1990 talk at MacWorld Expo, Bill explained his programming philosophy as “prove it”. Every line of code was followed by another line that made sure it really did what it claimed.

We took his advice to heart while building the Goldenseal accounting software. Its code doesn’t test every single line, but there are many thousands of “sanity checks” to make sure things are really OK.

It’s the reason why Goldenseal rarely crashes. Instead, if something goes wrong, it shows an error message. Even better, the message has the exact file and line for the error. That way, bug fixes are easy: we know exactly where to look in the source code. It saves time during development, and also in the finished app. If users run into a bug, they can tell us exactly where to fix it.

After giving the message, we want to “do no harm”. So, our code throws an exception. It’s C++ for “get me out of here!” The exception zooms away from the code that would cause a crash or other problem. Usually it jumps all the way out to the event loop. That’s the beating heart of the app: where it constantly waits for mouse clicks, keyboard presses, and other user actions.

The exception is caught there, and the event loop continues. Nearly always, the app returns to normal after that. You can continue working, or at least save your work before closing out.

When we started with Qt a couple years ago, one of the first things we did was to add exception-catching inside its event loop. Most exceptions worked OK, but some never got there. Instead, they crashed immediately. It was annoying, and sometimes made a file that couldn’t be opened. We really don’t want that to happen.

Last week our staff did some troubleshooting. Rather than wait for natural errors, we added deliberate exceptions in different spots. All the lethal ones that showed up were in the early startup code, so we added code to catch them before reaching the loop. I think that may be all it takes to make the new accounting app as reliable as the old one.

Qt warns against throwing exceptions through their signals/slots system, but we didn’t find anything that got stuck there. It may become a problem in future versions of Qt. We’ll see.

In general, our staff is very happy with Qt. It has plenty of quirks, but it does the job. Too bad that we didn’t start using it a few years earlier…

Dennis Kolva
Programming Director
TurtleSoft.com