Skip to content

Commit

Permalink
migrated Apple Script to Python for easier maintenance
Browse files Browse the repository at this point in the history
  • Loading branch information
ma4nn committed Jan 4, 2024
1 parent 85c12f0 commit 1273608
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 193 deletions.
55 changes: 24 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,43 @@
# MoneyMoney Extension: Sum by Bank

This is an AppleScript extension for the great [MoneyMoney software](https://moneymoney-app.com/) to generate an Excel list with all sums by bank account.
This is a Pyton script for the great [MoneyMoney software](https://moneymoney-app.com/) to generate a list with all balances by bank account.
This is useful e.g. to export the total values per bank to a summary Excel document or to monitor certain threshold values per bank.

## Installation

For this AppleScript to work it is required to add a custom attribute `bankIdentifier` to each account in MoneyMoney
that you want to track. The total values are then summed up by this chosen bank identifier.
```
pip install -r requirements.txt
```

At the beginning of the Apple Script file `moneymney-sum-by-bank.scpt` you can then customize the behaviour of the script:

|Variable|Description|
|--------|-----------|
|`exportFileName`|The name of the resulting Excel file. You can either use an existing file or leave it to missing value to create a new one.|
|`startRowIndex`/`startColumnIndex`|The index of the cell row/column to start the table.|
|`isSortDescending`|Whether to sort the resulting sums in a descending order or not.|
|`isCloseExcel`|Whether to close Excel after the export.|
|`cellThresholdValue`|Threshold value above that the cell is colored|
|`cellThresholdColor`|Threshold background color value|

If you optionally want to use this AppleScript within the services menu of the _MoneyMoney_ application, the best way is to use the [Mac Automator](https://support.apple.com/de-de/guide/automator/aut73234890a/mac):
On Mac if you (optionally) want to use this Python script within the services menu of the _MoneyMoney_ application, the best way is to use the [Mac Automator](https://support.apple.com/de-de/guide/automator/aut73234890a/mac):
1. Create a new "Quick Action Workflow" in Automator
1. Choose "No Input" in "MoneyMoney"
1. Add the action "Execute AppleScript" and paste the contents of the file `moneymoney-sum-by-bank.scpt` into the text box
1. Save the workflow
2. Choose "No Input" in "MoneyMoney"
3. Add the action "Execute AppleScript" and paste this script into the text box and adapt the script path accordingly:
```applescript
on run {input, parameters}
tell application "Terminal"
do script "python3 ~/path/to/script/moneymoney-sum-by-bank.py && read -s -n 1 key && exit 0"
end tell
return input
end run
```
4. Save the workflow

Then you have a new menu item with the chosen name in _MoneyMoney > Services_.

## Usage

After click on the new menu item in _MoneyMoney > Services_, Microsoft Excel will open and show all bank sums in a descending order:
![Excel file with sums by bank account](moneymoney-sum-by-bank.png "Excel file with sums by bank account")

As an alternative you can also simply double click on the `moneymney-sum-by-bank.scpt` script to execute it manually.
**Note:** The MoneyMoney application has to be unlocked when executing the script otherwise an error will be thrown.

For more information see also [my blog post](https://dev-investor.de/finanz-apps/money-money/maximum-pro-bank-extension/).

## Notes
This Python script sums all account balances from MoneyMoney by BIC. If a BIC is not available (e.g. in case of an offline or a credit card account),
the script looks for a custom attribute `bankIdentifier` in the account settings and uses this as reference.
If neither of this information is available on the account and it has a balance, the value is added to "other".

- Tested with Excel for Mac 16.43/16.64
- The MoneyMoney application has to be unlocked when executing the script otherwise an error will be thrown
- Basically a better way would be to automatically group by account bic but not all accounts do have a bic (e.g. credit cards).
The result of the Python script can e.g. be used in Excel:
![Excel file with sums by bank account](moneymoney-sum-by-bank.png "Excel file with sums by bank account")

## Known Limitations
- Support only for Euro currency
- Accounts with no `bankIdentifier` attribute are ignored in export file
For more information see also [my blog post](https://dev-investor.de/finanz-apps/money-money/maximum-pro-bank-extension/).

## License

Expand Down
49 changes: 49 additions & 0 deletions moneymoney-sum-by-bank.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pandas as pd
import plistlib
import subprocess
import logging


def run_apple_script(script):
command = ['osascript', '-e', script]
with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as pipe:
result = pipe.communicate()
if result[1]:
raise Exception('Could not run Apple Script: %s' % result[1].decode().strip())

return result


# @see https://moneymoney-app.com/applescript/
def fetch_moneymoney_accounts() -> {}:
result = run_apple_script('tell application "MoneyMoney" to export accounts')

# Parse XML property list.
try:
plist = plistlib.loads(result[0])
except plistlib.InvalidFileException as exception:
raise Exception('Could not parse XML property list. %s' % repr(exception))

return plist


def moneymoney_sum_by_account() -> pd.DataFrame:
balance_per_bank_and_currency = []
for account in fetch_moneymoney_accounts():
if account['portfolio'] is True or account['group'] is True:
continue

if not account['bankCode']:
account['bankCode'] = account['attributes']['bankIdentifier'] if 'bankIdentifier' in account['attributes'] else 'other'
logging.debug("Account %s has no bank code, using '%s'" % (account["name"], account['bankCode']))

for balance in account['balance']:
balance_per_bank_and_currency.append([account['bankCode'], balance[0], balance[1]])

df = pd.DataFrame(balance_per_bank_and_currency, columns=['bank', 'balance', 'currency'])
return df.groupby(['bank', 'currency']).agg({'balance': 'sum'})


#logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
df = moneymoney_sum_by_account()
print(df[df['balance'] > 0].sort_values(by='balance', ascending=False))
162 changes: 0 additions & 162 deletions moneymoney-sum-by-bank.scpt

This file was deleted.

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pandas

0 comments on commit 1273608

Please sign in to comment.