Skip to content

Commit bd120f7

Browse files
committed
feat: API per la gestione delle notifiche
1 parent c9b11e6 commit bd120f7

2 files changed

Lines changed: 278 additions & 1 deletion

File tree

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
<?php
2+
3+
/*
4+
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
5+
* Copyright (C) DevCode s.r.l.
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
namespace API\App\v1;
22+
23+
use API\Interfaces\RetrieveInterface;
24+
use API\Resource;
25+
26+
/**
27+
* Risorsa API per la gestione delle notifiche push basate sui log delle operazioni.
28+
* Recupera le operazioni sui moduli interventi e genera notifiche per i tecnici interessati.
29+
*/
30+
class GestioneNotifiche extends Resource implements RetrieveInterface
31+
{
32+
/**
33+
* Operazioni da monitorare per le notifiche
34+
*/
35+
private const OPERAZIONI_MONITORATE = [
36+
'edit_sessione',
37+
'update_inline_sessione',
38+
'delete_sessione',
39+
'add_sessione',
40+
'cambio_stato_intervento'
41+
];
42+
43+
/**
44+
* Recupera le notifiche da inviare basate sui log delle operazioni
45+
*
46+
* @param array $request Richiesta contenente updated_at
47+
* @return array Array di notifiche con token e messaggi
48+
*/
49+
public function retrieve($request)
50+
{
51+
$updated_at = $request['updated_at'] ?? null;
52+
53+
if (empty($updated_at)) {
54+
return [
55+
'notifications' => [],
56+
'message' => 'Parametro updated_at richiesto'
57+
];
58+
}
59+
60+
$database = database();
61+
62+
// Recupera le operazioni monitorate dalla data specificata
63+
$operazioni = $this->getOperazioniDaNotificare($database, $updated_at);
64+
65+
if (empty($operazioni)) {
66+
return [
67+
'notifications' => [],
68+
'message' => 'Nessuna operazione da notificare'
69+
];
70+
}
71+
72+
// Genera le notifiche per ogni operazione
73+
$notifiche = [];
74+
foreach ($operazioni as $operazione) {
75+
$notifiche_operazione = $this->generaNotifichePerOperazione($database, $operazione);
76+
$notifiche = array_merge($notifiche, $notifiche_operazione);
77+
}
78+
79+
return [
80+
'notifications' => $notifiche,
81+
'total_count' => count($notifiche),
82+
'operations_processed' => count($operazioni)
83+
];
84+
}
85+
86+
/**
87+
* Recupera le operazioni da notificare dalla data specificata
88+
*
89+
* @param object $database Connessione database
90+
* @param string $updated_at Data di riferimento
91+
* @return array Array delle operazioni
92+
*/
93+
private function getOperazioniDaNotificare($database, $updated_at)
94+
{
95+
$operazioni_list = "'" . implode("','", self::OPERAZIONI_MONITORATE) . "'";
96+
97+
$query = "SELECT
98+
zz_operations.*,
99+
zz_modules_lang.title as module_name
100+
FROM zz_operations
101+
LEFT JOIN zz_modules ON zz_operations.id_module = zz_modules.id
102+
LEFT JOIN zz_modules_lang ON zz_modules.id = zz_modules_lang.id_record
103+
AND zz_modules_lang.id_lang = " . prepare(\Models\Locale::getDefault()->id) . "
104+
WHERE zz_operations.op IN ({$operazioni_list})
105+
AND zz_operations.created_at > " . prepare($updated_at) . "
106+
AND zz_modules.name = 'Interventi'
107+
ORDER BY zz_operations.created_at DESC";
108+
109+
return $database->fetchArray($query);
110+
}
111+
112+
/**
113+
* Genera le notifiche per una specifica operazione
114+
*
115+
* @param object $database Connessione database
116+
* @param array $operazione Dati dell'operazione
117+
* @return array Array delle notifiche generate
118+
*/
119+
private function generaNotifichePerOperazione($database, $operazione)
120+
{
121+
$notifiche = [];
122+
123+
// Recupera le informazioni complete dell'intervento
124+
$intervento_info = $this->getInterventoInfo($database, $operazione['id_record']);
125+
126+
if (empty($intervento_info)) {
127+
return $notifiche;
128+
}
129+
130+
// Recupera i tecnici interessati all'intervento
131+
$tecnici_interessati = $this->getTecniciInteressati($database, $operazione['id_record']);
132+
133+
if (empty($tecnici_interessati)) {
134+
return $notifiche;
135+
}
136+
137+
// Genera il messaggio in base al tipo di operazione
138+
$messaggio = $this->generaMessaggio($operazione, $intervento_info);
139+
140+
if (empty($messaggio)) {
141+
return $notifiche;
142+
}
143+
144+
// Recupera i token FCM per ogni tecnico interessato
145+
foreach ($tecnici_interessati as $tecnico) {
146+
if (empty($tecnico['user_id'])) {
147+
continue; // Salta i tecnici senza utente associato
148+
}
149+
150+
$tokens = $this->getTokensFCM($database, $tecnico['user_id']);
151+
152+
foreach ($tokens as $token) {
153+
$notifiche[] = [
154+
'token' => $token['token'],
155+
'platform' => $token['platform'],
156+
'message' => $messaggio,
157+
'title' => 'OpenSTAManager',
158+
'data' => [
159+
'operation_id' => $operazione['id'],
160+
'operation_type' => $operazione['op'],
161+
'intervento_id' => $operazione['id_record'],
162+
'intervento_codice' => $intervento_info['codice'],
163+
'tecnico_id' => $tecnico['idtecnico'],
164+
'tecnico_nome' => $tecnico['ragione_sociale'],
165+
'timestamp' => $operazione['created_at']
166+
]
167+
];
168+
}
169+
}
170+
171+
return $notifiche;
172+
}
173+
174+
/**
175+
* Recupera le informazioni complete di un intervento
176+
*
177+
* @param object $database Connessione database
178+
* @param int $id_intervento ID dell'intervento
179+
* @return array|null Informazioni dell'intervento
180+
*/
181+
private function getInterventoInfo($database, $id_intervento)
182+
{
183+
$query = "SELECT
184+
in_interventi.id,
185+
in_interventi.codice,
186+
in_interventi.richiesta,
187+
in_interventi.descrizione,
188+
in_interventi.idstatointervento,
189+
in_statiintervento_lang.title as stato_descrizione,
190+
an_anagrafiche.ragione_sociale as cliente,
191+
an_anagrafiche.idanagrafica as id_cliente
192+
FROM in_interventi
193+
LEFT JOIN in_statiintervento ON in_interventi.idstatointervento = in_statiintervento.id
194+
LEFT JOIN in_statiintervento_lang ON in_statiintervento.id = in_statiintervento_lang.id_record
195+
AND in_statiintervento_lang.id_lang = " . prepare(\Models\Locale::getDefault()->id) . "
196+
LEFT JOIN an_anagrafiche ON in_interventi.idanagrafica = an_anagrafiche.idanagrafica
197+
WHERE in_interventi.id = " . prepare($id_intervento);
198+
199+
return $database->fetchOne($query);
200+
}
201+
202+
/**
203+
* Recupera i tecnici interessati a un intervento specifico
204+
*
205+
* @param object $database Connessione database
206+
* @param int $id_intervento ID dell'intervento
207+
* @return array Array dei tecnici interessati
208+
*/
209+
private function getTecniciInteressati($database, $id_intervento)
210+
{
211+
$query = "SELECT DISTINCT
212+
in_interventi_tecnici.idtecnico,
213+
an_anagrafiche.ragione_sociale,
214+
zz_users.id as user_id
215+
FROM in_interventi_tecnici
216+
LEFT JOIN an_anagrafiche ON in_interventi_tecnici.idtecnico = an_anagrafiche.idanagrafica
217+
LEFT JOIN zz_users ON an_anagrafiche.idanagrafica = zz_users.idanagrafica
218+
WHERE in_interventi_tecnici.idintervento = " . prepare($id_intervento) . "
219+
AND zz_users.id IS NOT NULL";
220+
221+
return $database->fetchArray($query);
222+
}
223+
224+
/**
225+
* Recupera i token FCM per un utente specifico
226+
*
227+
* @param object $database Connessione database
228+
* @param int $user_id ID dell'utente
229+
* @return array Array dei token FCM
230+
*/
231+
private function getTokensFCM($database, $user_id)
232+
{
233+
$query = "SELECT token, platform, device_info
234+
FROM zz_app_tokens
235+
WHERE id_user = " . prepare($user_id) . "
236+
AND token IS NOT NULL
237+
AND token != ''";
238+
239+
return $database->fetchArray($query);
240+
}
241+
242+
/**
243+
* Genera il messaggio di notifica in base al tipo di operazione
244+
*
245+
* @param array $operazione Dati dell'operazione
246+
* @param array $intervento_info Informazioni complete dell'intervento
247+
* @return string Messaggio di notifica
248+
*/
249+
private function generaMessaggio($operazione, $intervento_info)
250+
{
251+
$intervento_codice = $intervento_info['codice'] ?? 'N/A';
252+
$cliente = $intervento_info['cliente'] ?? 'N/A';
253+
254+
switch ($operazione['op']) {
255+
case 'cambio_stato_intervento':
256+
$stato_nuovo = $intervento_info['stato_descrizione'] ?? 'N/A';
257+
return "L'attività {$intervento_codice} è passata nello stato: {$stato_nuovo}";
258+
259+
case 'add_sessione':
260+
return "Nuova sessione creata per l'attività {$intervento_codice}";
261+
262+
case 'update_inline_sessione':
263+
case 'edit_sessione':
264+
return "Sessione modificata per l'attività {$intervento_codice}";
265+
266+
case 'delete_sessione':
267+
return "Sessione eliminata per l'attività {$intervento_codice}";
268+
269+
default:
270+
return "Aggiornamento per l'attività {$intervento_codice}";
271+
}
272+
}
273+
}

update/2_10.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,8 @@ INSERT INTO `zz_api_resources` (`id`, `version`, `type`, `resource`, `class`, `e
9696
VALUES (NULL, 'app-v1', 'update', 'fcm-tokens', 'API\\App\\v1\\FcmTokens', '1');
9797

9898
-- Tabella per la gestione dei gruppi in tipi di intervento
99-
CREATE TABLE `in_tipiintervento_groups` (`id` INT NOT NULL AUTO_INCREMENT , `idtipointervento` INT NOT NULL , `id_gruppo` INT NOT NULL , PRIMARY KEY (`id`));
99+
CREATE TABLE `in_tipiintervento_groups` (`id` INT NOT NULL AUTO_INCREMENT , `idtipointervento` INT NOT NULL , `id_gruppo` INT NOT NULL , PRIMARY KEY (`id`));
100+
101+
-- Registrazione della risorsa API per la gestione delle notifiche
102+
INSERT INTO `zz_api_resources` (`id`, `version`, `type`, `resource`, `class`, `enabled`)
103+
VALUES (NULL, 'app-v1', 'retrieve', 'gestione-notifiche', 'API\\App\\v1\\GestioneNotifiche', '1');

0 commit comments

Comments
 (0)