# Easyfatt - Python
Questo pacchetto fornisce diversi strumenti per semplificare lo sviluppo di automazioni in **Python** per l'applicativo gestionale "[**Danea Easyfatt**](https://www.danea.it/software/easyfatt/)".
## Funzioni
- Lettura file `.DefXml` esportati da Easyfatt (_ordini cliente, vendite banco, preventivi, ecc.._)
- **Download driver** firebird (necessario per la connessione al DB di Easyfatt)
- Connessione al **database** di Easyfatt
## Utilizzo
### File `.DefXml`
Il modulo `easyfatt_db_connector.xml` espone la classe `EasyfattXML` e la funzione `read_xml` (una funzione "utility" che restituisce un'istanza di `EasyfattXML`).
Sia i metodi `EasyfattXML.from_xml*()` che la funzione `read_xml()` accettano il parametro `convert_types` (di default impostato a `True`) che permette di convertire i valori dei tag in tipi Python nativi (es. `int`, `float`, `bool`, ecc..). Se disabilitato i valori dei tag saranno sempre stringhe o `None`.
#### Esempio
In questo esempio lo script leggerà l'esportazione di una serie di ordini cliente e stamperà a schermo l'indirizzo di spedizione di ogni documento:
```python
from pathlib import Path
from easyfatt_db_connector.xml import read_xml
xml_file = Path("OrdiniCliente.DefXml").expanduser()
# Questa istruzione...
xml_object = read_xml(xml_file, convert_types=True)
# ... si può scrivere anche così
xml_object = EasyfattXML.from_xml_string(xml_file.read_bytes(), convert_types=True)
for doc in xml_object.documents:
print(f"Document n°{doc.number}{doc.numbering} will be shipped at '{doc.delivery.address}'")
```
L'output sarà il seguente:
```plaintext
Document n°1 will be shipped at ''
Document n°2 will be shipped at ''
Document n°3 will be shipped at ''
Document n°1/A will be shipped at ''
Document n°2/A will be shipped at ''
Document n°4 will be shipped at ''
Document n°5 will be shipped at ''
Document n°6 will be shipped at 'Via Facciolati, 546'
Document n°3/A will be shipped at 'Via Catania, sn'
Document n°7 will be shipped at ''
Document n°8 will be shipped at 'Via Rodolfo Manganaro'
Document n°9 will be shipped at 'Via Enrico Berlinguer,75'
Document n°10 will be shipped at ''
Document n°11 will be shipped at 'Via C. Colombo, 632'
Document n°12 will be shipped at ''
Document n°13 will be shipped at ''
Document n°1/B will be shipped at ''
Document n°14 will be shipped at 'Via G. Di Vittorio, 56'
Document n°15 will be shipped at 'Via Cavour, 152'
Document n°16 will be shipped at 'Via N.S. degli Angeli, 28'
```
### Database: download driver Firebird (_prerequisito_)
Per connettersi al DB di Easyfatt è necessario scaricare il driver Firebird `Firebird-{version}-embed.zip` (versione [2.5.8](https://github.com/FirebirdSQL/firebird/releases/tag/R2_5_8) o [2.5.9](https://github.com/FirebirdSQL/firebird/releases/tag/R2_5_9)) e specificarne il percorso.
```python
from easyfatt_db_connector.core.connection import EasyfattFDB
database = EasyfattFDB(archive_path=database_path, firebird_path="./firebird-driver")
```
Questa procedura può essere automatizzata impostando il parametro `download_firebird` a `True` (di default è `False`). E' possibile controllare il percorso di download del driver tramite il parametro `firebird_path` (di default `~/.cache/firebird-driver/`).
```python
from easyfatt_db_connector import EasyfattFDB
database = EasyfattFDB(archive_path=database_path, download_firebird=True)
```
> **ATTENZIONE**
>
> L'opzione `download_firebird` è impostata di default a `False` per evitare che il programma effettui download in ambienti di Produzione.
>
> Se questo è il comportamento desiderato impostare il parametro a `True`.
### Database: connessione e query
In fase di connessione al DB l'istanza `EasyfattFDB` provvederà a fare una copia del database in una cartella temporanea (ed alla sua eliminazione ad operazioni terminate) così da permettere l'utilizzo anche con Easyfatt in esecuzione.
```python
from easyfatt_db_connector.core.connection import EasyfattFDB
database = EasyfattFDB(archive_path=database_path, download_firebird=True)
with database.connect() as connection:
customers = [dict(item) for item in connection.cursor().execute('''
SELECT anag."CodAnagr", ANAG."Nome", ANAG."Indirizzo", ANAG."Cap", ANAG."Citta", ANAG."Prov", ANAG."Regione", IIF(naz."NomeNazionePrint" IS NULL, 'Italia', naz."NomeNazionePrint") AS Nazione
FROM "TAnagrafica" AS anag
LEFT JOIN "TNazioni" naz ON ANAG."Nazione" = naz."NomeNazione";
''').fetchallmap()]
print(customers)
```
## Development
### Note per Windows
#### Build con PyInstaller
In fase di build con PyInstaller (sia in modalità `--onefile` che `--onedir`) è necessario tenere in considerazione le seguenti note:
- **Non usare mai UPX** se disponibile (a causa di un bug che porta la DLL `fbclient.dll` a crashare in modo randomico impedendo la connessione al DB). Se possibile includere sempre `--noupx` tra gli argomenti di build.
- Aggiungere `--collect-all sqlalchemy_firebird` tra gli argomenti di build per evitare che PyInstaller non includa il modulo `fdb` e `firebird-driver` (che non vengono rilevato automaticamente).
### Python
```shell
poetry config virtualenvs.prefer-active-python true
poetry env use $(pyenv which python)
```
### Database
1. Installare [**Firebird SQL** 2.5.9](https://firebirdsql.org/en/firebird-2-5/) (selezionare la versione "_64-bit Classic, Superclassic & Superserver_")
2. Assicurarsi di selezionare "**Run as service**"
Per controllare l'avvenuta installazione:
1. Aprire un terminale Powershell nella cartella di installzione (nel mio caso `C:\Program Files\Firebird\Firebird_2_5`)
2. Lanciare il comando `cd bin`
3. Lanciare il comando `./isql.exe "{PERCORSO_DATABASE}\{NOME_DATABASE}.eft" -u sysdba -p masterkey`
4. Ora è possibile eseguire query SQL (assicurandosi che finiscano SEMPRE con `;`)
![picture 10](images/b84c1a8129e2b6860dd8fb3ca97956e01f1df8ab2447a4b3a79aa503a7389066.png)
### Database tool
1. Installare ed aprire [**DBeaver**](https://dbeaver.io/):
![picture 1](images/6ad115036db6d0cacd65cd56fd433824e02255f08aad3bfe807015622b98d251.png)
2. Cliccare su "File > Nuovo":
![picture 3](images/5bf1d7e5c76f4d7428abc4f7dcaed9aefbb74c04a4adaa944446dfa714d13f9d.png)
3. Cliccare su "DBeaver > Connessione a Database" e cliccare "Avanti":
![picture 2](images/b871bea2ba76855114647dff6732888f05cc37831d177b7172c90f9b581e54df.png)
4. Nel campo di ricerca scrivere "Firebird", selezionare il primo risultato e cliccare "Avanti":
![picture 4](images/a1c9c3910a6054f08b630aa07e697704c3f834011b9666c6ba76d77f80a1c7bf.png)
5. Compilare i dati richiesti:
- **Generale**:
- Host: `localhost` (default)
- Porta: `3050` (default)
- Percorso: adeguare alla posizione del database nel proprio sistema
- **Autenticazione**:
- Nome utente: `SYSDBA` (default)
- Password: `masterkey`
![picture 8](images/25f4675dde1c3ead454938029857e73e3c2ab931f5a3308e5a72bbf3c0c448d9.png)
6. Terminare la configurazione del driver cliccando su "Fine"
## Alcune note
- Assicurarsi che sia visibile almeno la finestra "Navigatore Database":
![picture 9](images/4296d83f4dc4bcd259c117af17cc52b8084a220ecb46b1ca086c22fd7a760d85.png)
Raw data
{
"_id": null,
"home_page": "https://github.com/LukeSavefrogs/easyfatt-db-connector/",
"name": "easyfatt-db-connector",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<3.12",
"maintainer_email": "",
"keywords": "",
"author": "Luca Salvarani",
"author_email": "lucasalvarani99@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/a1/bd/6c030be8b46c2c4db1c49b93d9bddd2d88161860780686b85cd68b437fcf/easyfatt_db_connector-0.3.2.tar.gz",
"platform": null,
"description": "# Easyfatt - Python\n\nQuesto pacchetto fornisce diversi strumenti per semplificare lo sviluppo di automazioni in **Python** per l'applicativo gestionale \"[**Danea Easyfatt**](https://www.danea.it/software/easyfatt/)\".\n\n## Funzioni\n\n- Lettura file `.DefXml` esportati da Easyfatt (_ordini cliente, vendite banco, preventivi, ecc.._)\n- **Download driver** firebird (necessario per la connessione al DB di Easyfatt)\n- Connessione al **database** di Easyfatt\n\n## Utilizzo\n\n### File `.DefXml`\n\nIl modulo `easyfatt_db_connector.xml` espone la classe `EasyfattXML` e la funzione `read_xml` (una funzione \"utility\" che restituisce un'istanza di `EasyfattXML`).\n\nSia i metodi `EasyfattXML.from_xml*()` che la funzione `read_xml()` accettano il parametro `convert_types` (di default impostato a `True`) che permette di convertire i valori dei tag in tipi Python nativi (es. `int`, `float`, `bool`, ecc..). Se disabilitato i valori dei tag saranno sempre stringhe o `None`.\n\n#### Esempio\n\nIn questo esempio lo script legger\u00e0 l'esportazione di una serie di ordini cliente e stamper\u00e0 a schermo l'indirizzo di spedizione di ogni documento:\n\n```python\nfrom pathlib import Path\nfrom easyfatt_db_connector.xml import read_xml\n\nxml_file = Path(\"OrdiniCliente.DefXml\").expanduser()\n\n# Questa istruzione...\nxml_object = read_xml(xml_file, convert_types=True)\n\n# ... si pu\u00f2 scrivere anche cos\u00ec\nxml_object = EasyfattXML.from_xml_string(xml_file.read_bytes(), convert_types=True)\n\nfor doc in xml_object.documents:\n print(f\"Document n\u00b0{doc.number}{doc.numbering} will be shipped at '{doc.delivery.address}'\")\n```\n\nL'output sar\u00e0 il seguente:\n\n```plaintext\nDocument n\u00b01 will be shipped at ''\nDocument n\u00b02 will be shipped at ''\nDocument n\u00b03 will be shipped at ''\nDocument n\u00b01/A will be shipped at ''\nDocument n\u00b02/A will be shipped at ''\nDocument n\u00b04 will be shipped at ''\nDocument n\u00b05 will be shipped at ''\nDocument n\u00b06 will be shipped at 'Via Facciolati, 546'\nDocument n\u00b03/A will be shipped at 'Via Catania, sn'\nDocument n\u00b07 will be shipped at ''\nDocument n\u00b08 will be shipped at 'Via Rodolfo Manganaro'\nDocument n\u00b09 will be shipped at 'Via Enrico Berlinguer,75'\nDocument n\u00b010 will be shipped at ''\nDocument n\u00b011 will be shipped at 'Via C. Colombo, 632'\nDocument n\u00b012 will be shipped at ''\nDocument n\u00b013 will be shipped at ''\nDocument n\u00b01/B will be shipped at ''\nDocument n\u00b014 will be shipped at 'Via G. Di Vittorio, 56'\nDocument n\u00b015 will be shipped at 'Via Cavour, 152'\nDocument n\u00b016 will be shipped at 'Via N.S. degli Angeli, 28'\n```\n\n### Database: download driver Firebird (_prerequisito_)\n\nPer connettersi al DB di Easyfatt \u00e8 necessario scaricare il driver Firebird `Firebird-{version}-embed.zip` (versione [2.5.8](https://github.com/FirebirdSQL/firebird/releases/tag/R2_5_8) o [2.5.9](https://github.com/FirebirdSQL/firebird/releases/tag/R2_5_9)) e specificarne il percorso.\n\n```python\nfrom easyfatt_db_connector.core.connection import EasyfattFDB\n\ndatabase = EasyfattFDB(archive_path=database_path, firebird_path=\"./firebird-driver\")\n```\n\nQuesta procedura pu\u00f2 essere automatizzata impostando il parametro `download_firebird` a `True` (di default \u00e8 `False`). E' possibile controllare il percorso di download del driver tramite il parametro `firebird_path` (di default `~/.cache/firebird-driver/`).\n\n```python\nfrom easyfatt_db_connector import EasyfattFDB\n\ndatabase = EasyfattFDB(archive_path=database_path, download_firebird=True)\n```\n\n> **ATTENZIONE**\n>\n> L'opzione `download_firebird` \u00e8 impostata di default a `False` per evitare che il programma effettui download in ambienti di Produzione.\n>\n> Se questo \u00e8 il comportamento desiderato impostare il parametro a `True`.\n\n### Database: connessione e query\n\nIn fase di connessione al DB l'istanza `EasyfattFDB` provveder\u00e0 a fare una copia del database in una cartella temporanea (ed alla sua eliminazione ad operazioni terminate) cos\u00ec da permettere l'utilizzo anche con Easyfatt in esecuzione.\n\n```python\nfrom easyfatt_db_connector.core.connection import EasyfattFDB\n\ndatabase = EasyfattFDB(archive_path=database_path, download_firebird=True)\n\nwith database.connect() as connection:\n customers = [dict(item) for item in connection.cursor().execute('''\n SELECT anag.\"CodAnagr\", ANAG.\"Nome\", ANAG.\"Indirizzo\", ANAG.\"Cap\", ANAG.\"Citta\", ANAG.\"Prov\", ANAG.\"Regione\", IIF(naz.\"NomeNazionePrint\" IS NULL, 'Italia', naz.\"NomeNazionePrint\") AS Nazione\n FROM \"TAnagrafica\" AS anag\n LEFT JOIN \"TNazioni\" naz ON ANAG.\"Nazione\" = naz.\"NomeNazione\";\n ''').fetchallmap()]\n\n print(customers)\n```\n\n## Development\n\n### Note per Windows\n\n#### Build con PyInstaller\n\nIn fase di build con PyInstaller (sia in modalit\u00e0 `--onefile` che `--onedir`) \u00e8 necessario tenere in considerazione le seguenti note:\n\n- **Non usare mai UPX** se disponibile (a causa di un bug che porta la DLL `fbclient.dll` a crashare in modo randomico impedendo la connessione al DB). Se possibile includere sempre `--noupx` tra gli argomenti di build.\n- Aggiungere `--collect-all sqlalchemy_firebird` tra gli argomenti di build per evitare che PyInstaller non includa il modulo `fdb` e `firebird-driver` (che non vengono rilevato automaticamente).\n\n### Python\n\n```shell\npoetry config virtualenvs.prefer-active-python true\npoetry env use $(pyenv which python)\n```\n\n### Database\n\n1. Installare [**Firebird SQL** 2.5.9](https://firebirdsql.org/en/firebird-2-5/) (selezionare la versione \"_64-bit Classic, Superclassic & Superserver_\")\n2. Assicurarsi di selezionare \"**Run as service**\"\n\nPer controllare l'avvenuta installazione:\n\n1. Aprire un terminale Powershell nella cartella di installzione (nel mio caso `C:\\Program Files\\Firebird\\Firebird_2_5`)\n2. Lanciare il comando `cd bin`\n3. Lanciare il comando `./isql.exe \"{PERCORSO_DATABASE}\\{NOME_DATABASE}.eft\" -u sysdba -p masterkey`\n4. Ora \u00e8 possibile eseguire query SQL (assicurandosi che finiscano SEMPRE con `;`)\n ![picture 10](images/b84c1a8129e2b6860dd8fb3ca97956e01f1df8ab2447a4b3a79aa503a7389066.png) \n\n### Database tool\n\n1. Installare ed aprire [**DBeaver**](https://dbeaver.io/):\n\n ![picture 1](images/6ad115036db6d0cacd65cd56fd433824e02255f08aad3bfe807015622b98d251.png) \n\n2. Cliccare su \"File > Nuovo\":\n\n ![picture 3](images/5bf1d7e5c76f4d7428abc4f7dcaed9aefbb74c04a4adaa944446dfa714d13f9d.png) \n\n3. Cliccare su \"DBeaver > Connessione a Database\" e cliccare \"Avanti\":\n\n ![picture 2](images/b871bea2ba76855114647dff6732888f05cc37831d177b7172c90f9b581e54df.png) \n\n4. Nel campo di ricerca scrivere \"Firebird\", selezionare il primo risultato e cliccare \"Avanti\":\n\n ![picture 4](images/a1c9c3910a6054f08b630aa07e697704c3f834011b9666c6ba76d77f80a1c7bf.png)\n\n5. Compilare i dati richiesti:\n - **Generale**:\n - Host: `localhost` (default)\n - Porta: `3050` (default)\n - Percorso: adeguare alla posizione del database nel proprio sistema\n - **Autenticazione**:\n - Nome utente: `SYSDBA` (default)\n - Password: `masterkey`\n\n ![picture 8](images/25f4675dde1c3ead454938029857e73e3c2ab931f5a3308e5a72bbf3c0c448d9.png) \n\n6. Terminare la configurazione del driver cliccando su \"Fine\"\n\n## Alcune note\n\n- Assicurarsi che sia visibile almeno la finestra \"Navigatore Database\":\n\n ![picture 9](images/4296d83f4dc4bcd259c117af17cc52b8084a220ecb46b1ca086c22fd7a760d85.png) \n",
"bugtrack_url": null,
"license": "MIT",
"summary": "",
"version": "0.3.2",
"project_urls": {
"Homepage": "https://github.com/LukeSavefrogs/easyfatt-db-connector/",
"Repository": "https://github.com/LukeSavefrogs/easyfatt-db-connector/"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3015ecde8b5853ab94165bcbaf190d1c62d42ba7ba879c7dbda0d47634b6940b",
"md5": "ed1d288cbcbd4e0327a1da1fd07be13d",
"sha256": "5f26705d954825a825495f6eb9804023650be252b76d91225b8ec96e75c28be3"
},
"downloads": -1,
"filename": "easyfatt_db_connector-0.3.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ed1d288cbcbd4e0327a1da1fd07be13d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<3.12",
"size": 44287,
"upload_time": "2023-09-13T08:22:26",
"upload_time_iso_8601": "2023-09-13T08:22:26.470249Z",
"url": "https://files.pythonhosted.org/packages/30/15/ecde8b5853ab94165bcbaf190d1c62d42ba7ba879c7dbda0d47634b6940b/easyfatt_db_connector-0.3.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a1bd6c030be8b46c2c4db1c49b93d9bddd2d88161860780686b85cd68b437fcf",
"md5": "764f42059cbd4f63e8a73276278b24c4",
"sha256": "006d1c054fa0938d3b2efd8499767b5fec76a035bd96b01dc5ad41e17cd9a489"
},
"downloads": -1,
"filename": "easyfatt_db_connector-0.3.2.tar.gz",
"has_sig": false,
"md5_digest": "764f42059cbd4f63e8a73276278b24c4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<3.12",
"size": 37991,
"upload_time": "2023-09-13T08:22:28",
"upload_time_iso_8601": "2023-09-13T08:22:28.107886Z",
"url": "https://files.pythonhosted.org/packages/a1/bd/6c030be8b46c2c4db1c49b93d9bddd2d88161860780686b85cd68b437fcf/easyfatt_db_connector-0.3.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-13 08:22:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "LukeSavefrogs",
"github_project": "easyfatt-db-connector",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "easyfatt-db-connector"
}