11 ms·
Hledger: Robust Plain Text Accounting
- sctb 7y agoDiscussion from 2017: https://news.ycombinator.com/item?id=15818682 https://news.ycombinator.com/item?id=15818682.
- Nerada 7y agoDoes Hledger support encrypting the ledger file? I don't mean placing the ledger in an encrypted container and mounting/unmounting as necessary, but I guess 'natively' as part of the file (think an encrypted Excel document). I'm a GnuCash user, but my biggest gripe is not being able to encrypt my accounting file. I'd love to have it sync across my devices via x cloud platform, but I'm always paranoid about uploading anything that isn't password protected. If I was able to do that it'd be the push that gets me to switch from the GnuCash GUI to a plaintext account. Maybe there's some other way I haven't thought of without a high barrier to entry like constantly mounting and unmounting an encrypted container to make changes.
- YaxelPerez 7y agoJust having the ledger in cryptomator works fine for me. Not sure how secure it is.
- Jtsummers 7y agoHledger just works on text files. You’d need some other system to keep them encrypted. I use KBFS which keeps things synced between my devices well enough.
- icebraining 7y agoYou can use a syncing application that encrypts beforehand. The one I use is git-annex, which supports many cloud platforms (as well as plain SSH/FTP/SMB/etc), but there are others.
- AdamGibbins 7y agobeancount does, you can transparently encrypt your data.
- dhruvkar 7y agois there any documentation for this?
- atmosx 7y agoI use gitcrypt.
- AdamGibbins 7y agoPersonally I prefer beancount, incredibly pluggable in python (imo a friendlier language to haskell), additionally much stricter in multiple aspects. Been maintaining my ledger with ledger-cli and then beacount for 10 years now.
- dragonsh 7y agoI am a user of both ledger-cli with emacs lisp bindings and beancount, fava with bank PDF statement preprocessing for journal entries. Used statistical inference to generate journal entries automatcomatically with tools like reckon (now use another one, as it's not maintained) and self written algorithms in Python with sci-kit learn. Works very well so far for over 6 years.
- nsomaru 7y agoI’d love to see your scripts if you could share them? Especially the part to automatically generate entries
- dragonsh 7y agoI have built the scripts using https://github.com/quentinsf/icsv2ledger/blob/master/icsv2ledger.py https://github.com/quentinsf/icsv2ledger/blob/master/icsv2le... as base. You can do the same as the scripts I wrote are specific to banks I am using and the pdf files they send, except one of the banks which provide qif format file which I convert to CSV. You can look at https://github.com/beancount/beancount/tree/master/examples/ingest https://github.com/beancount/beancount/tree/master/examples/... for beancount custom import example.
- HorizonXP 7y agoI just spent the last week reconciling my books, using my scores of Excel files as a source, moving them to ledger. I learned rudimentary double-entry accounting in high school, and I love that ledger enforces it so that I can be strict about my tracking. I still have to figure out how to produce balance sheets and income statements so that I can confirm that my accounts are balanced correctly. Honestly wish I had done this sooner. Edit: Looking at beancount again, I should just use that instead of ledger. Ledger's simple, elegant, and nice, but I'm a Python guy, and I should just use what I know.
- edwintorok 7y agoI've recently come across two systems that use hledger for processing bank statements: https://pauley.org.za/hledger-flow/ https://pauley.org.za/hledger-flow/ https://github.com/adept/full-fledged-hledger/wiki https://github.com/adept/full-fledged-hledger/wiki They treat the statements as the single source of truth, with preprocessing and rules that can be used to turn them into hledger journals.
- apauley 7y agoI'd be happy to hear if you've found hledger-flow useful. Feel free to create an issue on https://github.com/apauley/hledger-flow https://github.com/apauley/hledger-flow if you think anything can be improved.
- techntoke 7y agohledger looks pretty amazing, but there are so many dependencies and updates with Haskell programs. Almost every other day I'm updating like 20 Haskell packages for hledger or pandoc when I run a system update. It isn't inherently bad, but never had this issue with a C or Go program.
- smichael 7y agoMay I ask what system is that ? Maybe one of the other packaging methods will give you a more stable installation ? https://hledger.org/download https://hledger.org/download
- jeremyjh 7y agoI'd bet money its Arch. I love `pacman` but the package spam for Haskell is a bit much as its automatically updating everytime a new package is hosted on hackage. I'd recommend skipping it all together, just use stack and build it from source, let stack manage GHC and you'll never update except when you want to.
- Shoop 7y agoTo add some context to this, the reason why packages which depend on haskell in arch are such a mess is because "the arch way" is to dynamically link everything. This has its advantages (namely security), but is not super compatible with the haskell ecosystem which is designed with static linking in mind. Like my parent commenter, I recommend just doing everything through stack. stack-static from the AUR [0] is the convenient way to do this (rather than dragging in a few gigs of ghc dependencies for stack only to have stack create its own local ghc installation as well). [0] https://aur.archlinux.org/packages/stack-static/ https://aur.archlinux.org/packages/stack-static/
- bscphil 7y agoIf I'm not mistaken, Arch has some ornery maintainers in the Haskell department as well. Pandoc in particular used to have a static package, but now it can't be installed without pulling in a bunch of Haskell development packages. The maintainer in this case refused to fix the problem and closes all bug reports without comment. Fortunately there's https://aur.archlinux.org/packages/pandoc-bin/ https://aur.archlinux.org/packages/pandoc-bin/
- smichael 7y agoI'm hledger's lead developer, thanks for the mention. If you have any questions or hit any snags trying it out, I'm ready to help. Critique of product, docs etc. is welcome. Last time (2017) we got 2 out of 41 comments about hledger, so I'm hoping for a few more. :) https://hledger.org/release-notes https://hledger.org/release-notes has the (software) changes since then. Our chat is #hledger on Freenode: http://webchat.freenode.net/?channels=hledger http://webchat.freenode.net/?channels=hledger
- wtvanhest 7y agoJust curious, do you guys have any power users? Like large companies? Also, what does the distant future look like for hledger?
- jsmith99 7y agoLarge companies don't usually post everything manually. They journal adjustments, but the day to day entries will be made automatically by their ERP from systems like Purchase to Pay.
- dragonsh 7y agoActually large companies are mostly manual compared to most small/medium size companies. Just too many processes to just generate correct journal entries in SAP from purchase, sales, operations, production and distribution. Moreover adjustments, inventory counting methods, purchase, sales require creative use of manual processes, excel and laborious job of account reconciliation at closing (which indeed is just a snapshot report at point in time). I have yet to see a multi-national SAP installation which automatically ingest banks, financial institutes reports and generate account reconciliation entries, government reports automatically. I feel combined with machine learning and storing hledger records in some large databse, it can become a powerful automated accounting system which SAP and large vendors can just dream of.
- jchoelt 7y ago
- z3t4 7y agoA ledger should be a database with only select and insert privileges. eg. No update or delete queries should be allowed.
- p1necone 7y agoIf you're writing a ledger for your own personal record keeping, and not for some third party to be able to audit you wouldn't it be helpful to be able to keep history tidy and clean up mistakes without having to add extra entries?
- repiret 7y agoYes in the sense that data shouldn't be destroyed, but you still need to be able to correct mistakes - those corrections just need to leave an audit trail.
- dmos62 7y agoThat's a solved problem: git.
- tty2300 7y agoGit allows rewriting history though.
- dmos62 7y agoBut not by mistake, and it facilitates remote backups. I took this to be the problem parent was talking about.
- jolmg 7y agoIf you're sharing the repo, then you'll have to convince everyone to discard their copy of the original history and accept your modified version. And if that's done and everyone accepts the new history, the original can still be kept in each copy of the repo on another branch and the rewrite seen in the reflog. If commits are being signed, you can keep undeniable record of who contributed what in the original history, and who rewrote it. If the point is to forbid you to modify even when you're the only person working on it, any common database will allow you to update and delete when you enter with administrative privileges, so I don't see the difference.
- ryanobjc 7y agoHledger is pretty good for basic accounting. I recently had to do some tracking of stocks and lots and forex and the developers decided not to implement lot-based tracking. Which made it impossible to accurately track money. So back to plain ledger. If I was starting over I'd probably consider beancount. But there's only so much I can do a day.
- smichael 7y agoI guess you haven’t seen https://github.com/simonmichael/hledger/issues/1015 https://github.com/simonmichael/hledger/issues/1015 ?
- ryanobjc 7y agoI have but I couldn't make it work. The issue seemed to boil down to "when do you price commodities?". Hledger doesn't let you report the price at the actual sale. The history flag didn't work I forget the reasons at this moment but if I recall correctly it boiled down to "price at market" type of features. That works fine for asset type accounts. But when we are taking about as-was accounting it doesn't work well enough. Beancount has some interesting ideas about lot tracking but switching cost is too high - I have years and 35k lines.
- smichael 7y agoWhat I mean is: - "The developers decided not to implement lot-based tracking" seems a misunderstanding. Perhaps "the developers have dragged their heels on exactly replicating Ledger's handling of lots" is more accurate (and I could justify that!). - we have never had sophisticated valuation/investment features, but there's a bunch of work in progress on this area right now; more flexible valuation (https://github.com/simonmichael/hledger/issues/329 https://github.com/simonmichael/hledger/issues/329) is a current focus and needs testers.. And, right now it should be possible to manage lots manually, similar to http://rantsideasstuff.com/posts/2018/07/01-tracking-investments-in-lots-with-hledger http://rantsideasstuff.com/posts/2018/07/01-tracking-investm... . It's a manual process in Ledger too after all. Let's chat in #hledger if you'd like.
- meruru 7y agoSee also https://plaintextaccounting.org https://plaintextaccounting.org for more on the broader ledger ecosystem.
- wodenokoto 7y agoWhich is also a really good introduction to accounting. I based my spreadsheet accounting on this guide.
- smichael 7y agowodenokoto, may I ask which guide ?
- enriquto 7y agoI would appreciate a small section on the README file that explains how to compile the program, what are the requirements (e.g., what debian packages to install), and a minimal cli use case. Also, running "make" prints a daunting 96 lines of text of which the last 50 (the ones that you get to see) are mostly useless. If I run "make build" it starts to download stuff from the internet, which I find extremely impolite, as I already downloaded the source code. What is the point of not including all the neeedded source code in the source distribution?
- TomK32 7y agoHaskell is a bit rare and so are its libraries rarely installed on systems. I can't remember, as arch has a proper package and I built hledger only once on a different system, but those downloads might be just libraries.
- enriquto 7y agoWhatever. Either they are dependencies that are required to be installed beforehand (just like a haskel compiler is required), or they are included in the source code distribution. Downloading them at compile time is very strange, and in my eyes unacceptable.
- x3ro 7y agoWhile I do see that this might be valuable, I find the argument strange and it makes me wonder in which area you work that this is so alien to you. I've generally come to expect that any software I download and try to build might, through a package manager, pull in additional dependencies (rust, Haskell, scala/Java/closure,...). The only real outliers here seem to be C and C++, of the ones I've worked with.
- owaty 7y agoIt's not different from what pip install or gem install do by default. A mature Haskell project such as hledger has probably a few hundred of transitive dependencies, so you won't be able to install them individually by hand. You might try to figure whether each of them is packaged by your distribution (unlikely, unless hledger itself is packaged), but that's not a typical path — just don't use make in that case.
- accrual 7y agoI've used the original ledger [0] for a few years to track my day-to-day cash flow and appreciate the simplicity. I create a new file every year and manage it with standard Unix tools, plus a few shell and Python wrappers to make entries and reports a little easier. The hardest part is just getting started and getting into the habit of maintaining the ledger. Once you start tracking it's difficult to stop! Seeing all of your accounts line up is a reward in itself. [0] https://www.ledger-cli.org https://www.ledger-cli.org
- tangue 7y agoIf you're using Emacs and are not familiar with double-entry accounting this video is a good introduction : https://www.youtube.com/watch?v=cjoCNRpLanY https://www.youtube.com/watch?v=cjoCNRpLanY (it's based on ledger not hledger)
- stevesimmons 7y agoThese ledger formats have what feels to me an overly verbose multi-line structure for each transaction. For 20 years, I have been using a format that combines a diary and ledger. The 'to' and 'from' accounts are either bank/asset accounts (sav, cc, hl for home loan, ...) or spend categories (snack, shopping, clothes, ... ). Each year I finish 31 December with a `# Closing balances` section for each bank/investment/pension account, then start a new text file `2019.txt` with an `# Opening balances` section before 1 January's entry. Here is a typical day's format: # 2019-05-27 Mon 2.50 sav>lunch Cafe Nero - Coffee 100.00 sav>cc Transfer - Credit card repayment amt from>to forex: shop - desc [txn #] # Diary * <topic> - <what> * Times - Sleep 01:00-06:00 5h. Run 45m. Work 08:00-18:00 10h. * Work - Meeting with xxx on xxx. We agreed to xxx. * Friends - Lunch with xxx * Note - Running shoes are Asics GT-2000, size 48, model T500N. # Links * Hledger: Robust plain text accounting - https://news.ycombinator.com/item?id=20012499 For the first 5 years, I was single and reconciled everything down to the cent, using an AWK script to generate totals to match against my bank statements. When I got married, all our accounts switched to joint ones. I didn't want to track my my partner's side of our spending. So these logs became more a personal diary than a fully reconciled ledger. Anything I want to remember long-term goes either there or secured in a password safe.
- kd5bjo 7y agoYou reinvented the accounting daybook: Shops doing paper accounting never went through the hassle of double-entry accounts for each sale. Instead, each was a single line in the day’s journal, and closing for the day involved reconciling the till with the sales journal, and entering the entire day’s revenue as a single transaction in the master account book.
- fiatjaf 7y agoI agree. They are too verbose. One line is enough. I actually think personal logs are useful for all things, not only money. In my business we use a text-file with logs for all the events, money, business stuff that happens, and then there's a program that reads all the lines, parses them and turns them into a final "state" of the company with everything that is being done and so on. From that we generate dashboards, reports and stuff. This is the system we use: https://github.com/fiatjaf/journalstate https://github.com/fiatjaf/journalstate (but really the power is in the concept, not the implementation). I've also turned that into a TodoMVC app: https://journalstate-todomvc.alhur.es/ https://journalstate-todomvc.alhur.es/, so you can see it in action in a fancy, useless way.
- mongol 7y agoI looked into plain text accounting but Swedish bookkeeping/accounting practises forbid practises where past records can be modified. It needs to be append-only. I started developing a command line accounting tool using SQLite and Go but it is only half-finished.
- estsauver 7y agoGit + Open Timestamps maybe?
- magnamerc 7y agoOr maybe gasp a blockchain.
- Someone 7y agoBinary files can be rewritten, too. To check that the first N transactions in a file weren’t tampered with, you have to either compare each transaction with a backup, or hash them and compare the result with the hash you got earlier. If, as I suspect, this ledger is append-only, both are fairly simple. If the ledger, say, had 42 lines earlier, do either head -42 ledger | diff ledger.copy (I’m not sure that’s valid shell, but you get the idea) or head -42 ledger | my-super-hash and compare the hash with one you got earlier. Also, some OS-es (e.g. Mac OS. See https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/chflags.2.html https://developer.apple.com/library/archive/documentation/Sy...) have the notion of append-only files. These, too do not safeguard against somebody rewriting the entire ledger, but they can make it harder to do that tampering. Finally, I haven’t thought it through, but possibly, you can create a user on your system for your accountant, set the owner of the ledger to that user, and make it impossible for anybody but that user to delete or replace the file. If that’s possible, it even would protect against reinstalling the system. You could recreate your accountant’s user ID, but not with the same password, so your accountant would still notice.
- noufalibrahim 7y agoI used to be a heavy ledger-cli user and wrote about my setup here http://nibrahim.net.in/2015/11/07/ledger_and_personal_finance.html http://nibrahim.net.in/2015/11/07/ledger_and_personal_financ...
- malicz 7y agoI am a freelance programmer and I use hledger in combination with beancount for a couple of years. why did you change and to what?
- fiatjaf 7y agoSee also http://hledger.alhur.es/ http://hledger.alhur.es/, hledger compiled for the web in a playground (you can also save your stuff to remoteStorage). Source: https://github.com/fiatjaf/hledger-web https://github.com/fiatjaf/hledger-web
- billfruit 7y agoDoes it do 'envelope' style budgets like YNAB?
- smichael 7y agoYou can do those with it, in a manual way (I did for a year or two). More info on this can be found at https://plaintextaccounting.org/#budgeting https://plaintextaccounting.org/#budgeting. There's also non-envelope style budget reports built in. For more on these see https://hledger.org/manual.html#budget-report https://hledger.org/manual.html#budget-report and https://hledger.org/Budgeting-and-forecasting.html https://hledger.org/Budgeting-and-forecasting.html.
- kazinator 7y agoThis is exactly how I do my accounting: record transactions in a plain text file, which is processed by the system, resulting in various ledger and account type objects being in a certain state, which can then be subject to queries and reports. Mine is written in TXR Lisp. It is not released to the public. All input is recorded via function call expressions, which are of course S-exps. There is only one single macro in the whole thing: def-date-var defines a variable that exhibits different values depending on a effective date context (established by a dynamically scoped date variable). With this we can do things like different tax rates for different periods, without having to introduce such things as parameters appearing in every input item. > The amounts within a transaction must always sum up to zero. As a convenience, one amount may be left blank; it will be inferred so as to balance the transaction. I also have transactions that sum to zero. There can be three or more account deltas in a transaction, not only two. This is not how accounting is taught in North America, though; I came up with it myself. Inferring one amount is a bad idea. My system throws an exception if the transaction amounts do not add to zero. However, the entry of items is done via various convenience functions, most of which generate the necessary transactions against all the right accounts. For instance, recording a new asset: (record-asset 1 "Discombobulator" :cca-50 ;; ID, description, capital-cost-allowance class (date 2017 1 23) ($ 79.99) ($ 4.00) ($ 5.60)) ;; base price, GST, PST taxes. From the looks of the journal format of hledger, it's too generic. I wouldn't want to use anything of the sort. Different items need their own syntax. I don't want to record a simple purchase of a recurring expense in the same way that I record an invoice. I bind a new variable when recording an invoice: (defparml %inv-0042% (new invoice number 42 provider %my-addr% client %foo-client-addr% remit-to "Kazinator" remit-days 25 date (date 2017 6 30) items (list (new time-unit start (date 2017 6 1) end (date 2017 6 2) hours 16 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 5) end (date 2017 6 9) hours 40 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 12) end (date 2017 6 16) hours 40 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 19) end (date 2017 6 23) hours 40 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 26) end (date 2017 6 30) hours 40 rate %rate-foo-client-2017%)))) There is no custom DSL here at all; just the new macro of the object system. This is then recorded using a plain function call to the convenience function record-invoice: (record-invoice %inv-0042% "Invoice 0042 issued to Foo, Inc.") This function will digest the invoice and post the right amounts into various accounts. The GST tax has to be charged, and such, When the invoice is paid: (record-paid-invoice %inv-0042% "Invoice 0042 paid by Foo, Inc." (date 2017 7 31)) this function will also update multiple accounts, including the automatic withholding of income tax, based on the withholding rate configured for the date into which the invoice lands. To generate a nice HTML invoice, at the REPL, I just call the .(html ...) method of the invoice object, which takes a stream argument. 1> (with-stream (s (open-file "invoice.html" "w")) %inv-0042%.(html s))