Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
HomegrownProvider
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 9
182
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
 getActiveEmployees
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getEmployee
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 supportsCreate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 supportsSync
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createEmployee
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 updateEmployee
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
20
 deactivateEmployee
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 syncEmployees
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace BuyerKiosk\Employee;
4
5/**
6 * Provider for manually managed employees (no external system)
7 *
8 * This provider handles full CRUD operations for employees that are
9 * created and managed directly in the BuyerKiosk system without any
10 * external scheduling or workforce management integration.
11 */
12class HomegrownProvider implements EmployeeProviderInterface
13{
14    /**
15     * @var \PDO Database connection
16     */
17    private $db;
18
19    /**
20     * Constructor
21     *
22     * @param \PDO $db Database connection to the store database
23     */
24    public function __construct(\PDO $db)
25    {
26        $this->db = $db;
27    }
28
29    /**
30     * Get all active employees
31     *
32     * @return Employee[] Array of Employee objects
33     */
34    public function getActiveEmployees(): array
35    {
36        $stmt = $this->db->prepare("
37            SELECT * FROM employees
38            WHERE active = 1
39            ORDER BY employeeFirstName, employeeLastName
40        ");
41        $stmt->execute();
42
43        return array_map(
44            fn($row) => Employee::fromRow($row),
45            $stmt->fetchAll(\PDO::FETCH_ASSOC)
46        );
47    }
48
49    /**
50     * Get single employee by ID
51     *
52     * @param int $employeeId The employee ID
53     * @return Employee|null Employee object or null if not found
54     */
55    public function getEmployee(int $employeeId): ?Employee
56    {
57        $stmt = $this->db->prepare("SELECT * FROM employees WHERE employeeID = :id");
58        $stmt->execute([':id' => $employeeId]);
59        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
60
61        return $row ? Employee::fromRow($row) : null;
62    }
63
64    /**
65     * Whether this provider supports creating new employees
66     *
67     * @return bool True - homegrown provider supports creating employees
68     */
69    public function supportsCreate(): bool
70    {
71        return true;
72    }
73
74    /**
75     * Whether this provider supports syncing from external source
76     *
77     * @return bool False - homegrown provider has no external source
78     */
79    public function supportsSync(): bool
80    {
81        return false;
82    }
83
84    /**
85     * Create new employee
86     *
87     * All employees created through this provider will have source='homegrown'
88     *
89     * @param array $data Employee data with keys:
90     *   - firstName (required)
91     *   - lastName (required)
92     *   - email
93     *   - phone
94     *   - photoUrl
95     *   - emergencyContactName
96     *   - emergencyContactPhone
97     *   - hireDate
98     *   - position
99     *   - hourlyRate
100     *   - dailyEmailEnabled
101     *   - role
102     * @return Employee The newly created employee
103     */
104    public function createEmployee(array $data): Employee
105    {
106        $stmt = $this->db->prepare("
107            INSERT INTO employees (
108                employeeFirstName, employeeLastName, email, phone, photoUrl,
109                emergencyContactName, emergencyContactPhone, hireDate,
110                position, hourlyRate, dailyEmailEnabled, source, role, active,
111                createdAt
112            ) VALUES (
113                :firstName, :lastName, :email, :phone, :photoUrl,
114                :emergencyName, :emergencyPhone, :hireDate,
115                :position, :hourlyRate, :dailyEmail, 'homegrown', :role, 1,
116                NOW()
117            )
118        ");
119
120        $stmt->execute([
121            ':firstName' => $data['firstName'],
122            ':lastName' => $data['lastName'],
123            ':email' => $data['email'] ?? null,
124            ':phone' => $data['phone'] ?? null,
125            ':photoUrl' => $data['photoUrl'] ?? null,
126            ':emergencyName' => $data['emergencyContactName'] ?? null,
127            ':emergencyPhone' => $data['emergencyContactPhone'] ?? null,
128            ':hireDate' => $data['hireDate'] ?? null,
129            ':position' => $data['position'] ?? null,
130            ':hourlyRate' => $data['hourlyRate'] ?? null,
131            ':dailyEmail' => $data['dailyEmailEnabled'] ?? 0,
132            ':role' => $data['role'] ?? 4,
133        ]);
134
135        return $this->getEmployee($this->db->lastInsertId());
136    }
137
138    /**
139     * Update employee data
140     *
141     * For homegrown employees, all fields are editable except source
142     *
143     * @param int $employeeId The employee ID
144     * @param array $data Fields to update
145     * @return Employee Updated employee object
146     */
147    public function updateEmployee(int $employeeId, array $data): Employee
148    {
149        $allowedFields = [
150            'employeeFirstName', 'employeeLastName', 'email', 'phone', 'photoUrl',
151            'emergencyContactName', 'emergencyContactPhone', 'hireDate', 'terminationDate',
152            'leaveStartDate', 'leaveEndDate', 'position', 'hourlyRate', 'dailyEmailEnabled',
153            'drsEmployeeId', 'role', 'mappedRole', 'roleColor', 'active'
154        ];
155
156        $updates = [];
157        $params = [':id' => $employeeId];
158
159        foreach ($data as $field => $value) {
160            if (in_array($field, $allowedFields)) {
161                $updates[] = "`$field` = :$field";
162                $params[":$field"] = $value;
163            }
164        }
165
166        if (empty($updates)) {
167            return $this->getEmployee($employeeId);
168        }
169
170        $sql = "UPDATE employees SET " . implode(', ', $updates) . " WHERE employeeID = :id";
171        $stmt = $this->db->prepare($sql);
172        $stmt->execute($params);
173
174        return $this->getEmployee($employeeId);
175    }
176
177    /**
178     * Deactivate employee
179     *
180     * Sets active=0 and records termination date
181     *
182     * @param int $employeeId The employee ID
183     * @param string|null $reason Termination reason (not stored for homegrown)
184     * @return bool True if successful
185     */
186    public function deactivateEmployee(int $employeeId, ?string $reason = null): bool
187    {
188        $stmt = $this->db->prepare("
189            UPDATE employees
190            SET active = 0, terminationDate = CURDATE()
191            WHERE employeeID = :id
192        ");
193        return $stmt->execute([':id' => $employeeId]);
194    }
195
196    /**
197     * Sync employees from external source
198     *
199     * @throws \Exception Always throws - homegrown provider has no external source
200     */
201    public function syncEmployees(): SyncResult
202    {
203        throw new \Exception('Homegrown provider does not support sync');
204    }
205}