Add occurrence checklist submodule
This commit is contained in:
1 parent
5dbbac35c3
commit
f9b5383ae9
12 files changed
+254
-2
No files matched your search
@@ -87,6 +87,8 @@ function market_management_mcp_tools(): array
|
||||
['name' => 'market_management.get_overview', 'description' => 'Marktübersicht mit serverseitigen Filtern lesen', 'inputSchema' => ['type' => 'object', 'properties' => $searchProperties]],
|
||||
['name' => 'market_management.create_occurrence', 'description' => 'Marktdurchführung mit mindestens einem Markttag anlegen', 'inputSchema' => ['type' => 'object', 'required' => ['market_definition_id', 'days'], 'properties' => ['market_definition_id' => ['type' => 'integer'], 'status' => ['type' => 'string'], 'days' => ['type' => 'array', 'minItems' => 1, 'items' => ['type' => 'object', 'required' => ['date'], 'properties' => $dayProperties]] + $occurrenceProperties]]],
|
||||
['name' => 'market_management.get_occurrence', 'description' => 'Marktdurchführung mit Markt, Markttagen und berechneten Verkaufsdaten lesen', 'inputSchema' => ['type' => 'object', 'required' => ['occurrence_id'], 'properties' => ['occurrence_id' => ['type' => 'integer'], 'include_archived' => ['type' => 'boolean']]]],
|
||||
['name' => 'market_management.get_occurrence_checklist', 'description' => 'Checkliste einer Marktdurchführung lesen', 'inputSchema' => ['type' => 'object', 'required' => ['occurrence_id'], 'properties' => ['occurrence_id' => ['type' => 'integer'], 'include_archived' => ['type' => 'boolean']]]],
|
||||
['name' => 'market_management.update_occurrence_checklist', 'description' => 'Checkliste einer Marktdurchführung vollständig ersetzen', 'inputSchema' => ['type' => 'object', 'required' => ['occurrence_id', 'items'], 'properties' => ['occurrence_id' => ['type' => 'integer'], 'comment' => ['type' => ['string', 'null']], 'items' => ['type' => 'array', 'items' => ['type' => 'object', 'required' => ['label', 'is_completed'], 'properties' => ['label' => ['type' => 'string'], 'is_completed' => ['type' => 'boolean']]]]]]],
|
||||
['name' => 'market_management.update_occurrence', 'description' => 'Marktdurchführung ändern', 'inputSchema' => ['type' => 'object', 'required' => ['occurrence_id'], 'properties' => ['occurrence_id' => ['type' => 'integer']] + $occurrenceProperties]],
|
||||
['name' => 'market_management.archive_occurrence', 'description' => 'Marktdurchführung archivieren', 'inputSchema' => ['type' => 'object', 'required' => ['occurrence_id'], 'properties' => ['occurrence_id' => ['type' => 'integer']]]],
|
||||
['name' => 'market_management.reactivate_occurrence', 'description' => 'Marktdurchführung reaktivieren', 'inputSchema' => ['type' => 'object', 'required' => ['occurrence_id'], 'properties' => ['occurrence_id' => ['type' => 'integer']]]],
|
||||
@@ -104,6 +106,7 @@ function market_management_mcp_is_write_tool(string $tool): bool
|
||||
'market_management.create_municipality',
|
||||
'market_management.archive_market', 'market_management.reactivate_market',
|
||||
'market_management.create_occurrence', 'market_management.update_occurrence',
|
||||
'market_management.update_occurrence_checklist',
|
||||
'market_management.archive_occurrence', 'market_management.reactivate_occurrence',
|
||||
'market_management.create_day', 'market_management.update_day', 'market_management.delete_day',
|
||||
], true);
|
||||
@@ -303,6 +306,16 @@ function market_management_mcp_call(PDO $pdo, string $tool, array $arguments): a
|
||||
market_management_require_positive_id($arguments['occurrence_id'] ?? null, 'occurrence_id'),
|
||||
(bool) ($arguments['include_archived'] ?? false)
|
||||
),
|
||||
'market_management.get_occurrence_checklist' => market_management_get_occurrence_checklist(
|
||||
$pdo,
|
||||
market_management_require_positive_id($arguments['occurrence_id'] ?? null, 'occurrence_id'),
|
||||
(bool) ($arguments['include_archived'] ?? false)
|
||||
),
|
||||
'market_management.update_occurrence_checklist' => market_management_update_occurrence_checklist(
|
||||
$pdo,
|
||||
market_management_require_positive_id($arguments['occurrence_id'] ?? null, 'occurrence_id'),
|
||||
$arguments
|
||||
),
|
||||
'market_management.update_occurrence' => market_management_mcp_update_occurrence(
|
||||
$pdo,
|
||||
market_management_require_positive_id($arguments['occurrence_id'] ?? null, 'occurrence_id'),
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
const MARKET_OCCURRENCE_CHECKLIST_DEFAULT_ITEMS = 30;
|
||||
|
||||
function market_management_checklist_default_items(): array
|
||||
{
|
||||
$items = [];
|
||||
for ($index = 1; $index <= MARKET_OCCURRENCE_CHECKLIST_DEFAULT_ITEMS; $index++) {
|
||||
$items[] = 'Position ' . $index;
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
function market_management_checklist_assert_occurrence(PDO $pdo, int $occurrenceId, bool $includeArchived = false): void
|
||||
{
|
||||
$predicate = $includeArchived ? 'TRUE' : 'archived_at IS NULL';
|
||||
$stmt = $pdo->prepare('SELECT id FROM market_occurrence WHERE id = :id AND ' . $predicate);
|
||||
$stmt->execute([':id' => $occurrenceId]);
|
||||
if ($stmt->fetchColumn() === false) {
|
||||
throw new InvalidArgumentException('occurrence_id verweist nicht auf eine Marktdurchführung.');
|
||||
}
|
||||
}
|
||||
|
||||
function market_management_checklist_initialize(PDO $pdo, int $occurrenceId): void
|
||||
{
|
||||
market_management_checklist_assert_occurrence($pdo, $occurrenceId, true);
|
||||
$parent = $pdo->prepare(
|
||||
'INSERT INTO market_occurrence_checklist (occurrence_id)
|
||||
VALUES (:occurrence_id)
|
||||
ON CONFLICT (occurrence_id) DO NOTHING'
|
||||
);
|
||||
$parent->execute([':occurrence_id' => $occurrenceId]);
|
||||
|
||||
$existing = $pdo->prepare('SELECT COUNT(*) FROM market_occurrence_checklist_item WHERE occurrence_id = :occurrence_id');
|
||||
$existing->execute([':occurrence_id' => $occurrenceId]);
|
||||
if ((int) $existing->fetchColumn() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = $pdo->prepare(
|
||||
'INSERT INTO market_occurrence_checklist_item
|
||||
(occurrence_id, position, label, is_completed)
|
||||
VALUES (:occurrence_id, :position, :label, :is_completed)'
|
||||
);
|
||||
foreach (market_management_checklist_default_items() as $position => $label) {
|
||||
$item->bindValue(':occurrence_id', $occurrenceId, PDO::PARAM_INT);
|
||||
$item->bindValue(':position', $position + 1, PDO::PARAM_INT);
|
||||
$item->bindValue(':label', $label, PDO::PARAM_STR);
|
||||
$item->bindValue(':is_completed', false, PDO::PARAM_BOOL);
|
||||
$item->execute();
|
||||
}
|
||||
}
|
||||
|
||||
function market_management_get_occurrence_checklist(PDO $pdo, int $occurrenceId, bool $includeArchived = false): array
|
||||
{
|
||||
market_management_checklist_assert_occurrence($pdo, $occurrenceId, $includeArchived);
|
||||
$parent = $pdo->prepare(
|
||||
'SELECT id, occurrence_id, comment, created_at, updated_at
|
||||
FROM market_occurrence_checklist
|
||||
WHERE occurrence_id = :occurrence_id'
|
||||
);
|
||||
$parent->execute([':occurrence_id' => $occurrenceId]);
|
||||
$checklist = $parent->fetch();
|
||||
if (!is_array($checklist)) {
|
||||
throw new RuntimeException('Checkliste der Marktdurchführung fehlt.');
|
||||
}
|
||||
$items = $pdo->prepare(
|
||||
'SELECT id, occurrence_id, position, label, is_completed, created_at, updated_at
|
||||
FROM market_occurrence_checklist_item
|
||||
WHERE occurrence_id = :occurrence_id
|
||||
ORDER BY position ASC, id ASC'
|
||||
);
|
||||
$items->execute([':occurrence_id' => $occurrenceId]);
|
||||
$checklist['items'] = $items->fetchAll();
|
||||
return $checklist;
|
||||
}
|
||||
|
||||
function market_management_update_occurrence_checklist(PDO $pdo, int $occurrenceId, array $input): array
|
||||
{
|
||||
market_management_checklist_assert_occurrence($pdo, $occurrenceId, true);
|
||||
$items = $input['items'] ?? null;
|
||||
if (!is_array($items)) {
|
||||
throw new InvalidArgumentException('items muss eine Liste sein.');
|
||||
}
|
||||
$comment = $input['comment'] ?? null;
|
||||
if ($comment !== null && !is_string($comment)) {
|
||||
throw new InvalidArgumentException('comment muss ein String oder null sein.');
|
||||
}
|
||||
|
||||
$startedTransaction = !$pdo->inTransaction();
|
||||
if ($startedTransaction) {
|
||||
$pdo->beginTransaction();
|
||||
}
|
||||
try {
|
||||
$parent = $pdo->prepare(
|
||||
'INSERT INTO market_occurrence_checklist (occurrence_id, comment)
|
||||
VALUES (:occurrence_id, :comment)
|
||||
ON CONFLICT (occurrence_id) DO UPDATE
|
||||
SET comment = EXCLUDED.comment, updated_at = NOW()'
|
||||
);
|
||||
$parent->execute([':occurrence_id' => $occurrenceId, ':comment' => $comment === null ? null : trim($comment)]);
|
||||
|
||||
$delete = $pdo->prepare('DELETE FROM market_occurrence_checklist_item WHERE occurrence_id = :occurrence_id');
|
||||
$delete->execute([':occurrence_id' => $occurrenceId]);
|
||||
$insert = $pdo->prepare(
|
||||
'INSERT INTO market_occurrence_checklist_item
|
||||
(occurrence_id, position, label, is_completed)
|
||||
VALUES (:occurrence_id, :position, :label, :is_completed)'
|
||||
);
|
||||
foreach (array_values($items) as $position => $item) {
|
||||
if (!is_array($item)) {
|
||||
throw new InvalidArgumentException('Jeder Checklistenpunkt muss ein Objekt sein.');
|
||||
}
|
||||
$label = $item['label'] ?? '';
|
||||
if (!is_string($label)) {
|
||||
throw new InvalidArgumentException('Der Text eines Checklistenpunkts muss ein String sein.');
|
||||
}
|
||||
$completed = $item['is_completed'] ?? false;
|
||||
if (!is_bool($completed)) {
|
||||
throw new InvalidArgumentException('is_completed muss boolean sein.');
|
||||
}
|
||||
$insert->bindValue(':occurrence_id', $occurrenceId, PDO::PARAM_INT);
|
||||
$insert->bindValue(':position', $position + 1, PDO::PARAM_INT);
|
||||
$insert->bindValue(':label', trim($label), PDO::PARAM_STR);
|
||||
$insert->bindValue(':is_completed', $completed, PDO::PARAM_BOOL);
|
||||
$insert->execute();
|
||||
}
|
||||
if ($startedTransaction) {
|
||||
$pdo->commit();
|
||||
}
|
||||
} catch (Throwable $error) {
|
||||
if ($startedTransaction && $pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
throw $error;
|
||||
}
|
||||
return market_management_get_occurrence_checklist($pdo, $occurrenceId, true);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../shared/db.php';
|
||||
require_once __DIR__ . '/occurrence_checklist.php';
|
||||
|
||||
const MARKET_MANAGEMENT_STATUSES = [
|
||||
'open',
|
||||
@@ -956,6 +957,7 @@ function market_management_create_occurrence(PDO $pdo, array $input): array
|
||||
'tax_status' => $taxStatus,
|
||||
'tax_rate' => $taxRate,
|
||||
]);
|
||||
market_management_checklist_initialize($pdo, (int) $occurrence['id']);
|
||||
if ($startedTransaction) {
|
||||
$pdo->commit();
|
||||
}
|
||||
@@ -1132,6 +1134,7 @@ function market_management_get_occurrence(PDO $pdo, int $occurrenceId, bool $inc
|
||||
? null
|
||||
: round((float) $summary['gross_amount'] - (float) $occurrence['paid_amount'], 2),
|
||||
];
|
||||
$occurrence['checklist'] = market_management_get_occurrence_checklist($pdo, $occurrenceId, $includeArchived);
|
||||
return $occurrence;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user