Files
erp_naurua/public/api/market-occurrence.php
T

195 lines
9.1 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../../modules/shared/db.php';
require_once __DIR__ . '/../../modules/shared/auth/service.php';
require_once __DIR__ . '/../../modules/erp/kontakte/service.php';
require_once __DIR__ . '/../../modules/market_management/service.php';
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
$env = expand_env_values(parse_env_file(__DIR__ . '/../../.env'));
$pdo = connect_database($env);
auth_bootstrap_session();
if (auth_current_user($pdo) === null) {
http_response_code(401);
echo json_encode(['ok' => false, 'error' => 'Unauthorized']);
exit;
}
$requestMethod = strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET'));
if ($requestMethod === 'POST') {
$csrf = (string) ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? '');
if (!auth_validate_csrf_token($csrf)) {
http_response_code(419);
echo json_encode(['ok' => false, 'error' => 'Ungültiges Sicherheits-Token']);
exit;
}
$payload = json_decode((string) file_get_contents('php://input'), true);
if (!is_array($payload)) {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'Ungültige Anfrage']);
exit;
}
try {
if (($payload['action'] ?? '') === 'create') {
$fields = is_array($payload['fields'] ?? null) ? $payload['fields'] : [];
$occurrence = market_management_create_occurrence($pdo, [
'market_definition_id' => $fields['market_definition_id'] ?? null,
'days' => [['date' => $fields['date'] ?? null]],
]);
echo json_encode(['ok' => true, 'occurrence_id' => (int) $occurrence['id']], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
$scope = (string) ($payload['scope'] ?? '');
$id = market_management_require_positive_id($payload['id'] ?? null, 'id');
$fields = is_array($payload['fields'] ?? null) ? $payload['fields'] : [];
$costTransactionStarted = false;
if (($payload['action'] ?? '') === 'delete') {
if (($payload['confirmation'] ?? '') !== 'DELETE') {
throw new InvalidArgumentException('Die Löschbestätigung muss exakt DELETE lauten.');
}
market_management_set_occurrence_archive($pdo, $id, true);
} elseif (($payload['action'] ?? '') === 'create_day') {
$fields['occurrence_id'] = $id;
$day = market_management_create_day($pdo, $fields);
echo json_encode(['ok' => true, 'day' => $day]);
exit;
} elseif (($payload['action'] ?? '') === 'delete_day') {
if (($payload['confirmation'] ?? '') !== 'DELETE') {
throw new InvalidArgumentException('Bestätigung muss exakt DELETE lauten.');
}
$day = market_management_delete_day($pdo, $id);
echo json_encode(['ok' => true, 'day' => $day]);
exit;
} elseif (($payload['action'] ?? '') === 'create_cost_item') {
$fields['occurrence_id'] = $id;
$costItem = market_management_create_cost_item($pdo, $fields);
echo json_encode(['ok' => true, 'cost_item' => $costItem], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
} elseif (($payload['action'] ?? '') === 'update_cost_item') {
$costItem = market_management_update_cost_item($pdo, $id, $fields);
echo json_encode(['ok' => true, 'cost_item' => $costItem], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
} elseif (($payload['action'] ?? '') === 'delete_cost_item') {
if (($payload['confirmation'] ?? '') !== 'DELETE') {
throw new InvalidArgumentException('Bestätigung muss exakt DELETE lauten.');
}
$costItem = market_management_delete_cost_item($pdo, $id);
echo json_encode(['ok' => true, 'cost_item' => $costItem], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
} elseif ($scope === 'day') {
market_management_update_day($pdo, $id, $fields);
} elseif (in_array($scope, ['occurrence', 'status', 'overview', 'participation', 'infrastructure', 'travel', 'notes'], true)) {
$contactFields = [];
foreach (['contact_person_name', 'contact_email', 'contact_phone'] as $contactField) {
if (array_key_exists($contactField, $fields)) {
$contactFields[$contactField] = $fields[$contactField];
unset($fields[$contactField]);
}
}
$existingOccurrence = null;
if ($contactFields !== []) {
$existingOccurrence = market_management_get_occurrence($pdo, $id, true);
}
if ($contactFields !== []) {
$contactFields['occurrence_id'] = $id;
market_management_set_occurrence_contact($pdo, $contactFields);
}
if ($fields !== []) {
$costItems = null;
if (array_key_exists('cost_items', $fields)) {
$costItems = is_string($fields['cost_items']) ? json_decode($fields['cost_items'], true) : $fields['cost_items'];
if (!is_array($costItems)) {
throw new InvalidArgumentException('Kostenpositionen sind ungültig.');
}
if (!$pdo->inTransaction()) {
$pdo->beginTransaction();
$costTransactionStarted = true;
}
unset($fields['cost_items']);
$keptCostItemIds = array_values(array_filter(array_map(
static fn (array $costItem): ?int => isset($costItem['id']) ? (int) $costItem['id'] : null,
array_filter($costItems, 'is_array')
)));
$existingCostItems = $pdo->prepare('SELECT id FROM market_occurrence_cost_item WHERE occurrence_id = :occurrence_id ORDER BY id ASC');
$existingCostItems->execute([':occurrence_id' => $id]);
foreach ($existingCostItems->fetchAll(PDO::FETCH_COLUMN) as $existingCostItemId) {
if (!in_array((int) $existingCostItemId, $keptCostItemIds, true)) {
market_management_delete_cost_item($pdo, (int) $existingCostItemId);
}
}
foreach ($costItems as $costItem) {
if (!is_array($costItem)) {
throw new InvalidArgumentException('Kostenposition ist ungültig.');
}
if (($costItem['cost_type_id'] ?? null) === '__new__') {
$newCostTypeName = trim((string) ($costItem['cost_type_name'] ?? ''));
$newCostType = market_management_create_cost_type($pdo, $newCostTypeName);
$costItem['cost_type_id'] = (int) $newCostType['id'];
}
unset($costItem['cost_type_name']);
if (isset($costItem['id'])) {
$costItemId = market_management_require_positive_id($costItem['id'], 'cost_item_id');
unset($costItem['id']);
market_management_update_cost_item($pdo, $costItemId, $costItem);
} else {
$costItem['occurrence_id'] = $id;
market_management_create_cost_item($pdo, $costItem);
}
}
}
market_management_update_occurrence($pdo, $id, $fields);
if ($costTransactionStarted) {
$pdo->commit();
$costTransactionStarted = false;
}
}
} else {
throw new InvalidArgumentException('Ungültiger Bearbeitungsbereich.');
}
echo json_encode(['ok' => true]);
exit;
} catch (Throwable $error) {
if ($costTransactionStarted && $pdo->inTransaction()) {
$pdo->rollBack();
}
http_response_code(422);
echo json_encode(['ok' => false, 'error' => $error->getMessage()], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
}
if (($requestMethod === 'GET') && ($_GET['action'] ?? '') === 'create_options') {
echo json_encode([
'ok' => true,
'market_definitions' => market_management_list_active_market_definitions($pdo),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
$occurrenceId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if (!is_int($occurrenceId) || $occurrenceId <= 0) {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'Invalid occurrence id']);
exit;
}
$occurrence = market_management_get_occurrence($pdo, $occurrenceId);
if ($occurrence === null) {
http_response_code(404);
echo json_encode(['ok' => false, 'error' => 'Occurrence not found']);
exit;
}
$market = market_management_get_market($pdo, (int) $occurrence['market_definition_id']);
if ($market === null) {
http_response_code(404);
echo json_encode(['ok' => false, 'error' => 'Market not found']);
exit;
}
echo json_encode(['ok' => true, 'market' => $market, 'occurrence' => $occurrence], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);