💾 Archived View for gemini.sensorstation.co › ~winduptoy › notes.accounting.gmi captured on 2024-05-10 at 10:40:40. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2024-07-08)

-=-=-=-=-=-=-

Accounting

2024-04-06: I'm re-publishing this from an archived copy because I was contacted by someone who said it was helpful info. Slimvoice is no longer published online as I ended up being slightly unhappy with the ergonomics of it. I'll update this guide one day when I have a better solution.

We've spent a few years perfecting a simplicity-oriented and open source accounting system to run our business. We believe it is applicable to many other small businesses and is a reliable, private, and completly free alternative to commercial products like QuickBooks. The system consists of Ledger, the open source plaintext accounting system, and Slimvoice, our home-grown order and invoicing companion.

Ledger may seem overwhelming at first but it's not hard to get the hang of it; the simplicity, power, and flexibility far outweighs anything like QuickBooks. An overview of plain text accounting will help you understand its advantages.

Plain Text Accounting

Understanding the basics of Ledger is critical to understanding this guide. Ledger's documentation is excellent, so make sure you understand the following sections:

Ledger Documentation

It doesn't require any programming experience, but familiarity with a text editor and the command line are necessary.

A Beginner's Guide to the Command Line

The basics

We follow the following basic account categories which are described in the "Structuring your Accounts" section of the Ledger documentation.

4.3 Structuring your Accounts

Here's an overview of all of the the accounts we've ended up with so far.

Assets
  Checking
  Cash
Donations
Expense
  Accounting
  Ag
    Education
    Equipment
    Materials
    Packaging
    Seeds
    Soil Test
  Hosting
  Mileage
  Phone
  Property Lease
  Tax
Income
  Ag
  Apps
  Development
Opening Balance
Taxable:VA:Sales Tax
  Food
  General

Other details

File organization

We have our finances organized by year, so they end up oulooking like this:

.
├── 2018                   [ previous years ]
    └── ...
├── 2019
    └── ...
├── 2020
    └── ...
