diff --git a/assets/js/billing.js b/assets/js/billing.js index 282d32e..4c2f680 100644 --- a/assets/js/billing.js +++ b/assets/js/billing.js @@ -1,13 +1,33 @@ function initBillingPage(projectId) { - document.querySelectorAll('.billing-amount').forEach(input => { - input.addEventListener('blur', function() { - const month = this.dataset.month; - const amount = this.value; + const saveBtn = document.getElementById('save-billing'); + const billingAmountInputs = document.querySelectorAll('.billing-amount'); + const totalBillingCell = document.getElementById('total-billing'); + + function updateTotalBilling() { + let total = 0; + billingAmountInputs.forEach(input => { + total += parseFloat(input.value) || 0; + }); + totalBillingCell.textContent = `€${total.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; + } + + billingAmountInputs.forEach(input => { + input.addEventListener('keyup', updateTotalBilling); + }); + + if (saveBtn) { + saveBtn.addEventListener('click', function() { + const billingData = []; + billingAmountInputs.forEach(input => { + billingData.push({ + month: input.dataset.month, + amount: input.value + }); + }); const formData = new FormData(); formData.append('projectId', projectId); - formData.append('month', month); - formData.append('amount', amount); + formData.append('billingData', JSON.stringify(billingData)); fetch('save_billing.php', { method: 'POST', @@ -16,9 +36,9 @@ function initBillingPage(projectId) { .then(response => response.json()) .then(data => { if (data.success) { - // Maybe show a small success indicator + alert('Billing data saved successfully!'); } else { - alert('Error saving billing amount: ' + data.error); + alert('Error saving billing data: ' + data.error); } }) .catch(error => { @@ -26,5 +46,8 @@ function initBillingPage(projectId) { alert('An unexpected error occurred.'); }); }); - }); + } + + // Initial calculation + updateTotalBilling(); } diff --git a/billing.php b/billing.php index e404f20..9805ab8 100644 --- a/billing.php +++ b/billing.php @@ -63,6 +63,7 @@ try {

Billing -

Return + Export to Excel
@@ -84,16 +85,20 @@ try { $currentMonth->modify('+1 month'); } ?> + Total Billing '; } ?> + € diff --git a/export_billing.php b/export_billing.php index 733e481..cb2110c 100644 --- a/export_billing.php +++ b/export_billing.php @@ -26,9 +26,12 @@ try { // Header row $header = ['Billing']; + $totalBilling = 0; foreach ($billingData as $row) { $header[] = date("M Y", strtotime($row['month'])); + $totalBilling += $row['amount']; } + $header[] = 'Total'; fputcsv($output, $header); // Data row @@ -36,6 +39,7 @@ try { foreach ($billingData as $row) { $data[] = $row['amount']; } + $data[] = $totalBilling; fputcsv($output, $data); fclose($output); diff --git a/save_billing.php b/save_billing.php index 4481695..961d9b2 100644 --- a/save_billing.php +++ b/save_billing.php @@ -6,31 +6,43 @@ $response = ['success' => false, 'error' => 'Invalid request']; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $projectId = $_POST['projectId'] ?? null; - $month = $_POST['month'] ?? null; - $amount = $_POST['amount'] ?? null; + $billingDataJson = $_POST['billingData'] ?? null; - if ($projectId && $month && $amount !== null) { - try { - $pdo = db(); - $stmt = $pdo->prepare("UPDATE billingMonthly SET amount = :amount WHERE projectId = :projectId AND month = :month"); - $stmt->execute([ - ':amount' => $amount, - ':projectId' => $projectId, - ':month' => $month - ]); + if ($projectId && $billingDataJson) { + $billingData = json_decode($billingDataJson, true); + + if (is_array($billingData)) { + try { + $pdo = db(); + $stmt = $pdo->prepare("UPDATE billingMonthly SET amount = :amount WHERE projectId = :projectId AND month = :month"); + + $pdo->beginTransaction(); + foreach ($billingData as $item) { + $stmt->execute([ + ':amount' => $item['amount'], + ':projectId' => $projectId, + ':month' => $item['month'] + ]); + } + $pdo->commit(); - if ($stmt->rowCount() > 0) { $response['success'] = true; unset($response['error']); - } else { - $response['error'] = 'No record found to update.'; + + } catch (PDOException $e) { + if ($pdo->inTransaction()) { + $pdo->rollBack(); + } + $response['error'] = 'Database error: ' . $e->getMessage(); + } catch (Exception $e) { + $response['error'] = 'An unexpected error occurred: ' . $e->getMessage(); } - } catch (PDOException $e) { - $response['error'] = 'Database error: ' . $e->getMessage(); + } else { + $response['error'] = 'Invalid billing data format.'; } } else { $response['error'] = 'Missing required fields.'; } } -echo json_encode($response); +echo json_encode($response); \ No newline at end of file diff --git a/save_override.php b/save_override.php index 6291136..8503930 100644 --- a/save_override.php +++ b/save_override.php @@ -93,5 +93,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } } -echo json_encode($response); +try { + echo json_encode($response, JSON_THROW_ON_ERROR); +} catch (JsonException $e) { + error_log('JSON encoding error: ' . $e->getMessage()); + http_response_code(500); + echo json_encode(['success' => false, 'error' => 'Internal server error during JSON encoding.']); +} exit; \ No newline at end of file