Cargo requests for other departments may now request they come out of the department budget. (#93152)

## About The Pull Request

When placing a cargo request as a non-cargo staff, you may now specify
which department you are requesting this for, which if approved will
bill that department from their budget. Requests placed this way will
need to be approved by cargo staff by default.

Originally I was going to tie this to my proposed rolling permission
system (Think an email chain where if things don't get approved, it goes
up a PDA Message chain until someone approves the thing), however I've
quite stalled on that and I wanted to at least get the baseline
functionality into people's hands.

Cargo, as per usual, has a right to refusal to reject the request as
well.

<img width="797" height="199" alt="image"
src="https://github.com/user-attachments/assets/19889b0a-8af5-4347-b91a-91cc39ab2bee"
/>
_WIP Photos, names/departments only show here as undefined due to being
admin spawned and not naturally spawned players_

## Why It's Good For The Game

Heads of staff can already order crates using their departmental
ordering apps and utilizing their funds, without needing QM approval.
This will allow for crewmembers within a department to request to
requisition supplies using their budget's funds as well.

As it stands, ordering from budget is already quite clunky, and being
able to go to cargo to place a request for your department should at
least elicit a conversation between heads of staff to see if it makes
sense. Keeping in mind, spending too much of a budget's funds can result
in failure to complete paychecks, so there is some conflict that can
arise from interacting with this mechanic too aggressively.

**I'll be real, there's a pretty good chance this may be too easy to use
and too powerful in it's current state.** If it needs something like the
additional rolling permissions system in place in the future, we may
want to re-assess at a later point.

## Changelog

🆑
qol: When placing cargo requests, you can now request that a crate be
obtained using your department's funds as opposed to the cargo budget.
/🆑

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
ArcaneMusic
2025-10-09 15:16:15 -04:00
committed by GitHub
parent e58874c63a
commit bf4cc3e415
5 changed files with 73 additions and 30 deletions
@@ -1,9 +1,9 @@
/datum/computer_file/program/budgetorders
filename = "orderapp"
filedesc = "NT IRN"
filedesc = "NT Shopping Network"
downloader_category = PROGRAM_CATEGORY_SUPPLY
program_open_overlay = "request"
extended_desc = "Nanotrasen Internal Requisition Network interface for supply purchasing using a department budget account."
extended_desc = "Nanotrasen Shopping Network interface for purchasing supplies from the cargo catalogue using a department budget account."
program_flags = PROGRAM_ON_NTNET_STORE | PROGRAM_REQUIRES_NTNET
can_run_on_flags = PROGRAM_LAPTOP | PROGRAM_PDA
size = 10
@@ -62,23 +62,27 @@
var/list/data = list()
data["location"] = SSshuttle.supply.getStatusText()
data["department"] = "Cargo"
var/datum/bank_account/buyer = SSeconomy.get_dep_account(cargo_account)
var/obj/item/card/id/id_card = computer.stored_id?.GetID()
if(id_card?.registered_account)
buyer = SSeconomy.get_dep_account(id_card?.registered_account.account_job.paycheck_department)
if((ACCESS_COMMAND in id_card.access))
requestonly = FALSE
buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department)
can_approve_requests = TRUE
// If buyer is a departmental budget, replaces "Cargo" with that budget - we're not using the cargo budget here
data["department"] = "[buyer.account_holder] Requisitions"
else
requestonly = TRUE
can_approve_requests = FALSE
if(ACCESS_COMMAND in id_card.access)
// If buyer is a departmental budget, replaces "Cargo" with that budget - we're not using the cargo budget here
data["department"] = addtext(buyer.account_holder, " Requisitions")
else
requestonly = TRUE
if(buyer)
data["points"] = buyer.account_balance
// To recap above because it's kind of a mess, here's all the options:
//Head of staff ID card: Can approve, buy, and make purchases using their own departmental budgets.
//ID card, not a head of staff: can request items from cargo using departmental budget.
//No ID card, can request items from cargo using the cargo budget.
//Otherwise static data, that is being applied in ui_data as the crates visible and buyable are not static, and are determined by inserted ID.
data["requestonly"] = requestonly
@@ -160,7 +164,8 @@
"cost" = pack.get_cost(),
"orderer" = order.orderer,
"reason" = order.reason,
"id" = order.id
"id" = order.id,
"account" = order.paying_account?.account_holder || "Cargo Department"
))
data["amount_by_name"] = amount_by_name
@@ -219,25 +224,31 @@
var/name = "*None Provided*"
var/rank = "*None Provided*"
var/ckey = usr.ckey
var/mob/living/carbon/human/hwoman
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
name = H.get_authentification_name()
rank = H.get_assignment(hand_first = TRUE)
hwoman = usr
rank = hwoman.get_assignment(hand_first = TRUE)
else if(issilicon(usr))
name = usr.real_name
rank = "Silicon"
var/datum/bank_account/account
// Our account that we want to end up paying with. Defaults to the cargo budget!
var/datum/bank_account/account = SSeconomy.get_dep_account(ACCOUNT_CAR)
// Our ID card that we want to pull from for identification. Modifies either name, account, or neither depending on function.
var/obj/item/card/id/id_card_customer = computer.stored_id?.GetID()
if(!id_card_customer)
id_card_customer = hwoman?.get_idcard(TRUE) //Grab from hands/mob if there's no id_card slot to prioritize.
name = id_card_customer?.registered_account.account_holder
if(self_paid)
var/mob/living/carbon/human/H = usr
var/obj/item/card/id/id_card = H.get_idcard(TRUE)
if(!istype(id_card))
if(!istype(id_card_customer))
computer.say("No ID card detected.")
return
if(IS_DEPARTMENTAL_CARD(id_card))
computer.say("[id_card] cannot be used to make purchases.")
if(IS_DEPARTMENTAL_CARD(id_card_customer))
computer.say("[id_card_customer] cannot be used to make purchases.")
return
account = id_card.registered_account
account = id_card_customer.registered_account
name = id_card_customer.registered_account.account_holder
if(!istype(account))
computer.say("Invalid bank account.")
return
@@ -248,6 +259,16 @@
if(isnull(reason) || ..())
return
if(id_card_customer?.registered_account?.account_job) //Find a budget to pull from
var/datum/bank_account/personal_department = SSeconomy.get_dep_account(id_card_customer.registered_account.account_job.paycheck_department)
if(!(personal_department.account_holder == "Cargo Budget"))
var/choice = tgui_alert(usr, "Which department are you requesting this for?", "Choose request department", list("Cargo Budget", "[personal_department.account_holder]"))
if(!choice)
return
if(choice != "Cargo Budget")
account = personal_department
name = id_card_customer.registered_account?.account_holder
if(pack.goody && !self_paid)
playsound(computer, 'sound/machines/buzz/buzz-sigh.ogg', 50, FALSE)
computer.say("ERROR: Small crates may only be purchased by private accounts.")
@@ -271,6 +292,7 @@
SSshuttle.shopping_list += SO
if(self_paid)
computer.say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.")
playsound(computer, 'sound/effects/coin2.ogg', 40, TRUE)
. = TRUE
if("remove")
var/id = text2num(params["id"])
@@ -723,6 +723,7 @@
SStgui.update_uis(computer)
update_pictures_for_all()
/// topic call that answers to people pressing "(Reply)" in chat
/datum/computer_file/program/messenger/Topic(href, href_list)
..()