leadModel = new SalesActualLeadModel(); $this->contactModel = new SalesContactPersonModel(); $this->activityModel = new SalesActivityModel(); $this->noteModel = new SalesLeadNoteModel(); } // ==================== LEAD APIs ==================== /** * Get all leads with pagination and filters * GET /api/sales/leads */ public function getLeads() { try { $limit = $this->request->getGet('limit') ?? 10; $offset = $this->request->getGet('offset') ?? 0; $filters = [ 'status' => $this->request->getGet('status'), 'assigned_to' => $this->request->getGet('assigned_to'), 'search' => $this->request->getGet('search'), ]; $result = $this->leadModel->getLeadsWithFilters($filters, $limit, $offset); return $this->respond([ 'status' => 'success', 'data' => $result['data'], 'total' => $result['total'], 'limit' => $limit, 'offset' => $offset ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Get single lead with complete details * GET /api/sales/leads/{id} */ public function getLead($id) { try { $lead = $this->leadModel->getLeadComplete($id); if (!$lead) { return $this->failNotFound('Lead not found'); } return $this->respond([ 'status' => 'success', 'data' => $lead ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Create new lead * POST /api/sales/leads */ public function createLead() { try { $data = $this->request->getJSON(true); // Set created_by and updated_by from authenticated user $data['created_by'] = $this->getUserId(); $data['updated_by'] = $this->getUserId(); if (!$this->leadModel->insert($data)) { return $this->fail($this->leadModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $leadId = $this->leadModel->getInsertID(); // Insert contact persons if provided if (!empty($data['contact_persons'])) { foreach ($data['contact_persons'] as $contact) { $contact['lead_id'] = $leadId; $contact['created_by'] = $this->getUserId(); $this->contactModel->insert($contact); } } $lead = $this->leadModel->getLeadComplete($leadId); return $this->respondCreated([ 'status' => 'success', 'message' => 'Lead created successfully', 'data' => $lead ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Update lead * PUT /api/sales/leads/{id} */ public function updateLead($id) { try { if (!$this->leadModel->find((int)$id)) { return $this->failNotFound('Lead not found'); } $data = $this->request->getJSON(true); $data['updated_by'] = $this->getUserId(); if (!$this->leadModel->update($id, $data)) { return $this->fail($this->leadModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $lead = $this->leadModel->getLeadComplete($id); return $this->respond([ 'status' => 'success', 'message' => 'Lead updated successfully', 'data' => $lead ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Delete lead * DELETE /api/sales/leads/{id} */ public function deleteLead($id) { try { if (!$this->leadModel->find((int)$id)) { return $this->failNotFound('Lead not found'); } $this->leadModel->delete($id); return $this->respondDeleted([ 'status' => 'success', 'message' => 'Lead deleted successfully' ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Get lead statistics * GET /api/sales/leads/stats */ public function getLeadStats() { try { $userId = $this->request->getGet('user_id'); $stats = $this->leadModel->getLeadStats($userId); return $this->respond([ 'status' => 'success', 'data' => $stats ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } // ==================== CONTACT PERSON APIs ==================== /** * Get contacts for a lead * GET /api/sales/leads/{leadId}/contacts */ public function getContacts($leadId) { try { $contacts = $this->contactModel->getContactsByLead($leadId); return $this->respond([ 'status' => 'success', 'data' => $contacts ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Create contact person * POST /api/sales/contacts */ public function createContact() { try { $data = $this->request->getJSON(true); $data['created_by'] = $this->getUserId(); $data['updated_by'] = $this->getUserId(); if (!$this->contactModel->insert($data)) { return $this->fail($this->contactModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $contactId = $this->contactModel->getInsertID(); $contact = $this->contactModel->find((int)$contactId); return $this->respondCreated([ 'status' => 'success', 'message' => 'Contact created successfully', 'data' => $contact ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Update contact person * PUT /api/sales/contacts/{id} */ public function updateContact($id) { try { if (!$this->contactModel->find((int)$id)) { return $this->failNotFound('Contact not found'); } $data = $this->request->getJSON(true); $data['updated_by'] = $this->getUserId(); if (!$this->contactModel->update((int)$id, $data)) { return $this->fail($this->contactModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $contact = $this->contactModel->find((int)$id); return $this->respond([ 'status' => 'success', 'message' => 'Contact updated successfully', 'data' => $contact ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Delete contact person * DELETE /api/sales/contacts/{id} */ public function deleteContact($id) { try { if (!$this->contactModel->find((int)$id)) { return $this->failNotFound('Contact not found'); } $this->contactModel->delete((int)$id); return $this->respondDeleted([ 'status' => 'success', 'message' => 'Contact deleted successfully' ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Set primary contact * PUT /api/sales/contacts/{id}/set-primary */ public function setPrimaryContact($id) { try { $contact = $this->contactModel->find((int)$id); if (!$contact) { return $this->failNotFound('Contact not found'); } $this->contactModel->setPrimaryContact($id, $contact['lead_id']); return $this->respond([ 'status' => 'success', 'message' => 'Primary contact updated successfully' ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } // ==================== ACTIVITY APIs ==================== /** * Get all activities with filters * GET /api/sales/activities */ public function getActivities() { try { $limit = $this->request->getGet('limit') ?? 10; $offset = $this->request->getGet('offset') ?? 0; $filters = [ 'status' => $this->request->getGet('status'), 'activity_type' => $this->request->getGet('activity_type'), 'assigned_to' => $this->request->getGet('assigned_to'), 'date_from' => $this->request->getGet('date_from'), 'date_to' => $this->request->getGet('date_to'), ]; $result = $this->activityModel->getActivitiesWithFilters($filters, $limit, $offset); return $this->respond([ 'status' => 'success', 'data' => $result['data'], 'total' => $result['total'], 'limit' => $limit, 'offset' => $offset ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Get activities for a specific lead * GET /api/sales/leads/{leadId}/activities */ public function getLeadActivities($leadId) { try { $status = $this->request->getGet('status'); $activities = $this->activityModel->getActivitiesByLead($leadId, $status); return $this->respond([ 'status' => 'success', 'data' => $activities ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Get activity timeline for a lead * GET /api/sales/leads/{leadId}/timeline */ public function getActivityTimeline($leadId) { try { $timeline = $this->activityModel->getActivityTimeline($leadId); return $this->respond([ 'status' => 'success', 'data' => $timeline ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Get upcoming activities for user * GET /api/sales/activities/upcoming */ public function getUpcomingActivities() { try { $userId = $this->getUserId(); $days = $this->request->getGet('days') ?? 7; $limit = $this->request->getGet('limit') ?? 10; $activities = $this->activityModel->getUpcomingActivities($userId, $days, $limit); return $this->respond([ 'status' => 'success', 'data' => $activities ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Create activity * POST /api/sales/activities */ public function createActivity() { try { $data = $this->request->getJSON(true); $data['created_by'] = $this->getUserId(); $data['updated_by'] = $this->getUserId(); if (!$this->activityModel->insert($data)) { return $this->fail($this->activityModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $activityId = $this->activityModel->getInsertID(); $activity = $this->activityModel->find((int)$activityId); return $this->respondCreated([ 'status' => 'success', 'message' => 'Activity created successfully', 'data' => $activity ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Update activity * PUT /api/sales/activities/{id} */ public function updateActivity($id) { try { if (!$this->activityModel->find((int)$id)) { return $this->failNotFound('Activity not found'); } $data = $this->request->getJSON(true); $data['updated_by'] = $this->getUserId(); if (!$this->activityModel->update($id, $data)) { return $this->fail($this->activityModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $activity = $this->activityModel->find((int)$id); return $this->respond([ 'status' => 'success', 'message' => 'Activity updated successfully', 'data' => $activity ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Complete activity * POST /api/sales/activities/{id}/complete */ public function completeActivity($id) { try { $activity = $this->activityModel->find((int)$id); if (!$activity) { return $this->failNotFound('Activity not found'); } if ($activity['status'] === 'completed') { return $this->fail('Activity is already completed', ResponseInterface::HTTP_BAD_REQUEST); } $data = $this->request->getJSON(true); $data['updated_by'] = $this->getUserId(); $this->activityModel->completeActivity((int)$id, $data); // Create follow-up activity if requested if (!empty($data['create_followup']) && $data['create_followup'] === true) { $followupData = [ 'lead_id' => $activity['lead_id'], 'activity_type' => $data['followup_type'] ?? 'Call', 'notes' => $data['followup_notes'] ?? '', 'scheduled_date' => $data['followup_date'] ?? null, 'assigned_to' => $activity['assigned_to'], 'parent_activity_id' => $id, 'created_by' => $this->getUserId(), 'updated_by' => $this->getUserId(), ]; $this->activityModel->insert($followupData); } $updatedActivity = $this->activityModel->find((int)$id); return $this->respond([ 'status' => 'success', 'message' => 'Activity completed successfully', 'data' => $updatedActivity ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Delete activity * DELETE /api/sales/activities/{id} */ public function deleteActivity($id) { try { if (!$this->activityModel->find((int)$id)) { return $this->failNotFound('Activity not found'); } $this->activityModel->delete((int)$id); return $this->respondDeleted([ 'status' => 'success', 'message' => 'Activity deleted successfully' ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Get pending activities count * GET /api/sales/activities/pending-count */ public function getPendingCount() { try { $userId = $this->getUserId(); $count = $this->activityModel->getPendingActivitiesCount($userId); return $this->respond([ 'status' => 'success', 'data' => ['count' => $count] ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } // ==================== LEAD NOTES APIs ==================== /** * Get notes for a lead * GET /api/sales/leads/{leadId}/notes */ public function getLeadNotes($leadId) { try { $notes = $this->noteModel->getNotesByLead($leadId); return $this->respond([ 'status' => 'success', 'data' => $notes ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Create note * POST /api/sales/notes */ public function createNote() { try { $data = $this->request->getJSON(true); $data['user_id'] = $this->getUserId(); $data['created_by'] = $this->getUserId(); $data['updated_by'] = $this->getUserId(); if (!$this->noteModel->insert($data)) { return $this->fail($this->noteModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $noteId = $this->noteModel->getInsertID(); $note = $this->noteModel->find((int)$noteId); return $this->respondCreated([ 'status' => 'success', 'message' => 'Note created successfully', 'data' => $note ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Update note * PUT /api/sales/notes/{id} */ public function updateNote($id) { try { $note = $this->noteModel->find((int)$id); if (!$note) { return $this->failNotFound('Note not found'); } // Check if user owns the note if ($note['user_id'] != $this->getUserId()) { return $this->failUnauthorized('You are not authorized to update this note'); } $data = $this->request->getJSON(true); $data['updated_by'] = $this->getUserId(); if (!$this->noteModel->update($id, $data)) { return $this->fail($this->noteModel->errors(), ResponseInterface::HTTP_BAD_REQUEST); } $updatedNote = $this->noteModel->find((int)$id); return $this->respond([ 'status' => 'success', 'message' => 'Note updated successfully', 'data' => $updatedNote ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * Delete note * DELETE /api/sales/notes/{id} */ public function deleteNote($id) { try { $note = $this->noteModel->find((int)$id); if (!$note) { return $this->failNotFound('Note not found'); } // Check if user owns the note if ($note['user_id'] != $this->getUserId()) { return $this->failUnauthorized('You are not authorized to delete this note'); } $this->noteModel->delete((int)$id); return $this->respondDeleted([ 'status' => 'success', 'message' => 'Note deleted successfully' ]); } catch (\Exception $e) { return $this->fail($e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } // ==================== HELPER METHODS ==================== /** * Get current user ID from session or JWT token * You'll need to implement this based on your authentication system */ private function getUserId() { // If using session if (session()->has('user_id')) { return session()->get('user_id'); } // If using JWT, decode token and get user_id // Example: return $this->decodeJWT()['user_id']; // For development/testing, you can return a default value return 1; } }