Tikettinumerointi (VVNKKNN) + automaattinen vastaus
Tikettinumero: - Uudet tiketit saavat juoksevan numeron VVNKKNN-formaatissa (vuosi+kuukausi sekoitettu sekvenssiin, esim. 2600301) - Numero näkyy tikettilistassa ja detail-näkymässä (#-merkillä) - Sähköpostin aihe muotoa "Tiketti #2600301: Alkuperäinen aihe" - Vastaukset ketjuuntuvat automaattisesti Autoreply: - Postilaatikkokohtainen asetus: checkbox + viestisisältö - Uusi tiketti lähettää automaattisen vastauksen asiakkaalle - Autoreply näkyy tiketin viestiketjussa (⚡ Automaattinen vastaus) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
44
db.php
44
db.php
@@ -236,6 +236,7 @@ function initDatabase(): void {
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS tickets (
|
||||
id VARCHAR(20) PRIMARY KEY,
|
||||
ticket_number INT DEFAULT NULL,
|
||||
company_id VARCHAR(50) NOT NULL,
|
||||
subject VARCHAR(500),
|
||||
from_email VARCHAR(255),
|
||||
@@ -317,6 +318,8 @@ function initDatabase(): void {
|
||||
smtp_from_email VARCHAR(255),
|
||||
smtp_from_name VARCHAR(255),
|
||||
aktiivinen BOOLEAN DEFAULT TRUE,
|
||||
auto_reply_enabled BOOLEAN DEFAULT FALSE,
|
||||
auto_reply_body TEXT,
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
INDEX idx_company (company_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
|
||||
@@ -441,6 +444,9 @@ function initDatabase(): void {
|
||||
"ALTER TABLE mailboxes ADD COLUMN smtp_user VARCHAR(255) DEFAULT '' AFTER smtp_port",
|
||||
"ALTER TABLE mailboxes ADD COLUMN smtp_password VARCHAR(255) DEFAULT '' AFTER smtp_user",
|
||||
"ALTER TABLE mailboxes ADD COLUMN smtp_encryption VARCHAR(10) DEFAULT 'tls' AFTER smtp_password",
|
||||
"ALTER TABLE tickets ADD COLUMN ticket_number INT DEFAULT NULL AFTER id",
|
||||
"ALTER TABLE mailboxes ADD COLUMN auto_reply_enabled BOOLEAN DEFAULT FALSE AFTER aktiivinen",
|
||||
"ALTER TABLE mailboxes ADD COLUMN auto_reply_body TEXT AFTER auto_reply_enabled",
|
||||
];
|
||||
foreach ($alters as $sql) {
|
||||
try { $db->query($sql); } catch (\Throwable $e) { /* sarake on jo olemassa / jo ajettu */ }
|
||||
@@ -986,6 +992,24 @@ function dbDeleteLead(string $leadId): void {
|
||||
|
||||
// ==================== TIKETIT ====================
|
||||
|
||||
/**
|
||||
* Generoi seuraava tikettinumero (VVNKKNN-formaatti).
|
||||
* Vuosi+kuukausi sekoitetaan juoksevaan numeroon.
|
||||
*/
|
||||
function dbNextTicketNumber(string $companyId): int {
|
||||
$yy = (int)date('y');
|
||||
$mm = (int)date('m');
|
||||
$fullYear = (int)date('Y');
|
||||
$count = (int)_dbFetchScalar(
|
||||
"SELECT COUNT(*) FROM tickets WHERE company_id = ? AND YEAR(created) = ? AND MONTH(created) = ?",
|
||||
[$companyId, $fullYear, $mm]
|
||||
);
|
||||
$seq = $count + 1;
|
||||
$hundreds = intdiv($seq, 100);
|
||||
$remainder = $seq % 100;
|
||||
return $yy * 100000 + $hundreds * 10000 + $mm * 100 + $remainder;
|
||||
}
|
||||
|
||||
function dbLoadTickets(string $companyId): array {
|
||||
$tickets = _dbFetchAll("SELECT * FROM tickets WHERE company_id = ? ORDER BY updated DESC", [$companyId]);
|
||||
|
||||
@@ -1017,9 +1041,9 @@ function dbSaveTicket(string $companyId, array $ticket): void {
|
||||
$db->begin_transaction();
|
||||
try {
|
||||
_dbExecute("
|
||||
INSERT INTO tickets (id, company_id, subject, from_email, from_name, status, type,
|
||||
INSERT INTO tickets (id, ticket_number, company_id, subject, from_email, from_name, status, type,
|
||||
assigned_to, customer_id, customer_name, message_id, mailbox_id, cc, priority, auto_close_at, created, updated)
|
||||
VALUES (:id, :company_id, :subject, :from_email, :from_name, :status, :type,
|
||||
VALUES (:id, :ticket_number, :company_id, :subject, :from_email, :from_name, :status, :type,
|
||||
:assigned_to, :customer_id, :customer_name, :message_id, :mailbox_id, :cc, :priority, :auto_close_at, :created, :updated)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
subject = VALUES(subject), from_email = VALUES(from_email), from_name = VALUES(from_name),
|
||||
@@ -1030,6 +1054,7 @@ function dbSaveTicket(string $companyId, array $ticket): void {
|
||||
auto_close_at = VALUES(auto_close_at), updated = VALUES(updated)
|
||||
", [
|
||||
'id' => $ticket['id'],
|
||||
'ticket_number' => $ticket['ticket_number'] ?? null,
|
||||
'company_id' => $companyId,
|
||||
'subject' => $ticket['subject'] ?? '',
|
||||
'from_email' => $ticket['from_email'] ?? '',
|
||||
@@ -1157,6 +1182,8 @@ function dbLoadMailboxes(string $companyId): array {
|
||||
$boxes = _dbFetchAll("SELECT * FROM mailboxes WHERE company_id = ?", [$companyId]);
|
||||
foreach ($boxes as &$b) {
|
||||
$b['aktiivinen'] = (bool)$b['aktiivinen'];
|
||||
$b['auto_reply_enabled'] = (bool)($b['auto_reply_enabled'] ?? false);
|
||||
$b['auto_reply_body'] = $b['auto_reply_body'] ?? '';
|
||||
$b['imap_port'] = (int)$b['imap_port'];
|
||||
$b['smtp_port'] = (int)($b['smtp_port'] ?? 587);
|
||||
unset($b['company_id']);
|
||||
@@ -1166,15 +1193,16 @@ function dbLoadMailboxes(string $companyId): array {
|
||||
|
||||
function dbSaveMailbox(string $companyId, array $mailbox): void {
|
||||
_dbExecute("
|
||||
INSERT INTO mailboxes (id, company_id, nimi, imap_host, imap_port, imap_user, imap_encryption, imap_password, smtp_from_email, smtp_from_name, smtp_host, smtp_port, smtp_user, smtp_password, smtp_encryption, aktiivinen)
|
||||
VALUES (:id, :company_id, :nimi, :imap_host, :imap_port, :imap_user, :imap_encryption, :imap_password, :smtp_from_email, :smtp_from_name, :smtp_host, :smtp_port, :smtp_user, :smtp_password, :smtp_encryption, :aktiivinen)
|
||||
INSERT INTO mailboxes (id, company_id, nimi, imap_host, imap_port, imap_user, imap_encryption, imap_password, smtp_from_email, smtp_from_name, smtp_host, smtp_port, smtp_user, smtp_password, smtp_encryption, aktiivinen, auto_reply_enabled, auto_reply_body)
|
||||
VALUES (:id, :company_id, :nimi, :imap_host, :imap_port, :imap_user, :imap_encryption, :imap_password, :smtp_from_email, :smtp_from_name, :smtp_host, :smtp_port, :smtp_user, :smtp_password, :smtp_encryption, :aktiivinen, :auto_reply_enabled, :auto_reply_body)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
nimi = VALUES(nimi), imap_host = VALUES(imap_host), imap_port = VALUES(imap_port),
|
||||
imap_user = VALUES(imap_user), imap_encryption = VALUES(imap_encryption),
|
||||
imap_password = VALUES(imap_password), smtp_from_email = VALUES(smtp_from_email),
|
||||
smtp_from_name = VALUES(smtp_from_name), smtp_host = VALUES(smtp_host), smtp_port = VALUES(smtp_port),
|
||||
smtp_user = VALUES(smtp_user), smtp_password = VALUES(smtp_password),
|
||||
smtp_encryption = VALUES(smtp_encryption), aktiivinen = VALUES(aktiivinen)
|
||||
smtp_encryption = VALUES(smtp_encryption), aktiivinen = VALUES(aktiivinen),
|
||||
auto_reply_enabled = VALUES(auto_reply_enabled), auto_reply_body = VALUES(auto_reply_body)
|
||||
", [
|
||||
'id' => $mailbox['id'],
|
||||
'company_id' => $companyId,
|
||||
@@ -1190,8 +1218,10 @@ function dbSaveMailbox(string $companyId, array $mailbox): void {
|
||||
'smtp_port' => $mailbox['smtp_port'] ?? 587,
|
||||
'smtp_user' => $mailbox['smtp_user'] ?? '',
|
||||
'smtp_password' => $mailbox['smtp_password'] ?? '',
|
||||
'smtp_encryption' => $mailbox['smtp_encryption'] ?? 'tls',
|
||||
'aktiivinen' => $mailbox['aktiivinen'] ?? true,
|
||||
'smtp_encryption' => $mailbox['smtp_encryption'] ?? 'tls',
|
||||
'aktiivinen' => $mailbox['aktiivinen'] ?? true,
|
||||
'auto_reply_enabled' => $mailbox['auto_reply_enabled'] ?? false,
|
||||
'auto_reply_body' => $mailbox['auto_reply_body'] ?? '',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user