bank_accounts/wtm.lua
2025-08-22 02:10:35 +02:00

118 lines
8.1 KiB
Lua

-- wtm.lua (FINAL - Abgesichert gegen Race Conditions)
-- Die globale pos_info wird aus den anderen Dateien mitbenutzt.
local function show_wtm_statement_form(player, account_type)
local player_name = player:get_player_name()
local data = bank_accounts.get_account_data(player_name)
local history = data.history; local lines = {}; local current_total_label = ""
table.insert(lines, minetest.formspec_escape(string.format("%-11s | %-13s | %-13s | %-20s | %-20s | %s", S("Date"), S("Amount"), S("New Balance"), S("Method"), S("Purpose"), S("Partner"))))
table.insert(lines, minetest.formspec_escape("-----------------------------------------------------------------------------------------"))
if history then for _, t in ipairs(history) do if t.account == account_type then
local parts = {}; table.insert(parts, string.format("%-11s", os.date("%Y-%m-%d", t.timestamp))); table.insert(parts, string.format("%12s", string.format("%+.2f", t.amount) .. " MG")); table.insert(parts, string.format("%12s", string.format("%.2f", t.new_total).." MG")); table.insert(parts, string.format("%-20s", S(t.type)))
local purpose = t.purpose or ""; local partner = t.other or ""; if purpose ~= "" or partner ~= "" then table.insert(parts, string.format("%-20s", purpose)); if partner ~= "" then table.insert(parts, partner) end end
table.insert(lines, minetest.formspec_escape(table.concat(parts, " | ")))
end end end
if account_type == "balance" then current_total_label = S("Current Balance: @1", string.format("%.2f", data.balance) .. " MG") else current_total_label = S("Current Credit Debt: @1", string.format("%.2f", data.credit) .. " MG") end
local form_name = "bank_accounts:wtm_statement@" .. player_name
local formspec = "size[13,9]".."label[0,0;"..S("Account Statement for @1", player_name).."]".."button_exit[0,0.5;2,1;view_balance;"..S("Balance").."]".."button_exit[2,0.5;2,1;view_credit;"..S("Credit").."]".."textlist[0,1.2;13,7;statement_list;"..table.concat(lines,",").."]".."label[0,8.4;"..current_total_label.."]".."button_exit[11,8.4;2,1;back;"..S("Back").."]"
minetest.show_formspec(player_name, form_name, formspec)
end
function wtm_main_form(player, pos)
local player_name = player:get_player_name()
local data = bank_accounts.get_account_data(player_name)
minetest.show_formspec(player_name, "bank_accounts:wtm_options",
"size[8,8]" ..
"button_exit[0.5,1;3.5,1;transfer_balance;"..S("Transfer from Balance").."]" ..
"button_exit[0.5,2.0;3.5,1;transfer_credit;"..S("Transfer from Credit").."]" ..
"button_exit[5,2.5;2.4,1;statement;"..S("Account Statement").."]" ..
"label[5,1;"..S("Balance: @1", string.format("%.2f", data.balance) .. " MG").."]" ..
"label[5,1.5;"..S("Credit Debt: @1", string.format("%.2f", data.credit) .. " MG").."]" ..
"button_exit[0.5,6;3,1;credit_card;"..S("Get Credit Card").."]" ..
"button_exit[0.5,7;3,1;debit_card;"..S("Get Debit Card").."]" ..
"button_exit[5,7;2,1;exit;"..S("Close").."]")
end
minetest.register_node("bank_accounts:wtm", {
description = S("Wire Transfer Machine"),
drawtype = "mesh",
mesh = "atm.obj",
paramtype = "light",
paramtype2 = "facedir",
tiles = {"wtm_col.png"},
groups = {cracky=3, crumbly=3, oddly_breakable_by_hand=2},
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
pos_info = pos
if itemstack:get_name() ~= "bank_accounts:atm_card" then
minetest.chat_send_player(player:get_player_name(), S("[WTM] Must use ATM card."))
return
end
minetest.show_formspec(player:get_player_name(), "bank_accounts:wtm_home",
"size[8,8]" .. "pwdfield[2,4;4,1;fourdigitpin;"..S("Four Digit Pin:").."]" ..
"button_exit[5,6;2,1;enter;"..S("Enter").."]" .. "button_exit[3,6;2,1;exit;"..S("Cancel").."]")
end,
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
if not formname:find("bank_accounts:wtm") then return end
local player_name = player:get_player_name()
local pos = pos_info
if not pos then return end
if formname == "bank_accounts:wtm_home" then
if fields.enter then if bank_accounts.get_pin(player_name) == fields.fourdigitpin then wtm_main_form(player, pos) else minetest.chat_send_player(player_name, S("[WTM] Invalid Pin.")) end end
elseif formname == "bank_accounts:wtm_options" then
if fields.statement then
show_wtm_statement_form(player, "balance")
elseif fields.transfer_balance or fields.transfer_credit then
local source_account = fields.transfer_balance and "balance" or "credit"
local source_label = ""
if source_account == "balance" then source_label = S("Transfer from Balance (Available: @1 MG)", string.format("%.2f", bank_accounts.get_balance(player_name)))
else source_label = S("Transfer from Credit (Debt: @1 MG)", string.format("%.2f", bank_accounts.get_credit(player_name))) end
minetest.show_formspec(player_name, "bank_accounts:wtm_transfer@"..source_account,
"size[8,8]" .. "label[0,0;"..source_label.."]" ..
"field[0.5,1.5;7.5,1;recipient;"..S("Recipient:")..";]" ..
"field[0.5,2.5;7.5,1;amount;"..S("Amount:")..";]" ..
"field[0.5,3.5;7.5,1;purpose;"..S("Purpose:")..";]" ..
"button_exit[4,7;2,1;send;"..S("Send").."]" ..
"button_exit[2,7;2,1;cancel;"..S("Cancel").."]")
elseif fields.credit_card then player:get_inventory():add_item("main", "bank_accounts:credit_card"); wtm_main_form(player, pos)
elseif fields.debit_card then player:get_inventory():add_item("main", "bank_accounts:debit_card"); wtm_main_form(player, pos)
end
elseif formname:find("bank_accounts:wtm_transfer@") then
if fields.send then
-- KORREKTUR: Prüfe auf das "Schloss", bevor die Transaktion beginnt
if bank_accounts.is_calculating_interest then
minetest.chat_send_player(player_name, S("[Bank] System is busy, please try again in a moment."))
wtm_main_form(player, pos)
return
end
local source_account = formname:match("bank_accounts:wtm_transfer@(.*)")
local recipient = fields.recipient; local amount = normalize_and_tonumber(fields.amount); local purpose = fields.purpose
if not recipient or recipient == "" or not bank_accounts.player_has_account(recipient) then minetest.chat_send_player(player_name, S("[WTM] Recipient not found or has no account."))
elseif not amount or amount <= 0 then minetest.chat_send_player(player_name, S("[WTM] Invalid amount."))
elseif source_account == "balance" and bank_accounts.get_balance(player_name) < amount then minetest.chat_send_player(player_name, S("[WTM] Insufficient funds."))
else
-- Da eine Überweisung zwei Schreibvorgänge erfordert, ist es hier am sichersten,
-- dass wir wissen, dass das System nicht beschäftigt ist.
if source_account == "balance" then
bank_accounts.add_balance(player_name, -amount, "Transfer Sent", purpose, recipient)
else
bank_accounts.add_credit(player_name, amount, "Transfer Sent (Credit)", purpose, recipient)
end
bank_accounts.add_balance(recipient, amount, "Transfer Received", purpose, player_name)
minetest.chat_send_player(player_name, S("[WTM] Successfully transferred @1 MG to @2.", string.format("%.2f", amount), recipient))
minetest.chat_send_player(recipient, S("[WTM] You received a transfer of @1 MG from @2.", string.format("%.2f", amount), player_name))
end
end
wtm_main_form(player, pos)
elseif formname:find("bank_accounts:wtm_statement@") then
local target_name = formname:match("bank_accounts:wtm_statement@(.*)"); if not target_name then return end
if fields.back then wtm_main_form(player, pos) else show_wtm_statement_form(player, fields.view_credit and "credit" or "balance") end
end
end)