Giter VIP home page Giter VIP logo

bank2ynab's Introduction

bank2ynab

This project consolidates other conversion efforts into one universal tool that easily converts and imports your bank's statements into YNAB.

Development: GitHub issues by-label GitHub open issues GitHub last commit PRs welcome! Join the chat at https://gitter.im/bank2ynab/Lobby Code style: black

Testing: Travis status Coverage Status Maintainability

What? (Features)

Convert your downloaded bank statements into YNAB's input format. Here's what this script does, step by step:

  1. Look for and parse the bank2ynab.conf. This file contains all the rules and import formats.
  2. Look for and parse every CSV file in the configured download directory.
  3. If the CSV file matches any of the configured formats:
    1. Create a new CSV file in YNAB's CSV format with the correct columns and a blank Category column.
    2. Optionally delete the original CSV file.

Wish List

  • add many more input formats from all the other YNAB-CSV-conversion projects.
  • maybe coming later: automatically download your bank statements? (uses external services; only available in some countries)
  • maybe coming later: automatically import the converted data into your YNAB app? (optional, default off)

Why?

There are currently more than 80 GitHub projects related to YNAB converter scripts. Clearly there's a need, but until now these solutions have been fragmented. The present project "bank2ynab" aims to focus the efforts on a common source that encapsulates a large number of bank formats. This will also provide a common basis for a solution using a variety of programming languages.

How? Contribute!

Installation Instructions

Requirements

  • Windows or Mac or Linux
  • Python v3.9+ installed (download it from python.org)
  • Support for other scripting languages may follow. Contributions are welcome!

User Guide

