Auto commit: 2025-11-27T12:16:59.506Z

This commit is contained in:
Flatlogic Bot 2025-11-27 12:16:59 +00:00
parent 893b3b9bfa
commit ffe0142f5f
5 changed files with 77 additions and 27 deletions

View File

@ -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();
}

View File

@ -63,6 +63,7 @@ try {
<h1 class="h2">Billing - <?php echo htmlspecialchars($project['name']); ?></h1>
<div class="header-actions">
<a href="project_details.php?id=<?php echo $projectId; ?>" class="btn btn-secondary">Return</a>
<button id="save-billing" class="btn btn-primary">Save</button>
<a href="export_billing.php?id=<?php echo $projectId; ?>" class="btn btn-secondary">Export to Excel</a>
</div>
</div>
@ -84,16 +85,20 @@ try {
$currentMonth->modify('+1 month');
}
?>
<th style="width: 150px;">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Billing</td>
<?php
$totalBilling = 0;
foreach ($billingData as $billingMonth) {
$totalBilling += $billingMonth['amount'];
echo '<td><input type="number" class="form-control billing-amount" data-month="' . $billingMonth['month'] . '" value="' . htmlspecialchars($billingMonth['amount']) . '"></td>';
}
?>
<td id="total-billing" class="fw-bold">&euro;<?php echo number_format($totalBilling, 2); ?></td>
</tr>
</tbody>
</table>

View File

@ -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);

View File

@ -6,27 +6,39 @@ $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.';

View File

@ -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;