L’aggregazione dei dati avviene unendo i dati provenienti dalle tre tabelle di base, esse sono organizzate seguendo la logica SQL dunque evitando qualsiasi doppione al fine di fornire tutti i doppioni utili alla lettura delle tabelle aggregate. Ad esempio la tabella dei movimenti non riporta il codice e la descrizione del piano dei conti in chiaro, ma il numero che corrisponde alla riga della tabella “Piano” dove si trovano i codici e le descrizioni in chiaro, così facendo nella tabella “Movimenti” non risulterà alcun doppione dunque la tabella manterrà le dimensioni minime e la ricerca dei dati sarà veloce, ma l’unione delle due tabelle riporterà dei doppioni di codici e descrizioni del piano dei conti al fine di facilitare al massimo la lettura da parte dell’utente.
Il primo risultato è visibile alla voce del menù “Movimenti” in basso a sinistra della bacheca di Wordpress, laddove sarà possibile osservare la struttura della tabella “Movimenti” e la tabella che risulta dall’unione di “Movimenti”, “Piano” e “Allegati”. Essa riporta il codice del piano dei conti, ma non la sua descrizione perché serve al controllo umano rapido da parte dell’utente, inoltre permette di osservare l’allegato di ogni movimenti in quanto esiste un link per ogni riga che corrisponde ad un singolo movimento. Notare che i movimenti mostrati riguardano l’anno in corso.
Perché ciò sia possibile è necessario costruire una routine PHP apposita:
function movimenti($year,$condition) { global $wpdb; $table_prefix = 'contab_personia_'; $table_name = $table_prefix . 'movimenti'; echo '<h1>Contabilità Personia - Movimenti</h1>'; $table_structure = struttura_tabella($table_name); switch ($condition) { case 1: $sql = $wpdb->prepare("SELECT * FROM $table_name WHERE YEAR(Data) = %d ORDER BY Data, Id ASC", $year); break; case 2: $sql = $wpdb->prepare("SELECT * FROM $table_name WHERE YEAR(Data) < %d ORDER BY Data, Id ASC", $year); break; case 3: $sql = $wpdb->prepare("SELECT * FROM $table_name WHERE YEAR(Data) > %d ORDER BY Data, Id ASC", $year); break; default: $sql = $wpdb->prepare("SELECT * FROM $table_name WHERE YEAR(Data) = %d ORDER BY Data, Id ASC", $year); } //$data_result = $wpdb->get_results("SELECT * FROM $table_name ORDER BY Data, Id ASC"); $data_result = $wpdb->get_results($sql); echo '<h4>Tabella riepilogativa</h4>'; echo '<table class="personia_contab_table_contab_personia" id="personia_contab_data_'.$table_name.'">'; echo '<thead>'; echo '<tr>'; foreach ($table_structure as $field) { echo '<th>' . $field->Field . '</th>'; } echo '<th>Allegati</th>'; echo '</tr>'; echo '</thead>'; echo '<tbody>'; foreach ($data_result as $row) { echo '<tr>'; echo '<td>'.$row->Id.'</td>'; echo '<td>'.$row->Descrizione.'</td>'; echo '<td>'; $foreign_sql = "SELECT Codice FROM contab_personia_piano WHERE Id = $row->Codice"; $linked_value = $wpdb->get_var($foreign_sql); echo $linked_value; echo '</td>'; echo '<td>'.$row->Data.'</td>'; echo '<td style="text-align:right;">'.number_format($row->Montante, 2, ',', '.').'</td>'; echo '<td style="text-align:center;">'; $allegati_sql = 'SELECT Link FROM contab_personia_allegati WHERE Movimento = ' . $row->Id; $links_allegati = $wpdb->get_results($allegati_sql); foreach ($links_allegati as $row) { echo '<a target="_blank" href="'.$row->Link.'">PDF</a> '; } echo '</td>'; echo '</tr>'; } echo '</tbody>'; echo '</table>'; echo '<button style="border-radius:10px;background-color:blue;color:white;box-shadow:2px 2px 4px grey;" class="bu_contab_personia_tab" title="Tabella movimenti">Stampa la tabella</button>'; } function struttura_tabella($table_name) { global $wpdb; $table_comment_query = $wpdb->get_var($wpdb->prepare("SELECT TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'", DB_NAME, $table_name)); $titolo = $table_comment_query ? $table_comment_query : $table_name; echo '<h3>' . $titolo . '</h3>'; $table_structure = $wpdb->get_results("DESCRIBE $table_name"); $pattern = '/\((.*?)\)/'; echo '<h4>Struttura della tabella</h4>'; echo '<table class="personia_contab_table_contab_personia" id="personia_contab_struct_'.$table_name.'">'; echo '<thead>'; echo '<tr>'; echo '<th>Campo</th><th>Tipo</th><th>Lunghezza</th><th>Null</th><th>Key</th><th>Default</th><th>Extra</th><th>Commento</th>'; echo '</tr>'; echo '</thead>'; echo '<tbody>'; foreach ($table_structure as $field) { echo '<tr>'; echo '<td>' . $field->Field . '</td>'; echo '<td>' . $field->Type . '</td>'; if ( strpos(strtolower($field->Type),'char') ) { if (preg_match($pattern, $field->Type, $matches)) { echo '<td>' . $matches[1] . '</td>'; } } else { echo '<td></td>'; } echo '<td>' . $field->Null . '</td>'; echo '<td>' . $field->Key . '</td>'; echo '<td>' . $field->Default . '</td>'; echo '<td>' . $field->Extra . '</td>'; $field_comment = $wpdb->get_var($wpdb->prepare("SELECT COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s' AND COLUMN_NAME = '%s'", DB_NAME, $table_name, $field->Field)); echo '<td>' . ($field_comment ? $field_comment : 'No comment') . '</td>'; echo '</tr>'; } echo '</tbody>'; echo '</table>'; return $table_structure; }
La stampa a schermo della struttura della tabella è una informazione ridondante non strettamente necessaria, ma utile alla comprensione del programma.
La tabella dei movimenti da sola non è sufficiente per l’analisi contabile e finanziaria, occorre una aggregazione basata sul codice del piano dei conti, la prima voce del menù di programma “Contabilità” si propone di mostrare questa aggregazione.
Al fine di procedere con l’aggregazione è necessario costruire una query apposita, notare il calcolo del bilancio totale alla fine:
SELECT P.Codice, P.Descrizione, SUM(M.Montante) AS Totale FROM contab_personia_piano P JOIN contab_personia_movimenti M ON P.Id = M.Codice GROUP BY P.Codice, P.Descrizione UNION ALL SELECT NULL AS Codice, 'Bilancio' AS Descrizione, SUM(M.Montante) AS Totale FROM contab_personia_piano P JOIN contab_personia_movimenti M ON P.Id = M.Codice;
In questo modo l’utente dispone di tutte le informazioni necessarie all’analisi contabile e finanziaria. Un utente con competenze di contabilità è già in grado di redarre un rapporto descrittivo della situazione contabile e finanziaria.
Se però l’azienda o organizzazione non dispone immediatamente di un professionista può sottoporre i dati ad un motore di intelligenza artificiale e valutare la risposta. I dati da sottoporre al motore di intelligenza artificiale devono essere organizzati in modo diverso dai dati sottoposti ad un utente umano, essi devono contenere il massimo di ridondanza possibile al fine di evitare tutti quei malintesi che un umano risolve attraverso l’interazione con l’insieme dei documenti disponibili oppure con altri umani. La tabella da sottoporre all’IA deve contenere i codici e le descrizioni dei codici di ogni movimento e deve essere sottoposta in un formato leggibile da macchina, tipicamente il formato CSV, a tal fine viene sviluppata una routine specifica:
function select_all_contab($year) { global $wpdb; $sql = "SELECT MAX(Data) AS max_date FROM contab_personia_movimenti"; $res = $wpdb->get_results($sql); if ($res) { $max_date = $res[0]->max_date; } else { $max_date = date('Y-m-d'); } $query = $wpdb->prepare(" SELECT contab_personia_movimenti.Id AS 'Identificatore', contab_personia_movimenti.Descrizione AS 'Descrizione della spesa', contab_personia_piano.Codice AS 'Codice del piano dei conti', contab_personia_piano.Descrizione AS 'Descrizione codice', contab_personia_movimenti.Data AS 'Data della spesa', contab_personia_movimenti.Montante AS 'Spesa in Euro' FROM contab_personia_movimenti JOIN contab_personia_piano ON contab_personia_movimenti.Codice = contab_personia_piano.Id WHERE YEAR(contab_personia_movimenti.Data) = %d", $year ); $results = $wpdb->get_results($query); $csv_data = ''; $csv_header = '"Identificatore","Descrizione della spesa","Codice del piano dei conti","Descrizione del codice","Data della spesa","Spesa in Euro"' . PHP_EOL; foreach ($results as $result) { $csv_data .= '"' . $result->{'Identificatore'} . '","' . $result->{'Descrizione della spesa'} . '","' . $result->{'Codice del piano dei conti'} . '","' . $result->{'Descrizione codice'} . '","' . $result->{'Data della spesa'} . '","' . $result->{'Spesa in Euro'} . '"' . PHP_EOL; } $csv_content = $csv_header . $csv_data; return [$csv_content,$max_date]; }
Notare la query specifica che contiene anche le descrizioni dei codici del piano dei conti.
Al fine di osservare il funzionamento di una contabilità sottoposta ad un servizio di intelligenza artificiale dobbiamo necessariamente dotarci di dati fittizi, comunque il più possibile aderenti alla realtà.
A tale scopo conviene approfittare dei vari servizi offerti in rete, per esempio un generatore di dati fittizi presso https://www.generatedata.com/generator oppure gli archivi offerti da https://www.kaggle.com/ non ultimo un servizio di intelligenza artificiale al quale si può chiedere di generare un giornale di contabilità fittizia.
La tabella fittizia è la seguente:
Descrizione del movimento contabile | Codice del piano dei conti | Descrizione del piano dei conti | Data | Importo |
---|---|---|---|---|
Vendita di beni | 4110101 | Vendita di prodotti | 01/01/2024 | 5000 |
Affitto ricevuto | 4110202 | Entrate da affitti | 02/01/2024 | 2000 |
Interessi ricevuti dalla banca | 4110301 | Interessi attivi | 03/01/2024 | 100 |
Pagamento stipendi | 5110101 | Salari e stipendi | 04/01/2024 | -3000 |
Affitto pagato | 5110202 | Spese di affitto | 05/01/2024 | -1500 |
Acquisto di materie prime | 5110301 | Costo del venduto | 06/01/2024 | -2000 |
Pagamento bollette elettricità | 5110401 | Spese per utenze | 07/01/2024 | -500 |
Ammortamento attrezzature | 5110502 | Ammortamenti | 08/01/2024 | -200 |
Pagamento imposte | 5110601 | Imposte e tasse | 09/01/2024 | -800 |
Acquisto licenze software | 5110701 | Spese per beni immateriali | 10/01/2024 | -1000 |
Entrate da interessi su obbligazioni | 4110302 | Interessi su titoli | 11/01/2024 | 300 |
Dividendi ricevuti | 4110401 | Dividendi | 12/01/2024 | 500 |
Entrate da royalties | 4110501 | Royalties | 13/01/2024 | 200 |
Entrate da donazioni | 4110601 | Donazioni | 14/01/2024 | 800 |
Vendita di titoli azionari | 4110701 | Guadagni da investimenti | 15/01/2024 | 1200 |
Pagamento fornitori | 5110801 | Pagamenti a fornitori | 16/01/2024 | -6000 |
Spese di pubblicità | 5110901 | Spese di marketing | 17/01/2024 | -500 |
Spese di manutenzione | 5110902 | Spese di manutenzione e riparazione | 18/01/2024 | -300 |
Spese di viaggio | 5110903 | Spese di viaggio | 19/01/2024 | -400 |
Spese per servizi professionali | 5110904 | Consulenze e servizi professionali | 20/01/2024 | -800 |
Pagamento premi assicurativi | 5111001 | Spese per assicurazioni | 21/01/2024 | -1000 |
Pagamento rate mutuo | 5111101 | Pagamenti rateali | 22/01/2024 | -2000 |
Entrate da rimborsi spese | 4110801 | Rimborsi spese | 23/01/2024 | 400 |
Entrate da sovvenzioni | 4110901 | Sovvenzioni | 24/01/2024 | 1500 |
Vendita di attrezzature obsolete | 4111001 | Guadagni da cessione di attivi | 25/01/2024 | 500 |
Affitto di attrezzature | 5111201 | Spese di locazione | 26/01/2024 | -300 |
Spese di formazione | 5111301 | Spese di formazione e sviluppo | 27/01/2024 | -800 |
Spese di ricerca e sviluppo | 5111401 | Ricerca e sviluppo | 28/01/2024 | -2000 |
Entrate da attività ricreative | 4111101 | Entrate da eventi e attività | 29/01/2024 | 600 |
Entrate da abbonamenti | 4111201 | Abbonamenti e iscrizioni | 30/01/2024 | 400 |
Vendita di servizi | 4110102 | Entrate da vendita di servizi | 01/02/2024 | 3000 |
Entrate da donazioni per beneficenza | 4110602 | Donazioni benefiche | 02/02/2024 | 1000 |
Entrate da sponsorizzazioni | 4111501 | Sponsorizzazioni | 03/02/2024 | 2000 |
Spese per materiali di consumo | 5111601 | Materiali di consumo | 04/02/2024 | -500 |
Spese per servizi di pulizia | 5111701 | Servizi di pulizia e manutenzione | 05/02/2024 | -300 |
Spese per servizi postali e di spedizione | 5111801 | Spese postali e di spedizione | 06/02/2024 | -200 |
Spese per servizi bancari | 5111901 | Commissioni e spese bancarie | 07/02/2024 | -400 |
Spese per servizi legali | 5112001 | Consulenze legali | 08/02/2024 | -1500 |
Entrate da vendite online | 4111301 | Vendite online | 09/02/2024 | 2000 |
Entrate da licenze software | 4110702 | Licenze software | 10/02/2024 | 800 |
Entrate da servizi di consulenza | 4111401 | Servizi di consulenza | 11/02/2024 | 1200 |
Entrate da interessi di mora | 4110303 | Interessi di mora | 12/02/2024 | 500 |
Entrate da rimborsi assicurativi | 4111601 | Rimborsi assicurativi | 13/02/2024 | 300 |
Entrate da affitto di immobili | 4110201 | Affitti attivi | 14/02/2024 | 2000 |
Entrate da vendite all'asta | 4111701 | Vendite all'asta | 15/02/2024 | 500 |
Entrate da vendite al dettaglio | 4111801 | Vendite al dettaglio | 28/05/2024 | 6000 |
Entrate da vendite all'ingrosso | 4111901 | Vendite all'ingrosso | 31/05/2024 | 4000 |
Il prompt per il motore di intelligenza artificiale è il seguente:
Prompt di sistema = “Rispondi in lingua italiana, in modo impersonale, non ti riferire ad alcuna persona ma solo al tema della risposta”
Prompt utente = “Scrivi un rapporto contabile e finanziario sull'analisi dei dati in formato csv seguenti:” + incolla i dati del file csv
Si procede dunque all’invio manuale del quesito a tre diversi motori disponibili gratuitamente in rete Internet: Mistral, OpenAI e Anthropic. Osserviamo i risultati:
Mistral modello Large
OpenAI modello chatGPT
Anthropic modello Claude
Si nota la diversità dello stile dei tre motori in esame. Ognuno di essi offre una risposta utile, produce un documento il cui contenuto possiede un valore commerciale. Il documento prodotto può essere valorizzato in termini monetari.
L’esercizio fin qui svolto ha seguito una modalità manuale, l’utente raccoglie i dati e li inserisce manualmente nello spazio apposito della pagina web del servizio di intelligenza artificiale, nel prossimo articolo osserveremo come questo esercizio si possa programmare in modo automatico, senza che l’utente debba fornire manualmente i dati al servizio di IA. In tal modo il programma provvede da solo a registrare il rapporto contabile generato dalla IA e lo mostra direttamente nella pagina che contiene la tabella analitica. Inoltre il programma dispone di criteri per la generazione del rapporto contabile e finanziario.