141 lines
4.6 KiB
PHP
141 lines
4.6 KiB
PHP
<?php
|
|
ini_set('display_errors', 0);
|
|
error_reporting(0);
|
|
|
|
require_once 'db/config.php';
|
|
|
|
// Function to send a consistent JSON response, aggressively cleaning any output.
|
|
function send_json_response($data) {
|
|
// Ensure no stray output is included.
|
|
if (ob_get_level() > 0) {
|
|
ob_end_clean();
|
|
}
|
|
header('Content-Type: application/json');
|
|
echo json_encode($data);
|
|
exit(); // Terminate immediately
|
|
}
|
|
|
|
// Set a global exception handler to catch any uncaught errors
|
|
set_exception_handler(function($exception) {
|
|
error_log($exception->getMessage());
|
|
send_json_response(['success' => false, 'message' => 'A server error occurred: ' . $exception->getMessage()]);
|
|
});
|
|
|
|
$response_data = [
|
|
'success' => false,
|
|
'message' => 'An unknown error occurred.',
|
|
// Initialize all fields JS expects to avoid 'undefined' issues
|
|
'wip' => 0,
|
|
'openingBalance' => 0,
|
|
'billings' => 0,
|
|
'expenses' => 0,
|
|
'cost' => 0,
|
|
'nsr' => 0,
|
|
'margin' => 0,
|
|
];
|
|
|
|
ob_clean(); // Clear any pre-existing output
|
|
try {
|
|
$data = $_POST;
|
|
|
|
$projectId = $data['projectId'] ?? null;
|
|
$month = $data['month'] ?? null;
|
|
|
|
if (!$projectId || !$month) {
|
|
send_json_response(['success' => false, 'message' => 'Missing project ID or month.']);
|
|
}
|
|
|
|
$pdo = db();
|
|
|
|
$metrics_from_form = [
|
|
'wip' => $data['wip'] ?? 0,
|
|
'opening_balance' => $data['openingBalance'] ?? 0,
|
|
'billing' => $data['billings'] ?? 0,
|
|
'expenses' => $data['expenses'] ?? 0,
|
|
'cost' => $data['cost'] ?? 0,
|
|
];
|
|
|
|
$pdo->beginTransaction();
|
|
|
|
// Check if records exist, if not, INSERT them. Otherwise, UPDATE.
|
|
$select_sql = "SELECT COUNT(*) FROM projectFinanceMonthly WHERE projectId = :projectId AND month = :month AND metricName = :metricName";
|
|
$select_stmt = $pdo->prepare($select_sql);
|
|
|
|
$update_sql = "UPDATE projectFinanceMonthly SET value = :value, is_overridden = 1 WHERE projectId = :projectId AND month = :month AND metricName = :metricName";
|
|
$update_stmt = $pdo->prepare($update_sql);
|
|
|
|
$insert_sql = "INSERT INTO projectFinanceMonthly (projectId, month, metricName, value, is_overridden) VALUES (:projectId, :month, :metricName, :value, 1)";
|
|
$insert_stmt = $pdo->prepare($insert_sql);
|
|
|
|
foreach ($metrics_from_form as $metricName => $value) {
|
|
$select_stmt->execute([
|
|
'projectId' => $projectId,
|
|
'month' => $month,
|
|
'metricName' => $metricName
|
|
]);
|
|
$exists = $select_stmt->fetchColumn() > 0;
|
|
|
|
if ($exists) {
|
|
$update_stmt->execute([
|
|
'value' => $value,
|
|
'projectId' => $projectId,
|
|
'month' => $month,
|
|
'metricName' => $metricName,
|
|
]);
|
|
} else {
|
|
$insert_stmt->execute([
|
|
'projectId' => $projectId,
|
|
'month' => $month,
|
|
'metricName' => $metricName,
|
|
'value' => $value,
|
|
]);
|
|
}
|
|
}
|
|
|
|
$pdo->commit();
|
|
|
|
// Recalculate NSR and Margin
|
|
$billing = floatval($metrics_from_form['billing']);
|
|
$expenses = floatval($metrics_from_form['expenses']);
|
|
$cost = floatval($metrics_from_form['cost']);
|
|
$wip = floatval($metrics_from_form['wip']);
|
|
$opening_balance = floatval($metrics_from_form['opening_balance']);
|
|
|
|
$nsr = $wip + $billing - $opening_balance - $expenses;
|
|
$margin = ($nsr > 0) ? (($nsr - $cost) / $nsr) : 0;
|
|
|
|
|
|
// Fetch the updated data to send back
|
|
$stmt = $pdo->prepare("SELECT metricName, value FROM projectFinanceMonthly WHERE projectId = ? AND month = ?");
|
|
$stmt->execute([$projectId, $month]);
|
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$response_data['success'] = true;
|
|
$response_data['message'] = 'Override saved successfully.';
|
|
|
|
foreach ($rows as $row) {
|
|
// Map db snake_case to form's camelCase
|
|
if ($row['metricName'] === 'opening_balance') {
|
|
$response_data['openingBalance'] = $row['value'];
|
|
} else if ($row['metricName'] === 'billing') {
|
|
$response_data['billings'] = $row['value'];
|
|
} else {
|
|
// Directly map other metrics like 'wip', 'expenses'
|
|
$response_data[$row['metricName']] = $row['value'];
|
|
}
|
|
}
|
|
|
|
$response_data['nsr'] = $nsr;
|
|
$response_data['margin'] = $margin;
|
|
|
|
send_json_response($response_data);
|
|
|
|
} catch (Exception $e) {
|
|
if (isset($pdo) && $pdo->inTransaction()) {
|
|
$pdo->rollBack();
|
|
}
|
|
// Log the error and send a JSON response directly
|
|
error_log($e->getMessage());
|
|
send_json_response(['success' => false, 'message' => 'A server error occurred: ' . $e->getMessage()]);
|
|
}
|