Repository navigation
Admin Technical Guide.it
Per chi tiene in piedi uno spazio DesKilo: i documenti che stampa, i file che scambia, i servizi con cui parla e la base dati che sta sotto. La configurazione di tutti i giorni sta nella guida di configurazione; quello che vede un membro sta nella guida utente.
Uno spazio segnato <!-- image: … --> è una schermata che la catena non
ha ancora ricevuto.
Tutto ciò che DesKilo stampa — una fattura, un sollecito, una lettera a un membro, un report di consumo, una dichiarazione IVA, un foglio di badge — esce da un solo motore. Un tipo di documento lo nomina; un progetto dice che aspetto ha; i dati che l'app gli consegna sono un vocabolario fisso di segnaposto.

L'editor dei report: i selettori di lingua e documento in alto, gli interruttori Marcatura / Visivo e Progetto / Anteprima sotto, e le bande della fattura — intestazione, corpo, piè di pagina — più giù.
Le copertine di badge e codici QR usano lo stesso motore di pagine delle lettere. Caricano le immagini dello spazio, usano la banda di continuazione nelle pagine successive e mantengono il piè di pagina in basso. Dimensioni delle carte e contenuto dei codici QR restano invariati.
I PDF delle analisi usano il designer dei report per intestazioni, introduzioni, piè di pagina e immagini condivise. Dati, grafici e spiegazioni delle stime restano presenti nei modelli a bande e posizionati.
Ogni report offre un modello Professionale oltre alle opzioni esistenti (#1994). Mantiene le sezioni specifiche: pagamenti confermati e in attesa separati e registrazioni complete dei consumi. I report gestionali non richiedono penali per ritardo. I modelli personalizzati restano fino alla sostituzione esplicita.
La lettera automatica segue il paese dello spazio (Francia: finestra destra; Germania: sinistra), salvo una posizione scelta esplicitamente. La lingua è indipendente dal paese. I modelli mostrano i dati legali forniti; aspetto e traduzione non dimostrano conformità normativa né sostituiscono la fatturazione elettronica.
Il modo rapido di progettare. Quattro bande di marcatura, ciascuna con il suo compito:
| Banda | Dove stampa |
|---|---|
| intestazione | in cima alla pagina 1 soltanto — la carta intestata |
| continuazione | in cima alla pagina 2 e seguenti — una striscia che nomina il documento |
| corpo | l'unica zona che scorre: è quella che prosegue e impagina |
| piè di pagina | in fondo a ogni pagina |
Dentro una banda, un segno per riga decide che cosa è la riga:
| Segno | In che cosa diventa la riga |
|---|---|
# |
un titolo |
## |
un sottotitolo |
- |
una riga piccola |
| a | b | |
una riga di tabella; una riga di --- rende intestazione quella sopra |
--- |
una linea orizzontale |
![nome|l|align] |
un'immagine dalla libreria, con dimensione e allineamento |
| (vuoto) | uno spazio |
| tutto il resto | testo corrente |
Il pannello Segnaposto e marcatura del progettista porta tutto questo in linea, più Inserisci un campo… — il selettore ricercabile, raggruppato per tema, con una riga di significato sotto ogni nome, ricercabile anche per quel significato — e tre pezzi già pronti: una riga che stampa solo quando il suo valore esiste, una riga per ogni riga di fattura, e il titolo che dice fattura, nota di credito o proforma. Quello che toccate atterra al cursore della banda modificata per ultima.
Intestazione e corpo si compongono dall’alto verso il basso. Il piè di pagina mantiene una posizione fissa in fondo a ogni pagina; le righe aggiuntive crescono verso l’alto. Solo la prima pagina stampa intestazione completa e indirizzi. Le successive usano la banda di continuazione e i numeri di pagina. Anche il PDF preparatorio della dichiarazione IVA usa questi modelli modificabili, mantenendo gli importi salvati e lo stato di presentazione.
Con Inserisci un’immagine caricate una sola volta un logo, una firma o un’altra immagine nella libreria dello spazio, quindi selezionatela in qualsiasi modello. Inseritela in una banda con ![name] o in un layout posizionato con <image name="name"/>. Un caricamento con lo stesso nome sostituisce l’immagine per le future generazioni di tutti i modelli che la usano; i PDF già salvati restano invariati.
I riepiloghi mensili usano il motore di pagine comune. L’anteprima separa servizi, pacchetti, elementi in attesa e crediti confermati. Gli spazi di sviluppo stampano la filigrana di sviluppo.
Il PDF di configurazione dello spazio è anche un tipo di report modificabile. Il modello conserva riepilogo, membri e ruoli, funzioni attive, disponibilità, inviti e gerarchia di piani, uffici, tavoli e posti. Può riutilizzare le immagini dello spazio e stampa la filigrana di sviluppo quando necessario.
Il modo esatto. Un layout XML colloca ogni elemento al millimetro, per un documento che deve soddisfare una busta a finestra o un modulo nazionale. Un layout vince sulle bande per il tipo su cui è impostato.
La radice e le sue zone:
<report-layout version="1" page="A4" margin="20mm"
margin-top="8mm" margin-bottom="8mm">
<header height="…">…</header>
<continuation height="…">…</continuation>
<recipient window="fr|din|off"/>
<body y="90mm">…</body>
<footer height="…">…</footer>
</report-layout>margin è il margine laterale; margin-top e margin-bottom separano
il margine verticale quando un documento li vuole distinti, e valgono il
margine laterale quando mancano. <recipient> prende una finestra con
nome — fr a 110 mm, din a 20 mm, entrambe a 45 mm dall'alto in un
riquadro di 85 × 40 mm — oppure x y w h espliciti, oppure off.
<body y="…"> è l'unica zona che scorre: y è il punto in cui
riprende, 90 mm sotto una finestra.
Elementi, validi dentro una zona, una <box> o una <column>:
| Elemento | Che cosa fa |
|---|---|
<text style="heading|subheading|body|small" align="left|center|right" bold="true"> |
un tratto di testo |
<image name="nome-in-libreria" fit="contain|cover|fill" align="…"/> |
un'immagine dalla libreria |
<table><col w="55%" align="right"/>…<row bold="true"><cell align="…">…</cell></row></table> |
una tabella con colonne dichiarate |
<box>…</box> |
un gruppo, perché i figli si posizionino dentro |
<columns><column>…</column>…</columns> |
gruppi affiancati |
<rule/> |
una linea orizzontale |
<spacer size="4mm"/> |
spazio verticale |
<markup>…</markup> |
marcatura di banda, alla lettera, dentro un layout posizionato |
Gli attributi di cornice — x y w h — valgono per qualsiasi
elemento. Con x o y l'elemento è posto in assoluto dentro il suo
genitore; senza né l'uno né l'altro scorre dopo i suoi fratelli.
Le unità sono mm cm px pt %. Un numero nudo è in millimetri; px è
il pixel CSS (1/96 di pollice); % è rispetto al genitore — larghezza
per x e w, altezza per y e h.
Ogni segnaposto che il motore conosce, per famiglia di documento, con i
cicli (lines, vat, usage_records, …) e i campi che ogni riga porta.
dart run tool/report.dart describe stampa l'elenco corrente — è
generato dallo stesso registro che legge il renderer, quindi non può mai
essere superato.
Liquid passa prima su tutto il file, prima che l'XML venga analizzato: una condizione può quindi aprirsi in un elemento e chiudersi in un altro. I valori sono sottoposti a escape XML in ingresso.
| Forma | Che cosa fa |
|---|---|
{{ campo }} |
stampa il valore, con escape |
{% if campo != "" %}…{% endif %} |
stampa il blocco solo quando il campo ha un valore |
{% if a == b %}…{% else %}…{% endif %} |
la forma a due rami |
{% unless campo == "" %}…{% endunless %} |
la forma negata |
{% for line in lines %}…{% endfor %} |
un passaggio per ogni riga di un ciclo |
{{ forloop.index }} |
il numero di riga, a partire da 1, dentro un ciclo |
La regola che frega tutti: ogni segnaposto che il motore conosce è
inizializzato vuoto, mai nullo. Un campo assente vale "", quindi
{% if x != "" %} si comporta bene e un progetto non stampa mai la
parola nil. I testi del proprietario (text.<chiave>) sono
inizializzati allo stesso modo tramite la loro tabella di valori
predefiniti.
I cicli e le loro righe. lines dà label, kind, pct, month, qty, unit_price, net, vat_rate, amount, negative. month è il mese della
posizione di abbonamento, già tradotto nella lingua del documento — è il
motivo per cui una riga di fattura può leggersi settembre 100 %. vat
dà la ripartizione per aliquota, usage_records le mezze giornate,
vat_positions e vat_rate_totals le righe proprie della
dichiarazione.
Una lettera che va in una busta a finestra ha una geometria, e non è questione di gusto:
| Cosa | Dove |
|---|---|
| riga del mittente | a 20 mm da sinistra, 20 mm dall'alto |
| blocco del destinatario | a 110 mm da sinistra, 45 mm dall'alto, dentro 85 × 40 mm |
| corpo | riprende a 90 mm |
| piè di pagina | su ogni pagina |
| striscia di continuazione | dalla pagina due |
Nulla oltre al destinatario può mettere inchiostro nella banda della finestra. Questo è dimostrato sul PDF prodotto, non a occhio: il controllo misura le posizioni di inchiostro del file generato e termina con errore quando qualcosa atterra dove sta la finestra.
dart run tool/report.dart check <layout.xml> [--data data.json]
dart run tool/report.dart render <layout.xml> [--data data.json] -o out.pdf
dart run tool/report.dart sample --kind invoice > data.json
dart run tool/report.dart describe
- check rende il progetto e lo misura contro il contratto della finestra. Uscita 0: conforme; uscita 1: inchiostro nella banda della finestra, e dice quale elemento; uscita 2: il progetto non si è potuto leggere, e nomina l'elemento che si è rotto.
- render produce il PDF, così un progetto si può verificare senza l'app.
- sample scrive un file di dati con ogni segnaposto che il motore conosce, che è il modo più rapido per vedere come si chiama un campo.
- describe stampa il vocabolario qui sopra — zone, elementi, attributi di cornice, unità, Liquid e l'elenco dei segnaposto. È generato dallo stesso registro che legge il renderer, quindi non può divergere dal motore.
La CLI è Dart puro e deve restarlo: non importa nulla da Flutter né dalle
localizzazioni, e un test si rompe nel momento in cui un file di dominio
che usa si tira dietro AppLocalizations.
Una fattura lascia DesKilo come un PDF che legge una persona e un file strutturato che legge una macchina, e i due dicono la stessa cosa perché sono prodotti dallo stesso documento congelato.
Tutti e tre sono la stessa fattura espressa in tre modi, e tutti e tre soddisfano EN 16931, il modello semantico europeo che dice quali fatti una fattura deve portare (BT-1 il numero, BT-48 l'identificativo IVA dell'acquirente, e così via).
| Formato | Che cos'è |
|---|---|
| CII | UN/CEFACT Cross Industry Invoice — la sintassi XML che prende Chorus Pro |
| UBL | OASIS Universal Business Language — la sintassi che prende Peppol |
| Factur-X | un PDF/A-3 con l'XML CII incorporato dentro — un file che una persona legge e una macchina analizza |
Factur-X è il motivo per cui il PDF e l'XML non possono contraddirsi: sono lo stesso file. Quando una piattaforma li vuole separati, entrambi sono prodotti dall'unico documento congelato, mai rigenerati dai dati vivi.
Prima di qualsiasi trasmissione l'app verifica il documento contro la norma e rifiuta nominando ciò che manca, perché una fattura respinta da una piattaforma costa più da riparare di una mai inviata.
Che cosa rifiuta:
- un venditore senza l'identificativo che il regime richiede — una partita IVA quando addebitate l'IVA, un numero di registrazione quando non la addebitate;
- un documento in inversione contabile il cui cliente non ha partita IVA: quel numero è ciò che prova che l'imposta è sua;
- un'esenzione senza motivo e senza un valore predefinito del paese su cui ripiegare;
- una partita IVA cliente la cui forma non corrisponde al suo paese — un avviso, non un rifiuto, dato che le forme cambiano;
- un acquirente senza indirizzo, non appena la destinazione ne richieda uno.
I membri indicano da sé il proprio paese e, quando fatturano come impresa, la propria partita IVA, accanto al loro indirizzo in Impostazioni → Dati personali.
Un documento può andare a due destinazioni insieme: la piattaforma pubblica che il vostro paese impone e il servizio proprio del cliente. Entrambe si configurano sullo spazio, e l'una o l'altra può essere spenta.
Le credenziali vivono sullo spazio, mai nel file di spazio e mai in un deployment — un export che mandate a un collega porta la configurazione e non le chiavi. Uno spazio di sviluppo usa sempre l'endpoint di prova, che fisicamente non può raggiungere una piattaforma pubblica: una fattura di prova non può quindi mai diventare reale.
Ogni tentativo è registrato nello storico di trasmissione della fattura stessa: quando, verso quale destinazione, che cosa ha risposto la piattaforma e quale riferimento ha restituito. Una trasmissione fallita lascia la fattura intatta e ritentabile — il documento è congelato, la trasmissione non ne fa parte.
Tre formati, un solo libro mastro sotto:
| Formato | Dove viene chiesto | Che cosa porta |
|---|---|---|
| FEC | Francia (art. A47 A-1 LPF) | ogni scrittura del periodo, nell'ordine di colonne imposto |
| SAF-T | lo standard OCSE, diversi paesi UE | il file di audit: conti, scritture, documenti |
| DATEV | Germania, per il software del consulente fiscale | le scritture nella disposizione che DATEV importa |
Tutti e tre coprono un periodo che scegliete voi e usano il piano dei conti configurato sullo spazio — il conto IVA compreso, ed è per questo che quel campo appartiene all'identità legale e non all'esportazione. Un periodo già esportato non è bloccato: un export è una lettura, e può essere ripreso dopo una correzione.
| Integrazione | Che cosa fa | Senza di essa |
|---|---|---|
| Fornitore di pagamento | incassa un pagamento a fronte di una fattura | i pagamenti si registrano a mano; nient'altro cambia |
| apre WhatsApp sul dispositivo: il link del gruppo dello spazio e il numero che un membro sceglie di condividere; il server non invia nulla a WhatsApp (0136) | non compare alcun pulsante WhatsApp | |
| Push | consegna le notifiche a un dispositivo | le notifiche compaiono all'apertura dell'app |
| Piattaforma di fatturazione elettronica | trasmette la fattura strutturata | il PDF è prodotto e inviato per altre vie |
Due regole valgono per tutte. Le credenziali vivono sullo spazio, in una tabella che il file di spazio e ogni deployment saltano: nessun export porta quindi mai una chiave. E un'integrazione non configurata degrada, non si rompe: la funzionalità che la richiede è spenta, la schermata lo dice, e nulla solleva eccezioni.
Non c'è alcuna integrazione e-mail. DesKilo non invia e-mail proprie: le sole e-mail sono quelle dell'account del servizio di accesso del server (conferma di iscrizione, reimpostazione della password, un codice di accesso). Tutto il resto raggiunge una persona nell'app: il feed degli eventi e la campanella, le push quando Firebase è configurato e, nell'app installata (non nel browser), un promemoria di check-in locale 15 minuti prima di una prenotazione (il promemoria).
Un'istanza è un DesKilo intero sulla propria base dati. Due spazi — anche una coppia di sviluppo e produzione — ne condividono una; due istanze non condividono nulla. Usatene una dove dati personali o credenziali di pagamento devono essere fisicamente separati, o dove un cliente pretende la propria base dati.
Il bundle è il materiale da costruzione dell'istanza: ogni migrazione in ordine, le funzioni edge, i bucket di archiviazione e il seme. Viene rigenerato a ogni migrazione applicata, così bundle e base dati viva non vanno mai fuori passo.
Create un'istanza dall'assistente dell'app o da
dart run tool/instance.dart; entrambi applicano il bundle a una base
vuota e timbrano a quale migrazione si trova. Una migrazione successiva
raggiunge un'istanza esistente per la stessa via — applicata in ordine dal
timbro in avanti, mai rieseguita.
La versione è un numero che lo schema porta con sé:
select public.deskilo_schema_version(); restituisce l'ultima migrazione
applicata, e ogni migrazione lo scrive nella propria transazione (#1312).
Un'app più vecchia del suo server continua a funzionare. Un'app più
recente del suo server si ferma su Questo server deve essere
aggiornato: chi gestisce il server applica le migrazioni mancanti; gli
altri possono aprire da lì la schermata Server e puntare il dispositivo
altrove. Senza rete il controllo semplicemente non avviene, e nulla viene
bloccato.
Configurazione e dati anagrafici viaggiano fra istanze attraverso il file di spazio, dato che un deployment ha bisogno di una sola base dati e un'istanza è esattamente il punto in cui ce ne sono due.
Impostazioni → Sviluppatore. Un buffer circolare delle ultime 500 voci,
appoggiato a un file sul dispositivo, con ogni errore del framework e
della piattaforma agganciato fin dalla prima riga di main().
Tre forme, e quella di mezzo è la utile:
- step — una decisione o un giro sul server andato come previsto.
- refused — l'app che declina ciò che qualcuno ha cercato di fare. Livello di avviso, e la prima cosa da cercare quando la segnalazione è «ho premuto e non è successo niente».
- failed — un'eccezione, che porta gli stessi campi dello step che ci stava provando, così una riga rossa non resta mai orfana del suo contesto.
Ogni riga è un verbo seguito da coppie chiave=valore, quindi un
registro si può grepare: grep 'act=check-in' legge un tipo di tentativo
da capo a fondo, e grep 'server=' legge ogni rifiuto emesso dal server,
con codice, messaggio, dettagli e suggerimento in un solo campo.
Un registro è per dispositivo. Il registro che risponde a «un membro non è riuscito a registrare l'ingresso» sta sul telefono di quel membro. Esporta lo scrive in un file timbrato con la versione dell'app e lo spazio, ed è ciò che lega un registro esportato alla segnalazione a cui risponde. I payload scansionati sono annotati per forma — schema, host, quali parametri sono presenti, quanto lunghi — mai per valore, perché un codice di invito è un segreto e un registro è fatto per essere mandato a qualcuno.
Uno «started» senza il suo «done» significa che l'atto non è mai
tornato: l'app è stata uccisa, la richiesta non è mai rientrata, o un
await è appeso. Quel buco è la scoperta.
Developers
Administrators
- Configuring the space
- Configurer l'espace 🇫🇷
- Den Bereich einrichten 🇩🇪
- Configurar el espacio 🇪🇸
- Configurare lo spazio 🇮🇹
- The technical side
- Le côté technique 🇫🇷
- Die technische Seite 🇩🇪
- La parte técnica 🇪🇸
- La parte tecnica 🇮🇹
- Environments: dev and prod
- Environnements : dev et prod 🇫🇷
- Umgebungen: Dev und Prod 🇩🇪
- Entornos: dev y prod 🇪🇸
- Ambienti: dev e prod 🇮🇹
Users — on the guide site