aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarf20 <aruizfernandez05@gmail.com>2024-03-20 17:31:54 +0100
committerarf20 <aruizfernandez05@gmail.com>2024-03-20 17:31:54 +0100
commit795940c0f278b7e2ff4ff7b0e328dca480662a1c (patch)
tree25b458537c49f90929ce944949c9cc73a288ca5e
parent041786bff99e94ea895bcbcd4cb257e53bd152b1 (diff)
downloadarfnet2-cstims-795940c0f278b7e2ff4ff7b0e328dca480662a1c.tar.gz
arfnet2-cstims-795940c0f278b7e2ff4ff7b0e328dca480662a1c.zip
Add ticket and ticket management
-rw-r--r--dbinit.sql13
-rw-r--r--managetickets.php213
-rw-r--r--openticket.php189
3 files changed, 414 insertions, 1 deletions
diff --git a/dbinit.sql b/dbinit.sql
index b505dbc..017f60a 100644
--- a/dbinit.sql
+++ b/dbinit.sql
@@ -28,7 +28,18 @@ CREATE TABLE `arfnet2`.`orders` (
`client` INT NOT NULL ,
`billing` VARCHAR(255) NOT NULL ,
`date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
- `status` ENUM('setting up','active','inactive') NOT NULL ,
+ `status` ENUM('setting up','active','inactive') NOT NULL DEFAULT 'setting up' ,
`comments` TEXT NOT NULL ,
PRIMARY KEY (`id`)
);
+
+CREATE TABLE `arfnet2`.`tickets` (
+ `id` INT NOT NULL AUTO_INCREMENT ,
+ `order` INT NOT NULL ,
+ `subject` VARCHAR(255) NOT NULL ,
+ `body` TEXT NOT NULL ,
+ `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
+ `status` ENUM('open','closed') NOT NULL DEFAULT 'open' ,
+ `asignee` INT NOT NULL ,
+ PRIMARY KEY (`id`)
+);
diff --git a/managetickets.php b/managetickets.php
new file mode 100644
index 0000000..02c2871
--- /dev/null
+++ b/managetickets.php
@@ -0,0 +1,213 @@
+<?php
+
+session_start();
+
+if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true){
+ header("location: /login.php");
+ exit;
+}
+
+$username = $_SESSION["username"];
+$type = $_SESSION["type"];
+
+if ($type != "admin") die("Permission denied.");
+
+require_once "config.php";
+
+// Get users
+$sql = "SELECT id, username, type FROM users";
+$stmt = mysqli_prepare($link, $sql);
+mysqli_stmt_execute($stmt);
+$result = mysqli_stmt_get_result($stmt);
+$users = $result->fetch_all(MYSQLI_ASSOC);
+
+// Get services
+$sql = "SELECT id, name, type, billing, description FROM services";
+$stmt = mysqli_prepare($link, $sql);
+mysqli_stmt_execute($stmt);
+$result = mysqli_stmt_get_result($stmt);
+$services = $result->fetch_all(MYSQLI_ASSOC);
+
+// Get orders
+$sql = "SELECT id, service, name, client, date, billing, status, comments FROM orders";
+$stmt = mysqli_prepare($link, $sql);
+mysqli_stmt_execute($stmt);
+$result = mysqli_stmt_get_result($stmt);
+$orders = $result->fetch_all(MYSQLI_ASSOC);
+
+// Get tickets
+$sql = "SELECT id, `order`, subject, body, date, status, asignee FROM tickets";
+$stmt = mysqli_prepare($link, $sql);
+mysqli_stmt_execute($stmt);
+$result = mysqli_stmt_get_result($stmt);
+$tickets = $result->fetch_all(MYSQLI_ASSOC);
+
+// GET actions
+// delete entry
+if (isset($_GET["del"])) {
+ $sql = "DELETE FROM tickets WHERE id = ?";
+ $stmt = mysqli_prepare($link, $sql);
+ mysqli_stmt_bind_param($stmt, "s", $param_id);
+ $param_id = $_GET["del"];
+ if (!mysqli_stmt_execute($stmt) || mysqli_stmt_affected_rows($stmt) != 1) {
+ echo "SQL error.";
+ } else header("location: ".$_SERVER['SCRIPT_NAME']);
+}
+
+// POST actions
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ // add entry
+ if (isset($_POST["add"])) {
+ $sql = "INSERT INTO tickets (`order`, subject, body, status, asignee) VALUES (?, ?, ?, ?, ?)";
+ $stmt = mysqli_prepare($link, $sql);
+ mysqli_stmt_bind_param($stmt, "sssss", $param_order, $param_subject, $param_body, $param_status, $param_asignee);
+ $param_order = $_POST["order"];
+ $param_subject = $_POST["subject"];
+ $param_body = $_POST["body"];
+ $param_status = $_POST["status"];
+ $param_asignee = $_POST["asignee"];
+
+ if (!mysqli_stmt_execute($stmt) || (mysqli_stmt_affected_rows($stmt) != 1)) {
+ echo "SQL error.";
+ } else header("location: ".$_SERVER['SCRIPT_NAME']);
+ }
+
+ // edit entry
+ if (isset($_POST["save"])) {
+ $sql = "UPDATE tickets SET status = ?, asignee = ? WHERE id = ?";
+ $stmt = mysqli_prepare($link, $sql);
+ mysqli_stmt_bind_param($stmt, "sss", $param_status, $param_asignee, $param_id);
+ $param_status = $_POST["status"];
+ $param_asignee = $_POST["asignee"];
+ $param_id = $_POST["id"];
+
+ if (!mysqli_stmt_execute($stmt) || (mysqli_stmt_affected_rows($stmt) != 1)) {
+ echo "SQL error.";
+ } else header("location: ".$_SERVER['SCRIPT_NAME']);
+ }
+}
+
+function getticketbyid($id) {
+ global $tickets;
+ foreach ($tickets as $ticket) {
+ if ($ticket["id"] == $id) {
+ return $ticket;
+ }
+ }
+}
+
+function getorderbyid($id) {
+ global $orders;
+ foreach ($orders as $order) {
+ if ($order["id"] == $id) {
+ return $order;
+ }
+ }
+}
+
+function getservicebyid($id) {
+ global $services;
+ foreach ($services as $service) {
+ if ($service["id"] == $id) {
+ return $service;
+ }
+ }
+}
+
+function getuserbyid($id) {
+ global $users;
+ foreach ($users as $user) {
+ if ($user["id"] == $id) {
+ return $user;
+ }
+ }
+}
+
+?>
+
+<!doctype html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <title>ARFNET CSTIMS</title>
+ </head>
+ <body>
+ <header><a href="https://arf20.com/">
+ <img src="arfnet_logo.png" width="64"><span class="title"><strong>ARFNET</strong></span>
+ </a></header>
+ <hr>
+ <main>
+ <div class="row">
+ <div class="col8">
+ <h2 class="center">ARFNET Client Service Ticket and Invoice Management System</h2>
+ <h3><?php echo strtoupper($type[0]).substr($type, 1); ?> panel</h3>
+ <h3>Tickets</h3>
+ <?php
+ if (isset($_GET["edit"])) {
+ $ticket = getticketbyid($_GET["edit"]);
+ $asignee_options = "";
+ foreach ($users as $user)
+ if ($user["type"] == "admin" || $user["type"] == "helpdesk")
+ $asignee_options .= "<option value=\"".$user["id"]."\" ".($ticket["asignee"] == $user["id"] ? "selected" : "").">".$user["username"]."</option>";
+ echo "<div class=\"form\"><h3>Edit ticket ".$ticket["id"]."</h3><form action=\"".$_SERVER['SCRIPT_NAME']."\" method=\"post\">\n"
+ ."<label>Instance</label><br><label>".getorderbyid($ticket["order"])["name"]."</label><br>\n"
+ ."<label>Service</label><br><label>".getservicebyid(getorderbyid($ticket["order"])["service"])["name"]."</label><br>\n"
+ ."<label>Client</label><br><label>".getuserbyid(getorderbyid($ticket["order"])["client"])["username"]."</label><br>\n"
+ ."<label>Subject</label><br><label>".$ticket["subject"]."</label><br>\n"
+ ."<label>Body</label><br><pre>".$ticket["body"]."</pre><br>\n"
+ ."<label>Status</label><br><select name=\"status\"><option value=\"open\" ".($ticket["status"] == "open" ? "selected" : "").">open</option><option value=\"closed\" ".($order["status"] == "closed" ? "selected" : "").">closed</option></select><br>\n"
+ ."<label>Asignee</label><br><select name=\"asignee\">$asignee_options</select><br>\n"
+ ."<input type=\"hidden\" name=\"id\" value=\"".$ticket["id"]."\">"
+ ."<br><input type=\"submit\" name=\"save\" value=\"Save\"><a href=\"".$_SERVER['SCRIPT_NAME']."\">cancel</a>"
+ ."</form></div>";
+ }
+
+ if (isset($_GET["add"])) {
+ $order_options = $asignee_options = "";
+ foreach ($orders as $order)
+ $order_options .= "<option value=\"".$order["id"]."\">".$order["name"]." (".getservicebyid($order["service"])["name"].")</option>";
+ foreach ($users as $user)
+ if ($user["type"] == "admin" || $user["type"] == "helpdesk")
+ $asignee_options .= "<option value=\"".$user["id"]."\">".$user["username"]."</option>";
+ echo "<div class=\"form\"><h3>Add ticket</h3><form action=\"".$_SERVER["SCRIPT_NAME"]."\" method=\"post\">\n"
+ ."<label>Order</label><br><select name=\"order\">".$order_options."</select><br>"
+ ."<label>Subject</label><br><input type=\"text\" name=\"subject\"><br>\n"
+ ."<label>Body</label><br><textarea name=\"body\" rows=\"10\" cols=\"80\"></textarea><br>\n"
+ ."<label>Status</label><br><select name=\"status\"><option value=\"open\">open</option><option value=\"closed\">closed</option></select><br>\n"
+ ."<label>Asignee</label><br><select name=\"asignee\">$asignee_options</select><br>\n"
+ ."<br><input type=\"submit\" name=\"add\" value=\"Add\"><a href=\"".$_SERVER["SCRIPT_NAME"]."\">cancel</a>"
+ ."</form></div>";
+ }
+ ?>
+
+ <a href="?add">add</a>
+ <table>
+ <tr><th>id</th><th>order</th><th>service</th><th>client</th><th>subject</th><th>body</th><th>status</th><th>asignee</th><th>action</th></tr>
+ <?php
+ foreach ($tickets as $ticket) {
+ $order = getorderbyid($ticket["order"]);
+ echo "<tr><td>".$ticket["id"]."</td>"
+ ."<td>".$order["name"]."</td>"
+ ."<td>".getservicebyid($order["service"])["name"]."</td>"
+ ."<td>".getuserbyid(getorderbyid($ticket["order"])["client"])["username"]."</td>"
+ ."<td>".$ticket["subject"]."</td>"
+ ."<td><pre>".$ticket["body"]."</pre></td>"
+ ."<td>".$ticket["status"]."</td>"
+ ."<td>".getuserbyid($ticket["asignee"])["username"]."</td>"
+ ."<td><a href=\"?del=".$ticket["id"]."\">del</a> <a href=\"?edit=".$ticket["id"]."\">edit</a></td></tr>\n";
+ }
+ ?>
+ </table>
+
+ </div>
+ <div class="col2">
+ <h3>Logged as <?php echo $username; ?></h3>
+ <h3><a href="/logout.php">Logout</h2>
+ <h3><a href="/admin.php">Back to admin panel</h2>
+ </div>
+ </div>
+ </main>
+ </body>
+</html>
+
diff --git a/openticket.php b/openticket.php
new file mode 100644
index 0000000..4448f7b
--- /dev/null
+++ b/openticket.php
@@ -0,0 +1,189 @@
+<?php
+
+session_start();
+
+if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true){
+ header("location: /login.php");
+ exit;
+}
+
+$clientid = $_SESSION["id"];
+$username = $_SESSION["username"];
+$type = $_SESSION["type"];
+
+require_once "config.php";
+
+// Get orders
+$sql = "SELECT id, name FROM orders WHERE client = ?";
+$stmt = mysqli_prepare($link, $sql);
+mysqli_stmt_bind_param($stmt, "s", $param_client);
+$param_client = $clientid;
+mysqli_stmt_execute($stmt);
+$result = mysqli_stmt_get_result($stmt);
+$services = $result->fetch_all(MYSQLI_ASSOC);
+
+// POST actions
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ // add entry
+ $sql = "INSERT INTO orders (service, name, client, billing, comments) VALUES (?, ?, ?, ?, ?)";
+ $stmt = mysqli_prepare($link, $sql);
+ mysqli_stmt_bind_param($stmt, "sssss", $param_service, $param_name, $param_client, $param_billing, $param_comments);
+ $param_service = $_POST["service"];
+ $param_name = $_POST["name"];
+ $param_client = $clientid;
+ $param_billing = $_POST["billing"];
+ $param_comments = $_POST["comments"];
+
+ if (!mysqli_stmt_execute($stmt) || (mysqli_stmt_affected_rows($stmt) != 1)) {
+ echo "SQL error.";
+ } else {
+ // send admin mail
+ // Get admin mails
+ $sql = "SELECT email FROM users WHERE type = 'admin'";
+ $stmt = mysqli_prepare($link, $sql);
+ mysqli_stmt_execute($stmt);
+ $result = mysqli_stmt_get_result($stmt);
+ $admins = $result->fetch_all(MYSQLI_ASSOC);
+
+ foreach ($admins as $admin) {
+ $mailer->addAddress($admin["email"]);
+ }
+
+ $mailer->Subject = "New service order request";
+ $mailer->Body = "Admins,\n\nUser $username requested service ".getservicebyid($_POST["service"])["name"]."\n\n"
+ ."Instance name: ".$_POST["name"]."\n"
+ ."Calculated billing: ".$_POST["billing"]."\n"
+ ."Comments:\n"
+ .$_POST["comments"]
+ ."\n\n--\nARFNET Client, Service, Ticket and Invoice Management System\nhttps://arf20.com";
+ if (!$mailer->send()) {
+ echo 'Mailer Error [ask arf20]: ' . $mailer->ErrorInfo;
+ } else header("location: ".$_SERVER['SCRIPT_NAME']);
+ }
+}
+
+function getservicebyid($id) {
+ global $services;
+ foreach ($services as $service) {
+ if ($service["id"] == $id) {
+ return $service;
+ }
+ }
+}
+
+function genoption($id, $name) {
+ return "<input type=\"radio\" name=\"service\" id=\"$id\" onclick=\"selectservice($id)\" value=\"$id\">"
+ ."<label for=\"$id\">$name</label><br>\n";
+}
+
+?>
+
+<!doctype html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <title>ARFNET CSTIMS</title>
+ <script type="text/javascript">
+ var services = <?php echo json_encode($services); ?>;
+ var service;
+ function selectservice(id) {
+ service = services.find((element) => element["id"] == id);
+ document.getElementById("pricelabel").innerHTML = "Price: " + service["billing"];
+ document.getElementById("description").innerHTML = service["description"];
+ if (service["name"] == "vps") {
+ document.getElementById("extraform").innerHTML
+ = `<label><b>Options</b></label><br><label>Cores</label><br><select id=\"cpus\" onclick=\"update()\"><option value=\"1\">1</option><option value=\"2\">2</option><option value=\"3\">3</option><option value=\"4\">4</option></select><br>
+ <label>Memory</label><br><select id=\"mem\" onclick=\"update()\"><option value=\"1\">1GB</option><option value=\"2\">2GB</option><option value=\"4\">4GB</option><option value=\"8\">8GB</option></select><br>
+ <label>SSD</label><br><select id=\"ssd\" onclick=\"update()\"><option value=\"5\">5GB</option><option value=\"10\">10GB</option><option value=\"15\">15GB</option><option value=\"20\">20GB</option><option value=\"30\">30GB</option></select><br>
+ <br><label id=\"calculated\">Calculated price: </label>`;
+ } else document.getElementById("extraform").innerHTML = "";
+ update();
+ }
+
+ function update() {
+ var comment = document.getElementById("commentbox").value;
+ if (service["name"] == "vps") {
+ var cpus = document.getElementById("cpus").value;
+ var mem = document.getElementById("mem").value;
+ var ssd = document.getElementById("ssd").value;
+ document.getElementById("comments").value = "Options:\ncpus: " + cpus + "\nmem: " + mem + "GB\nssd: " + ssd + "GB\n\nClient comment:\n" + comment;
+ var price = (1*Number(cpus)**2) + (0.5*Number(mem)**2) + (0.02*Number(ssd)**2);
+ document.getElementById("calculated").innerHTML = "Calculated price: " + price + " €/mo";
+ document.getElementById("billing").value = price + " €/mo";
+ } else {
+ document.getElementById("comments").value = "Client comment:\n" + comment;
+ document.getElementById("billing").value = service["billing"];
+ }
+ }
+ </script>
+ </head>
+ <body>
+ <header><a href="https://arf20.com/">
+ <img src="arfnet_logo.png" width="64"><span class="title"><strong>ARFNET</strong></span>
+ </a></header>
+ <hr>
+ <main>
+ <div class="row">
+ <div class="col8">
+ <h2>ARFNET Client Service Ticket and Invoice Management System</h2>
+ <h3><?php echo strtoupper($type[0]).substr($type, 1); ?> panel</h3>
+ <div class="form">
+ <h3>Order a new service</h3>
+ <form action="<?php echo $_SERVER['SCRIPT_NAME']; ?>" method="post">
+ <div class="border">
+ <label><b>Service</b></label><br>
+ <div class="row">
+ <div class="col">
+ <label>Premium</dev><br>
+ <?php
+ foreach ($services as $service) {
+ if ($service["type"] != "premium") continue;
+ echo genoption($service["id"], $service["name"]);
+ }
+ ?>
+ </div>
+ <div class="col">
+ <label>Standard</dev><br>
+ <?php
+ foreach ($services as $service) {
+ if ($service["type"] != "standard") continue;
+ echo genoption($service["id"], $service["name"]);
+ }
+ ?>
+ </div>
+ <div class="col">
+ <label>Free</dev><br>
+ <?php
+ foreach ($services as $service) {
+ if ($service["type"] != "free") continue;
+ echo genoption($service["id"], $service["name"]);
+ }
+ ?>
+ </div>
+ </div>
+ </div>
+ <br><label>Description</label><pre id="description"></pre>
+ <label id="pricelabel">Price: </label><br>
+ <br><div class="border" id="extraform"></div>
+ <br><label>Instance name</label><br>
+ <input type=text name="name"><br>
+ <div id="commentcontainer">
+ <br><label>Comments (describe use case and requirements)</label><br>
+ <textarea id="commentbox" rows="10" cols="80" onchange="update()"></textarea><br>
+ </div>
+ <input type="hidden" name="billing" id="billing">
+ <input type="hidden" name="comments" id="comments">
+ <br><input type="submit" value="Place order">
+ </form>
+ </div>
+ </div>
+ <div class="col2">
+ <h3>Logged as <?php echo $username; ?></h3>
+ <h3><a href="/logout.php">Logout</h2>
+ <h3><a href="/client.php">Back to dashboard</h2>
+ </div>
+ </div>
+ </main>
+ </body>
+</html>