apiKey = config('trello.api_key'); $this->apiToken = config('trello.api_token'); $this->boardId = config('trello.board_id'); } /** * Create a new card on the board */ public function createCard(string $orderId, string $orderNumber, string $orderType = 'standard', ?string $startingListId = null): ?string { if (! $this->isConfigured()) { Log::warning('Trello not configured, skipping card creation', [ 'order_id' => $orderId, 'api_key' => $this->apiKey ? 'set' : 'empty', 'api_token' => $this->apiToken ? 'set' : 'empty', 'board_id' => $this->boardId ? 'set' : 'empty', ]); return null; } try { $listId = $startingListId ?? $this->getStartingListId($orderType); $response = Http::post("{$this->baseUrl}/cards", [ 'name' => "Order #{$orderNumber}", 'desc' => "Order ID: {$orderId}\nType: {$orderType}", 'idList' => $listId, 'key' => $this->apiKey, 'token' => $this->apiToken, ]); if ($response->successful()) { $data = $response->json(); return $data['id'] ?? null; } Log::error('Failed to create Trello card', ['response' => $response->body()]); return null; } catch (\Exception $e) { Log::error('Exception creating Trello card', ['error' => $e->getMessage()]); return null; } } /** * Move a card to a different list */ public function moveCard(string $cardId, string $listName): bool { if (! $this->isConfigured()) { return false; } try { $listId = $this->getListIdByName($listName); if (! $listId) { Log::warning('Trello list not found', ['list_name' => $listName]); return false; } $response = Http::put("{$this->baseUrl}/cards/{$cardId}", [ 'idList' => $listId, 'key' => $this->apiKey, 'token' => $this->apiToken, ]); return $response->successful(); } catch (\Exception $e) { Log::error('Exception moving Trello card', [ 'card_id' => $cardId, 'error' => $e->getMessage(), ]); return false; } } /** * Attach a file or URL to a card */ public function attachFile(string $cardId, string $fileName, string $fileUrl): bool { if (! $this->isConfigured()) { return false; } try { $response = Http::post("{$this->baseUrl}/cards/{$cardId}/attachments", [ 'name' => $fileName, 'url' => $fileUrl, 'key' => $this->apiKey, 'token' => $this->apiToken, ]); return $response->successful(); } catch (\Exception $e) { Log::error('Exception attaching file to Trello card', [ 'card_id' => $cardId, 'error' => $e->getMessage(), ]); return false; } } /** * Check/tick a checklist item on a card */ public function checkItem(string $cardId, string $checklistName, string $itemName): bool { if (! $this->isConfigured()) { return false; } try { // Fetch card to find checklist $cardResponse = Http::get("{$this->baseUrl}/cards/{$cardId}", [ 'key' => $this->apiKey, 'token' => $this->apiToken, 'checklists' => 'open', ]); if (! $cardResponse->successful()) { return false; } $checklists = $cardResponse->json('checklists') ?? []; $checklist = collect($checklists)->firstWhere('name', $checklistName); if (! $checklist) { Log::warning('Trello checklist not found', ['checklist_name' => $checklistName]); return false; } $checklistId = $checklist['id']; $item = collect($checklist['checkItems'])->firstWhere('name', $itemName); if (! $item) { Log::warning('Trello checklist item not found', ['item_name' => $itemName]); return false; } $response = Http::put("{$this->baseUrl}/checklists/{$checklistId}/checkItems/{$item['id']}", [ 'state' => 'complete', 'key' => $this->apiKey, 'token' => $this->apiToken, ]); return $response->successful(); } catch (\Exception $e) { Log::error('Exception checking Trello item', [ 'card_id' => $cardId, 'error' => $e->getMessage(), ]); return false; } } /** * Get starting list ID for order type */ protected function getStartingListId(string $orderType): string { if ($orderType === 'custom') { return config('trello.lists.custom.new_custom_order'); } return config('trello.lists.standard.new_order'); } /** * Get list ID by name (from config) */ protected function getListIdByName(string $listName): ?string { $lists = array_merge( config('trello.lists.standard', []), config('trello.lists.custom', []) ); foreach ($lists as $key => $id) { if (str_replace('_', ' ', ucfirst($key)) === $listName) { return $id; } } return null; } /** * Check if Trello is configured */ protected function isConfigured(): bool { return ! empty($this->apiKey) && ! empty($this->apiToken) && ! empty($this->boardId); } }