{"id":32300452,"url":"https://github.com/pitwch/dart_proffix_rest","last_synced_at":"2026-02-20T23:01:33.467Z","repository":{"id":59185769,"uuid":"470095102","full_name":"pitwch/dart_proffix_rest","owner":"pitwch","description":"Flutter Client for Proffix Rest API","archived":false,"fork":false,"pushed_at":"2025-12-19T07:45:24.000Z","size":10700,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-22T02:35:48.725Z","etag":null,"topics":["dart","flutter","proffix","rest-api","restful-api"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/dart_proffix_rest","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pitwch.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-15T09:49:04.000Z","updated_at":"2025-12-19T07:45:28.000Z","dependencies_parsed_at":"2024-12-31T10:04:49.301Z","dependency_job_id":"7c51b711-16f2-4a1d-8153-2b7f1283ed5f","html_url":"https://github.com/pitwch/dart_proffix_rest","commit_stats":{"total_commits":65,"total_committers":3,"mean_commits":"21.666666666666668","dds":0.4,"last_synced_commit":"6d93074e50ab81f0f80c66d2e854de0e1aad6e9d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pitwch/dart_proffix_rest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitwch%2Fdart_proffix_rest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitwch%2Fdart_proffix_rest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitwch%2Fdart_proffix_rest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitwch%2Fdart_proffix_rest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pitwch","download_url":"https://codeload.github.com/pitwch/dart_proffix_rest/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitwch%2Fdart_proffix_rest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29667119,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T19:49:36.704Z","status":"ssl_error","status_checked_at":"2026-02-20T19:44:05.372Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","flutter","proffix","rest-api","restful-api"],"created_at":"2025-10-23T05:18:54.938Z","updated_at":"2026-02-20T23:01:33.461Z","avatar_url":"https://github.com/pitwch.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\nThis README describes the package. If you publish this package to pub.dev,\nthis README's contents appear on the landing page for your package.\n\nFor information about how to write a good package README, see the guide for\n[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).\n\nFor general information about developing packages, see the Dart guide for\n[creating packages](https://dart.dev/guides/libraries/create-library-packages)\nand the Flutter guide for\n[developing packages and plugins](https://flutter.dev/developing-packages).\n--\u003e\n\n\u003c!-- markdownlint-disable MD041 --\u003e\n\n[![pub package](https://img.shields.io/pub/v/dart_proffix_rest)](https://pub.dev/packages/dart_proffix_rest)\n[![Build Status](https://github.com/pitwch/dart_proffix_rest/actions/workflows/ci.yml/badge.svg)](https://github.com/pitwch/dart_proffix_rest/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/pitwch/dart_proffix_rest/branch/main/graph/badge.svg?token=MDG6GG8RCE)](https://codecov.io/gh/pitwch/dart_proffix_rest)\n[![License](https://img.shields.io/github/license/pitwch/dart_proffix_rest)](https://github.com/pitwch/dart_proffix_rest/blob/main/LICENSE)\n\n# Dart Wrapper für PROFFIX REST-API\n\n![alt text](https://raw.githubusercontent.com/pitwch/dart_proffix_rest/main/_assets/dart-proffix.png \"Dart Wrapper PROFFIX REST API\")\n\nDieser Wrapper wird von der [Pedrett IT+Web AG](https://www.pitw.ch) - dem unabhängigen und innovativen Proffix Px5 Partner - **unterhalten und entwickelt**.\n\n## Übersicht\n\n- [Installation](#installation)\n  - [Konfiguration](#konfiguration)\n- [Optionen](#optionen)\n  - [Methoden](#methoden)\n  - [Spezielle Endpunkte](#spezielle-endpunkte)\n- [Weitere Beispiele](#weitere-beispiele)\n\n## Installation\n\n```bash\ndart pub add dart_proffix_rest\n```\n\n### Konfiguration\n\nDie Konfiguration wird dem Client mitgegeben:\n\n| Konfiguration | Beispiel                                | Type                 | Bemerkung                             |\n|---------------|-----------------------------------------|----------------------|---------------------------------------|\n| restURL       | \u003chttps://myserver.ch:12299\u003e             | `string`             | URL der REST-API **ohne pxapi/v4/**   |\n| database      | DEMO                                    | `string`             | Name der Datenbank                    |\n| username      | USR                                     | `string`             | Names des Benutzers                   |\n| password      | b62cce2fe18f7a156a9c...                 | `string`             | SHA256-Hash des Benutzerpasswortes    |\n| modules       | [\"ADR\", \"FIB\"]                          | `List\u003cString\u003e?`      | Benötigte Module (mit Komma getrennt) |\n| options       | ProffixRestOptions(volumeLicence: true) | `ProffixRestOptions` | Optionen (Details unter Optionen)     |\n\nBeispiel:\n\n```dart\nimport 'package:dart_proffix_rest/dart_proffix_rest.dart';\n\n\nvar pxClient = ProffixClient(\n        database: 'DEMODBPX5',\n        restURL: 'https://myserver.ch:12299',\n        username: 'USR',\n        password: 'b62cce2fe18f7a156a9c719c57bebf0478a3d50f0d7bd18d9e8a40be2e663017',\n        modules: [\"VOL\"],\n        options: null);\n\n    var request =\n        await pxClient.get(endpoint: \"ADR/Adresse\", params: {\"Limit\": \"1\"});\n\n\n```\n\n\u003e Hinweis zu VOL: Wenn das Modul \"VOL\" genutzt wird (oder `volumeLicence == true` gesetzt ist), führt `logout()` standardmäßig keinen Aufruf an die REST-API aus. Bei Bedarf können Sie einen Logout mit `forceLogout: true` erzwingen und mit `clearSessionCache` steuern, ob ein aktivierter Session-Cache geleert werden soll. Siehe Abschnitt „Logout“ weiter unten.\n\n### Optionen\n\nOptionen sind **fakultativ** und werden in der Regel nicht benötigt:\n\n| Option        | Beispiel                              | Bemerkung                                                      |\n|---------------|---------------------------------------|----------------------------------------------------------------|\n| key           | 112a5a90fe28b...242b10141254b4de59028 | API-Key als SHA256 - Hash (kann auch direkt mitgegeben werden) |\n| version       | v3                                    | API-Version; Standard = v3                                     |\n| loginEndpoint | /pxapi/                               | Prefix für die API; Standard = /pxapi/                         |\n| LoginEndpoint | PRO/Login                             | Endpunkt für Login; Standard = PRO/Login                       |\n| userAgent     | DartWrapper                           | User Agent; Standard = DartWrapper                             |\n| timeout       | 15                                    | Timeout in Sekunden                                            |\n| batchsize     | 200                                   | Batchgrösse für Batchrequests; Standard = 200                  |\n| log           | true                                  | Aktiviert den Log für Debugging; Standard = false              |\n| volumeLicence | false                                 | Nutzt PROFFIX Volumenlizenzierung                              |\n\n#### Session Caching (optional)\n\nAb Version 0.4.1 kann die PxSessionId optional gecached werden, um unnötige Logins zu vermeiden. Der Cache wird solange verwendet, bis eine Anfrage mit HTTP 401 (Unauthorized) fehlschlägt. In diesem Fall wird die Session automatisch invalidiert, neu eingeloggt und die Anfrage einmalig wiederholt.\n\nEs gibt zwei Möglichkeiten:\n\n1. Einfach aktivieren (Default: Datei-basierter Cache)\n\nOhne eigene Callbacks wird automatisch ein Datei-basierter Cache verwendet:\n\n- Windows: %APPDATA%/dart_proffix_rest\n- Sonst: systemTemp/dart_proffix_rest\n\n```dart\nfinal client = ProffixClient(\n  database: 'DEMO',\n  restURL: 'https://myserver.ch:12299',\n  username: 'USR',\n  password: '...SHA256... ',\n  options: ProffixRestOptions(\n    enableSessionCaching: true, // aktiviert den Cache\n  ),\n);\n```\n\n1. Eigene Speicherlogik verwenden\n\nSie können eigene Callbacks zum Laden/Speichern/Löschen der Session-ID übergeben (z. B. Secure Storage, SharedPreferences, etc.):\n\n```dart\nfinal myStore = MySessionStore(); // ihre eigene Implementierung\n\nfinal client = ProffixClient(\n  database: 'DEMO',\n  restURL: 'https://myserver.ch:12299',\n  username: 'USR',\n  password: '...SHA256... ',\n  options: ProffixRestOptions(\n    enableSessionCaching: true,\n    loadSessionId: () async =\u003e await myStore.read(),\n    saveSessionId: (sid) async =\u003e await myStore.write(sid),\n    clearSessionId: () async =\u003e await myStore.clear(),\n  ),\n);\n```\n\nVerhalten im Überblick:\n\n- Der Client lädt beim ersten Zugriff auf `getPxSessionId()` einen vorhandenen Cache, falls aktiviert.\n- Jeder erfolgreiche Request aktualisiert die intern gespeicherte Session und persistiert sie (falls aktiviert).\n- Bei HTTP 401 wird der Cache invalidiert, neu eingeloggt und die Anfrage einmal wiederholt.\n\n#### Methoden\n\n| Parameter  | Typ                     | Bemerkung                                                                                                |\n|------------|-------------------------|----------------------------------------------------------------------------------------------------------|\n| endpoint   | `string`                | Endpunkt der PROFFIX REST-API; z.B. ADR/Adresse,STU/Rapporte...                                          |\n| data       | `string`                | Daten (werden automatisch in JSON konvertiert)                                                           |\n| parameters | `Map\u003cString, dynamic\u003e?` | Parameter gemäss [PROFFIX REST API Docs](https://www.proffix.net/Portals/0/content/REST%20API/index.html) |\n\nFolgende unterschiedlichen Methoden sind mit dem Wrapper möglich:\n\n##### Get / Query\n\n```dart\n\n    var request =\n        await pxClient.get(endpoint: \"ADR/Adresse/1\", params: {\"Fields\": \"AdressNr\"});\n\n```\n\n##### Put / Update\n\n```dart\n\n    var request =\n        await pxClient.put(endpoint: \"ADR/Adresse/1\", {\n  \"Name\":   \"Muster GmbH\",\n  \"Ort\":    \"Zürich\",\n  \"Zürich\": \"8000\",\n });\n\n```\n\n##### Patch / Update\n\n```dart\n\n var request =\n        await pxClient.patch(endpoint: \"ADR/Adresse/1\", {\n  \"Name\":   \"Muster GmbH\",\n  \"Ort\":    \"Zürich\",\n  \"Zürich\": \"8000\",\n });\n\n```\n\n##### Post / Create\n\n```dart\n\n var request =\n        await pxClient.post(endpoint: \"ADR/Adresse/1\", {\n  \"Name\":   \"Muster GmbH\",\n  \"Ort\":    \"Zürich\",\n  \"Zürich\": \"8000\",\n });\n\n```\n\n##### Delete / Delete\n\n```dart\n\n  var request =\n        await pxClient.delete(endpoint: \"ADR/Adresse/1\");\n\n```\n\n#### Spezielle Endpunkte\n\n##### Check\n\nPrüft die Login - Credentials und gibt bei Fehlern eine Exception aus.\n\n```dart\n\n var check = await pxClient.check();\n\n // If statusCode = 200 -\u003e Success\n if(check.statusCode = 200){\n  print(\"OK\")\n// Else show exception\n } else {\n  print(check)\n }\n\n```\n\n##### Upload / Download File\n\nLädt eine Datei auf PRO/Datei hoch und gibt die DateiNr als String zurück\n\n```dart\n\n  // Upload File\n  final File file = File(\"_assets/dart-proffix.png\");\n\n  var bytes = file.readAsBytesSync();\n  var dataUpload = Uint8List.fromList(bytes);\n\n  var dateiNr = await pxClient.uploadFile(\"testDate.png\",dataUpload);\n\n  // Download File (again)\n  var fileAgain = await pxClient.downloadFile(dateiNr: dateiNr.toString());\n\n```\n\n##### Logout\n\nLoggt den Client von der PROFFIX REST-API aus und gibt die Session / Lizenz damit wieder frei. Zusätzlich wird der Dart Client geschlossen.\n\nAb dieser Version berücksichtigt der Client die PROFFIX Volumenlizenzierung (VOL):\n\n- Wenn die Volumenlizenz aktiv ist (Option `volumeLicence == true` oder das Modul `\"VOL\"` gesetzt ist), wird standardmässig **kein Logout** ausgeführt, da dies nicht erforderlich ist.\n- Mit dem Parameter `forceLogout: true` können Sie dennoch einen Logout erzwingen.\n- Mit `clearSessionCache: false` können Sie steuern, ob ein aktivierter Session-Cache beim Logout geleert werden soll (Standard: `true`).\n\nParameter der Methode `logout()`:\n\n- `forceLogout` (bool, default `false`): Erzwingt den Logout auch bei VOL.\n- `clearSessionCache` (bool, default `true`): Löscht bei aktivem Session-Caching die persistierte PxSessionId.\n\n```dart\n// Standard-Logout (bei VOL wird nichts gemacht)\nvar logoutResp = await pxClient.logout();\n\n// Logout erzwingen, auch wenn VOL aktiv ist\nvar forcedLogoutResp = await pxClient.logout(forceLogout: true);\n\n// Logout erzwingen, aber den Session-Cache behalten (z. B. zur Wiederverwendung)\nvar forcedLogoutKeepCache = await pxClient.logout(\n  forceLogout: true,\n  clearSessionCache: false,\n);\n```\n\nDer Wrapper führt den **Logout auch automatisch bei Fehlern** durch, damit keine Lizenz geblockt wird. Bei aktivem Session-Caching wird der Cache im Fehlerfall invalidiert und beim nächsten Request automatisch neu eingeloggt.\n\n##### getPxSessionId()\n\nGibt die aktuelle PxSessionId zurück\n\n```dart\n\n var pxSessionId = await pxClient.getPxSessionId();\n\n```\n\n##### setPxSessionId()\n\nSetzt die PxSessionId manuell\n\n**Hinweis:** Diese Methode wird nur für Servicelogins (z.b. via Extension oder Proffix WebView benötigt)\n\n```dart\n\n pxClient.setPxSessionId(\"99753429-9716-cf41-066a-8c98edc5e928\");\n\n```\n\n##### GET List\n\nGibt direkt die Liste der PROFFIX REST API aus (ohne Umwege)\n\n```dart\n\nvar list = await pxClient.getList(listeNr: 1232,data: {});\n\n```\n\n**Hinweis:** Der Dateityp (zurzeit nur PDF) kann über den Header `File-Type` ermittelt werden\\*\n\n#### Hilfsfunktionen\n\n##### convertPxTimeToTime\n\nKonvertiert einen Zeitstempel der PROFFIX REST-API in time.Time\n\n```dart\n\nvar tim = ProffixHelpers().convertPxTimeToTime('2004-04-11 00:00:00')\n\n```\n\n##### convertTimeToPxTime\n\nKonvertiert einen time.Time in einen Zeitstempel der PROFFIX REST-API\n\n```dart\n\n// Create DateTime from now\nvar timeNow = DateTime tmpDateTime = DateTime.now();\n\n// Convert to PxTime\nvar tm = ProffixHelpers().convertTimeToPxTime(timeNow);\n\n```\n\n##### convertLocationId\n\nExtrahiert die ID aus dem Header Location der PROFFIX REST-API\n\n```dart\n\n// Example Create Address\n  var postReq =\n        await tempClient.post(endpoint: \"ADR/Adresse\", data: {\n    \"Name\": \"Test\",\n    \"Vorname\": \"Rest\",\n    \"Ort\": \"Zürich\",\n    \"PLZ\": \"8000\",\n    \"Land\": {\"LandNr\": \"CH\"},\n  });\n\n  // Get LocationID from Header --\u003e returns newly created AdressNr from posted Address\n createdAdressNr = ProffixHelpers().convertLocationId(postReq.headers);\n\n```\n\n##### getFilteredCount\n\nExtrahiert die Anzahl Ergebnisse aus dem Header PxMetaData der PROFFIX REST-API\n\n```dart\n\n// Example Get Address with Filter PLZ == Münchwilen\n    var getReq = await tempClient.get(endpoint: \"ADR/Adresse\", params: {\n      \"Filter\": \"PLZ=='Münchwilen'\",\n      \"Fields\": \"AdressNr,Name,Vorname,Ort,PLZ\"\n    });\n\n  // Get FilteredCount from Header --\u003e returns the total amount of filtered Addresses\n countAddresses = ProffixHelpers().getFilteredCount(getReq.headers);\n\n```\n\n### Weitere Beispiele\n\nIm Ordner [/example](https://github.com/pitwch/dart_proffix_rest/tree/master/example) finden sich weitere,\nauskommentierte Beispiele.\n\n### Proof of Work\n\nDieser Wrapper wird **produktiv** mit allen pfx Apps - den [Apps für Proffix](https://pfx.ch) eingesetzt.\n\n\u003c!-- markdownlint-enable MD041 --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpitwch%2Fdart_proffix_rest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpitwch%2Fdart_proffix_rest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpitwch%2Fdart_proffix_rest/lists"}