Auto commit: 2025-11-27T12:16:59.506Z
This commit is contained in:
parent
893b3b9bfa
commit
ffe0142f5f
@ -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();
|
||||
}
|
||||
|
||||
@ -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">€<?php echo number_format($totalBilling, 2); ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
@ -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;
|
||||
Loading…
x
Reference in New Issue
Block a user