233 lines
7.0 KiB
PHP
233 lines
7.0 KiB
PHP
<?php
|
|
|
|
/**
|
|
* BOHA Automation - Bank Accounts API
|
|
*
|
|
* GET /api/admin/bank-accounts.php - Seznam bankovnich uctu
|
|
* POST /api/admin/bank-accounts.php - Vytvoreni uctu
|
|
* PUT /api/admin/bank-accounts.php?id=X - Uprava uctu
|
|
* DELETE /api/admin/bank-accounts.php?id=X - Smazani uctu
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once dirname(__DIR__) . '/config.php';
|
|
require_once dirname(__DIR__) . '/includes/JWTAuth.php';
|
|
require_once dirname(__DIR__) . '/includes/AuditLog.php';
|
|
|
|
setCorsHeaders();
|
|
setSecurityHeaders();
|
|
setNoCacheHeaders();
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
$authData = JWTAuth::requireAuth();
|
|
AuditLog::setUser($authData['user_id'], $authData['user']['username'] ?? 'unknown');
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$id = isset($_GET['id']) ? (int) $_GET['id'] : null;
|
|
|
|
try {
|
|
$pdo = db();
|
|
|
|
switch ($method) {
|
|
case 'GET':
|
|
requirePermission($authData, 'offers.settings');
|
|
handleGetBankAccountList($pdo);
|
|
break;
|
|
|
|
case 'POST':
|
|
requirePermission($authData, 'offers.settings');
|
|
handleCreateBankAccount($pdo);
|
|
break;
|
|
|
|
case 'PUT':
|
|
requirePermission($authData, 'offers.settings');
|
|
if (!$id) {
|
|
errorResponse('ID účtu je povinné');
|
|
}
|
|
handleUpdateBankAccount($pdo, $id);
|
|
break;
|
|
|
|
case 'DELETE':
|
|
requirePermission($authData, 'offers.settings');
|
|
if (!$id) {
|
|
errorResponse('ID účtu je povinné');
|
|
}
|
|
handleDeleteBankAccount($pdo, $id);
|
|
break;
|
|
|
|
default:
|
|
errorResponse('Metoda není povolena', 405);
|
|
}
|
|
} catch (PDOException $e) {
|
|
error_log('Bank Accounts API error: ' . $e->getMessage());
|
|
if (DEBUG_MODE) {
|
|
errorResponse('Chyba databáze: ' . $e->getMessage(), 500);
|
|
} else {
|
|
errorResponse('Chyba databáze', 500);
|
|
}
|
|
}
|
|
|
|
function handleGetBankAccountList(PDO $pdo): void
|
|
{
|
|
$stmt = $pdo->query('SELECT * FROM bank_accounts ORDER BY position, id');
|
|
successResponse($stmt->fetchAll());
|
|
}
|
|
|
|
function handleCreateBankAccount(PDO $pdo): void
|
|
{
|
|
$input = getJsonInput();
|
|
|
|
$accountName = trim($input['account_name'] ?? '');
|
|
$bankName = trim($input['bank_name'] ?? '');
|
|
$accountNumber = trim($input['account_number'] ?? '');
|
|
$iban = trim($input['iban'] ?? '');
|
|
$bic = trim($input['bic'] ?? '');
|
|
$currency = trim($input['currency'] ?? 'CZK');
|
|
$isDefault = !empty($input['is_default']) ? 1 : 0;
|
|
|
|
if (!$accountName) {
|
|
errorResponse('Název účtu je povinný');
|
|
}
|
|
if (mb_strlen($accountName) > 100) {
|
|
errorResponse('Název účtu je příliš dlouhý (max 100 znaků)');
|
|
}
|
|
if (mb_strlen($bankName) > 255) {
|
|
errorResponse('Název banky je příliš dlouhý (max 255 znaků)');
|
|
}
|
|
if (mb_strlen($accountNumber) > 50) {
|
|
errorResponse('Číslo účtu je příliš dlouhé (max 50 znaků)');
|
|
}
|
|
if (mb_strlen($iban) > 50) {
|
|
errorResponse('IBAN je příliš dlouhý (max 50 znaků)');
|
|
}
|
|
if (mb_strlen($bic) > 20) {
|
|
errorResponse('BIC/SWIFT je příliš dlouhý (max 20 znaků)');
|
|
}
|
|
if (!in_array($currency, ['CZK', 'EUR', 'USD', 'GBP'])) {
|
|
errorResponse('Neplatná měna');
|
|
}
|
|
|
|
// Zjistit dalsi pozici
|
|
$maxPos = (int) $pdo->query('SELECT COALESCE(MAX(position), 0) FROM bank_accounts')->fetchColumn();
|
|
|
|
$pdo->beginTransaction();
|
|
try {
|
|
// Pokud je default, zrusit ostatnim
|
|
if ($isDefault) {
|
|
$pdo->exec('UPDATE bank_accounts SET is_default = 0');
|
|
}
|
|
|
|
$stmt = $pdo->prepare('
|
|
INSERT INTO bank_accounts
|
|
(account_name, bank_name, account_number, iban, bic, currency, is_default, position)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
');
|
|
$stmt->execute([$accountName, $bankName, $accountNumber, $iban, $bic, $currency, $isDefault, $maxPos + 1]);
|
|
$newId = (int) $pdo->lastInsertId();
|
|
|
|
$pdo->commit();
|
|
|
|
AuditLog::logCreate(
|
|
'bank_account',
|
|
$newId,
|
|
['account_name' => $accountName],
|
|
"Vytvořen bankovní účet '$accountName'"
|
|
);
|
|
|
|
successResponse(['id' => $newId], 'Bankovní účet byl vytvořen');
|
|
} catch (PDOException $e) {
|
|
$pdo->rollBack();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
function handleUpdateBankAccount(PDO $pdo, int $id): void
|
|
{
|
|
$stmt = $pdo->prepare('SELECT * FROM bank_accounts WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
$account = $stmt->fetch();
|
|
|
|
if (!$account) {
|
|
errorResponse('Bankovní účet nebyl nalezen', 404);
|
|
}
|
|
|
|
$input = getJsonInput();
|
|
|
|
// Delkove limity a validace
|
|
$maxLengths = ['account_name' => 100, 'bank_name' => 255, 'account_number' => 50, 'iban' => 50, 'bic' => 20];
|
|
foreach ($maxLengths as $f => $max) {
|
|
if (isset($input[$f]) && mb_strlen(trim((string)$input[$f])) > $max) {
|
|
errorResponse("Pole $f je příliš dlouhé (max $max znaků)");
|
|
}
|
|
}
|
|
if (isset($input['currency']) && !in_array($input['currency'], ['CZK', 'EUR', 'USD', 'GBP'])) {
|
|
errorResponse('Neplatná měna');
|
|
}
|
|
|
|
$fields = ['account_name', 'bank_name', 'account_number', 'iban', 'bic', 'currency'];
|
|
$updates = [];
|
|
$params = [];
|
|
|
|
foreach ($fields as $field) {
|
|
if (array_key_exists($field, $input)) {
|
|
$updates[] = "$field = ?";
|
|
$params[] = trim((string) $input[$field]);
|
|
}
|
|
}
|
|
|
|
$pdo->beginTransaction();
|
|
try {
|
|
if (array_key_exists('is_default', $input)) {
|
|
$isDefault = !empty($input['is_default']) ? 1 : 0;
|
|
if ($isDefault) {
|
|
$pdo->exec('UPDATE bank_accounts SET is_default = 0');
|
|
}
|
|
$updates[] = 'is_default = ?';
|
|
$params[] = $isDefault;
|
|
}
|
|
|
|
if (empty($updates)) {
|
|
errorResponse('Žádná data k aktualizaci');
|
|
}
|
|
|
|
$updates[] = 'modified_at = NOW()';
|
|
$params[] = $id;
|
|
|
|
$sql = 'UPDATE bank_accounts SET ' . implode(', ', $updates) . ' WHERE id = ?';
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
|
|
$pdo->commit();
|
|
|
|
AuditLog::logUpdate('bank_account', $id, [], $input, "Aktualizován bankovní účet #{$id}");
|
|
|
|
successResponse(null, 'Bankovní účet byl aktualizován');
|
|
} catch (PDOException $e) {
|
|
$pdo->rollBack();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
function handleDeleteBankAccount(PDO $pdo, int $id): void
|
|
{
|
|
$stmt = $pdo->prepare('SELECT * FROM bank_accounts WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
$account = $stmt->fetch();
|
|
|
|
if (!$account) {
|
|
errorResponse('Bankovní účet nebyl nalezen', 404);
|
|
}
|
|
|
|
$pdo->prepare('DELETE FROM bank_accounts WHERE id = ?')->execute([$id]);
|
|
|
|
AuditLog::logDelete(
|
|
'bank_account',
|
|
$id,
|
|
['account_name' => $account['account_name']],
|
|
"Smazán bankovní účet '{$account['account_name']}'"
|
|
);
|
|
|
|
successResponse(null, 'Bankovní účet byl smazán');
|
|
}
|