Commit 00f555fb authored by Mahmoud Aglan's avatar Mahmoud Aglan

test

parent a4373d67
...@@ -36,18 +36,25 @@ class PoolGridApiController extends Controller ...@@ -36,18 +36,25 @@ class PoolGridApiController extends Controller
{ {
$body = $request->jsonBody(); $body = $request->jsonBody();
$date = trim((string) ($body['date'] ?? '')); $date = trim((string) ($body['date'] ?? ''));
$startTime = trim((string) ($body['start_time'] ?? ''));
$endTime = trim((string) ($body['end_time'] ?? ''));
$action = trim((string) ($body['action'] ?? '')); $action = trim((string) ($body['action'] ?? ''));
$cells = $body['cells'] ?? []; $cells = $body['cells'] ?? [];
$groupId = !empty($body['group_id']) ? (int) $body['group_id'] : null; $groupId = !empty($body['group_id']) ? (int) $body['group_id'] : null;
$notes = trim((string) ($body['notes'] ?? '')); $notes = trim((string) ($body['notes'] ?? ''));
if (!$date || !$startTime || !$endTime || !$action || empty($cells)) { // Support multi-slot (slots array) or legacy single start_time/end_time
if (!empty($body['slots']) && is_array($body['slots'])) {
$slots = $body['slots'];
} else {
$startTime = trim((string) ($body['start_time'] ?? ''));
$endTime = trim((string) ($body['end_time'] ?? ''));
$slots = [['start_time' => $startTime, 'end_time' => $endTime]];
}
if (!$date || !$action || empty($cells) || empty($slots)) {
return $this->json(['error' => 'بيانات ناقصة'], 400); return $this->json(['error' => 'بيانات ناقصة'], 400);
} }
$result = PoolGridService::bulkAssign((int) $id, $date, $startTime, $endTime, $action, $cells, $groupId, $notes ?: null); $result = PoolGridService::bulkAssign((int) $id, $date, $slots, $action, $cells, $groupId, $notes ?: null);
return $this->json($result, $result['success'] ? 200 : 422); return $this->json($result, $result['success'] ? 200 : 422);
} }
...@@ -56,14 +63,21 @@ class PoolGridApiController extends Controller ...@@ -56,14 +63,21 @@ class PoolGridApiController extends Controller
{ {
$body = $request->jsonBody(); $body = $request->jsonBody();
$date = trim((string) ($body['date'] ?? '')); $date = trim((string) ($body['date'] ?? ''));
$startTime = trim((string) ($body['start_time'] ?? ''));
$cells = $body['cells'] ?? []; $cells = $body['cells'] ?? [];
if (!$date || !$startTime || empty($cells)) { // Support multi-slot or legacy single start_time
if (!empty($body['slots']) && is_array($body['slots'])) {
$slots = $body['slots'];
} else {
$startTime = trim((string) ($body['start_time'] ?? ''));
$slots = [['start_time' => $startTime]];
}
if (!$date || empty($cells) || empty($slots)) {
return $this->json(['error' => 'بيانات ناقصة'], 400); return $this->json(['error' => 'بيانات ناقصة'], 400);
} }
$result = PoolGridService::bulkClear((int) $id, $date, $startTime, $cells); $result = PoolGridService::bulkClear((int) $id, $date, $slots, $cells);
return $this->json($result); return $this->json($result);
} }
...@@ -88,14 +102,21 @@ class PoolGridApiController extends Controller ...@@ -88,14 +102,21 @@ class PoolGridApiController extends Controller
$body = $request->jsonBody(); $body = $request->jsonBody();
$date = trim((string) ($body['date'] ?? '')); $date = trim((string) ($body['date'] ?? ''));
$fromTime = trim((string) ($body['from_time'] ?? '')); $fromTime = trim((string) ($body['from_time'] ?? ''));
// Support multi-target (to_slots array) or legacy single to_time/to_end_time
if (!empty($body['to_slots']) && is_array($body['to_slots'])) {
$toSlots = $body['to_slots'];
} else {
$toTime = trim((string) ($body['to_time'] ?? '')); $toTime = trim((string) ($body['to_time'] ?? ''));
$toEndTime = trim((string) ($body['to_end_time'] ?? '')); $toEndTime = trim((string) ($body['to_end_time'] ?? ''));
$toSlots = [['start' => $toTime, 'end' => $toEndTime]];
}
if (!$date || !$fromTime || !$toTime || !$toEndTime) { if (!$date || !$fromTime || empty($toSlots)) {
return $this->json(['error' => 'بيانات ناقصة'], 400); return $this->json(['error' => 'بيانات ناقصة'], 400);
} }
$result = PoolGridService::copySlot((int) $id, $date, $fromTime, $toTime, $toEndTime); $result = PoolGridService::copySlot((int) $id, $date, $fromTime, $toSlots);
return $this->json($result, $result['success'] ? 200 : 422); return $this->json($result, $result['success'] ? 200 : 422);
} }
......
<?php
declare(strict_types=1);
namespace App\Modules\SportsActivity\Controllers\Api;
use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Modules\SportsActivity\Services\PoolGridTemplateService;
class PoolGridTemplateApiController extends Controller
{
public function list(Request $request, string $id): Response
{
$templates = PoolGridTemplateService::getTemplates((int) $id);
return $this->json(['templates' => $templates]);
}
public function store(Request $request, string $id): Response
{
$body = $request->jsonBody();
$name = trim((string) ($body['name'] ?? ''));
$description = trim((string) ($body['description'] ?? ''));
$color = trim((string) ($body['color'] ?? '#3B82F6'));
$entries = $body['entries'] ?? [];
if (!$name) {
return $this->json(['error' => 'اسم القالب مطلوب'], 400);
}
$result = PoolGridTemplateService::createTemplate((int) $id, $name, $description ?: null, $color, $entries);
return $this->json($result, $result['success'] ? 200 : 422);
}
public function update(Request $request, string $id, string $tid): Response
{
$body = $request->jsonBody();
$name = trim((string) ($body['name'] ?? ''));
$description = trim((string) ($body['description'] ?? ''));
$color = trim((string) ($body['color'] ?? '#3B82F6'));
$entries = $body['entries'] ?? [];
if (!$name) {
return $this->json(['error' => 'اسم القالب مطلوب'], 400);
}
$db = \App\Core\App::getInstance()->db();
$ts = date('Y-m-d H:i:s');
$db->update('sa_pool_zone_templates', [
'name' => $name,
'description' => $description ?: null,
'color' => $color,
'updated_at' => $ts,
], 'id = ?', [(int) $tid]);
// Replace entries
$db->delete('sa_pool_zone_template_entries', 'template_id = ?', [(int) $tid]);
foreach ($entries as $entry) {
$zoneJson = $entry['zone_selection_json'] ?? '{}';
if (is_array($zoneJson)) {
$zoneJson = json_encode($zoneJson, JSON_UNESCAPED_UNICODE);
}
$db->insert('sa_pool_zone_template_entries', [
'template_id' => (int) $tid,
'day_of_week' => (int) ($entry['day_of_week'] ?? 0),
'start_time' => $entry['start_time'] ?? '09:00:00',
'end_time' => $entry['end_time'] ?? '10:00:00',
'zone_selection_type' => $entry['zone_selection_type'] ?? 'all',
'zone_selection_json' => $zoneJson,
'assignment_type' => $entry['assignment_type'] ?? 'training',
'group_id' => !empty($entry['group_id']) ? (int) $entry['group_id'] : null,
'coach_id' => !empty($entry['coach_id']) ? (int) $entry['coach_id'] : null,
'label' => $entry['label'] ?? $name,
'notes' => $entry['notes'] ?? null,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
return $this->json(['success' => true]);
}
public function delete(Request $request, string $id, string $tid): Response
{
$result = PoolGridTemplateService::deleteTemplate((int) $tid);
return $this->json($result, $result['success'] ? 200 : 422);
}
public function expand(Request $request, string $id, string $tid): Response
{
$body = $request->jsonBody();
$fromDate = trim((string) ($body['from_date'] ?? ''));
$toDate = trim((string) ($body['to_date'] ?? ''));
if (!$fromDate || !$toDate) {
return $this->json(['error' => 'التواريخ مطلوبة'], 400);
}
if ($fromDate > $toDate) {
return $this->json(['error' => 'تاريخ البداية يجب أن يكون قبل النهاية'], 400);
}
// Max 60 days to prevent accidental mass generation
$daysDiff = (strtotime($toDate) - strtotime($fromDate)) / 86400;
if ($daysDiff > 60) {
return $this->json(['error' => 'الحد الأقصى 60 يوم للتوسيع'], 400);
}
$result = PoolGridTemplateService::expandTemplate((int) $tid, $fromDate, $toDate);
return $this->json($result, $result['success'] ? 200 : 422);
}
public function rollback(Request $request, string $id, string $tid, string $rid): Response
{
$result = PoolGridTemplateService::rollbackRun((int) $rid);
return $this->json($result, $result['success'] ? 200 : 422);
}
}
...@@ -155,4 +155,12 @@ return [ ...@@ -155,4 +155,12 @@ return [
['POST', '/api/sa/pool-grid/{id:\d+}/clear', 'SportsActivity\Controllers\Api\PoolGridApiController@clear', ['auth', 'csrf'], 'sa.pool-grid.manage'], ['POST', '/api/sa/pool-grid/{id:\d+}/clear', 'SportsActivity\Controllers\Api\PoolGridApiController@clear', ['auth', 'csrf'], 'sa.pool-grid.manage'],
['POST', '/api/sa/pool-grid/{id:\d+}/update-grid', 'SportsActivity\Controllers\Api\PoolGridApiController@updateGrid', ['auth', 'csrf'], 'sa.pool-grid.manage'], ['POST', '/api/sa/pool-grid/{id:\d+}/update-grid', 'SportsActivity\Controllers\Api\PoolGridApiController@updateGrid', ['auth', 'csrf'], 'sa.pool-grid.manage'],
['POST', '/api/sa/pool-grid/{id:\d+}/copy-slot', 'SportsActivity\Controllers\Api\PoolGridApiController@copySlot', ['auth', 'csrf'], 'sa.pool-grid.manage'], ['POST', '/api/sa/pool-grid/{id:\d+}/copy-slot', 'SportsActivity\Controllers\Api\PoolGridApiController@copySlot', ['auth', 'csrf'], 'sa.pool-grid.manage'],
// Pool Grid Templates
['GET', '/api/sa/pool-grid/{id:\d+}/templates', 'SportsActivity\Controllers\Api\PoolGridTemplateApiController@list', ['auth'], 'sa.pool-grid.manage'],
['POST', '/api/sa/pool-grid/{id:\d+}/templates', 'SportsActivity\Controllers\Api\PoolGridTemplateApiController@store', ['auth', 'csrf'], 'sa.pool-grid.manage'],
['POST', '/api/sa/pool-grid/{id:\d+}/templates/{tid:\d+}', 'SportsActivity\Controllers\Api\PoolGridTemplateApiController@update', ['auth', 'csrf'], 'sa.pool-grid.manage'],
['POST', '/api/sa/pool-grid/{id:\d+}/templates/{tid:\d+}/delete', 'SportsActivity\Controllers\Api\PoolGridTemplateApiController@delete', ['auth', 'csrf'], 'sa.pool-grid.manage'],
['POST', '/api/sa/pool-grid/{id:\d+}/templates/{tid:\d+}/expand', 'SportsActivity\Controllers\Api\PoolGridTemplateApiController@expand', ['auth', 'csrf'], 'sa.pool-grid.manage'],
['POST', '/api/sa/pool-grid/{id:\d+}/templates/{tid:\d+}/runs/{rid:\d+}/rollback', 'SportsActivity\Controllers\Api\PoolGridTemplateApiController@rollback', ['auth', 'csrf'], 'sa.pool-grid.manage'],
]; ];
...@@ -104,7 +104,10 @@ final class PoolGridService ...@@ -104,7 +104,10 @@ final class PoolGridService
]; ];
} }
public static function bulkAssign(int $facilityId, string $date, string $startTime, string $endTime, string $action, array $cells, ?int $groupId, ?string $notes): array /**
* Bulk assign cells across one or more time slots.
*/
public static function bulkAssign(int $facilityId, string $date, array $slots, string $action, array $cells, ?int $groupId, ?string $notes, ?int $templateRunId = null): array
{ {
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$ts = date('Y-m-d H:i:s'); $ts = date('Y-m-d H:i:s');
...@@ -127,7 +130,6 @@ final class PoolGridService ...@@ -127,7 +130,6 @@ final class PoolGridService
$maxRows = (int) ($facility['pool_grid_rows'] ?? 0); $maxRows = (int) ($facility['pool_grid_rows'] ?? 0);
$maxCols = (int) ($facility['pool_grid_cols'] ?? 0); $maxCols = (int) ($facility['pool_grid_cols'] ?? 0);
$group = null;
$coachId = null; $coachId = null;
$label = ''; $label = '';
...@@ -149,6 +151,14 @@ final class PoolGridService ...@@ -149,6 +151,14 @@ final class PoolGridService
$assigned = 0; $assigned = 0;
$skipped = 0; $skipped = 0;
foreach ($slots as $slot) {
$startTime = $slot['start_time'] ?? '';
$endTime = $slot['end_time'] ?? '';
if (!$startTime || !$endTime) continue;
$startTimeFull = (strlen($startTime) === 5) ? $startTime . ':00' : $startTime;
$endTimeFull = (strlen($endTime) === 5) ? $endTime . ':00' : $endTime;
foreach ($cells as $cell) { foreach ($cells as $cell) {
$row = (int) ($cell['row'] ?? -1); $row = (int) ($cell['row'] ?? -1);
$col = (int) ($cell['col'] ?? -1); $col = (int) ($cell['col'] ?? -1);
...@@ -162,7 +172,7 @@ final class PoolGridService ...@@ -162,7 +172,7 @@ final class PoolGridService
"SELECT id FROM sa_pool_zone_bookings "SELECT id FROM sa_pool_zone_bookings
WHERE facility_id = ? AND booking_date = ? AND start_time = ? WHERE facility_id = ? AND booking_date = ? AND start_time = ?
AND zone_row = ? AND zone_col = ? AND status = 'active'", AND zone_row = ? AND zone_col = ? AND status = 'active'",
[$facilityId, $date, $startTime . ':00', $row, $col] [$facilityId, $date, $startTimeFull, $row, $col]
); );
if ($conflict) { if ($conflict) {
...@@ -170,11 +180,11 @@ final class PoolGridService ...@@ -170,11 +180,11 @@ final class PoolGridService
continue; continue;
} }
$db->insert('sa_pool_zone_bookings', [ $insertData = [
'facility_id' => $facilityId, 'facility_id' => $facilityId,
'booking_date' => $date, 'booking_date' => $date,
'start_time' => $startTime . ':00', 'start_time' => $startTimeFull,
'end_time' => $endTime . ':00', 'end_time' => $endTimeFull,
'zone_row' => $row, 'zone_row' => $row,
'zone_col' => $col, 'zone_col' => $col,
'assignment_type' => $action, 'assignment_type' => $action,
...@@ -186,20 +196,35 @@ final class PoolGridService ...@@ -186,20 +196,35 @@ final class PoolGridService
'created_by' => $employeeId, 'created_by' => $employeeId,
'created_at' => $ts, 'created_at' => $ts,
'updated_at' => $ts, 'updated_at' => $ts,
]); ];
if ($templateRunId !== null) {
$insertData['template_run_id'] = $templateRunId;
}
$db->insert('sa_pool_zone_bookings', $insertData);
$assigned++; $assigned++;
} }
}
return ['success' => true, 'assigned' => $assigned, 'skipped' => $skipped]; return ['success' => true, 'assigned' => $assigned, 'skipped' => $skipped];
} }
public static function bulkClear(int $facilityId, string $date, string $startTime, array $cells): array /**
* Bulk clear cells across one or more time slots.
*/
public static function bulkClear(int $facilityId, string $date, array $slots, array $cells): array
{ {
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$ts = date('Y-m-d H:i:s'); $ts = date('Y-m-d H:i:s');
$employeeId = (int) (App::getInstance()->session()->get('employee_id') ?? 0); $employeeId = (int) (App::getInstance()->session()->get('employee_id') ?? 0);
$cleared = 0; $cleared = 0;
foreach ($slots as $slot) {
$startTime = $slot['start_time'] ?? '';
if (!$startTime) continue;
$startTimeFull = (strlen($startTime) === 5) ? $startTime . ':00' : $startTime;
foreach ($cells as $cell) { foreach ($cells as $cell) {
$row = (int) ($cell['row'] ?? -1); $row = (int) ($cell['row'] ?? -1);
$col = (int) ($cell['col'] ?? -1); $col = (int) ($cell['col'] ?? -1);
...@@ -210,7 +235,7 @@ final class PoolGridService ...@@ -210,7 +235,7 @@ final class PoolGridService
"SELECT id FROM sa_pool_zone_bookings "SELECT id FROM sa_pool_zone_bookings
WHERE facility_id = ? AND booking_date = ? AND start_time = ? WHERE facility_id = ? AND booking_date = ? AND start_time = ?
AND zone_row = ? AND zone_col = ? AND status = 'active'", AND zone_row = ? AND zone_col = ? AND status = 'active'",
[$facilityId, $date, $startTime . ':00', $row, $col] [$facilityId, $date, $startTimeFull, $row, $col]
); );
if ($existing) { if ($existing) {
...@@ -223,6 +248,7 @@ final class PoolGridService ...@@ -223,6 +248,7 @@ final class PoolGridService
$cleared++; $cleared++;
} }
} }
}
return ['success' => true, 'cleared' => $cleared]; return ['success' => true, 'cleared' => $cleared];
} }
...@@ -244,16 +270,21 @@ final class PoolGridService ...@@ -244,16 +270,21 @@ final class PoolGridService
return ['success' => true]; return ['success' => true];
} }
public static function copySlot(int $facilityId, string $date, string $fromTime, string $toTime, string $toEndTime): array /**
* Copy from one source slot to one or more target slots.
*/
public static function copySlot(int $facilityId, string $date, string $fromTime, array $toSlots): array
{ {
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$ts = date('Y-m-d H:i:s'); $ts = date('Y-m-d H:i:s');
$employeeId = (int) (App::getInstance()->session()->get('employee_id') ?? 0); $employeeId = (int) (App::getInstance()->session()->get('employee_id') ?? 0);
$fromTimeFull = (strlen($fromTime) === 5) ? $fromTime . ':00' : $fromTime;
$source = $db->select( $source = $db->select(
"SELECT * FROM sa_pool_zone_bookings "SELECT * FROM sa_pool_zone_bookings
WHERE facility_id = ? AND booking_date = ? AND start_time = ? AND status = 'active'", WHERE facility_id = ? AND booking_date = ? AND start_time = ? AND status = 'active'",
[$facilityId, $date, $fromTime . ':00'] [$facilityId, $date, $fromTimeFull]
); );
if (empty($source)) { if (empty($source)) {
...@@ -263,12 +294,20 @@ final class PoolGridService ...@@ -263,12 +294,20 @@ final class PoolGridService
$copied = 0; $copied = 0;
$skipped = 0; $skipped = 0;
foreach ($toSlots as $target) {
$toTime = $target['start'] ?? '';
$toEndTime = $target['end'] ?? '';
if (!$toTime || !$toEndTime) continue;
$toTimeFull = (strlen($toTime) === 5) ? $toTime . ':00' : $toTime;
$toEndTimeFull = (strlen($toEndTime) === 5) ? $toEndTime . ':00' : $toEndTime;
foreach ($source as $s) { foreach ($source as $s) {
$conflict = $db->selectOne( $conflict = $db->selectOne(
"SELECT id FROM sa_pool_zone_bookings "SELECT id FROM sa_pool_zone_bookings
WHERE facility_id = ? AND booking_date = ? AND start_time = ? WHERE facility_id = ? AND booking_date = ? AND start_time = ?
AND zone_row = ? AND zone_col = ? AND status = 'active'", AND zone_row = ? AND zone_col = ? AND status = 'active'",
[$facilityId, $date, $toTime . ':00', $s['zone_row'], $s['zone_col']] [$facilityId, $date, $toTimeFull, $s['zone_row'], $s['zone_col']]
); );
if ($conflict) { if ($conflict) {
...@@ -279,8 +318,8 @@ final class PoolGridService ...@@ -279,8 +318,8 @@ final class PoolGridService
$db->insert('sa_pool_zone_bookings', [ $db->insert('sa_pool_zone_bookings', [
'facility_id' => $facilityId, 'facility_id' => $facilityId,
'booking_date' => $date, 'booking_date' => $date,
'start_time' => $toTime . ':00', 'start_time' => $toTimeFull,
'end_time' => $toEndTime . ':00', 'end_time' => $toEndTimeFull,
'zone_row' => $s['zone_row'], 'zone_row' => $s['zone_row'],
'zone_col' => $s['zone_col'], 'zone_col' => $s['zone_col'],
'assignment_type' => $s['assignment_type'], 'assignment_type' => $s['assignment_type'],
...@@ -295,6 +334,7 @@ final class PoolGridService ...@@ -295,6 +334,7 @@ final class PoolGridService
]); ]);
$copied++; $copied++;
} }
}
return ['success' => true, 'copied' => $copied, 'skipped' => $skipped]; return ['success' => true, 'copied' => $copied, 'skipped' => $skipped];
} }
......
<?php
declare(strict_types=1);
return [
'up' => "CREATE TABLE `sa_pool_zone_templates` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`facility_id` BIGINT UNSIGNED NOT NULL,
`name` VARCHAR(200) NOT NULL,
`description` TEXT NULL,
`color` VARCHAR(20) NULL DEFAULT '#3B82F6',
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
`created_by` BIGINT UNSIGNED NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_sa_pzt_facility` (`facility_id`, `is_active`),
CONSTRAINT `fk_sa_pzt_facility` FOREIGN KEY (`facility_id`) REFERENCES `sa_facilities`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
'down' => "DROP TABLE IF EXISTS `sa_pool_zone_templates`;",
];
<?php
declare(strict_types=1);
return [
'up' => "CREATE TABLE `sa_pool_zone_template_entries` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`template_id` BIGINT UNSIGNED NOT NULL,
`day_of_week` TINYINT UNSIGNED NOT NULL COMMENT '0=Sunday...6=Saturday',
`start_time` TIME NOT NULL,
`end_time` TIME NOT NULL,
`zone_selection_type` VARCHAR(20) NOT NULL COMMENT 'cells, row, column, all',
`zone_selection_json` JSON NOT NULL,
`assignment_type` VARCHAR(20) NOT NULL COMMENT 'training, blocked, maintenance, hourly',
`group_id` BIGINT UNSIGNED NULL,
`coach_id` BIGINT UNSIGNED NULL,
`label` VARCHAR(200) NULL,
`notes` TEXT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_sa_pzte_template` (`template_id`),
INDEX `idx_sa_pzte_day` (`day_of_week`, `start_time`),
CONSTRAINT `fk_sa_pzte_template` FOREIGN KEY (`template_id`) REFERENCES `sa_pool_zone_templates`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_sa_pzte_group` FOREIGN KEY (`group_id`) REFERENCES `sa_groups`(`id`) ON DELETE SET NULL,
CONSTRAINT `fk_sa_pzte_coach` FOREIGN KEY (`coach_id`) REFERENCES `sa_coaches`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
'down' => "DROP TABLE IF EXISTS `sa_pool_zone_template_entries`;",
];
<?php
declare(strict_types=1);
return [
'up' => "CREATE TABLE `sa_pool_zone_template_runs` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`template_id` BIGINT UNSIGNED NOT NULL,
`date_from` DATE NOT NULL,
`date_to` DATE NOT NULL,
`generated_count` INT UNSIGNED NOT NULL DEFAULT 0,
`skipped_count` INT UNSIGNED NOT NULL DEFAULT 0,
`status` VARCHAR(20) NOT NULL DEFAULT 'completed' COMMENT 'completed, rolled_back',
`rolled_back_at` TIMESTAMP NULL,
`rolled_back_by` BIGINT UNSIGNED NULL,
`created_by` BIGINT UNSIGNED NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_sa_pztr_template` (`template_id`),
CONSTRAINT `fk_sa_pztr_template` FOREIGN KEY (`template_id`) REFERENCES `sa_pool_zone_templates`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
'down' => "DROP TABLE IF EXISTS `sa_pool_zone_template_runs`;",
];
<?php
declare(strict_types=1);
return [
'up' => "ALTER TABLE `sa_pool_zone_bookings`
ADD COLUMN `template_run_id` BIGINT UNSIGNED NULL AFTER `notes`,
ADD INDEX `idx_sa_pzb_run` (`template_run_id`);",
'down' => "ALTER TABLE `sa_pool_zone_bookings`
DROP INDEX `idx_sa_pzb_run`,
DROP COLUMN `template_run_id`;",
];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment