Skip to content

Commit 6e052f5

Browse files
committed
Add InquiryFollowup model
Introduce a new InquiryFollowup model with helper methods for managing follow-ups. Implements create() to insert records (with type casts/defaults) and return the new ID, latestForInquiry() to fetch recent follow-ups joined with admin info (ordered by created_at and id, with a limit), and countOpenByAssignee() to count incomplete follow-ups for a given assigned admin. Uses Database::connection() with prepared statements and basic input validation.
1 parent b9538fa commit 6e052f5

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

app/Models/InquiryFollowup.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Models;
6+
7+
use App\Core\Database;
8+
use PDO;
9+
10+
final class InquiryFollowup
11+
{
12+
public function create(array $data): int
13+
{
14+
$sql = 'INSERT INTO inquiry_followups (
15+
inquiry_id,
16+
admin_id,
17+
followup_type,
18+
content,
19+
next_contact_at,
20+
is_completed
21+
) VALUES (
22+
:inquiry_id,
23+
:admin_id,
24+
:followup_type,
25+
:content,
26+
:next_contact_at,
27+
:is_completed
28+
)';
29+
30+
$stmt = Database::connection()->prepare($sql);
31+
$ok = $stmt->execute([
32+
'inquiry_id' => (int) ($data['inquiry_id'] ?? 0),
33+
'admin_id' => isset($data['admin_id']) && $data['admin_id'] !== '' ? (int) $data['admin_id'] : null,
34+
'followup_type' => (string) ($data['followup_type'] ?? 'note'),
35+
'content' => (string) ($data['content'] ?? ''),
36+
'next_contact_at' => $data['next_contact_at'] ?? null,
37+
'is_completed' => !empty($data['is_completed']) ? 1 : 0,
38+
]);
39+
40+
return $ok ? (int) Database::connection()->lastInsertId() : 0;
41+
}
42+
43+
public function latestForInquiry(int $inquiryId, int $limit = 20): array
44+
{
45+
$sql = 'SELECT
46+
f.*,
47+
a.username AS admin_username,
48+
a.nickname AS admin_nickname
49+
FROM inquiry_followups f
50+
LEFT JOIN admins a ON a.id = f.admin_id
51+
WHERE f.inquiry_id = :inquiry_id
52+
ORDER BY f.created_at DESC, f.id DESC
53+
LIMIT :limit';
54+
55+
$stmt = Database::connection()->prepare($sql);
56+
$stmt->bindValue(':inquiry_id', $inquiryId, PDO::PARAM_INT);
57+
$stmt->bindValue(':limit', max(1, $limit), PDO::PARAM_INT);
58+
$stmt->execute();
59+
60+
return $stmt->fetchAll();
61+
}
62+
63+
public function countOpenByAssignee(int $adminId): int
64+
{
65+
if ($adminId <= 0) {
66+
return 0;
67+
}
68+
69+
$sql = 'SELECT COUNT(*)
70+
FROM inquiry_followups f
71+
INNER JOIN inquiries i ON i.id = f.inquiry_id
72+
WHERE i.assigned_admin_id = :admin_id
73+
AND f.is_completed = 0';
74+
75+
$stmt = Database::connection()->prepare($sql);
76+
$stmt->execute(['admin_id' => $adminId]);
77+
78+
return (int) $stmt->fetchColumn();
79+
}
80+
}

0 commit comments

Comments
 (0)