Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 181
0.00% covered (danger)
0.00%
0 / 43
CRAP
0.00% covered (danger)
0.00%
0 / 1
Event
0.00% covered (danger)
0.00%
0 / 181
0.00% covered (danger)
0.00%
0 / 43
4692
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 create
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
30
 getById
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
12
 update
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
30
 delete
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getAll
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getActive
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getByYear
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getUpcoming
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getInBuildUp
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getInWindDown
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getBuildUpStartDate
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getWindDownEndDate
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getCurrentPhase
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
110
 toArray
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
2
 getId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getTemplateId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setTemplateId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setName
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getEventType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEventType
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getYear
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setYear
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getStartDate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setStartDate
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getEndDate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEndDate
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getBuildUpDays
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBuildUpDays
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getWindDownDays
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setWindDownDays
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getColor
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setColor
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getIcon
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setIcon
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 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setNotes
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getIsActive
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setIsActive
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getIsRecurring
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setIsRecurring
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace BuyerKiosk\Backstock;
4
5class Event extends Backstock
6{
7    public $id;
8    public $templateId;
9    public $name;
10    public $eventType;
11    public $year;
12    public $startDate;
13    public $endDate;
14    public $buildUpDays;
15    public $windDownDays;
16    public $color;
17    public $icon;
18    public $notes;
19    public $isActive;
20    public $isRecurring;
21    public $createdAt;
22    public $updatedAt;
23
24    public function __construct(\Store $store)
25    {
26        parent::__construct($store);
27    }
28
29    /**
30     * Create a new event
31     * @return $this
32     */
33    public function create()
34    {
35        $stmt = $this->storeDB->prepare("
36            INSERT INTO bsEvents (
37                templateId, name, eventType, year, startDate, endDate,
38                buildUpDays, windDownDays, color, icon, notes,
39                isActive, isRecurring, created_at, updated_at
40            ) VALUES (
41                :templateId, :name, :eventType, :year, :startDate, :endDate,
42                :buildUpDays, :windDownDays, :color, :icon, :notes,
43                :isActive, :isRecurring, NOW(), NOW()
44            )
45        ");
46
47        $stmt->bindValue(":templateId", $this->templateId, $this->templateId === null ? \PDO::PARAM_NULL : \PDO::PARAM_INT);
48        $stmt->bindValue(":name", $this->name);
49        $stmt->bindValue(":eventType", $this->eventType);
50        $stmt->bindValue(":year", $this->year, \PDO::PARAM_INT);
51        $stmt->bindValue(":startDate", $this->startDate);
52        $stmt->bindValue(":endDate", $this->endDate);
53        $stmt->bindValue(":buildUpDays", $this->buildUpDays ?? 14, \PDO::PARAM_INT);
54        $stmt->bindValue(":windDownDays", $this->windDownDays ?? 7, \PDO::PARAM_INT);
55        $stmt->bindValue(":color", $this->color, $this->color === null ? \PDO::PARAM_NULL : \PDO::PARAM_STR);
56        $stmt->bindValue(":icon", $this->icon, $this->icon === null ? \PDO::PARAM_NULL : \PDO::PARAM_STR);
57        $stmt->bindValue(":notes", $this->notes, $this->notes === null ? \PDO::PARAM_NULL : \PDO::PARAM_STR);
58        $stmt->bindValue(":isActive", $this->isActive ?? 1, \PDO::PARAM_INT);
59        $stmt->bindValue(":isRecurring", $this->isRecurring ?? 1, \PDO::PARAM_INT);
60
61        $stmt->execute();
62        $this->id = $this->storeDB->lastInsertId();
63        return $this;
64    }
65
66    /**
67     * Load event by ID
68     * @param int $id
69     * @return $this
70     */
71    public function getById($id)
72    {
73        $stmt = $this->storeDB->prepare("
74            SELECT templateId, name, eventType, year, startDate, endDate,
75                   buildUpDays, windDownDays, color, icon, notes,
76                   isActive, isRecurring, created_at, updated_at
77            FROM bsEvents
78            WHERE id = :id
79        ");
80        $stmt->bindValue(":id", $id, \PDO::PARAM_INT);
81
82        if ($stmt->execute()) {
83            $row = $stmt->fetch(\PDO::FETCH_ASSOC);
84            if ($row) {
85                $this->id = $id;
86                $this->templateId = $row['templateId'];
87                $this->name = $row['name'];
88                $this->eventType = $row['eventType'];
89                $this->year = $row['year'];
90                $this->startDate = $row['startDate'];
91                $this->endDate = $row['endDate'];
92                $this->buildUpDays = $row['buildUpDays'];
93                $this->windDownDays = $row['windDownDays'];
94                $this->color = $row['color'];
95                $this->icon = $row['icon'];
96                $this->notes = $row['notes'];
97                $this->isActive = $row['isActive'];
98                $this->isRecurring = $row['isRecurring'];
99                $this->createdAt = $row['created_at'];
100                $this->updatedAt = $row['updated_at'];
101            }
102        }
103        return $this;
104    }
105
106    /**
107     * Update existing event
108     * @return $this
109     */
110    public function update()
111    {
112        $stmt = $this->storeDB->prepare("
113            UPDATE bsEvents SET
114                templateId = :templateId,
115                name = :name,
116                eventType = :eventType,
117                year = :year,
118                startDate = :startDate,
119                endDate = :endDate,
120                buildUpDays = :buildUpDays,
121                windDownDays = :windDownDays,
122                color = :color,
123                icon = :icon,
124                notes = :notes,
125                isActive = :isActive,
126                isRecurring = :isRecurring,
127                updated_at = NOW()
128            WHERE id = :id
129        ");
130
131        $stmt->bindValue(":templateId", $this->templateId, $this->templateId === null ? \PDO::PARAM_NULL : \PDO::PARAM_INT);
132        $stmt->bindValue(":name", $this->name);
133        $stmt->bindValue(":eventType", $this->eventType);
134        $stmt->bindValue(":year", $this->year, \PDO::PARAM_INT);
135        $stmt->bindValue(":startDate", $this->startDate);
136        $stmt->bindValue(":endDate", $this->endDate);
137        $stmt->bindValue(":buildUpDays", $this->buildUpDays, \PDO::PARAM_INT);
138        $stmt->bindValue(":windDownDays", $this->windDownDays, \PDO::PARAM_INT);
139        $stmt->bindValue(":color", $this->color, $this->color === null ? \PDO::PARAM_NULL : \PDO::PARAM_STR);
140        $stmt->bindValue(":icon", $this->icon, $this->icon === null ? \PDO::PARAM_NULL : \PDO::PARAM_STR);
141        $stmt->bindValue(":notes", $this->notes, $this->notes === null ? \PDO::PARAM_NULL : \PDO::PARAM_STR);
142        $stmt->bindValue(":isActive", $this->isActive, \PDO::PARAM_INT);
143        $stmt->bindValue(":isRecurring", $this->isRecurring, \PDO::PARAM_INT);
144        $stmt->bindValue(":id", $this->id, \PDO::PARAM_INT);
145
146        $stmt->execute();
147        return $this;
148    }
149
150    /**
151     * Delete event
152     * @return $this
153     */
154    public function delete()
155    {
156        $stmt = $this->storeDB->prepare("DELETE FROM bsEvents WHERE id = :id");
157        $stmt->bindValue(":id", $this->id, \PDO::PARAM_INT);
158        $stmt->execute();
159        return $this;
160    }
161
162    /**
163     * Get all events for the store
164     * @return array
165     */
166    public function getAll()
167    {
168        $stmt = $this->storeDB->prepare("
169            SELECT id, templateId, name, eventType, year, startDate, endDate,
170                   buildUpDays, windDownDays, color, icon, notes,
171                   isActive, isRecurring, created_at, updated_at
172            FROM bsEvents
173            ORDER BY startDate DESC
174        ");
175        $stmt->execute();
176        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
177    }
178
179    /**
180     * Get active events
181     * @return array
182     */
183    public function getActive()
184    {
185        $stmt = $this->storeDB->prepare("
186            SELECT id, templateId, name, eventType, year, startDate, endDate,
187                   buildUpDays, windDownDays, color, icon, notes,
188                   isActive, isRecurring, created_at, updated_at
189            FROM bsEvents
190            WHERE isActive = 1
191            ORDER BY startDate DESC
192        ");
193        $stmt->execute();
194        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
195    }
196
197    /**
198     * Get events for a specific year
199     * @param int $year
200     * @return array
201     */
202    public function getByYear($year)
203    {
204        $stmt = $this->storeDB->prepare("
205            SELECT id, templateId, name, eventType, year, startDate, endDate,
206                   buildUpDays, windDownDays, color, icon, notes,
207                   isActive, isRecurring, created_at, updated_at
208            FROM bsEvents
209            WHERE year = :year
210            ORDER BY startDate ASC
211        ");
212        $stmt->bindValue(":year", $year, \PDO::PARAM_INT);
213        $stmt->execute();
214        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
215    }
216
217    /**
218     * Get events starting in the next N days
219     * @param int $days
220     * @return array
221     */
222    public function getUpcoming($days = 30)
223    {
224        $stmt = $this->storeDB->prepare("
225            SELECT id, templateId, name, eventType, year, startDate, endDate,
226                   buildUpDays, windDownDays, color, icon, notes,
227                   isActive, isRecurring, created_at, updated_at
228            FROM bsEvents
229            WHERE startDate BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL :days DAY)
230            AND isActive = 1
231            ORDER BY startDate ASC
232        ");
233        $stmt->bindValue(":days", $days, \PDO::PARAM_INT);
234        $stmt->execute();
235        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
236    }
237
238    /**
239     * Get events currently in build-up phase
240     * @return array
241     */
242    public function getInBuildUp()
243    {
244        $stmt = $this->storeDB->prepare("
245            SELECT id, templateId, name, eventType, year, startDate, endDate,
246                   buildUpDays, windDownDays, color, icon, notes,
247                   isActive, isRecurring, created_at, updated_at
248            FROM bsEvents
249            WHERE DATE_SUB(startDate, INTERVAL buildUpDays DAY) <= CURDATE()
250            AND startDate > CURDATE()
251            AND isActive = 1
252            ORDER BY startDate ASC
253        ");
254        $stmt->execute();
255        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
256    }
257
258    /**
259     * Get events currently in wind-down phase
260     * @return array
261     */
262    public function getInWindDown()
263    {
264        $stmt = $this->storeDB->prepare("
265            SELECT id, templateId, name, eventType, year, startDate, endDate,
266                   buildUpDays, windDownDays, color, icon, notes,
267                   isActive, isRecurring, created_at, updated_at
268            FROM bsEvents
269            WHERE endDate < CURDATE()
270            AND DATE_ADD(endDate, INTERVAL windDownDays DAY) >= CURDATE()
271            AND isActive = 1
272            ORDER BY endDate ASC
273        ");
274        $stmt->execute();
275        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
276    }
277
278    /**
279     * Calculate build-up start date
280     * @return string Date in Y-m-d format
281     */
282    public function getBuildUpStartDate()
283    {
284        if (!$this->startDate || !$this->buildUpDays) {
285            return null;
286        }
287        $date = new \DateTime($this->startDate);
288        $date->modify("-{$this->buildUpDays} days");
289        return $date->format('Y-m-d');
290    }
291
292    /**
293     * Calculate wind-down end date
294     * @return string Date in Y-m-d format
295     */
296    public function getWindDownEndDate()
297    {
298        if (!$this->endDate || !$this->windDownDays) {
299            return null;
300        }
301        $date = new \DateTime($this->endDate);
302        $date->modify("+{$this->windDownDays} days");
303        return $date->format('Y-m-d');
304    }
305
306    /**
307     * Get current phase of the event
308     * @return string Phase: 'upcoming', 'build_up', 'active', 'wind_down', 'completed'
309     */
310    public function getCurrentPhase()
311    {
312        if (!$this->startDate || !$this->endDate) {
313            return 'upcoming';
314        }
315
316        $today = new \DateTime();
317        $startDate = new \DateTime($this->startDate);
318        $endDate = new \DateTime($this->endDate);
319
320        $buildUpStart = new \DateTime($this->startDate);
321        $buildUpStart->modify("-{$this->buildUpDays} days");
322
323        $windDownEnd = new \DateTime($this->endDate);
324        $windDownEnd->modify("+{$this->windDownDays} days");
325
326        if ($today < $buildUpStart) {
327            return 'upcoming';
328        } elseif ($today >= $buildUpStart && $today < $startDate) {
329            return 'build_up';
330        } elseif ($today >= $startDate && $today <= $endDate) {
331            return 'active';
332        } elseif ($today > $endDate && $today <= $windDownEnd) {
333            return 'wind_down';
334        } else {
335            return 'completed';
336        }
337    }
338
339    /**
340     * Convert to array for JSON serialization
341     * @return array
342     */
343    public function toArray()
344    {
345        return [
346            'id' => $this->id,
347            'templateId' => $this->templateId,
348            'name' => $this->name,
349            'eventType' => $this->eventType,
350            'year' => $this->year,
351            'startDate' => $this->startDate,
352            'endDate' => $this->endDate,
353            'buildUpDays' => $this->buildUpDays,
354            'windDownDays' => $this->windDownDays,
355            'buildUpStartDate' => $this->getBuildUpStartDate(),
356            'windDownEndDate' => $this->getWindDownEndDate(),
357            'color' => $this->color,
358            'icon' => $this->icon,
359            'notes' => $this->notes,
360            'isActive' => (bool)$this->isActive,
361            'isRecurring' => (bool)$this->isRecurring,
362            'currentPhase' => $this->getCurrentPhase(),
363            'createdAt' => $this->createdAt,
364            'updatedAt' => $this->updatedAt
365        ];
366    }
367
368    /**
369     * @return int
370     */
371    public function getId()
372    {
373        return $this->id;
374    }
375
376    /**
377     * @param int $id
378     * @return $this
379     */
380    public function setId($id)
381    {
382        $this->id = $id;
383        return $this;
384    }
385
386    /**
387     * @return int|null
388     */
389    public function getTemplateId()
390    {
391        return $this->templateId;
392    }
393
394    /**
395     * @param int|null $templateId
396     * @return $this
397     */
398    public function setTemplateId($templateId)
399    {
400        $this->templateId = $templateId;
401        return $this;
402    }
403
404    /**
405     * @return string
406     */
407    public function getName()
408    {
409        return $this->name;
410    }
411
412    /**
413     * @param string $name
414     * @return $this
415     */
416    public function setName($name)
417    {
418        $this->name = $name;
419        return $this;
420    }
421
422    /**
423     * @return string
424     */
425    public function getEventType()
426    {
427        return $this->eventType;
428    }
429
430    /**
431     * @param string $eventType
432     * @return $this
433     */
434    public function setEventType($eventType)
435    {
436        $this->eventType = $eventType;
437        return $this;
438    }
439
440    /**
441     * @return int
442     */
443    public function getYear()
444    {
445        return $this->year;
446    }
447
448    /**
449     * @param int $year
450     * @return $this
451     */
452    public function setYear($year)
453    {
454        $this->year = $year;
455        return $this;
456    }
457
458    /**
459     * @return string
460     */
461    public function getStartDate()
462    {
463        return $this->startDate;
464    }
465
466    /**
467     * @param string $startDate
468     * @return $this
469     */
470    public function setStartDate($startDate)
471    {
472        $this->startDate = $startDate;
473        return $this;
474    }
475
476    /**
477     * @return string
478     */
479    public function getEndDate()
480    {
481        return $this->endDate;
482    }
483
484    /**
485     * @param string $endDate
486     * @return $this
487     */
488    public function setEndDate($endDate)
489    {
490        $this->endDate = $endDate;
491        return $this;
492    }
493
494    /**
495     * @return int
496     */
497    public function getBuildUpDays()
498    {
499        return $this->buildUpDays;
500    }
501
502    /**
503     * @param int $buildUpDays
504     * @return $this
505     */
506    public function setBuildUpDays($buildUpDays)
507    {
508        $this->buildUpDays = $buildUpDays;
509        return $this;
510    }
511
512    /**
513     * @return int
514     */
515    public function getWindDownDays()
516    {
517        return $this->windDownDays;
518    }
519
520    /**
521     * @param int $windDownDays
522     * @return $this
523     */
524    public function setWindDownDays($windDownDays)
525    {
526        $this->windDownDays = $windDownDays;
527        return $this;
528    }
529
530    /**
531     * @return string|null
532     */
533    public function getColor()
534    {
535        return $this->color;
536    }
537
538    /**
539     * @param string|null $color
540     * @return $this
541     */
542    public function setColor($color)
543    {
544        $this->color = $color;
545        return $this;
546    }
547
548    /**
549     * @return string|null
550     */
551    public function getIcon()
552    {
553        return $this->icon;
554    }
555
556    /**
557     * @param string|null $icon
558     * @return $this
559     */
560    public function setIcon($icon)
561    {
562        $this->icon = $icon;
563        return $this;
564    }
565
566    /**
567     * @return string|null
568     */
569    public function getNotes()
570    {
571        return $this->notes;
572    }
573
574    /**
575     * @param string|null $notes
576     * @return $this
577     */
578    public function setNotes($notes)
579    {
580        $this->notes = $notes;
581        return $this;
582    }
583
584    /**
585     * @return bool
586     */
587    public function getIsActive()
588    {
589        return (bool)$this->isActive;
590    }
591
592    /**
593     * @param bool $isActive
594     * @return $this
595     */
596    public function setIsActive($isActive)
597    {
598        $this->isActive = $isActive ? 1 : 0;
599        return $this;
600    }
601
602    /**
603     * @return bool
604     */
605    public function getIsRecurring()
606    {
607        return (bool)$this->isRecurring;
608    }
609
610    /**
611     * @param bool $isRecurring
612     * @return $this
613     */
614    public function setIsRecurring($isRecurring)
615    {
616        $this->isRecurring = $isRecurring ? 1 : 0;
617        return $this;
618    }
619}