Skip to content

Commit 08f2a30

Browse files
authored
Merge pull request #1166 from itflow-org/quote-upload
Ability to upload files to an approved quote
2 parents b0a79c1 + 72a84af commit 08f2a30

File tree

8 files changed

+216
-13
lines changed

8 files changed

+216
-13
lines changed

database_updates.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,10 +2490,20 @@ function processFile($file_path, $file_name, $mysqli) {
24902490
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.2'");
24912491
}
24922492

2493-
// if (CURRENT_DATABASE_VERSION == '1.8.2') {
2494-
// // Insert queries here required to update to DB version 1.8.3
2493+
if (CURRENT_DATABASE_VERSION == '1.8.2') {
2494+
mysqli_query($mysqli, "CREATE TABLE `quote_files` (
2495+
`quote_id` INT(11) NOT NULL,
2496+
`file_id` INT(11) NOT NULL,
2497+
PRIMARY KEY (`quote_id`, `file_id`)
2498+
)");
2499+
2500+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.3'");
2501+
}
2502+
2503+
// if (CURRENT_DATABASE_VERSION == '1.8.3') {
2504+
// // Insert queries here required to update to DB version 1.8.4
24952505
// // Then, update the database to the next sequential version
2496-
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.3'");
2506+
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.4'");
24972507
// }
24982508

