Commit 166011ba authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix(manager): event cancel, the club calendar feed, dead routes

- Cancelling a club event posted to a missing action; it now marks the event
  cancelled (migration 007 adds org_events.status, which the list already
  showed) and the calendar feed leaves cancelled events out.
- The calendar feed read the wrong path parameter and set its start bound
  twice, so it returned nothing for the club; it now returns the club's
  events inside the asked range.
- Treasury settings had no view and nothing read its settings: routes and
  actions removed. The branding colour and asset routes left behind when the
  game's look was locked are removed too.
Co-Authored-By: 's avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 03d7eec4
...@@ -281,8 +281,6 @@ return [ ...@@ -281,8 +281,6 @@ return [
// Branding // Branding
'branding' => ['module' => 'branding', 'action' => 'index'], 'branding' => ['module' => 'branding', 'action' => 'index'],
'branding/colors' => ['module' => 'branding', 'action' => 'colors'],
'branding/assets' => ['module' => 'branding', 'action' => 'assets'],
'branding/update-color' => ['module' => 'branding', 'action' => 'updateColor'], 'branding/update-color' => ['module' => 'branding', 'action' => 'updateColor'],
'branding/reset-colors' => ['module' => 'branding', 'action' => 'resetColors'], 'branding/reset-colors' => ['module' => 'branding', 'action' => 'resetColors'],
...@@ -388,8 +386,6 @@ return [ ...@@ -388,8 +386,6 @@ return [
'organizations/{id}/treasury/transactions' => ['module' => 'org-treasury', 'action' => 'transactions'], 'organizations/{id}/treasury/transactions' => ['module' => 'org-treasury', 'action' => 'transactions'],
'organizations/{id}/treasury/deposit' => ['module' => 'org-treasury', 'action' => 'deposit'], 'organizations/{id}/treasury/deposit' => ['module' => 'org-treasury', 'action' => 'deposit'],
'organizations/{id}/treasury/withdraw' => ['module' => 'org-treasury', 'action' => 'withdraw'], 'organizations/{id}/treasury/withdraw' => ['module' => 'org-treasury', 'action' => 'withdraw'],
'organizations/{id}/treasury/settings' => ['module' => 'org-treasury', 'action' => 'settings'],
'organizations/{id}/treasury/settings/update' => ['module' => 'org-treasury', 'action' => 'updateSettings'],
// Org Challenges // Org Challenges
'org-challenges' => ['module' => 'org-challenges', 'action' => 'list'], 'org-challenges' => ['module' => 'org-challenges', 'action' => 'list'],
......
-- Club events can be cancelled without being deleted: the events list has a
-- "cancel" action and shows a status badge, but the table had no status.
ALTER TABLE public.org_events
ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'scheduled';
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'org_events_status_check' AND conrelid = 'public.org_events'::regclass) THEN
ALTER TABLE public.org_events ADD CONSTRAINT org_events_status_check
CHECK (status IN ('scheduled', 'active', 'cancelled', 'completed'));
END IF;
END $$;
...@@ -177,6 +177,32 @@ class OrgEventsController ...@@ -177,6 +177,32 @@ class OrgEventsController
Response::success('تم تحديث الفعالية', "/organizations/{$orgId}/events"); Response::success('تم تحديث الفعالية', "/organizations/{$orgId}/events");
} }
public function cancel(array $params, string $method): void
{
Auth::requireCsrf();
$orgId = $params['id'];
$eventId = $params['eventId'];
$event = $this->db->selectOne('org_events', [
'id' => "eq.{$eventId}",
'org_id' => "eq.{$orgId}",
]);
if (!$event) {
Response::error('الفعالية غير موجودة', "/organizations/{$orgId}/events");
return;
}
$this->db->update('org_events', ['id' => "eq.{$eventId}"], [
'status' => 'cancelled',
'updated_at' => date('c'),
]);
AuditLog::log('cancel', 'org_event', $eventId, $event, ['status' => 'cancelled']);
Response::success('تم إلغاء الفعالية', "/organizations/{$orgId}/events");
}
public function delete(array $params, string $method): void public function delete(array $params, string $method): void
{ {
Auth::requireCsrf(); Auth::requireCsrf();
...@@ -233,15 +259,16 @@ class OrgEventsController ...@@ -233,15 +259,16 @@ class OrgEventsController
public function apiCalendar(array $params, string $method): void public function apiCalendar(array $params, string $method): void
{ {
$orgId = $params['id']; // The route is api/org-events/{orgId}/calendar.
$orgId = $params['orgId'] ?? $params['id'] ?? '';
$start = $_GET['start'] ?? date('Y-m-01T00:00:00'); $start = $_GET['start'] ?? date('Y-m-01T00:00:00');
$end = $_GET['end'] ?? date('Y-m-t') . 'T23:59:59'; $end = $_GET['end'] ?? date('Y-m-t') . 'T23:59:59';
$events = $this->db->select('org_events', [ $events = $this->db->select('org_events', [
'select' => 'id,title,title_ar,starts_at,ends_at,event_type,is_online,location', 'select' => 'id,title,title_ar,starts_at,ends_at,event_type,is_online,location',
'org_id' => "eq.{$orgId}", 'org_id' => "eq.{$orgId}",
'starts_at' => "gte.{$start}", 'status' => 'neq.cancelled',
'starts_at' => "lte.{$end}", 'and' => "(starts_at.gte.{$start},starts_at.lte.{$end})",
'order' => 'starts_at.asc', 'order' => 'starts_at.asc',
]); ]);
......
...@@ -214,43 +214,4 @@ class OrgTreasuryController ...@@ -214,43 +214,4 @@ class OrgTreasuryController
]); ]);
Response::success("تم سحب {$amount} {$currency}", "/organizations/{$orgId}/treasury"); Response::success("تم سحب {$amount} {$currency}", "/organizations/{$orgId}/treasury");
} }
public function settings(array $params, string $method): void
{
$orgId = $params['id'];
$org = $this->db->selectOne('el3ab_organizations', ['id' => "eq.{$orgId}"]);
if (!$org) {
Response::error('المنظمة غير موجودة', '/organizations');
return;
}
$treasury = $this->db->selectOne('org_treasury', ['org_id' => "eq.{$orgId}"]);
$settings = json_decode($treasury['settings'] ?? '{}', true);
$pageTitle = "إعدادات الخزينة - {$org['name']}";
$moduleCSS = 'org-treasury';
View::render('org-treasury/settings', compact('org', 'treasury', 'settings', 'pageTitle', 'moduleCSS'));
}
public function updateSettings(array $params, string $method): void
{
Auth::requireCsrf();
$orgId = $params['id'];
$settings = [
'auto_collect_rate' => (float)($_POST['auto_collect_rate'] ?? 0),
'max_deposit_per_day' => (int)($_POST['max_deposit_per_day'] ?? 0),
'withdrawal_approval_required' => isset($_POST['withdrawal_approval_required']),
'min_withdrawal_amount' => (int)($_POST['min_withdrawal_amount'] ?? 0),
];
$this->db->update('org_treasury', ['org_id' => "eq.{$orgId}"], [
'settings' => json_encode($settings),
'updated_at' => date('c'),
]);
AuditLog::log('update_treasury_settings', 'org_treasury', $orgId, null, $settings);
Response::success('تم تحديث إعدادات الخزينة', "/organizations/{$orgId}/treasury/settings");
}
} }
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