From 04ca99d7e9f939b5d515fc9076b0ad2cd2a941e9 Mon Sep 17 00:00:00 2001 From: Yaroslav Nurkov <78199449+AnywayFarus@users.noreply.github.com> Date: Thu, 6 Oct 2022 01:25:38 +0300 Subject: [PATCH] NT Pay app. Money send on distance, transaction log! (#70108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * base * reasons * GetToken proc, with a many remarks * Add a way to change reason in transfer_money proc. Add a reasons. * Reason to use the app. Commission. Standard application. * Apply suggestions from code review - Tralezab Co-authored-by: tralezab <40974010+tralezab@users.noreply.github.com> * Tralezab & jlsnow301 advices. New format(everywhere) * Nanotrasen * Refactor TGUI(not me:( ). Fix useless capitalize * Update code/modules/economy/account.dm * Trans transforms in transaction * coMmission. little autodoc mistalke. Translation != Transaction * oops * Merge Conflict * ... * back feats * mistakes bye! * ну да Co-authored-by: tralezab <40974010+tralezab@users.noreply.github.com> --- code/datums/components/payment.dm | 2 +- code/datums/components/pricetag.dm | 2 +- code/datums/station_traits/positive_traits.dm | 2 +- .../computer/chef_orders/chef_order.dm | 4 +- .../newscaster/newscaster_machine.dm | 2 +- code/game/machinery/roulette_machine.dm | 4 +- code/game/objects/items/cards_ids.dm | 22 ++- code/game/objects/items/crab17.dm | 2 +- code/game/objects/structures/displaycase.dm | 4 +- code/modules/art/paintings.dm | 2 +- code/modules/cargo/markets/_market.dm | 2 +- code/modules/economy/account.dm | 49 ++++- code/modules/economy/holopay.dm | 4 +- .../file_system/programs/bounty_board.dm | 2 +- .../file_system/programs/nt_pay.dm | 82 ++++++++ .../modular_computers/hardware/hard_drive.dm | 1 + .../modular_computers/laptop_vendor.dm | 2 +- code/modules/projectiles/pins.dm | 8 +- code/modules/religion/religion_sects.dm | 2 +- code/modules/religion/rites.dm | 2 +- .../religion/sparring/sparring_datum.dm | 2 +- code/modules/research/bepis.dm | 2 +- code/modules/shuttle/special.dm | 4 +- code/modules/shuttle/supply.dm | 2 +- code/modules/vending/_vending.dm | 6 +- tgstation.dme | 1 + tgui/packages/tgui/interfaces/NtosPay.tsx | 180 ++++++++++++++++++ 27 files changed, 355 insertions(+), 42 deletions(-) create mode 100644 code/modules/modular_computers/file_system/programs/nt_pay.dm create mode 100644 tgui/packages/tgui/interfaces/NtosPay.tsx diff --git a/code/datums/components/payment.dm b/code/datums/components/payment.dm index 9c9ff93f02d..027b7edb871 100644 --- a/code/datums/components/payment.dm +++ b/code/datums/components/payment.dm @@ -156,7 +156,7 @@ to_chat(user, span_warning("ID Card lacks funds. Aborting.")) user.balloon_alert(user, "Cost: [total_cost] credits.") return FALSE - target_acc.transfer_money(idcard.registered_account, total_cost) + target_acc.transfer_money(idcard.registered_account, total_cost, "Nanotrasen: Usage of Corporate Machinery") log_econ("[total_cost] credits were spent on [parent] by [user] via [idcard.registered_account.account_holder]'s card.") idcard.registered_account.bank_card_talk("[total_cost] credits deducted from your account.") playsound(src, 'sound/effects/cashregister.ogg', 20, TRUE) diff --git a/code/datums/components/pricetag.dm b/code/datums/components/pricetag.dm index f419bd1e089..fe1ac57323f 100644 --- a/code/datums/components/pricetag.dm +++ b/code/datums/components/pricetag.dm @@ -90,7 +90,7 @@ // And of course, the cut is removed from what cargo gets. (But not below zero, just in case) overall_item_price = max(0, overall_item_price - payee_cut) - payee.adjust_money(payee_cut) + payee.adjust_money(payee_cut, "Pricetag: [capitalize(source)] Sale") payee.bank_card_talk("Sale of [source] recorded. [payee_cut] credits added to account.") // Update the report with the modified final price diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm index b756ad042c7..9ae7bef3e81 100644 --- a/code/datums/station_traits/positive_traits.dm +++ b/code/datums/station_traits/positive_traits.dm @@ -263,7 +263,7 @@ var/holochip_amount = id_card.registered_account.account_balance new /obj/item/holochip(wallet, holochip_amount) - id_card.registered_account.adjust_money(-holochip_amount) + id_card.registered_account.adjust_money(-holochip_amount, "System: Withdrawal") new /obj/effect/spawner/random/entertainment/wallet_storage(wallet) diff --git a/code/game/machinery/computer/chef_orders/chef_order.dm b/code/game/machinery/computer/chef_orders/chef_order.dm index 0492566858e..7f49feb9513 100644 --- a/code/game/machinery/computer/chef_orders/chef_order.dm +++ b/code/game/machinery/computer/chef_orders/chef_order.dm @@ -83,7 +83,7 @@ say("No bank account detected!") return var/final_cost = get_total_cost() - if(!chef_card.registered_account.adjust_money(-final_cost)) + if(!chef_card.registered_account.adjust_money(-final_cost, "Chef Order: Purchase")) say("Sorry, but you do not have enough money.") return say("Thank you for your purchase! It will arrive on the next cargo shuttle!") @@ -106,7 +106,7 @@ return var/final_cost = get_total_cost() final_cost *= 2 - if(!chef_card.registered_account.adjust_money(-final_cost)) + if(!chef_card.registered_account.adjust_money(-final_cost, "Chef Order: Purchase")) say("Sorry, but you do not have enough money. Remember, Express upcharges the cost!") return say("Thank you for your purchase! Please note: The charge of this purchase and machine cooldown has been doubled!") diff --git a/code/game/machinery/newscaster/newscaster_machine.dm b/code/game/machinery/newscaster/newscaster_machine.dm index 7b1490531ef..0edf55e6356 100644 --- a/code/game/machinery/newscaster/newscaster_machine.dm +++ b/code/game/machinery/newscaster/newscaster_machine.dm @@ -792,7 +792,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) if(!current_user.has_money(active_request.value) || (current_user.account_holder != active_request.owner)) playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) return TRUE - payment_target.transfer_money(current_user, active_request.value) + payment_target.transfer_money(current_user, active_request.value, "Bounty Request") say("Paid out [active_request.value] credits.") GLOB.request_list.Remove(active_request) qdel(active_request) diff --git a/code/game/machinery/roulette_machine.dm b/code/game/machinery/roulette_machine.dm index 7c6482b90ef..9bb658abbf8 100644 --- a/code/game/machinery/roulette_machine.dm +++ b/code/game/machinery/roulette_machine.dm @@ -205,7 +205,7 @@ var/payout = potential_payout - my_card.registered_account.transfer_money(player_id.registered_account, bet_amount) + my_card.registered_account.transfer_money(player_id.registered_account, bet_amount, "Roulette: Bet") playing = TRUE update_appearance() @@ -262,7 +262,7 @@ var/remaining_payout = payout - my_card.registered_account.adjust_money(-payout) + my_card.registered_account.adjust_money(-payout, "Roulette: Payout") for(var/coin_type in coin_values) //Loop through all coins from most valuable to least valuable. Try to give as much of that coin (the iterable) as possible until you can't anymore, then move to the next. var/value = coin_values[coin_type] //Change this to use initial value once we change to mat datum coins. diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 95d4794ccfd..a857fd66687 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -102,6 +102,12 @@ /// Boolean value. If TRUE, the [Intern] tag gets prepended to this ID card when the label is updated. var/is_intern = FALSE + ///Way to use NT pay. Or how to save money. 1 - 100%, 0.05 - 5% + var/commission = 0.05 + + ///Payment under >99 credits withdraw. (this + 1 = min value to withdraw) + var/commission_minimal = 5 + /obj/item/card/id/Initialize(mapload) . = ..() @@ -580,7 +586,7 @@ if(!cash_money) to_chat(user, span_warning("[money] doesn't seem to be worth anything!")) return - registered_account.adjust_money(cash_money) + registered_account.adjust_money(cash_money, "System: Deposit") SSblackbox.record_feedback("amount", "credits_inserted", cash_money) log_econ("[cash_money] credits were inserted into [src] owned by [src.registered_name]") if(physical_currency) @@ -612,7 +618,7 @@ total += physical_money.get_item_credit_value() CHECK_TICK - registered_account.adjust_money(total) + registered_account.adjust_money(total, "System: Deposit") SSblackbox.record_feedback("amount", "credits_inserted", total) log_econ("[total] credits were inserted into [src] owned by [src.registered_name]") QDEL_LIST(money) @@ -665,15 +671,19 @@ if(loc != user) to_chat(user, span_warning("You must be holding the ID to continue!")) return - var/amount_to_remove = tgui_input_number(user, "How much do you want to withdraw? (Max: [registered_account.account_balance] cr)", "Withdraw Funds", max_value = registered_account.account_balance) + if(registered_account.account_balance < (commission_minimal + 1) ) + to_chat(user, span_warning("You must be holding the ID to continue!")) + return + var/amount_to_remove = tgui_input_number(user, "How much do you want to withdraw? (Max: [registered_account.account_balance] cr)(Commission is [commission_minimal] credits. From 100 credits is [commission * 100]% with rounding.)", "Withdraw Funds", max_value = registered_account.account_balance, min_value = 6) if(!amount_to_remove || QDELETED(user) || QDELETED(src) || issilicon(user) || loc != user) return if(!alt_click_can_use_id(user)) return - if(registered_account.adjust_money(-amount_to_remove)) - var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove) + if(registered_account.adjust_money(-amount_to_remove, "System: Withdrawal")) + var/commission_amount = amount_to_remove < 100 ? commission_minimal : round(amount_to_remove * commission) + var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove - commission_amount) user.put_in_hands(holochip) - to_chat(user, span_notice("You withdraw [amount_to_remove] credits into a holochip.")) + to_chat(user, span_notice("You withdraw [amount_to_remove - commission_amount] credits into a holochip. Commission was [commission_amount] credits")) SSblackbox.record_feedback("amount", "credits_removed", amount_to_remove) log_econ("[amount_to_remove] credits were removed from [src] owned by [src.registered_name]") return diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm index 71375c1a257..a436e4a1b02 100644 --- a/code/game/objects/items/crab17.dm +++ b/code/game/objects/items/crab17.dm @@ -200,7 +200,7 @@ var/amount = B.account_balance * percentage_lost var/datum/bank_account/account = bogdanoff?.get_bank_account() if (account) // get_bank_account() may return FALSE - account.transfer_money(B, amount) + account.transfer_money(B, amount, "?VIVA¿: !LA CRABBE¡") B.bank_card_talk("You have lost [percentage_lost * 100]% of your funds! A spacecoin credit deposit machine is located at: [get_area(src)].") addtimer(CALLBACK(src, .proc/dump), 150) //Drain every 15 seconds diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 1ae5b6241c5..1507750838f 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -471,9 +471,9 @@ to_chat(usr, span_notice("You do not possess the funds to purchase this.")) return TRUE else - account.adjust_money(-sale_price) + account.adjust_money(-sale_price, "Display Case: [capitalize(showpiece)]") if(payments_acc) - payments_acc.adjust_money(sale_price) + payments_acc.adjust_money(sale_price, "Display Case: [capitalize(showpiece)]") usr.put_in_hands(showpiece) to_chat(usr, span_notice("You purchase [showpiece] for [sale_price] credits.")) playsound(src, 'sound/effects/cashregister.ogg', 40, TRUE) diff --git a/code/modules/art/paintings.dm b/code/modules/art/paintings.dm index f927fdccc9d..f949822c58f 100644 --- a/code/modules/art/paintings.dm +++ b/code/modules/art/paintings.dm @@ -214,7 +214,7 @@ return if(sniped_amount != painting_metadata.credit_value) return - if(!account.adjust_money(-offer_amount)) + if(!account.adjust_money(-offer_amount, "Painting: Patron of [painting_metadata.title]")) to_chat(user, span_warning("Transaction failure. Please try again.")) return painting_metadata.patron_ckey = user.ckey diff --git a/code/modules/cargo/markets/_market.dm b/code/modules/cargo/markets/_market.dm index 64936e6213e..3c264289cd2 100644 --- a/code/modules/cargo/markets/_market.dm +++ b/code/modules/cargo/markets/_market.dm @@ -47,7 +47,7 @@ return FALSE if(I.buy(uplink, user, method)) - uplink.current_user.adjust_money(-price) + uplink.current_user.adjust_money(-price, "Other: Third Party Transaction") if(ismob(user)) var/mob/m_user = user m_user.playsound_local(get_turf(m_user), 'sound/machines/twobeep_high.ogg', 50, TRUE) diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm index 888f43b11cc..abddb4f5771 100644 --- a/code/modules/economy/account.dm +++ b/code/modules/economy/account.dm @@ -25,6 +25,10 @@ var/replaceable = FALSE ///Cooldown timer on replacing a civilain bounty. Bounties can only be replaced once every 5 minutes. COOLDOWN_DECLARE(bounty_timer) + ///A special semi-tandom token for tranfering money from NT pay app + var/pay_token + ///List with a transaction history for NT pay app + var/list/transaction_history = list() /datum/bank_account/New(newname, job, modifier = 1, player_account = TRUE) account_holder = newname @@ -32,6 +36,7 @@ payday_modifier = modifier add_to_accounts = player_account setup_unique_account_id() + pay_token = uppertext("[copytext(newname, 1, 2)][copytext(newname, -1)]-[random_capital_letter()]-[rand(1111,9999)]") /datum/bank_account/Destroy() if(add_to_accounts) @@ -59,6 +64,7 @@ /datum/bank_account/vv_edit_var(var_name, var_value) // just so you don't have to do it manually var/old_id = account_id + var/old_balance = account_balance . = ..() switch(var_name) if(NAMEOF(src, account_id)) @@ -70,6 +76,8 @@ setup_unique_account_id() else SSeconomy.bank_accounts_by_id -= "[account_id]" + if(NAMEOF(src, account_balance)) + add_log_to_history(var_value - old_balance, "Nanotrasen: Moderator Action") /** * Sets the bank_account to behave as though a CRAB-17 event is happening. @@ -100,10 +108,13 @@ * Adjusts the balance of a bank_account as well as sanitizes the numerical input. * Arguments: * * amount - the quantity of credits that will be written off if the value is negative, or added if it is positive. + * * reason - the reason for the appearance or loss of money */ -/datum/bank_account/proc/adjust_money(amount) +/datum/bank_account/proc/adjust_money(amount, reason) if((amount < 0 && has_money(-amount)) || amount > 0) _adjust_money(amount) + if(reason) + add_log_to_history(amount, reason) return TRUE return FALSE @@ -112,13 +123,25 @@ * Arguments: * * datum/bank_account/from - The bank account that is sending the credits to this bank_account datum. * * amount - the quantity of credits that are being moved between bank_account datums. + * * transfer_reason - override for adjust_money reason. Use if no default reason(Transfer to/from Name Surname). */ -/datum/bank_account/proc/transfer_money(datum/bank_account/from, amount) +/datum/bank_account/proc/transfer_money(datum/bank_account/from, amount, transfer_reason) if(from.has_money(amount)) - adjust_money(amount) + var/reason_to = "Transfer: From [from.account_holder]" + var/reason_from = "Transfer: To [account_holder]" + + if(istype(from, /datum/bank_account/department)) + reason_to = "Nanotrasen: Salary" + reason_from = "" + + if(transfer_reason) + reason_to = istype(src, /datum/bank_account/department) ? "" : transfer_reason + reason_from = transfer_reason + + adjust_money(amount, reason_to) + from.adjust_money(-amount, reason_from) SSblackbox.record_feedback("amount", "credits_transferred", amount) log_econ("[amount] credits were transferred from [from.account_holder]'s account to [src.account_holder]") - from.adjust_money(-amount) return TRUE return FALSE @@ -136,7 +159,7 @@ if(amount_of_paychecks == 1) money_to_transfer = clamp(money_to_transfer, 0, PAYCHECK_CREW) //We want to limit single, passive paychecks to regular crew income. if(free) - adjust_money(money_to_transfer) + adjust_money(money_to_transfer, "Nanotrasen: Shift Payment") SSblackbox.record_feedback("amount", "free_income", money_to_transfer) SSeconomy.station_target += money_to_transfer log_econ("[money_to_transfer] credits were given to [src.account_holder]'s account from income.") @@ -248,4 +271,20 @@ /datum/bank_account/remote // Bank account not belonging to the local station add_to_accounts = FALSE +/** + * Add log to transactions history. Deletes the oldest log when the history has more than 20 entries. + * Main format: Category: Reason in Reason. Example: Vending: Machinery Using + * Arguments: + * * adjusted_money - How much was added, negative values removing cash. + * * reason - The reason of interact with balance, for example, "Bought chips" or "Payday". + */ +/datum/bank_account/proc/add_log_to_history(adjusted_money, reason) + if(transaction_history.len >= 20) + transaction_history.Cut(1,2) + + transaction_history += list(list( + "adjusted_money" = adjusted_money, + "reason" = reason, + )) + #undef DUMPTIME diff --git a/code/modules/economy/holopay.dm b/code/modules/economy/holopay.dm index 5efd0a52041..4f601c89929 100644 --- a/code/modules/economy/holopay.dm +++ b/code/modules/economy/holopay.dm @@ -262,7 +262,7 @@ /// Exit checks in case the user cancelled or entered an invalid amount if(!amount || QDELETED(user) || QDELETED(src) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE)) return FALSE - if(!payee.adjust_money(-amount)) + if(!payee.adjust_money(-amount, "Holopay: [capitalize(name)]")) balloon_alert(user, "insufficient credits") to_chat(user, span_warning("You don't have the money to pay for this.")) return FALSE @@ -281,7 +281,7 @@ */ /obj/structure/holopay/proc/alert_buyer(payee, amount) /// Pay the owner - linked_card.registered_account.adjust_money(amount) + linked_card.registered_account.adjust_money(amount, "Holopay: [name]") /// Make alerts linked_card.registered_account.bank_card_talk("[payee] has deposited [amount] cr at your holographic pay stand.") say("Thank you for your patronage, [payee]!") diff --git a/code/modules/modular_computers/file_system/programs/bounty_board.dm b/code/modules/modular_computers/file_system/programs/bounty_board.dm index 56fa706f891..9d2ce018c38 100644 --- a/code/modules/modular_computers/file_system/programs/bounty_board.dm +++ b/code/modules/modular_computers/file_system/programs/bounty_board.dm @@ -104,7 +104,7 @@ if(!current_user.has_money(active_request.value) || (current_user.account_holder != active_request.owner)) playsound(computer, 'sound/machines/buzz-sigh.ogg', 30, TRUE) return - request_target.transfer_money(current_user, active_request.value) + request_target.transfer_money(current_user, active_request.value, "Bounties: Request Completed") computer.say("Paid out [active_request.value] credits.") GLOB.request_list.Remove(active_request) return TRUE diff --git a/code/modules/modular_computers/file_system/programs/nt_pay.dm b/code/modules/modular_computers/file_system/programs/nt_pay.dm new file mode 100644 index 00000000000..7b99fcfe44b --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/nt_pay.dm @@ -0,0 +1,82 @@ +/datum/computer_file/program/nt_pay + filename = "ntpay" + filedesc = "Nanotrasen Pay System" + category = PROGRAM_CATEGORY_MISC + program_icon_state = "generic" + extended_desc = "An application that locally (in your sector) helps to transfer money or track your expenses and profits." + size = 2 + tgui_id = "NtosPay" + program_icon = "money-bill-wave" + usage_flags = PROGRAM_ALL + ///Reference to the currently logged in user. + var/datum/bank_account/current_user + ///Pay token, by which we can send credits + var/token + ///Amount of credits, which we sends + var/money_to_send = 0 + ///Pay token what we want to find + var/wanted_token + +/datum/computer_file/program/nt_pay/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + + switch(action) + if("Transaction") + token = params["token"] + money_to_send = params["amount"] + var/datum/bank_account/recipient + if(!token) + return to_chat(usr, span_notice("You need to enter your transfer target's pay token.")) + if(!money_to_send) + return to_chat(usr, span_notice("You need to specify how much you're sending.")) + if(token == current_user.pay_token) + return to_chat(usr, span_notice("You can't send credits to yourself.")) + + for(var/account as anything in SSeconomy.bank_accounts_by_id) + var/datum/bank_account/acc = SSeconomy.bank_accounts_by_id[account] + if(acc.pay_token == token) + recipient = acc + break + + if(!recipient) + return to_chat(usr, span_notice("The app can't find who you're trying to pay. Did you enter the pay token right?")) + if(!current_user.has_money(money_to_send)) + return current_user.bank_card_talk("You cannot afford it.") + + recipient.bank_card_talk("You received [money_to_send] credit(s). Reason: transfer from [current_user.account_holder]") + recipient.transfer_money(current_user, money_to_send) + current_user.bank_card_talk("You send [money_to_send] credit(s) to [recipient.account_holder]. Now you have [current_user.account_balance] credit(s)") + + if("GetPayToken") + wanted_token = null + for(var/account in SSeconomy.bank_accounts_by_id) + var/datum/bank_account/acc = SSeconomy.bank_accounts_by_id[account] + if(acc.account_holder == params["wanted_name"]) + wanted_token = "Token: [acc.pay_token]" + break + if(!wanted_token) + return wanted_token = "Account \"[params["wanted_name"]]\" not found." + + + +/datum/computer_file/program/nt_pay/ui_data(mob/user) + var/list/data = get_header_data() + var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD] + + if(card_slot && card_slot.stored_card && card_slot.stored_card.registered_account) + current_user = card_slot.stored_card.registered_account + else + current_user = null + + if(!current_user) + data["name"] = null + else + data["name"] = current_user.account_holder + data["owner_token"] = current_user.pay_token + data["money"] = current_user.account_balance + data["wanted_token"] = wanted_token + data["transaction_list"] = current_user.transaction_history + + return data diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 59d97017544..bbf455beecf 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -185,6 +185,7 @@ . = ..() store_file(new /datum/computer_file/program/messenger) + store_file(new /datum/computer_file/program/nt_pay) store_file(new /datum/computer_file/program/notepad) // For borg integrated tablets. No downloader. diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index f4b9d3267ba..438c8c5de86 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -193,7 +193,7 @@ var/obj/item/card/id/ID = I var/datum/bank_account/account = ID.registered_account var/target_credits = total_price - credits - if(!account.adjust_money(-target_credits)) + if(!account.adjust_money(-target_credits, "Vending: Laptop Vendor")) say("Insufficient credits on card to purchase!") return credits += target_credits diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 1f0fd50ff44..512ec2ccaaa 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -276,8 +276,8 @@ var/datum/bank_account/credit_card_details = user.get_bank_account() if(user in gun_owners) if(multi_payment && credit_card_details) - if(credit_card_details.adjust_money(-payment_amount)) - pin_owner.registered_account.adjust_money(payment_amount) + if(credit_card_details.adjust_money(-payment_amount, "Firing Pin: Gun Rent")) + pin_owner.registered_account.adjust_money(payment_amount, "Firing Pin: Payout For Gun Rent") return TRUE to_chat(user, span_warning("ERROR: User balance insufficent for successful transaction!")) return FALSE @@ -290,8 +290,8 @@ return FALSE switch(license_request) if("Yes") - if(credit_card_details.adjust_money(-payment_amount)) - pin_owner.registered_account.adjust_money(payment_amount) + if(credit_card_details.adjust_money(-payment_amount, "Firing Pin: Gun License")) + pin_owner.registered_account.adjust_money(payment_amount, "Firing Pin: Gun License Bought") gun_owners += user to_chat(user, span_notice("Gun license purchased, have a secure day!")) active_prompt = FALSE diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm index 26eebbb251d..d5b3a7041cb 100644 --- a/code/modules/religion/religion_sects.dm +++ b/code/modules/religion/religion_sects.dm @@ -256,7 +256,7 @@ to_chat(chap, span_warning("[GLOB.deity] refuses to heal this metallic taint!")) return TRUE - account.adjust_money(-GREEDY_HEAL_COST) + account.adjust_money(-GREEDY_HEAL_COST, "Church Donation: Treatment") var/heal_amt = 30 var/list/hurt_limbs = blessed.get_damaged_bodyparts(1, 1, null, BODYTYPE_ORGANIC) if(hurt_limbs.len) diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm index 6ae08a45add..d6f16b9f7f7 100644 --- a/code/modules/religion/rites.dm +++ b/code/modules/religion/rites.dm @@ -278,7 +278,7 @@ if(!account || account.account_balance < money_cost) to_chat(user, span_warning("This rite requires more money!")) return FALSE - account.adjust_money(-money_cost) + account.adjust_money(-money_cost, "Church Donation: Rite") . = ..() /datum/religion_rites/greed/vendatray diff --git a/code/modules/religion/sparring/sparring_datum.dm b/code/modules/religion/sparring/sparring_datum.dm index 453f09e6181..904d64f25d0 100644 --- a/code/modules/religion/sparring/sparring_datum.dm +++ b/code/modules/religion/sparring/sparring_datum.dm @@ -294,7 +294,7 @@ var/datum/bank_account/winner_account = winner.get_bank_account() if(!loser_account || !winner_account)//the winner is pretty owned in this case but whatever shoulda read the fine print of the contract return - winner_account.transfer_money(loser_account, loser_account.account_balance) + winner_account.transfer_money(loser_account, loser_account.account_balance, "Bet: Sparring") if(STAKES_YOUR_SOUL) var/turf/shard_turf = get_turf(loser) if(!shard_turf) diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm index 3953fe93652..1f420a8c2f6 100644 --- a/code/modules/research/bepis.dm +++ b/code/modules/research/bepis.dm @@ -227,7 +227,7 @@ if(!account.has_money(deposit_value)) say("You do not possess enough credits.") return - account.adjust_money(-deposit_value) //The money vanishes, not paid to any accounts. + account.adjust_money(-deposit_value, "Vending: B.E.P.I.S. Chamber") //The money vanishes, not paid to any accounts. SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value) log_econ("[deposit_value] credits were inserted into [src] by [account.account_holder]") banked_cash += deposit_value diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index e73bc45b7a8..37f8ca253f3 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -328,11 +328,11 @@ if(account) if(account.account_balance < threshold - payees[AM]) - account.adjust_money(-account.account_balance) + account.adjust_money(-account.account_balance, "Scanner Gate: Entry Fee") payees[AM] += account.account_balance else var/money_owed = threshold - payees[AM] - account.adjust_money(-money_owed) + account.adjust_money(-money_owed, "Scanner Gate: Partial Entry Fee") payees[AM] += money_owed //Here is all the possible paygate payment methods. diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 04394397f3e..166ae110e5e 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -147,7 +147,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( else paying_for_this = SSeconomy.get_dep_account(ACCOUNT_CAR) if(paying_for_this) - if(!paying_for_this.adjust_money(-price)) + if(!paying_for_this.adjust_money(-price, "Cargo: [spawning_order.pack.name]")) if(spawning_order.paying_account) paying_for_this.bank_card_talk("Cargo order #[spawning_order.id] rejected due to lack of funds. Credits required: [price]") continue diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 04d02be8182..a6bc40594ad 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -1081,7 +1081,7 @@ GLOBAL_LIST_EMPTY(vending_products) price_to_use = R.custom_premium_price ? R.custom_premium_price : extra_price if(LAZYLEN(R.returned_products)) price_to_use = 0 //returned items are free - if(price_to_use && !account.adjust_money(-price_to_use)) + if(price_to_use && !account.adjust_money(-price_to_use, "Vending: [R.name]")) say("You do not possess the funds to purchase [R.name].") flick(icon_deny,src) vend_ready = TRUE @@ -1393,8 +1393,8 @@ GLOBAL_LIST_EMPTY(vending_products) balloon_alert(user, "insufficient funds") return TRUE /// Make the transaction - payee.adjust_money(-dispensed_item.custom_price) - linked_account.adjust_money(dispensed_item.custom_price) + payee.adjust_money(-dispensed_item.custom_price, , "Vending: [dispensed_item]") + linked_account.adjust_money(dispensed_item.custom_price, "Vending: [dispensed_item] Bought") linked_account.bank_card_talk("[payee.account_holder] made a [dispensed_item.custom_price] \ cr purchase at your custom vendor.") /// Log the transaction diff --git a/tgstation.dme b/tgstation.dme index dc686e8cc53..ed205b712fb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3860,6 +3860,7 @@ #include "code\modules\modular_computers\file_system\programs\jobmanagement.dm" #include "code\modules\modular_computers\file_system\programs\newscasterapp.dm" #include "code\modules\modular_computers\file_system\programs\notepad.dm" +#include "code\modules\modular_computers\file_system\programs\nt_pay.dm" #include "code\modules\modular_computers\file_system\programs\ntdownloader.dm" #include "code\modules\modular_computers\file_system\programs\ntmessenger.dm" #include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm" diff --git a/tgui/packages/tgui/interfaces/NtosPay.tsx b/tgui/packages/tgui/interfaces/NtosPay.tsx new file mode 100644 index 00000000000..2c35f19a27e --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosPay.tsx @@ -0,0 +1,180 @@ +import { NtosWindow } from '../layouts'; +import { useBackend } from '../backend'; +import { Stack, Section, Box, Button, Input, Table, Tooltip, NoticeBox, Divider, RestrictedInput } from '../components'; + +type Data = { + name: string; + owner_token: string; + money: number; + transaction_list: Transactions[]; + wanted_token: string; +}; + +type Transactions = { + adjusted_money: number; + reason: string; +}; +let name_to_token, money_to_send, token; + +export const NtosPay = (props, context) => { + const { data } = useBackend(context); + const { name } = data; + + if (!name) { + return ( + + + + You need to insert your ID card into the card slot in order to use + this application. + + + + ); + } + + return ( + + + + + + + + + + + + + + + + ); +}; + +/** Displays the user's name and balance. */ +const Introduction = (props, context) => { + const { data } = useBackend(context); + const { name, owner_token, money } = data; + return ( +
+ + Hi, {name}. + Your pay token is {owner_token}. + + Account balance: {money} credit{money === 1 ? '' : 's'} + +
+
+ ); +}; + +/** Displays the transfer section. */ +const TransferSection = (props, context) => { + const { act, data } = useBackend(context); + const { money, wanted_token } = data; + + return ( + + +
+ + + (token = value)} + /> + + + + (money_to_send = value)} + value={1} + /> + +
+
+ +
+ + (name_to_token = value)} + /> +
+
+
+ ); +}; + +/** Displays the transaction history. */ +const TransactionHistory = (props, context) => { + const { data } = useBackend(context); + const { transaction_list = [] } = data; + + return ( +
+
}> + + {transaction_list.map((log) => ( + + + {log.adjusted_money > 1 ? '+' : ''} + {log.adjusted_money} + + {log.reason} + + ))} +
+
+
+ ); +}; + +/** Renders a set of sticky headers */ +const TableHeaders = (props, context) => { + return ( + + + + Amount + + + Reason + + +
+ ); +};