24992509
} else {

db.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,20 @@ CREATE TABLE `quotes` (
13081308
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
13091309
/*!40101 SET character_set_client = @saved_cs_client */;
13101310

1311+
--
1312+
-- Table structure for table `quote_files`
1313+
--
1314+
1315+
DROP TABLE IF EXISTS `quote_files`;
1316+
/*!40101 SET @saved_cs_client = @@character_set_client */;
1317+
/*!40101 SET character_set_client = utf8 */;
1318+
CREATE TABLE `quote_files` (
1319+
`quote_id` int(11) NOT NULL,
1320+
`file_id` int(11) NOT NULL,
1321+
PRIMARY KEY (`quote_id`,`file_id`)
1322+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
1323+
/*!40101 SET character_set_client = @saved_cs_client */;
1324+
13111325
--
13121326
-- Table structure for table `rack_units`
13131327
--

guest/guest_post.php

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@
5050
$subject = "Quote Accepted - $client_name - Quote $quote_prefix$quote_number";
5151
$body = "Hello, <br><br>This is a notification that a quote has been accepted in ITFlow. <br><br>Client: $client_name<br>Quote: <a href=\'https://$config_base_url/quote.php?quote_id=$quote_id\'>$quote_prefix$quote_number</a><br><br>~<br>$company_name - Billing<br>$config_quote_from_email";
5252

53-
$data[] = [
54-
'from' => $config_quote_from_email,
55-
'from_name' => $config_quote_from_name,
56-
'recipient' => $config_quote_notification_email,
57-
'subject' => $subject,
58-
'body' => $body,
59-
];
53+
$data[] = [
54+
'from' => $config_quote_from_email,
55+
'from_name' => $config_quote_from_name,
56+
'recipient' => $config_quote_notification_email,
57+
'subject' => $subject,
58+
'body' => $body,
59+
];
6060

6161
$mail = addToMailQueue($data);
6262
}
@@ -200,4 +200,95 @@
200200
echo "Invalid!!";
201201
}
202202
}
203+
204+
if (isset($_POST['guest_quote_upload_file'])) {
205+
$quote_id = intval($_POST['quote_id']);
206+
$url_key = sanitizeInput($_POST['url_key']);
207+
208+
// Select only the necessary fields
209+
$sql = mysqli_query($mysqli, "SELECT quote_prefix, quote_number, client_id FROM quotes LEFT JOIN clients ON quote_client_id = client_id WHERE quote_id = $quote_id AND quote_url_key = '$url_key'");
210+
211+
if (mysqli_num_rows($sql) == 1) {
212+
$row = mysqli_fetch_array($sql);
213+
$quote_prefix = sanitizeInput($row['quote_prefix']);
214+
$quote_number = intval($row['quote_number']);
215+
$client_id = intval($row['client_id']);
216+
217+
// Define & create directories, as required
218+
$upload_file_dir = "../uploads/clients/$client_id/";
219+
mkdirMissing($upload_file_dir);
220+
221+
// Store attached any file
222+
if (!empty($_FILES)) {
223+
224+
for ($i = 0; $i < count($_FILES['file']['name']); $i++) {
225+
// Extract file details for this iteration
226+
$single_file = [
227+
'name' => $_FILES['file']['name'][$i],
228+
'type' => $_FILES['file']['type'][$i],
229+
'tmp_name' => $_FILES['file']['tmp_name'][$i],
230+
'error' => $_FILES['file']['error'][$i],
231+
'size' => $_FILES['file']['size'][$i]
232+
];
233+
234+
if ($file_reference_name = checkFileUpload($single_file, array('pdf'))) {
235+
236+
$file_tmp_path = $_FILES['file']['tmp_name'][$i];
237+
238+
$file_name = sanitizeInput($_FILES['file']['name'][$i]);
239+
$extarr = explode('.', $_FILES['file']['name'][$i]);
240+
$file_extension = sanitizeInput(strtolower(end($extarr)));
241+
242+
// Extract the file mime type and size
243+
$file_mime_type = sanitizeInput($single_file['type']);
244+
$file_size = intval($single_file['size']);
245+
246+
// Define destination file path
247+
$dest_path = $upload_file_dir . $file_reference_name;
248+
249+
// Get/Create a top-level folder called Client Uploads
250+
$folder_sql = mysqli_query($mysqli, "SELECT * FROM folders WHERE folder_name = 'Client Uploads' AND parent_folder = 0 AND folder_client_id = $client_id LIMIT 1");
251+
if (mysqli_num_rows($folder_sql) == 1) {
252+
// Get
253+
$row = mysqli_fetch_array($folder_sql);
254+
$folder_id = $row['folder_id'];
255+
} else {
256+
// Create
257+
mysqli_query($mysqli,"INSERT INTO folders SET folder_name = 'Client Uploads', parent_folder = 0, folder_location = 1, folder_client_id = $client_id");
258+
$folder_id = mysqli_insert_id($mysqli);
259+
logAction("Folder", "Create", "Automatically created folder Client Uploads", $client_id, $folder_id);
260+
}
261+
262+
// Do move/upload
263+
move_uploaded_file($file_tmp_path, $dest_path);
264+
265+
// Create reference in files
266+
mysqli_query($mysqli,"INSERT INTO files SET file_reference_name = '$file_reference_name', file_name = '$file_name', file_description = 'Uploaded via $quote_prefix$quote_number', file_ext = '$file_extension', file_mime_type = '$file_mime_type', file_size = $file_size, file_folder_id = $folder_id, file_client_id = $client_id");
267+
$file_id = mysqli_insert_id($mysqli);
268+
269+
// Associate file with quote
270+
mysqli_query($mysqli, "INSERT INTO quote_files SET quote_id = $quote_id, file_id = $file_id");
271+
272+
// Logging & feedback
273+
$_SESSION['alert_message'] = 'File uploaded!';
274+
appNotify("Quote File", "$file_name was uploaded to quote $quote_prefix$quote_number", "quote.php?quote_id=$quote_id", $client_id);
275+
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Upload', history_description = 'Client uploaded file $file_name', history_quote_id = $quote_id");
276+
logAction("File", "Upload", "Guest uploaded file $file_name to quote $quote_prefix$quote_number", $client_id);
277+
278+
} else {
279+
$_SESSION['alert_type'] = 'error';
280+
$_SESSION['alert_message'] = 'Something went wrong uploading the file - please let the support team know.';
281+
logApp("Guest", "error", "Error uploading file to invoice");
282+
}
283+
284+
}
285+
}
286+
287+
header("Location: " . $_SERVER["HTTP_REFERER"]);
288+
289+
} else {
290+
echo "Invalid!!";
291+
}
292+
}
293+
203294
?>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<div class="modal" id="uploadFileModal" tabindex="-1">
2+
<div class="modal-dialog">
3+
<div class="modal-content bg-dark">
4+
<div class="modal-header">
5+
<h5 class="modal-title"><i class="fa fa-fw fa-cloud-upload-alt mr-2"></i>Upload File</h5>
6+
<button type="button" class="close text-white" data-dismiss="modal">
7+
<span>&times;</span>
8+
</button>
9+
</div>
10+
<form action="guest_post.php" method="post" enctype="multipart/form-data" autocomplete="off">
11+
<input type="hidden" name="quote_id" value="<?php echo $quote_id; ?>">
12+
<input type="hidden" name="url_key" value="<?php echo $url_key; ?>">
13+
<div class="modal-body bg-white">
14+
15+
<div class="form-group">
16+
<input type="file" class="form-control-file" name="file[]" id="fileInput" accept=".pdf">
17+
</div>
18+
19+
</div>
20+
<div class="modal-footer bg-white">
21+
<button type="submit" name="guest_quote_upload_file" class="btn btn-primary text-bold"><i class="fa fa-upload mr-2"></i>Upload</button>
22+
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
23+
</div>
24+
</form>
25+
</div>
26+
</div>
27+
</div>

