mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-28 22:47:59 +01:00
NanoBank Premium: Remote Approval of Departmental Cargo Crates! (#25871)
* NanoBank Premium * TGUI prettier * Apply suggestions from code review Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * default case for request notice --------- Signed-off-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
#define TRANSFER_REQUEST_MAX 5000
|
||||
#define TRANSFER_COOLDOWN 5 SECONDS
|
||||
#define PREMIUM_COST 250
|
||||
|
||||
/datum/data/pda/app/nanobank
|
||||
name = "NanoBank"
|
||||
icon = "fas fa-university"
|
||||
notify_icon = "comments"
|
||||
title = "NanoBank 1.1"
|
||||
title = "NanoBank 1.2"
|
||||
template = "pda_nanobank"
|
||||
update = PDA_APP_UPDATE_SLOW //we want to avoid iterating through the data lists constantly
|
||||
|
||||
@@ -16,6 +17,9 @@
|
||||
///world time of last transaction, used for cooldowns (to protect against transfer spams or accidental double clicks)
|
||||
var/last_transaction = 0
|
||||
|
||||
/// Has this user purchased NanoBank Premium?
|
||||
var/premium_version = FALSE
|
||||
|
||||
/datum/data/pda/app/nanobank/start()
|
||||
. = ..()
|
||||
reconnect_database()
|
||||
@@ -83,6 +87,68 @@
|
||||
|
||||
data["available_accounts"] = get_available_account_data()
|
||||
|
||||
data["is_premium"] = premium_version
|
||||
data["supply_requests"] = list()
|
||||
|
||||
if(premium_version && user_account)
|
||||
var/list/supply_requests = list()
|
||||
for(var/datum/supply_order/order as anything in SSeconomy.request_list)
|
||||
//can this specific order request be approved the the mob user?
|
||||
var/can_approve = FALSE
|
||||
//can this specific order request be denied the the mob user?
|
||||
var/can_deny = FALSE
|
||||
|
||||
// Step 0: Initial checks for denial & CT Approval requirements
|
||||
if(order.orderedby == user_account.account_name)
|
||||
can_deny = TRUE //if it's your crate, you can deny it;
|
||||
|
||||
if(isnull(order.ordered_by_department))
|
||||
if(order.orderedby != user_account.account_name)
|
||||
continue // non-department personal order, if it's not yours, you don't get to see it
|
||||
if(user_account.account_type == ACCOUNT_TYPE_DEPARTMENT)
|
||||
can_deny = TRUE // if it's a department account, you can deny crates (only it's department crates will show up)
|
||||
if(order.requires_cargo_approval)
|
||||
can_approve = FALSE // You cannot remotely approve CT locked transactions :)
|
||||
|
||||
else if(order.requires_head_approval)
|
||||
// Step 1: Check if this is a department account and assign permission accordingly
|
||||
if(user_account.account_type == ACCOUNT_TYPE_DEPARTMENT) //set to TRUE initially if account is a Department account
|
||||
if(order.ordered_by_department.department_account != user_account)
|
||||
continue // department order, but wrong department, skip this order!
|
||||
can_approve = TRUE
|
||||
can_deny = TRUE
|
||||
|
||||
// Step 2: Check through members
|
||||
var/member_identified = FALSE // is this user in the order's department?
|
||||
for(var/datum/department_member/member as anything in order.ordered_by_department.members)
|
||||
if(member.member_account != user_account)
|
||||
continue
|
||||
member_identified = TRUE
|
||||
if(member.can_approve_crates)
|
||||
can_approve = TRUE
|
||||
can_deny = TRUE
|
||||
member_identified = TRUE
|
||||
break
|
||||
|
||||
// Step 3: If user is not a member of order's department & this is a personal account, skip this order in the UI
|
||||
if(!member_identified && user_account.account_type == ACCOUNT_TYPE_PERSONAL)
|
||||
continue // Don't show this order if it's a department order and the user is not part of that department
|
||||
|
||||
var/list/request_data = list(
|
||||
"ordernum" = order.ordernum,
|
||||
"supply_type" = order.object.name,
|
||||
"orderedby" = order.orderedby,
|
||||
"department" = order.ordered_by_department?.department_name,
|
||||
"cost" = order.object.get_cost(),
|
||||
"comment" = order.comment,
|
||||
"req_cargo_approval" = order.requires_cargo_approval,
|
||||
"req_head_approval" = order.requires_head_approval,
|
||||
"can_approve" = can_approve,
|
||||
"can_deny" = can_deny,
|
||||
"singleton_id" = initial(order.object?.singleton_group_id)
|
||||
)
|
||||
supply_requests += list(request_data)
|
||||
data["supply_requests"] = supply_requests
|
||||
return data
|
||||
|
||||
/datum/data/pda/app/nanobank/ui_act(action, list/params, datum/tgui/ui)
|
||||
@@ -160,6 +226,21 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Authentification Failure: incorrect pin.</span>")
|
||||
|
||||
if("purchase_premium")
|
||||
if(premium_version)
|
||||
return
|
||||
var/choice = tgui_alert(user, "Purchase NanoBank Premium on this PDA for [PREMIUM_COST] credits?", "Confirm", list("Yes", "No"))
|
||||
if(choice != "Yes")
|
||||
return
|
||||
if(pay_with_account(user, PREMIUM_COST, "NanoBank Premium Purchase", "[pda]", account_database.vendor_account))
|
||||
premium_version = TRUE
|
||||
title += " Premium" // cash money
|
||||
if(!pda.silent)
|
||||
playsound(pda, 'sound/machines/ping.ogg', 50, FALSE)
|
||||
else
|
||||
if(!pda.silent)
|
||||
playsound(pda, 'sound/machines/buzz-sigh.ogg', 15, FALSE)
|
||||
|
||||
if("toggle_member_approval")
|
||||
for(var/datum/station_department/department as anything in SSjobs.station_departments)
|
||||
if(department.department_account == user_account)
|
||||
@@ -181,7 +262,16 @@
|
||||
department.auto_approval_cap = clamp(new_amount, 0, 3000)
|
||||
else
|
||||
department.auto_approval_cap = 0
|
||||
|
||||
if("approve_crate")
|
||||
var/ordernum = text2num(params["ordernum"])
|
||||
if(!ordernum)
|
||||
return
|
||||
approve_crate(ordernum, user)
|
||||
if("deny_crate")
|
||||
var/ordernum = text2num(params["ordernum"])
|
||||
if(!ordernum)
|
||||
return
|
||||
deny_crate(ordernum, user)
|
||||
if(play_beep && !pda.silent)
|
||||
playsound(pda, 'sound/machines/terminal_select.ogg', 15, TRUE)
|
||||
|
||||
@@ -280,6 +370,113 @@
|
||||
/datum/data/pda/app/nanobank/proc/can_receive()
|
||||
return pda.owner && !hidden
|
||||
|
||||
|
||||
/datum/data/pda/app/nanobank/proc/approve_crate(order_num, mob/user)
|
||||
if(!premium_version)
|
||||
return // cheater cheater pumpkin eater
|
||||
|
||||
for(var/datum/supply_order/order as anything in SSeconomy.request_list)
|
||||
if(order.ordernum != order_num)
|
||||
continue
|
||||
//can this specific order request be approved the the mob user?
|
||||
var/can_approve = FALSE
|
||||
|
||||
if(order.requires_cargo_approval)
|
||||
return // You cannot remotely approve CT locked transactions :)
|
||||
if(order.requires_head_approval)
|
||||
if(user_account.account_type == ACCOUNT_TYPE_DEPARTMENT) //set to TRUE initially if account is a Department account
|
||||
if(order.ordered_by_department.department_account != user_account)
|
||||
return // department order, but wrong department, yeet
|
||||
can_approve = TRUE
|
||||
|
||||
// Check through members
|
||||
var/member_identified = FALSE // is this user in the order's department?
|
||||
for(var/datum/department_member/member as anything in order.ordered_by_department.members)
|
||||
if(member.member_account != user_account)
|
||||
continue
|
||||
member_identified = TRUE
|
||||
if(member.can_approve_crates)
|
||||
can_approve = TRUE
|
||||
break
|
||||
|
||||
// Step 3: If user is not a member of order's department & this is a personal account, skip this order in the UI
|
||||
if(!member_identified && user_account.account_type == ACCOUNT_TYPE_PERSONAL)
|
||||
return // user not in this department, get outta here!
|
||||
|
||||
if(!can_approve)
|
||||
return
|
||||
|
||||
var/datum/supply_packs/pack = order.object
|
||||
var/datum/money_account/account = order.ordered_by_department.department_account
|
||||
///just give the account pin here, its too much work for players to get the department account pin number since approval is access locked anyway
|
||||
if(attempt_account_authentification(account, user, account.account_pin))
|
||||
if(pay_with_account(user, pack.get_cost(), "[pack.name] Crate Purchase", "[src]", account_database.vendor_account))
|
||||
if(!pda.silent)
|
||||
playsound(pda, 'sound/machines/ping.ogg', 50, FALSE)
|
||||
order.requires_head_approval = FALSE
|
||||
SSeconomy.process_supply_order(order, TRUE)
|
||||
pda.investigate_log("| [key_name(user)] has authorized an order for [pack.name]. Remaining Cargo Balance: [SSeconomy.cargo_account.credit_balance].", "cargo")
|
||||
SSblackbox.record_feedback("tally", "cargo_shuttle_order", 1, pack.name)
|
||||
else
|
||||
pda.atom_say("ERROR: Account tied to order cannot pay, auto-denying order")
|
||||
SSeconomy.request_list -= order
|
||||
|
||||
/datum/data/pda/app/nanobank/proc/deny_crate(order_num, user)
|
||||
if(!premium_version)
|
||||
return // cheater cheater pumpkin eater
|
||||
|
||||
for(var/datum/supply_order/order as anything in SSeconomy.request_list)
|
||||
if(order.ordernum != order_num)
|
||||
continue
|
||||
|
||||
//can this specific order request be denied by the currently opened NanoBank account?
|
||||
var/can_deny = FALSE
|
||||
if(order.orderedby == user_account.account_name)
|
||||
can_deny = TRUE
|
||||
else if(order.requires_head_approval)
|
||||
if(user_account.account_type == ACCOUNT_TYPE_DEPARTMENT) //set to TRUE initially if account is a Department account
|
||||
if(order.ordered_by_department.department_account != user_account)
|
||||
return // department order, but wrong department
|
||||
can_deny = TRUE
|
||||
|
||||
for(var/datum/department_member/member as anything in order.ordered_by_department.members)
|
||||
if(member.member_account != user_account)
|
||||
continue
|
||||
if(member.can_approve_crates)
|
||||
can_deny = TRUE
|
||||
break
|
||||
|
||||
if(!can_deny)
|
||||
return
|
||||
SSeconomy.request_list -= order
|
||||
pda.investigate_log("| [key_name(user)] has denied an order for [order.object.name] through the Nanobank app.", "cargo")
|
||||
|
||||
/datum/data/pda/app/nanobank/proc/pay_with_account(user, amount, purpose, transactor, datum/money_account/target)
|
||||
if(user_account.suspended)
|
||||
to_chat(user, "<span class='warning'>Unable to access account: account suspended.</span>")
|
||||
return FALSE
|
||||
if(!account_database.charge_account(user_account, amount, purpose, transactor, allow_overdraft = FALSE, supress_log = FALSE))
|
||||
to_chat(user, "<span class='warning'>Unable to complete transaction: account has insufficient credit balance to purchase this.</span>")
|
||||
return FALSE
|
||||
account_database.credit_account(target, amount, purpose, transactor, FALSE)
|
||||
return TRUE
|
||||
|
||||
/datum/data/pda/app/nanobank/proc/attempt_account_authentification(datum/money_account/customer_account, mob/user, pin)
|
||||
if(customer_account.security_level > ACCOUNT_SECURITY_RESTRICTED)
|
||||
return FALSE
|
||||
var/attempt_pin = pin
|
||||
if(customer_account.security_level != ACCOUNT_SECURITY_ID && !attempt_pin)
|
||||
//if pin is not given, we'll prompt them here
|
||||
attempt_pin = tgui_input_number(user, "Enter pin code", "Vendor transaction")
|
||||
if(!attempt_pin)
|
||||
return FALSE
|
||||
var/is_admin = is_admin(user)
|
||||
if(!account_database.try_authenticate_login(customer_account, attempt_pin, TRUE, FALSE, is_admin))
|
||||
to_chat(user, "<span class='warning'>Unable to access account: incorrect credentials.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
#undef TRANSFER_COOLDOWN
|
||||
|
||||
#undef TRANSFER_REQUEST_MAX
|
||||
#undef PREMIUM_COST
|
||||
|
||||
Reference in New Issue
Block a user