-
Notifications
You must be signed in to change notification settings - Fork 0
/
BitcoinMonkey.lua
163 lines (122 loc) · 5.42 KB
/
BitcoinMonkey.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
-- BitcoinMonkey.lua
--
-- Umwandlung einer Bitcoin Core CSV Exportdatei in MonkeyOffice Buchungen
--- TODO:
--- - Angabe der Ausgabedatei
local ftcsv = require("ftcsv")
local date = require("date")
local cli = require ("cliargs")
local requests = require ("requests")
--
-- Hilfsfunktionen zur String-Behandlung
--
local DELIM = "," -- Delimiter
local function csvField (str)
-- Helper function for quoting delimiter character and escaping double quotes.
if str == nil or str == "" then
return ""
end
return '"' .. string.gsub(str, '"', '""') .. '"'
end
-- Command Line Usage
cli:set_name("BitcoinMonkey")
cli:set_description("Umwandlung einer Bitcoin Core CSV Exportdatei in MonkeyOffice Buchungen")
cli:argument("CSVDATEI", "Bitcoin Core CSV Exportdatei")
cli:option("-w, --waehrung=WAEHRUNG", "Währung", "EUR")
cli:option("-f, --finanzkonto=KONTO", "Finanzkonto")
cli:option("-g, --gegenkonto=KONTO", "Gegenkonto")
cli:option("-s, --steuersatz=STEUERSATZ", "Steuersatz", "-")
cli:option("-1, --ks1=KOSTENSTELLE", "Kostenstelle1", "")
cli:option("-2, --ks2=KOSTENSTELLE", "Kostenstelle2", "")
cli:option("-n, --firma=NR", "Firmennummer", "0")
cli:option("-b, --bestand=BTC", "Initialer Bestand des BTC-Kontos", "0")
cli:option("-d, --startdatum=DATE", "Frühestes Datum")
cli:option("-D, --endedatum=DATE", "Spätestes Datum")
cli:option("-o, --output=OFILE", "Ausgabedatei")
-- Kommandozeile parsen und auf Vollständigkeit überprüfen
local args, err = cli:parse(arg)
if not args and err then
print(string.format('%s: %s', cli.name, err))
cli:print_help()
os.exit(1)
end
if not args.finanzkonto or not args.gegenkonto then
print "Die Angabe von Finanzkonto und Gegenkonto ist erforderlich"
print(string.format('%s: %s', cli.name, err))
os.exit(1)
end
local BestandBTC = tonumber(args.bestand)
local Finanzkonto = tostring(args.finanzkonto)
local Gegenkonto = tostring(args.gegenkonto)
local Waehrung = tostring(args.waehrung)
local Steuersatz = tostring(args.waehrung)
local Kostenstelle1 = tostring(args.ks1)
local Kostenstelle2 = tostring(args.ks2)
local Firma = tostring(args.firma)
local StartDatum = nil
local EndeDatum = nil
if args.startdatum then
StartDatum = date(tostring(args.startdatum))
end
if args.endedatum then
EndeDatum = date(tostring(args.endedatum))
end
-- CSV Datei öffnen und konvertieren
local Transaktionen = ftcsv.parse(args["CSVDATEI"], DELIM, { header = true })
if Transaktionen == nil then
print (string.format ("Die Datei '%s' kann nicht geöffnet werden", args["CSVDATEI"]))
os.exit (1)
end
print ( "Firma" .. DELIM .. "Datum" .. DELIM ..
"BelegNr" .. DELIM .. "Referenz" .. DELIM ..
"Waehrung" .. DELIM .. "Text" .. DELIM ..
"KontoSoll" .. DELIM .. "KontoHaben" .. DELIM ..
"Betrag" .. DELIM .."Steuersatz" .. DELIM ..
"Kostenstelle1" .. DELIM .."Kostenstelle2" .. DELIM .. "Notiz" )
-- Transaktionen nach Datum sortieren
table.sort(Transaktionen, function (a,b)
return date(a.Date) < date(b.Date)
end)
for n, Transaktion in ipairs(Transaktionen) do
TransaktionsDatum = date(Transaktion.Date)
if (not StartDatum or StartDatum <= TransaktionsDatum) and
(not EndeDatum or EndeDatum >= TransaktionsDatum) and
(Transaktion.Confirmed == "true") then
Datum = string.format ("%02d.%02d.%04d", TransaktionsDatum:getday(), TransaktionsDatum:getmonth(), TransaktionsDatum:getyear())
BetragBTC = tonumber(Transaktion["Amount (BTC)"])
BestandBTC = BestandBTC + BetragBTC
-- Historischen Umrechnungskurs erfragen
RequestDate = string.format ("%04s-%02s-%02s", TransaktionsDatum:getyear(), TransaktionsDatum:getmonth(), TransaktionsDatum:getday())
RequestURL = string.format ("https://api.coindesk.com/v1/bpi/historical/close.json?currency=%s&start=%s&end=%s",
Waehrung, RequestDate, RequestDate )
Response = requests.get(RequestURL)
if (Response.status_code ~= 200) then
print(string.format("Request to '%s' results in Status %s", RequestURL, Response.status_code) )
os.exit (1)
end
Result, Error = Response.json()
Wechselkurs = Result.bpi[RequestDate]
BetragWaehrung = string.gsub(string.format ("%.2f", Wechselkurs * BetragBTC), "%.", "," )
if Transaktion.Type == "Received with" then
Text = string.format("Erwerb: %.8f / Neuer Bestand: %.8f", BetragBTC, BestandBTC)
else
Text = string.format("Verkauf: %.8f / Neuer Bestand: %.8f", math.abs(BetragBTC), BestandBTC)
end
Notiz = string.format("CoinBase BPI: %f ( x %f = %f %s / Label: %s", Wechselkurs, BetragBTC, Wechselkurs * BetragBTC, Waehrung, Transaktion.Label)
print(string.format('%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s',
csvField(Firma), DELIM, -- Firma
csvField(Datum), DELIM, -- Datum
csvField(Transaktion.ID), DELIM, -- BelegNr
csvField(Transaktion.Address), DELIM, -- Referenz
csvField(Waehrung), DELIM, -- Währung
csvField(Text), DELIM, -- Text
csvField(Finanzkonto), DELIM, -- KontoSoll
csvField(Gegenkonto), DELIM, -- KontoHaben
csvField(BetragWaehrung), DELIM, -- Betrag
csvField(Steuersatz), DELIM, -- Steuersatz
csvField(Kostenstelle1), DELIM, -- Kostenstelle1
csvField(Kostenstelle2), DELIM, -- Kostenstelle2
csvField(Notiz) -- Notiz
))
end
end