MoneyMoney kann mit Extensions erweitert werden, zur Weiterverarbeitung in anderen Anwendungen zu exportieren. Diese Extensions sind kurze Lua-Skripte, die einfach zu erstellen, zu modifizieren und auszuwechseln sind. Das Skript des CSV-Exports steht für eigene Anpassungen als Open-Source zur Verfügung. So lässt sich der CSV-Export durch Modifikation dieses Skripts bis ins Detail konfigurieren. (Download) Die Lua-Skripte werden in einer virtuellen Maschine ausgeführt und kommunizieren über eine dokumentierte API mit MoneyMoney. Das vorliegende Dokument spezifiziert diese API. Die Wahl der Skriptsprache fiel auf Lua, da sie relativ leicht zu erlernen ist und sich gut mit C/C++/Objective-C kombinieren lässt. Für unsere Extensions reicht es vollkommen aus, die ersten fünf Kapitel von »Programming in Lua« gelesen zu haben. Die meisten innerhalb einer Extension aufgerufenen Funktionen sind nämlich gar nicht Bestandteil von Lua, sondern existieren ausschließlich in MoneyMoney. Das Verzeichnis, in dem eigene Extensions abgelegt werden, kann über Menü Fehlermeldungen werden im Protokoll-Fenster von MoneyMoney angezeigt. Das Protokoll-Fenster lässt sich mit der Menüfunktion »Fenster« → »Protokollfenster« erreichen. Jede Änderung an Dateien in diesem Verzeichnis wirkt sich unmittelbar auf MoneyMoney aus, d.h. es ist nicht nötig, MoneyMoney neu zu starten. Ein Skript weist sich als Export-Extension aus, indem es am Beginn des Skripts einen Aufruf der Art enthält. Bei den benannten Parameter der Funktion Die Parameter der Funktion Die Variablen Die Ausgabe der Standard-Funktion Die Standard-Funktion Das Skript selbst muss UTF-8-kodiert sein und es werden auch alle Strings als UTF-8-Strings zwischen dem Skript und MoneyMoney übergeben, außer es steht in der API-Beschreibung, dass es sich um Binärdaten handelt. MoneyMoney treibt die Ausführung des Skripts, was bedeutet, dass jedes Skript bestimmte Funktionen als Einsprungspunkte zur Verfügung stellen muss. MoneyMoney ruft zum Umsatzexport folgende Funktionen des Skripts auf: Es wird das einfache I/O-Modell von Lua verwendet: Das Skript braucht die Daten bloß mit Diese Funktion schreibt den Dateianfang: Parameter: Mögliche Rückgabewerte: Diese Funktion schreibt die Umsätze eines Buchungstags in die Datei: Parameter: Mögliche Rückgabewerte: Diese Funktion schreibt das Dateiende: Parameter: Table Mögliche Rückgabewerte: Folgende Vorlage kann als Ausgangspunkt für eigene Export-Extensions dienen. Die Informationen eines Konto werden in einer Lua-Tabelle gespeichert. Folgende Felder sind definiert: Die Daten eines Umsatzes werden in einer Lua-Tabelle gespeichert. Die Felder orientieren sich an SWIFT MT-940/MT-942: Erzeugt ein neues Objekt mit Informationen zu einer Bank. Um den richtigen Nummernkreis zu wählen, wird die globale Variable Parameter: String Beispiel: Die Informationen zu einer Bank werden in einer Lua-Tabelle gespeichert. Derzeit gibt es nur ein einziges belegtes Feld: Mit dieser Funktion kann ein Text übersetzt werden. Diese Funktion ist primär für die mit MoneyMoney ausgelieferten Extensions gedacht. Sie ist ein Wrapper für die Cocoa-Funktion Parameter: String Rückgabewert: String Lokalisiert eine Zeitangabe. Da die von Lua unterstützten POSIX Locales innerhalb von macOS-Apps nicht zur Verfügung stehen, baut diese Funktion auf der Cocoa-Klasse Parameter: Rückgabewert: String Lokalisiert eine Zahl. Da die von Lua unterstützten POSIX Locales innerhalb von macOS-Apps nicht zur Verfügung stehen, baut diese Funktion auf der Cocoa-Klasse Parameter: Rückgabewert: String Lokalisiert einen Währungsbetrag. Parameter: Rückgabewert: String Konvertiert einen Text von UTF-8 zu einem anderen Zeichensatz. Parameter: Rückgabewert: Binary Konvertiert einen Text von einem anderen Zeichensatz zu UTF-8. Parameter: Rückgabewert: String MoneyMoney Export API Für Entwickler, Stand 31.10.2022
Einführung
Vom Skript zur Extension
Installation
Hilfe
→ Zeige Datenbank im Finder
im Finder geöffnet werden:~/Library/Containers/com.moneymoney-app.retail/Data/Library/Application Support/MoneyMoney/Extensions
Registrierung einer Extension
Exporter{version = 1.00,
format = "Custom CSV file",
fileExtension = "csv",
description = "Export transactions as custom CSV file"}
Exporter
handelt es sich um:
version
: Versionsnummer der Extensionformat
(optional): Bezeichnung des Dateiformats, wie sie in der Formatauswahl des Datei-Speichern-Dialogs angezeigt wirdfileExtension
(optional): DateinamenserweiterungbundleIdentifier
(optional): Wenn dieser Parameter mit dem Bundle-Identifier einer installierten App belegt ist, wird die App im Menü »Sende Umsätze an« gelistet.hidden
(optional): Wenn dieser Parameter mit true
belegt ist, wird diese Extension nicht im Auswahldialog für den manuellen Umsatzexport angezeigt. Standardmäßig wird die Extension angezeigt.reverseOrder
(optional): Wenn dieser Parameter mit true
belegt ist, werden die Umsätze in umgekehrter Reihenfolge an das Skript übergeben. Standardmäßig werden die Umsätze in der gleichen Reihenfolge übergeben, wie sie in MoneyMoney angezeigt werden, d.h. neueste Umsätze zuerst.description
(optional): Beschreibung der ExtensionLua-Laufzeitumgebung
Exporter
sind später im Skript als globale Variablen version
, format
, fileExtension
, bundleIdentifier
, reverseOrder
und description
zugänglich. Zusätzlich ist auch noch die globale Variable extensionName
mit dem Namen der Extension definiert.MM.productName
und MM.productVersion
enthalten Informationen zur Anwendung, also MoneyMoney.print
wird im Protokoll-Fenster von MoneyMoney angezeigt.error
bricht die Ausführung des Skripts ab.Aufbau einer Export-Extension
Einsprungspunkte
WriteHeader
(Dateianfang)WriteTransactions
(Umsätze schreiben)WriteTail
(Dateiende)assert(io.write(...))
zur Standardausgabe (stdout
) schreiben. Das Öffnen und Schließen der Ausgabedatei übernimmt MoneyMoney.Dateianfang
function WriteHeader (account, startDate, endDate, transactionCount)
account
: Das Konto, von dem die Umsätze exportiert werden; Die Strukur ist im Abschnitt »Datenstruktur eines Kontos« beschrieben.startDate
: Das Buchungsdatum des ältesten Umsatzes; Die Angabe erfolgt in Form eines POSIX-Zeitstempels.endDate
: Das Buchungsdatum des neuesten Umsatzes; Die Angabe erfolgt in Form eines POSIX-Zeitstempels.transactionCount
: Anzahl der zu exportierenden Umsätze
nil
, wenn die Funktion erfolgreich war.Umsätze schreiben
function WriteTransactions (account, transactions)
account
: Das Konto, von dem die Umsätze exportiert werden; Die Strukur ist im Abschnitt »Datenstruktur eines Kontos« beschrieben.transactions
: Ein Array mit den Umsätzen eines Buchungstags; Die Struktur der Array-Elemente ist im Abschnitt »Datenstruktur eines Umsatzes« beschrieben.
nil
, wenn die Funktion erfolgreich war.Dateiende
function WriteTail (account)
account
: Das Konto, von dem die Umsätze exportiert werden; Die Strukur ist im Abschnitt »Datenstruktur eines Kontos« beschrieben.
nil
, wenn die Funktion erfolgreich war.Vorlage
Exporter{version = 1.00,
format = "Custom CSV file",
fileExtension = "csv",
description = "Export transactions as custom CSV file"}
local function csvField (str)
-- Helper function for quoting separator character and escaping double quotes.
if str == nil then
return ""
elseif string.find(str, ";") then
return '"' .. string.gsub(str, '"', '""') .. '"'
else
return str
end
end
function WriteHeader (account, startDate, endDate, transactionCount)
-- Write CSV header.
assert(io.write("Date;Value date;Category;Name;Purpose;Account;Bank;Amount;Currency\n"))
end
function WriteTransactions (account, transactions)
-- Write one line per transaction.
for _,transaction in ipairs(transactions) do
assert(io.write(csvField(MM.localizeDate(transaction.bookingDate)) .. ";" ..
csvField(MM.localizeDate(transaction.valueDate)) .. ";" ..
csvField(string.gsub(transaction.category, [[\]], " - ")) .. ";" ..
csvField(transaction.name) .. ";" ..
csvField(transaction.purpose) .. ";" ..
csvField(transaction.accountNumber) .. ";" ..
csvField(transaction.bankCode) .. ";" ..
csvField(MM.localizeNumber("0.00;-0.00", transaction.amount)) .. ";" ..
csvField(transaction.currency) .. "\n"))
end
end
function WriteTail (account)
-- Nothing to do.
end
Die API von MoneyMoney
Datenstruktur eines Kontos
name
: Bezeichnung des Kontosowner
: Name des KontoinhabersaccountNumber
: KontonummersubAccount
: UnterkontomerkmalbankCode
: Bankleitzahlcurrency
: Kontowährungiban
: IBANbic
: BICtype
: Kontoart; Mögliche Werte sind AccountTypeGiro
(Girokonto), AccountTypeSavings
(Sparkonto), AccountTypeFixedTermDeposit
(Festgeldanlage), AccountTypeLoan
(Darlehenskonto), AccountTypeCreditCard
(Kreditkarte), AccountTypeCash
(Bargeld), AccountTypeOther
(Sonstige). Die Konstanten sind mit dem englischen Beschreibungstext belegt. Der in Klammern angegebene deutsche Beschreibungstext kann mit der Funktion MM.localizeText
erzeugt werden.attributes
: Benutzerdefinierte Feldercomment
: Notizbalance
: KontostandbalanceDate
: Datum des Kontostands; Die Angabe erfolgt in Form eines POSIX-Zeitstempels.Datenstruktur eines Umsatzes
name
: Name des Auftraggebers/ZahlungsempfängersaccountNumber
: Kontonummer oder IBAN des Auftraggebers/ZahlungsempfängersbankCode
: Bankzeitzahl oder BIC des Auftraggebers/Zahlungsempfängersamount
: Betragcurrency
: WährungbookingDate
: Buchungstag; Die Angabe erfolgt in Form eines POSIX-Zeitstempels.valueDate
: Wertstellungsdatum; Die Angabe erfolgt in Form eines POSIX-Zeitstempels.purpose
: Verwendungszweck; Mehrere Zeilen können durch Zeilenumbrüche ("\n"
) getrennt werden.transactionCode
: GeschäftsvorfallcodetextKeyExtension
: TextschlüsselergänzungpurposeCode
: SEPA-VerwendungsschlüsselbookingKey
: SWIFT-BuchungsschlüsselbookingText
: UmsatzartprimanotaNumber
: Primanota-NummerbatchReference
: SammlerreferenzendToEndReference
: SEPA-Ende-zu-Ende-ReferenzmandateReference
: SEPA-MandatsreferenzcreditorId
: SEPA-Gläubiger-IDreturnReason
: Rückgabegrundbooked
: Gebuchter oder vorgemerkter Umsatzcheckmark
: Als erledigt oder unerledigt markierter Umsatzcategory
: Kategoriennamecomment
: Notizid
: Interner Primärschlüssel dieses Umsatzes in der MoneyMoney-Datenbank
Objekt für Bankinformationen
bankInfo = BankInfo(bankCode)
country
herangezogen.bankCode
: Bankleitzahlprint(BankInfo("80007777").name)
Datenstruktur für Bankinformationen
name
: Name der Bank
Sonstige Funktionen
str = MM.localizeText(str)
NSLocalizedString
und liefert natürlich nur dann eine Übersetzung, wenn der Text in MoneyMoney hinterlegt worden ist.str
: Englischer Textstr
: Übersetzter Textstr = MM.localizeDate([format, ]date)
NSDateFormatter
auf.
format
(optional): Ausgabeformat; Die Angabe erfolgt wie bei der Cocoa-Klasse NSDateFormatter
nach dem Unicode Technical Standard #35.date
: Datum; Die Angabe erfolgt in Form eines POSIX-Zeitstempels. str
: Datum im lokalisierten Formatstr = MM.localizeNumber([format, ]num)
NSNumberFormatter
auf.
format
(optional): Ausgabeformat; Die Angabe erfolgt wie bei der Cocoa-Klasse NSNumberFormatter
nach dem Unicode Technical Standard #35.num
: Zahlstr
: Zahl im lokalisierten Formatstr = MM.localizeAmount([format, ]amount[, currency])
format
(optional): Ausgabeformat; Die Angabe erfolgt wie bei der Cocoa-Klasse NSNumberFormatter
nach dem Unicode Technical Standard #35.amount
: Betragcurrency
(optional): Währung; Ohne diesen Parameter wird nur der Betrag ohne Währungsangabe zurückgegeben.str
: Währungsbetrag im lokalisierten Formatdata = MM.toEncoding(charset, str[, bom])
charset
: Zeichensatz; Die Angabe erfolgt wie bei HTTP nach IANA.str
: Text in UTF-8bom
(optional): Wenn dieser Parameter mit true
belegt ist, wird der Rückgabewert um eine Byte Order Mark (BOM) ergänzt, sofern sie für den angegeben Zeichensatz existiert.data
: Text im angegebenen Zeichensatzstr = MM.fromEncoding(charset, data)
charset
: Zeichensatz; Die Angabe erfolgt wie bei HTTP nach IANA.data
: Text im angegebenen Zeichensatzstr
: Text in UTF-8