mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-26 22:42:26 +01:00
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. <img width="575" height="700" alt="image" src="https://github.com/user-attachments/assets/f14c9c0d-39fb-41b1-b3e9-aa479ccc0804" /> <img width="575" height="700" alt="image" src="https://github.com/user-attachments/assets/7e33b8ef-caff-4e11-9e02-7c0ab3b4dba9" /> <img width="452" height="532" alt="image" src="https://github.com/user-attachments/assets/413d8097-1379-432a-91ec-cd7ed13f0832" /> <img width="452" height="532" alt="image" src="https://github.com/user-attachments/assets/8b73ddc0-3dfa-4503-bfcc-972a32687f97" /> <img width="575" height="700" alt="image" src="https://github.com/user-attachments/assets/93663ba7-e443-45f4-8b87-cc04de35faf7" /> <img width="452" height="532" alt="image" src="https://github.com/user-attachments/assets/8d4a1ba7-fbd5-40c9-a5ef-592c2067074e" />
This commit is contained in:
@@ -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 += "<u>Shipped at:</u> [time_shipped]<br>"
|
||||
if(received_by)
|
||||
order_data += "<u>Received by:</u [received_by]><br>"
|
||||
order_data += "<u>Received by:</u> [received_by]<br>"
|
||||
order_data += "<u>Delivered at:</u> [time_delivered]<br>"
|
||||
order_data += "<hr>"
|
||||
order_data += "<u>Order ID:</u> [order_id]<br>"
|
||||
@@ -276,7 +275,7 @@
|
||||
order_data += "<li>[item["name"]]: [item["price"]]</li>"
|
||||
order_data += "<li>Crate Fee: [SScargo.get_cratefee()]</li>"
|
||||
order_data += "<li>Handling Fee: [SScargo.get_handlingfee()]</li>"
|
||||
order_data += "<li>Shuttle Fee: [get_shipment_cost()]</li>"
|
||||
order_data += "<li>Supplier Fee: [get_shipment_cost()]</li>"
|
||||
order_data += "</ul>"
|
||||
|
||||
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 += "<p>Shuttle Data</p>"
|
||||
invoice_data += "<table>"
|
||||
invoice_data += "<tr>"
|
||||
invoice_data += "<td>Shuttle Fee::</td>"
|
||||
invoice_data += "<td>Supplier fee::</td>"
|
||||
invoice_data += "<td>[shuttle_fee]</td>"
|
||||
invoice_data += "</tr>"
|
||||
invoice_data += "<tr>"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Price">
|
||||
{data.order_details.price}.toFixed(2) 电
|
||||
{data.order_details.price.toFixed(2)} 电
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Operations Expense">
|
||||
{data.order_details.price_cargo.toFixed(2)} 电
|
||||
@@ -168,9 +169,6 @@ export const Overview = (props, context) => {
|
||||
<LabeledList.Item label="Personal Expense">
|
||||
{data.order_details.price_customer.toFixed(2)} 电
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Personal Expense">
|
||||
{data.order_details.price_customer.toFixed(2)} 电
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Ordered At">
|
||||
{data.order_details.time_submitted}
|
||||
</LabeledList.Item>
|
||||
@@ -223,29 +221,41 @@ export const Payment = (props, context) => {
|
||||
<Section
|
||||
title={'Payment: Order No. ' + data.order_details.order_id}
|
||||
buttons={
|
||||
<Button
|
||||
content={
|
||||
data.order_details.status === 'shipped'
|
||||
? 'Confirm Delivery and Pay'
|
||||
: data.order_details.status === 'delivered'
|
||||
? 'Delivered Already'
|
||||
: data.order_details.needs_payment
|
||||
? 'Pay'
|
||||
: 'Paid but not Shipped'
|
||||
}
|
||||
disabled={
|
||||
!data.order_details.needs_payment ||
|
||||
data.order_details.status === 'delivered'
|
||||
}
|
||||
icon="check"
|
||||
color="green"
|
||||
onClick={() => act('deliver', { deliver: 'true' })}
|
||||
/>
|
||||
<>
|
||||
<Button
|
||||
content="Account"
|
||||
color="good"
|
||||
onClick={() => act('accountselect')}
|
||||
/>
|
||||
<Button
|
||||
content={
|
||||
data.order_details.status === 'shipped'
|
||||
? 'Confirm Delivery'
|
||||
: data.order_details.status === 'delivered'
|
||||
? 'Delivered Already'
|
||||
: 'Not Shipped'
|
||||
}
|
||||
disabled={data.order_details.status !== 'shipped'}
|
||||
icon="check"
|
||||
color="green"
|
||||
onClick={() => act('deliver', { deliver: 'true' })}
|
||||
/>
|
||||
<Button
|
||||
content="Pay"
|
||||
disabled={!data.order_details.needs_payment}
|
||||
icon="credit-card"
|
||||
color="green"
|
||||
onClick={() => act('pay', { deliver: 'true' })}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Price">
|
||||
{data.order_details.price.toFixed(2)} 电
|
||||
{data.order_details.price_customer.toFixed(2)} 电
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Paying Account">
|
||||
{data.paying_account}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Customer">
|
||||
{data.order_details.ordered_by}
|
||||
|
||||
@@ -6,6 +6,9 @@ import {
|
||||
Input,
|
||||
NumberInput,
|
||||
Section,
|
||||
Flex,
|
||||
Table,
|
||||
Box,
|
||||
} from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
@@ -27,6 +30,7 @@ type Item = {
|
||||
type ItemBuy = {
|
||||
name: string;
|
||||
amount: number;
|
||||
price: number;
|
||||
};
|
||||
|
||||
export const QuikPay = (props, context) => {
|
||||
@@ -39,12 +43,6 @@ export const QuikPay = (props, context) => {
|
||||
title="Ordering"
|
||||
buttons={
|
||||
<>
|
||||
<Button
|
||||
content={data.editmode ? 'Unlocked' : 'Locked'}
|
||||
color={data.editmode ? 'bad' : ''}
|
||||
icon={data.editmode ? 'lock-open' : 'lock'}
|
||||
onClick={() => act('locking')}
|
||||
/>
|
||||
{data.editmode ? (
|
||||
<Button
|
||||
content="Select Account"
|
||||
@@ -53,6 +51,12 @@ export const QuikPay = (props, context) => {
|
||||
onClick={() => act('accountselect')}
|
||||
/>
|
||||
) : null}
|
||||
<Button
|
||||
content={data.editmode ? 'Unlocked' : 'Locked'}
|
||||
color={data.editmode ? 'bad' : ''}
|
||||
icon={data.editmode ? 'lock-open' : 'lock'}
|
||||
onClick={() => act('locking')}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
@@ -69,55 +73,73 @@ export const ItemWindow = (props, context) => {
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<LabeledList>
|
||||
{data.items.map((item) => (
|
||||
<LabeledList.Item key={item.name} label={item.name}>
|
||||
{item.price.toFixed(2)}电
|
||||
<Button
|
||||
content="Buy"
|
||||
icon="calendar"
|
||||
onClick={() => act('buy', { buying: item.name, amount: 1 })}
|
||||
/>
|
||||
{data.editmode ? (
|
||||
<Flex direction="row">
|
||||
<Flex.Item grow={1}>
|
||||
<Section title="For sale" fill>
|
||||
<Table>
|
||||
{data.items.map((item) => (
|
||||
<Table.Row key={item.name}>
|
||||
<Table.Cell>{item.name}</Table.Cell>
|
||||
<Table.Cell align="right">
|
||||
{item.price.toFixed(2)}电
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{!data.editmode ? (
|
||||
<Button
|
||||
content="Buy"
|
||||
icon="calendar"
|
||||
onClick={() =>
|
||||
act('buy', { buying: item.name, amount: 1 })
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
|
||||
<Button
|
||||
content="Delete"
|
||||
icon="trash"
|
||||
color="bad"
|
||||
onClick={() => act('remove', { removing: item.name })}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
</Flex.Item>
|
||||
<Box width="1px" backgroundColor="rgba(255, 255, 255, 0.15)" mx={2} />
|
||||
<Flex.Item grow={1}>
|
||||
<Section
|
||||
fill
|
||||
title="Cart"
|
||||
buttons={
|
||||
<>
|
||||
|
||||
{' '}
|
||||
<Button
|
||||
content="Delete"
|
||||
content="Clear"
|
||||
icon="trash"
|
||||
color="bad"
|
||||
onClick={() => act('remove', { removing: item.name })}
|
||||
onClick={() => act('clear')}
|
||||
/>
|
||||
<Button
|
||||
content="Confirm"
|
||||
icon="check"
|
||||
color={data.sum ? 'good' : ''}
|
||||
onClick={() => act('confirm')}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
<Section
|
||||
title="Cart"
|
||||
buttons={
|
||||
<>
|
||||
{' '}
|
||||
<Button
|
||||
content="Clear"
|
||||
icon="trash"
|
||||
color="bad"
|
||||
onClick={() => act('clear')}
|
||||
/>
|
||||
<Button
|
||||
content="Confirm"
|
||||
icon="check"
|
||||
color={data.sum ? 'good' : ''}
|
||||
onClick={() => act('confirm')}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{data.buying.length < 1 ? (
|
||||
'Your shopping cart is empty.'
|
||||
) : (
|
||||
<CartWindow />
|
||||
)}
|
||||
</Section>
|
||||
}
|
||||
>
|
||||
{data.buying.length < 1 ? (
|
||||
'Your shopping cart is empty.'
|
||||
) : (
|
||||
<CartWindow />
|
||||
)}
|
||||
</Section>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -148,17 +170,32 @@ export const CartWindow = (props, context) => {
|
||||
<Section>
|
||||
<LabeledList>
|
||||
{data.buying.map((item) => (
|
||||
<LabeledList.Item key={item.name} label={item.name}>
|
||||
x{item.amount}
|
||||
<Button
|
||||
content="Remove"
|
||||
icon="times"
|
||||
onClick={() => act('removal', { removal: item.name })}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<Table.Row key={item.name}>
|
||||
<Table.Cell> {item.name}</Table.Cell>
|
||||
<Table.Cell>x{item.amount}</Table.Cell>
|
||||
<Table.Cell align="right">
|
||||
<Flex justify="flex-end">
|
||||
<Flex.Item>{(item.price * item.amount).toFixed(2)}电</Flex.Item>
|
||||
<Flex.Item>
|
||||
|
||||
<Button
|
||||
icon="trash"
|
||||
onClick={() => act('removal', { removal: item.name })}
|
||||
/>
|
||||
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</LabeledList>
|
||||
{data.sum ? 'Please swipe your ID to pay.' : ''}
|
||||
{data.sum ? (
|
||||
<Section color="average">
|
||||
The total is {data.sum.toFixed(2)}电.
|
||||
<br />
|
||||
Please swipe your id to pay.
|
||||
</Section>
|
||||
) : null}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user