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+ }
0 commit comments