└── 2021
    ├── sensorstation.txt  [ main ledger file, major transactions ]
    ├── csa_payments.txt   [ customer cash payments ]
    ├── csa_donations.txt  [ tax-deductable food donations ]
    ├── csa_harvest.txt    [ you can track veggies too ]
    ├── mileage.txt        [ just mileage transactions ]
    ├── orders.txt         [ transactions generated from Slimvoice orders, don't touch ]
    ├── orders             [ Slimvoice order source files ]
    │   ├── 00001_2021-05-19_Jones
    │   ├── 00002_2021-05-20_Gander
    │   └── 00003_2021-05-21_Grilli
    └── receipts           [ receipts to substantiate expenses ]
        ├── 2021-01-01_DigitalOcean.pdf
        ├── 2021-01-02_VA-SCC.pdf
        └── 2021-01-03_HomeDepot.pdf

Ledger allows you to import other files, so running it on the main `sensorstation.txt` file will include all details about payments, donations, mileage, and orders. You can structure this however you like, this is just how we do it.

Payments

If you sell at a market to customers on the street, you may be able to total up your cash for the day and make a single ledger entry for your income. We operate our CSA on a share-commitment model in which customers come to pick up produce every week and are committed for the whole season. Customers don't always have exact change, so we need to keep track of balances and credits available to each customer.

To make collecting payments easy, we created a separate file in our accounting folder for customer payments and used Ledger's `include` command to import it into our main ledger.

Here's a snippet from our payments.txt file:

2021/05/20 (1113)
	Assets:Checking		$20.50
	Customer:Amy

2021/05/20
	Assets:Cash			$20.50
	Customer:Erin

2021/05/20
	Assets:Cash			$21.00
	Customer:Vicki

In this example, our weekly share cost $20.00 + $0.50 sales tax for a total of $20.50.

Assuming you've created transactions for Amy, Erin, and Vicki's orders (see above), Ledger will compute Amy and Erin to have a balance of $0.00 and Vicki will have a balance of $-0.50, meaning you owe her $0.50.

In our model, we will return any unspent credit to each customer at the end of the year. Notice that our customer accounts are not categorized under "Income:Customer:...". This unspent credit of Vicki's does not count towards our taxable income, as we are simply holding it for Vicki temporarily. Check with your accountant and local laws to determine if this is appropriate for your case.

When we make a trip to the bank to deposit our cash, we can record the deposit like so:

06/04
	Assets:Checking			$41.50
	Assets:Cash

Mileage

We want to use the IRS's standard deduction for personal vehicle use. According to IRS rules, you must provide records that substantiate the date, odometer begin and end readings, depature location, destination, and business purpose of each trip. As we file taxes quarterly, we need to report this with our income and expenses.

https://www.irs.gov/publications/p463

Note that not all trips can be deducted as business trips. Make sure you understand the tax laws and discuss it with your accountant.

First we added a new file to our accounting folder with the name of the vehicle, and used the `include` command to import it into our main ledger. Having one file per vehicle can make it easier to quickly enter odometer readings if you're doing it daily.

Here's a snippet from our mileage_yaris.txt file:

; January 1 odometer: 144328
year 2021

; Assert that all details required by the IRS are provided for every transaction
; (must use --strict flag on the command line)
account Expense:Mileage
	assert commodity == "mi"
	assert amount > mi 0
	assert has_meta('Depart')
	assert has_meta('Destination')
	assert has_meta('Time')
	assert has_meta('Purpose')

tag Depart
tag Destination
tag Purpose
tag Time

bucket Vehicle:2007 Yaris
apply account Expense

; Dollar equivalent per mile
; (using the --market flag on the command line will show dollar values)
P 01/01 mi $0.56 ; IRS 2021

bucket Vehicle:2007 Yaris
apply account Expense

05/11
	Mileage			(146757 mi - 146738 mi)
	; Depart: 1234 Office St.
	; Destination: 5678 Farm Rd.
	; Time: 09:05 AM
	; Purpose: Agriculture Labor

05/11
	Mileage			(146775 mi - 146757 mi)
	; Depart: 5678 Farm Rd.
	; Destination: 1234 Office St.
	; Time: 2:45 PM
	; Purpose: Return to office

Ledger can keep track of any unit; this account posting uses miles as the unit instead of dollars. You can do math within the account posting as long as the expression is wrapped in parentheses. This way you can record begin and end odometer readings as `(end - begin)` and let Ledger do the math for you when you balance. Mileage can now be queried just like any other Ledger transaction in order to get the appropriate report for your taxing authority. If you want to figure out the dollar-equivalent per mile, use the `--market` flag when invoking Ledger and it will automatically convert miles to dollars at the rate you have specified.

Non-cash donations

As with mileage, you can also track non-cash donations for tax deduction purposes. It's as simple as giving each commodity a value, and then using the `--market` flag to compute the total value of all donations.

year 2021

bucket Equity
 
; ALL UNITS IN POUNDS
P 07/01 squash $2.49 ; Fresh Market organic squash
P 07/01 bean $4.99 ; Kroger organic green beans
P 07/22 cucumber $2.29 ; Fresh Market organic cucumber

07/08 Food Bank
	Donation			31 squash

07/12 Food Bank
	Donation			14 bean
	Donation			43 squash
	Equity

07/22 Homeless Shelter
	Donation			59 squash
	Donation			13 bean
	Donation			4 cucumber
	Equity

Orders and Invoices

When a customer places an order that requires an invoice, use Slimvoice to create a new order. Slimvoice will create a plain text file with the order number. You can then fill in all the details for the customer, line items and quantities, and taxes. The final result will look something like this:

ORDER: 00012
DATE: 2021-07-31
CURRENCY: USD
CATEGORY: Ag:CSA
CUSTOMER: Rick Cooper

ITEMS
	Arugula
		PRICE: 8.00/lb
		QTY: 0.5
		TAXED: food
	Mustard Greens
		PRICE: 4.50/lb
		QTY: 1.0
		TAXED: food
	Zucchini
		PRICE: 2.00/lb
		QTY: 4
		TAXED: food
	Delivery
		PRICE: 5.00

TAXES
	[VA:Sales Tax:Food]
		TAG: food
		RATE: 2.5%

Slimvoice then does all the hard work of computing subtotals and taxes and places these totals into a new Ledger journal that lives beside your standard journal. You can use the Ledger `include` directive to have the Slimvoice totals imported into your primary journal. Slimvoice can also render templates from order data, making it simple to generate invoices and send them to the customer. The Slimvoice documentation provides more details on its operation.

Slimvoice Documentation

Sales Tax

Collecting

When you use Slimvoice to process your orders, it will automatically generate appropriate balances for tax accounts in the ledger. Here's a sample snippet from an order:

ITEMS
	Tomato
		PRICE: 3.00/lb
		QTY: 4.5
		TAXED: food

TAXES
	[VA:Sales Tax:Food]
		TAG: food
		RATE: 2.5%

When processed by Slimvoice, it will produce the following transaction:

2021/05/19	(#100)	Amy
	Customer:Amy                   $13.84
	Income:CSA                    $-13.50
	Liability:VA:Sales Tax:Food    $-0.34
	(Taxable:VA:Sales Tax:Food)   $-13.50

Meaning:

Virtual postings

Paying

To determine the sales tax that you collected, run this report:

ledger register --monthly --effective 'Liability:VA:Sales Tax' -f company.txt

The first number will be the tax owed (assuming you haven't paid it yet), and the second number will be a running total, which is irrelevant to this situation.

Breaking these arguments down:

To find the total income that should be taxed, run this report, which will take into account the virtual postings mentioned above:

ledger register --monthly --effective 'Taxable' -f company.txt

When making a payment on January 5th for December's taxes, be sure to set the "effective date" to the previous year so that you can verify that all taxes are paid up. The same applies for each month (e.g. paying June's taxes in July). For example:

2022/01/05=2021/12/31	Virginia department of Taxation
	Liability:VA:Sales Tax:Food		$21.56
	Assets:Checking

A small wrinkle in this situation is rounding errors and discounts. For example, if you collect 2.5% sales tax on an order with a subtotal of $10.79, you would collect $0.26975, which rounds to $0.27. This rounding error will accumulate on every order. So if, for example, you have made a total of $859.04 of sales in a given month, 2.5% of that is $21.48 (what the state will calculate that you owe), but you will have found that you have collected something like $21.56. That's $0.08 that you've overcollected, and since everything must balance in ledger, it needs to be accounted for somehow.

In our case, the state of Virginia also gives an extra "dealer discount" of some very small percentage for those who pay on time. So in the above example, the state calculates that we owe $21.48 in taxes minus their $0.21 dealer discount for a total of $21.27 owed. Since we actually collected $21.56 from customers over the course of the month, we'll just lump our $0.08 overcollection in with the $0.21 dealer discount and just classify this as extra income.

This is how the transaction posting from above should now look to account for all of this:

2022/01/05=2021/12/31	Virginia department of Taxation
	Liability:VA:Sales Tax:Food	$21.56
	Assets:Checking				-$21.27
	Income:VA Dealer Discount

The first line in the transaction states that we are removing $21.56 from our sales tax liability. The second line states that $21.27 of that is coming out of our checking account (what we paid to the state). The third line indicates that the remainder, the dealer discount plus our overcollection, gets categorized as income; since ledger forces each transaction to balance, the math is done for us when we leave out the amount on this line.

1099s

Figuring out which clients owe you a 1099, or those that have paid you $600.00 or more over the course of the year:

ledger register --group-by 'payee' --subtotal --display 'U(T)>=600' 'Income' -f company.txt

Breaking these arguments down:

If you have any contractors, you can also see which contractors to whom you owe a 1099 by running the same report on the relevant 'Expense' accounts:

ledger register --group-by 'payee' --subtotal --display 'U(T)>=600' 'Expense:Contractor' -f company.txt

Distributions

If your business is set up like a pass-through entity so that you pay yourself via distributions rather than an official payroll process, you can record your distributions like so:

2021/06/04
	Distribution			$1000.00	; Payee: Matt
	Distribution			$1000.00	; Payee: Ruth
	Assets:Checking

Estimated Quarterly Tax

If you live in a sane country and need to pay quarterly tax estimates, you can probably use Ledger's `--quarterly` option. If you live in the United States, the IRS has shifted quarters around to fudge the books, and now we all have to live with it. This simple shell script divides the report into four "magic IRS quarters":

#!/bin/sh

FILE=$1

echo -e "\n=== IRS Q1 (Jan 1 - Mar 31) ===\n"
ledger balance --effective --period 'until 4/1' -f "$FILE" --no-pager

echo -e "\n=== IRS Q2 (Apr 1 - May 31) ===\n"
ledger balance --effective --period 'from 4/1 to 6/1' -f "$FILE" --no-pager

echo -e "\n=== IRS Q3 (Jun 1 - Aug 31) ===\n"
ledger balance --effective --period 'from 6/1 to 9/1' -f "$FILE" --no-pager

echo -e "\n=== IRS Q4 (Sep 1 - Dec 31) ===\n"
ledger balance --effective --period 'from 9/1' -f "$FILE" --no-pager

echo -e "\n=== Totals ===\n"
ledger balance --effective -f "$FILE" --no-pager