stage #2
@@ -36,7 +36,4 @@ if (isset($session_is_admin) && $session_is_admin) {
|
||||
require_once "../post/logout.php";
|
||||
|
||||
// TODO: Find a home for these
|
||||
|
||||
require_once "../post/ai.php";
|
||||
require_once "../post/misc.php";
|
||||
|
||||
|
||||
244
agent/ajax.php
244
agent/ajax.php
@@ -699,3 +699,247 @@ if (isset($_GET['client_duplicate_check'])) {
|
||||
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_reword'])) {
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$promptText = $row['ai_model_prompt'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
// Collecting the input data from the AJAX request.
|
||||
$inputJSON = file_get_contents('php://input');
|
||||
$input = json_decode($inputJSON, TRUE); // Convert JSON into array.
|
||||
|
||||
$userText = $input['text'];
|
||||
|
||||
// Preparing the data for the OpenAI Chat API request.
|
||||
$data = [
|
||||
"model" => "$model_name", // Specify the model
|
||||
"messages" => [
|
||||
["role" => "system", "content" => $promptText],
|
||||
["role" => "user", "content" => $userText],
|
||||
],
|
||||
"temperature" => 0.5
|
||||
];
|
||||
|
||||
// Initialize cURL session to the OpenAI Chat API.
|
||||
$ch = curl_init("$url");
|
||||
|
||||
// Set cURL options for the request.
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key,
|
||||
]);
|
||||
|
||||
// Execute the cURL session and capture the response.
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
// Decode the JSON response.
|
||||
$responseData = json_decode($response, true);
|
||||
|
||||
// Check if the response contains the expected data and return it.
|
||||
if (isset($responseData['choices'][0]['message']['content'])) {
|
||||
// Get the response content.
|
||||
$content = $responseData['choices'][0]['message']['content'];
|
||||
|
||||
// Clean any leading "html" word or other unwanted text at the beginning.
|
||||
$content = preg_replace('/^html/i', '', $content); // Remove any occurrence of 'html' at the start
|
||||
|
||||
// Clean the response content to remove backticks or code block markers.
|
||||
$cleanedContent = str_replace('```', '', $content); // Remove backticks if they exist.
|
||||
|
||||
// Trim any leading/trailing whitespace.
|
||||
$cleanedContent = trim($cleanedContent);
|
||||
|
||||
// Return the cleaned response.
|
||||
echo json_encode(['rewordedText' => $cleanedContent]);
|
||||
} else {
|
||||
// Handle errors or unexpected response structure.
|
||||
echo json_encode(['rewordedText' => 'Failed to get a response from the AI API.']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_create_document_template'])) {
|
||||
// get_ai_document_template.php
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
$prompt = $_POST['prompt'] ?? '';
|
||||
|
||||
// Basic validation
|
||||
if(empty($prompt)){
|
||||
echo "No prompt provided.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Prepare prompt
|
||||
$system_message = "You are a helpful IT documentation assistant. You will create a well-structured HTML template for IT documentation based on a given prompt. Include headings, subheadings, bullet points, and possibly tables for clarity. No Lorem Ipsum, use realistic placeholders and professional language.";
|
||||
$user_message = "Create an HTML formatted IT documentation template based on the following request:\n\n\"$prompt\"\n\nThe template should be structured, professional, and useful for IT staff. Include relevant sections, instructions, prerequisites, and best practices.";
|
||||
|
||||
$post_data = [
|
||||
"model" => "$model_name",
|
||||
"messages" => [
|
||||
["role" => "system", "content" => $system_message],
|
||||
["role" => "user", "content" => $user_message]
|
||||
],
|
||||
"temperature" => 0.5
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
echo "Error: " . curl_error($ch);
|
||||
exit;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$response_data = json_decode($response, true);
|
||||
$template = $response_data['choices'][0]['message']['content'] ?? "<p>No content returned from AI.</p>";
|
||||
|
||||
// Print the generated HTML template directly
|
||||
echo $template;
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_ticket_summary'])) {
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
// Retrieve the ticket_id from POST
|
||||
$ticket_id = intval($_POST['ticket_id']);
|
||||
|
||||
// Query the database for ticket details
|
||||
$sql = mysqli_query($mysqli, "
|
||||
SELECT ticket_subject, ticket_details, ticket_source, ticket_priority, ticket_status_name, category_name
|
||||
FROM tickets
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
LEFT JOIN categories ON ticket_category = category_id
|
||||
WHERE ticket_id = $ticket_id
|
||||
LIMIT 1
|
||||
");
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$ticket_subject = $row['ticket_subject'];
|
||||
$ticket_details = strip_tags($row['ticket_details']); // strip HTML for cleaner prompt
|
||||
$ticket_status = $row['ticket_status_name'];
|
||||
$ticket_category = $row['category_name'];
|
||||
$ticket_source = $row['ticket_source'];
|
||||
$ticket_priority = $row['ticket_priority'];
|
||||
|
||||
// Get ticket replies
|
||||
$sql_replies = mysqli_query($mysqli, "
|
||||
SELECT ticket_reply, ticket_reply_type, user_name
|
||||
FROM ticket_replies
|
||||
LEFT JOIN users ON ticket_reply_by = user_id
|
||||
WHERE ticket_reply_ticket_id = $ticket_id
|
||||
AND ticket_reply_archived_at IS NULL
|
||||
ORDER BY ticket_reply_id ASC
|
||||
");
|
||||
|
||||
$all_replies_text = "";
|
||||
while ($reply = mysqli_fetch_assoc($sql_replies)) {
|
||||
$reply_type = $reply['ticket_reply_type'];
|
||||
$reply_text = strip_tags($reply['ticket_reply']);
|
||||
$reply_by = $reply['user_name'];
|
||||
$all_replies_text .= "\nReply Type: $reply_type Reply By: $reply_by: Reply Text: $reply_text";
|
||||
}
|
||||
|
||||
$prompt = "
|
||||
Summarize the following IT support ticket and its responses in a concise, clear, and professional manner.
|
||||
The summary should include:
|
||||
|
||||
1. Main Issue: What was the problem reported by the user?
|
||||
2. Actions Taken: What steps were taken to address the issue?
|
||||
3. Resolution or Next Steps: Was the issue resolved or is it ongoing?
|
||||
|
||||
Please ensure:
|
||||
- If there are multiple issues, summarize each separately.
|
||||
- Urgency: If the ticket or replies express urgency or escalation, highlight it.
|
||||
- Attachments: If mentioned in the ticket, note any relevant attachments or files.
|
||||
- Avoid extra explanations or unnecessary information.
|
||||
|
||||
Ticket Data:
|
||||
- Ticket Source: $ticket_source
|
||||
- Current Ticket Status: $ticket_status
|
||||
- Ticket Priority: $ticket_priority
|
||||
- Ticket Category: $ticket_category
|
||||
- Ticket Subject: $ticket_subject
|
||||
- Ticket Details: $ticket_details
|
||||
- Replies:
|
||||
$all_replies_text
|
||||
|
||||
Formatting instructions:
|
||||
- Use valid HTML tags only.
|
||||
- Use <h3> for section headers (Main Issue, Actions Taken, Resolution).
|
||||
- Use <ul><li> for bullet points under each section.
|
||||
- Do NOT wrap the output in ```html or any other code fences.
|
||||
- Do NOT include <html>, <head>, or <body>.
|
||||
- Output only the summary content in pure HTML.
|
||||
If any part of the ticket or replies is unclear or ambiguous, mention it in the summary and suggest if further clarification is needed.
|
||||
";
|
||||
|
||||
// Prepare the POST data
|
||||
$post_data = [
|
||||
"model" => "$model_name",
|
||||
"messages" => [
|
||||
["role" => "system", "content" => "Your task is to summarize IT support tickets with clear, concise details."],
|
||||
["role" => "user", "content" => $prompt]
|
||||
],
|
||||
"temperature" => 0.3
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
echo "Error: " . curl_error($ch);
|
||||
exit;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$response_data = json_decode($response, true);
|
||||
$summary = $response_data['choices'][0]['message']['content'] ?? "No summary available.";
|
||||
|
||||
|
||||
echo $summary; // nl2br to convert newlines to <br>, htmlspecialchars to prevent XSS
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ if (isset($_GET['calendar_id'])) {
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-1">Calendars</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#addCalendarModal"><i class="fas fa-plus"></i></button>
|
||||
<button type="button" class="btn btn-dark btn-sm ajax-modal" data-modal-url="modals/calendar/calendar_add.php"><i class="fas fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -82,8 +82,6 @@ if (isset($_GET['calendar_id'])) {
|
||||
<?php
|
||||
|
||||
require_once "modals/calendar/calendar_event_add.php";
|
||||
require_once "modals/calendar/calendar_add.php";
|
||||
|
||||
|
||||
//loop through IDs and create a modal for each
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
|
||||
|
||||
@@ -1,94 +1,55 @@
|
||||
/*
|
||||
* LISTENERS
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
|
||||
// Modal loaded listener - populate client select
|
||||
const changeClientModalLoad = document.getElementById('clientChangeTicketModalLoad');
|
||||
changeClientModalLoad.addEventListener('click', function() {
|
||||
populateChangeClientModal_Clients();
|
||||
// Function to load contacts for a given client
|
||||
function loadContacts(clientId) {
|
||||
if (!clientId) return;
|
||||
|
||||
var $contactSelect = $('#contact_select');
|
||||
$contactSelect.html('<option value="">Loading...</option>');
|
||||
|
||||
$.ajax({
|
||||
url: 'ajax.php',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
get_client_contacts: 1,
|
||||
client_id: clientId
|
||||
},
|
||||
success: function(response) {
|
||||
$contactSelect.empty();
|
||||
if (response.contacts && response.contacts.length > 0) {
|
||||
$contactSelect.append('<option value="">Select a contact</option>');
|
||||
$.each(response.contacts, function(i, contact) {
|
||||
$contactSelect.append(
|
||||
$('<option>', {
|
||||
value: contact.contact_id,
|
||||
text: contact.contact_name
|
||||
})
|
||||
|
||||
// Client selected listener - populate contact select
|
||||
// We seem to have to use jQuery to listen for events, as the client input is a select2 component?
|
||||
const clientSelectDropdown = document.getElementById("changeClientSelect");
|
||||
$(clientSelectDropdown).on('select2:select', function (e) {
|
||||
let client_id = $(this).find(':selected').val();
|
||||
populateChangeClientModal_Contacts(client_id);
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
// Populate client list function
|
||||
function populateChangeClientModal_Clients() {
|
||||
|
||||
// Get current client ID
|
||||
let current_client_id = document.getElementById("client_id").value;
|
||||
|
||||
// Send a GET request to ajax.php as ajax.php?get_active_clients=true
|
||||
jQuery.get(
|
||||
"ajax.php",
|
||||
{get_active_clients: 'true'},
|
||||
function(data) {
|
||||
|
||||
// If we get a response from ajax.php, parse it as JSON
|
||||
const response = JSON.parse(data);
|
||||
|
||||
// Access the data for clients (multiple)
|
||||
const clients = response.clients;
|
||||
|
||||
// Client dropdown already defined in listeners as clientSelectDropdown
|
||||
|
||||
// Clear dropdown
|
||||
let i, L = clientSelectDropdown.options.length - 1;
|
||||
for (i = L; i >= 0; i--) {
|
||||
clientSelectDropdown.remove(i);
|
||||
}
|
||||
clientSelectDropdown[clientSelectDropdown.length] = new Option('- Client -', '0');
|
||||
|
||||
// Populate dropdown
|
||||
clients.forEach(client => {
|
||||
if (parseInt(current_client_id) !== parseInt(client.client_id)) {
|
||||
// Show clients returned (excluding the current client ID - we can't change a ticket client to itself)
|
||||
clientSelectDropdown[clientSelectDropdown.length] = new Option(client.client_name, client.client_id);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Populate client contact function (after a client is selected)
|
||||
function populateChangeClientModal_Contacts(client_id) {
|
||||
// Send a GET request to ajax.php as ajax.php?get_client_contacts=true&client_id=NUM
|
||||
jQuery.get(
|
||||
"ajax.php",
|
||||
{get_client_contacts: 'true', client_id: client_id},
|
||||
function(data) {
|
||||
|
||||
// If we get a response from ajax.php, parse it as JSON
|
||||
const response = JSON.parse(data);
|
||||
|
||||
// Access the data for contacts (multiple)
|
||||
const contacts = response.contacts;
|
||||
|
||||
// Contacts dropdown
|
||||
const contactSelectDropdown = document.getElementById("changeContactSelect");
|
||||
|
||||
// Clear Category dropdown
|
||||
let i, L = contactSelectDropdown.options.length - 1;
|
||||
for (i = L; i >= 0; i--) {
|
||||
contactSelectDropdown.remove(i);
|
||||
}
|
||||
contactSelectDropdown[contactSelectDropdown.length] = new Option('- Contact -', '0');
|
||||
|
||||
// Populate dropdown
|
||||
contacts.forEach(contact => {
|
||||
contactSelectDropdown[contactSelectDropdown.length] = new Option(contact.contact_name, contact.contact_id);
|
||||
});
|
||||
} else {
|
||||
$contactSelect.append('<option value="">No contacts found</option>');
|
||||
}
|
||||
|
||||
// Refresh Select2
|
||||
if ($.fn.select2) {
|
||||
$contactSelect.trigger('change.select2');
|
||||
}
|
||||
);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('AJAX Error:', error);
|
||||
$contactSelect.html('<option value="">Failed to load contacts</option>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Load contacts for the currently selected client when modal opens
|
||||
var initialClientId = $('#client_select').val();
|
||||
loadContacts(initialClientId);
|
||||
|
||||
// Load contacts when client changes
|
||||
$('#client_select').on('change', function() {
|
||||
var clientId = $(this).val();
|
||||
loadContacts(clientId);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<div class="modal" id="addCalendarModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-calendar-plus mr-2"></i>New Calendar</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
@@ -36,6 +40,6 @@
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<div class="modal" id="addRackModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$client_id = intval($_GET['client_id'] ?? 0);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-server mr-2"></i>New Rack</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
@@ -148,6 +154,7 @@
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
<div class="modal" id="addTicketWatcherModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$ticket_id = intval($_GET['ticket_id'] ?? 0);
|
||||
$client_id = intval(getFieldById('tickets', $ticket_id, 'ticket_client_id') ?? 0);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-eye mr-2"></i>Adding a ticket Watcher: <strong><?php echo "$ticket_prefix$ticket_number"; ?></strong> - <?php echo $client_name; ?></h5>
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-eye mr-2"></i>Adding a ticket Watcher</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
@@ -10,8 +17,6 @@
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id; ?>">
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<input type="hidden" name="ticket_number" value="<?php echo "$ticket_prefix$ticket_number"; ?>">
|
||||
<input type="hidden" name="watcher_notify" value="0"> <!-- Default 0 -->
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -59,6 +64,5 @@
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,23 +1,43 @@
|
||||
<div class="modal" id="clientChangeTicketModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-md">
|
||||
<div class="modal-content">
|
||||
<?php
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$ticket_id = intval($_GET['ticket_id']);
|
||||
$current_client_id = intval(getFieldById('tickets', $ticket_id, 'ticket_client_id'));
|
||||
$ticket_prefix = nullable_htmlentities(getFieldById('tickets', $ticket_id, 'ticket_prefix'));
|
||||
$ticket_number = nullable_htmlentities(getFieldById('tickets', $ticket_id, 'ticket_number'));
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-people-carry mr-2"></i>Change <?php echo "$ticket_prefix$ticket_number"; ?> to another client</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
<h5 class="modal-title">
|
||||
<i class="fa fa-fw fa-people-carry mr-2"></i>
|
||||
Change <?php echo "$ticket_prefix$ticket_number"; ?> to another client
|
||||
</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal"><span>×</span></button>
|
||||
</div>
|
||||
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>New Client <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-users"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="new_client_id" id="changeClientSelect" required>
|
||||
<select class="form-control select2" name="new_client_id" id="client_select" required>
|
||||
<?php
|
||||
$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_lead = 0 AND client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||
$client_id_select = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
?>
|
||||
<option value="<?= $client_id_select ?>" <?php if ($current_client_id == $client_id_select) echo 'selected'; ?>>
|
||||
<?= $client_name ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,22 +48,23 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="new_contact_id" id="changeContactSelect">
|
||||
<select class="form-control select2" name="new_contact_id" id="contact_select">
|
||||
<option value="">- Select a contact -</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="change_client_ticket" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Change</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
<button type="submit" name="change_client_ticket" class="btn btn-primary text-bold">
|
||||
<i class="fa fa-check mr-2"></i>Change
|
||||
</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal">
|
||||
<i class="fa fa-times mr-2"></i>Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket Change Client JS -->
|
||||
<link rel="stylesheet" href="../plugins/jquery-ui/jquery-ui.min.css">
|
||||
<script src="../plugins/jquery-ui/jquery-ui.min.js"></script>
|
||||
<script src="js/ticket_change_client.js"></script>
|
||||
<script src="/agent/js/ticket_change_client.js"></script>
|
||||
|
||||
<?php require_once '../../../includes/modal_footer.php'; ?>
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
<div class="modal" id="editTicketVendorModal<?php echo $ticket_id; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$ticket_id = intval($_GET['ticket_id'] ?? 0);
|
||||
|
||||
$client_id = intval(getFieldById('tickets', $ticket_id, 'ticket_client_id') ?? 0);
|
||||
$vendor_id = intval(getFieldById('tickets', $ticket_id, 'ticket_vendor_id') ?? 0);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-building mr-2"></i>Editing ticket Vendor: <strong><?php echo "$ticket_prefix$ticket_number"; ?></strong> - <?php echo $client_name; ?></h5>
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-building mr-2"></i>Editing ticket Vendor</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id; ?>">
|
||||
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -24,9 +33,9 @@
|
||||
$sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_vendors)) {
|
||||
$vendor_id_select = intval($row['vendor_id']);
|
||||
$vendor_name_select = nullable_htmlentities($row['vendor_name']);
|
||||
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
||||
?>
|
||||
<option <?php if ($vendor_id == $vendor_id_select) { echo "selected"; } ?> value="<?php echo $vendor_id_select; ?>"><?php echo $vendor_name_select; ?></option>
|
||||
<option <?php if ($vendor_id == $vendor_id_select) { echo "selected"; } ?> value="<?= $vendor_id_select ?>"><?= $vendor_name ?></option>
|
||||
|
||||
<?php
|
||||
}
|
||||
@@ -44,6 +53,5 @@
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,11 +1,85 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$ticket_id = intval($_GET['ticket_id']);
|
||||
|
||||
$ticket_sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT * FROM tickets
|
||||
LEFT JOIN clients ON ticket_client_id = client_id
|
||||
LEFT JOIN contacts ON ticket_contact_id = contact_id
|
||||
LEFT JOIN users ON ticket_assigned_to = user_id
|
||||
LEFT JOIN locations ON ticket_location_id = location_id
|
||||
LEFT JOIN assets ON ticket_asset_id = asset_id
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
LEFT JOIN categories ON ticket_category = category_id
|
||||
WHERE ticket_id = $ticket_id
|
||||
$access_permission_query
|
||||
LIMIT 1"
|
||||
);
|
||||
|
||||
$row = mysqli_fetch_array($ticket_sql);
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_rate = floatval($row['client_rate']);
|
||||
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
|
||||
$ticket_number = intval($row['ticket_number']);
|
||||
$ticket_category = intval($row['ticket_category']);
|
||||
$ticket_category_display = nullable_htmlentities($row['category_name']);
|
||||
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
|
||||
$ticket_priority = nullable_htmlentities($row['ticket_priority']);
|
||||
$ticket_billable = intval($row['ticket_billable']);
|
||||
$ticket_onsite = intval($row['ticket_onsite']);
|
||||
|
||||
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
|
||||
$ticket_created_by = intval($row['ticket_created_by']);
|
||||
$ticket_date = date('Y-m-d', strtotime($ticket_created_at));
|
||||
$ticket_first_response_at = nullable_htmlentities($row['ticket_first_response_at']);
|
||||
if ($ticket_first_response_at) {
|
||||
$ticket_first_response_date_time = date('Y-m-d H:i', strtotime($ticket_first_response_at));
|
||||
} else {
|
||||
$ticket_first_response_date_time = '';
|
||||
}
|
||||
$ticket_resolved_at = nullable_htmlentities($row['ticket_resolved_at']);
|
||||
if ($ticket_resolved_at) {
|
||||
$ticket_resolved_date = date('Y-m-d', strtotime($ticket_resolved_at));
|
||||
} else {
|
||||
$ticket_resolved_date = '';
|
||||
}
|
||||
|
||||
$ticket_assigned_to = intval($row['ticket_assigned_to']);
|
||||
if ($ticket_assigned_to) {
|
||||
$ticket_assigned_agent = nullable_htmlentities($row['user_name']);
|
||||
} else {
|
||||
$ticket_assigned_agent = '';
|
||||
}
|
||||
|
||||
$contact_id = intval($row['contact_id']);
|
||||
$contact_name = nullable_htmlentities($row['contact_name']);
|
||||
|
||||
$asset_id = intval($row['asset_id']);
|
||||
$asset_name = nullable_htmlentities($row['asset_name']);
|
||||
$asset_type = nullable_htmlentities($row['asset_type']);
|
||||
|
||||
$location_id = intval($row['location_id']);
|
||||
$location_name = nullable_htmlentities($row['location_name']);
|
||||
$location_address = nullable_htmlentities($row['location_address']);
|
||||
$location_city = nullable_htmlentities($row['location_city']);
|
||||
$location_state = nullable_htmlentities($row['location_state']);
|
||||
$location_zip = nullable_htmlentities($row['location_zip']);
|
||||
$location_phone = formatPhoneNumber($row['location_phone']);
|
||||
|
||||
//Get Total Ticket Time
|
||||
$ticket_total_reply_time = mysqli_query($mysqli, "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(ticket_reply_time_worked))) AS ticket_total_reply_time FROM ticket_replies WHERE ticket_reply_archived_at IS NULL AND ticket_reply_ticket_id = $ticket_id");
|
||||
$row = mysqli_fetch_array($ticket_total_reply_time);
|
||||
$ticket_total_reply_time = nullable_htmlentities($row['ticket_total_reply_time']);
|
||||
|
||||
$sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_status LIKE 'Draft' AND invoice_client_id = $client_id ORDER BY invoice_number ASC");
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal" id="addInvoiceFromTicketModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-file-invoice-dollar mr-2"></i>Invoice ticket</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
@@ -19,19 +93,56 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-create-invoice"><i class="fa fa-fw fa-check mr-2"></i>Create New Invoice</a>
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-add-to-invoice"><i class="fa fa-fw fa-plus mr-2"></i>Add to Existing Invoice</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-add-to-invoice"><i class="fa fa-fw fa-plus mr-2"></i>Add to Existing Invoice</a>
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-create-invoice"><i class="fa fa-fw fa-check mr-2"></i>Create New Invoice</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-create-invoice">
|
||||
<?php
|
||||
|
||||
if (mysqli_num_rows($sql_invoices) > 0) { ?>
|
||||
|
||||
<div class="tab-pane fade <?php if (mysqli_num_rows($sql_invoices) > 0) { echo "active show"; } ?>" id="pills-add-to-invoice">
|
||||
<div class="form-group">
|
||||
<label>Existing Invoice</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="invoice_id">
|
||||
<option value="0">- Select an Existing Invoice -</option>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_invoices)) {
|
||||
$invoice_id = intval($row['invoice_id']);
|
||||
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
|
||||
$invoice_number = intval($row['invoice_number']);
|
||||
$invoice_scope = nullable_htmlentities($row['invoice_scope']);
|
||||
$invoice_status = nullable_htmlentities($row['invoice_status']);
|
||||
$invoice_date = nullable_htmlentities($row['invoice_date']);
|
||||
$invoice_due = nullable_htmlentities($row['invoice_due']);
|
||||
$invoice_amount = floatval($row['invoice_amount']);
|
||||
?>
|
||||
<option value="<?php echo $invoice_id; ?>"><?php echo "$invoice_prefix$invoice_number | $invoice_scope"; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="tab-pane fade <?php if (mysqli_num_rows($sql_invoices) == 0) { echo "active show"; } ?>" id="pills-create-invoice">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
@@ -55,7 +166,7 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="category">
|
||||
<option value="">- Category -</option>
|
||||
<option value="">- Select a Category -</option>
|
||||
<?php
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Income' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
||||
@@ -70,7 +181,7 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
?>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#addQuickCategoryIncomeModal"><i class="fas fa-fw fa-plus"></i></button>
|
||||
<button type="button" class="btn btn-secondary ajax-modal" data-modal-url="/admin/modals/category/category_add.php?category=Expense"><i class="fas fa-fw fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -78,56 +189,23 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Scope</label>
|
||||
<label>Invoice Title</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="scope" placeholder="Quick description" value="Ticket <?php echo "$ticket_prefix$ticket_number - $ticket_subject"; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
if (mysqli_num_rows($sql_invoices) > 0) { ?>
|
||||
|
||||
<div class="tab-pane fade" id="pills-add-to-invoice">
|
||||
<div class="form-group">
|
||||
<label>Invoice</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="invoice_id">
|
||||
<option value="0">- Invoice -</option>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_invoices)) {
|
||||
$invoice_id = intval($row['invoice_id']);
|
||||
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
|
||||
$invoice_number = intval($row['invoice_number']);
|
||||
$invoice_scope = nullable_htmlentities($row['invoice_scope']);
|
||||
$invoice_status = nullable_htmlentities($row['invoice_status']);
|
||||
$invoice_date = nullable_htmlentities($row['invoice_date']);
|
||||
$invoice_due = nullable_htmlentities($row['invoice_due']);
|
||||
$invoice_amount = floatval($row['invoice_amount']);
|
||||
?>
|
||||
<option value="<?php echo $invoice_id; ?>"><?php echo "$invoice_prefix$invoice_number | $invoice_scope"; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
<select class="form-control select2" name="scope" data-tags="true" data-placeholder="- Enter or Select an Invoice Title -">
|
||||
<option value=""></option>
|
||||
<option><?= date('F Y'); ?> Tickets</option>
|
||||
<option><?= "Ticket $ticket_prefix$ticket_number - $ticket_subject" ?></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Item <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
@@ -141,7 +219,35 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
<div class="form-group">
|
||||
<label>Item Description</label>
|
||||
<div class="input-group">
|
||||
<textarea class="form-control" rows="5" name="item_description"><?php echo "# $contact_name - $asset_name - $ticket_date\nTicket $ticket_prefix$ticket_number\n$ticket_subject\nTT: $ticket_total_reply_time"; ?></textarea>
|
||||
<textarea class="form-control" rows="10" name="item_description"><?php
|
||||
// Build description text cleanly in PHP, not mixed with HTML
|
||||
$description = "#Ticket: {$ticket_prefix}{$ticket_number} - $ticket_subject\n";
|
||||
$description .= "Priority: {$ticket_priority}\n";
|
||||
$description .= "Opened at: {$ticket_date}\n";
|
||||
if ($ticket_first_response_date_time) {
|
||||
$description .= "Initial Response: {$ticket_first_response_date_time}\n";
|
||||
}
|
||||
if ($ticket_resolved_date) {
|
||||
$description .= "Resolved at: {$ticket_resolved_date}\n";
|
||||
}
|
||||
if ($ticket_assigned_agent) {
|
||||
$description .= "Agent: {$ticket_assigned_agent}\n";
|
||||
}
|
||||
if ($location_id) {
|
||||
$description .= "Location: {$location_name}\n";
|
||||
}
|
||||
if ($contact_id) {
|
||||
$description .= "Contact: {$contact_name}\n";
|
||||
}
|
||||
if ($asset_id) {
|
||||
$description .= "Asset: {$asset_name}\n";
|
||||
}
|
||||
if ($ticket_total_reply_time) {
|
||||
$description .= "Agent Time Spent: {$ticket_total_reply_time}";
|
||||
}
|
||||
|
||||
echo trim($description); // Trim any leading/trailing spaces/newlines
|
||||
?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -156,6 +262,9 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name="qty" value="<?php echo roundToNearest15($ticket_total_reply_time); ?>" required>
|
||||
</div>
|
||||
<small class="form-text text-muted">
|
||||
Based off Ticket time spent <strong><?= $ticket_total_reply_time ?></strong> in 15 Min Increments rounded up.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -170,6 +279,9 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name="price" value="<?php echo number_format($client_rate, 2, '.', ''); ?>" required>
|
||||
</div>
|
||||
<small class="form-text text-muted">
|
||||
Based off Hourly Client rate of <strong><?= numfmt_format_currency($currency_format, $client_rate, $session_company_currency); ?></strong>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -205,6 +317,6 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
40
agent/modals/ticket/ticket_summary.php
Normal file
40
agent/modals/ticket/ticket_summary.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$ticket_id = intval($_GET['ticket_id']);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title" id="summaryModalTitle">Ticket Summary</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="summaryContent">
|
||||
<div class="text-center"><i class="fas fa-spinner fa-spin"></i> Generating summary...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
$.ajax({
|
||||
url: 'ajax.php?ai_ticket_summary',
|
||||
method: 'POST',
|
||||
data: { ticket_id: <?php echo $ticket_id; ?> },
|
||||
success: function(response) {
|
||||
$('#summaryContent').html(response);
|
||||
},
|
||||
error: function() {
|
||||
$('#summaryContent').html('Error generating summary.');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
@@ -59,7 +59,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-arrow-right"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="destination" data-tags="true" data-placeholder="- Select / Input Destination -" required>
|
||||
<select class="form-control select2" name="destination" data-tags="true" data-placeholder="- Select or Enter a Destination -" required>
|
||||
<option value=""></option>
|
||||
<?php
|
||||
if ($client_id) {
|
||||
|
||||
@@ -40,6 +40,4 @@ foreach (glob("post/*.php") as $user_module) {
|
||||
require_once "../post/logout.php";
|
||||
|
||||
// TODO: Find a home for these
|
||||
|
||||
require_once "../post/ai.php";
|
||||
require_once "../post/misc.php";
|
||||
|
||||
@@ -444,9 +444,8 @@ if (isset($_POST['add_ticket_watcher'])) {
|
||||
|
||||
$ticket_id = intval($_POST['ticket_id']);
|
||||
$client_id = intval($_POST['client_id']);
|
||||
$ticket_number = sanitizeInput($_POST['ticket_number']);
|
||||
$watcher_emails = preg_split("/,| |;/", $_POST['watcher_email']); // Split on comma, semicolon or space, we sanitize later
|
||||
$notify = intval($_POST['watcher_notify']);
|
||||
$notify = intval($_POST['watcher_notify'] ?? 0);
|
||||
|
||||
// Process each watcher in list
|
||||
foreach ($watcher_emails as $watcher_email) {
|
||||
@@ -505,7 +504,7 @@ if (isset($_POST['add_ticket_watcher'])) {
|
||||
addToMailQueue($data);
|
||||
}
|
||||
|
||||
logAction("Ticket", "Edit", "$session_name added $watcher_email as a watcher for ticket $config_ticket_prefix$ticket_number", $client_id, $ticket_id);
|
||||
logAction("Ticket", "Edit", "$session_name added $watcher_email as a watcher for ticket $ticket_prefix$ticket_number", $client_id, $ticket_id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2147,6 +2146,7 @@ if (isset($_POST['add_invoice_from_ticket'])) {
|
||||
|
||||
//Get the last Invoice Number and add 1 for the new invoice number
|
||||
$invoice_number = $config_invoice_next_number;
|
||||
$invoice_prefix = sanitizeInput($config_invoice_prefix);
|
||||
$new_config_invoice_next_number = $config_invoice_next_number + 1;
|
||||
mysqli_query($mysqli, "UPDATE settings SET config_invoice_next_number = $new_config_invoice_next_number WHERE company_id = 1");
|
||||
|
||||
@@ -2155,6 +2155,11 @@ if (isset($_POST['add_invoice_from_ticket'])) {
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO invoices SET invoice_prefix = '$config_invoice_prefix', invoice_number = $invoice_number, invoice_scope = '$scope', invoice_date = '$date', invoice_due = DATE_ADD('$date', INTERVAL $client_net_terms day), invoice_currency_code = '$session_company_currency', invoice_category_id = $category, invoice_status = 'Draft', invoice_url_key = '$url_key', invoice_client_id = $client_id");
|
||||
$invoice_id = mysqli_insert_id($mysqli);
|
||||
} else {
|
||||
$sql_invoice = mysqli_query($mysqli, "SELECT invoice_prefix, invoice_number FROM invoices WHERE invoice_id = $invoice_id");
|
||||
$row = mysqli_fetch_array($sql_invoice);
|
||||
$invoice_prefix = sanitizeInput($row['invoice_prefix']);
|
||||
$invoice_number = intval($row['invoice_number']);
|
||||
}
|
||||
|
||||
//Add Item
|
||||
@@ -2195,9 +2200,9 @@ if (isset($_POST['add_invoice_from_ticket'])) {
|
||||
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_invoice_id = $invoice_id WHERE ticket_id = $ticket_id");
|
||||
|
||||
logAction("Invoice", "Create", "$session_name created invoice $config_invoice_prefix$invoice_number from Ticket $ticket_prefix$ticket_number", $client_id, $invoice_id);
|
||||
logAction("Invoice", "Create", "$session_name created invoice $invoice_prefix$invoice_number from Ticket $ticket_prefix$ticket_number", $client_id, $invoice_id);
|
||||
|
||||
flash_alert("Invoice $config_invoice_prefix$invoice_number created from ticket");
|
||||
flash_alert("Invoice $invoice_prefix$invoice_number created from ticket");
|
||||
|
||||
redirect("invoice.php?invoice_id=$invoice_id");
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-server mr-2"></i>Network Racks</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addRackModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/rack/rack_add.php?client_id=<?= $client_id ?>">
|
||||
<i class="fas fa-plus mr-2"></i>New Rack
|
||||
</button>
|
||||
</div>
|
||||
@@ -342,6 +342,4 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/rack/rack_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -381,7 +381,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
<div class="btn-toolbar">
|
||||
|
||||
<?php if ($config_module_enable_accounting && $ticket_billable == 1 && empty($invoice_id) && lookupUserPermission("module_sales") >= 2) { ?>
|
||||
<a href="#" class="btn btn-light btn-sm ml-3" href="#" data-toggle="modal" data-target="#addInvoiceFromTicketModal">
|
||||
<a href="#" class="btn btn-light btn-sm ml-3 ajax-modal" href="#" data-modal-url="modals/ticket/ticket_invoice_add.php?ticket_id=<?= $ticket_id ?>" data-modal-size="lg">
|
||||
<i class="fas fa-fw fa-file-invoice mr-2"></i>Invoice
|
||||
</a>
|
||||
<?php }
|
||||
@@ -416,7 +416,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
data-modal-url="modals/ticket/ticket_edit.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#summaryModal">
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/ticket/ticket_summary.php?ticket_id=<?= $ticket_id ?>" data-modal-size="lg">
|
||||
<i class="fas fa-fw fa-lightbulb mr-2"></i>Summarize
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#mergeTicketModal<?php echo $ticket_id; ?>">
|
||||
@@ -431,15 +431,15 @@ if (isset($_GET['ticket_id'])) {
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_asset.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-desktop mr-2"></i>Add Asset
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editTicketVendorModal<?php echo $ticket_id; ?>">
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_vendor.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-building mr-2"></i>Add Vendor
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#addTicketWatcherModal">
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/ticket/ticket_add_watcher.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-users mr-2"></i>Add Watcher
|
||||
</a>
|
||||
<?php } ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" id="clientChangeTicketModalLoad" data-target="#clientChangeTicketModal">
|
||||
<a class="dropdown-item ajax-modal" href="#" id="clientChangeTicketModalLoad" data-modal-url="modals/ticket/ticket_change_client.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-people-carry mr-2"></i>Change Client
|
||||
</a>
|
||||
<?php if (lookupUserPermission("module_support") == 3) { ?>
|
||||
@@ -1077,8 +1077,8 @@ if (isset($_GET['ticket_id'])) {
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-eye mr-2 mt-2"></i>Watchers</h5>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<a class="btn btn-light text-secondary btn-sm" href="#" data-toggle="modal" data-target="#addTicketWatcherModal">
|
||||
<i class="fas fa-edit"></i>
|
||||
<a class="btn btn-light text-secondary btn-sm ajax-modal" href="#" data-modal-url="modals/ticket/ticket_add_watcher.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-plus"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
@@ -1114,7 +1114,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<a class="btn btn-light text-secondary btn-sm ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_asset.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
<i class="fas fa-fw fa-edit"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
@@ -1161,8 +1161,8 @@ if (isset($_GET['ticket_id'])) {
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-building mr-2 mt-2"></i>Vendor</h5>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<a class="btn btn-light text-secondary btn-sm" href="#" data-toggle="modal" data-target="#editTicketVendorModal<?php echo $ticket_id; ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
<a class="btn btn-light text-secondary btn-sm ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_vendor.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-edit"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
@@ -1244,16 +1244,9 @@ if (isset($_GET['ticket_id'])) {
|
||||
|
||||
<?php
|
||||
if (lookupUserPermission("module_support") >= 2 && empty($ticket_closed_at)) {
|
||||
require_once "modals/ticket/ticket_edit_vendor.php";
|
||||
require_once "modals/ticket/ticket_add_watcher.php";
|
||||
require_once "modals/ticket/ticket_change_client.php";
|
||||
require_once "modals/ticket/ticket_edit_schedule.php";
|
||||
require_once "modals/ticket/ticket_merge.php";
|
||||
}
|
||||
|
||||
if (lookupUserPermission("module_support") >= 2 && lookupUserPermission("module_sales") >= 2 && $config_module_enable_accounting) {
|
||||
require_once "modals/ticket/ticket_invoice_add.php";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1261,25 +1254,6 @@ require_once "../includes/footer.php";
|
||||
|
||||
?>
|
||||
|
||||
<!-- Summary Modal -->
|
||||
<div class="modal fade" id="summaryModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title" id="summaryModalTitle">Ticket Summary</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="summaryContent">
|
||||
<div class="text-center"><i class="fas fa-spinner fa-spin"></i> Generating summary...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/show_modals.js"></script>
|
||||
|
||||
<?php if (empty($ticket_closed_at)) { ?>
|
||||
@@ -1297,23 +1271,6 @@ require_once "../includes/footer.php";
|
||||
|
||||
<script src="/js/pretty_content.js"></script>
|
||||
|
||||
<script>
|
||||
$('#summaryModal').on('shown.bs.modal', function (e) {
|
||||
// Perform AJAX request to get the summary
|
||||
$.ajax({
|
||||
url: 'post.php?ai_ticket_summary',
|
||||
method: 'POST',
|
||||
data: { ticket_id: <?php echo $ticket_id; ?> },
|
||||
success: function(response) {
|
||||
$('#summaryContent').html(response);
|
||||
},
|
||||
error: function() {
|
||||
$('#summaryContent').html('Error generating summary.');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="/plugins/SortableJS/Sortable.min.js"></script>
|
||||
<script>
|
||||
new Sortable(document.querySelector('table#tasks tbody'), {
|
||||
|
||||
@@ -40,7 +40,5 @@ foreach (glob("post/*.php") as $user_module) {
|
||||
require_once "../../post/logout.php";
|
||||
|
||||
// TODO: Find a home for these
|
||||
|
||||
require_once "../../post/ai.php";
|
||||
require_once "../../post/misc.php";
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ $(document).ready(function() {
|
||||
// Show the progress indicator
|
||||
editor.setProgressState(true);
|
||||
|
||||
fetch('post.php?ai_reword', {
|
||||
fetch('ajax.php?ai_reword', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -236,7 +236,7 @@ $(document).ready(function() {
|
||||
rewordButtonApi.setEnabled(false);
|
||||
editor.setProgressState(true);
|
||||
|
||||
fetch('post.php?ai_reword', {
|
||||
fetch('ajax.php?ai_reword', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ text: content }),
|
||||
|
||||
251
post/ai.php
251
post/ai.php
@@ -1,251 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for AI Functions
|
||||
*/
|
||||
|
||||
// TODO: Should this be moved to AJAX?
|
||||
|
||||
if (isset($_GET['ai_reword'])) {
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$promptText = $row['ai_model_prompt'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
// Collecting the input data from the AJAX request.
|
||||
$inputJSON = file_get_contents('php://input');
|
||||
$input = json_decode($inputJSON, TRUE); // Convert JSON into array.
|
||||
|
||||
$userText = $input['text'];
|
||||
|
||||
// Preparing the data for the OpenAI Chat API request.
|
||||
$data = [
|
||||
"model" => "$model_name", // Specify the model
|
||||
"messages" => [
|
||||
["role" => "system", "content" => $promptText],
|
||||
["role" => "user", "content" => $userText],
|
||||
],
|
||||
"temperature" => 0.5
|
||||
];
|
||||
|
||||
// Initialize cURL session to the OpenAI Chat API.
|
||||
$ch = curl_init("$url");
|
||||
|
||||
// Set cURL options for the request.
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key,
|
||||
]);
|
||||
|
||||
// Execute the cURL session and capture the response.
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
// Decode the JSON response.
|
||||
$responseData = json_decode($response, true);
|
||||
|
||||
// Check if the response contains the expected data and return it.
|
||||
if (isset($responseData['choices'][0]['message']['content'])) {
|
||||
// Get the response content.
|
||||
$content = $responseData['choices'][0]['message']['content'];
|
||||
|
||||
// Clean any leading "html" word or other unwanted text at the beginning.
|
||||
$content = preg_replace('/^html/i', '', $content); // Remove any occurrence of 'html' at the start
|
||||
|
||||
// Clean the response content to remove backticks or code block markers.
|
||||
$cleanedContent = str_replace('```', '', $content); // Remove backticks if they exist.
|
||||
|
||||
// Trim any leading/trailing whitespace.
|
||||
$cleanedContent = trim($cleanedContent);
|
||||
|
||||
// Return the cleaned response.
|
||||
echo json_encode(['rewordedText' => $cleanedContent]);
|
||||
} else {
|
||||
// Handle errors or unexpected response structure.
|
||||
echo json_encode(['rewordedText' => 'Failed to get a response from the AI API.']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_ticket_summary'])) {
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
// Retrieve the ticket_id from POST
|
||||
$ticket_id = intval($_POST['ticket_id']);
|
||||
|
||||
// Query the database for ticket details
|
||||
$sql = mysqli_query($mysqli, "
|
||||
SELECT ticket_subject, ticket_details, ticket_source, ticket_priority, ticket_status_name, category_name
|
||||
FROM tickets
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
LEFT JOIN categories ON ticket_category = category_id
|
||||
WHERE ticket_id = $ticket_id
|
||||
LIMIT 1
|
||||
");
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$ticket_subject = $row['ticket_subject'];
|
||||
$ticket_details = strip_tags($row['ticket_details']); // strip HTML for cleaner prompt
|
||||
$ticket_status = $row['ticket_status_name'];
|
||||
$ticket_category = $row['category_name'];
|
||||
$ticket_source = $row['ticket_source'];
|
||||
$ticket_priority = $row['ticket_priority'];
|
||||
|
||||
// Get ticket replies
|
||||
$sql_replies = mysqli_query($mysqli, "
|
||||
SELECT ticket_reply, ticket_reply_type, user_name
|
||||
FROM ticket_replies
|
||||
LEFT JOIN users ON ticket_reply_by = user_id
|
||||
WHERE ticket_reply_ticket_id = $ticket_id
|
||||
AND ticket_reply_archived_at IS NULL
|
||||
ORDER BY ticket_reply_id ASC
|
||||
");
|
||||
|
||||
$all_replies_text = "";
|
||||
while ($reply = mysqli_fetch_assoc($sql_replies)) {
|
||||
$reply_type = $reply['ticket_reply_type'];
|
||||
$reply_text = strip_tags($reply['ticket_reply']);
|
||||
$reply_by = $reply['user_name'];
|
||||
$all_replies_text .= "\nReply Type: $reply_type Reply By: $reply_by: Reply Text: $reply_text";
|
||||
}
|
||||
|
||||
$prompt = "
|
||||
Summarize the following IT support ticket and its responses in a concise, clear, and professional manner.
|
||||
The summary should include:
|
||||
|
||||
1. Main Issue: What was the problem reported by the user?
|
||||
2. Actions Taken: What steps were taken to address the issue?
|
||||
3. Resolution or Next Steps: Was the issue resolved or is it ongoing?
|
||||
|
||||
Please ensure:
|
||||
- If there are multiple issues, summarize each separately.
|
||||
- Urgency: If the ticket or replies express urgency or escalation, highlight it.
|
||||
- Attachments: If mentioned in the ticket, note any relevant attachments or files.
|
||||
- Avoid extra explanations or unnecessary information.
|
||||
|
||||
Ticket Data:
|
||||
- Ticket Source: $ticket_source
|
||||
- Current Ticket Status: $ticket_status
|
||||
- Ticket Priority: $ticket_priority
|
||||
- Ticket Category: $ticket_category
|
||||
- Ticket Subject: $ticket_subject
|
||||
- Ticket Details: $ticket_details
|
||||
- Replies:
|
||||
$all_replies_text
|
||||
|
||||
Formatting instructions:
|
||||
- Use valid HTML tags only.
|
||||
- Use <h3> for section headers (Main Issue, Actions Taken, Resolution).
|
||||
- Use <ul><li> for bullet points under each section.
|
||||
- Do NOT wrap the output in ```html or any other code fences.
|
||||
- Do NOT include <html>, <head>, or <body>.
|
||||
- Output only the summary content in pure HTML.
|
||||
If any part of the ticket or replies is unclear or ambiguous, mention it in the summary and suggest if further clarification is needed.
|
||||
";
|
||||
|
||||
// Prepare the POST data
|
||||
$post_data = [
|
||||
"model" => "$model_name",
|
||||
"messages" => [
|
||||
["role" => "system", "content" => "Your task is to summarize IT support tickets with clear, concise details."],
|
||||
["role" => "user", "content" => $prompt]
|
||||
],
|
||||
"temperature" => 0.3
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
echo "Error: " . curl_error($ch);
|
||||
exit;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$response_data = json_decode($response, true);
|
||||
$summary = $response_data['choices'][0]['message']['content'] ?? "No summary available.";
|
||||
|
||||
|
||||
echo $summary; // nl2br to convert newlines to <br>, htmlspecialchars to prevent XSS
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_create_document_template'])) {
|
||||
// get_ai_document_template.php
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
$prompt = $_POST['prompt'] ?? '';
|
||||
|
||||
// Basic validation
|
||||
if(empty($prompt)){
|
||||
echo "No prompt provided.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Prepare prompt
|
||||
$system_message = "You are a helpful IT documentation assistant. You will create a well-structured HTML template for IT documentation based on a given prompt. Include headings, subheadings, bullet points, and possibly tables for clarity. No Lorem Ipsum, use realistic placeholders and professional language.";
|
||||
$user_message = "Create an HTML formatted IT documentation template based on the following request:\n\n\"$prompt\"\n\nThe template should be structured, professional, and useful for IT staff. Include relevant sections, instructions, prerequisites, and best practices.";
|
||||
|
||||
$post_data = [
|
||||
"model" => "$model_name",
|
||||
"messages" => [
|
||||
["role" => "system", "content" => $system_message],
|
||||
["role" => "user", "content" => $user_message]
|
||||
],
|
||||
"temperature" => 0.5
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
echo "Error: " . curl_error($ch);
|
||||
exit;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$response_data = json_decode($response, true);
|
||||
$template = $response_data['choices'][0]['message']['content'] ?? "<p>No content returned from AI.</p>";
|
||||
|
||||
// Print the generated HTML template directly
|
||||
echo $template;
|
||||
}
|
||||
Reference in New Issue
Block a user