gaeb 0.5.2__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.
- gaeb-0.5.2/PKG-INFO +180 -0
- gaeb-0.5.2/README.md +149 -0
- gaeb-0.5.2/pyproject.toml +51 -0
- gaeb-0.5.2/src/gaeb/__init__.py +84 -0
- gaeb-0.5.2/src/gaeb/builder.py +307 -0
- gaeb-0.5.2/src/gaeb/diff.py +208 -0
- gaeb-0.5.2/src/gaeb/io/__init__.py +0 -0
- gaeb-0.5.2/src/gaeb/io/excel/__init__.py +0 -0
- gaeb-0.5.2/src/gaeb/io/excel/reader.py +222 -0
- gaeb-0.5.2/src/gaeb/io/excel/writer.py +261 -0
- gaeb-0.5.2/src/gaeb/io/gaeb2000/__init__.py +0 -0
- gaeb-0.5.2/src/gaeb/io/gaeb2000/reader.py +256 -0
- gaeb-0.5.2/src/gaeb/io/gaeb2000/writer.py +196 -0
- gaeb-0.5.2/src/gaeb/io/gaeb90/__init__.py +0 -0
- gaeb-0.5.2/src/gaeb/io/gaeb90/reader.py +389 -0
- gaeb-0.5.2/src/gaeb/io/gaeb90/writer.py +224 -0
- gaeb-0.5.2/src/gaeb/io/utils.py +31 -0
- gaeb-0.5.2/src/gaeb/io/xml/__init__.py +0 -0
- gaeb-0.5.2/src/gaeb/io/xml/reader.py +396 -0
- gaeb-0.5.2/src/gaeb/io/xml/validator.py +131 -0
- gaeb-0.5.2/src/gaeb/io/xml/writer.py +516 -0
- gaeb-0.5.2/src/gaeb/models/__init__.py +20 -0
- gaeb-0.5.2/src/gaeb/models/enums.py +51 -0
- gaeb-0.5.2/src/gaeb/models/lv.py +300 -0
- gaeb-0.5.2/src/gaeb/models/preisspiegel.py +79 -0
- gaeb-0.5.2/src/gaeb/models/raumbuch.py +95 -0
- gaeb-0.5.2/src/gaeb/py.typed +0 -0
gaeb-0.5.2/PKG-INFO
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: gaeb
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Summary: Python library for reading, writing, converting and diffing GAEB files (AVA data exchange format, DA XML 2.0–3.3, GAEB 90, GAEB 2000)
|
|
5
|
+
Keywords: gaeb,ava,construction,leistungsverzeichnis,bau,gaeb90,gaeb2000,xml,excel,diff
|
|
6
|
+
Author: Attackwave
|
|
7
|
+
Author-email: Attackwave <attackwave@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Office/Business
|
|
18
|
+
Requires-Dist: pydantic>=2.0
|
|
19
|
+
Requires-Dist: lxml>=4.9.4
|
|
20
|
+
Requires-Dist: pytest>=7.0 ; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest-cov>=4.0 ; extra == 'dev'
|
|
22
|
+
Requires-Dist: openpyxl>=3.1 ; extra == 'excel'
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Project-URL: Homepage, https://github.com/Attackwave/gaeb-python
|
|
25
|
+
Project-URL: Repository, https://github.com/Attackwave/gaeb-python
|
|
26
|
+
Project-URL: Issues, https://github.com/Attackwave/gaeb-python/issues
|
|
27
|
+
Project-URL: Changelog, https://github.com/Attackwave/gaeb-python/blob/main/CHANGELOG.md
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Provides-Extra: excel
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# gaeb
|
|
33
|
+
|
|
34
|
+
Python-Bibliothek zum Lesen, Schreiben, Konvertieren und Vergleichen von **GAEB-Dateien** (AVA – Ausschreibung, Vergabe, Abrechnung im deutschen Bauwesen).
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- **GAEB DA XML 2.0–3.3** lesen und schreiben (automatische Versionserkennung, Multi-Version Writer)
|
|
39
|
+
- **GAEB 90** lesen und schreiben (`.d80`–`.d89`; Encoding-Autoerkennung)
|
|
40
|
+
- **GAEB 2000** lesen und schreiben (`.p80`–`.p89`)
|
|
41
|
+
- **Alle Austauschphasen**: Mengenermittlung (31), Kostenermittlung (50–52), Vergabe (80–89, 83Z, 84Z, 86ZR, 86ZE), Handel/Handwerk (93–97)
|
|
42
|
+
- **BoQ Builder**: programmatischer LV-Aufbau mit Auto-OZ-Generierung und Fluent API
|
|
43
|
+
- **Excel-Export** (.xlsx) mit Hierarchie-Layout — optional via `pip install gaeb[excel]`
|
|
44
|
+
- **Document Diff**: zwei LVs vergleichen, alle Felder prüfen, finanzielle Auswirkungen berechnen
|
|
45
|
+
- **XSD-Validierung** gegen offizielle GAEB-Schemas (Phasen 80–87)
|
|
46
|
+
- **Preisspiegel- & Raumbuch-Modell** für Angebotsvergleiche und räumliche Zuordnung
|
|
47
|
+
- **Security-Hardened**: XXE-Prevention, Billion-Laughs-Schutz, Dateigrössen-Limit, Rekursionstiefenbegrenzung
|
|
48
|
+
- Einheitliches **Pydantic v2** Datenmodell für alle Formate
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install gaeb
|
|
54
|
+
|
|
55
|
+
# Mit Excel-Export
|
|
56
|
+
pip install gaeb[excel]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Schnellstart
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
import gaeb
|
|
63
|
+
|
|
64
|
+
# Lesen
|
|
65
|
+
lv = gaeb.read_xml("ausschreibung.x83")
|
|
66
|
+
lv = gaeb.read_gaeb90("ausschreibung.d83")
|
|
67
|
+
lv = gaeb.read_gaeb2000("ausschreibung.p83")
|
|
68
|
+
|
|
69
|
+
# Metadaten
|
|
70
|
+
print(lv.titel_lv) # LV-Titel
|
|
71
|
+
print(lv.phase) # Phase.ANGEBOTSAUFFORDERUNG
|
|
72
|
+
print(lv.xml_version) # "3.3" (nur bei DA XML)
|
|
73
|
+
print(lv.encoding) # "cp850" (nur bei GAEB 90 / 2000)
|
|
74
|
+
print(lv.gesamtsumme) # Decimal oder None
|
|
75
|
+
|
|
76
|
+
# Positionen
|
|
77
|
+
for pos in lv.alle_positionen:
|
|
78
|
+
print(pos.oz, pos.kurztext, pos.menge, pos.einheit)
|
|
79
|
+
|
|
80
|
+
# Schreiben / Konvertieren
|
|
81
|
+
gaeb.write_xml(lv, "ausgabe.x83")
|
|
82
|
+
gaeb.write_xml(lv, "ausgabe_v32.x83", version="3.2") # explizite Version
|
|
83
|
+
gaeb.write_gaeb90(lv, "ausgabe.d83")
|
|
84
|
+
gaeb.write_gaeb2000(lv, "ausgabe.p83")
|
|
85
|
+
|
|
86
|
+
# Excel-Export
|
|
87
|
+
gaeb.write_excel(lv, "ausgabe.xlsx")
|
|
88
|
+
gaeb.write_excel(lv, "ausgabe.xlsx", langtext=True)
|
|
89
|
+
|
|
90
|
+
# Zwei LVs vergleichen
|
|
91
|
+
lv_neu = gaeb.read_xml("angebot.x84")
|
|
92
|
+
result = gaeb.vergleiche(lv, lv_neu)
|
|
93
|
+
|
|
94
|
+
print(result.nur_in_alt) # gelöschte OZ-Nummern
|
|
95
|
+
print(result.nur_in_neu) # neue OZ-Nummern
|
|
96
|
+
for pa in result.geaendert:
|
|
97
|
+
print(pa.oz, pa.aenderungen)
|
|
98
|
+
print(result.gesamtsumme_diff) # finanzielle Differenz
|
|
99
|
+
|
|
100
|
+
# XSD-Validierung
|
|
101
|
+
fehler = gaeb.validiere("ausschreibung.x83")
|
|
102
|
+
if fehler:
|
|
103
|
+
print(fehler)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## BoQ Builder
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
import gaeb
|
|
110
|
+
|
|
111
|
+
lv = (
|
|
112
|
+
gaeb.BoQBuilder(
|
|
113
|
+
phase=gaeb.Phase.ANGEBOTSAUFFORDERUNG,
|
|
114
|
+
titel_lv="Hochwasserschutz",
|
|
115
|
+
projekt="Testprojekt",
|
|
116
|
+
)
|
|
117
|
+
.titel("Erdarbeiten")
|
|
118
|
+
.position("Bodenaushub", einheit="m³", menge=250, ep="12.50")
|
|
119
|
+
.position("Bodentransport", einheit="m³", menge=250, ep="8.00")
|
|
120
|
+
.ende()
|
|
121
|
+
.titel("Betonarbeiten")
|
|
122
|
+
.untertitel("Fundamente")
|
|
123
|
+
.position("Streifenfundament", einheit="m³", menge=30, ep="185.00")
|
|
124
|
+
.ende()
|
|
125
|
+
.ende()
|
|
126
|
+
.build()
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
gaeb.write_xml(lv, "ausschreibung.x83")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
OZ-Generierung basiert auf dem `BoQBkdn`-Schema (Standard: 2+2+4 Zeichen):
|
|
133
|
+
- Titel: `01`, `02`, …
|
|
134
|
+
- Untertitel: `0101`, `0102`, …
|
|
135
|
+
- Position: `01000001`, `01010001`, …
|
|
136
|
+
|
|
137
|
+
## Datenmodell
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
Leistungsverzeichnis
|
|
141
|
+
├── phase: Phase
|
|
142
|
+
├── titel_lv, projekt, auftraggeber, auftragnehmer
|
|
143
|
+
├── waehrung, xml_version, encoding
|
|
144
|
+
├── vorbemerkungen: list[str]
|
|
145
|
+
├── zeitvertrag_typ: str | None
|
|
146
|
+
├── boq_bkdn: list[BoQBkdn]
|
|
147
|
+
├── gesamtsumme: Decimal | None (property)
|
|
148
|
+
└── titel: list[Titel]
|
|
149
|
+
├── nummer, kurztext, langtext
|
|
150
|
+
├── positionen: list[Position]
|
|
151
|
+
│ ├── oz, kurztext, langtext
|
|
152
|
+
│ ├── menge, einheit, einheitspreis
|
|
153
|
+
│ ├── gesamtpreis (property: menge × EP)
|
|
154
|
+
│ ├── gesamtbetrag, mwst, nachlass_prozent
|
|
155
|
+
│ ├── pauschale, entfaellt, nicht_angeboten
|
|
156
|
+
│ ├── stundenlohn, schwerpunkt, provis
|
|
157
|
+
│ ├── typ: PositionTyp
|
|
158
|
+
│ ├── aln_gruppe, aln_nummer, ep_anteile
|
|
159
|
+
│ └── periodqty, min_menge, max_menge (Z-Phasen)
|
|
160
|
+
└── untertitel: list[Titel] (rekursiv)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Unterstützte Phasen
|
|
164
|
+
|
|
165
|
+
| Bereich | Phasen |
|
|
166
|
+
|---------|--------|
|
|
167
|
+
| Mengenermittlung | 31 |
|
|
168
|
+
| Kostenermittlung | 50, 51, 52 |
|
|
169
|
+
| Vergabe (Procurement) | 80–89, 83Z, 84Z, 86ZR, 86ZE |
|
|
170
|
+
| Handel / Handwerk | 93–97 |
|
|
171
|
+
|
|
172
|
+
## Optionale Abhängigkeiten
|
|
173
|
+
|
|
174
|
+
| Extra | Paket | Feature |
|
|
175
|
+
|-------|-------|---------|
|
|
176
|
+
| `gaeb[excel]` | openpyxl ≥ 3.1 | Excel-Export (.xlsx) |
|
|
177
|
+
|
|
178
|
+
## Lizenz
|
|
179
|
+
|
|
180
|
+
MIT – siehe [LICENSE](../LICENSE)
|
gaeb-0.5.2/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# gaeb
|
|
2
|
+
|
|
3
|
+
Python-Bibliothek zum Lesen, Schreiben, Konvertieren und Vergleichen von **GAEB-Dateien** (AVA – Ausschreibung, Vergabe, Abrechnung im deutschen Bauwesen).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **GAEB DA XML 2.0–3.3** lesen und schreiben (automatische Versionserkennung, Multi-Version Writer)
|
|
8
|
+
- **GAEB 90** lesen und schreiben (`.d80`–`.d89`; Encoding-Autoerkennung)
|
|
9
|
+
- **GAEB 2000** lesen und schreiben (`.p80`–`.p89`)
|
|
10
|
+
- **Alle Austauschphasen**: Mengenermittlung (31), Kostenermittlung (50–52), Vergabe (80–89, 83Z, 84Z, 86ZR, 86ZE), Handel/Handwerk (93–97)
|
|
11
|
+
- **BoQ Builder**: programmatischer LV-Aufbau mit Auto-OZ-Generierung und Fluent API
|
|
12
|
+
- **Excel-Export** (.xlsx) mit Hierarchie-Layout — optional via `pip install gaeb[excel]`
|
|
13
|
+
- **Document Diff**: zwei LVs vergleichen, alle Felder prüfen, finanzielle Auswirkungen berechnen
|
|
14
|
+
- **XSD-Validierung** gegen offizielle GAEB-Schemas (Phasen 80–87)
|
|
15
|
+
- **Preisspiegel- & Raumbuch-Modell** für Angebotsvergleiche und räumliche Zuordnung
|
|
16
|
+
- **Security-Hardened**: XXE-Prevention, Billion-Laughs-Schutz, Dateigrössen-Limit, Rekursionstiefenbegrenzung
|
|
17
|
+
- Einheitliches **Pydantic v2** Datenmodell für alle Formate
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install gaeb
|
|
23
|
+
|
|
24
|
+
# Mit Excel-Export
|
|
25
|
+
pip install gaeb[excel]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Schnellstart
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import gaeb
|
|
32
|
+
|
|
33
|
+
# Lesen
|
|
34
|
+
lv = gaeb.read_xml("ausschreibung.x83")
|
|
35
|
+
lv = gaeb.read_gaeb90("ausschreibung.d83")
|
|
36
|
+
lv = gaeb.read_gaeb2000("ausschreibung.p83")
|
|
37
|
+
|
|
38
|
+
# Metadaten
|
|
39
|
+
print(lv.titel_lv) # LV-Titel
|
|
40
|
+
print(lv.phase) # Phase.ANGEBOTSAUFFORDERUNG
|
|
41
|
+
print(lv.xml_version) # "3.3" (nur bei DA XML)
|
|
42
|
+
print(lv.encoding) # "cp850" (nur bei GAEB 90 / 2000)
|
|
43
|
+
print(lv.gesamtsumme) # Decimal oder None
|
|
44
|
+
|
|
45
|
+
# Positionen
|
|
46
|
+
for pos in lv.alle_positionen:
|
|
47
|
+
print(pos.oz, pos.kurztext, pos.menge, pos.einheit)
|
|
48
|
+
|
|
49
|
+
# Schreiben / Konvertieren
|
|
50
|
+
gaeb.write_xml(lv, "ausgabe.x83")
|
|
51
|
+
gaeb.write_xml(lv, "ausgabe_v32.x83", version="3.2") # explizite Version
|
|
52
|
+
gaeb.write_gaeb90(lv, "ausgabe.d83")
|
|
53
|
+
gaeb.write_gaeb2000(lv, "ausgabe.p83")
|
|
54
|
+
|
|
55
|
+
# Excel-Export
|
|
56
|
+
gaeb.write_excel(lv, "ausgabe.xlsx")
|
|
57
|
+
gaeb.write_excel(lv, "ausgabe.xlsx", langtext=True)
|
|
58
|
+
|
|
59
|
+
# Zwei LVs vergleichen
|
|
60
|
+
lv_neu = gaeb.read_xml("angebot.x84")
|
|
61
|
+
result = gaeb.vergleiche(lv, lv_neu)
|
|
62
|
+
|
|
63
|
+
print(result.nur_in_alt) # gelöschte OZ-Nummern
|
|
64
|
+
print(result.nur_in_neu) # neue OZ-Nummern
|
|
65
|
+
for pa in result.geaendert:
|
|
66
|
+
print(pa.oz, pa.aenderungen)
|
|
67
|
+
print(result.gesamtsumme_diff) # finanzielle Differenz
|
|
68
|
+
|
|
69
|
+
# XSD-Validierung
|
|
70
|
+
fehler = gaeb.validiere("ausschreibung.x83")
|
|
71
|
+
if fehler:
|
|
72
|
+
print(fehler)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## BoQ Builder
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
import gaeb
|
|
79
|
+
|
|
80
|
+
lv = (
|
|
81
|
+
gaeb.BoQBuilder(
|
|
82
|
+
phase=gaeb.Phase.ANGEBOTSAUFFORDERUNG,
|
|
83
|
+
titel_lv="Hochwasserschutz",
|
|
84
|
+
projekt="Testprojekt",
|
|
85
|
+
)
|
|
86
|
+
.titel("Erdarbeiten")
|
|
87
|
+
.position("Bodenaushub", einheit="m³", menge=250, ep="12.50")
|
|
88
|
+
.position("Bodentransport", einheit="m³", menge=250, ep="8.00")
|
|
89
|
+
.ende()
|
|
90
|
+
.titel("Betonarbeiten")
|
|
91
|
+
.untertitel("Fundamente")
|
|
92
|
+
.position("Streifenfundament", einheit="m³", menge=30, ep="185.00")
|
|
93
|
+
.ende()
|
|
94
|
+
.ende()
|
|
95
|
+
.build()
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
gaeb.write_xml(lv, "ausschreibung.x83")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
OZ-Generierung basiert auf dem `BoQBkdn`-Schema (Standard: 2+2+4 Zeichen):
|
|
102
|
+
- Titel: `01`, `02`, …
|
|
103
|
+
- Untertitel: `0101`, `0102`, …
|
|
104
|
+
- Position: `01000001`, `01010001`, …
|
|
105
|
+
|
|
106
|
+
## Datenmodell
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
Leistungsverzeichnis
|
|
110
|
+
├── phase: Phase
|
|
111
|
+
├── titel_lv, projekt, auftraggeber, auftragnehmer
|
|
112
|
+
├── waehrung, xml_version, encoding
|
|
113
|
+
├── vorbemerkungen: list[str]
|
|
114
|
+
├── zeitvertrag_typ: str | None
|
|
115
|
+
├── boq_bkdn: list[BoQBkdn]
|
|
116
|
+
├── gesamtsumme: Decimal | None (property)
|
|
117
|
+
└── titel: list[Titel]
|
|
118
|
+
├── nummer, kurztext, langtext
|
|
119
|
+
├── positionen: list[Position]
|
|
120
|
+
│ ├── oz, kurztext, langtext
|
|
121
|
+
│ ├── menge, einheit, einheitspreis
|
|
122
|
+
│ ├── gesamtpreis (property: menge × EP)
|
|
123
|
+
│ ├── gesamtbetrag, mwst, nachlass_prozent
|
|
124
|
+
│ ├── pauschale, entfaellt, nicht_angeboten
|
|
125
|
+
│ ├── stundenlohn, schwerpunkt, provis
|
|
126
|
+
│ ├── typ: PositionTyp
|
|
127
|
+
│ ├── aln_gruppe, aln_nummer, ep_anteile
|
|
128
|
+
│ └── periodqty, min_menge, max_menge (Z-Phasen)
|
|
129
|
+
└── untertitel: list[Titel] (rekursiv)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Unterstützte Phasen
|
|
133
|
+
|
|
134
|
+
| Bereich | Phasen |
|
|
135
|
+
|---------|--------|
|
|
136
|
+
| Mengenermittlung | 31 |
|
|
137
|
+
| Kostenermittlung | 50, 51, 52 |
|
|
138
|
+
| Vergabe (Procurement) | 80–89, 83Z, 84Z, 86ZR, 86ZE |
|
|
139
|
+
| Handel / Handwerk | 93–97 |
|
|
140
|
+
|
|
141
|
+
## Optionale Abhängigkeiten
|
|
142
|
+
|
|
143
|
+
| Extra | Paket | Feature |
|
|
144
|
+
|-------|-------|---------|
|
|
145
|
+
| `gaeb[excel]` | openpyxl ≥ 3.1 | Excel-Export (.xlsx) |
|
|
146
|
+
|
|
147
|
+
## Lizenz
|
|
148
|
+
|
|
149
|
+
MIT – siehe [LICENSE](../LICENSE)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "gaeb"
|
|
3
|
+
version = "0.5.2"
|
|
4
|
+
description = "Python library for reading, writing, converting and diffing GAEB files (AVA data exchange format, DA XML 2.0–3.3, GAEB 90, GAEB 2000)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { text = "MIT" }
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Attackwave", email = "attackwave@gmail.com" }
|
|
9
|
+
]
|
|
10
|
+
keywords = ["gaeb", "ava", "construction", "leistungsverzeichnis", "bau", "gaeb90", "gaeb2000", "xml", "excel", "diff"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Topic :: Office/Business",
|
|
21
|
+
]
|
|
22
|
+
requires-python = ">=3.10"
|
|
23
|
+
dependencies = [
|
|
24
|
+
"pydantic>=2.0",
|
|
25
|
+
"lxml>=4.9.4",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/Attackwave/gaeb-python"
|
|
30
|
+
Repository = "https://github.com/Attackwave/gaeb-python"
|
|
31
|
+
Issues = "https://github.com/Attackwave/gaeb-python/issues"
|
|
32
|
+
Changelog = "https://github.com/Attackwave/gaeb-python/blob/main/CHANGELOG.md"
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
dev = [
|
|
36
|
+
"pytest>=7.0",
|
|
37
|
+
"pytest-cov>=4.0",
|
|
38
|
+
]
|
|
39
|
+
excel = [
|
|
40
|
+
"openpyxl>=3.1",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["uv_build>=0.11.1,<0.12.0"]
|
|
45
|
+
build-backend = "uv_build"
|
|
46
|
+
|
|
47
|
+
[dependency-groups]
|
|
48
|
+
dev = [
|
|
49
|
+
"pytest>=9.0.2",
|
|
50
|
+
"pytest-cov>=7.1.0",
|
|
51
|
+
]
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""gaeb – Python library for reading and writing GAEB files (AVA).
|
|
2
|
+
|
|
3
|
+
Note on language
|
|
4
|
+
----------------
|
|
5
|
+
GAEB is a German construction-industry standard (Gemeinsamer Ausschuss
|
|
6
|
+
Elektronik im Bauwesen). A mixed naming convention is used:
|
|
7
|
+
|
|
8
|
+
- **Methods and functions** use English names (``read_xml``, ``write_gaeb90``,
|
|
9
|
+
``validate``, ``compare``).
|
|
10
|
+
- **Domain fields** on model classes use German identifiers that directly mirror
|
|
11
|
+
the official GAEB specification:
|
|
12
|
+
|
|
13
|
+
Leistungsverzeichnis – bill of quantities (BoQ)
|
|
14
|
+
Titel – section / chapter
|
|
15
|
+
Position – line item
|
|
16
|
+
Kurztext – short description
|
|
17
|
+
Langtext – long description
|
|
18
|
+
Einheit – unit of measure
|
|
19
|
+
Menge – quantity
|
|
20
|
+
Einheitspreis – unit price
|
|
21
|
+
Gesamtpreis – total price
|
|
22
|
+
Phase – exchange phase (e.g. 83 = tender, 84 = bid)
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from .builder import BoQBuilder
|
|
26
|
+
from .diff import DiffResult, FieldChange, PositionChange, compare
|
|
27
|
+
from .io.excel.reader import read as read_excel
|
|
28
|
+
from .io.excel.writer import write as write_excel
|
|
29
|
+
from .io.gaeb90.reader import read as read_gaeb90
|
|
30
|
+
from .io.gaeb90.writer import write as write_gaeb90
|
|
31
|
+
from .io.gaeb2000.reader import read as read_gaeb2000
|
|
32
|
+
from .io.gaeb2000.writer import write as write_gaeb2000
|
|
33
|
+
from .io.xml.reader import read as read_xml
|
|
34
|
+
from .io.xml.validator import ValidationError, validate, validate_or_raise
|
|
35
|
+
from .io.xml.writer import write as write_xml
|
|
36
|
+
from .models import (
|
|
37
|
+
Bieter,
|
|
38
|
+
BieterEP,
|
|
39
|
+
BoQBkdn,
|
|
40
|
+
Leistungsverzeichnis,
|
|
41
|
+
Phase,
|
|
42
|
+
Position,
|
|
43
|
+
PositionTyp,
|
|
44
|
+
Preisspiegel,
|
|
45
|
+
Raum,
|
|
46
|
+
Raumbuch,
|
|
47
|
+
Raumgruppe,
|
|
48
|
+
RaumPosition,
|
|
49
|
+
Titel,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
__all__ = [
|
|
53
|
+
"Bieter",
|
|
54
|
+
"BieterEP",
|
|
55
|
+
"BoQBkdn",
|
|
56
|
+
"BoQBuilder",
|
|
57
|
+
"DiffResult",
|
|
58
|
+
"FieldChange",
|
|
59
|
+
"Leistungsverzeichnis",
|
|
60
|
+
"Phase",
|
|
61
|
+
"Position",
|
|
62
|
+
"PositionChange",
|
|
63
|
+
"PositionTyp",
|
|
64
|
+
"Preisspiegel",
|
|
65
|
+
"Raum",
|
|
66
|
+
"RaumPosition",
|
|
67
|
+
"Raumbuch",
|
|
68
|
+
"Raumgruppe",
|
|
69
|
+
"Titel",
|
|
70
|
+
"ValidationError",
|
|
71
|
+
"compare",
|
|
72
|
+
"read_excel",
|
|
73
|
+
"read_gaeb90",
|
|
74
|
+
"read_gaeb2000",
|
|
75
|
+
"read_xml",
|
|
76
|
+
"validate",
|
|
77
|
+
"validate_or_raise",
|
|
78
|
+
"write_excel",
|
|
79
|
+
"write_gaeb90",
|
|
80
|
+
"write_gaeb2000",
|
|
81
|
+
"write_xml",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
__version__ = "0.5.2"
|