Fix: Change 'amount' to 'price' to match database schema - Database uses 'price' column, not 'amount' - Update all queries in DailySummaryService, HourlySummaryService - Update RetribusiWriteService (SELECT, INSERT, UPDATE) - Update Validator to use 'price' field - Update check_database.php and TROUBLESHOOTING.md

This commit is contained in:
mwpn
2025-12-17 13:36:29 +07:00
parent 56403469ef
commit ca3b1bd0d7
8 changed files with 61 additions and 52 deletions

5
.gitignore vendored
View File

@@ -31,7 +31,10 @@ composer.phar
composer.lock
# Backup
*.sql
*.bak
backup/
# SQL files (exclude backup, but allow migrations)
*.sql
!migrations/*.sql

View File

@@ -81,6 +81,7 @@ composer dump-autoload --optimize
Masuk ke: **Website -> api.btekno.cloud -> Settings -> Configuration**
Ganti isi configuration dengan:
```nginx
server {
listen 80;
@@ -128,6 +129,7 @@ composer dump-autoload --optimize
```
**Cek PHP socket path:**
```bash
# Cek PHP version yang digunakan
php -v

View File

@@ -2,10 +2,14 @@
## Error: "Unknown column 't.amount' in 'SELECT'"
### Kemungkinan Penyebab:
### Root Cause:
**Kolom di database adalah `price`, bukan `amount`!**
Database production menggunakan kolom `price` di tabel `tariffs`, tapi code menggunakan `amount`. Ini menyebabkan mismatch.
### Kemungkinan Penyebab Lain:
1. **OPcache belum di-clear** - PHP masih menggunakan file lama
2. **Struktur database berbeda** - Kolom `amount` mungkin tidak ada atau nama berbeda
3. **File belum ter-update** - Meskipun sudah `git pull`, file mungkin belum benar-benar ter-update
2. **File belum ter-update** - Meskipun sudah `git pull`, file mungkin belum benar-benar ter-update
---
@@ -65,7 +69,7 @@ SELECT
e.gate_code,
e.category,
COUNT(*) as total_count,
COALESCE(t.amount, 0) as tariff_amount
COALESCE(t.price, 0) as tariff_amount
FROM entry_events e
INNER JOIN locations l ON e.location_code = l.code AND l.is_active = 1
INNER JOIN gates g ON e.location_code = g.location_code
@@ -80,7 +84,7 @@ GROUP BY
e.location_code,
e.gate_code,
e.category,
COALESCE(t.amount, 0)
COALESCE(t.price, 0)
LIMIT 5;
```

View File

@@ -92,7 +92,7 @@ try {
e.gate_code,
e.category,
COUNT(*) as total_count,
COALESCE(t.amount, 0) as tariff_amount
COALESCE(t.price, 0) as tariff_amount
FROM entry_events e
INNER JOIN locations l ON e.location_code = l.code AND l.is_active = 1
INNER JOIN gates g ON e.location_code = g.location_code
@@ -107,7 +107,7 @@ try {
e.location_code,
e.gate_code,
e.category,
COALESCE(t.amount, 0)
COALESCE(t.price, 0)
LIMIT 1
";

View File

@@ -236,7 +236,7 @@ class RetribusiWriteService
public function getTariff(string $locationCode, string $gateCode, string $category): ?array
{
$stmt = $this->db->prepare(
'SELECT location_code, gate_code, category, amount
'SELECT location_code, gate_code, category, price
FROM tariffs
WHERE location_code = ? AND gate_code = ? AND category = ?
LIMIT 1'
@@ -256,7 +256,7 @@ class RetribusiWriteService
public function createTariff(array $data): array
{
$stmt = $this->db->prepare(
'INSERT INTO tariffs (location_code, gate_code, category, amount)
'INSERT INTO tariffs (location_code, gate_code, category, price)
VALUES (?, ?, ?, ?)'
);
@@ -264,7 +264,7 @@ class RetribusiWriteService
$data['location_code'],
$data['gate_code'],
$data['category'],
(int) $data['amount']
(int) $data['price']
]);
return $this->getTariff($data['location_code'], $data['gate_code'], $data['category']);
@@ -285,9 +285,9 @@ class RetribusiWriteService
$updates = [];
$params = [];
if (isset($data['amount'])) {
$updates[] = 'amount = ?';
$params[] = (int) $data['amount'];
if (isset($data['price'])) {
$updates[] = 'price = ?';
$params[] = (int) $data['price'];
}
if (empty($updates)) {

View File

@@ -43,7 +43,7 @@ class DailySummaryService
e.gate_code,
e.category,
COUNT(*) as total_count,
COALESCE(t.amount, 0) as tariff_amount
COALESCE(t.price, 0) as tariff_amount
FROM entry_events e
INNER JOIN locations l ON e.location_code = l.code AND l.is_active = 1
INNER JOIN gates g ON e.location_code = g.location_code
@@ -58,7 +58,7 @@ class DailySummaryService
e.location_code,
e.gate_code,
e.category,
COALESCE(t.amount, 0)
COALESCE(t.price, 0)
";
$stmt = $this->db->prepare($sql);

View File

@@ -45,7 +45,7 @@ class HourlySummaryService
e.gate_code,
e.category,
COUNT(*) as total_count,
COALESCE(t.amount, 0) as tariff_amount
COALESCE(t.price, 0) as tariff_amount
FROM entry_events e
INNER JOIN locations l ON e.location_code = l.code AND l.is_active = 1
INNER JOIN gates g ON e.location_code = g.location_code
@@ -61,7 +61,7 @@ class HourlySummaryService
e.location_code,
e.gate_code,
e.category,
COALESCE(t.amount, 0)
COALESCE(t.price, 0)
";
$stmt = $this->db->prepare($sql);

View File

@@ -281,15 +281,15 @@ class Validator
}
}
// Amount: required for POST, optional for update
if (isset($data['amount'])) {
if (!is_int($data['amount']) && !is_numeric($data['amount'])) {
$errors['amount'] = 'Must be an integer';
} elseif ((int) $data['amount'] < 0) {
$errors['amount'] = 'Must be >= 0';
// Price: required for POST, optional for update
if (isset($data['price'])) {
if (!is_int($data['price']) && !is_numeric($data['price'])) {
$errors['price'] = 'Must be an integer';
} elseif ((int) $data['price'] < 0) {
$errors['price'] = 'Must be >= 0';
}
} elseif (!$isUpdate) {
$errors['amount'] = 'Field is required';
$errors['price'] = 'Field is required';
}
return $errors;