From 306206f542e5ac920d2db9419d86bcad9204ef3a Mon Sep 17 00:00:00 2001 From: Casper3667 <8396443+Casper3667@users.noreply.github.com> Date: Mon, 2 Feb 2026 00:29:38 +0100 Subject: [PATCH] Operations delivery app fixes and improvements (#21720) A small bundle of fixes with what is displayed, as mentioned in the changelog. Notable changes: - It is now possible to charge department accounts directly using it. The one doing it is logged in the transaction log for that account so command can still go and check it. This was a feature I have been requested repeatedly to make by operations member, to help encourage people to buy more things for their department. Only a hangar tech should be able to change the account that is charged as well. - The delivery and pay buttons are now separate in the delivery app, permitting someone to pay without having it delivered, or have it delivered without paying. This also fixes a bug that paying before it gets shipped to the Horizon could get an order permanently stuck as being shipped & paid but not delivered. image image image image image image --- code/datums/cargo.dm | 15 +- code/modules/cooking/machinery/commissary.dm | 4 +- code/modules/economy/quikpay.dm | 4 +- .../programs/civilian/cargo_delivery.dm | 75 ++++++--- .../OperationsDeliveryImprovements.yml | 12 ++ .../tgui/interfaces/CargoDelivery.tsx | 56 ++++--- tgui/packages/tgui/interfaces/QuikPay.tsx | 153 +++++++++++------- 7 files changed, 201 insertions(+), 118 deletions(-) create mode 100644 html/changelogs/OperationsDeliveryImprovements.yml diff --git a/code/datums/cargo.dm b/code/datums/cargo.dm index b86dc3f663d..31e055de4a6 100644 --- a/code/datums/cargo.dm +++ b/code/datums/cargo.dm @@ -42,9 +42,8 @@ // Returns a list of all the objects in the order - Formatted as a list to be json_encoded /datum/cargo_order/proc/get_object_list() var/list/object_list = list() - for (var/datum/cargo_order_item/coi in items) - for(var/atom/object in coi.ci.items) - object_list.Add(object.name) + for(var/item in get_item_list()) + object_list.Add(item["name"]) return object_list // Gets a list of the order data - Formatted as list to be json_encoded @@ -253,7 +252,7 @@ if(time_shipped) order_data += "Shipped at: [time_shipped]
" if(received_by) - order_data += "Received by:
" + order_data += "Received by: [received_by]
" order_data += "Delivered at: [time_delivered]
" order_data += "
" order_data += "Order ID: [order_id]
" @@ -276,7 +275,7 @@ order_data += "
  • [item["name"]]: [item["price"]]
  • " order_data += "
  • Crate Fee: [SScargo.get_cratefee()]
  • " order_data += "
  • Handling Fee: [SScargo.get_handlingfee()]
  • " - order_data += "
  • Shuttle Fee: [get_shipment_cost()]
  • " + order_data += "
  • Supplier Fee: [get_shipment_cost()]
  • " order_data += "" return order_data.Join("") @@ -338,7 +337,7 @@ time_shipped = worldtime2text() //Marks a order as delivered - Returns a status message -/datum/cargo_order/proc/set_delivered(var/user_name, var/user_id, var/paid=0) +/datum/cargo_order/proc/set_delivered(var/user_name, var/user_id) if(user_id <= 0) user_id = null if(status == "shipped") @@ -346,8 +345,6 @@ time_delivered = worldtime2text() received_by = user_name received_by_id = user_id - if(paid) - set_paid(user_name, user_id) return "The order has been delivered" else return "The order could not be delivered - Invalid Status" @@ -443,7 +440,7 @@ invoice_data += "

    Shuttle Data

    " invoice_data += "" invoice_data += "" - invoice_data += "" + invoice_data += "" invoice_data += "" invoice_data += "" invoice_data += "" diff --git a/code/modules/cooking/machinery/commissary.dm b/code/modules/cooking/machinery/commissary.dm index c8eb1ff99fd..b7b719b360f 100644 --- a/code/modules/cooking/machinery/commissary.dm +++ b/code/modules/cooking/machinery/commissary.dm @@ -291,7 +291,7 @@ /obj/structure/cash_register/commissary/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "QuikPay", "Idris Quik-Pay Register", 400, 400) + ui = new(user, src, "QuikPay", "Idris Quik-Pay Register", 550, 550) ui.open() /obj/structure/cash_register/commissary/ui_data(var/mob/user) @@ -349,7 +349,7 @@ if(L["name"] == params["buying"]) L["amount"]++ return TRUE - buying += list(list("name" = params["buying"], "amount" = params["amount"])) + buying += list(list("name" = params["buying"], "amount" = params["amount"], "price" = items_to_price[params["buying"]])) if("removal") var/index = 0 diff --git a/code/modules/economy/quikpay.dm b/code/modules/economy/quikpay.dm index 12d92abcabb..c8451d39227 100644 --- a/code/modules/economy/quikpay.dm +++ b/code/modules/economy/quikpay.dm @@ -117,7 +117,7 @@ /obj/item/quikpay/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "QuikPay", "Idris Quik-Pay", 400, 400) + ui = new(user, src, "QuikPay", "Idris Quik-Pay", 550, 550) ui.open() /obj/item/quikpay/ui_data(var/mob/user) @@ -176,7 +176,7 @@ if(L["name"] == params["buying"]) L["amount"]++ return TRUE - buying += list(list("name" = params["buying"], "amount" = params["amount"])) + buying += list(list("name" = params["buying"], "amount" = params["amount"], "price" = items_to_price[params["buying"]])) if("removal") var/index = 0 diff --git a/code/modules/modular_computers/file_system/programs/civilian/cargo_delivery.dm b/code/modules/modular_computers/file_system/programs/civilian/cargo_delivery.dm index 6fb869794fa..a6665c7fa9c 100644 --- a/code/modules/modular_computers/file_system/programs/civilian/cargo_delivery.dm +++ b/code/modules/modular_computers/file_system/programs/civilian/cargo_delivery.dm @@ -16,6 +16,7 @@ var/list/order_details = list() //Order Details for the order var/datum/cargo_order/co var/mod_mode = TRUE //If it can be used to pay for orders + var/destinationact = "Personal" /datum/computer_file/program/civilian/cargodelivery/ui_data(mob/user) var/list/data = initial_data() @@ -46,6 +47,8 @@ //Pass the status message along data["status_message"] = status_message + data["paying_account"] = destinationact + return data /datum/computer_file/program/civilian/cargodelivery/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) @@ -55,18 +58,35 @@ var/obj/item/card/id/I = usr.GetIdCard() - //Check if we want to deliver or pay - //If we are at the status shipped, then only the confirm delivery and pay button should be shown (deliver) - //If the status is not shipped, then only show the pay button as we can not confirm that it has been paid so far - //Everyone can pay / confirm delivery if(action == "deliver") - order_details = co.get_list() - //Check if its already delivered - if(order_details["status"] == "delivered" && !order_details["needs_payment"]) - status_message = "Unable to Deliver - Order has already been delivered and paid for." + if(computer && computer.card_slot && computer.network_card) + var/obj/item/card/id/id_card + if(computer.card_slot?.stored_card) + id_card = computer.card_slot.stored_card + if(!id_card?.registered_name) + status_message = "Card Error: Invalid ID Card in Card Reader" + return TRUE + order_details = co.get_list() + + //Check if its already delivered + if(order_details["status"] == "delivered") + status_message = "Unable to Deliver - Order has already been delivered." + return TRUE + + //If a payment is not needed and we are at the status shipped, then confirm the delivery + else if(order_details["status"] == "shipped") + playsound(computer, 'sound/machines/chime.ogg', 50, TRUE) + status_message = co.set_delivered(GetNameAndAssignmentFromId(id_card), usr.character_id) + order_details = co.get_list() + else + status_message = "The order is not yet shipped." + return TRUE + else + status_message = "Unable to process - Network Card or Card Reader Missing" return TRUE + if(action == "pay") if(computer && computer.card_slot && computer.network_card) var/using_id = FALSE var/obj/item/card/id/id_card @@ -77,6 +97,13 @@ using_id = FALSE status_message = "Card Error: Invalid ID Card in Card Reader" + order_details = co.get_list() + + //Check if its already paid for + if(!order_details["needs_payment"]) + status_message = "Unable to pay - Order has already been paid for." + return TRUE + var/obj/item/spacecash/ewallet/charge_card if(!using_id) if(isliving(usr)) @@ -85,14 +112,18 @@ if(!istype(charge_card)) return TRUE - //Check if a payment is required if(order_details["needs_payment"]) var/transaction_amount = order_details["price_customer"] var/transaction_purpose = "Cargo Order #[order_details["order_id"]]" var/transaction_terminal = "Modular Computer #[computer.network_card.identification_id]" if(using_id) - var/status = SSeconomy.transfer_money(id_card.associated_account_number, SScargo.supply_account.account_number,transaction_purpose,transaction_terminal,transaction_amount,null,usr) + var/status + if(destinationact == "Personal") + status = SSeconomy.transfer_money(id_card.associated_account_number, SScargo.supply_account.account_number,transaction_purpose,transaction_terminal,transaction_amount,null,usr) + else + transaction_purpose = "Cargo Order #[order_details["order_id"]] by [id_card.registered_name]" + status = SSeconomy.transfer_money(SSeconomy.get_department_account(destinationact)?.account_number, SScargo.supply_account.account_number,transaction_purpose,transaction_terminal,transaction_amount,null,usr) if(status) status_message = status return TRUE @@ -106,22 +137,10 @@ charge_card.worth -= transaction_amount playsound(computer, 'sound/machines/chime.ogg', 50, TRUE) - - //Check if we have delivered it aswell or only paid - if(order_details["status"] == "shipped") - status_message = co.set_delivered(GetNameAndAssignmentFromId(I), usr.character_id, 1) - else - status_message = co.set_paid(GetNameAndAssignmentFromId(I), usr.character_id) + status_message = co.set_paid(GetNameAndAssignmentFromId(id_card), usr.character_id) order_details = co.get_list() - - else - //If a payment is not needed and we are at the status shipped, then confirm the delivery - if(order_details["status"] == "shipped") - playsound(computer, 'sound/machines/chime.ogg', 50, TRUE) - status_message = co.set_delivered(GetNameAndAssignmentFromId(I), usr.character_id, 0) - order_details = co.get_list() else - status_message = "Unable to process - Network Card or Cardreader Missing" + status_message = "Unable to process - Network Card or Card Reader Missing" return TRUE @@ -147,3 +166,11 @@ else page = "overview_main" //fall back to overview_main if a unknown page has been supplied return TRUE + if(action == "accountselect") + var/list/choices = assoc_to_keys(SSeconomy.department_accounts) + choices += "Personal" + var/dest = tgui_input_list(usr, "What account would you like to select?", "Destination Account", choices) + if(!dest) + return FALSE + destinationact = dest + return TRUE diff --git a/html/changelogs/OperationsDeliveryImprovements.yml b/html/changelogs/OperationsDeliveryImprovements.yml new file mode 100644 index 00000000000..9212e12469e --- /dev/null +++ b/html/changelogs/OperationsDeliveryImprovements.yml @@ -0,0 +1,12 @@ +author: TheGreyWolf + +delete-after: True + +changes: + - rscadd: "Added the ability to charge department accounts directly for operation orders through the operations delivery app, without command presence required." + - rscadd: "Separated the delivery and the pay buttons in the operations delivery app." + - bugfix: "Fixed the display of who accepted a delivery order when printing an invoice." + - bugfix: "Prices shown on the delivery app are now correct." + - bugfix: "The paper spawning in crates from the cargo elevator now properly show the supposed contents." + - rscadd: "The quikpay ui was updated." + diff --git a/tgui/packages/tgui/interfaces/CargoDelivery.tsx b/tgui/packages/tgui/interfaces/CargoDelivery.tsx index bbaf284bb07..4ed762ed7da 100644 --- a/tgui/packages/tgui/interfaces/CargoDelivery.tsx +++ b/tgui/packages/tgui/interfaces/CargoDelivery.tsx @@ -15,6 +15,7 @@ export type CargoData = { order_details: Order; page: string; status_message: string; + paying_account: string; }; type Order = { @@ -160,7 +161,7 @@ export const Overview = (props, context) => { : 'Unauthorised'} - {data.order_details.price}.toFixed(2) 电 + {data.order_details.price.toFixed(2)} 电 {data.order_details.price_cargo.toFixed(2)} 电 @@ -168,9 +169,6 @@ export const Overview = (props, context) => { {data.order_details.price_customer.toFixed(2)} 电 - - {data.order_details.price_customer.toFixed(2)} 电 - {data.order_details.time_submitted} @@ -223,29 +221,41 @@ export const Payment = (props, context) => {
    act('deliver', { deliver: 'true' })} - /> + <> +
    Shuttle Fee::Supplier fee::[shuttle_fee]
    + {data.items.map((item) => ( + + {item.name} + + {item.price.toFixed(2)}电   + + + {!data.editmode ? ( +
    + + + + +
    -   + {' '}
    + } + > + {data.buying.length < 1 ? ( + 'Your shopping cart is empty.' + ) : ( + + )} + +
    + ); }; @@ -148,17 +170,32 @@ export const CartWindow = (props, context) => {
    {data.buying.map((item) => ( - - x{item.amount}  -
    ); };