spliit-app / spliit

Free and Open Source Alternative to Splitwise. Share expenses with your friends and family.
https://spliit.app
MIT License
642 stars 111 forks source link

Import from Splitwise #22

Open rgov opened 6 months ago

rgov commented 6 months ago

Splitwise offers an "Export as spreadsheet" feature. It would be useful to be able to import this data into Spliit for continuity of groups that were created before.

Splitwise exports CSV files with the following headers:

Date Description Category Cost Currency UserA UserB ...

Values in the User columns are calculated as (Paid - Owe). For example, if UserA paid $100 for an item whose cost was split evenly, UserA's entry would be $100 - $50 = $50 and UserB's would be $0 - $50 = -$50.

Date Description Category Cost Currency UserA UserB
2024-01-01 Something General 100.00 USD 50.00 -50.00

The final row is the total balance per user, which is the column sum for that user. There is no need to import this, but for the record, a positive value represents that the user "gets back" some amount, whereas a negative value represents that the user "owes" the amount.

This would require #6, at least the ability to split unevenly by dollar amount.

I'd suggest matching users by column name and error if a match isn't found; it's very easy to edit the CSV file if the name needs to be changed, no need to create new UI for it.

ChristopherJohnston commented 5 months ago

I have the beginnings of an implementation as a script here: https://github.com/ChristopherJohnston/spliit2/blob/splitwise-import-2/src/scripts/import.ts (use npx ts-node ./src/scripts/import.ts to run)

This was created before the recent uneven split addition, and also assumes implementation of expenseDate and categories per my recent PRs....I'll update it accordingly once these are done.

I was able to match balances on a split wise group that has ~2800 lines in the export (granted this is a group of 2 participants where all of the expenses are equal split)

This script would require hosting your own instance of the app but could probably be used as part of a future "create group from csv" implementation

scastiel commented 5 months ago

I love this! It shouldn’t be too hard to develop a MVP of an import feature (e.g. assuming that the user names match exactly). @ChristopherJohnston tell me if you’re interested to work on such a feature, otherwise I’ll take care of it 😃

ChristopherJohnston commented 5 months ago

if the import was done as part of a group creation then we wouldn't need to have matching names - the group participants would be taken from the csv.

eg.

create group -> enter group name -> select csv file -? submit

new group, participants and expense history is created from CSV

ChristopherJohnston commented 5 months ago

@ChristopherJohnston tell me if you’re interested to work on such a feature, otherwise I’ll take care of it 😃

I'm not particularly skilled at the UI part, so the file upload part would probably slow me down somewhat!

ChristopherJohnston commented 5 months ago

The export is essentially a ledger so some of the information about how the expense was split is lost. It's possible to infer but not sure if this is always going to be correct.

A few hurdles I've seen so far:

Splitwise allows multiple payees for an expense which is shown as a positive number for each participant who made a payment and does not owe and a negative number for each participant who owes.

E.g

Participant A and B pay 75 each for an expense split equally between 3:

Total: 150 ParticipantA: 25 ParticipantB: 25 ParticipantC: -50

Expenses with costs that are Odd numbers (eg 1.55 paid by A, split between 2 participants) are sometimes split unevenly (A=0.78, B=-0.77), sometimes rounded up (A=0.78, B=-0.78), sometimes rounded down (A=0.77, B=-0.77)

Sometimes the expense amount is more than the total split. E.g £100 bill paid by A, split £90 of that evenly between 2 participants (A=45, B=-45)

I'm sure there are some others I haven't seen yet.

rrbadiani commented 4 months ago

In cases like above where multiple payees have net positive contribution in a transaction we will need to either create multiple entries or we will require the support for multi-payer feature #14

ChristopherJohnston commented 4 months ago

Import script here: https://gist.github.com/ChristopherJohnston/a6e69bd8894f20ecfe127fa4149bd013

This is not going to be exact - rounding differences will accumulate. That said, I have a ~3000 row, 2-participant export tying out to within around £0.10.

webzit commented 4 months ago

Many thanks for the script. Sadly I am using the Docker image and so as I understand it I can't run it (as the Docker image only contains the runtime bin -right?). Looking forward to this being implemented soon to finally be able to switch from Splitwise. 🎉

ChristopherJohnston commented 4 months ago

Many thanks for the script. Sadly I am using the Docker image and so as I understand it I can't run it (as the Docker image only contains the runtime bin -right?). Looking forward to this being implemented soon to finally be able to switch from Splitwise. 🎉

If you download the source code and point to the db used by the container then you should be able to run the script to achieve your goal

webzit commented 4 months ago

Thank you very much. That worked well! I just had to (i) set the environment variables ("export POSTGRES_PRISMA_URL=postgresql://postgres:${POSTGRES_PASSWORD}@192.168.0.99", ...) (ii) change my splitwise account to English, as "Payment" is otherwise "Zahlung", and (iii) remove all the empty lines in the csv file as well as the last line.

A total of 635 lines and only a difference (due to rounding) to splitwise of 0.02€ that's awesome. 🎉🎉🎉

victormihalache commented 3 months ago

Given that this will add the import logic, would it also be possible to make it so one could import from Spliit's own JSON file?

ChristopherJohnston commented 3 months ago

Given that this will add the import logic, would it also be possible to make it so one could import from Spliit's own JSON file?

this should probably be tackled first. Splitwise import is a bit more tricky.