diff --git a/SQL/migrate/V057__cargo_logging_table.sql b/SQL/migrate/V057__cargo_logging_table.sql new file mode 100644 index 00000000000..d1a94ec2f95 --- /dev/null +++ b/SQL/migrate/V057__cargo_logging_table.sql @@ -0,0 +1,41 @@ +--- +--- Adds the cargo logging tables +--- + +CREATE TABLE `ss13_cargo_orderlog` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `game_id` VARCHAR(50) NOT NULL DEFAULT '' COLLATE 'utf8mb4_unicode_ci', + `order_id` INT(11) NOT NULL, + `status` VARCHAR(50) NOT NULL DEFAULT '' COLLATE 'utf8mb4_unicode_ci', + `price` INT(11) NOT NULL DEFAULT '0', + `ordered_by_id` INT(11) NULL DEFAULT NULL, + `ordered_by` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', + `authorized_by_id` INT(11) NULL DEFAULT NULL, + `authorized_by` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', + `received_by_id` INT(11) NULL DEFAULT NULL, + `received_by` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', + `paid_by_id` INT(11) NULL DEFAULT NULL, + `paid_by` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', + `time_submitted` TIME NULL DEFAULT NULL, + `time_approved` TIME NULL DEFAULT NULL, + `time_shipped` TIME NULL DEFAULT NULL, + `time_delivered` TIME NULL DEFAULT NULL, + `time_paid` TIME NULL DEFAULT NULL, + `reason` TEXT(65535) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', + PRIMARY KEY (`id`) USING BTREE +) +COLLATE='utf8mb4_unicode_ci' +ENGINE=InnoDB; + +CREATE TABLE `ss13_cargo_orderlog_items` ( + `cargo_orderlog_id` INT(11) UNSIGNED NOT NULL, + `cargo_item_id` INT(11) UNSIGNED NOT NULL, + `amount` INT(11) NOT NULL, + PRIMARY KEY (`cargo_orderlog_id`, `cargo_item_id`) USING BTREE, + INDEX `index_orderlog_id` (`cargo_orderlog_id`) USING BTREE, + INDEX `index_item_id` (`cargo_item_id`) USING BTREE, + CONSTRAINT `FK_ss13_cargo_orderlog_items_ss13_cargo_items` FOREIGN KEY (`cargo_item_id`) REFERENCES `ss13_cargo_items` (`id`) ON UPDATE CASCADE ON DELETE CASCADE, + CONSTRAINT `FK_ss13_cargo_orderlog_items_ss13_cargo_orderlog` FOREIGN KEY (`cargo_orderlog_id`) REFERENCES `ss13_cargo_orderlog` (`id`) ON UPDATE CASCADE ON DELETE CASCADE +) +COLLATE='utf8mb4_unicode_ci' +ENGINE=InnoDB; diff --git a/code/controllers/subsystems/cargo.dm b/code/controllers/subsystems/cargo.dm index 8faf7998a70..11ca579a379 100644 --- a/code/controllers/subsystems/cargo.dm +++ b/code/controllers/subsystems/cargo.dm @@ -42,6 +42,9 @@ var/datum/controller/subsystem/cargo/SScargo //Item vars var/last_item_id = 0 //The ID of the last item that has been added + //Bool to indicate if orders have been dumped + var/dumped_orders = FALSE + //Exports and bounties var/list/exports_list = list() var/list/bounties_list = list() @@ -707,3 +710,75 @@ var/datum/controller/subsystem/cargo/SScargo charge_cargo("Shipment #[current_shipment.shipment_num] - Expense",current_shipment.shipment_cost_purchase) return 1 + +//Dumps the cargo orders to the database when the round ends +/datum/controller/subsystem/cargo/proc/dump_orders() + if(dumped_orders) + log_debug("SScargo: Order Data Dump Aborted - Orders already dumped") + return + if(config.cargo_load_items_from != "sql") + log_debug("SScargo: Order Data Dump Aborted - Cargo not loaded from database") + return + if(!establish_db_connection(dbcon)) + log_debug("SScargo: SQL ERROR - Failed to connect. - Unable to dump order data") + return + + dumped_orders = TRUE + + // Loop through all the orders and dump them all + var/DBQuery/dump_query = dbcon.NewQuery("INSERT INTO `ss13_cargo_orderlog` (`game_id`, `order_id`, `status`, `price`, `ordered_by_id`, `ordered_by`, `authorized_by_id`, `authorized_by`, `received_by_id`, `received_by`, `paid_by_id`, `paid_by`, `time_submitted`, `time_approved`, `time_shipped`, `time_delivered`, `time_paid`, `reason`) \ + VALUES (:game_id:, :order_id:, :status:, :price:, :ordered_by_id:, :ordered_by:, :authorized_by_id:, :authorized_by:, :received_by_id:, :received_by:, :paid_by_id:, :paid_by:, :time_submitted:, :time_approved:, :time_shipped:, :time_delivered:, :time_paid:, :reason:)") + var/DBQuery/dump_item_query = dbcon.NewQuery("INSERT INTO `ss13_cargo_orderlog_items` (`cargo_orderlog_id`, `cargo_item_id`, `amount`) \ + VALUES (:cargo_orderlog_id:, :cargo_item_id:, :amount:)") + var/DBQuery/log_id = dbcon.NewQuery("SELECT LAST_INSERT_ID() AS log_id") + for(var/datum/cargo_order/co in all_orders) + //Iterate over the items in the order and build the a list with the item count + var/list/itemcount = list() + for(var/datum/cargo_order_item/coi in co.items) + if(!isnull(itemcount["[coi.ci.id]"])) + itemcount["[coi.ci.id]"] = itemcount["[coi.ci.id]"] + 1 + else + itemcount["[coi.ci.id]"] = 1 + + if(!dump_query.Execute(list( + "game_id"=game_id, + "order_id"=co.order_id, + "status"=co.status, + "price"=co.price, + "ordered_by_id"=co.ordered_by_id, + "ordered_by"=co.ordered_by, + "authorized_by_id"=co.authorized_by_id, + "authorized_by"=co.authorized_by, + "received_by_id"=co.received_by_id, + "received_by"=co.received_by, + "paid_by_id"=co.paid_by_id, + "paid_by"=co.paid_by, + "time_submitted"=co.time_submitted, + "time_approved"=co.time_approved, + "time_shipped"=co.time_shipped, + "time_delivered"=co.time_delivered, + "time_paid"=co.time_paid, + "reason"=co.reason + ))) + log_debug("SScargo: SQL ERROR - Cound not write order to database") + continue + + //Run the query to get the inserted id + log_id.Execute() + + var/db_log_id = null + if (log_id.NextRow()) + db_log_id = text2num(log_id.item[1]) + + if(db_log_id) + for(var/item_id in itemcount) + dump_item_query.Execute(list( + "cargo_orderlog_id"=db_log_id, + "cargo_item_id"=item_id, + "amount"=itemcount[item_id] + )) + CHECK_TICK + + +/hook/roundend/proc/dump_cargoorders() + SScargo.dump_orders() diff --git a/code/datums/cargo.dm b/code/datums/cargo.dm index 7c694ad61c2..3519760b284 100644 --- a/code/datums/cargo.dm +++ b/code/datums/cargo.dm @@ -111,11 +111,15 @@ var/status = "basket" //Status of the order: basket - Adding items, submitted - Submitted to cargo, approved - Order sent to suppliers, rejected - Order has been denied, shipped - Has been shipped to the station, delivered - Order has been delivered var/container_type = "" //Type of the container for the order - cate, box var/list/required_access = list() //Access required to unlock the crate - var/can_add_items = 1 //If new items can be added to the order + var/can_add_items = 1 //If new items can be added to the order var/ordered_by = null //Person that ordered the items + var/ordered_by_id = null //Character ID of the person that ordered the items var/authorized_by = null //Person that authorized the order + var/authorized_by_id = null //Character ID of the person that authorized the items var/received_by = null //Person the order has been delivered to by cargo + var/received_by_id = null //Character ID of the person that received the items var/paid_by = null //Person that has paid for the order + var/paid_by_id = null //Character ID of the Person that paid for the items var/time_submitted = null //Time the order has been sent to cargo var/time_approved = null //Time the order has been approved by cargo var/time_shipped = null //Time the order has been shipped to the station @@ -181,7 +185,7 @@ container_type = coi.ci.container_type else if (container_type != coi.ci.container_type) return "Unable to add item - Different container required" //You can only add items with the same container type to the order - + //Check if more items can be added to the order if(!can_add_items) return "Unable to add item - Order can not contain more items" @@ -227,7 +231,7 @@ return "Unable to remove item - Internal Error 608" // Returns the value of the order -/datum/cargo_order/proc/get_value(var/type=0) +/datum/cargo_order/proc/get_value(var/type=0) //Type specifies if the price cargo has to pay or the price the customer has to be should be returned // 0 - Price the customer has to pay // 1 - Price cargo has to pay @@ -389,11 +393,17 @@ for(var/object in get_object_list()) order_data += "
  • [object]
  • " order_data += "" - + return order_data.Join("") //Marks a order as submitted -/datum/cargo_order/proc/set_submitted(var/oid) +/datum/cargo_order/proc/set_submitted(var/user_name, var/user_id, var/order_reason) + if(user_id <= 0) + user_id = null + + ordered_by = user_name + ordered_by_id = user_id + reason = order_reason status = "submitted" time_submitted = worldtime2text() order_id = SScargo.get_next_order_id() @@ -401,11 +411,14 @@ return 1 //Marks a order as approved - Returns a status message -/datum/cargo_order/proc/set_approved(var/approved_by) +/datum/cargo_order/proc/set_approved(var/user_name, var/user_id) + if(user_id <= 0) + user_id = null if(status == "submitted") status = "approved" time_approved = worldtime2text() - authorized_by = approved_by + authorized_by = user_name + authorized_by_id = user_id return "The order has been approved" else return "The order could not be approved - Invalid Status" @@ -425,21 +438,27 @@ time_shipped = worldtime2text() //Marks a order as delivered - Returns a status message -/datum/cargo_order/proc/set_delivered(var/customer_name, var/paid=0) +/datum/cargo_order/proc/set_delivered(var/user_name, var/user_id, var/paid=0) + if(user_id <= 0) + user_id = null if(status == "shipped") status = "delivered" time_delivered = worldtime2text() - received_by = customer_name + received_by = user_name + received_by_id = user_id if(paid) - set_paid(customer_name) + set_paid(user_name, user_id) return "The order has been delivered" else return "The order could not be delivered - Invalid Status" //Mark a order as paid -/datum/cargo_order/proc/set_paid(var/customer_name) +/datum/cargo_order/proc/set_paid(var/user_name, var/user_id) + if(user_id <= 0) + user_id = null time_paid = worldtime2text() - paid_by = customer_name + paid_by = user_name + paid_by_id = user_id return "The order has been paid for" /* @@ -559,4 +578,4 @@ generate_invoice() else return "Invoice Unavailable. Shipment not completed." - return shipment_invoice \ No newline at end of file + return shipment_invoice diff --git a/code/modules/modular_computers/file_system/programs/civilian/cargo_control.dm b/code/modules/modular_computers/file_system/programs/civilian/cargo_control.dm index de2edc5301b..67ada1d53bb 100644 --- a/code/modules/modular_computers/file_system/programs/civilian/cargo_control.dm +++ b/code/modules/modular_computers/file_system/programs/civilian/cargo_control.dm @@ -13,7 +13,6 @@ /datum/nano_module/program/civilian/cargocontrol name = "Cargo Control" var/page = "overview_main" //overview_main - Main Menu, overview_submitted - Submitted Order Overview, overview_approved - Approved Order Overview, settings - Settings, details - order details, bounties - centcom bounties - var/last_user_name = "" //Name of the User that last used the computer var/status_message //A status message that can be displayed var/list/order_details = list() //Order Details for the order var/list/shipment_details = list() //Shipment Details for a selected shipment @@ -29,10 +28,7 @@ //Send the status message data["status_message"] = status_message - //Pass the ID Data - var/obj/item/card/id/user_id_card = user.GetIdCard() - last_user_name = GetNameAndAssignmentFromId(user_id_card) - data["username"] = last_user_name + data["username"] = GetNameAndAssignmentFromId(user.GetIdCard()) var/list/submitted_orders = SScargo.get_orders_by_status("submitted",1) data["order_submitted_number"] = submitted_orders.len @@ -108,6 +104,11 @@ ui.set_auto_update(TRUE) /datum/nano_module/program/civilian/cargocontrol/Topic(href, href_list) + if(..()) + return TRUE + + var/obj/item/card/id/I = usr.GetIdCard() + var/datum/shuttle/autodock/ferry/supply/shuttle = SScargo.shuttle var/obj/item/modular_computer/console = program.computer if (!shuttle) @@ -150,7 +151,7 @@ if(href_list["order_approve"]) var/datum/cargo_order/co = SScargo.get_order_by_id(text2num(href_list["order_approve"])) if(co) - var/message = co.set_approved(last_user_name) + var/message = co.set_approved(GetNameAndAssignmentFromId(I), usr.character_id) if(message) status_message = message return TRUE @@ -166,7 +167,7 @@ //Send shuttle if(href_list["shuttle_send"]) - var/message = SScargo.shuttle_call(last_user_name) + var/message = SScargo.shuttle_call(GetNameAndAssignmentFromId(I)) if(message) status_message = message return TRUE @@ -260,4 +261,4 @@ status_signal.transmission_method = 1 status_signal.data["command"] = command - frequency.post_signal(src, status_signal) \ No newline at end of file + frequency.post_signal(src, status_signal) 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 9f02178accc..fa10dc2de34 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 @@ -12,7 +12,6 @@ /datum/nano_module/program/civilian/cargodelivery name = "Cargo Delivery" var/page = "overview_main" //overview_main - Main Menu, order_overview - Overview page for a specific order, order_payment - Payment page for a specific order - var/last_user_name = "" //Name of the User that last used the computer var/status_message //A status message that can be displayed var/list/order_details = list() //Order Details for the order var/datum/cargo_order/co @@ -34,7 +33,6 @@ data["id_account_number"] = id_card ? id_card.associated_account_number : null data["id_owner"] = id_card && id_card.registered_name ? id_card.registered_name : "-----" data["id_name"] = id_card ? id_card.name : "-----" - last_user_name = data["id_owner"] //Pass the shipped orders data["order_list"] = SScargo.get_orders_by_status("shipped",1) + SScargo.get_orders_by_status("approved",1) @@ -61,6 +59,7 @@ if(..()) return TRUE + 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) @@ -96,16 +95,16 @@ //Check if we have delivered it aswell or only paid if(order_details["status"] == "shipped") - status_message = co.set_delivered(id_card.registered_name,1) + status_message = co.set_delivered(GetNameAndAssignmentFromId(I), usr.character_id, 1) else - status_message = co.set_paid(id_card.registered_name) + status_message = co.set_paid(GetNameAndAssignmentFromId(I), usr.character_id) order_details = co.get_list() else - //TODO: Add a sound effect here //If a payment is not needed and we are at the status shipped, then confirm the delivery if(order_details["status"] == "shipped") - status_message = co.set_delivered(id_card.registered_name,0) + playsound(program.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" @@ -113,12 +112,8 @@ //But only cargo can switch between the pages - var/mob/user = usr - if(!istype(user)) - return - var/obj/item/card/id/I = user.GetIdCard() - if(!istype(I) || !I.registered_name || !(access_cargo in I.access) || issilicon(user)) - to_chat(user, SPAN_WARNING("Authentication error: Unable to locate ID with appropriate access to allow this operation.")) + if(!istype(I) || !I.registered_name || !(access_cargo in I.access) || issilicon(usr)) + to_chat(usr, SPAN_WARNING("Authentication error: Unable to locate ID with appropriate access to allow this operation.")) return if(href_list["page"]) diff --git a/code/modules/modular_computers/file_system/programs/civilian/cargo_order.dm b/code/modules/modular_computers/file_system/programs/civilian/cargo_order.dm index a144d1db395..7664510e054 100644 --- a/code/modules/modular_computers/file_system/programs/civilian/cargo_order.dm +++ b/code/modules/modular_computers/file_system/programs/civilian/cargo_order.dm @@ -14,7 +14,6 @@ var/selected_category = "" // Category that is currently selected var/selected_item = "" // Path of the currently selected item var/datum/cargo_order/co - var/last_user_name = "" //Name of the user that used the program var/status_message //Status Message to be displayed to the user var/user_tracking_id = 0 //Tracking id of the user var/user_tracking_code = 0 //Tracking Code of the user @@ -28,14 +27,7 @@ var/list/data = host.initial_data() //Pass the ID Data - var/obj/item/card/id/user_id_card = user.GetIdCard() - if(!user_id_card) - last_user_name = "Unknown" - else - last_user_name = user_id_card.registered_name - - - data["username"] = last_user_name + data["username"] = GetNameAndAssignmentFromId(user.GetIdCard()) //Pass the list of all ordered items and the order value data["order_items"] = co.get_item_list() @@ -92,12 +84,14 @@ if(..()) return TRUE + var/obj/item/card/id/I = usr.GetIdCard() + //Send the order to cargo if(href_list["submit_order"]) if(!co.items.len) return TRUE //Only submit the order if there are items in it - if(last_user_name == "Unknown") + if(!I) status_message = "Unable to submit order. ID could not be located." return TRUE @@ -106,9 +100,7 @@ status_message = "Unable to submit order. No reason supplied." return TRUE - co.ordered_by = last_user_name - co.reason = reason - co.set_submitted() + co.set_submitted(GetNameAndAssignmentFromId(I), usr.character_id, reason) status_message = "Order submitted successfully. Order ID: [co.order_id] Tracking code: [co.get_tracking_code()]" //TODO: Print a list with the order data co = null @@ -175,4 +167,4 @@ if(href_list["clear_message"]) status_message = null - return TRUE \ No newline at end of file + return TRUE diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index ac99898734b..10a44c97ae4 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -101,10 +101,9 @@ ui.open() ui.set_auto_update(1) -/obj/machinery/computer/shuttle_control/Topic(user, href_list) +/obj/machinery/computer/shuttle_control/Topic(href_list, href_list) ..() - - handle_topic_href(SSshuttle.shuttles[shuttle_tag], href_list, user) + handle_topic_href(SSshuttle.shuttles[shuttle_tag], href_list, usr) /obj/machinery/computer/shuttle_control/emag_act(var/remaining_charges, var/mob/user) if(!hacked)