Accounting for Engineers
An introduction to accounting concepts using basic data transformations
When engineers join Pennylane, they are generally not familiar with accounting concepts. Since we expect them to dive deep on accounting topics, engineers go through an advanced training process during the first weeks. We are sharing today a simplified version of how we introduce accounting to engineers during their first weeks.
🙌 Let’s add an invoice to our books!
Congratulations, you just sold a flamethrower! The customer has not paid yet but you created an invoice using your favorite billing software. We’ll model that as a JSON file for clarity:
{
"currency": "eur",
"customer_email": "testuser@test.com",
"customer_name": "ACME Inc",
"date": "2021-12-10",
"lines": [
{
"amount": 2700,
"currency": "eur",
"description": "Flamethrower",
"unit_amount": 2700,
"quantity": 1,
"vat_rate": 20,
}
]
"paid": false,
"tax": 540,
"total": 3240,
}
In real life, invoices have many other fields, but this is a simplified version for our need (taken the Stripe Billing API).
A company has many more accounts in its accounting books than in the bank.
Accounting uses a concept of account that is very similar to a bank account. What is special though is that there is an account for everything. So keep in mind that a company has many more accounts in its accounting books than in the bank. We’ll later see why this makes sense.
Each account contains entries that are similar to bank transactions: they have a label, a date, and an amount.
Let’s now see how the above invoice translates into accounting data:
date | account | label | amount
-------------+------------+------------+-----------
2021-12-10 | 411ACMEINC | Acme Inc | -3240.00
2021-12-10 | 700PROFIT | Acme Inc | 2700.00
2021-12-10 | 445VAT | Acme Inc | 540.00
We just created our first accounting transaction! As you can see, every account has an identifier that follows a specific convention (the French GAAP definitions in this case):
411ACMEINC
: the411
prefix indicates that it's a customer account. We also see that this customer has their own account. The amount represents how much the customer owes us for this invoice. Until the invoice is paid, this customer account has a negative balance. This account is useful to compute the overall balance of a customer. Reasoning by balance helps to know how much money a customer owes us, regardless of the associated invoices.700PROFIT
: the7
prefix indicates that this is a profit account. Profit and Loss are always computed excluding taxes, hence the 2 700 EUR amount in this account. Measuring profit (and Loss) is useful to drive your business and generate accounting reports (like the Income Statement).445VAT
: The445
is a VAT-specific prefix. The associate entry represents VAT that is due to the administration. The balance of this account is used to know how much VAT must be paid every month.
In every entry we see above, we use a dedicated account that serves its purpose in accounting (e.g getting paid, declaring taxes, generating reports) using its balance.
Key learnings:
1. Accounting splits entries into many accounts following a legal convention.
2. Every account has a specific purpose defined by its name prefix.
💳 And now a payment
In this type of accounting, called accrual accounting, invoices (due amounts) are taken into account separately from payments (received/sent amounts). So after entering an invoice into the system, let’s talk about payments.
What we started to build earlier is called the general ledger in accounting. It contains all entries for a given company, and each of them is attached to an underlying account.
In the previous section, you might have noticed that we stored redundant information: the total amount is just the sum of the profit and the VAT. Without noticing it, we implemented the double-entry mechanism, which is one of the fundamental principles in accounting. Double-entry is achieved in an accounting transaction when sum of debits = sum of credits
. While the previous transaction was entered without thinking about balancing entries, we'll see how this principle is involved in receiving bank transactions.
Let’s now assume you receive a payment in your bank account:
{
"date": "2021-12-15", "amount": 3240, "label": "ACME Inc Txn 000xx23"
}
Your bank account data is generally as poor as the above JSON. Smart systems can automatically reconcile that, but complex cases require some manual input. Great news in this case! This looks like a payment from the above invoice (same amount and similar label), so here is how it translates into the general ledger:
date | account | label | amount
-------------+------------+-----------------------+-----------
2021-12-15 | 411ACMEINC | ACME Inc Txn 000xx23 | 3240.00
2021-12-15 | 512SWAN | ACME Inc Txn 000xx23 | -3240.00
2021-12-10 | 411ACMEINC | Acme Inc | -3240.00
2021-12-10 | 700PROFIT | Acme Inc | 2700.00
2021-12-10 | 445VAT | Acme Inc | 540.00
We just added two new entries into our ledger. A few interesting observations:
- ✅ Double-entry has been respected for this new transaction, we have two entries that are balanced with each other.
- 🙌 The
411ACMEINC
account has now a balance of zero, meaning that this client does not owe you any money. Your accountant will not worry about this account since it is up to date (balance = 0). - 🙃
512SWAN
: this is a new account that represents a bank account (the512
prefix is reserved for bank accounts). Why is the amount negative whereas we just received money? Great question! In accounting, bank accounts increase ↗️ with debits ↘️. To understand that, you can see a bank account as money that you owe to your shareholders.
Let’s assume we now receive another payment that looks like that:
{
"date": "2021-12-18", "amount": 20, "label": "Corner beers Txn 000XX65"
}
This one can not be matched with any existing customer account. So we’ll put it in a pending account:
date | account | label | amount
-------------+------------+---------------------------+-----------
2021-12-18 | 512SWAN | Corner beers Txn 000XX65 | -20.00
2021-12-18 | 471PENDING | Corner beers Txn 000XX65 | 20.00 ... old data ommitted
Here is how to interpret these new entries:
- The pending account (with the
471
prefix) has been introduced and has a non-zero balance. This means that data is missing from the books. We are indeed missing the invoice associated with this payment. - Double-entry is satisfied (as always) thanks to this
471
account.
We are almost done. Can you guess what will happen when we’ll receive the invoice associated with the unknown payment?
- We’ll enter the invoice exactly the same way as in the first step (using customer + VAT + profit accounts).
- We’ll also add a transaction to empty the
471
pending account and therefore empty the customer account.
Key learnings:
1. Accounting transactions all respect the double-entry principle.
2. 🙃 Bank-related accounts are used differently as your bank statements.
3. Pending accounts are double-entry artifacts that we use for unmatched bank transaction.
🔭 Further accounting concepts
We just scratched the surface of accounting with a basic data entry example.
There are several other interesting concepts we did not cover:
- Balance Sheet and Income Statement: these are reports that are essentially aggregations on the general ledger. They are tightly related to the active and passive assets concepts we did not cover here.
- Fiscal year: accounting is performed for every fiscal year in isolation. This means that closed fiscal years are immutable, but also that we use special accounting entries to the balance of every account at the same value as the end of the previous fiscal year. Fiscal years, therefore, create data snapshots that are very useful for computations.
- VAT computation: computing VAT is a hard problem. There are many vat rates, multiple modes (is the invoice related to goods or services?), and specific rules when you are buying/selling outside your country (is it inside/outside Europe, inside/outside your country), etc.
- Exotic kinds of “invoices”: deferred credits, prepaid expenses, accrued expenses, unbilled revenues… are all special concepts with their own kind of accounting specifics.
Are you curious to know more about accounting and join a fast-growing full-remote team? We are hiring Software Engineers (full-stack and front-end), Senior Software Engineers, and Engineering Managers.