209 lines
8.6 KiB
PHP
209 lines
8.6 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../db/config.php';
|
|
|
|
function getCurrentAppUser() {
|
|
// In a real application, this would fetch the logged-in user from a session or token.
|
|
// For now, we'll hardcode the admin user from the seeded data.
|
|
// This assumes the admin user has company_id 1 (from the seed).
|
|
// This will need to be replaced with proper authentication later.
|
|
static $user = null;
|
|
if ($user === null) {
|
|
$user = db()->query("SELECT * FROM users WHERE role = 'admin' LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
return $user;
|
|
}
|
|
|
|
function get_current_company_id() {
|
|
$user = getCurrentAppUser();
|
|
return $user ? $user['company_id'] : null;
|
|
}
|
|
|
|
function get_company_onboarding_status($company_id) {
|
|
$stmt = db()->prepare("SELECT onboarding_complete FROM companies WHERE id = ?");
|
|
$stmt->execute([$company_id]);
|
|
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
return $result ? (bool)$result['onboarding_complete'] : false;
|
|
}
|
|
|
|
function logActivity($job_id, $event_type, $field_name = null, $old_value = null, $new_value = null) {
|
|
$user = getCurrentAppUser();
|
|
if (!$user) { return; } // Don't log if no user context
|
|
$stmt = db()->prepare("INSERT INTO activity_logs (job_id, company_id, user_id, user_name, event_type, field_name, old_value, new_value) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([
|
|
$job_id,
|
|
$user['company_id'],
|
|
$user['id'],
|
|
$user['name'],
|
|
$event_type,
|
|
$field_name,
|
|
$old_value,
|
|
$new_value
|
|
]);
|
|
}
|
|
|
|
function getJobStatuses($company_id) {
|
|
$stmt = db()->prepare("SELECT * FROM job_statuses WHERE company_id = ?");
|
|
$stmt->execute([$company_id]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function getClients($company_id) {
|
|
$stmt = db()->prepare("SELECT * FROM clients WHERE company_id = ? AND is_active = 1");
|
|
$stmt->execute([$company_id]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function getCompanyRequiredFolders($company_id) {
|
|
$stmt = db()->prepare("SELECT * FROM job_folders WHERE company_id = ? AND is_required = TRUE ORDER BY name ASC");
|
|
$stmt->execute([$company_id]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
// New functions for File & Folder Manager
|
|
|
|
/**
|
|
* Ensures all required folders for a company are created for a specific job.
|
|
* This should be called when a new job is created or when new required folders are added globally.
|
|
*/
|
|
function ensureRequiredJobFoldersExist($job_id, $company_id) {
|
|
$pdo = db();
|
|
$required_folders = getCompanyRequiredFolders($company_id);
|
|
|
|
$insert_stmt = $pdo->prepare(
|
|
"INSERT IGNORE INTO job_job_folders (job_id, company_id, folder_id, name, is_custom)
|
|
VALUES (?, ?, ?, ?, ?)"
|
|
);
|
|
|
|
foreach ($required_folders as $rf) {
|
|
// Check if this required folder already exists for this job
|
|
$check_stmt = $pdo->prepare(
|
|
"SELECT COUNT(*) FROM job_job_folders WHERE job_id = ? AND company_id = ? AND folder_id = ? AND is_custom = FALSE"
|
|
);
|
|
$check_stmt->execute([$job_id, $company_id, $rf['id']]);
|
|
if ($check_stmt->fetchColumn() == 0) {
|
|
$insert_stmt->execute([$job_id, $company_id, $rf['id'], $rf['name'], FALSE]);
|
|
}
|
|
}
|
|
}
|
|
|
|
function getJobFolders($job_id, $company_id) {
|
|
$stmt = db()->prepare("SELECT jjf.*, COUNT(jf.id) as file_count
|
|
FROM job_job_folders jjf
|
|
LEFT JOIN job_files jf ON jjf.id = jf.job_job_folder_id
|
|
WHERE jjf.job_id = ? AND jjf.company_id = ?
|
|
GROUP BY jjf.id
|
|
ORDER BY jjf.is_custom ASC, jjf.name ASC");
|
|
$stmt->execute([$job_id, $company_id]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function getFilesInJobFolder($job_job_folder_id, $company_id) {
|
|
$stmt = db()->prepare("SELECT * FROM job_files WHERE job_job_folder_id = ? AND company_id = ? ORDER BY filename ASC");
|
|
$stmt->execute([$job_job_folder_id, $company_id]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function createJobFolder($job_id, $company_id, $folder_name, $is_custom = TRUE, $folder_id = null) {
|
|
$pdo = db();
|
|
// Check for duplicate folder name for this job
|
|
$check_stmt = $pdo->prepare("SELECT COUNT(*) FROM job_job_folders WHERE job_id = ? AND company_id = ? AND name = ?");
|
|
$check_stmt->execute([$job_id, $company_id, $folder_name]);
|
|
if ($check_stmt->fetchColumn() > 0) {
|
|
return ['success' => FALSE, 'message' => 'Folder with this name already exists for this job.'];
|
|
}
|
|
|
|
$stmt = $pdo->prepare("INSERT INTO job_job_folders (job_id, company_id, folder_id, name, is_custom) VALUES (?, ?, ?, ?, ?)");
|
|
$success = $stmt->execute([$job_id, $company_id, $folder_id, $folder_name, $is_custom]);
|
|
return ['success' => $success, 'id' => $pdo->lastInsertId()];
|
|
}
|
|
|
|
function deleteJobFolder($job_job_folder_id, $job_id, $company_id) {
|
|
$pdo = db();
|
|
$pdo->beginTransaction();
|
|
try {
|
|
// Check if the folder is custom and empty
|
|
$folder_info_stmt = $pdo->prepare("SELECT is_custom FROM job_job_folders WHERE id = ? AND job_id = ? AND company_id = ?");
|
|
$folder_info_stmt->execute([$job_job_folder_id, $job_id, $company_id]);
|
|
$folder = $folder_info_stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$folder) {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'Folder not found.'];
|
|
}
|
|
|
|
if (!$folder['is_custom']) {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'Required folders cannot be deleted.'];
|
|
}
|
|
|
|
$file_count_stmt = $pdo->prepare("SELECT COUNT(*) FROM job_files WHERE job_job_folder_id = ? AND company_id = ?");
|
|
$file_count_stmt->execute([$job_job_folder_id, $company_id]);
|
|
if ($file_count_stmt->fetchColumn() > 0) {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'This folder must be empty before it can be deleted.'];
|
|
}
|
|
|
|
// Delete the folder entry from the database
|
|
$delete_stmt = $pdo->prepare("DELETE FROM job_job_folders WHERE id = ? AND job_id = ? AND company_id = ?");
|
|
$success = $delete_stmt->execute([$job_job_folder_id, $job_id, $company_id]);
|
|
|
|
if ($success) {
|
|
logActivity($job_id, 'folder_deleted', 'folder', $folder_info_stmt->fetchColumn(3), null); // Log the name of the deleted folder
|
|
$pdo->commit();
|
|
return ['success' => TRUE];
|
|
} else {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'Failed to delete folder.'];
|
|
}
|
|
} catch (PDOException $e) {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'Database error: ' . $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
function addJobFile($job_id, $job_job_folder_id, $company_id, $user_id, $filename, $filepath, $mimetype, $size) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("INSERT INTO job_files (job_id, job_job_folder_id, company_id, user_id, filename, filepath, mimetype, size) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$success = $stmt->execute([$job_id, $job_job_folder_id, $company_id, $user_id, $filename, $filepath, $mimetype, $size]);
|
|
if ($success) {
|
|
logActivity($job_id, 'file_uploaded', 'file', null, $filename); // Log the uploaded file
|
|
}
|
|
return ['success' => $success, 'id' => $pdo->lastInsertId()];
|
|
}
|
|
|
|
function deleteJobFile($file_id, $job_id, $company_id) {
|
|
$pdo = db();
|
|
$pdo->beginTransaction();
|
|
try {
|
|
// Get file information to delete from file system
|
|
$file_info_stmt = $pdo->prepare("SELECT filename, filepath FROM job_files WHERE id = ? AND job_id = ? AND company_id = ?");
|
|
$file_info_stmt->execute([$file_id, $job_id, $company_id]);
|
|
$file = $file_info_stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$file) {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'File not found.'];
|
|
}
|
|
|
|
// Delete file from filesystem
|
|
if (file_exists($file['filepath'])) {
|
|
unlink($file['filepath']);
|
|
}
|
|
|
|
// Delete from database
|
|
$delete_stmt = $pdo->prepare("DELETE FROM job_files WHERE id = ? AND job_id = ? AND company_id = ?");
|
|
$success = $delete_stmt->execute([$file_id, $job_id, $company_id]);
|
|
|
|
if ($success) {
|
|
logActivity($job_id, 'file_deleted', 'file', $file['filename'], null); // Log the deleted file
|
|
$pdo->commit();
|
|
return ['success' => TRUE];
|
|
} else {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'Failed to delete file from database.'];
|
|
}
|
|
} catch (PDOException $e) {
|
|
$pdo->rollBack();
|
|
return ['success' => FALSE, 'message' => 'Database error: ' . $e->getMessage()];
|
|
}
|
|
} |