guest/guest_view_quote.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,19 @@
270270
<div class="text-center"><?php echo nl2br($config_quote_footer); ?></div>
271271
<div class="">
272272
<?php
273-
if ($quote_status == "Sent" || $quote_status == "Viewed" && strtotime($quote_expire) > strtotime("now")) {
274-
?>
273+
if ($quote_status == "Sent" || $quote_status == "Viewed" && strtotime($quote_expire) > strtotime("now")) { ?>
275274
<a class="btn btn-success confirm-link" href="guest_post.php?accept_quote=<?php echo $quote_id; ?>&url_key=<?php echo $url_key; ?>">
276275
<i class="fas fa-fw fa-thumbs-up mr-2"></i>Accept
277276
</a>
278277
<a class="btn btn-danger confirm-link" href="guest_post.php?decline_quote=<?php echo $quote_id; ?>&url_key=<?php echo $url_key; ?>">
279278
<i class="fas fa-fw fa-thumbs-down mr-2"></i>Decline
280279
</a>
281280
<?php } ?>
281+
<?php if ($quote_status == "Accepted") { ?>
282+
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#uploadFileModal">
283+
<i class="fas fa-fw fa-cloud-upload-alt mr-2"></i>Upload File
284+
</button>
285+
<?php } ?>
282286
</div>
283287

284288
</div>
@@ -712,5 +716,6 @@
712716
</script>
713717

714718
<?php
719+
require_once "guest_quote_upload_file_modal.php";
715720
require_once "guest_footer.php";
716721

includes/database_version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
* It is used in conjunction with database_updates.php
66
*/
77

8-
DEFINE("LATEST_DATABASE_VERSION", "1.8.2");
8+
DEFINE("LATEST_DATABASE_VERSION", "1.8.3");

post/user/file.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@
284284

285285
mysqli_query($mysqli,"DELETE FROM files WHERE file_id = $file_id");
286286

287+
mysqli_query($mysqli,"DELETE FROM quote_files WHERE file_id = $file_id");
288+
287289
//Logging
288290
logAction("File", "Delete", "$session_name deleted file $file_name", $client_id);
289291

quote.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@
108108
$json_products = json_encode($products);
109109
}
110110

111+
// Quote File Attachments
112+
$sql_quote_files = mysqli_query(
113+
$mysqli,
114+
"SELECT file_reference_name, file_name, file_created_at FROM quote_files LEFT JOIN files ON quote_files.file_id = files.file_id WHERE quote_id = $quote_id"
115+
);
116+
111117
?>
112118

113119
<ol class="breadcrumb d-print-none">
@@ -491,6 +497,54 @@
491497
</div>
492498
</div>
493499

500+
<?php if (mysqli_num_rows($sql_quote_files) > 0) { ?>
501+
<div class="row mb-3">
502+
<div class="col-sm d-print-none">
503+
<div class="card">
504+
<div class="card-header text-bold">
505+
<i class="fa fa-paperclip mr-2"></i>Attachments
506+
<div class="card-tools">
507+
<button type="button" class="btn btn-tool" data-card-widget="collapse">
508+
<i class="fas fa-minus"></i>
509+
</button>
510+
<button type="button" class="btn btn-tool" data-card-widget="remove">
511+
<i class="fas fa-times"></i>
512+
</button>
513+
</div>
514+
</div>
515+
<div class="card-body">
516+
<table class="table">
517+
<thead>
518+
<tr>
519+
<th>File Name</th>
520+
<th>Upload date</th>
521+
</tr>
522+
</thead>
523+
<tbody>
524+
<?php
525+
526+
while ($quote_file = mysqli_fetch_array($sql_quote_files)) {
527+
$name = nullable_htmlentities($quote_file['file_name']);
528+
$ref_name = nullable_htmlentities($quote_file['file_reference_name']);
529+
$created = nullable_htmlentities($quote_file['file_created_at']);
530+
531+
?>
532+
<tr>
533+
<td><a target="_blank" href="/uploads/clients/<?php echo $client_id ?>/<?php echo $ref_name ?>"><?php echo $name; ?></a></td>
534+
<td><?php echo $created; ?></td>
535+
</tr>
536+
<?php
537+
}
538+
?>
539+
540+
</tbody>
541+
</table>
542+
</div>
543+
</div>
544+
</div>
545+
</div>
546+
<?php } ?>
547+
494548
<div class="row mb-3">
495549
<div class="col-sm d-print-none">
496550
<div class="card">

0 commit comments

Comments
 (0)