Using bank2ynab is easy:

  1. Download some bank statements from your banking website.
    • Make sure to choose CSV format. Save with the default suggested filename so that the converter can find it.
    • It's okay if the statements contain data that you already have in YNAB. YNAB will detect and skip these.
  2. Check the [DEFAULT] configuration in user_configuration.conf. You only need to do this once. Specifically:
    • Source Path = c:\users\example-username\Downloads Specify where you save your downloaded CSV files.
    • Delete Source File = True set to False if you want to keep the original CSV you downloaded.
  3. Check that the configuration in bank2ynab.conf contains a [SECTION] for your banking format. You only need to do this once per bank you use. If you can't find your bank in the config, tell us your bank's format and we can add it to the project.
  4. Install the required dependencies by navigating to the bank2ynab directory in your command line and entering the following - pip install -r requirements.txt or pip3 install -r requirements.txt.
  5. Run the bank2ynab.py conversion script to generate the YNAB-ready CSV output file. How to do this depends on your operating system:
    • Windows: Open a command prompt, navigate to the script directory, and run the command python bank2ynab.
      • Pro tip: Create a program shortcut! Right-click on the bank2ynab.bat file, choose Send to and then choose Desktop (create shortcut). Now you can just double-click that shortcut!
    • Linux/Mac: Open a terminal, navigate to the script directory, and run the command python3 ./bank2ynab.     - Important: Be sure to use python3 specifically, and not python or python2 which is probably the system default.
  6. Depending on your configuration, the conversion script will now import your files into YNAB automatically, or you can add the files manually:
    • Automatic import (when you have provided your YNAB API access token:
      • The conversion script will now ask you which budget it should use to import your converted CSV file to (if you have multiple). It will also ask you which account inside the budget to use (if you have multiple); you'll only have to answer this question once.
    • Manually drag-and-drop the converted CSV file onto the YNAB web app:
      • YNAB will detect this and offer you import options. If you had already switched YNAB to the corresponding account view, YNAB will understand that you want to import this file to this account.

Known Bugs

For details, please see our issue list labeled "Bug".

List of Supported Banks

Here is a list of the banks and their formats that we already support. Note that we have many more formats in the pipeline so the list continues to grow, and we are happy to receive requests. In alphabetical order (country and bank):

  1. AT easybank credit card
  2. AT Raiffeisen Bank 2018
  3. AT Raiffeisen Bank RCM
  4. AT Raiffeisen Bank 2019 checking
  5. AT Raiffeisen Bank 2021 checking
  6. AT Raiffeisen VISA
  7. AU ANZ
  8. AU ING
  9. AU National Australia Bank
  10. BE BNP Paribas Fortis old
  11. BE BNP Paribas Fortis Export
  12. BE KBC checking
  13. BE KBC credit
  14. BE Keytrade Bank
  15. BR Banco Bradesco Checking
  16. BR Banco do Brasil, checking
  17. BR Inter, checking
  18. CA TD Canada Trust, checking+Visa
  19. CH UBS Checking account
  20. CH UBS Checking account - Alternative 1
  21. CH UBS Credit card
  22. CH Neon Monthly Account Statement
  23. CH SwissCard
  24. CH ZKB Erweiterte Suche
  25. CH ZKB Finanzassistent-Chronik
  26. CO Bancolombia
  27. Crypto.com
  28. CZ AirBank checking and savings
  29. CZ Ceska Sporitelna
  30. CZ Raiffeisen bank
  31. DE Amazon VISA LBB
  32. DE Commerzbank checking
  33. DE Consorsbank checking
  34. DE Deutsche Bank
  35. DE Deutsche Bank Credit Card
  36. DE Deutsche Kreditbank checking
  37. DE Deutsche Kreditbank checking new
  38. DE Deutsche Kreditbank credit card
  39. DE Fiducia (Volksbank, Sparda-Bank, BBBank, PSD Bank, Raiffeisen, ...)
  40. DE ING-DiBa
  41. DE Kreissparkasse
  42. DE N26
  43. DE Ostseesparkasse Rostock checking
  44. DE Ostseesparkasse Rostock credit card
  45. DE Sparkasse Rhein-Neckar-Nord
  46. DE Sparkasse Südholstein
  47. DK Bankernes EDB Central
  48. DK Danske Bank
  49. DK Jyske Bank VISA
  50. DK Nordea
  51. DK Portalbank
  52. Hibiscus banking software
  53. HU Erste Bank checking
  54. HU K&H
  55. HU OTP
  56. IE AIB Ireland
  57. IE Bank of Ireland
  58. IE First South Credit Union
  59. IE N26
  60. IE Ulster Bank, savings
  61. IT RomagnaBanca Inbank
  62. LV Swedbank
  63. Mint
  64. MV Bank of Maldives, checking
  65. NETELLER
  66. NL Bunq checking
  67. NL bunqDesktop software
  68. NL bunqDesktop software 2
  69. NL ING
  70. NL ING Checking 2020
  71. NL KNAB
  72. NL Rabobank
  73. NL Rabobank-2018
  74. NL Rabobank Credit Card
  75. NO DNB
  76. NO Sparebank 1 VISA
  77. Personal Capital
  78. PL Alior Bank
  79. PL mBank
  80. PL PKO BP
  81. Revolut
  82. SE Handelsbanken
  83. SE Länsförsäkringar checking
  84. SE Nordea - internetbanken.privat.nordea.se
  85. SE Nordea - netbank.nordea.se
  86. SE SEB Skandinaviska Enskilda Banken
  87. SE Sparbanken Tanum
  88. SE Swedbank
  89. SE Swedbank 2019
  90. SE Swedbank 2020
  91. SG OCBC Bank
  92. SG OCBC Bank Credit Card
  93. SG POSB savings
  94. SK Tatra Banka
  95. SK VUB
  96. UK Co-operative Bank
  97. UK Monzo checking
  98. UK Barclaycard credit card
  99. UK Barclaycard Business Credit Card
  100. UK first direct checking
  101. UK John Lewis Partnership Card (Pre-2022 Format)
  102. UK John Lewis Partnership Card (NewDay Format)
  103. US Bank of America
  104. US Bank of America Credit Card
  105. US BB&T
  106. US Chase Credit Card 2017
  107. US Chase Credit Card 2019
  108. US Schwab Checking
  109. US Schwab Savings
  110. US TB Bank
  111. US USAA
  112. Wise

XKCD on standards: Fortunately, the charging one has been solved now that we've all standardized on mini-USB. Or is it micro-USB? Shit.


Disclaimer: Please use at your own risk. This tool is neither officially supported by YNAB (the company) nor by YNAB (the software) in any way. Use of this tool could introduce problems into your budget that YNAB, through its official support channels, will not be able to troubleshoot or fix. See also the full MIT licence.

bank2ynab's People

Contributors

azd325 avatar cptaeons avatar dowjones-jupyterhub avatar duch11 avatar ekeih avatar eloyz avatar exaldraen avatar fwullschleger avatar github-actions[bot] avatar jakejx avatar jd1 avatar limdingwen avatar lint-action avatar m4a1x avatar mhegadorn avatar milankowww avatar mokshasoul avatar nejch avatar nielsmaerten avatar nocalla avatar pezmc avatar psmarcin avatar sambaum avatar sebrut avatar sliceolife avatar thomdietrich avatar torbengb avatar toyg avatar tradfursten avatar wooter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bank2ynab's Issues

User-defined mapping file to assign categories based on Payee pattern

Feature suggestion - obviously for a future release!

The user can provide a file that contains mapping information (format yet to be decided), primarily consisting of a Payee pattern and a master category:category; plus possibly additional information?
For each input transaction, the script would look up the Payee string in the mapping file. If a match is found, the output category is filled with the data from the mapping file.

This was directly inspired from this section:
https://github.com/jasonmadigan/aib-to-ynab#mapping-files

Very rough format idea:

"valid for [SECTION]s, or * for all sections";"input payee pattern, allows Regex or at least asterisk as wildcard";"output Payee string";"output category string"
"[AT Raiffeisen bank],[AT Raiffeisen VISA]";"paypa*";"PayPal";"Online spending:PayPal"
"*";"Spar*";"Spar";"Household:Groceries"

The input columns could be case insensitive; the output columns case sensitive.

Python 3: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdc in position 21: invalid continuation byte

Using a freshly downloaded bank file, I get this error with Python 3 (on master and also on the other branches). (discovered while testing #59)

Your specified download directory was not found: /home/torben/Downloadsx
Parsing file: elbi_umsaetze_20171025234336.csv
Using format: AT Raiffeisen Bank
Traceback (most recent call last):
  File "bank2ynab.py", line 179, in <module>
    main()
  File "bank2ynab.py", line 169, in main
    output = clean_data(file)
  File "bank2ynab.py", line 76, in clean_data
    for row in transaction_reader:
  File "/usr/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdc in position 21: invalid continuation byte

Note:

  • The file seems to be not in Unicode format but in Windows ISO-8859-1 format, at least according to Notepadqq (a Notepad++ clone for Linux).
  • The VISA statement from the same bank, same website, same time of download, is reported as UNIX/OS X UTF-8 w/o BOM format. This file has not been tested yet because the script stops after the first file (and I haven't tried to run it without the other file present yet!).

Python 2.x Support

As requested by u/fio_smiles, this may be possible. Need handling for the following main issues:

  • ConfigParser to configparser
  • csv delimiter as string, not unicode
  • csv newline invalid

Assigning myself to this issue. It's not a high importance item, but might help prevent problems if @torbengb starts accidentally using Python 2 again...

Support for Rabobank [NL]

Example row: "NL12RABO3456789012","EUR","20140318","D","3.00","","","20140318","ba","","Rest Bernoulliborg GRONINGEN","Betaalautomaat 14:42 pasnr. 004","","","","","","",""
Note date format.

[NL Rabobank]
Source Filename Pattern = transactions
Source Filename Extension = .txt
Input Columns = skip,skip,Date,Outflow/Inflow Designator,Inflow,skip,Payee,skip,skip,skip,Memo,skip,skip,skip,skip,skip,skip,skip
Plugin = Need to parse the Outflow/Inflow designator. This is reasonably common, so a general plugin for this would probably be most helpful.

Master Issue #21

Set up more formalized tests

Apart from our manual testing with random files, @toyg suggested in #54 a more structured approach.

I welcome the idea but I'm not sure how to do it - from what I've seen, GitHub has several useful features built in, but it does require some effort to set up. I don't want to impose a lot of overhead on this little project of ours, so once more it boils down to "is it worth the effort?" Certainly a subjective measure, and I will be last person to object or stand in the way if you want to go ahead with it.

Let's investigate options, benefits, and required effort?

Need to document dependencies

As mentioned in issue #5 it would be useful to have a central list of required modules, or dependencies. Apparently Python doesn't support the "package.json" format but there are other interesting solutions that make dependencies easy to handle.

Of course a there's a relevant Stack Overflow answer :-) but seems like this alternative would create a requirement file that contains only what the specified project needs - and skip other irrelevant bits we might have in our local environment.

(This idea was sparked mainly by the Github notification about dependencies.)

Support for more complex formats

There is a question of how much we can actually stretch the current approach of just reordering a few fields. For example, I'm looking at https://github.com/JamesBelchamber/ynab-jlp-csv-converter/blob/master/convert.py and apparently that bank (JLP) does not have different columns for Inflows and Outflows, but rather a single column for values that are marked as CR in another field when it's a credit. This is literally the first random script I picked from the list, chances are that there are loads of these. Special-casing this sort of thing will only get us so far.

What about adding the possibility of loading a different class that will do the record parsing and will then provide an iterator returning the necessary format? That way we can deal with untractable special cases in dedicated modules.

I'm thinking we could have a modules subfolder that contains, for example, a jlp.py file with some sort of class that provides a standard interface. Then in the config file the user could specify an option like Parsing Module = jlp. If the option is specified, the code will load the module and hand over parsing to it, expecting to get back an iterator that we can use with csv; otherwise, we do the regular parsing (in fact, we could have a default.py module that holds default parsing logic, shortening the main script). This is pretty easy in Python 3 with a bit of importlib magic, and I'm pretty sure there is a Python2 equivalent too.

As well as dealing with difficult special cases, this could potentially open the door to supporting pretty much any file format, not just csv.

Branching strategy?

So far we (well, you!) have been very good and diligent about doing changes in feature-specific branches. (I haven't been as diligent, but luckily my inputs have been mostly testing and documentation so I don't feel too guilty.)

Anyway, I've been thinking about terms like "versions" and "releases". As long as all our efforts flow back into master, I'm not sure we can ever say we have a stable release point?

You're probably aware of several different strategies. I happen to like this one and put it to you as a question: should we think about having a branching strategy? Which one? This one I suggested (cheat sheet here), or some other?

Support for JLP [UK]

Plugin created. Needs further follow-up to get test file.

@toyg has a plugin for this in the JLP branch.

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

Script doesn't like Umlauts: üöäÜÖÄßæøåÆØÅ

My testing showed that the script stops at line 71 'transaction_data = list(transaction_reader)' if the file contains special characters like üöäÜÖÄßæøåÆØÅ. Shouldn't the whole Unicode business already take care of umlauts?

The error message on the console is:

Trying format:  Raiffeisen Bank
Parsing file:  elbi_umsaetze_20171018213618.csv
Traceback (most recent call last):
  File "./transaction_csv_cleanup.py", line 160, in <module>
    main()
  File "./transaction_csv_cleanup.py", line 152, in main
    output = clean_data(file)
  File "./transaction_csv_cleanup.py", line 70, in clean_data
    transaction_data = list(transaction_reader)
  File "/usr/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdf in position 3101: invalid continuation byte

When I replace all umlauts in the test file 'elbi_umsaetze_20171018213618.csv' then this error goes away.

Workaround: open the file in Notepad and use search&replace to remove the special characters. (Yes this sucks, we're working on it!)

[Optimisation] Bring existing code into line with PEP8

The following issues were flagged in the main script by pycodestyle.py. It's probably worth looking at these for the purpose of readability as the code grows more complex.
This is based off the test-prep branch as it stands currently (which I think needs to be merged into master, as I mentioned in #77.).
EDIT 2: Obviously we'll need to do this every now and then, but I've brought the existing code in the core up to standard anyway. Closing this.

EDIT: Worked through these, so moved them below this line.

  • bank2ynab.py:311:80: E501 line too long (102 > 79 characters)
  • bank2ynab.py:328:80: E501 line too long (99 > 79 characters)
  • bank2ynab.py:133:80: E501 line too long (86 > 79 characters)
  • bank2ynab.py:32:1: E402 module level import not at top of file
  • bank2ynab.py:33:1: E402 module level import not at top of file
  • bank2ynab.py:34:1: E402 module level import not at top of file
  • bank2ynab.py:35:1: E402 module level import not at top of file
  • bank2ynab.py:99:80: E501 line too long (85 > 79 characters)
  • bank2ynab.py:218:80: E501 line too long (93 > 79 characters)
  • bank2ynab.py:220:80: E501 line too long (98 > 79 characters)
  • bank2ynab.py:219:80: E501 line too long (101 > 79 characters)
  • bank2ynab.py:217:80: E501 line too long (92 > 79 characters)
  • bank2ynab.py:216:80: E501 line too long (86 > 79 characters)
  • bank2ynab.py:214:80: E501 line too long (95 > 79 characters)
  • bank2ynab.py:213:80: E501 line too long (97 > 79 characters)
  • bank2ynab.py:212:80: E501 line too long (95 > 79 characters)
  • bank2ynab.py:104:80: E501 line too long (113 > 79 characters)
  • bank2ynab.py:105:80: E501 line too long (119 > 79 characters)
  • bank2ynab.py:106:80: E501 line too long (115 > 79 characters)
  • bank2ynab.py:107:80: E501 line too long (115 > 79 characters)
  • bank2ynab.py:108:80: E501 line too long (116 > 79 characters)
  • bank2ynab.py:109:80: E501 line too long (112 > 79 characters)
  • bank2ynab.py:110:80: E501 line too long (115 > 79 characters)
  • bank2ynab.py:111:80: E501 line too long (119 > 79 characters)
  • bank2ynab.py:112:80: E501 line too long (112 > 79 characters)
  • bank2ynab.py:113:80: E501 line too long (117 > 79 characters)
  • bank2ynab.py:114:80: E501 line too long (104 > 79 characters)
  • bank2ynab.py:122:80: E501 line too long (86 > 79 characters)
  • bank2ynab.py:282:80: E501 line too long (141 > 79 characters)
  • bank2ynab.py:296:80: E501 line too long (99 > 79 characters)
  • bank2ynab.py:89:80: E501 line too long (81 > 79 characters)
  • bank2ynab.py:276:13: E722 do not use bare except'
  • bank2ynab.py:86:37: E128 continuation line under-indented for visual indent
  • bank2ynab.py:87:37: E128 continuation line under-indented for visual indent

Support for Hypovereinsbank [DE] - Missing filename

Sourced from andsens/ynab-csv-converter.

Row format: 'account_no', 'date', 'txn_date', 'payee1', 'payee2', 'text','amount', 'currency'

Unclear if header is present.

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Input Columns = skip, Date, skip, Payee, Memo, Inflow, skip

From Issue #21 master list

Support for Sparkasse [DE]

Sourced from ma-ver-ick/ynab-converter.

File layout:
Sparkasse
Auftragskonto, Buchungstag, Valutadatum, Buchungstext, Verwendungszweck, Beguenstigter/Zahlungspflichtiger, Kontonummer, BLZ, Betrag, Waehrung, Info

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

From Issue #21 master list

Add import formats from other projects

I noted that there are nearly 90 YNAB CSV projects. I want to contact each of them and ask for their CSV format. This ticket is my reminder to do that.

Edit 1: Here's a checklist in alphabetical order of all the repositories I've found (source / recent). Checked off when I have analysed them.
Edit 2: @nocalla added some subheadings to try make this list a bit more comprehensible. Try to make headings for scripts for specific banks if there are duplicates, as this will be the most efficient way for us to incorporate individual banks. Create an issue for each identified bank and use the bank format label to track - link the issue number back to the relevant entry on this list.
Edit 3: @nocalla has changed the checkmarks to mean that they have been made into an issue

I am adding the formats to our survey. (Results are here.)

Issue Created

Link to relevant issue search

To Be Sorted

Irrelevant/Empty/No bank specified

Already Supported

chatgroup

I think it could be worth having a chatgroup somewhere to coordinate in realtime. Last night I was almost undone by not realizing @nocalla was pushing to the same branch I was working on.

I’m happy with anything you guys like - telegram, whatsapp, irc...

Rename filenames to match project name?

Would it be helpful to rename the script from transaction_csv_cleanup.py to bank2ynab.py, and the config file from config.conf to bank2ynab.conf?

I believe it would help "the project" because it creates a direct correlation between the project name and the script name (like MS Excel is also called excel.exe). It would also be handy because users (me!) could put the script and config in the user-home directory or anywhere else that is already in the path, and avoid having to cd to the script location first or precede the command with the script path.

If you agree I could do the simple pull, but these are your file names so I don't want to steamroll over your choices, hence this question for your consideration.

Date parsing

Looking at the various converter scripts, one of the recurring conversions that have to be done is date parsing. Some banks use '-' as separator, some (for example Rabobank ) have no separator at all...

Python already has syntax for date parsing, so we should probably just have an optional parameter to surface it when necessary.

Date formats accepted by YNAB are documented here.

Brainstorm: what config parameters do we need?

To kick things off, I'll start with these. I've tried to sort them in a sort of chronological order:

  • nickname for this configuration (so people can have several)
  • download from bank (boolean)
  • download from bank URL
  • bank login
  • bank auth1
  • bank auth2
  • downloaded file path (like "/home/username/Downloads/")
  • downloaded filename pattern (like "bank_export_*")
  • downloaded filename extension (like ".csv")
  • downloaded file CSV delimiter character (like "," or ";")
  • downloaded file has column headers (boolean)
  • downloaded file column names and column order
  • convert (boolean)
  • converted file filename pattern (prefix like "fixed_")
  • converted file filename pattern (suffix like "_fixed")
  • converted filename extension (like ".csv")
  • remove downloaded file after conversion (boolean)

We need a user guide

  • how to get the script working
    • how to install required modules
    • how to modify the config file
    • how the script detects one or more config files, and how it finds the correct config section
    • how to take advantage of the bank formats included in the project

(see #4 (comment) for a starting point)

Config file search pattern is too simple

Situation:

  • The check currently looks in the script directory for any file that endswith(".conf") (line 156). What is the reason for this choice of search pattern?

Problem:

  • No error appears if the actual bank2ynab.conf is missing, if foo.conf is present.
  • The search pattern would also find a file named foo.conf or even one named dont_use_this_bank2ynab.conf.
  • These files would be found even if the actual bank2ynab.conf is present. Which one would then be used?

Suggestion:

  • Search for the exact config file bank2ynab.conf.

Output file has an extra \n character between each line on windows

This looks like a manifestation of the handling of Windows files outlined here,

Be careful using codecs.open() to read files on Windows. The docs say: """Note Files are always opened in binary mode, even if no binary mode was specified. This is done to avoid data loss due to encodings using 8-bit values. This means that no automatic conversion of '\n' is done on reading and writing.""" This means that your lines will end in \r\n and you will need/want to strip those off.

Support for Nordea [DK,SE]

Sources:

2017-10-23,Kortköp 171019 GOG COM,,"-119,00","1.000,99"

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

FileNotFoundError when trying to write output file where file doesn't exist yet

python bank2ynab.py
Format: IE Bank of Ireland
Can't find: c:\users\example-username\Downloads
Trying: D:\Users\nocalla\Downloads
Parsing file: test_BOI_TransactionExport (2).csv
Parsed 28 lines
Writing file: fixed_test_BOI_TransactionExport (2).csv
Traceback (most recent call last):
File "bank2ynab.py", line 341, in
main()
File "bank2ynab.py", line 330, in main
write_data(file, output)
File "bank2ynab.py", line 280, in write_data
with CrossversionCsvWriter(new_filename, __PY2) as writer:
File "bank2ynab.py", line 44, in init
self.encoding = detect_encoding(self.file_path)
File "bank2ynab.py", line 110, in detect_encoding
with codecs.open(filepath, "r", encoding=enc) as f:
File "C:\Users\nocalla\AppData\Local\Programs\Python\Python35-32\lib\codecs.py", line 895, in open
file = builtins.open(filename, mode, buffering)
FileNotFoundError: [Errno 2] No such file or directory: 'D:\Users\nocalla\Downloads\fixed_test_BOI_TransactionExport (2).csv'

Python 2: CSV not working with non-ascii characters

As sourced from @toyg:

Ok, I did some more testing and there is still an outstanding issue with csv not working properly in py2 when source data contains non-ascii characters, regardless of how source or target files are opened and regardless of unicode_literals (which I'd rather stay away from, anyway, since it changes a lot of things behind the scenes in py2).

This is even mentioned halfway through the examples, providing a solution (the UnicodeWriter class) that is fugly but will probably work. I'll have a look online for alternatives.

Prerequisite before sorting Pull #56

Support for Barclaycard [DE]

Sourced from ma-ver-ick/ynab-converter.

File layout:
Barclaycard Germany
Buchung/ Valuta, Belegdatum, Beschreibung, Kartennummer, Karteninhaber, Betrag

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

From Issue #21 master list

Use payee for memo if no existing memo

I'll change how my payee swap thing works to just use payee info only if memo is blank or there's no memo column. I think this is logical behaviour for a default setting and doesn't really need a switch on the configuration. Thoughts?

Support for Amex [International?]

Sourced from akirayamamoto/amexcleaner

Input (no header):
# Date, Description, Amount, Bill Start Date
29/06/2012,Outflow description,R$ #.###,##, 01/06/2012
30/06/2012,Inflow description,- R$ #.###,##, 01/06/2012

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

From Issue #21 master list

check if config file exists

Also found in Scottrobertson's code:

def perform_request(path)
  raise 'Cannot find config file' unless File.exists?(config_path)

Support for Purdue Federal [US]

Sourced from wesmcouch/Purdue-Federal-You-Need-A-Budget-Converter-YNAB-.

if row[1].include? '(Pending)' # Do not include pending transactions in the import
		next
	end
	
	if row[4][0].chr == '(' # Move outflows and inflows to proper columns
		datLength = row[4].length
		datLength = datLength - 2
		row[4] = row[4][1, datLength]
		row[5] = ""
	else
		row[5] = row[4]
		row[4] = ""
	end

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

From Issue #21 master list

[Feature] template filename

This is a feature request, absolutely optional and not urgent, but there you go.

It would be cool to actually put in some logic to allow for templates from source filenames. What I mean is:

  • UK Cooperative bank (and Smile online bank) generate csv files called XXXXXX_ZZZZZZZZ_YYYY_MM_DD.csv, where XXXXXX is the bank sort code, ZZZZZZZZ is the account number, and YYYY_MM_DD is the date when the file was generated.

  • it would be cool if bank2ynab could understand these info, even superficially. This would probably help in any future feature that involves automatic uploading, since it might make it easier to target this or that account.

Push transactions into YNAB programmatically

Scott Robertson has a method to push transactions into YNAB programmatically.

  • Can we incorporate that into our script, in order to eliminate the manual step of drag-and-dropping the output CSV file?

If we can do that, we could all but automate the entire process, like he has done. Manually donwload a CSV file (possibly automate this later, for US/UK), then run bank2ynab which then auto-converts, auto-imports, and removes the original CSV and the converted CSV file.

source: https://github.com/scottrobertson/fintech-to-ynab#csv-imports:

You can import a CSV directly into YNAB via the CLI. To do so, please use the following:
python python/import.py --account=AccountName --path=/path/to.csv
The format should be: date, description, amount

Support for Handelsbanken [SE]

Hi, I got a request from @toyg to add this issue here since you were looking for more formats with input examples to add to this project.

This is about support for Handelsbanken, a Swedish bank.

The file extension is .xls, but the content of the file is HTML. See attached file for input example. Note that the actual data is anonimised, so the math does not add up.

kontotransactionlist.txt
(The attached file has extension .txt since it's not allowed to attach .xls files on github, but the real file should be .xls)

Since the format is unconventional you will probably need a plugin. I created a converter some time ago which may help: https://github.com/joacand/HandelsbankenYNABConverter

It's just a quick script and it probably needs be improved and changed to fit this project. You are free to use the code in any way you see fit.

Edit from Nocalla (tentative config 15/02/2018)
[SE Handelsbanken]
Source Filename Pattern = kontotransactionlist
Source Filename Extension = .xls
Input Columns = skip,Date,Payee,Inflow,skip
Source CSV Delimiter = ;
Header Rows = 7
Plugin = handelsbanken

From Issue #21 master list

[Feature] skip records in file

Script language: Python2.7
Operating system: Windows
OS Version: 10

Request:
I'd like to be able to specify a switch in the config to remove non-transaction data from being written into my import file.

Background:
One thing that my bank puts into the records is when interest rates change, etc, and this gives records which I end up deleting prior to or after import, if I withdraw from an ATM either I get a second row of identifying information which is irrelevant for YNAB.

Approach idea:

  • add a switch into the config
  • add a test condition into the writer (I've done this locally in a version I can play with and try to push if of interest) which checks for input and output blanks in the row
  • bypass the writing of the row if it's a non-transaction

Thoughts?

Separate default config file from users' actual configuration

Situation:
Users (including ourselves) make changes to the bank2ynab.conf file, not least in order to specify our personal preference for the download directory.

Problem:
Having a user-modified local config file conflicts with the config file of the package because it has the same name.

Solution suggestion:
We could deliver the config file as bank2ynab.conf.txt and require the user to actively rename or copy it to bank2ynab.conf in order to activate it. That would be part of the user guide / installation instructions and could also be checked by the suggested validate() function.
This would allow us to maintain a true "package version" while allowing users to hold local preferences in their own actual copy.

Drawback:
When a user downloads an updated release, he must actively merge the changes in the new bank2ynab.conf.txt into his existing bank2ynab.conf.

The drawmack carries a risk of mistakes, but the benefit of content separation could make it worth it. Thoughts?

Support for Danskebank [DK]

Sourced from andsens/ynab-csv-converter.
Also trahkoi/ynab-danske-csv.

Row format: 'date', 'text', 'amount', 'balance', 'status', 'cleared'

Unclear if header is present.

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

From Issue #21 master list

configparser.NoOptionError: No option 'plugin' in section: 'AT Raiffeisen Bank'

Script language: Python2 and Python3
Operating system: Linux
OS Version: Ubuntu 16.04 LTS

What did you DO? (steps to reproduce)
grabbed bank2ynab.py from master, then ran it once with py2 and once with py3.

What did you EXPECT to happen?
successful conversion.

What ACTUALLY happened?
Error using py2:

Traceback (most recent call last):
  File "bank2ynab.py", line 451, in <module>
    b2y = Bank2Ynab(get_configs(), __PY2)
  File "bank2ynab.py", line 423, in __init__
    bank_config = fix_conf_params(config_object, section)
  File "bank2ynab.py", line 231, in fix_conf_params
    config[key] = get_config_line(conf_obj, section_name, config[key])
  File "bank2ynab.py", line 245, in get_config_line
    line = conf_obj.get(section_name, param)
  File "/usr/lib/python2.7/ConfigParser.py", line 618, in get
    raise NoOptionError(option, section)
ConfigParser.NoOptionError: No option 'plugin' in section: 'AT Raiffeisen Bank'

Error using py3:

Traceback (most recent call last):
File "/usr/lib/python3.5/configparser.py", line 786, in get
value = d[option]
File "/usr/lib/python3.5/collections/init.py", line 878, in getitem
return self.missing(key) # support subclasses that define missing
File "/usr/lib/python3.5/collections/init.py", line 870, in missing
raise KeyError(key)
KeyError: 'plugin'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bank2ynab.py", line 451, in <module>
    b2y = Bank2Ynab(get_configs(), __PY2)
  File "bank2ynab.py", line 423, in __init__
    bank_config = fix_conf_params(config_object, section)
  File "bank2ynab.py", line 231, in fix_conf_params
    config[key] = get_config_line(conf_obj, section_name, config[key])
  File "bank2ynab.py", line 245, in get_config_line
    line = conf_obj.get(section_name, param)
  File "/usr/lib/python3.5/configparser.py", line 789, in get
    raise NoOptionError(option, section)
configparser.NoOptionError: No option 'plugin' in section: 'AT Raiffeisen Bank'
  • I do not understand what the option 'plugin' means. There is no config parameter containing that word.
  • I also noted that the line Use Payees for Memo was removed from the default section in .conf in master. I would say that's a mistake and it should come back (default FALSE). Right?

Support for Nordnet [SE]

Sourced from andsens/ynab-csv-converter.

Row format: 'line_id', 'bogf_date', 'trns_date', 'val_date', 'trns_type','stock_name', 'instr_type', 'isin', 'quantity', 'price','interest', 'fee', 'amount', 'currency', 'buy_price','result', 'total_qty', 'saldo', 'exch_rate', 'trns_text','shred_date', 'verification_number',

Unclear if header is present.

To be filled in as required. Delete fields that match default values.
Source Filename Pattern = example_transaction_export_filename
Source Filename Extension = .csv
Use Regex for Filename = False
Source CSV Delimiter = ,
Source Has Column Headers = True
Input Columns = Date,Payee,Outflow,Inflow,Running Balance
Plugin =

From Issue #21 master list

We need some starting code!

I nominate my handsome script as a starting point! In all seriousness though, your idea of a universal config file is a good one. So if we each add our individual script and adapt it for a config maybe we can merge scripts then?

newline = "" only works on Windows

Line 111:

I've looked things up and it seems that the 'open()' call should be replaced with an 'io.open()' call instead. I believe the reason is that 'open()', on Linux, does not have the 'newline' parameter (not even in my up-to-date version '3.5.1-3'). (source, source)

Using 'io.open()' requires an import of 'io' in line 20, which in turn requires 'io' to have to be installed first using 'sudo python -m pip install unicodecsv').

But using 'io.open()' gives me all kinds of follow-up troubles, so that can't be it either. I also found sources that suggested importing 'unicodecsv' instead of 'csv' because that handles things nicer, but that too became too hairy for a Python novice as I am.

Another suggestion (and another) was to code myself out of the parameter problem while staying with the normal 'open()' but I couldn't make it work:

#    with open(new_filename, "w", newline = "") as file:
    if os.name is "nt": newlinefoo = {'newline':''}
    else: newlinefoo = {}
    with open(new_filename, "w", newlinefoo) as file:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.