Kostenarten und geschützte Standkosten umsetzen
This commit is contained in:
1 parent
313475afec
commit
3a0cb81a97
7 files changed
+200
-17
No files matched your search
@@ -89,6 +89,60 @@ function market_management_create_municipality(PDO $pdo, string $name): array
|
||||
return (array) $stmt->fetch();
|
||||
}
|
||||
|
||||
function market_management_list_cost_types(PDO $pdo): array
|
||||
{
|
||||
return $pdo->query(
|
||||
'SELECT id, code, name, is_system, is_active
|
||||
FROM market_cost_type
|
||||
WHERE is_active = TRUE
|
||||
ORDER BY is_system DESC, name ASC, id ASC'
|
||||
)->fetchAll() ?: [];
|
||||
}
|
||||
|
||||
function market_management_get_cost_type(PDO $pdo, int $costTypeId): ?array
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT id, code, name, is_system, is_active
|
||||
FROM market_cost_type WHERE id = :id AND is_active = TRUE'
|
||||
);
|
||||
$stmt->execute([':id' => $costTypeId]);
|
||||
$type = $stmt->fetch();
|
||||
return is_array($type) ? $type : null;
|
||||
}
|
||||
|
||||
function market_management_get_cost_type_id(PDO $pdo, string $code): int
|
||||
{
|
||||
$stmt = $pdo->prepare('SELECT id FROM market_cost_type WHERE code = :code AND is_active = TRUE');
|
||||
$stmt->execute([':code' => $code]);
|
||||
$id = $stmt->fetchColumn();
|
||||
if ($id === false) {
|
||||
throw new RuntimeException('Standard-Kostenart fehlt.');
|
||||
}
|
||||
return (int) $id;
|
||||
}
|
||||
|
||||
function market_management_create_cost_type(PDO $pdo, string $name, ?string $code = null): array
|
||||
{
|
||||
$name = trim($name);
|
||||
$code = trim((string) ($code ?? ''));
|
||||
if ($name === '') {
|
||||
throw new InvalidArgumentException('Kostenartenname fehlt.');
|
||||
}
|
||||
if ($code === '') {
|
||||
$code = strtolower(trim((string) preg_replace('/[^a-z0-9]+/i', '_', $name), '_'));
|
||||
}
|
||||
if ($code === '') {
|
||||
throw new InvalidArgumentException('Code der Kostenart fehlt.');
|
||||
}
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO market_cost_type (code, name)
|
||||
VALUES (:code, :name)
|
||||
RETURNING id, code, name, is_system, is_active'
|
||||
);
|
||||
$stmt->execute([':code' => $code, ':name' => $name]);
|
||||
return (array) $stmt->fetch();
|
||||
}
|
||||
|
||||
function market_management_require_positive_id(mixed $value, string $field): int
|
||||
{
|
||||
if (!is_int($value) && !ctype_digit((string) $value)) {
|
||||
@@ -724,6 +778,13 @@ function market_management_create_occurrence(PDO $pdo, array $input): array
|
||||
'contact_email' => null,
|
||||
'contact_phone' => null,
|
||||
]);
|
||||
market_management_create_cost_item($pdo, [
|
||||
'occurrence_id' => (int) $occurrence['id'],
|
||||
'cost_type_id' => market_management_get_cost_type_id($pdo, 'stand_fee'),
|
||||
'gross_amount' => 0,
|
||||
'tax_status' => 'taxable',
|
||||
'tax_rate' => 8.10,
|
||||
]);
|
||||
if ($startedTransaction) {
|
||||
$pdo->commit();
|
||||
}
|
||||
@@ -865,8 +926,14 @@ function market_management_get_occurrence(PDO $pdo, int $occurrenceId, bool $inc
|
||||
'last_name' => '',
|
||||
'party_name' => '',
|
||||
]],
|
||||
'cost_types' => market_management_list_cost_types($pdo),
|
||||
];
|
||||
$costs = $pdo->prepare('SELECT * FROM market_occurrence_cost_item WHERE occurrence_id = :occurrence_id ORDER BY id ASC');
|
||||
$costs = $pdo->prepare(
|
||||
'SELECT item.*, type.code AS cost_type_code, type.name AS cost_type
|
||||
FROM market_occurrence_cost_item item
|
||||
INNER JOIN market_cost_type type ON type.id = item.cost_type_id
|
||||
WHERE item.occurrence_id = :occurrence_id ORDER BY item.id ASC'
|
||||
);
|
||||
$costs->execute([':occurrence_id' => $occurrenceId]);
|
||||
$occurrence['cost_items'] = $costs->fetchAll();
|
||||
$costSummary = $pdo->prepare(
|
||||
@@ -1195,35 +1262,51 @@ function market_management_set_occurrence_contact(PDO $pdo, array $input): array
|
||||
function market_management_create_cost_item(PDO $pdo, array $input): array
|
||||
{
|
||||
$occurrenceId = market_management_require_positive_id($input['occurrence_id'] ?? null, 'occurrence_id');
|
||||
$costType = trim((string) ($input['cost_type'] ?? ''));
|
||||
$costTypeId = market_management_require_positive_id($input['cost_type_id'] ?? null, 'cost_type_id');
|
||||
$grossAmount = market_management_optional_number($input, 'gross_amount');
|
||||
$taxStatus = trim((string) ($input['tax_status'] ?? ''));
|
||||
$taxRate = market_management_optional_number($input, 'tax_rate') ?? '0.00';
|
||||
if ($costType === '' || $grossAmount === null || !in_array($taxStatus, ['tax_free', 'taxable'], true)) {
|
||||
throw new InvalidArgumentException('cost_type, gross_amount und tax_status sind erforderlich.');
|
||||
if ($grossAmount === null || !in_array($taxStatus, ['tax_free', 'taxable'], true)) {
|
||||
throw new InvalidArgumentException('cost_type_id, gross_amount und tax_status sind erforderlich.');
|
||||
}
|
||||
if (($taxStatus === 'tax_free' && $taxRate !== '0.00') || ($taxStatus === 'taxable' && (float) $taxRate <= 0)) {
|
||||
throw new InvalidArgumentException('tax_rate passt nicht zu tax_status.');
|
||||
}
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO market_occurrence_cost_item
|
||||
(occurrence_id, cost_type, description, gross_amount, tax_status, tax_rate)
|
||||
VALUES (:occurrence_id, :cost_type, :description, :gross_amount, :tax_status, :tax_rate)
|
||||
(occurrence_id, cost_type_id, description, gross_amount, tax_status, tax_rate)
|
||||
VALUES (:occurrence_id, :cost_type_id, :description, :gross_amount, :tax_status, :tax_rate)
|
||||
RETURNING *'
|
||||
);
|
||||
if (market_management_get_cost_type($pdo, $costTypeId) === null) {
|
||||
throw new InvalidArgumentException('Kostenart nicht gefunden oder inaktiv.');
|
||||
}
|
||||
$stmt->execute([
|
||||
':occurrence_id' => $occurrenceId,
|
||||
':cost_type' => $costType,
|
||||
':cost_type_id' => $costTypeId,
|
||||
':description' => market_management_optional_string($input, 'description'),
|
||||
':gross_amount' => $grossAmount,
|
||||
':tax_status' => $taxStatus,
|
||||
':tax_rate' => $taxRate,
|
||||
]);
|
||||
return (array) $stmt->fetch();
|
||||
$item = (array) $stmt->fetch();
|
||||
$item['cost_type'] = market_management_get_cost_type($pdo, $costTypeId)['name'];
|
||||
return $item;
|
||||
}
|
||||
|
||||
function market_management_delete_cost_item(PDO $pdo, int $costItemId): array
|
||||
{
|
||||
$stmt = $pdo->prepare('SELECT id, occurrence_id FROM market_occurrence_cost_item WHERE id = :id');
|
||||
$stmt->execute([':id' => $costItemId]);
|
||||
$item = $stmt->fetch();
|
||||
if (!is_array($item)) {
|
||||
throw new RuntimeException('Kostenposition nicht gefunden.');
|
||||
}
|
||||
$first = $pdo->prepare('SELECT MIN(id) FROM market_occurrence_cost_item WHERE occurrence_id = :occurrence_id');
|
||||
$first->execute([':occurrence_id' => $item['occurrence_id']]);
|
||||
if ((int) $first->fetchColumn() === $costItemId) {
|
||||
throw new InvalidArgumentException('Die erste Standkostenposition darf nicht gelöscht werden.');
|
||||
}
|
||||
$stmt = $pdo->prepare('DELETE FROM market_occurrence_cost_item WHERE id = :id RETURNING id, occurrence_id');
|
||||
$stmt->execute([':id' => $costItemId]);
|
||||
$item = $stmt->fetch();
|
||||
@@ -1237,13 +1320,13 @@ function market_management_update_cost_item(PDO $pdo, int $costItemId, array $in
|
||||
{
|
||||
$sets = [];
|
||||
$params = [':id' => $costItemId];
|
||||
if (array_key_exists('cost_type', $input)) {
|
||||
$costType = trim((string) $input['cost_type']);
|
||||
if ($costType === '') {
|
||||
throw new InvalidArgumentException('cost_type darf nicht leer sein.');
|
||||
if (array_key_exists('cost_type_id', $input)) {
|
||||
$costTypeId = market_management_require_positive_id($input['cost_type_id'], 'cost_type_id');
|
||||
if (market_management_get_cost_type($pdo, $costTypeId) === null) {
|
||||
throw new InvalidArgumentException('Kostenart nicht gefunden oder inaktiv.');
|
||||
}
|
||||
$sets[] = 'cost_type = :cost_type';
|
||||
$params[':cost_type'] = $costType;
|
||||
$sets[] = 'cost_type_id = :cost_type_id';
|
||||
$params[':cost_type_id'] = $costTypeId;
|
||||
}
|
||||
foreach (['description' => 'string', 'gross_amount' => 'number', 'tax_status' => 'string', 'tax_rate' => 'number'] as $field => $type) {
|
||||
if (!array_key_exists($field, $input)) {
|
||||
@@ -1269,5 +1352,6 @@ function market_management_update_cost_item(PDO $pdo, int $costItemId, array $in
|
||||
if (!is_array($item)) {
|
||||
throw new RuntimeException('Kostenposition nicht gefunden.');
|
||||
}
|
||||
$item['cost_type'] = market_management_get_cost_type($pdo, (int) $item['cost_type_id'])['name'];
|
||||
return $item;
|
||||
}
|
||||
Reference in new issue
Block a user