Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 197
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
NoteController
0.00% covered (danger)
0.00%
0 / 197
0.00% covered (danger)
0.00%
0 / 11
992
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getNotes
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
30
 getNote
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
 createNote
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
20
 updateNote
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
12
 deleteNote
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 togglePin
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 toggleReaction
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
6
 addComment
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
20
 deleteComment
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
12
 getComments
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace BuyerKiosk\Backstock\Controllers;
4
5/**
6 * NoteController
7 *
8 * Handles API routes for backstock notes, reactions, and comments.
9 */
10class NoteController extends \BuyerKiosk\Core\Controllers\BaseController
11{
12    /**
13     * @var \Store Store object
14     */
15    private $store;
16
17    /**
18     * Constructor
19     *
20     * @param \Slim\Slim $app Slim application instance
21     * @param \Store $store Store object
22     */
23    public function __construct($app, \Store $store)
24    {
25        parent::__construct($app);
26        $this->store = $store;
27    }
28
29    /**
30     * Get all active notes
31     *
32     * GET /api/:typeNum/backstock/notes
33     */
34    public function getNotes()
35    {
36        $app = $this->_app;
37        $limit = $app->request->get('limit') ?: 20;
38        $offset = $app->request->get('offset') ?: 0;
39
40        try {
41            $noteModel = new Note($this->store);
42
43            $notes = $noteModel->getActiveNotes(true, (int)$limit, (int)$offset);
44
45            $result = [];
46            foreach ($notes as $note) {
47                $result[] = $note->toArray();
48            }
49
50            echo json_encode([
51                'success' => true,
52                'notes' => $result,
53                'count' => count($result),
54                'limit' => (int)$limit,
55                'offset' => (int)$offset
56            ]);
57
58        } catch (\Exception $e) {
59            echo json_encode([
60                'error' => true,
61                'message' => 'Failed to retrieve notes: ' . $e->getMessage()
62            ]);
63        }
64    }
65
66    /**
67     * Get single note with reactions and comments
68     *
69     * GET /api/:typeNum/backstock/notes/:noteId
70     */
71    public function getNote($noteId)
72    {
73        try {
74            $noteModel = new Note($this->store);
75
76            $note = $noteModel->getById((int)$noteId);
77
78            if (!$note) {
79                echo json_encode([
80                    'error' => true,
81                    'message' => 'Note not found'
82                ]);
83                return;
84            }
85
86            echo json_encode([
87                'success' => true,
88                'note' => $note->toArray()
89            ]);
90
91        } catch (\Exception $e) {
92            echo json_encode([
93                'error' => true,
94                'message' => 'Failed to retrieve note: ' . $e->getMessage()
95            ]);
96        }
97    }
98
99    /**
100     * Create new note
101     *
102     * POST /api/:typeNum/backstock/notes
103     */
104    public function createNote()
105    {
106        $app = $this->_app;
107
108        try {
109            $noteModel = new Note($this->store);
110
111            $data = json_decode($app->request->getBody(), true);
112
113            if (empty($data['content'])) {
114                echo json_encode([
115                    'error' => true,
116                    'message' => 'Content is required'
117                ]);
118                return;
119            }
120
121            // Get employee info from session or request
122            $employeeId = $data['employeeId'] ?? ($app->user->id ?? 0);
123            $employeeName = $data['employeeName'] ?? ($app->user->display_name ?? 'Unknown');
124
125            $noteId = $noteModel->create(
126                (int)$employeeId,
127                $employeeName,
128                $data['content'],
129                $data['title'] ?? null,
130                $data['isPinned'] ?? false,
131                $data['endDate'] ?? null
132            );
133
134            if ($noteId) {
135                $note = $noteModel->getById($noteId);
136                echo json_encode([
137                    'success' => true,
138                    'noteId' => $noteId,
139                    'note' => $note->toArray()
140                ]);
141            } else {
142                echo json_encode([
143                    'error' => true,
144                    'message' => 'Failed to create note'
145                ]);
146            }
147
148        } catch (\Exception $e) {
149            echo json_encode([
150                'error' => true,
151                'message' => 'Failed to create note: ' . $e->getMessage()
152            ]);
153        }
154    }
155
156    /**
157     * Update note
158     *
159     * PUT /api/:typeNum/backstock/notes/:noteId
160     */
161    public function updateNote($noteId)
162    {
163        $app = $this->_app;
164
165        try {
166            $noteModel = new Note($this->store);
167
168            $data = json_decode($app->request->getBody(), true);
169
170            $success = $noteModel->update((int)$noteId, $data);
171
172            if ($success) {
173                $note = $noteModel->getById((int)$noteId);
174                echo json_encode([
175                    'success' => true,
176                    'note' => $note->toArray()
177                ]);
178            } else {
179                echo json_encode([
180                    'error' => true,
181                    'message' => 'Failed to update note'
182                ]);
183            }
184
185        } catch (\Exception $e) {
186            echo json_encode([
187                'error' => true,
188                'message' => 'Failed to update note: ' . $e->getMessage()
189            ]);
190        }
191    }
192
193    /**
194     * Delete note
195     *
196     * DELETE /api/:typeNum/backstock/notes/:noteId
197     */
198    public function deleteNote($noteId)
199    {
200        try {
201            $noteModel = new Note($this->store);
202
203            $success = $noteModel->delete((int)$noteId);
204
205            echo json_encode([
206                'success' => $success
207            ]);
208
209        } catch (\Exception $e) {
210            echo json_encode([
211                'error' => true,
212                'message' => 'Failed to delete note: ' . $e->getMessage()
213            ]);
214        }
215    }
216
217    /**
218     * Toggle pin status
219     *
220     * POST /api/:typeNum/backstock/notes/:noteId/pin
221     */
222    public function togglePin($noteId)
223    {
224        try {
225            $noteModel = new Note($this->store);
226
227            $isPinned = $noteModel->togglePin((int)$noteId);
228
229            echo json_encode([
230                'success' => true,
231                'isPinned' => $isPinned
232            ]);
233
234        } catch (\Exception $e) {
235            echo json_encode([
236                'error' => true,
237                'message' => 'Failed to toggle pin: ' . $e->getMessage()
238            ]);
239        }
240    }
241
242    /**
243     * Toggle reaction on note
244     *
245     * POST /api/:typeNum/backstock/notes/:noteId/react
246     */
247    public function toggleReaction($noteId)
248    {
249        $app = $this->_app;
250
251        try {
252            $noteModel = new Note($this->store);
253
254            $data = json_decode($app->request->getBody(), true);
255
256            $employeeId = $data['employeeId'] ?? ($app->user->id ?? 0);
257            $reactionType = $data['reactionType'] ?? 'like';
258
259            $result = $noteModel->toggleReaction((int)$noteId, (int)$employeeId, $reactionType);
260
261            echo json_encode([
262                'success' => true,
263                'action' => $result['action'],
264                'reactionCount' => $result['count']
265            ]);
266
267        } catch (\Exception $e) {
268            echo json_encode([
269                'error' => true,
270                'message' => 'Failed to toggle reaction: ' . $e->getMessage()
271            ]);
272        }
273    }
274
275    /**
276     * Add comment to note
277     *
278     * POST /api/:typeNum/backstock/notes/:noteId/comments
279     */
280    public function addComment($noteId)
281    {
282        $app = $this->_app;
283
284        try {
285            $noteModel = new Note($this->store);
286
287            $data = json_decode($app->request->getBody(), true);
288
289            if (empty($data['comment'])) {
290                echo json_encode([
291                    'error' => true,
292                    'message' => 'Comment is required'
293                ]);
294                return;
295            }
296
297            $employeeId = $data['employeeId'] ?? ($app->user->id ?? 0);
298            $employeeName = $data['employeeName'] ?? ($app->user->display_name ?? 'Unknown');
299
300            $commentId = $noteModel->addComment(
301                (int)$noteId,
302                (int)$employeeId,
303                $employeeName,
304                $data['comment']
305            );
306
307            if ($commentId) {
308                $comments = $noteModel->getComments((int)$noteId);
309                echo json_encode([
310                    'success' => true,
311                    'commentId' => $commentId,
312                    'comments' => $comments,
313                    'commentCount' => count($comments)
314                ]);
315            } else {
316                echo json_encode([
317                    'error' => true,
318                    'message' => 'Failed to add comment'
319                ]);
320            }
321
322        } catch (\Exception $e) {
323            echo json_encode([
324                'error' => true,
325                'message' => 'Failed to add comment: ' . $e->getMessage()
326            ]);
327        }
328    }
329
330    /**
331     * Delete comment
332     *
333     * DELETE /api/:typeNum/backstock/notes/:noteId/comments/:commentId
334     */
335    public function deleteComment($noteId, $commentId)
336    {
337        $app = $this->_app;
338
339        try {
340            $noteModel = new Note($this->store);
341
342            $data = json_decode($app->request->getBody(), true);
343            $employeeId = $data['employeeId'] ?? ($app->user->id ?? 0);
344
345            $success = $noteModel->deleteComment((int)$commentId, (int)$employeeId);
346
347            if ($success) {
348                $comments = $noteModel->getComments((int)$noteId);
349                echo json_encode([
350                    'success' => true,
351                    'comments' => $comments,
352                    'commentCount' => count($comments)
353                ]);
354            } else {
355                echo json_encode([
356                    'error' => true,
357                    'message' => 'Failed to delete comment (unauthorized or not found)'
358                ]);
359            }
360
361        } catch (\Exception $e) {
362            echo json_encode([
363                'error' => true,
364                'message' => 'Failed to delete comment: ' . $e->getMessage()
365            ]);
366        }
367    }
368
369    /**
370     * Get comments for a note
371     *
372     * GET /api/:typeNum/backstock/notes/:noteId/comments
373     */
374    public function getComments($noteId)
375    {
376        try {
377            $noteModel = new Note($this->store);
378
379            $comments = $noteModel->getComments((int)$noteId);
380
381            echo json_encode([
382                'success' => true,
383                'comments' => $comments,
384                'count' => count($comments)
385            ]);
386
387        } catch (\Exception $e) {
388            echo json_encode([
389                'error' => true,
390                'message' => 'Failed to retrieve comments: ' . $e->getMessage()
391            ]);
392        }
393    }
394}