La ricevuta bancaria è uno dei metodi di pagamento previsti per regolare i rapporti tra cliente e fornitore.
Il funzionamento è molto semplice, viene prodotto e stampato un tagliando, promemoria della scadenza di un debito.
Alla scadenza viene addebitato il conto del debitore e accreditato il conto del creditore.
Il normale flusso delle operazioni è :
- L'azienda creditrice prepara il flusso Ri.Ba e lo invia alla banca
- La banca o l'azienda, a seconda degli accordi stampano ed inviano gli avvisi al cliente
- Alla scadenza la banca a seconda degli accordi intrapresi prepara un flusso per l'azienda cliente dell'esito di ciascun pagamento
Nell'esempio ho predisposto solamente la creazione del file Ri.Ba da inviare alla banca
Secondo gli accordi presi da banche e aziende clienti per ciascuna tipologia di comunicazione è prevista una struttura particolare che ne descrive le particolarità.
Tutti i flussi sono definiti con righe (records) a lunghezza fissa di 120 caratteri, la prima riga è il record di header del flusso, sostanzialmente contiene Le informazioni generali relative al flusso.
HEADER
Campo | Valore | Descrizione |
Tipo Record | IB | Valore fisso "IB" come qualificatore flusso Ri.Ba |
Mittente | Codice SIA Azienda | Codice sia dell'azienda Mittente |
Ricevente | Codice ABI Banca | Codice abi della banca incasso Ri.Ba |
Come ultima riga del flusso è prevista la presenza di un record di coda che ha lo scopo sostanziale di "validare" gli elementi presenti nel flusso certificando che il flusso è completo.
FOOTER
Campo | Descrizione |
Tipo Record | Valore fisso "EF" come qualificatore di fine flusso |
Mittente | Codice sia dell'azienda Mittente |
Ricevente | Codice abi della banca incasso Ri.Ba |
Importi | Sommatoria degli importi dei documenti Ri.Ba |
Numero Righe | Conteggio delle righe presenti nel flusso |
Numero Ricevute | Numero Ri.Ba |
Per ogni Ricevuta Bancaria sono previsti 7 records
Tipo Record |
14 |
20 |
30 |
40 |
50 |
51 |
70 |
Ciascuno di questi descrive una parte delle informazioni riguardo il rapporto di credito / debito, chi deve pagare quando e dove.
La descrizione completa del tracciato Ri.Ba Cbi è codificata insieme a tutte le altre convenzioni di flusso nel documento "CBI-RIB-001.doc" scaricabile all'indirizzo Associazione CBI - Standard Tecnici
Per l'interfacciamento con i dati delle Ri.Ba ho utilizzato due tabelle
Tabella | Descrizione |
TestataDisposizioni | Definizione dei dati generali per ciascun flusso, la chiave principale è un numero progressivo che è ridondato nelle righe come prima parte della PK |
RigheDisposizioni | Dettaglio invio riba, una riga contiene una scadenza la pk è composta dal progressivo invio e da un numero progressivo di riga. La PK garantisce anche l'ordinamento dei dati nell'estrazione |
Tramite il wizard di Visual Studio 2005 ho generato il DataSet tipizzato e i TableAdapters che ho utilizzato nella mia applicazione.
La realizzazione ha comportato la scrittura di un progetto con i moduli principali
Modulo | Descrizione |
MainForm | Form principale dell'applicazione |
GeneraDatiRibaForm | Form Interfaccia per la creazione dei dati di prova |
GeneraFileRibaForm | Form Interfaccia creazione file flusso |
DatiCbi | Classe helper per file flusso |
La form principale (MainForm) contiene
Campo | Descrizione |
ImageMenu | ImageList contenente le icone necessarie al programma |
LvMenu | Listview che interfaccia mainform con le altre 2 form, nel campo "Tag" dei ListViewItem ho impostato il nome del form da caricare tramite doppio click sull'icona corrispondente |
ApriFormByName | Metodo che consente di aprire una form con il nome |
lvMenu_DoubleClick | Gestore dell'evento doppio click sulla listview |
Evento ApriFormByName
private void ApriFormByName(string formName, string namespaceName)
{
string fullName = namespaceName;
try
{
if (namespaceName == null)
fullName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
if (!fullName.EndsWith("."))
fullName += ".";
fullName += formName;
Type oFormType = Type.GetType(fullName, true, true);
((Form)oFormType.GetConstructor(System.Type.EmptyTypes).Invoke(null)).Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + " " + ex.StackTrace);
}
}
Evento lvMenu_DoubleClick
private void lvMenu_DoubleClick(object sender, EventArgs e)
{
string nomeForm = (string)lvMenu.SelectedItems[0].Tag;
ApriFormByName(nomeForm, null);
}
Generazione Dati di Prova
Questa form contiene una normalissima creazione di TestataDisposizioni e RigheDisposizioni con dati "random", nota: i dati sono palesemente falsati proprio perchè non possano in alcun modo ricondurre a situazioni reali. Eventuali utilizzatori in condizioni reali dovranno provvedere in proprio a inserire i dati nel database.
private void CreaDatiRiba()
{
int righe = 0;
righe = CheckValore(righeTextBox);
if (righe <= 0)
return;
testataTableAdapter.Fill(dsDati.TestataDisposizioni);
…
int idTestata = dsDati.TestataDisposizioni.Rows.Count;
if (idTestata > 0)
{
idTestata = (int)dsDati.TestataDisposizioni.Rows[idTestata - 1]["IdInvio"];
}
idTestata += 1;
daticbiDataSet.TestataDisposizioniRow drTestata = (daticbiDataSet.TestataDisposizioniRow)dsDati.TestataDisposizioni.NewRow();
drTestata.AbiAzienda = rnd.Next(1, 99999);
drTestata.CabAzienda = rnd.Next(1, 99999);
dsDati.TestataDisposizioni.Rows.Add(drTestata);
for (int k = 0; k < righe; k++)
{
daticbiDataSet.RigheDisposizioniRow drRighe = (daticbiDataSet.RigheDisposizioniRow)dsDati.RigheDisposizioni.NewRow();
dsDati.RigheDisposizioni.Rows.Add(drRighe);
}
testataTableAdapter.Update(dsDati.TestataDisposizioni);
righeTableAdapter.Update(dsDati.RigheDisposizioni);
MessageBox.Show("Dati generati");
}
Generazione File flusso Riba
Si tratta di una classe che contiene i campi:
Nome | Descrizione |
fileButton | Sostituisce la label del campo "nome del file" con un clic si apre la finestra di dialogo "SaveFileDialog" che consente di scegliere il nome del file da generare |
fileTextBox | Gestisce il nome del file |
invioComboBox | In collegamento con la datatable TestateDisposizioni |
generaButton | Attiva la creazione del file Ri.Ba |
Classe DatiCbiRiba
Si tratta di una classe costruita appositamente per fornire una interfaccia tra le tabelle TestataDisposizioni e RigheDisposizioni.
Le uniche cose degne di nota sono i metodi:
Nome | Descrizione |
RecordIB() | Genera il testo del record header |
RecordEF() | Genera il testo del record footer |
Record14() | Genera il testo del record 14 |
Record20() | Genera il testo del record 20 |
Record30() | Genera il testo del record 30 |
Record40() | Genera il testo del record 40 |
Record50() | Genera il testo del record 50 |
Record51() | Genera il testo del record 51 |
Record70() | Genera il testo del record 70 |
Avvertenza:
Il flusso generato dal programma non ha mai avuto il "battesimo del fuoco", data la complessità sono convinto che ci siano alcuni (speriamo pochi) errori.
Ringrazio in anticipo se qualcuno farà questa prova e me ne comunicherà il risultato.
Riferimenti:
Esempio C#
Esempio VB.NET
Associazione CBI - Standard Tecnici
System.Text Namespace