diff --git a/FIX_AND_MIGRATE.php b/FIX_AND_MIGRATE.php new file mode 100644 index 0000000..056505b --- /dev/null +++ b/FIX_AND_MIGRATE.php @@ -0,0 +1,76 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + echo "--- ๐ ์ฌ์ธต ๋ง์ด๊ทธ๋ ์ด์ ๋ฐ ๋ฐ์ดํฐ ๋ณต๊ตฌ ์์ ---\n"; + + // 1. ์คํค๋ง ๊ฐ์ ๋ณด์ + $newColumns = [ + 'disposal_recipient' => 'TEXT', + 'disposal_date' => 'TEXT', + 'real_user' => 'TEXT', + 'disposal_user_id' => 'INTEGER' + ]; + foreach ($newColumns as $col => $type) { + try { + $db->exec("ALTER TABLE laptop_assets ADD COLUMN $col $type"); + echo "โ ์ปฌ๋ผ ๋ณด์ : $col\n"; + } catch (PDOException $e) { + // Already exists or other error + } + } + + // 2. ์ธ์ฝ๋ฉ ๋ณต๊ตฌ (URL-Encoded ๋ฐ์ดํฐ๊ฐ ์๋ณ๋์ด ์์ ์๋) + $stmt = $db->query("SELECT id, assigned_user_name, disposal_recipient FROM laptop_assets"); + $assets = $stmt->fetchAll(PDO::FETCH_ASSOC); + + $fixCount = 0; + $updateStmt = $db->prepare("UPDATE laptop_assets SET assigned_user_name = ?, disposal_recipient = ? WHERE id = ?"); + + foreach ($assets as $asset) { + $uName = $asset['assigned_user_name']; + $dRec = $asset['disposal_recipient']; + + $newUName = $uName; + $newDRec = $dRec; + + // URL ์ธ์ฝ๋ฉ ํ์ง ๋ฐ ๋ณํ + if ($uName && strpos($uName, '%') !== false) { + $newUName = urldecode($uName); + } + if ($dRec && strpos($dRec, '%') !== false) { + $newDRec = urldecode($dRec); + } + + if ($newUName !== $uName || $newDRec !== $dRec) { + $updateStmt->execute([$newUName, $newDRec, $asset['id']]); + $fixCount++; + } + } + echo "โ Mojibake/URL-Encoding ๋ฐ์ดํฐ ๋ณต๊ตฌ: {$fixCount}๊ฑด ์์ ์๋ฃ.\n"; + + // 3. STOCK ์์ฐ ๋ช ์น ๋๊ธฐํ + $stmtStock = $db->prepare("UPDATE laptop_assets SET assigned_user_name = '์ ๋ฌด์ฉ(TEMP_44666b)', current_user_id = NULL WHERE status = 'stock'"); + $stmtStock->execute(); + echo "โ ์ฌ๊ณ (STOCK) ๋ช ์นญ ๋๊ธฐํ ์๋ฃ.\n"; + + echo "--- ๐ ๋ชจ๋ ๋ณต๊ตฌ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์ ์ด ์๋ฃ๋์์ต๋๋ค. ---"; + +} catch (Exception $e) { + echo "โ ์ค๋ฅ: " . $e->getMessage() . "\n"; +} +?> \ No newline at end of file diff --git a/RECOVER_MIGRATE.php b/RECOVER_MIGRATE.php new file mode 100644 index 0000000..61785d0 --- /dev/null +++ b/RECOVER_MIGRATE.php @@ -0,0 +1,89 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + echo "--- [๋ณต๊ตฌ ๋ง์ด๊ทธ๋ ์ด์ ์์] ๋ ธํธ๋ถ ์์ฐ ๊ด๋ฆฌ ์์คํ v2.1 ---\n\n"; + + // 2. ๋ฐฑ์ ์์ฑ + $backupPath = $dbPath . '.bak_' . date('Ymd_His'); + if (!copy($dbPath, $backupPath)) { + throw new Exception("๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์ ์์ฑ ์คํจ"); + } + echo "๐ก๏ธ ๋ฐ์ดํฐ ์์ : ์์ ์ ์๋ณธ ๋ฐฑ์ ์ด ์์ฑ๋์์ต๋๋ค. ($backupPath)\n"; + + // 3. ์คํค๋ง ํ์ฅ (์ ๊ท ๊ท๊ฒฉ ์ปฌ๋ผ ์ถ๊ฐ) + $newColumns = [ + 'disposal_recipient' => 'TEXT', + 'disposal_date' => 'TEXT', + 'real_user' => 'TEXT', + 'disposal_user_id' => 'INTEGER' + ]; + + foreach ($newColumns as $col => $type) { + try { + $db->exec("ALTER TABLE laptop_assets ADD COLUMN $col $type"); + echo "โ ์ปฌ๋ผ ๋ณด์ ์ฑ๊ณต: $col\n"; + } catch (PDOException $e) { + if (strpos($e->getMessage(), 'duplicate column name') !== false) { + echo "โน๏ธ ์ด๋ฏธ ์กด์ฌํจ: $col (์คํค๋ง ์ ์ง)\n"; + } else { + throw $e; + } + } + } + + // 4. ๋ฐ์ดํฐ ์ ํฉ์ฑ - STOCK ์์ฐ '์ ๋ฌด์ฉ' ๋ช ์นญ ํตํฉ + $stmtStock = $db->prepare(" + UPDATE laptop_assets + SET assigned_user_name = '์ ๋ฌด์ฉ(TEMP_44666b)', + current_user_id = NULL + WHERE status = 'stock' + AND (assigned_user_name != '์ ๋ฌด์ฉ(TEMP_44666b)' OR assigned_user_name IS NULL) + "); + $stmtStock->execute(); + $affectedStock = $stmtStock->rowCount(); + echo "โ ๋ฐ์ดํฐ ์ ํฉ์ฑ: STOCK ์์ฐ $affectedStock ๊ฑด์ ์ ๋ ฅ์ '์ ๋ฌด์ฉ'์ผ๋ก ํต์ผํ์ต๋๋ค.\n"; + + // 5. ๋ฐ์ดํฐ ์ ํฉ์ฑ - ๋งค๊ฐ ๋์์ ID ๋ณต๊ตฌ (์ง์ DB ๋์กฐ) + $allDisposed = $db->query(" + SELECT id, disposal_recipient + FROM laptop_assets + WHERE status = 'disposed' + AND disposal_recipient IS NOT NULL + AND disposal_user_id IS NULL + ")->fetchAll(PDO::FETCH_ASSOC); + + $idRestored = 0; + $userFinder = $db->prepare("SELECT id FROM users WHERE name = ? LIMIT 1"); + $idUpdater = $db->prepare("UPDATE laptop_assets SET disposal_user_id = ? WHERE id = ?"); + + foreach ($allDisposed as $row) { + $userFinder->execute([$row['disposal_recipient']]); + $uid = $userFinder->fetchColumn(); + if ($uid) { + $idUpdater->execute([$uid, $row['id']]); + $idRestored++; + } + } + echo "โ ๋ฐ์ดํฐ ์ ํฉ์ฑ: DISPOSED ์์ฐ $idRestored ๊ฑด์ ์ฌ์ ๋งคํ์ ์๋ฃํ์ต๋๋ค.\n\n"; + + echo "--- [๋ง์ด๊ทธ๋ ์ด์ ์ฑ๊ณต] ๋ณต๊ตฌ๋ DB๊ฐ ์ต์ ๊ท๊ฒฉ์ผ๋ก ์ ๋ฐ์ดํธ๋์์ต๋๋ค. ---\n"; + +} catch (Exception $e) { + echo "\nโ [๋ง์ด๊ทธ๋ ์ด์ ์คํจ] ์ค๋ฅ ๋ด์ฉ: " . $e->getMessage() . "\n"; +} diff --git a/api.php b/api.php index ffc57a2..e2e792d 100644 --- a/api.php +++ b/api.php @@ -669,34 +669,62 @@ LIMIT 1")->fetchColumn(); } $updates = []; $params = []; + $log_msg = ""; + if ($newStatus) { $updates[] = "status = ?"; $params[] = $newStatus; - // ๋ง์ฝ ์ํ๋ฅผ 'stock'(์ฌ๊ณ )์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ '์ ๋ฌด์ฉ'์ผ๋ก ์ค์ , 'disposed'(๋งค๊ฐ)์ธ ๊ฒฝ์ฐ ์์ ์ด๊ธฐํ if ($newStatus === 'stock') { $updates[] = "current_user_id = NULL"; $updates[] = "assigned_user_name = '์ ๋ฌด์ฉ(TEMP_44666b)'"; + $log_msg = "์ผ๊ด ์ํ ๋ณ๊ฒฝ: ์ฌ๊ณ (์ ๋ฌด์ฉ ์ง์ )"; } elseif ($newStatus === 'disposed') { $updates[] = "current_user_id = NULL"; $updates[] = "assigned_user_name = NULL"; $updates[] = "disposal_date = '" . date('Y-m-d') . "'"; + $log_msg = "์ผ๊ด ์ํ ๋ณ๊ฒฝ: ๋งค๊ฐ๋จ"; + } elseif ($newStatus === 'assigned') { + $log_msg = "์ผ๊ด ์ํ ๋ณ๊ฒฝ: ์ง์๋ฐฐ์ "; } } if ($newModelId) { $updates[] = "model_id = ?"; $params[] = $newModelId; + $log_msg .= ($log_msg ? ", " : "") . "์ผ๊ด ๋ชจ๋ธ ๋ณ๊ฒฝ(ID: $newModelId)"; } + if (empty($updates)) { echo json_encode(['success' => false, 'error' => 'No updates specified']); break; } - $sql = "UPDATE laptop_assets SET " . implode(", ", $updates) . " WHERE id IN (" . implode(",", array_fill( - 0, - count($ids), - "?" - )) . ")"; + + $placeholders = implode(",", array_fill(0, count($ids), "?")); + $sql = "UPDATE laptop_assets SET " . implode(", ", $updates) . " WHERE id IN ($placeholders)"; $stmt = $db->prepare($sql); $stmt->execute(array_merge($params, $ids)); + + // ํ์คํ ๋ฆฌ ์ผ๊ด ๊ธฐ๋ก + if ($log_msg) { + $history_sql = "INSERT INTO asset_history (asset_id, log_type, user_name, action_date, note) VALUES (?, 'bulk_update', '์์คํ (์ผ๊ด)', ?, ?)"; + $h_stmt = $db->prepare($history_sql); + foreach ($ids as $id) { + $h_stmt->execute([$id, date('Y-m-d'), $log_msg]); + } + } + + echo json_encode(['success' => true]); + break; + + case 'bulk_delete_laptops': + $data = json_decode(file_get_contents('php://input'), true); + $ids = $data['ids']; + if (empty($ids)) { + echo json_encode(['success' => false, 'error' => 'No items selected']); + break; + } + $placeholders = implode(",", array_fill(0, count($ids), "?")); + $db->prepare("DELETE FROM laptop_assets WHERE id IN ($placeholders)")->execute($ids); + // ๊ด๋ จ ํ์คํ ๋ฆฌ๋ ์ญ์ ? ๋ณดํต ์์ฐ ์ญ์ ์์๋ ํ์คํ ๋ฆฌ๋ ํจ๊ป ๋ ๋ฆฌ๊ฑฐ๋ ๋จ๊น. ์ฌ๊ธฐ์ DB ์ ํฉ์ฑ์ ์ํด ์ฐ์ ์ญ์ ๋ ์ํ๋๋ผ๋ ์์ฐ์ ์ฌ๋ผ์ง. echo json_encode(['success' => true]); break; @@ -799,6 +827,33 @@ LIMIT 1")->fetchColumn(); echo json_encode(['success' => true]); break; + case 'bulk_delete_models': + $data = json_decode(file_get_contents('php://input'), true); + $ids = $data['ids']; + if (empty($ids)) { + echo json_encode(['success' => false, 'error' => 'No items selected']); + break; + } + try { + $db->beginTransaction(); + $placeholders = implode(",", array_fill(0, count($ids), "?")); + + // 1. ํด๋น ๋ชจ๋ธ์ ์ฐธ์กฐ ์ค์ธ ์์ฐ๋ค์ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ ํด์ (ID ์ฐธ์กฐ๋ฅผ NULL๋ก ๋ณ๊ฒฝ) + $stmt1 = $db->prepare("UPDATE laptop_assets SET model_id = NULL WHERE model_id IN ($placeholders)"); + $stmt1->execute($ids); + + // 2. ๋ ธํธ๋ถ ๋ชจ๋ธ ๋ง์คํฐ ์ ๋ณด ์ญ์ + $stmt2 = $db->prepare("DELETE FROM laptop_models WHERE id IN ($placeholders)"); + $stmt2->execute($ids); + + $db->commit(); + echo json_encode(['success' => true]); + } catch (Exception $e) { + $db->rollBack(); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + break; + case 'bulk_update_users': $data = json_decode(file_get_contents('php://input'), true); $userIds = $data['user_ids']; @@ -1033,6 +1088,20 @@ ORDER BY r.id DESC"; } break; + case 'get_settings': + $settings = $db->query("SELECT key_name, value FROM system_settings")->fetchAll(PDO::FETCH_KEY_PAIR); + echo json_encode(['success' => true, 'settings' => $settings]); + break; + + case 'update_settings': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("INSERT OR REPLACE INTO system_settings (key_name, value) VALUES (?, ?)"); + foreach ($data['settings'] as $key => $value) { + $stmt->execute([$key, (string) $value]); + } + echo json_encode(['success' => true]); + break; + case 'return_general_rental': $data = json_decode(file_get_contents('php://input'), true); $returnDate = date('Y-m-d'); diff --git a/check_schema.php b/check_schema.php index 7a18594..74ae34a 100644 --- a/check_schema.php +++ b/check_schema.php @@ -1,4 +1,19 @@ query("PRAGMA table_info(laptop_assets)")->fetchAll(PDO::FETCH_ASSOC); -echo json_encode($cols, JSON_PRETTY_PRINT); \ No newline at end of file +try { + $db = new PDO('sqlite:d:/Docker/jasan/dda/assets.db'); + $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + echo "--- LAPTOP_ASSETS SCHEMA ---\n"; + $res = $db->query('PRAGMA table_info(laptop_assets)')->fetchAll(); + foreach ($res as $col) { + echo "{$col['name']} ({$col['type']})\n"; + } + + echo "\n--- LAPTOP_MODELS SCHEMA ---\n"; + $res = $db->query('PRAGMA table_info(laptop_models)')->fetchAll(); + foreach ($res as $col) { + echo "{$col['name']} ({$col['type']})\n"; + } +} catch (Exception $e) { + echo $e->getMessage(); +} \ No newline at end of file diff --git a/check_tables.php b/check_tables.php new file mode 100644 index 0000000..7f7d961 --- /dev/null +++ b/check_tables.php @@ -0,0 +1,9 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $tables = $db->query("SELECT name FROM sqlite_master WHERE type='table'")->fetchAll(PDO::FETCH_COLUMN); + print_r($tables); +} catch (Exception $e) { + echo $e->getMessage(); +} diff --git a/dda/assets.db b/dda/assets.db index 7d42aaf..752be65 100644 Binary files a/dda/assets.db and b/dda/assets.db differ diff --git a/dda/assets.db.back b/dda/assets.db.back new file mode 100644 index 0000000..7d42aaf Binary files /dev/null and b/dda/assets.db.back differ diff --git a/dda/assets.db.bak_20260304_122706 b/dda/assets.db.bak_20260304_122706 new file mode 100644 index 0000000..7d42aaf Binary files /dev/null and b/dda/assets.db.bak_20260304_122706 differ diff --git a/dda/assets.db.bak_20260304_122901 b/dda/assets.db.bak_20260304_122901 new file mode 100644 index 0000000..7d42aaf Binary files /dev/null and b/dda/assets.db.bak_20260304_122901 differ diff --git a/debug_db.php b/debug_db.php new file mode 100644 index 0000000..e622bea --- /dev/null +++ b/debug_db.php @@ -0,0 +1,5 @@ +query("SELECT id, asset_tag, status, assigned_user_name FROM laptop_assets LIMIT 50")->fetchAll(PDO::FETCH_ASSOC); +echo json_encode($rows, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); +?> \ No newline at end of file diff --git a/general_rental.php b/general_rental.php index 0cde8fd..261225b 100644 --- a/general_rental.php +++ b/general_rental.php @@ -67,102 +67,118 @@ - -
|
+
+ ์ฌ์๋ช
+
-
-
-
-
-
-
-
-
-
-
-
-
- Rental Employee - -
-
-
-
-
- Rental Items
+ |
+ + ์๋ ํ๋ชฉ | +
+
+ ์๋์ผ
+
-
-
-
-
+ |
+
+
+ ์ํ/๊ฒฝ๊ณผ
+
-
-
-
-
-
-
- Start
- Date
-
-
- Status
+ |
+ + ์ฌ์ | ++ ๊ด๋ฆฌ | +
|---|---|---|---|---|---|
|
+
+
+
+
+
+
|
+
+
+
+
+
+
+ |
+ + + | +
-
-
-
+
-
-
-
-
-
+
+
-
+
+
+
-
-
-
-
-
-
-
-
+ Reason
-
-
- |
+ + + | ++ + + + + ์ฒ๋ฆฌ์๋ฃ + + | +
์์ฐํ๊ทธ/๋ฐฐ์ ํํฉ
์ถ์ ์ฆ ๊ด๋ฆฌ
-๋ณด์์ค ์ฐ๋ ๋ฐ์ดํฐ
-๋ณตํฉ๊ธฐ ๊ณ์
-์์ ๊ณ์ /pw ๊ด๋ฆฌ
-์ถ์ ์ฆ ๊ด๋ฆฌ
+๋ณด์์ค ์ฐ๋ ๋ฐ์ดํฐ
+๋ณตํฉ๊ธฐ ๊ณ์
+์์ ๊ณ์ /pw ๊ด๋ฆฌ
+