lxw-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lxw_cli-0.1.0/.claude/scheduled_tasks.lock +1 -0
- lxw_cli-0.1.0/.env.example +6 -0
- lxw_cli-0.1.0/.gitattributes +2 -0
- lxw_cli-0.1.0/.github/workflows/publish.yml +39 -0
- lxw_cli-0.1.0/.github/workflows/test.yml +36 -0
- lxw_cli-0.1.0/.gitignore +40 -0
- lxw_cli-0.1.0/LICENSE +21 -0
- lxw_cli-0.1.0/PKG-INFO +403 -0
- lxw_cli-0.1.0/README.md +368 -0
- lxw_cli-0.1.0/docs/tui-screenshot.svg +177 -0
- lxw_cli-0.1.0/pyproject.toml +71 -0
- lxw_cli-0.1.0/src/lxw_cli/__init__.py +1 -0
- lxw_cli-0.1.0/src/lxw_cli/__main__.py +4 -0
- lxw_cli-0.1.0/src/lxw_cli/cli.py +207 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/__init__.py +0 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/_common.py +40 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/articles.py +110 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/contacts.py +215 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/delivery_notes.py +114 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/invoices.py +179 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/mcp.py +167 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/orders.py +117 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/quotations.py +117 -0
- lxw_cli-0.1.0/src/lxw_cli/commands/vouchers.py +121 -0
- lxw_cli-0.1.0/src/lxw_cli/config.py +235 -0
- lxw_cli-0.1.0/src/lxw_cli/core/__init__.py +10 -0
- lxw_cli-0.1.0/src/lxw_cli/core/client.py +200 -0
- lxw_cli-0.1.0/src/lxw_cli/core/constants.py +25 -0
- lxw_cli-0.1.0/src/lxw_cli/core/errors.py +19 -0
- lxw_cli-0.1.0/src/lxw_cli/core/models.py +30 -0
- lxw_cli-0.1.0/src/lxw_cli/core/services.py +598 -0
- lxw_cli-0.1.0/src/lxw_cli/mcp_server.py +367 -0
- lxw_cli-0.1.0/src/lxw_cli/output.py +191 -0
- lxw_cli-0.1.0/src/lxw_cli/tui/__init__.py +7 -0
- lxw_cli-0.1.0/src/lxw_cli/tui/app.py +391 -0
- lxw_cli-0.1.0/src/lxw_cli/tui/detail.py +220 -0
- lxw_cli-0.1.0/src/lxw_cli/tui/entities.py +174 -0
- lxw_cli-0.1.0/src/lxw_cli/tui/order_form.py +286 -0
- lxw_cli-0.1.0/tests/__init__.py +0 -0
- lxw_cli-0.1.0/tests/conftest.py +31 -0
- lxw_cli-0.1.0/tests/snapshots/contacts_flat.txt +7 -0
- lxw_cli-0.1.0/tests/snapshots/contacts_grouped.txt +14 -0
- lxw_cli-0.1.0/tests/snapshots/invoices_list.txt +5 -0
- lxw_cli-0.1.0/tests/test_cli.py +372 -0
- lxw_cli-0.1.0/tests/test_cli_snapshots.py +138 -0
- lxw_cli-0.1.0/tests/test_client.py +136 -0
- lxw_cli-0.1.0/tests/test_config.py +145 -0
- lxw_cli-0.1.0/tests/test_mcp_server.py +154 -0
- lxw_cli-0.1.0/tests/test_output.py +116 -0
- lxw_cli-0.1.0/tests/test_resolve.py +120 -0
- lxw_cli-0.1.0/tests/test_services.py +257 -0
- lxw_cli-0.1.0/tests/test_tui.py +622 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"sessionId":"89a7173f-ca25-480d-9741-339a7e21c739","pid":3945,"procStart":"Thu Jul 16 09:04:14 2026","acquiredAt":1784194733658}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- name: Install uv
|
|
14
|
+
uses: astral-sh/setup-uv@v5
|
|
15
|
+
|
|
16
|
+
- name: Build sdist + wheel
|
|
17
|
+
run: uv build
|
|
18
|
+
|
|
19
|
+
- uses: actions/upload-artifact@v4
|
|
20
|
+
with:
|
|
21
|
+
name: dist
|
|
22
|
+
path: dist/
|
|
23
|
+
|
|
24
|
+
publish:
|
|
25
|
+
needs: build
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
environment: pypi
|
|
28
|
+
# Trusted Publishing: kein API-Token nötig — auf pypi.org unter
|
|
29
|
+
# "Publishing" diesen Repo/Workflow als Trusted Publisher eintragen.
|
|
30
|
+
permissions:
|
|
31
|
+
id-token: write
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/download-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: dist
|
|
36
|
+
path: dist/
|
|
37
|
+
|
|
38
|
+
- name: Publish to PyPI
|
|
39
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
name: py${{ matrix.python-version }} · ${{ matrix.os }}
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
# --clear: setup-uv legt je nach Plattform bereits ein .venv an
|
|
28
|
+
run: |
|
|
29
|
+
uv venv --clear
|
|
30
|
+
uv pip install -e ".[dev]"
|
|
31
|
+
|
|
32
|
+
- name: Ruff
|
|
33
|
+
run: uv run --no-project ruff check src tests
|
|
34
|
+
|
|
35
|
+
- name: Pytest
|
|
36
|
+
run: uv run --no-project pytest -v
|
lxw_cli-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
.eggs/
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.coverage
|
|
12
|
+
htmlcov/
|
|
13
|
+
*.egg
|
|
14
|
+
|
|
15
|
+
# Virtual environments
|
|
16
|
+
.venv/
|
|
17
|
+
venv/
|
|
18
|
+
env/
|
|
19
|
+
|
|
20
|
+
# Environment files
|
|
21
|
+
.env
|
|
22
|
+
.env.local
|
|
23
|
+
|
|
24
|
+
# Claude Code (lokale Einstellungen)
|
|
25
|
+
.claude/settings.local.json
|
|
26
|
+
|
|
27
|
+
# IDE
|
|
28
|
+
.vscode/
|
|
29
|
+
.idea/
|
|
30
|
+
*.swp
|
|
31
|
+
*.swo
|
|
32
|
+
|
|
33
|
+
# OS
|
|
34
|
+
.DS_Store
|
|
35
|
+
Thumbs.db
|
|
36
|
+
|
|
37
|
+
# Downloads / Outputs
|
|
38
|
+
*.pdf
|
|
39
|
+
*.csv
|
|
40
|
+
!tests/**/*.csv
|
lxw_cli-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Markus Oeffling
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
lxw_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lxw-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Inoffizielles CLI/TUI/MCP-Tool für die Lexware Office API (vormals lexoffice)
|
|
5
|
+
Project-URL: Homepage, https://github.com/OEM-Mrks/lxw-cli
|
|
6
|
+
Project-URL: Documentation, https://developers.lexware.io/
|
|
7
|
+
Author: Markus Oeffling
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: api,cli,lexoffice,lexware,mcp,tui
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Office/Business :: Financial :: Accounting
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: fastmcp>=2.10
|
|
21
|
+
Requires-Dist: httpx>=0.27
|
|
22
|
+
Requires-Dist: pydantic>=2.6
|
|
23
|
+
Requires-Dist: python-dotenv>=1.0
|
|
24
|
+
Requires-Dist: rich>=13.7
|
|
25
|
+
Requires-Dist: tenacity>=8.2
|
|
26
|
+
Requires-Dist: textual>=0.58
|
|
27
|
+
Requires-Dist: typer>=0.12
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# lxw-cli
|
|
37
|
+
|
|
38
|
+
Ein Kommandozeilen-Tool für die [Lexware Office API](https://developers.lexware.io/) (vormals lexoffice). Liest Rechnungen, Kontakte, Belege, Artikel, Angebote, Aufträge und Lieferscheine — und legt Drafts neu an.
|
|
39
|
+
|
|
40
|
+
> **Hinweis:** Inoffizielles Community-Tool — kein Produkt der Haufe-Lexware
|
|
41
|
+
> GmbH & Co. KG und nicht mit ihr verbunden. „Lexware" ist eine Marke der
|
|
42
|
+
> Haufe Group.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- Zwei Frontends auf einem UI-freien Core: **CLI** (skriptbar) und **interaktive TUI** (`lxw` ohne Argumente)
|
|
47
|
+
- Lesen: `list` (paginiert + Filter), `get` (Detail), `pdf` (Download)
|
|
48
|
+
- Schreiben: `create-draft` für Belege (Rechnungen, Angebote, Aufträge, Lieferscheine, Belege), `create` für Stammdaten (Kontakte, Artikel)
|
|
49
|
+
- Paginierung: `--limit N`, `--all`/`-a` bzw. `--limit 0` für **alle** Treffer über alle Seiten
|
|
50
|
+
- Artikel-Volltextsuche: `articles list --search/-q` (Bezeichnung, Beschreibung, Teil-Artikelnummer)
|
|
51
|
+
- Kontakte: `--customer` / `--vendor` (nur Kunden/Lieferanten), optional `--grouped`
|
|
52
|
+
- Ausgabe: Tabelle (Rich), JSON (pipe-fähig), CSV, Datei-Output
|
|
53
|
+
- PDF-Download nach Datei **oder** Verzeichnis (Auto-Dateiname); `-o` optional
|
|
54
|
+
- Komfort: API-Key-Abfrage beim ersten Start, Warte-Animation bei längeren Abrufen
|
|
55
|
+
- Eingebauter Rate-Limit-Schutz (2 req/s) + automatische Retries auf 429/5xx
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
Läuft auf **macOS, Linux und Windows** (Python ≥ 3.11). Empfohlen als
|
|
60
|
+
isoliertes Tool mit [uv](https://docs.astral.sh/uv/) oder
|
|
61
|
+
[pipx](https://pipx.pypa.io/):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uv tool install lxw-cli # oder: pipx install lxw-cli
|
|
65
|
+
lxw profile
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Alternativ klassisch in ein Environment:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install lxw-cli
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Aus dem Quellcode (Entwicklung)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone https://github.com/OEM-Mrks/lxw-cli
|
|
78
|
+
cd lxw-cli
|
|
79
|
+
uv venv && source .venv/bin/activate
|
|
80
|
+
uv pip install -e ".[dev]"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## API-Key konfigurieren
|
|
84
|
+
|
|
85
|
+
Lege einen API-Key in deinem Lexware-Account an: <https://app.lexware.de/addons/public-api>
|
|
86
|
+
|
|
87
|
+
**Einfachste Variante:** Ruf `lxw` einfach auf. Findet das Tool keinen Key,
|
|
88
|
+
fragt es im Terminal danach, prüft ihn gegen die API und speichert ihn unter
|
|
89
|
+
`~/.config/lexware/.env` (Datei-Rechte `0600`, nur für dich lesbar; unter
|
|
90
|
+
Windows `%APPDATA%\lexware\.env`). Ab dann funktioniert `lxw` aus **jedem**
|
|
91
|
+
Verzeichnis, ohne weitere Einrichtung.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
lxw profile
|
|
95
|
+
# → Kein Lexware API-Key gefunden. Lexware API-Key: ********
|
|
96
|
+
# → ✓ API-Key gespeichert in ~/.config/lexware/.env — angemeldet als Acme GmbH
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Der Key wird in dieser Reihenfolge gesucht:
|
|
100
|
+
|
|
101
|
+
1. gesetzte Environment-Variable `LEXWARE_API_KEY`
|
|
102
|
+
2. projektlokale `.env` (vom aktuellen Verzeichnis aufwärts — praktisch für die Entwicklung)
|
|
103
|
+
3. globale `~/.config/lexware/.env` (bzw. `$XDG_CONFIG_HOME/lexware/.env`; unter Windows `%APPDATA%\lexware\.env`)
|
|
104
|
+
|
|
105
|
+
Wer es manuell vorziehen will, kann den Key auch direkt setzen:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
cp .env.example .env # projektlokal
|
|
109
|
+
# LEXWARE_API_KEY=… eintragen
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
In nicht-interaktiven Kontexten (Pipes, Cron, MCP-Server über stdio) wird **nicht**
|
|
113
|
+
gefragt — dort muss der Key vorab über eine der drei Quellen vorhanden sein.
|
|
114
|
+
|
|
115
|
+
## Quickstart
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Auth-Test: zeigt Firmenprofil
|
|
119
|
+
lxw profile
|
|
120
|
+
|
|
121
|
+
# Rechnungen (Tabelle) — Standard: 25 Einträge
|
|
122
|
+
lxw invoices list --limit 10
|
|
123
|
+
|
|
124
|
+
# ALLE Rechnungen laden (paginiert automatisch über alle Seiten)
|
|
125
|
+
lxw invoices list --all
|
|
126
|
+
lxw invoices list --limit 0 # gleichbedeutend
|
|
127
|
+
|
|
128
|
+
# Archivierte sind standardmäßig ausgeblendet — bei Bedarf einblenden
|
|
129
|
+
lxw invoices list --include-archived
|
|
130
|
+
lxw contacts list --include-archived
|
|
131
|
+
|
|
132
|
+
# Rechnungen als JSON in jq pipen
|
|
133
|
+
lxw --json invoices list --status open | jq '.[].voucherNumber'
|
|
134
|
+
|
|
135
|
+
# CSV-Export von Kunden
|
|
136
|
+
lxw --csv --output kunden.csv contacts list --customer --limit 200
|
|
137
|
+
|
|
138
|
+
# Artikel suchen — Teiltreffer in Bezeichnung, Beschreibung und Artikelnummer
|
|
139
|
+
lxw articles list --search "schraube"
|
|
140
|
+
lxw articles list -q "SCH-" # auch Teil-Artikelnummern
|
|
141
|
+
lxw articles list --number SCH-001 # exakte Artikelnummer (serverseitig, schnell)
|
|
142
|
+
|
|
143
|
+
# Rechnung per Belegnummer abrufen (UUID auch möglich)
|
|
144
|
+
lxw invoices get FB2600682
|
|
145
|
+
lxw --json invoices get FB2600682 | jq '.totalGrossAmount'
|
|
146
|
+
|
|
147
|
+
# PDF einer Rechnung herunterladen (UUID oder Belegnummer)
|
|
148
|
+
lxw invoices pdf FB2600682 # → ./invoice-FB2600682.pdf
|
|
149
|
+
lxw invoices pdf FB2600682 --output ~/Rechnungen # Verzeichnis: Dateiname automatisch
|
|
150
|
+
lxw invoices pdf FB2600682 --output rechnung.pdf # exakter Dateipfad
|
|
151
|
+
|
|
152
|
+
# Kontakt anlegen (Stammdaten — kein Draft)
|
|
153
|
+
lxw contacts create --body '{
|
|
154
|
+
"roles": {"customer": {}},
|
|
155
|
+
"company": {"name": "Test GmbH"}
|
|
156
|
+
}'
|
|
157
|
+
|
|
158
|
+
# Komplexere Bodies aus Datei
|
|
159
|
+
lxw invoices create-draft --body @invoice-template.json
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Verfügbare Befehle
|
|
163
|
+
|
|
164
|
+
| Befehl | Zweck |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `lxw profile` | Firmenprofil abrufen (Auth-Test) |
|
|
167
|
+
| `lxw invoices` | Rechnungen: `list`, `get`, `pdf`, `create-draft` |
|
|
168
|
+
| `lxw contacts` | Kontakte: `list`, `get`, `create` |
|
|
169
|
+
| `lxw vouchers` | Belege: `list`, `get`, `create-draft` |
|
|
170
|
+
| `lxw articles` | Artikel: `list`, `get`, `create` (mit Volltextsuche) |
|
|
171
|
+
| `lxw quotations` | Angebote: `list`, `get`, `pdf`, `create-draft` |
|
|
172
|
+
| `lxw orders` | Aufträge (Auftragsbestätigungen): `list`, `get`, `pdf`, `create-draft` |
|
|
173
|
+
| `lxw delivery-notes` | Lieferscheine: `list`, `get`, `pdf`, `create-draft` |
|
|
174
|
+
|
|
175
|
+
Hinweis: `create-draft` legt **Belege** als Entwurf an (Draft, nicht finalisiert);
|
|
176
|
+
**Stammdaten** (Kontakte, Artikel) kennen keinen Draft-Status und werden mit
|
|
177
|
+
`create` direkt angelegt.
|
|
178
|
+
|
|
179
|
+
Detail-Hilfe mit `lxw <command> --help` bzw. `lxw <command> list --help`.
|
|
180
|
+
|
|
181
|
+
## Suchen, Filtern & Paginierung
|
|
182
|
+
|
|
183
|
+
Alle `list`-Befehle teilen sich dasselbe Paginierungs-Verhalten und besitzen
|
|
184
|
+
befehlsspezifische Filter. Intern wird serverseitig seitenweise abgerufen —
|
|
185
|
+
immer mit dem API-Maximum von 250 Datensätzen/Request (mit Rate-Limit-Schutz),
|
|
186
|
+
damit so wenige Requests wie möglich nötig sind.
|
|
187
|
+
|
|
188
|
+
### Menge: --limit und --all (für jeden `list`-Befehl)
|
|
189
|
+
|
|
190
|
+
| Option | Wirkung |
|
|
191
|
+
|---|---|
|
|
192
|
+
| `--limit N`, `-n N` | Maximal N Einträge (Standard: 25). |
|
|
193
|
+
| `--limit 0` | Unbegrenzt — lädt **alle** Treffer über alle Seiten. |
|
|
194
|
+
| `--all`, `-a` | Wie `--limit 0`; überschreibt ein gesetztes `--limit`. |
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
lxw invoices list --all # alle Rechnungen
|
|
198
|
+
lxw contacts list --customer -a # alle Kunden
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Am Listenende wird die **Gesamtzahl** der Datensätze ausgegeben (aus dem
|
|
202
|
+
`totalElements` der API) — z.B. `→ 25 von 1234 Rechnungen angezeigt (mehr mit
|
|
203
|
+
--all)` bzw. `→ 1234 Kontakte gesamt`, wenn alles geladen wurde. Diese Zeile geht
|
|
204
|
+
auf **stderr**, stört also `--json`/`--csv`-Pipes nicht. Bei der clientseitigen
|
|
205
|
+
Artikelsuche wird stattdessen die Trefferzahl gezeigt (`→ 12 Treffer`).
|
|
206
|
+
|
|
207
|
+
### Befehlsspezifische Filter
|
|
208
|
+
|
|
209
|
+
| Befehl | Filter-Optionen |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `invoices list` | `--status`, `--number` (exakt), `--contact-id`, `--include-archived` |
|
|
212
|
+
| `vouchers list` | `--type`, `--status`, `--number` (exakt), `--contact-id`, `--include-archived` |
|
|
213
|
+
| `contacts list` | `--name` (≥3 Z.), `--email` (≥3 Z.), `--number`, `--customer`, `--vendor`, `--grouped/--flat`, `--include-archived` |
|
|
214
|
+
| `articles list` | `--search`/`-q` (Volltext), `--number` (exakt), `--type product\|service`, `--gtin` (exakt) |
|
|
215
|
+
| `quotations list` | `--status`, `--include-archived` |
|
|
216
|
+
| `orders list` | `--status`, `--include-archived` |
|
|
217
|
+
| `delivery-notes list` | `--status`, `--include-archived` |
|
|
218
|
+
|
|
219
|
+
`--status` und `--type` sind komma-separiert (z.B. `--status open,paid`).
|
|
220
|
+
|
|
221
|
+
### Archivierte ausblenden (Standard)
|
|
222
|
+
|
|
223
|
+
Archivierte Datensätze werden bei **Belegen** (Rechnungen, Belege, Angebote,
|
|
224
|
+
Lieferscheine) **und Kontakten** standardmäßig ausgeblendet — `--include-archived`
|
|
225
|
+
zeigt sie. Bei Belegen filtert die API serverseitig (`archived=false`), die
|
|
226
|
+
Gesamtzahl bleibt also exakt; bei Kontakten geschieht es clientseitig (siehe
|
|
227
|
+
unten). Der Footer weist mit `· ohne archivierte (--include-archived zeigt alle)`
|
|
228
|
+
darauf hin.
|
|
229
|
+
|
|
230
|
+
### Kontakte: nur Kunden oder nur Lieferanten
|
|
231
|
+
|
|
232
|
+
`contacts list` liefert standardmäßig **eine zusammenhängende Liste** (nicht
|
|
233
|
+
getrennt — gut für Pipes und Weiterverarbeitung durch LLMs). Auf Wunsch nur eine
|
|
234
|
+
Rolle oder optional gruppiert:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
lxw contacts list # aktive Kontakte, eine Liste
|
|
238
|
+
lxw contacts list --customer # nur Kunden (serverseitig gefiltert)
|
|
239
|
+
lxw contacts list --vendor # nur Lieferanten (serverseitig gefiltert)
|
|
240
|
+
lxw contacts list --grouped # Tabelle in Kunden-/Lieferanten-Abschnitte
|
|
241
|
+
lxw contacts list --include-archived # archivierte Kontakte einblenden
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Bei `--grouped` zeigt jede Tabelle die passende Kunden- bzw. Lieferantennummer;
|
|
245
|
+
Kontakte mit beiden Rollen erscheinen in beiden Abschnitten (`role`-Spalte =
|
|
246
|
+
`customer+vendor`). `--json` und `--csv` sind immer eine flache Liste mit
|
|
247
|
+
`role`-Spalte.
|
|
248
|
+
|
|
249
|
+
**Archivierte Kontakte** werden standardmäßig ausgeblendet — `--include-archived`
|
|
250
|
+
zeigt sie wieder. Da die Kontakt-API archivierte nicht serverseitig filtern kann,
|
|
251
|
+
geschieht das clientseitig: `lxw` blättert durch die Seiten und überspringt
|
|
252
|
+
archivierte, bis genug aktive für das `--limit` zusammen sind. Der Footer zeigt
|
|
253
|
+
dann z.B. `→ 298 aktive Kontakte gesamt (14 archivierte ausgeblendet)`.
|
|
254
|
+
|
|
255
|
+
### Artikel-Volltextsuche: --search / -q
|
|
256
|
+
|
|
257
|
+
Die Lexware-API filtert Artikel serverseitig **nur exakt** (`--number`, `--gtin`,
|
|
258
|
+
`--type`). Für unscharfe Suche nach **Bezeichnung, Beschreibung oder
|
|
259
|
+
Teil-Artikelnummer** gibt es `--search`/`-q` — dabei werden Artikel clientseitig
|
|
260
|
+
durchsucht (Teiltreffer, Groß-/Kleinschreibung egal):
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
lxw articles list -q "schraube" # Bezeichnung/Beschreibung
|
|
264
|
+
lxw articles list -q "SCH-" # Teil-Artikelnummer
|
|
265
|
+
lxw articles list --number SCH-001 # exakte Nummer (serverseitig, schnell)
|
|
266
|
+
lxw articles list -q "kabel" --type product --all # kombinierbar
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Hinweis: `--search` scannt im Zweifel alle Artikel (bricht ab, sobald genug
|
|
270
|
+
Treffer für `--limit` gefunden sind). Bei sehr großen Beständen entsprechend
|
|
271
|
+
langsamer als die exakten Server-Filter.
|
|
272
|
+
|
|
273
|
+
## Globale Optionen
|
|
274
|
+
|
|
275
|
+
| Flag | Zweck |
|
|
276
|
+
|---|---|
|
|
277
|
+
| `--json` | JSON-Ausgabe (für Pipelines) |
|
|
278
|
+
| `--csv` | CSV-Ausgabe |
|
|
279
|
+
| `--output PATH`, `-o` | In Datei statt stdout schreiben |
|
|
280
|
+
| `--version`, `-V` | Version anzeigen |
|
|
281
|
+
|
|
282
|
+
## Interaktive TUI
|
|
283
|
+
|
|
284
|
+
Neben der CLI gibt es eine **Terminal-UI** zum Durchstöbern deiner Daten
|
|
285
|
+
(Rechnungen, Kontakte, Belege, Artikel, Angebote, Aufträge, Lieferscheine) —
|
|
286
|
+
und zum Anlegen neuer Aufträge als Entwurf.
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
lxw # ohne Argumente im Terminal → TUI startet automatisch
|
|
290
|
+
lxw-tui # oder explizit
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+

|
|
294
|
+
|
|
295
|
+
- Links die Entitäten wählen (Pfeile + Enter), rechts die Liste; **Enter** auf
|
|
296
|
+
einer Zeile öffnet die Detailansicht, **Esc** schließt sie.
|
|
297
|
+
- Die Detailansicht zeigt die Felder **menschenlesbar** (deutsche Feldnamen,
|
|
298
|
+
Datumsangaben als TT.MM.JJJJ, ja/nein, verschachtelte Strukturen als Pfad wie
|
|
299
|
+
*Adressen › Rechnungsadresse › Ort*). Mit **j** wechselt man jederzeit auf das
|
|
300
|
+
**rohe JSON** der API und zurück.
|
|
301
|
+
- Tastenkürzel: **Tab** Fokus wechseln · **r** aktualisieren · **n** neuer
|
|
302
|
+
Auftrag · **m** mehr laden · **/** suchen · **q** beenden (immer als Leiste
|
|
303
|
+
unten sichtbar).
|
|
304
|
+
- **Paginierung**: Jede Liste lädt zunächst eine volle API-Seite (250
|
|
305
|
+
Datensätze — das Server-Maximum pro Request). Scrollt man auf die letzte
|
|
306
|
+
Zeile (oder drückt **m**), wird automatisch der nächste Schwung nachgeladen;
|
|
307
|
+
die Cursor-Position bleibt erhalten. Die Statuszeile zeigt den Stand, z.B.
|
|
308
|
+
`250 von 1234 Rechnungen — ans Ende scrollen oder m lädt mehr`.
|
|
309
|
+
- **Suchen** (**/**): öffnet eine Suchleiste über der Tabelle. **Tippen
|
|
310
|
+
filtert sofort** die bereits geladenen Zeilen (clientseitig, über alle
|
|
311
|
+
sichtbaren Spalten). **Enter sucht über die API** — bei Kontakten per Name
|
|
312
|
+
bzw. E-Mail (enthält die Eingabe ein `@`, wird die E-Mail-Suche verwendet;
|
|
313
|
+
min. 3 Zeichen), bei Artikeln per Volltextsuche. In den API-Treffern kann
|
|
314
|
+
anschließend weiter lokal gefiltert werden. **Esc** schließt die Suche und
|
|
315
|
+
stellt die normale Liste wieder her.
|
|
316
|
+
- **Auftrag anlegen** (**n**): Kunde per Namenssuche wählen, Artikel suchen und
|
|
317
|
+
mit Menge und (editierbarem) Netto-Einzelpreis als Positionen hinzufügen —
|
|
318
|
+
der Preis wird aus dem Artikel vorbelegt und kann vor dem Hinzufügen
|
|
319
|
+
überschrieben werden. Optional Einleitungs- und Schlusstext eintragen, dann
|
|
320
|
+
*„Auftrag anlegen"* — der Auftrag wird als **Entwurf** gespeichert und die
|
|
321
|
+
Auftragsliste geöffnet. Während Suchen und Anlegen laufen, zeigt das Formular
|
|
322
|
+
eine Lade-Animation. Finalisieren/Versenden bleibt bewusst der Lexware-UI
|
|
323
|
+
vorbehalten.
|
|
324
|
+
- Firmenname oben = Verbindungstest; Fehler aus der API werden als Hinweis und
|
|
325
|
+
in der Statuszeile angezeigt (nie verschluckt).
|
|
326
|
+
|
|
327
|
+
Die TUI startet **nur im interaktiven Terminal**. Sobald `lxw` mit
|
|
328
|
+
Argumenten aufgerufen wird oder die Ausgabe in eine Pipe/Datei geht, verhält es
|
|
329
|
+
sich unverändert wie die CLI — Skripte und `… | jq` bleiben also unberührt.
|
|
330
|
+
|
|
331
|
+
Technisch spricht die TUI ausschließlich den UI-freien Core (`lxw_cli.core`)
|
|
332
|
+
— exakt dieselbe API wie CLI und MCP-Server.
|
|
333
|
+
|
|
334
|
+
## Claude-Integration (MCP-Server)
|
|
335
|
+
|
|
336
|
+
Das CLI bringt einen eingebauten MCP-Server mit, mit dem **Claude Code** (und Claude Desktop) deine Lexware-Daten direkt abfragen kann.
|
|
337
|
+
|
|
338
|
+
### Setup in einem Schritt
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
lxw mcp install-claude
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Das registriert den Server bei Claude Code (Scope `user`, also für alle Projekte). Der API-Key wird dabei **nicht** an Claude übergeben — der Server liest ihn selbst aus `~/.config/lexware/.env` (chmod 600); falls er dort noch fehlt, legt `install-claude` ihn einmalig ab. Danach:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
claude mcp list # 'lexware' muss in der Liste erscheinen
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Öffne Claude Code in einem Projekt und frag z.B.:
|
|
351
|
+
|
|
352
|
+
> *"Wie viele offene Rechnungen habe ich?"*
|
|
353
|
+
> *"Lade die PDF von Rechnung FB2600682 herunter."*
|
|
354
|
+
> *"Zeig mir alle Kunden, deren Name mit 'A' anfängt."*
|
|
355
|
+
|
|
356
|
+
Claude erkennt die Tools automatisch und ruft sie auf.
|
|
357
|
+
|
|
358
|
+
### Verfügbare MCP-Tools
|
|
359
|
+
|
|
360
|
+
26 Tools mit identischem Verhalten wie die CLI-Befehle:
|
|
361
|
+
|
|
362
|
+
- **Lesen**: `profile`, `list_invoices`, `get_invoice`, `download_invoice_pdf`, `list_contacts`, `get_contact`, `list_vouchers`, `get_voucher`, `list_articles`, `get_article`, `list_quotations`, `get_quotation`, `download_quotation_pdf`, `list_order_confirmations`, `get_order_confirmation`, `download_order_confirmation_pdf`, `list_delivery_notes`, `get_delivery_note`, `download_delivery_note_pdf`
|
|
363
|
+
- **Belege als Draft anlegen**: `create_invoice_draft`, `create_voucher_draft`, `create_quotation_draft`, `create_order_confirmation_draft`, `create_delivery_note_draft`
|
|
364
|
+
- **Stammdaten anlegen** (kein Draft): `create_contact`, `create_article`
|
|
365
|
+
|
|
366
|
+
Alle document-Tools (`get_*`, `download_*_pdf`) akzeptieren UUID **oder** Belegnummer (z.B. `FB2600682`). PDFs landen in `~/Downloads/lexware/`.
|
|
367
|
+
|
|
368
|
+
Die `list_*`-Tools bieten dieselben Optionen wie die CLI:
|
|
369
|
+
|
|
370
|
+
- `limit` begrenzt die Trefferzahl; `limit=0` lädt **alle** (paginiert intern).
|
|
371
|
+
- `list_articles` hat `search` für die Volltextsuche (Bezeichnung/Beschreibung/Teil-Artikelnummer) zusätzlich zum exakten `article_number`.
|
|
372
|
+
- `list_contacts` filtert mit `customer` / `vendor` nach Rolle.
|
|
373
|
+
- Belege-Tools (`list_invoices`, `list_vouchers`, `list_quotations`, `list_delivery_notes`) und `list_contacts` blenden archivierte standardmäßig aus; `include_archived=true` zeigt sie.
|
|
374
|
+
|
|
375
|
+
### Weitere mcp-Befehle
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
lxw mcp status # zeigt aktuelle Registrierung
|
|
379
|
+
lxw mcp install-claude --force # Re-Install (z.B. nach API-Key-Wechsel)
|
|
380
|
+
lxw mcp uninstall-claude # entfernen
|
|
381
|
+
lxw mcp serve # läuft direkt — wird von Claude Code intern aufgerufen
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Out of Scope (v1)
|
|
385
|
+
|
|
386
|
+
Bewusst nicht enthalten:
|
|
387
|
+
|
|
388
|
+
- Finalisierung von Rechnungen (`/finalize`)
|
|
389
|
+
- Stornierungen / Credit Notes als eigene Workflows
|
|
390
|
+
- Webhooks / Event-Subscriptions
|
|
391
|
+
- Multi-Account-Profile (nutze stattdessen verschiedene `.env`-Dateien)
|
|
392
|
+
|
|
393
|
+
## Entwicklung
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
uv pip install -e ".[dev]"
|
|
397
|
+
pytest -v
|
|
398
|
+
ruff check src tests
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Lizenz
|
|
402
|
+
|
|
403
|
+
MIT
|