isaacharrisholt / quiffen

Quiffen is a Python package for parsing QIF (Quicken Interchange Format) files.
MIT License
31 stars 26 forks source link

ValueError: Unknown line code: t #58

Open michaelwl opened 1 year ago

michaelwl commented 1 year ago
raise ValueError(f"Unknown line code: {line_code}")

ValueError: Unknown line code: t

According to Wikipedia, "T" means Amount of the item. For payments, a leading minus sign is required. For deposits, either no sign or a leading plus sign is accepted. Do not include currency symbols ($, £, ¥, etc.). Comma separators between thousands are allowed.

https://en.wikipedia.org/wiki/Quicken_Interchange_Format

paulmcq commented 1 year ago

It seems that line codes must be in UPPER CASE. GnuCash has a good write-up on QIF: https://github.com/Gnucash/gnucash/blob/stable/gnucash/import-export/qif-imp/file-format.txt

isaacharrisholt commented 1 year ago

That's correct. Line codes are typically uppercase. May I ask which program has generated the lowercase line codes?

We can probably add a workaround for this though, as I don't think that comparing against an uppercase line code should break anything.

It's not technically on spec though, so I'm a little reticent to do that if it can be avoided.

michaelwl commented 1 year ago

The program that created the QIF file is "Quicken 2011 Home and Business Release R 8(20.1.8.6) on Windows.

The QIF file that is created by the File > Export feature does in fact generate all lines codes as capital letters. I can't work out where the "t" came from. Running it now again, with a fresh export, produces this

Python 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.

from quiffen import Qif, QifDataType import os import decimal folder = r'C:\Users........\Files' sourcefile = os.path.join(folder,'Exported.qif') qif = Qif.parse(sourcefile, day_first=False) Traceback (most recent call last): File "", line 1, in File "C:\Python311\Lib\site-packages\quiffen\core\qif.py", line 260, in parse new_transaction, new_classes = Transaction.from_list( ^^^^^^^^^^^^^^^^^^^^^^ File "C:\Python311\Lib\site-packages\quiffen\core\transaction.py", line 477, in from_list raise ValueError(f"Unknown line code: {line_code}") ValueError: Unknown line code: X

The source transactions come from the "Invoice - Customer Invoices" feature. where the "X" is referring to parts of the invoice.

..... XI3 XE0/ 0/ 0 XR0.0 XT0.00 ^ D6/30'10 U13,057.03 T13,057.03 C N5 Pxxxxxxxxxxxxxxx Axxxxxxxxxxxxxxx A A A A S $11,606.25 S[Sales Tax] $1,450.78 XI1 XE7/30'10 XC[Sales Tax*] XR12.50 XT1,450.78 XNxxxxxxxxxxxxxx X#154.75 X$75.0 XFT XN X#0.0 X$0.0 ^ D7/26'10 U-10,000.00 T-10,000.00 .....

image

isaacharrisholt commented 1 year ago

Oh interesting, that's a Quicken Business line code. Quiffen doesn't currently support those, but it probably should. Is that something you'd be comfortable looking into?

michaelwl commented 1 year ago

I have two thoughts: (1) a qif file is basically made up of fragments, right? In this case here it seems that the business invoices fragment is not handled by your library. Rather than bombing out entirely, it should just exclude the fragment it cannot process.

(2) sure, I'd love to do my bit, but I'm not sure I'm qualified, haha. I'm just an amateur coder and a hardcore lurker. Love all this open source stuff, but don't know that my skills are up to it :)

isaacharrisholt commented 1 year ago

You're right! It should definitely handle it more gracefully than it does. It could use warnings.warn. However, this could lead to some silent missing data, so in this case I actually think blowing up is probably preferred. This way, if someone is using the library to process many files, they can use try/catch to find which files are problematic, rather than just silently losing data.

As for your skill, it doesn't matter! I'm always open to having more people help, and I'd be happy to coach wherever needed! This work is predominantly copy-paste of existing stuff, for the most part, so it shouldn't be too difficult. It's a good first issue for someone who hasn't done much open source work 😉