Compare commits
259 Commits
cdff4a8987
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b2127b70c9 | |||
| db46c38ac6 | |||
| af69b98365 | |||
| 87ff81d001 | |||
| cbc2afa9e1 | |||
| 47e70d952e | |||
| 5a1fa5a7e4 | |||
| 4defeb11f0 | |||
| 2591d78716 | |||
| ac99ca73a5 | |||
| 17cbd61fb4 | |||
| f18f8cae2d | |||
| 7fb778125b | |||
| a279c581e3 | |||
| aa73ffb444 | |||
| 61cd933de3 | |||
| 9ef23a735a | |||
| 089dadd52b | |||
| 9f5f4150f1 | |||
| c64327cbe7 | |||
| 9e25ca15bc | |||
| 754ae39364 | |||
| 6590674d8e | |||
| 6c31b9fbf3 | |||
| f5cc53253e | |||
| cf4b632cba | |||
| 95fb80dd57 | |||
| b7fd1da5b8 | |||
| e342ace5c3 | |||
| fb710b73e0 | |||
| c813a8fc1b | |||
| f8b895cec7 | |||
| cb20f31f10 | |||
| a6a7d9c3e9 | |||
| 05709677ac | |||
| 54606dce88 | |||
| 2f2dd83e2b | |||
| 0eda150f8b | |||
| 58b16509da | |||
| 39bd9e01e2 | |||
| 21528e2353 | |||
| d905896891 | |||
| 1635610aff | |||
| e083f3c2ac | |||
| 2a601ec3c1 | |||
| f01f08cda9 | |||
| 832aaf2088 | |||
| 623f4a12e1 | |||
| 56ff5010c7 | |||
| 0c54145655 | |||
| 3393e7ce47 | |||
| 807b6c79f4 | |||
| 80000c15c3 | |||
| fe302ef950 | |||
| efef193612 | |||
| a1a7f45f06 | |||
| 9b3c3859cc | |||
| 22b0cf8afc | |||
| e2bfa2aac6 | |||
| 5f3615548b | |||
| 4f740e81ad | |||
| 6f188649ff | |||
| beb1fdc0da | |||
| da4eed34c3 | |||
| 5bd83324b2 | |||
| 1b834ab919 | |||
| d40106d43b | |||
| 71620fe35b | |||
| 5564befd1d | |||
| 7f4f8e98b9 | |||
| bfda1c75f6 | |||
| 388afbfd99 | |||
| 642d0092d1 | |||
| 55aa5f38b8 | |||
| dd8258f575 | |||
| a16f8a8845 | |||
| e2d9951e38 | |||
| 3704274e26 | |||
| dc8fb06110 | |||
| 7492059744 | |||
| 0d0a9425da | |||
| ccafaf6617 | |||
| 6be81e973f | |||
| f070e92a0c | |||
| 8f82eef438 | |||
| 9a5bae7243 | |||
| b95f76341f | |||
| 7c0ad9776c | |||
| 2b0bad3cb3 | |||
| 61999ea966 | |||
| b814ffa70d | |||
| 68266a3345 | |||
| 44a116fb6e | |||
| 7a6b331e27 | |||
| 09b8ee7e6e | |||
| c070f1fd28 | |||
| 66260e23ef | |||
| cd5feb94c8 | |||
| e73fea929d | |||
| 7dee350422 | |||
| c50d0b937c | |||
| ef80d62f0c | |||
| ab24f24bba | |||
| 4356ed2cc1 | |||
| e500b20fc5 | |||
| 15e4f01f83 | |||
| e20a34d254 | |||
| da29b7b33e | |||
| a5837526be | |||
| f8360c1af0 | |||
| 5d3a8e5237 | |||
| ecd2ac37d7 | |||
| 24ac020314 | |||
| 94f2aeb027 | |||
| 1f52aa697b | |||
| e0c5b87c08 | |||
| b01e778216 | |||
| 3976d66ccf | |||
| c8e958ef32 | |||
| b7585c1975 | |||
| 32fb4999cc | |||
| 023929fce2 | |||
| 89a4f1bfe0 | |||
| ba3cc9c6fa | |||
| 5058457714 | |||
| 07a22c5c11 | |||
| bc06323061 | |||
| dcb8830d8c | |||
| 77584c8749 | |||
| c1f860d3c5 | |||
| dde4ee997e | |||
| 6a671b7c6f | |||
| 884750a2ae | |||
| 83cea43c9c | |||
| 37c791e6c5 | |||
| 660f27936d | |||
| 11f57055f2 | |||
| 479519285c | |||
| 14654ac367 | |||
| 3473b2c37c | |||
| 339ba53257 | |||
| 5b6f32f404 | |||
| c06837948f | |||
| 84626705e8 | |||
| 3a2d7c075d | |||
| 17a4d4e38a | |||
| b48060aabc | |||
| aeb35b4d43 | |||
| 1d23117f2f | |||
| 5c92c3eaec | |||
| a4f07d3e33 | |||
| b5b0c58f39 | |||
| 9c87541a49 | |||
| c8ee75f80c | |||
| ef8686d714 | |||
| cf79b32fc2 | |||
| de3899accf | |||
| 7b7df71279 | |||
| 3ba2a6ccdc | |||
| 9747f7996c | |||
| dd1362fec8 | |||
| 780974081b | |||
| 8511f224f6 | |||
| 8e6b7466a6 | |||
| 0e4b218563 | |||
| ba11ad68ea | |||
| 1c18ca98bf | |||
| 13faea2164 | |||
| 83a250e66b | |||
| 6d52f160e8 | |||
| 198a9a1d62 | |||
| 1eb42b2366 | |||
| e3a7e79dad | |||
| a785eecbc2 | |||
| 8ec356df70 | |||
| 8f74aac945 | |||
| 1e917e5bbd | |||
| b6f9f1a4bf | |||
| 3fc8c495f0 | |||
| dd20c42851 | |||
| 997592e17f | |||
| 1b6d3feaa4 | |||
| f471138b96 | |||
| f0370fa5cd | |||
| f7dd9d49f3 | |||
| bfef814673 | |||
| aae5196bc1 | |||
| 6217a41bd9 | |||
| c470729918 | |||
| 05392ef5e9 | |||
| db6b3b7329 | |||
| 1b8270b908 | |||
| 94ff9aa100 | |||
| 3dc8af5e70 | |||
| 2e3061d238 | |||
| 9fec1a91f4 | |||
| 6a569c685a | |||
| 1f05543524 | |||
| 00f180ea39 | |||
| fddcbb058e | |||
| b52e36fe57 | |||
| 2945be89d3 | |||
| 85fec18c4a | |||
| 841b8745b6 | |||
| 46d3bbd77b | |||
| 466ae4afd5 | |||
| aabf626b78 | |||
| 95e4c366d6 | |||
| 4d42f82e6a | |||
| 650b07687b | |||
| 397457b20e | |||
| b13800b797 | |||
| ebaedd574b | |||
| 5327789473 | |||
| fc1b1bc946 | |||
| 5e65dc2b36 | |||
| 74df118118 | |||
| f16902fd01 | |||
| 39e5f3ddbb | |||
| f7033ebe76 | |||
| 4fe5c37bb5 | |||
| 3e97c2aeec | |||
| f21e218420 | |||
| e63e127bef | |||
| 2dc83248ee | |||
| 8c109eebcd | |||
| 9f1402bc55 | |||
| b0b65f0614 | |||
| 5f781c513b | |||
| a0be038bbf | |||
| 76fde13623 | |||
| e4c7ccf152 | |||
| 501c862eeb | |||
| b128cfb5e6 | |||
| b527faf086 | |||
| 8c6d91b463 | |||
| e082dec1e1 | |||
| bd4b8d297e | |||
| 4777f5afbf | |||
| f6e955601d | |||
| 896cf7a227 | |||
| 2e76c4d959 | |||
| e87c1b930c | |||
| 920c7bf0f3 | |||
| 740a1b2ac8 | |||
| 6f2402dea4 | |||
| 716ff80905 | |||
| 6c1bb728c7 | |||
| 8e6b57a219 | |||
| 037ad07806 | |||
| 6a50eef3ed | |||
| 62d328b46e | |||
| 745012136b | |||
| dc24a2593a | |||
| f8c660e1ee | |||
| 1075997873 | |||
| 944d960401 | |||
| 854d575cd6 | |||
| 87da0094a7 |
Vendored
+28
-11
@@ -9,27 +9,32 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"name": "Python: Aktuelle Datei",
|
"name": "Python: Aktuelle Datei",
|
||||||
"type": "python",
|
"type": "debugpy",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${file}",
|
"program": "${file}",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"justMyCode": true
|
"justMyCode": true
|
||||||
}
|
},
|
||||||
{
|
{
|
||||||
"name": "Python: CompareLists",
|
"name": "Python: CompareLists",
|
||||||
"type": "python",
|
"type": "debugpy",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${file}",
|
"program": "${file}",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"justMyCode": true,
|
"justMyCode": true,
|
||||||
"args": [
|
"args": [
|
||||||
"-n 400102196",
|
"400102530",
|
||||||
"-t"
|
"tree",
|
||||||
|
"--local_bom",
|
||||||
|
"--local_teilestamm",
|
||||||
|
"--local_rd_ids",
|
||||||
|
"--rm_bom_ids_cfg", "C:\\Users\\s.steuer\\Documents\\Pythonprojekte\\CreoMigrate\\cfg\\BOM-Settings.cfg", "ExcludedPartnumbersInBOM",
|
||||||
|
"--rm_summary_ids_cfg", "C:\\Users\\s.steuer\\Documents\\Pythonprojekte\\CreoMigrate\\cfg\\BOM-Settings.cfg", "ExcludedPartnumbersInSummary"
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
{
|
{
|
||||||
"name": "Python: create TOS sring",
|
"name": "Python: create TOS sring",
|
||||||
"type": "python",
|
"type": "debugpy",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${file}",
|
"program": "${file}",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
@@ -37,10 +42,10 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"--console"
|
"--console"
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
{
|
{
|
||||||
"name": "fetch blacklist from server",
|
"name": "fetch blacklist from server",
|
||||||
"type": "python",
|
"type": "debugpy",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${file}",
|
"program": "${file}",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
@@ -48,10 +53,10 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"--blacklist"
|
"--blacklist"
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
{
|
{
|
||||||
"name": "Python: Build Demo Gui",
|
"name": "Python: Build Demo Gui",
|
||||||
"type": "python",
|
"type": "debugpy",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${file}",
|
"program": "${file}",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
@@ -59,6 +64,18 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"-d"
|
"-d"
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Python: Build Real Gui",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": true,
|
||||||
|
"args": [
|
||||||
|
"-s 400102196",
|
||||||
|
"--uselocal",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Projektübersicht
|
||||||
|
|
||||||
|
**CreoMigrate** enthält Skripte zur Migration von Creo-Altdaten nach Solid Edge / Rule
|
||||||
|
Designer. Ziel ist es, alte 3D-Daten aus Creo mit aktuellen SIVAS-Informationen in die
|
||||||
|
neue Konstruktionsumgebung zu überführen. Der Fokus liegt auf automatisierbaren Prozessen
|
||||||
|
mit wenig Nutzereingriff (Datenbank-Abgleich, Listenvergleich, TOS-String-Erzeugung).
|
||||||
|
|
||||||
|
## Projektstruktur
|
||||||
|
|
||||||
|
```text
|
||||||
|
CreoMigrate/
|
||||||
|
├── bin/ # Nummerierte Workflow-Batch-Skripte (01..06) + GUI/Setup
|
||||||
|
├── lib/ # Python-Quellcode
|
||||||
|
├── Include/ # Zusätzliche Includes
|
||||||
|
├── cfg/ # Konfiguration
|
||||||
|
├── data/ # Datenbanken / Eingabedaten
|
||||||
|
├── doc/ # Dokumentation
|
||||||
|
├── log/ # Log-Dateien
|
||||||
|
└── work/ # Arbeitsdateien
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow-Skripte (bin/)
|
||||||
|
|
||||||
|
Die Batch-Skripte sind in Ausführungsreihenfolge nummeriert:
|
||||||
|
|
||||||
|
1. `01_get_rd_dbase.bat` — Rule-Designer-Bestand ableiten
|
||||||
|
2. `02_get_sivas_dbase.bat` — SIVAS-Datenbank ableiten
|
||||||
|
3. `03_get_blacklist_dbase.bat` — Blacklist erzeugen
|
||||||
|
4. `04_compare_lists.bat` — Listen vergleichen
|
||||||
|
5. `05_get_sivas_teilestamm.bat` — Teilestamm aus SIVAS
|
||||||
|
6. `06_migrationsstatus_treeview.bat` — Migrationsstatus als Treeview
|
||||||
|
|
||||||
|
Weitere: `gui.bat` (GUI), `create_tos_string.bat` / `write_tos_string_to_file.bat`
|
||||||
|
(TOS-Strings), `install_py.bat`, `cremig_setenv.bat`, `get_cmd.bat`.
|
||||||
|
|
||||||
|
## Kernmodule (lib/)
|
||||||
|
|
||||||
|
- `CreoMigrateGui.py`, `gui.py`, `controller.py` — GUI + Steuerung (Tkinter)
|
||||||
|
- `compare_lists.py` — Listenvergleich
|
||||||
|
- `create_tos.py` — TOS-String-Erzeugung
|
||||||
|
- `caditem.py` — Datenmodell CAD-Item
|
||||||
|
- `update_database.py`, `manage_configs.py` — DB/Config
|
||||||
|
- `test_*.py` — Tests
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
bin\install_py.bat
|
||||||
|
```
|
||||||
|
Legt die virtuelle Umgebung an und installiert `lib/requirements.txt`.
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"folders": [
|
|
||||||
{
|
|
||||||
"path": "."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"[python]": {
|
|
||||||
"editor.defaultFormatter": "ms-python.autopep8"
|
|
||||||
},
|
|
||||||
"python.formatting.provider": "none"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,5 +29,5 @@ Vorteile:
|
|||||||
- Loslösen von Excel als Bedienumgebung, somit nicht an Version oder Hersteller gebunden.
|
- Loslösen von Excel als Bedienumgebung, somit nicht an Version oder Hersteller gebunden.
|
||||||
- Problemloseres Ausrollen auf mehrere Benutzer
|
- Problemloseres Ausrollen auf mehrere Benutzer
|
||||||
|
|
||||||
|
Installationsvoraussetzungen:
|
||||||
|
- Tabellenkalkulationsprogramm (Excel) in 64-Bit Version -> Dies ist wichtig, da unter 32-Bit das Migrationstool von Siemens (DataPrep-Tool) nicht korrekt funktioniert!
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
IF "%1" == "-s" (set SIVAS_ID=%2) else (set /p SIVAS_ID=Enter Sivas ID:)
|
IF "%1" == "-s" (set SIVAS_ID=%2) else (set /p SIVAS_ID=Enter Sivas ID:)
|
||||||
CALL manage_interpreter.bat activate_interpreter
|
CALL manage_interpreter.bat activate_interpreter
|
||||||
python %CREMIG_LIB%\update_database.py --sivasid=%SIVAS_ID%
|
python %CREMIG_LIB%\update_database.py --sivasid=%SIVAS_ID% --bom
|
||||||
CALL manage_interpreter.bat deactivate_interpreter
|
CALL manage_interpreter.bat deactivate_interpreter
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
@echo off
|
@echo off
|
||||||
CALL 01_get_rd_dbase.bat
|
|
||||||
CALL manage_interpreter.bat activate_interpreter
|
CALL manage_interpreter.bat activate_interpreter
|
||||||
python %CREMIG_LIB%\compare_lists.py %*
|
python %CREMIG_LIB%\compare_lists.py %*
|
||||||
CALL manage_interpreter.bat deactivate_interpreter
|
CALL manage_interpreter.bat deactivate_interpreter
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
IF "%1" == "-s" (set SIVAS_ID=%2) else (set /p SIVAS_ID=Enter Sivas ID or IDs:)
|
||||||
CALL manage_interpreter.bat activate_interpreter
|
CALL manage_interpreter.bat activate_interpreter
|
||||||
python %CREMIG_LIB%\get_sivas_teilestamm.py %*
|
python %CREMIG_LIB%\update_database.py --sivasid=%SIVAS_ID% -t
|
||||||
CALL manage_interpreter.bat deactivate_interpreter
|
CALL manage_interpreter.bat deactivate_interpreter
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
CALL cremig_setenv.bat
|
||||||
:start
|
:start
|
||||||
set /p "id=Baugruppennummer: "
|
set /p "id=Artikelnummer: "
|
||||||
CALL 04_compare_lists.bat --sivasid %id% -t
|
CALL 04_compare_lists.bat "%id%" tree --rm_bom_ids_cfg %CREMIG_CFG%\BOM-Settings.cfg ExcludedPartnumbersInBOM --rm_summary_ids_cfg %CREMIG_CFG%\BOM-Settings.cfg ExcludedPartnumbersInSummary
|
||||||
goto start
|
goto start
|
||||||
|
|||||||
+13
-2
@@ -10,6 +10,10 @@ set CREMIG_DATA=%CREMIG%\data
|
|||||||
set CREMIG_WORK=%CREMIG%\work
|
set CREMIG_WORK=%CREMIG%\work
|
||||||
set CREMIG_LOG=%CREMIG%\log
|
set CREMIG_LOG=%CREMIG%\log
|
||||||
|
|
||||||
|
rem Hilfsvariable um den Programmpfad zu Solid Egde immer an die aktuelle Version anzupassen. Dieser ändert sich jedesmal beim Update der Jahresversionen (Solid Edge hängt immer die Jahreszahl der Version im Ordnernamen an).
|
||||||
|
rem Deshalb muss dieser Pfad möglichst automatisch ausgelesen werden. Da auch immer das Programm Keyshot in diesem Zuge mitinstalliert wird, konnte eine Umgebungsvariable gefunden werden, die denselben Pfad verwendet wie die DataPrepUtility.exe
|
||||||
|
set SOLIDEDGE_VERSION=%KEYSHOT_EXTERNAL_LICENSE_FOLDER%
|
||||||
|
|
||||||
if not exist %CREMIG%\work mkdir %CREMIG%\work
|
if not exist %CREMIG%\work mkdir %CREMIG%\work
|
||||||
if not exist %CREMIG%\log mkdir %CREMIG%\log
|
if not exist %CREMIG%\log mkdir %CREMIG%\log
|
||||||
if not exist %CREMIG%\data mkdir %CREMIG%\data
|
if not exist %CREMIG%\data mkdir %CREMIG%\data
|
||||||
@@ -27,9 +31,16 @@ set RD_DATABASE_NAME=RD_Teilenummern.csv
|
|||||||
set BLACKLIST_DATABASE_SOURCE=\\ruledesigner\RDF_Daten\Konfigurator\CustomVaulting
|
set BLACKLIST_DATABASE_SOURCE=\\ruledesigner\RDF_Daten\Konfigurator\CustomVaulting
|
||||||
set BLACKLIST_DATABASE_NAME=ERP_BOM.ini
|
set BLACKLIST_DATABASE_NAME=ERP_BOM.ini
|
||||||
set VBA_MACRO_NAME=vba_format_excel.xlsm
|
set VBA_MACRO_NAME=vba_format_excel.xlsm
|
||||||
set SIVAS_DATABASE_QUERY=Y:\jit\programme\Sivas2json.exe
|
set SIVAS_BOM=Y:\jit\programme\Sivas2json.exe
|
||||||
set SIVAS_TEILESTAMM=\\195.243.223.3\sivas\jit\programme\KSbExcelExportSivasTeilestamm.exe
|
set SIVAS_TEILESTAMM=\\195.243.223.3\sivas\jit\programme\KSbExcelExportSivasTeilestamm.exe
|
||||||
set SIVAS_EXCEL_EXPORT_DIR=%CREMIG_WORK%
|
set SIVAS_EXCEL_EXPORT_DIR=%CREMIG_DATA%
|
||||||
|
set SIEMENS_DATA_PREP_TOOL=%SOLIDEDGE_VERSION%\DataPrepUtility.exe
|
||||||
|
set LOG_EDITOR=notepad.exe
|
||||||
|
set RD_SQL_DATABASE_CREDENTIALS=\\fileserver01\abteilungen\Entwicklung\Administration\Lizenzen\RDSQLDatabaseCredentials.bat
|
||||||
|
|
||||||
|
if exist %RD_SQL_DATABASE_CREDENTIALS% (
|
||||||
|
call %RD_SQL_DATABASE_CREDENTIALS%
|
||||||
|
)
|
||||||
|
|
||||||
rem Um den Python-Interpreter auf U:\ zu nutzen, Kommentar (rem) in nachfolgender Zeile entfernen
|
rem Um den Python-Interpreter auf U:\ zu nutzen, Kommentar (rem) in nachfolgender Zeile entfernen
|
||||||
rem set NETWORK_INTERPRETER_PATH=\\ssg.local\freigaben\Allgemein\Programmierumgebung\Python312
|
rem set NETWORK_INTERPRETER_PATH=\\ssg.local\freigaben\Allgemein\Programmierumgebung\Python312
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
@echo off
|
@echo off
|
||||||
CALL cremig_setenv.bat
|
CALL cremig_setenv.bat
|
||||||
IF NOT EXIST %CREMIG%\.venv CALL %CREMIG_BIN%\install_py.bat
|
CALL manage_interpreter.bat activate_interpreter
|
||||||
CALL %CREMIG%\.venv\Scripts\activate.bat
|
|
||||||
python %CREMIG_LIB%\CreoMigrateGui.py %*
|
python %CREMIG_LIB%\CreoMigrateGui.py %*
|
||||||
deactivate
|
CALL manage_interpreter.bat deactivate_interpreter
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ deactivate
|
|||||||
goto :eof
|
goto :eof
|
||||||
|
|
||||||
:activate_interpreter_network
|
:activate_interpreter_network
|
||||||
|
ECHO Initialisiere Python-Interpreter in %NETWORK_INTERPRETER_PATH%...
|
||||||
SET OLD_PATH=%PATH%
|
SET OLD_PATH=%PATH%
|
||||||
SET PATH=%NETWORK_INTERPRETER_PATH%;%PATH%
|
SET PATH=%NETWORK_INTERPRETER_PATH%;%PATH%
|
||||||
goto :eof
|
goto :eof
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
REM Ermittle das aktuelle Datum im Format YYYY-MM-DD
|
||||||
|
for /f "delims=" %%a in ('powershell Get-Date -Format "yyyy_MM_dd"') do set datetime=%%a
|
||||||
|
|
||||||
|
set "Namensanfang=TOS-Gruppenstring_"
|
||||||
|
set "Dateiname=%Namensanfang%!datetime!.txt"
|
||||||
|
|
||||||
|
REM Führe die folgende .bat aus mit dem gesetzten Schalter -o um eine Datei mit dem Code zu generieren
|
||||||
|
CALL %CREMIG_BIN%\create_tos_string.bat -o %Dateiname%
|
||||||
|
|
||||||
|
echo Die Datei wurde in %CREMIG_WORK% mit dem Namen: %Dateiname% gespeichert
|
||||||
|
echo Bitte pflegen sie den Inhalt dieser Datei in die jeweiligen CampiEsterni.ini unter CALC LINK10 ein.
|
||||||
|
echo:
|
||||||
|
|
||||||
|
endlocal
|
||||||
|
pause
|
||||||
+22
-12
@@ -1,4 +1,5 @@
|
|||||||
[Kategorien]
|
[Kategorien]
|
||||||
|
<undefiniert>
|
||||||
Baugruppe
|
Baugruppe
|
||||||
Einzelteil
|
Einzelteil
|
||||||
Kaufteil
|
Kaufteil
|
||||||
@@ -58,27 +59,36 @@ Aluminium
|
|||||||
Stahl
|
Stahl
|
||||||
|
|
||||||
[Fertigungsart]:
|
[Fertigungsart]:
|
||||||
3D-drucken
|
3D - 3D drucken
|
||||||
biegen
|
BI - biegen
|
||||||
drehen
|
DR - drehen
|
||||||
extrudieren
|
EX - extrudieren
|
||||||
fräsen
|
FR - fräsen
|
||||||
gießen
|
GI - gießen
|
||||||
laser-/wasserstrahlschneiden
|
LW - laser- und wasserstrahlschneiden
|
||||||
sägen
|
SA - sägen
|
||||||
schweißen
|
SW - schweißen
|
||||||
spritzgießen
|
SP - spritzgießen
|
||||||
stanzen
|
ST - stanzen
|
||||||
strangpressen
|
SN - strangpressen
|
||||||
|
|
||||||
[Beschaffungsart]
|
[Beschaffungsart]
|
||||||
Eigenbau
|
Eigenbau
|
||||||
Kaufteil
|
Kaufteil
|
||||||
|
|
||||||
[Ruestcode]
|
[Ruestcode]
|
||||||
|
Trümmerbaugruppe
|
||||||
HZS Halbzeuge Sägeteile
|
HZS Halbzeuge Sägeteile
|
||||||
SRC Standard Rüstcode
|
SRC Standard Rüstcode
|
||||||
|
|
||||||
|
|
||||||
|
[RuestcodeStandard]
|
||||||
|
HZS Halbzeuge Sägeteile
|
||||||
|
SRC Standard Rüstcode
|
||||||
|
|
||||||
|
[RuestcodeBaugruppe]
|
||||||
Trümmerbaugruppe
|
Trümmerbaugruppe
|
||||||
|
SRC Standard Rüstcode
|
||||||
|
|
||||||
[Halbzeug]
|
[Halbzeug]
|
||||||
WAHR
|
WAHR
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[ExcludedPartnumbersInBOM]
|
||||||
|
#============================================================================================================================
|
||||||
|
# Teilenummern, die in der Migrationsübersicht (u.a. im Baum von CreoMigrate) nicht dargestellt sein sollen
|
||||||
|
#============================================================================================================================
|
||||||
|
|
||||||
|
MA0000008
|
||||||
|
MA0000005
|
||||||
|
|
||||||
|
[ExcludedPartnumbersInSummary]
|
||||||
|
#============================================================================================================================
|
||||||
|
# Teilenummern, die in der Zusammenfassung der Migrationsübersicht nicht enthalten sein sollen
|
||||||
|
# Wenn die Nummer bereits in der Sektion "ExcludedPartnumbersInBOM" enthalten ist, muss sie hier nicht nochmal aufgelistet werden
|
||||||
|
#============================================================================================================================
|
||||||
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
[Farbauswahl]
|
[Farbauswahl]
|
||||||
|
PANTONE 2175 C
|
||||||
RAL 1004 Goldgelb
|
RAL 1004 Goldgelb
|
||||||
RAL 2000 Gelborange
|
RAL 2000 Gelborange
|
||||||
RAL 3002 Kaminrot
|
RAL 3002 Kaminrot
|
||||||
@@ -21,6 +22,9 @@ Grau
|
|||||||
Rot
|
Rot
|
||||||
Grün
|
Grün
|
||||||
Blau
|
Blau
|
||||||
|
siehe Oben
|
||||||
|
Ocker
|
||||||
|
Transparent
|
||||||
|
|
||||||
[FarbeEloxieren]
|
[FarbeEloxieren]
|
||||||
Rot
|
Rot
|
||||||
|
|||||||
+64
-19
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
[Fertigungsarten]
|
[Fertigungsarten]
|
||||||
3D - 3D drucken=3D-drucken
|
3D - 3D-drucken=3D-drucken
|
||||||
BI - biegen=biegen
|
BI - biegen=biegen
|
||||||
DR - drehen=drehen
|
DR - drehen=drehen
|
||||||
EX - extrudieren=extrudieren
|
EX - extrudieren=extrudieren
|
||||||
@@ -15,19 +15,19 @@ ST - stanzen=stanzen
|
|||||||
SW - schweißen=schweißen
|
SW - schweißen=schweißen
|
||||||
|
|
||||||
[FertigungsartenBaugruppe]
|
[FertigungsartenBaugruppe]
|
||||||
biegen
|
BI - biegen
|
||||||
drehen
|
DR - drehen
|
||||||
fräsen
|
FR - fräsen
|
||||||
laser-/wasserstrahlschneiden
|
LW - laser- und wasserstrahlschneiden
|
||||||
stanzen
|
ST - stanzen
|
||||||
sägen
|
SA - sägen
|
||||||
|
|
||||||
[FertigungsartSchweissbaugruppe]
|
[FertigungsartSchweissbaugruppe]
|
||||||
schweißen
|
SW - schweißen
|
||||||
|
|
||||||
[FertigungsartenAllgemeintoleranzenMapping]
|
[FertigungsartenAllgemeintoleranzenMapping]
|
||||||
3D - 3D drucken=Allgemeintoleranz3DDruck
|
3D - 3D-drucken=Allgemeintoleranz3DDruck
|
||||||
BI - biegen=AllgemeintoleranzSpanen
|
BI - biegen=AllgemeintoleranzBiegen
|
||||||
DR - drehen=AllgemeintoleranzSpanen
|
DR - drehen=AllgemeintoleranzSpanen
|
||||||
EX - extrudieren=AllgemeintoleranzExtrudieren
|
EX - extrudieren=AllgemeintoleranzExtrudieren
|
||||||
FR - fräsen=AllgemeintoleranzSpanen
|
FR - fräsen=AllgemeintoleranzSpanen
|
||||||
@@ -40,6 +40,20 @@ SP - spritzgießen=AllgemeintoleranzSpritzgiessen
|
|||||||
ST - stanzen=AllgemeintoleranzStanzen
|
ST - stanzen=AllgemeintoleranzStanzen
|
||||||
SW - schweißen=AllgemeintoleranzSchweissen
|
SW - schweißen=AllgemeintoleranzSchweissen
|
||||||
|
|
||||||
|
[AllgemeintoleranzSpanen]
|
||||||
|
ISO 2768:1991-fH
|
||||||
|
ISO 2768:1991-fK
|
||||||
|
ISO 2768:1991-fL
|
||||||
|
ISO 2768:1991-mH
|
||||||
|
ISO 2768:1991-mK
|
||||||
|
ISO 2768:1991-mL
|
||||||
|
ISO 2768:1991-cH
|
||||||
|
ISO 2768:1991-cK
|
||||||
|
ISO 2768:1991-cL
|
||||||
|
ISO 2768:1991-vH
|
||||||
|
ISO 2768:1991-vK
|
||||||
|
ISO 2768:1991-vL
|
||||||
|
|
||||||
[AllgemeintoleranzBaugruppe]
|
[AllgemeintoleranzBaugruppe]
|
||||||
ISO 2768:1991-fH
|
ISO 2768:1991-fH
|
||||||
ISO 2768:1991-fK
|
ISO 2768:1991-fK
|
||||||
@@ -105,15 +119,15 @@ EN ISO 13920-DG
|
|||||||
EN ISO 13920-DH
|
EN ISO 13920-DH
|
||||||
|
|
||||||
[AllgemeintoleranzSpritzgiessen]
|
[AllgemeintoleranzSpritzgiessen]
|
||||||
ISO 20457 - TG1
|
DIN ISO 20457-TG1
|
||||||
ISO 20457 - TG2
|
DIN ISO 20457-TG2
|
||||||
ISO 20457 - TG3
|
DIN ISO 20457-TG3
|
||||||
ISO 20457 - TG4
|
DIN ISO 20457-TG4
|
||||||
ISO 20457 - TG5
|
DIN ISO 20457-TG5
|
||||||
ISO 20457 - TG6
|
DIN ISO 20457-TG6
|
||||||
ISO 20457 - TG7
|
DIN ISO 20457-TG7
|
||||||
ISO 20457 - TG8
|
DIN ISO 20457-TG8
|
||||||
ISO 20457 - TG9
|
DIN ISO 20457-TG9
|
||||||
|
|
||||||
[AllgemeintoleranzStanzen]
|
[AllgemeintoleranzStanzen]
|
||||||
DIN 6930-2 - f
|
DIN 6930-2 - f
|
||||||
@@ -129,3 +143,34 @@ DIN 16941 - 2A
|
|||||||
DIN 16941 - 2B
|
DIN 16941 - 2B
|
||||||
DIN 16941 - 3A
|
DIN 16941 - 3A
|
||||||
DIN 16941 - 3B
|
DIN 16941 - 3B
|
||||||
|
|
||||||
|
[AllgemeintoleranzVerpressen]
|
||||||
|
ISO 2768:1991-fH
|
||||||
|
ISO 2768:1991-fK
|
||||||
|
ISO 2768:1991-fL
|
||||||
|
ISO 2768:1991-mH
|
||||||
|
ISO 2768:1991-mK
|
||||||
|
ISO 2768:1991-mL
|
||||||
|
ISO 2768:1991-cH
|
||||||
|
ISO 2768:1991-cK
|
||||||
|
ISO 2768:1991-cL
|
||||||
|
ISO 2768:1991-vH
|
||||||
|
ISO 2768:1991-vK
|
||||||
|
ISO 2768:1991-vL
|
||||||
|
|
||||||
|
[AllgemeintoleranzBiegen]
|
||||||
|
ISO 2768:1991-fH
|
||||||
|
ISO 2768:1991-fK
|
||||||
|
ISO 2768:1991-fL
|
||||||
|
ISO 2768:1991-mH
|
||||||
|
ISO 2768:1991-mK
|
||||||
|
ISO 2768:1991-mL
|
||||||
|
ISO 2768:1991-cH
|
||||||
|
ISO 2768:1991-cK
|
||||||
|
ISO 2768:1991-cL
|
||||||
|
ISO 2768:1991-vH
|
||||||
|
ISO 2768:1991-vK
|
||||||
|
ISO 2768:1991-vL
|
||||||
|
DIN 2194 - G1
|
||||||
|
DIN 2194 - G2
|
||||||
|
DIN 2194 - G3
|
||||||
|
|||||||
+2362
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
\,?,|,!,@,à,è,ì,ò,ù,£,$,%,;
|
||||||
+221
-32
@@ -1,8 +1,32 @@
|
|||||||
{
|
{
|
||||||
|
"VA": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
"1.4301": {
|
"1.4301": {
|
||||||
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
|
"X5CrNi18-10": {
|
||||||
|
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"1.4301 (X5CrNi18-10)": {
|
||||||
|
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"1.4301f / 59381": {
|
||||||
|
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"X5CrNi 18-10": {
|
||||||
|
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"X5CrNi 18-9": {
|
||||||
|
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
"1.4305": {
|
"1.4305": {
|
||||||
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
@@ -15,10 +39,42 @@
|
|||||||
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
|
"X10CrNiS 18-9": {
|
||||||
|
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"X8CrNiS 18-9": {
|
||||||
|
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"X8CrNiS18-9": {
|
||||||
|
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"X12CrNi17 7": {
|
||||||
|
"Werkstoff": "1.4310 (X10CrNi18-8)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"Aluminium": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"AlCuMgPb": {
|
||||||
|
"Werkstoff": "EN AW-2007 (3.1645)",
|
||||||
|
"Werkstofftyp": "Aluminium"
|
||||||
|
},
|
||||||
"3.3206.72": {
|
"3.3206.72": {
|
||||||
"Werkstoff": "EN AW-6063-T66",
|
"Werkstoff": "EN AW-6063-T66",
|
||||||
"Werkstofftyp": "Aluminium"
|
"Werkstofftyp": "Aluminium"
|
||||||
},
|
},
|
||||||
|
"AlSiMg 0,5 F25": {
|
||||||
|
"Werkstoff": "EN AW-6063-T66",
|
||||||
|
"Werkstofftyp": "Aluminium"
|
||||||
|
},
|
||||||
|
"F25": {
|
||||||
|
"Werkstoff": "EN AW-6063-T66",
|
||||||
|
"Werkstofftyp": "Aluminium"
|
||||||
|
},
|
||||||
"AlMgSi0.5": {
|
"AlMgSi0.5": {
|
||||||
"Werkstoff": "EN AW-6060 (3.3206)",
|
"Werkstoff": "EN AW-6060 (3.3206)",
|
||||||
"Werkstofftyp": "Aluminium"
|
"Werkstofftyp": "Aluminium"
|
||||||
@@ -27,21 +83,41 @@
|
|||||||
"Werkstoff": "EN AW-6060 (3.3206)",
|
"Werkstoff": "EN AW-6060 (3.3206)",
|
||||||
"Werkstofftyp": "Aluminium"
|
"Werkstofftyp": "Aluminium"
|
||||||
},
|
},
|
||||||
|
"AlMgSi 0.5": {
|
||||||
|
"Werkstoff": "EN AW-6060 (3.3206)",
|
||||||
|
"Werkstofftyp": "Aluminium"
|
||||||
|
},
|
||||||
|
"AlMgSi0.5 F22": {
|
||||||
|
"Werkstoff": "EN AW-6060-T66 (3.3206-T66)",
|
||||||
|
"Werkstofftyp": "Aluminium"
|
||||||
|
},
|
||||||
"AlSiMg 0,5 F22": {
|
"AlSiMg 0,5 F22": {
|
||||||
"Werkstoff": "EN AW-6060-T66 (3.3206-T66)",
|
"Werkstoff": "EN AW-6060-T66 (3.3206-T66)",
|
||||||
"Werkstofftyp": "Aluminium"
|
"Werkstofftyp": "Aluminium"
|
||||||
},
|
},
|
||||||
"AlSiMg 0,5 F25": {
|
"AlMg3": {
|
||||||
"Werkstoff": "EN AW-6063-T66",
|
"Werkstoff": "EN AW-5754 (3.3535)",
|
||||||
"Werkstofftyp": "Aluminium"
|
"Werkstofftyp": "Aluminium"
|
||||||
},
|
},
|
||||||
|
"St": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
"C45": {
|
"C45": {
|
||||||
"Werkstoff": "1.0503 (C45)",
|
"Werkstoff": "1.0503 (C45)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
"F25": {
|
"Ck60": {
|
||||||
"Werkstoff": "EN AW-6063-T66",
|
"Werkstoff": "1.1221 (C60E)",
|
||||||
"Werkstofftyp": "Aluminium"
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"S355JO": {
|
||||||
|
"Werkstoff": "1.0553 (S355J0)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"1.0038 (S235JR)": {
|
||||||
|
"Werkstoff": "1.0038 (S235JR)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
"S235JR": {
|
"S235JR": {
|
||||||
"Werkstoff": "1.0038 (S235JR)",
|
"Werkstoff": "1.0038 (S235JR)",
|
||||||
@@ -51,14 +127,6 @@
|
|||||||
"Werkstoff": "1.0038 (S235JR)",
|
"Werkstoff": "1.0038 (S235JR)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
"S235JRG2C": {
|
|
||||||
"Werkstoff": "1.0122 (S235JRC)",
|
|
||||||
"Werkstofftyp": "Stahl"
|
|
||||||
},
|
|
||||||
"S235JRG2C+C": {
|
|
||||||
"Werkstoff": "1.0122 (S235JRC)",
|
|
||||||
"Werkstofftyp": "Stahl"
|
|
||||||
},
|
|
||||||
"St-37": {
|
"St-37": {
|
||||||
"Werkstoff": "1.0038 (S235JR)",
|
"Werkstoff": "1.0038 (S235JR)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
@@ -67,40 +135,161 @@
|
|||||||
"Werkstoff": "1.0038 (S235JR)",
|
"Werkstoff": "1.0038 (S235JR)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
"X5CrNi18-10": {
|
"S235 JR": {
|
||||||
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
"Werkstoff": "1.0038 (S235JR)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
"X8CrNiS 18-9": {
|
"S235JR galv. verzinkt Fe/Zn 8-15 B": {
|
||||||
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
"Werkstoff": "1.0038 (S235JR)",
|
||||||
|
"Werkstofftyp": "Stahl",
|
||||||
|
"Oberfläche": "verzinken"
|
||||||
|
},
|
||||||
|
"S235JR+Cr": {
|
||||||
|
"Werkstoff": "1.0038+CR (S235JR+CR)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
"X8CrNiS18-9": {
|
"S235JRG2C": {
|
||||||
"Werkstoff": "1.4305 (X8CrNiS18-9)",
|
"Werkstoff": "1.0122 (S235JRC)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
"1.4301 (X5CrNi18-10)": {
|
"S235JRG2C+C": {
|
||||||
"Werkstoff": "1.4301 (X5CrNi18-10)",
|
"Werkstoff": "1.0122 (S235JRC)",
|
||||||
"Werkstofftyp": "Stahl"
|
"Werkstofftyp": "Stahl"
|
||||||
},
|
},
|
||||||
|
"S235JRC": {
|
||||||
|
"Werkstoff": "1.0122 (S235JRC)",
|
||||||
|
"Werkstofftyp": "Stahl"
|
||||||
|
},
|
||||||
|
"Kunststo": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
"PA6 GF30": {
|
"PA6 GF30": {
|
||||||
"Werkstoff": "PA 6 GF 30",
|
"Werkstoff": "PA 6 GF 30",
|
||||||
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
"Oberfläche": "Masterbatch (Grundfarbe)"
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
},
|
},
|
||||||
"S235JR galv. verzinkt Fe/Zn 8-15 B": {
|
"PA 6 GF 30 Regranulat schwarz": {
|
||||||
"Werkstoff": "1.0038 (S235JR) ",
|
"Werkstoff": "PA 6 GF 30 (REC)",
|
||||||
"Werkstofftyp": "Stahl",
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
"Oberfläche": "verzinken"
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
},
|
|
||||||
"VA": {
|
|
||||||
"Werkstoff": "false",
|
|
||||||
"Message": "Bitte individuell wählen!"
|
|
||||||
},
|
},
|
||||||
"PA6 GF30; Farbe ähnlich RAL 5015": {
|
"PA6 GF30; Farbe ähnlich RAL 5015": {
|
||||||
"Werkstoff": "PA 6 GF 30",
|
"Werkstoff": "PA 6 GF 30",
|
||||||
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
"Oberfläche":"Masterbatch (Grundfarbe)",
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
"Farbe": "RAL 5015"
|
"Farbe": "RAL 5015 Himmelblau"
|
||||||
}
|
},
|
||||||
|
"PA6 30% GF / RAL 7035": {
|
||||||
|
"Werkstoff": "PA 6 GF 30",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
|
"Farbe": "RAL 7035 Lichtgrau"
|
||||||
|
},
|
||||||
|
"PA6 30% GF ": {
|
||||||
|
"Werkstoff": "PA 6 GF 30",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
|
},
|
||||||
|
"PA 66 GF 50": {
|
||||||
|
"Werkstoff": "PA 66 GF 50",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
|
},
|
||||||
|
"PC GF 10": {
|
||||||
|
"Werkstoff": "PC GF 10",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
|
},
|
||||||
|
"POM schw": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
|
"Farbe": "Schwarz"
|
||||||
|
},
|
||||||
|
"POM schwarz": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
|
"Farbe": "Schwarz"
|
||||||
|
},
|
||||||
|
"POM sch": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
|
"Farbe": "Schwarz"
|
||||||
|
},
|
||||||
|
"POM weiß": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
|
"Farbe": "Weiß"
|
||||||
|
},
|
||||||
|
"POM natur": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
|
"Farbe": "Natur"
|
||||||
|
},
|
||||||
|
"POM": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
|
},
|
||||||
|
"POM ": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
|
},
|
||||||
|
"POM ": {
|
||||||
|
"Werkstoff": "POM",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)"
|
||||||
|
},
|
||||||
|
"PUR D44 ": {
|
||||||
|
"Werkstoff": "Bitte individuell wählen!",
|
||||||
|
"Werkstofftyp": "Kunst-/ Verbundstoff",
|
||||||
|
"Oberfläche": "Masterbatch (Grundfarbe)",
|
||||||
|
"Farbe": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"-": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"Al": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"-----": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"---": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"----": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"--- / ---": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"--- / 2391": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"--- / 444": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"--- / EN 24017": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
},
|
||||||
|
"Federsta": {
|
||||||
|
"Werkstoff": "false",
|
||||||
|
"Message": "Bitte individuell wählen!"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ ISO 13715
|
|||||||
|
|
||||||
[Oberflaechennorm]
|
[Oberflaechennorm]
|
||||||
ISO 1302:2002
|
ISO 1302:2002
|
||||||
ISO 21920
|
|
||||||
|
|
||||||
[Massnorm]
|
[Massnorm]
|
||||||
ISO 14405
|
ISO 14405
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ verzinken
|
|||||||
blank
|
blank
|
||||||
phosphatieren
|
phosphatieren
|
||||||
|
|
||||||
|
[Schweissbaugruppe]
|
||||||
|
lackieren
|
||||||
|
pulverbeschichten
|
||||||
|
verzinken
|
||||||
|
vernickeln
|
||||||
|
brünieren
|
||||||
|
härten
|
||||||
|
bürsten
|
||||||
|
sandstrahlen
|
||||||
|
|
||||||
[Oberflaechenbehandlungen]
|
[Oberflaechenbehandlungen]
|
||||||
Masterbatch (Grundfarbe)
|
Masterbatch (Grundfarbe)
|
||||||
blank
|
blank
|
||||||
@@ -43,3 +53,5 @@ pulverbeschichten
|
|||||||
sandstrahlen
|
sandstrahlen
|
||||||
vernickeln
|
vernickeln
|
||||||
verzinken
|
verzinken
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Status]
|
||||||
|
0=VERFÜGBAR
|
||||||
|
1=IN BEARBEITUNG
|
||||||
|
2=IN ÜBERARBEITUNG
|
||||||
|
3=FREIGEGEBEN
|
||||||
|
4=FREIGEGEBEN
|
||||||
|
10=VORLÄUFIG
|
||||||
|
11=PROTOTYP
|
||||||
|
12=IN PRÜFUNG
|
||||||
|
13=UNGÜLTIG
|
||||||
|
101=BAGATELLÄNDERUNG
|
||||||
|
102=REVISION VERFÜGBAR
|
||||||
|
103=ZUR PRÜFUNG
|
||||||
|
104=REVISION IN PRÜFUNG
|
||||||
|
105=REVISION ZUR PRÜFUNG
|
||||||
|
106=GESPERRT
|
||||||
+125
-47
@@ -6,7 +6,7 @@
|
|||||||
"0": "Intern/Referenzgruppe",
|
"0": "Intern/Referenzgruppe",
|
||||||
"1": "Halbzeug",
|
"1": "Halbzeug",
|
||||||
"2": "Verkaufsprodukte",
|
"2": "Verkaufsprodukte",
|
||||||
"3": "Schönenberger Produkte",
|
"3": "Schönenberger Produkt",
|
||||||
"4": "Automation",
|
"4": "Automation",
|
||||||
"5": "Maschinenelement",
|
"5": "Maschinenelement",
|
||||||
"6": "Schönenberger Komponenten",
|
"6": "Schönenberger Komponenten",
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Schoenenberger_Produkt": {
|
"TOS_Schoenenberger_Produkt": {
|
||||||
"TOS-level": 2,
|
"TOS-level": 2,
|
||||||
|
"_comment" : "3 - Schönenberger Produkt",
|
||||||
"children": {
|
"children": {
|
||||||
"30": "ILS IntraLogistikSystem",
|
"30": "ILS IntraLogistikSystem",
|
||||||
"31": "MAS Mittenabgehängtes System - OMNIFLO",
|
"31": "MAS Mittenabgehängtes System - OMNIFLO",
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_ILS": {
|
"TOS_ILS": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "30 - Schönenberger Produkt -> ILS IntraLogistikSystem",
|
||||||
"children": {
|
"children": {
|
||||||
"300": "ILS 2.0",
|
"300": "ILS 2.0",
|
||||||
"301": "ILS 3.0",
|
"301": "ILS 3.0",
|
||||||
@@ -62,48 +64,9 @@
|
|||||||
"302": "TOS_ILS_Foerderer"
|
"302": "TOS_ILS_Foerderer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TOS_ILS_Foerderer": {
|
|
||||||
"TOS-level": 4,
|
|
||||||
"children": {
|
|
||||||
"3020": "ETF"
|
|
||||||
},
|
|
||||||
"reference-ids": {}
|
|
||||||
},
|
|
||||||
"TOS_MAS": {
|
|
||||||
"TOS-level": 3,
|
|
||||||
"children": {
|
|
||||||
"310": "Fahrstrecke",
|
|
||||||
"311": "Ein- und Anbaugruppe für Omniflo System",
|
|
||||||
"312": "Verbinder und Kleinteil",
|
|
||||||
"313": "Baugruppe für Aktionen an/mit Trolleys",
|
|
||||||
"314": "Förderer"
|
|
||||||
},
|
|
||||||
"reference-ids": {
|
|
||||||
"310": "TOS_MAS_Fahrstrecke"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"TOS_Spinnereikomponente": {
|
|
||||||
"TOS-level": 3,
|
|
||||||
"children": {
|
|
||||||
"320": "Hülsenreiniger automatisch",
|
|
||||||
"321": "Hülsenreiniger manuell",
|
|
||||||
"322": "Reibradantrieb RA"
|
|
||||||
},
|
|
||||||
"reference-ids": {}
|
|
||||||
},
|
|
||||||
"TOS_Betriebsmittel": {
|
|
||||||
"TOS-level": 3,
|
|
||||||
"children": {
|
|
||||||
"330": "Trolley Standard",
|
|
||||||
"331": "Trolley Projekte"
|
|
||||||
},
|
|
||||||
"reference-ids": {
|
|
||||||
"330": "TOS_Trolley",
|
|
||||||
"331": "TOS_Trolley_Projekte"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"TOS_ILS_2": {
|
"TOS_ILS_2": {
|
||||||
"TOS-level": 4,
|
"TOS-level": 4,
|
||||||
|
"_comment" : "300 - Schönenberger Produkt -> ILS IntraLogistikSystem -> ILS 2.0",
|
||||||
"children": {
|
"children": {
|
||||||
"3000": "Modul",
|
"3000": "Modul",
|
||||||
"3001": "Modul-Komponente",
|
"3001": "Modul-Komponente",
|
||||||
@@ -114,8 +77,31 @@
|
|||||||
},
|
},
|
||||||
"reference-ids": {}
|
"reference-ids": {}
|
||||||
},
|
},
|
||||||
"TOS_MAS_Fahrstrecke": {
|
"TOS_ILS_Foerderer": {
|
||||||
"TOS-level": 4,
|
"TOS-level": 4,
|
||||||
|
"_comment" : "302 - Schönenberger Produkt -> ILS IntraLogistikSystem -> Förderer",
|
||||||
|
"children": {
|
||||||
|
"3020": "ETF"
|
||||||
|
},
|
||||||
|
"reference-ids": {}
|
||||||
|
},
|
||||||
|
"TOS_MAS": {
|
||||||
|
"TOS-level": 3,
|
||||||
|
"_comment" : "31 - Schönenberger Produkt -> MAS Mittenabgehängtes System - OMNIFLO",
|
||||||
|
"children": {
|
||||||
|
"310": "Fahrstrecke",
|
||||||
|
"311": "Ein- und Anbaugruppe für Omniflo System",
|
||||||
|
"312": "Verbinder und Kleinteil",
|
||||||
|
"313": "Baugruppe für Aktionen an/mit Trolleys",
|
||||||
|
"314": "Förderer"
|
||||||
|
},
|
||||||
|
"reference-ids": {
|
||||||
|
"310": "TOS_MAS_Fahrstecke"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TOS_MAS_Fahrstecke": {
|
||||||
|
"TOS-level": 4,
|
||||||
|
"_comment" : "310 - Schönenberger Produkt -> MAS Mittenabgehängtes System - OMNIFLO -> Fahrstrecke",
|
||||||
"children": {
|
"children": {
|
||||||
"3100": "Aluschiene",
|
"3100": "Aluschiene",
|
||||||
"3101": "Bogen",
|
"3101": "Bogen",
|
||||||
@@ -127,8 +113,31 @@
|
|||||||
},
|
},
|
||||||
"reference-ids": {}
|
"reference-ids": {}
|
||||||
},
|
},
|
||||||
"TOS_Trolley": {
|
"TOS_Spinnereikomponente": {
|
||||||
|
"TOS-level": 3,
|
||||||
|
"_comment" : "32 - Schönenberger Produkt -> Spinnereikomponente",
|
||||||
|
"children": {
|
||||||
|
"320": "Hülsenreiniger automatisch",
|
||||||
|
"321": "Hülsenreiniger manuell",
|
||||||
|
"322": "Reibradantrieb RA"
|
||||||
|
},
|
||||||
|
"reference-ids": {}
|
||||||
|
},
|
||||||
|
"TOS_Betriebsmittel": {
|
||||||
|
"TOS-level": 3,
|
||||||
|
"_comment" : "33 - Schönenberger Produkt -> Betriebsmittel",
|
||||||
|
"children": {
|
||||||
|
"330": "Trolley Standard",
|
||||||
|
"331": "Trolley Projekte"
|
||||||
|
},
|
||||||
|
"reference-ids": {
|
||||||
|
"330": "TOS_Trolley",
|
||||||
|
"331": "TOS_Trolley_Projekte"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TOS_Trolley": {
|
||||||
"TOS-level": 4,
|
"TOS-level": 4,
|
||||||
|
"_comment" : "330 - Schönenberger Produkt -> Betriebsmittel -> Trolley Standard",
|
||||||
"children": {
|
"children": {
|
||||||
"3300": "Omniflo",
|
"3300": "Omniflo",
|
||||||
"3301": "Spinnerei",
|
"3301": "Spinnerei",
|
||||||
@@ -144,6 +153,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Trolley_Omniflo": {
|
"TOS_Trolley_Omniflo": {
|
||||||
"TOS-level": 5,
|
"TOS-level": 5,
|
||||||
|
"_comment" : "3300 - Schönenberger Produkt -> Betriebsmittel -> Trolley Standard -> Omniflo",
|
||||||
"children": {
|
"children": {
|
||||||
"33000": "Trolley-V",
|
"33000": "Trolley-V",
|
||||||
"33001": "Trolley Hängeware",
|
"33001": "Trolley Hängeware",
|
||||||
@@ -157,6 +167,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Trolley_Spinnerei": {
|
"TOS_Trolley_Spinnerei": {
|
||||||
"TOS-level": 5,
|
"TOS-level": 5,
|
||||||
|
"_comment" : "3301 - Schönenberger Produkt -> Betriebsmittel -> Trolley Standard -> Spinnerei",
|
||||||
"children": {
|
"children": {
|
||||||
"33010": "Spulenzug",
|
"33010": "Spulenzug",
|
||||||
"33011": "Zubehör"
|
"33011": "Zubehör"
|
||||||
@@ -165,6 +176,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Trolley_ILS": {
|
"TOS_Trolley_ILS": {
|
||||||
"TOS-level": 5,
|
"TOS-level": 5,
|
||||||
|
"_comment" : "3302 - Schönenberger Produkt -> Betriebsmittel -> Trolley Standard -> ILS",
|
||||||
"children": {
|
"children": {
|
||||||
"33020": "Single carrier SC",
|
"33020": "Single carrier SC",
|
||||||
"33021": "Minitrolley MT",
|
"33021": "Minitrolley MT",
|
||||||
@@ -174,6 +186,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Trolley_Projekte": {
|
"TOS_Trolley_Projekte": {
|
||||||
"TOS-level": 4,
|
"TOS-level": 4,
|
||||||
|
"_comment" : "331 - Schönenberger Produkt -> Betriebsmittel -> Trolley Projekte",
|
||||||
"children": {
|
"children": {
|
||||||
"3310": "Liegeware",
|
"3310": "Liegeware",
|
||||||
"3311": "diverse Anwendungen",
|
"3311": "diverse Anwendungen",
|
||||||
@@ -185,6 +198,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Geruest": {
|
"TOS_Geruest": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "34 - Schönenberger Produkt -> Gerüst",
|
||||||
"children": {
|
"children": {
|
||||||
"340": "Rohrträger",
|
"340": "Rohrträger",
|
||||||
"341": "Abhänger",
|
"341": "Abhänger",
|
||||||
@@ -198,6 +212,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_FremdTransport": {
|
"TOS_FremdTransport": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "35 - Schönenberger Produkt -> Fremd-Transportsysteme & SSG-Anbauten",
|
||||||
"children": {
|
"children": {
|
||||||
"350": "PIN & Klinke",
|
"350": "PIN & Klinke",
|
||||||
"351": "CDDC",
|
"351": "CDDC",
|
||||||
@@ -207,6 +222,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_MAS_Konfig": {
|
"TOS_MAS_Konfig": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "36 - Schönenberger Produkt -> Förderer MAS aktuell Konfiguration",
|
||||||
"children": {
|
"children": {
|
||||||
"360": "Farbe / EL / H"
|
"360": "Farbe / EL / H"
|
||||||
},
|
},
|
||||||
@@ -214,6 +230,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Automation": {
|
"TOS_Automation": {
|
||||||
"TOS-level": 2,
|
"TOS-level": 2,
|
||||||
|
"_comment" : "4 - Automation",
|
||||||
"children": {
|
"children": {
|
||||||
"40": "Schaltschrank",
|
"40": "Schaltschrank",
|
||||||
"41": "Schaltschrank Einbaumaterial",
|
"41": "Schaltschrank Einbaumaterial",
|
||||||
@@ -221,7 +238,7 @@
|
|||||||
"43": "Sensorik",
|
"43": "Sensorik",
|
||||||
"44": "Kabel",
|
"44": "Kabel",
|
||||||
"45": "Installationsmaterial",
|
"45": "Installationsmaterial",
|
||||||
"46": "Frei",
|
"46": "Divers",
|
||||||
"47": "Frei",
|
"47": "Frei",
|
||||||
"48": "Frei",
|
"48": "Frei",
|
||||||
"49": "Sonstiges"
|
"49": "Sonstiges"
|
||||||
@@ -233,11 +250,13 @@
|
|||||||
"43": "TOS_Automation_Sensorik",
|
"43": "TOS_Automation_Sensorik",
|
||||||
"44": "TOS_Kabel",
|
"44": "TOS_Kabel",
|
||||||
"45": "TOS_Installation",
|
"45": "TOS_Installation",
|
||||||
|
"46": "TOS_Auto_Divers",
|
||||||
"49": "TOS_Automation_Sonstiges"
|
"49": "TOS_Automation_Sonstiges"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TOS_Schaltschrank": {
|
"TOS_Schaltschrank": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
" _comment" : "40 - Automation -> Schaltschrank",
|
||||||
"children": {
|
"children": {
|
||||||
"400": "Stand Schaltschrank",
|
"400": "Stand Schaltschrank",
|
||||||
"401": "Kompakt Schaltschrank",
|
"401": "Kompakt Schaltschrank",
|
||||||
@@ -250,6 +269,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Schalt_Einbau": {
|
"TOS_Schalt_Einbau": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "41 - Automation -> Schaltschrank Einbaumaterial",
|
||||||
"children": {
|
"children": {
|
||||||
"410": "Einbaumaterial",
|
"410": "Einbaumaterial",
|
||||||
"411": "Netzteil",
|
"411": "Netzteil",
|
||||||
@@ -261,18 +281,32 @@
|
|||||||
"417": "Motorschutzschalter",
|
"417": "Motorschutzschalter",
|
||||||
"418": "Frequenzumrichter"
|
"418": "Frequenzumrichter"
|
||||||
},
|
},
|
||||||
|
"reference-ids": {
|
||||||
|
"414": "TOS_SchaltEin_Netz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TOS_SchaltEin_Netz": {
|
||||||
|
"TOS-level": 4,
|
||||||
|
"_comment" : "414 - Automation -> Schaltschrank Einbaumaterial -> Netzwerk Komponente",
|
||||||
|
"children": {
|
||||||
|
"4140": "managed Switch",
|
||||||
|
"4141": "unmanaged Switch",
|
||||||
|
"4142": "VPN-Router"
|
||||||
|
},
|
||||||
"reference-ids": {}
|
"reference-ids": {}
|
||||||
},
|
},
|
||||||
"TOS_Dezentral": {
|
"TOS_Dezentral": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "42 - Automation -> Dezentrale Hardware",
|
||||||
"children": {
|
"children": {
|
||||||
"420": "Bedientableau",
|
"420": "Bedientableau",
|
||||||
"421": "I/O - Modul IP65/IP67"
|
"421": "Modul IP65/IP67"
|
||||||
},
|
},
|
||||||
"reference-ids": {}
|
"reference-ids": {}
|
||||||
},
|
},
|
||||||
"TOS_Automation_Sensorik": {
|
"TOS_Automation_Sensorik": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "43 - Automation -> Sensorik",
|
||||||
"children": {
|
"children": {
|
||||||
"430": "Induktiv",
|
"430": "Induktiv",
|
||||||
"431": "Optisch",
|
"431": "Optisch",
|
||||||
@@ -285,20 +319,46 @@
|
|||||||
"438": "Reedkontakte",
|
"438": "Reedkontakte",
|
||||||
"439": "Scanner / Kamera"
|
"439": "Scanner / Kamera"
|
||||||
},
|
},
|
||||||
|
"reference-ids": {
|
||||||
|
"439": "TOS_Auto_Sens_ScaKa"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TOS_Auto_Sens_ScaKa": {
|
||||||
|
"TOS-level": 4,
|
||||||
|
"_comment" : "439 - Automation -> Sensorik -> Scanner / Kamera",
|
||||||
|
"children": {
|
||||||
|
"4390": "Camera",
|
||||||
|
"4391": "Scanner",
|
||||||
|
"4392": "Handscanner"
|
||||||
|
},
|
||||||
"reference-ids": {}
|
"reference-ids": {}
|
||||||
},
|
},
|
||||||
"TOS_Kabel": {
|
"TOS_Kabel": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "44 - Automation -> Kabel",
|
||||||
"children": {
|
"children": {
|
||||||
"440": "Steuerleitung",
|
"440": "Steuerleitung",
|
||||||
"441": "Anschlussleitung",
|
"441": "Anschlussleitung",
|
||||||
"442": "Feldbusleitung",
|
"442": "Feldbusleitung",
|
||||||
"443": "Zubehör"
|
"443": "Zubehör"
|
||||||
},
|
},
|
||||||
|
"reference-ids": {
|
||||||
|
"440": "TOS_Auto_Kabel_Steuer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TOS_Auto_Kabel_Steuer": {
|
||||||
|
"TOS-level": 4,
|
||||||
|
"_comment" : "440 - Automation -> Kabel -> Steuerleitung",
|
||||||
|
"children": {
|
||||||
|
"4400": "Geschirmt",
|
||||||
|
"4401": "Nummeriert",
|
||||||
|
"4402": "UL/CSA"
|
||||||
|
},
|
||||||
"reference-ids": {}
|
"reference-ids": {}
|
||||||
},
|
},
|
||||||
"TOS_Installation": {
|
"TOS_Installation": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "45 - Automation -> Installationsmaterial",
|
||||||
"children": {
|
"children": {
|
||||||
"450": "Kabelpritsche",
|
"450": "Kabelpritsche",
|
||||||
"451": "Kabelkanal",
|
"451": "Kabelkanal",
|
||||||
@@ -307,8 +367,17 @@
|
|||||||
},
|
},
|
||||||
"reference-ids": {}
|
"reference-ids": {}
|
||||||
},
|
},
|
||||||
|
"TOS_Auto_Divers": {
|
||||||
|
"TOS-level": 3,
|
||||||
|
"_comment" : "46 - Automation -> Divers",
|
||||||
|
"children": {
|
||||||
|
"460": "Auswahl Lichttaster"
|
||||||
|
},
|
||||||
|
"reference-ids": {}
|
||||||
|
},
|
||||||
"TOS_Automation_Sonstiges": {
|
"TOS_Automation_Sonstiges": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "49 - Automation -> Sonstiges",
|
||||||
"children": {
|
"children": {
|
||||||
"490": "Beschriftung",
|
"490": "Beschriftung",
|
||||||
"491": "Schüttgut"
|
"491": "Schüttgut"
|
||||||
@@ -317,6 +386,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Maschinenelement": {
|
"TOS_Maschinenelement": {
|
||||||
"TOS-level": 2,
|
"TOS-level": 2,
|
||||||
|
"_comment" : "5 - Maschinenelement",
|
||||||
"children": {
|
"children": {
|
||||||
"50": "Verbindungselement",
|
"50": "Verbindungselement",
|
||||||
"51": "Lager",
|
"51": "Lager",
|
||||||
@@ -338,6 +408,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Verbindungselement": {
|
"TOS_Verbindungselement": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "50 - Maschinenelement -> Verbindungselement",
|
||||||
"children": {
|
"children": {
|
||||||
"500": "Schraube",
|
"500": "Schraube",
|
||||||
"501": "Mutter",
|
"501": "Mutter",
|
||||||
@@ -352,6 +423,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Lager": {
|
"TOS_Lager": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "51 - Maschinenelement -> Lager",
|
||||||
"children": {
|
"children": {
|
||||||
"510": "Gleitlager",
|
"510": "Gleitlager",
|
||||||
"511": "Wälzlager"
|
"511": "Wälzlager"
|
||||||
@@ -360,6 +432,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Kraft_Drehmoment": {
|
"TOS_Kraft_Drehmoment": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "52 - Maschinenelement -> Kraft-/Drehmomentübertragungselement",
|
||||||
"children": {
|
"children": {
|
||||||
"520": "Zahntriebelement",
|
"520": "Zahntriebelement",
|
||||||
"521": "Kettentriebelement",
|
"521": "Kettentriebelement",
|
||||||
@@ -373,6 +446,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Sicherungselement": {
|
"TOS_Sicherungselement": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "54 - Maschinenelement -> Sicherungselement",
|
||||||
"children": {
|
"children": {
|
||||||
"540": "Schraubensicherung",
|
"540": "Schraubensicherung",
|
||||||
"541": "Wellen-/Bohrungssicherung",
|
"541": "Wellen-/Bohrungssicherung",
|
||||||
@@ -382,6 +456,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Bedienungselement": {
|
"TOS_Bedienungselement": {
|
||||||
"TOS-level": 3,
|
"TOS-level": 3,
|
||||||
|
"_comment" : "55 - Maschinenelement -> Bedienungselement",
|
||||||
"children": {
|
"children": {
|
||||||
"550": "Griffe",
|
"550": "Griffe",
|
||||||
"551": "Hebel",
|
"551": "Hebel",
|
||||||
@@ -392,6 +467,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Schoenenberger_Komponenten": {
|
"TOS_Schoenenberger_Komponenten": {
|
||||||
"TOS-level": 2,
|
"TOS-level": 2,
|
||||||
|
"_comment" : "6 - Schönenberger Komponenten",
|
||||||
"children": {
|
"children": {
|
||||||
"60": "frei",
|
"60": "frei",
|
||||||
"61": "frei",
|
"61": "frei",
|
||||||
@@ -408,8 +484,9 @@
|
|||||||
},
|
},
|
||||||
"TOS_Pneumatik": {
|
"TOS_Pneumatik": {
|
||||||
"TOS-level": 2,
|
"TOS-level": 2,
|
||||||
|
"_comment" : "7 - Pneumatik",
|
||||||
"children": {
|
"children": {
|
||||||
"70": "Pneumatische Antriebe und Zylinder",
|
"70": "Pneumatischer Antrieb und Zylinder",
|
||||||
"71": "Ventil",
|
"71": "Ventil",
|
||||||
"72": "Sensoren und Leitungen",
|
"72": "Sensoren und Leitungen",
|
||||||
"73": "Schlauch",
|
"73": "Schlauch",
|
||||||
@@ -421,6 +498,7 @@
|
|||||||
},
|
},
|
||||||
"TOS_Konfig": {
|
"TOS_Konfig": {
|
||||||
"TOS-level": 2,
|
"TOS-level": 2,
|
||||||
|
"_comment" : "8 - Konfiguration",
|
||||||
"children": {
|
"children": {
|
||||||
"80": "Texte",
|
"80": "Texte",
|
||||||
"81": "Band-Konfiguration",
|
"81": "Band-Konfiguration",
|
||||||
|
|||||||
@@ -7,8 +7,11 @@ Schwermetall
|
|||||||
[Stahl]
|
[Stahl]
|
||||||
1.0035 (S185)
|
1.0035 (S185)
|
||||||
1.0038 (S235JR)
|
1.0038 (S235JR)
|
||||||
|
1.0038+AR (S235JR+AR)
|
||||||
|
1.0038+CR (S235JR+CR)
|
||||||
1.0122 (S235JRC)
|
1.0122 (S235JRC)
|
||||||
1.0122+C (S235JRC+C)
|
1.0122+C (S235JRC+C)
|
||||||
|
1.0242+Z275-M-A-C (S250GD+Z275-M-A-C)
|
||||||
1.0330 (DC01)
|
1.0330 (DC01)
|
||||||
1.0401 (C15)
|
1.0401 (C15)
|
||||||
1.0501 (C35)
|
1.0501 (C35)
|
||||||
@@ -21,6 +24,7 @@ Schwermetall
|
|||||||
1.0715+C (11SMn30+C)
|
1.0715+C (11SMn30+C)
|
||||||
1.0917 (DX51D+Z)
|
1.0917 (DX51D+Z)
|
||||||
1.1191 (C45E)
|
1.1191 (C45E)
|
||||||
|
1.1221 (C60E)
|
||||||
1.2842 (90MnCrV8)
|
1.2842 (90MnCrV8)
|
||||||
1.4035 (X45CrS13)
|
1.4035 (X45CrS13)
|
||||||
1.4301 (X5CrNi18-10)
|
1.4301 (X5CrNi18-10)
|
||||||
@@ -28,18 +32,22 @@ Schwermetall
|
|||||||
1.4310 (X10CrNi18-8)
|
1.4310 (X10CrNi18-8)
|
||||||
1.5023 (38Si7)
|
1.5023 (38Si7)
|
||||||
1.7131 (16MnCr5)
|
1.7131 (16MnCr5)
|
||||||
|
1.7225 (42CrMo4)
|
||||||
siehe Hersteller
|
siehe Hersteller
|
||||||
|
siehe Stückliste
|
||||||
|
|
||||||
[Aluminium]
|
[Aluminium]
|
||||||
EN AW-1050A (3.0255)
|
EN AW-1050A (3.0255)
|
||||||
EN AW-2007 (3.1645)
|
EN AW-2007 (3.1645)
|
||||||
EN AW-2014-T3 (3.1255-T3)
|
EN AW-2014-T3 (3.1255-T3)
|
||||||
EN AW-2014-T4 (3.1255-T4)
|
EN AW-2014-T4 (3.1255-T4)
|
||||||
|
EN AW-5754 (3.3535)
|
||||||
EN AW-6060 (3.3206)
|
EN AW-6060 (3.3206)
|
||||||
EN AW-6060-T66 (3.3206-T66)
|
EN AW-6060-T66 (3.3206-T66)
|
||||||
EN AW-7075 (3.4365)
|
EN AW-7075 (3.4365)
|
||||||
EN AW-6063-T66
|
EN AW-6063-T66
|
||||||
siehe Hersteller
|
siehe Hersteller
|
||||||
|
siehe Stückliste
|
||||||
|
|
||||||
[Kunst-/ Verbundstoff]
|
[Kunst-/ Verbundstoff]
|
||||||
ABS
|
ABS
|
||||||
@@ -48,6 +56,7 @@ CR/SBR-A65
|
|||||||
Hostaform 13031 MB1.5
|
Hostaform 13031 MB1.5
|
||||||
Irogran A87
|
Irogran A87
|
||||||
Murtfeldt "S" 1000
|
Murtfeldt "S" 1000
|
||||||
|
Murtfeldt Original "S" grün
|
||||||
PA
|
PA
|
||||||
PA 2200
|
PA 2200
|
||||||
PA 2200 SLS
|
PA 2200 SLS
|
||||||
@@ -57,32 +66,44 @@ PA 6 GF 30
|
|||||||
PA 66
|
PA 66
|
||||||
PA 66 GF 25
|
PA 66 GF 25
|
||||||
PA 66 GF 30
|
PA 66 GF 30
|
||||||
|
PA 66 GF 50
|
||||||
PA GF 25
|
PA GF 25
|
||||||
PBT
|
PBT
|
||||||
PC
|
PC
|
||||||
|
PC GF 10
|
||||||
PE
|
PE
|
||||||
PE-HD
|
PE-HD
|
||||||
PE-LD
|
PE-LD
|
||||||
PE-UHMW
|
PE-UHMW
|
||||||
|
PE-UHMW antistatisch
|
||||||
POM
|
POM
|
||||||
POM-C
|
POM-C
|
||||||
POM-H
|
POM-H
|
||||||
PP
|
PP
|
||||||
PP-C
|
PP-C
|
||||||
PP-H
|
PP-H
|
||||||
|
PP SLS
|
||||||
|
PP T20
|
||||||
PTFE
|
PTFE
|
||||||
PUR
|
PUR
|
||||||
|
PUR - 95 Shore A
|
||||||
|
PUR D44 - 80 Shore A
|
||||||
PVC
|
PVC
|
||||||
|
PVC-P (weich)
|
||||||
PVC-U
|
PVC-U
|
||||||
siehe Hersteller
|
siehe Hersteller
|
||||||
|
siehe Stückliste
|
||||||
TPU
|
TPU
|
||||||
|
TPU - 95 Shore A
|
||||||
TPU - 98 Shore A
|
TPU - 98 Shore A
|
||||||
|
|
||||||
[Schwermetall]
|
[Schwermetall]
|
||||||
|
CC493K - GC (CuSn7Zn4Pb7 - C - GC)
|
||||||
CW459K (CuSn8P)
|
CW459K (CuSn8P)
|
||||||
CW614N (CuZn39Pb3)
|
CW614N (CuZn39Pb3)
|
||||||
CW708R (CuZn31Si)
|
CW708R (CuZn31Si)
|
||||||
siehe Hersteller
|
siehe Hersteller
|
||||||
|
siehe Stückliste
|
||||||
|
|
||||||
[Festigkeitsklasse]
|
[Festigkeitsklasse]
|
||||||
010.9
|
010.9
|
||||||
|
|||||||
+14
-2
@@ -1,3 +1,15 @@
|
|||||||
[Zielpfade]
|
[Zielpfade]
|
||||||
\\ssg.local\freigaben\SIVAS_CAD_EDM\Migration\02_Bedarfspool
|
Produktiv=\\ssg.local\freigaben\SIVAS_CAD_EDM\Migration\02_Bedarfspool
|
||||||
\\ssg.local\freigaben\SIVAS_CAD_EDM\Schulung\Migration\02_Bedarfspool
|
Schulung=\\ssg.local\freigaben\SIVAS_CAD_EDM\Schulung\Migration\02_Bedarfspool
|
||||||
|
|
||||||
|
[3D-Modelle]
|
||||||
|
BaugruppeSchweissbaugruppe=\\ssg.local\freigaben\Abteilungen\Entwicklung\CAD\Standards\SolidEdge\Template\DIN Metric\baugruppe.asm
|
||||||
|
Kaufteil=\\ssg.local\freigaben\SIVAS_CAD_EDM\Migration\06_3D_Vorlagen\ET_mit_Volumen.par
|
||||||
|
Einzelteil=\\ssg.local\freigaben\SIVAS_CAD_EDM\Migration\06_3D_Vorlagen\ET_mit_Volumen.par
|
||||||
|
EinzelteilDefault=\\ssg.local\freigaben\SIVAS_CAD_EDM\Migration\01_Rohdatenpool\
|
||||||
|
|
||||||
|
# [3D-Modelle]
|
||||||
|
# BaugruppeSchweissbaugruppe=Baugruppe
|
||||||
|
# Kaufteil=Kaufteil
|
||||||
|
# Einzelteil=Einzelteil
|
||||||
|
# EinzelteilDefault=C:\Users\m.stangl\Documents\10-Develop\CreoMigrate\work\test
|
||||||
+20
-13
@@ -1,20 +1,27 @@
|
|||||||
[EinzelTextblöcke]
|
[EinzelTextblöcke]
|
||||||
Version=ACHTUNG Index in Sivas mit Kleinbuchstaben. Nach Freigabe der Teilenummer den großen Index in SIVAS löschen und auf kleinen verlinken. Sobald die Revision höher als '{"Version"}' ist kann Information gelöscht werden.
|
Kleinbuchstabe=ACHTUNG Kleinbuchstaben-Index in SIVAS. Nach Freigabe der Teilenummer in SIVAS den Großbuchstaben-Index löschen, alle Dokumente auf den Kleinbuchstaben-Index verlinken und den Kleinbuchstaben-Index erneut freigeben. Sobald die Revision höher als {aenderungsindex} ist kann diese Zusatzinformation aus RuleDesigner gelöscht werden.
|
||||||
Truemmer=ACHTUNG Trümmerbaugruppe. Nach einer Revision oder Bagatelländerung muss der Rüstcode in der Stücklisten bei allen Stücklistenpositionen manuell in "TR - Trümmerteile" geändert werden.
|
Truemmer=ACHTUNG Trümmerbaugruppe. Nach einer Revision oder Bagatelländerung muss der Rüstcode in der SIVAS-Stückliste bei allen Stücklistenpositionen manuell in "TR - Trümmerteile" geändert werden.
|
||||||
Blacklist=ACHTUNG BG mit Beistellungen. Es wird keine Stückliste übergeben. Diese muss bei einer Änderung händisch angelegt und archiviert werden. Hierfür die Verantwortlichen für den Teilestamm informieren.
|
BlacklistBG=ACHTUNG BG mit Beistellungen. Es wird keine Stückliste übergeben. Diese muss bei einer Änderung händisch angelegt und archiviert werden. Hierfür die Verantwortlichen für den Teilestamm informieren.
|
||||||
|
BlacklistHZ=ACHTUNG Bearbeitetes Halbzeug mit Beistellungen. Es wird keine Stückliste übergeben. Diese muss bei einer Änderung händisch angelegt und archiviert werden. Hierfür die Verantwortlichen für den Teilestamm informieren.
|
||||||
Werkstoffdiskrepanz=ACHTUNG Materialdiskrepanz. SIVAS-Material und/oder Zeichnungsmaterial / geliefertes Material unterschiedlich. Muss abgeklärt werden. Näheres siehe JIRA.
|
Werkstoffdiskrepanz=ACHTUNG Materialdiskrepanz. SIVAS-Material und/oder Zeichnungsmaterial / geliefertes Material unterschiedlich. Muss abgeklärt werden. Näheres siehe JIRA.
|
||||||
|
Dispoinaktiv=ACHTUNG BG mit dispoinaktiven Stücklistenpositionen. Es wird keine Stückliste übergeben. Diese muss bei einer Änderung händisch angelegt und archiviert werden. Hierfür die Verantwortlichen für den Teilestamm informieren.
|
||||||
|
|
||||||
[ComboTextblöcke]
|
[ComboTextblöcke]
|
||||||
VersionTruemmer=ACHTUNG Index in Sivas mit Kleinbuchstaben + Trümmerbaugruppe. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
KleinbuchstabeTruemmer=ACHTUNG Index in Sivas mit Kleinbuchstaben + Trümmerbaugruppe. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
VersionBlacklist=ACHTUNG Index in Sivas mit Kleinbuchstaben + BG mit Beistellungen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
KleinbuchstabeBlacklistBG=ACHTUNG Index in Sivas mit Kleinbuchstaben + BG mit Beistellungen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
VersionWerkstoffdiskrepanz=ACHTUNG Index in Sivas mit Kleinbuchstaben + Materialdiskrepanz. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
KleinbuchstabeWerkstoffdiskrepanz=ACHTUNG Index in Sivas mit Kleinbuchstaben + Materialdiskrepanz. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
TruemmerBlacklist=ACHTUNG Trümmerbaugruppe + BG mit Beistellungen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
KleinbuchstabeDispoinaktiv=ACHTUNG Index in Sivas mit Kleinbuchstaben + BG mit Dispoinaktiven Stücklistenpositionen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
|
TruemmerBlacklistBG=ACHTUNG Trümmerbaugruppe + BG mit Beistellungen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
TruemmerWerkstoffdiskrepanz=ACHTUNG Trümmerbaugruppe + Materialdiskrepanz. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
TruemmerWerkstoffdiskrepanz=ACHTUNG Trümmerbaugruppe + Materialdiskrepanz. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
VersionTruemmerBlacklist=ACHTUNG Index in Sivas mit Kleinbuchstaben + Trümmerbaugruppe + BG mit Beistellungen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
TruemmerDispoinaktiv=ACHTUNG Trümmerbaugruppe + BG mit dispoinaktiven Stücklistenpositionen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
|
KleinbuchstabeTruemmerBlacklist=ACHTUNG Index in Sivas mit Kleinbuchstaben + Trümmerbaugruppe + BG mit Beistellungen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
|
KleinbuchstabeTruemmerDispoinaktiv=ACHTUNG Index in Sivas mit Kleinbuchstaben + Trümmerbaugruppe + BG mit dispoinaktiven Stücklistenpositionen. Ausführliche Informationen zu erforderlichen Tätigkeiten / potentiellen Fehlern vgl. Konstruktionsrichtlinien
|
||||||
|
BlacklistHZDispoinaktiv=ACHTUNG Bearbeitetes Halbzeug mit beigestellten und dispoinaktiven Stücklistenpositionen. Es wird keine Stückliste übergeben. Diese muss bei einer Änderung händisch angelegt und archiviert werden. Hierfür die Verantwortlichen für den Teilestamm informieren.
|
||||||
|
BlacklistBGDispoinaktiv=ACHTUNG BG mit beigestellten und dispoinaktiven Stücklistenpositionen. Es wird keine Stückliste übergeben. Diese muss bei einer Änderung händisch angelegt und archiviert werden. Hierfür die Verantwortlichen für den Teilestamm informieren.
|
||||||
|
|
||||||
;Nachfolgende Kombinationen können nicht auftreten:
|
;Nachfolgende Kombinationen können nicht auftreten:
|
||||||
;- BlacklistWerkstoffdiskrepanz
|
;- BlacklistBGWerkstoffdiskrepanz
|
||||||
;- VersionTruemmerWerkstoffdiskrepanz
|
;- KleinbuchstabeTruemmerWerkstoffdiskrepanz
|
||||||
;- VersionBlacklistWerkstoffdiskrepanz
|
;- KleinbuchstabeBlacklistBGWerkstoffdiskrepanz
|
||||||
;- TruemmerBlacklistWerkstoffdiskrepanz=
|
;- TruemmerBlacklistBGWerkstoffdiskrepanz
|
||||||
;- VersionTruemmerBlacklistWerkstoffdiskrepanz=
|
;- KleinbuchstabeTruemmerBlacklistBGWerkstoffdiskrepanz
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Fenster]
|
||||||
|
#Büro-Auflösung (hochformat)
|
||||||
|
CanvasBreite=1080
|
||||||
|
CanvasHoehe=1490
|
||||||
|
Dimension=1080x1490
|
||||||
|
|
||||||
|
# Homeoffice Auflösung (querformat)
|
||||||
|
# CanvasBreite=1000
|
||||||
|
# CanvasHoehe=1350
|
||||||
|
# Dimension=1100x1400
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
[Fenster]
|
||||||
|
CanvasBreite=950
|
||||||
|
CanvasHoehe=1450
|
||||||
|
Dimension=970x900
|
||||||
@@ -44,15 +44,15 @@
|
|||||||
inkscape:pageopacity="0"
|
inkscape:pageopacity="0"
|
||||||
inkscape:pagecheckerboard="0"
|
inkscape:pagecheckerboard="0"
|
||||||
inkscape:deskcolor="#646464"
|
inkscape:deskcolor="#646464"
|
||||||
inkscape:zoom="0.5"
|
inkscape:zoom="0.70710678"
|
||||||
inkscape:cx="178"
|
inkscape:cx="499.21739"
|
||||||
inkscape:cy="769"
|
inkscape:cy="1096.7226"
|
||||||
inkscape:window-width="2560"
|
inkscape:window-width="1920"
|
||||||
inkscape:window-height="1377"
|
inkscape:window-height="1017"
|
||||||
inkscape:window-x="-8"
|
inkscape:window-x="-8"
|
||||||
inkscape:window-y="-8"
|
inkscape:window-y="108"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="g107"
|
inkscape:current-layer="g1"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
showguides="true"><inkscape:page
|
showguides="true"><inkscape:page
|
||||||
x="0"
|
x="0"
|
||||||
@@ -1921,10 +1921,6 @@
|
|||||||
id="path207"
|
id="path207"
|
||||||
d="m 1677.5192,1265.858 0.061,21.9234 -232.6023,0.3586 v -22.282 z"
|
d="m 1677.5192,1265.858 0.061,21.9234 -232.6023,0.3586 v -22.282 z"
|
||||||
style="fill:none;stroke:#afafaf;stroke-width:1.50001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
style="fill:none;stroke:#afafaf;stroke-width:1.50001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
sodipodi:nodetypes="ccccc" /><path
|
|
||||||
id="path208"
|
|
||||||
d="m 1941.7978,1265.858 0.061,21.9234 -232.6023,0.3586 v -21.9233 z"
|
|
||||||
style="fill:none;stroke:#afafaf;stroke-width:1.50001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
sodipodi:nodetypes="ccccc" /></g><g
|
sodipodi:nodetypes="ccccc" /></g><g
|
||||||
id="g44"
|
id="g44"
|
||||||
transform="translate(-0.03690938,1.4420048)"><text
|
transform="translate(-0.03690938,1.4420048)"><text
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 164 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
+120
-91
@@ -8,9 +8,9 @@ Beim Doppelklick auf eine bereits migrierte Teilenummer dürfen die Formularfeld
|
|||||||
**Allgemeine Hinweise:**
|
**Allgemeine Hinweise:**
|
||||||
1. Für jedes der nachfolgend aufgelisteten Feldnamen (z.B. "Teilenummer") soll ein Label-Widget in der 1. Spalte "Feld" der GUI erstellt werden. Labeltext ist jeweils der Feldname. Ausnahme ist das Feld "Baugruppennummer", bei dem das Label und ein Entry-Feld oberhalb des Treeviews liegen.
|
1. Für jedes der nachfolgend aufgelisteten Feldnamen (z.B. "Teilenummer") soll ein Label-Widget in der 1. Spalte "Feld" der GUI erstellt werden. Labeltext ist jeweils der Feldname. Ausnahme ist das Feld "Baugruppennummer", bei dem das Label und ein Entry-Feld oberhalb des Treeviews liegen.
|
||||||
2. Die eingetragenen Feldwerte sollen in einer json-Datei gespeichert werden. Wird eine Teilenummer geöffnet/bearbeitet, für die bereits eine json-Datei exisitert, müssen die Felder mit den Werten aus dieser json-Datei befüllt werden. Nur beim erstmaligen Öffnen/Bearbeiten einer Teilenummer dürfen Felder geleert oder auf den Defaultwert umgestellt werden. Art und Umfang dieser initialen Feldanpassungen wird in den nachfolgenden Feldspezifikationen näher beschrieben.
|
2. Die eingetragenen Feldwerte sollen in einer json-Datei gespeichert werden. Wird eine Teilenummer geöffnet/bearbeitet, für die bereits eine json-Datei exisitert, müssen die Felder mit den Werten aus dieser json-Datei befüllt werden. Nur beim erstmaligen Öffnen/Bearbeiten einer Teilenummer dürfen Felder geleert oder auf den Defaultwert umgestellt werden. Art und Umfang dieser initialen Feldanpassungen wird in den nachfolgenden Feldspezifikationen näher beschrieben.
|
||||||
3. Defaultwert bedeutet, dass beim Bearbeiten einer **neuen** Teilenummer, die noch keine json-Datei besitzt, ein bestimmter, voreingestellter Wert eingetragen / vorausgewählt ist
|
3. Defaultwert bedeutet in den nachfolgenden Feldspezifikationen, dass beim Doppelklick auf eine Teilenummer im Treeview, die zum ersten mal bearbeitet wird (also noch keine json-Speicherdatei im [work-Ordner](../work/) exisitiert (siehe oben Punkt 2)), ein bestimmter, voreingestellter Wert in das Feld eingetragen / vorausgewählt wird
|
||||||
4. "state" beschreibt in den nachfolgenden Feldspezifikationen den Parameter "state" des tk-Widgets. Dieser Parameter definiert, in welchem Umfang ein User mit dem Widget interagieren kann
|
4. "state" beschreibt in den nachfolgenden Feldspezifikationen den Parameter "state" des tk-Widgets. Dieser Parameter definiert, in welchem Umfang ein User mit dem Widget interagieren kann. Beispiel: bei einem Eingabefeld (Entry) sorgt der state "readonly" dafür, dass kein Text in das Eingabefeld eingetragen, aber der Text daraus kopiert werden kann. Hingegen kann beim state "disabled" weder Text eingetragen, noch kopiert werden. Wird überhaupt kein state vorgegeben, kann der User wiederum sowohl Text eingeben, als auch Text kopieren.
|
||||||
5. "from_siv.csv" beschreibt nachfolgend die CSV-Datei, welche die Teilestamminformationen zu einer Teilenummer enthält. Die CSV wird durch den Sivas-internen Prozess "ExcelUeb" von Hr. Jakob erzeugt (siehe auch [get_sivas_teilestamm.py](../lib/get_sivas_teilestamm.py))
|
5. "from_siv.csv" beschreibt nachfolgend die CSV-Datei, welche die Teilestamminformationen zu einer Teilenummer enthält. Die CSV wird durch den Sivas-internen Prozess "ExcelUeb" von Hr. Jakob erzeugt (der Aufruf des Prozesses erfolgt im Pythonprogramm [get_sivas_teilestamm.py](../lib/get_sivas_teilestamm.py))
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -41,7 +41,8 @@ Besitzt die eingetragenen Teilenummer keine Stückliste, soll im Treeview nur di
|
|||||||
>**Pflichtfeld:** Ja, immer
|
>**Pflichtfeld:** Ja, immer
|
||||||
---
|
---
|
||||||
#### **Spalte 2: SIVAS-Werte**
|
#### **Spalte 2: SIVAS-Werte**
|
||||||
>**Widget-Typ:** Entry
|
>**Widget:**
|
||||||
|
>**Typ:** Entry
|
||||||
>**state:** readonly
|
>**state:** readonly
|
||||||
|
|
||||||
>**Wert:** Aus Spalte "Teilenummer" in "from_siv.csv"
|
>**Wert:** Aus Spalte "Teilenummer" in "from_siv.csv"
|
||||||
@@ -77,7 +78,8 @@ Wird zur Definierung des Wertes in der Spalte "New Path" benötigt, siehe [Impfd
|
|||||||
>**Pflichtfeld:** Ja, immer
|
>**Pflichtfeld:** Ja, immer
|
||||||
---
|
---
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
>**Werte:** Sektion "Kategorien" in [Allgemein.cfg](../cfg/Allgemein.cfg)
|
>**Werte:** Sektion "Kategorien" in [Allgemein.cfg](../cfg/Allgemein.cfg)
|
||||||
>**Defaultwert:** Leer -> Kategoriefestlegung kann nicht automatisch erfolgen
|
>**Defaultwert:** Leer -> Kategoriefestlegung kann nicht automatisch erfolgen
|
||||||
>**state:** readonly
|
>**state:** readonly
|
||||||
@@ -437,26 +439,27 @@ Der Wert aus der Spalte "HzOhneSaegeliste" in "from_siv.csv" muss in gemappter /
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
>**Defaultwert:** "" (leer)
|
>**Defaultwert:** "" (leer)
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
- state der ComboBox je nach Situation (readonly / disabled)
|
- state der ComboBox je nach Situation (readonly / disabled)
|
||||||
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
||||||
|
-
|
||||||
|
|
||||||
IF PDM-Kategorie == "Baugruppe":
|
IF PDM-Kategorie == "Baugruppe":
|
||||||
Dropdownwerte = None (keine Werte)
|
Dropdownwerte = None (keine Werte)
|
||||||
state = disabled
|
state = disabled
|
||||||
|
|
||||||
ELSE IF PDM-Kategorie != "Baugruppe":
|
ELSE IF PDM-Kategorie != "Baugruppe":
|
||||||
IF Rüstcode == "HZS Halbzeuge Sägeteile":
|
IF Rüstcode == "HZS Halbzeuge Sägeteile":
|
||||||
Dropdownwerte = Sektion "HalbzeugOhneSaegeliste" aus Allgemein.cfg
|
Dropdownwerte = Sektion "HalbzeugOhneSaegeliste" aus Allgemein.cfg
|
||||||
state = readonly
|
state = readonly
|
||||||
|
|
||||||
ELSE IF Rüstcode == "SRC Standard Rüstcode":
|
ELSE IF Rüstcode == "SRC Standard Rüstcode":
|
||||||
Dropdownwerte = None (keine Werte)
|
Dropdownwerte = None (keine Werte)
|
||||||
state = disabled
|
state = disabled
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **Migration**
|
#### **Migration**
|
||||||
@@ -479,7 +482,8 @@ Der Wert aus der Spalte "HzOhneSaegeliste" in "from_siv.csv" muss in gemappter /
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
>**state:** readonly
|
>**state:** readonly
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
@@ -541,7 +545,8 @@ Es muss geprüft werden, ob ein zulässiger Rüstcode eingetragen ist, siehe [Fe
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
||||||
@@ -599,7 +604,8 @@ Es muss geprüft werden, ob ein zulässiger Rüstcode eingetragen ist, siehe [Fe
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
||||||
@@ -690,7 +696,8 @@ Es muss geprüft werden, ob ein zulässiger Rüstcode eingetragen ist, siehe [Fe
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
||||||
@@ -746,7 +753,8 @@ Es muss geprüft werden, ob ein zulässiger Rüstcode eingetragen ist, siehe [Fe
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
||||||
@@ -808,7 +816,8 @@ Der Wert "Eigenbaugruppe" aus der Spalte "Beschaffungsart" in "from_siv.csv" mus
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
- Dropdownwerte (Quelle, wo die Dropdownwerte zu finden sind, bzw. direkt die Werte)
|
||||||
@@ -873,7 +882,8 @@ Der Wert "Eigenbaugruppe" aus der Spalte "Beschaffungsart" in "from_siv.csv" mus
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
>**Defaultwert:** Keiner (leer)
|
>**Defaultwert:** Keiner (leer)
|
||||||
>**Read only:** Ja
|
>**Read only:** Ja
|
||||||
|
|
||||||
@@ -1190,7 +1200,8 @@ Der Text vor dem Herstellernamen (besteht aus Herstellernummer + Zeichenkette "
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** Entry
|
>**Widget:**
|
||||||
|
>**Typ:** Entry
|
||||||
>**Defaultwert:** "" (keiner)
|
>**Defaultwert:** "" (keiner)
|
||||||
|
|
||||||
**Nachfolgende Logik definiert:**
|
**Nachfolgende Logik definiert:**
|
||||||
@@ -1353,7 +1364,8 @@ Vor der Erstellung der Impfdatei muss geprüft werden, ob ein gültiger Werkstof
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** ComboBox
|
>**Widget:**
|
||||||
|
>**Typ:** ComboBox
|
||||||
|
|
||||||
- state der ComboBox je nach Situation (readonly / disabled)
|
- state der ComboBox je nach Situation (readonly / disabled)
|
||||||
|
|
||||||
@@ -1661,22 +1673,13 @@ Erfolgt eine Wertänderung in der ComboBox des Feldes [Werkstofftyp](#werkstofft
|
|||||||
|
|
||||||
>**Wert:** Aus Spalte "Version" in "from_siv.csv"
|
>**Wert:** Aus Spalte "Version" in "from_siv.csv"
|
||||||
|
|
||||||
---
|
In diesem Feld soll informativ der Wert aus dem SIVAS-Feld "Version" dargestellt werden.
|
||||||
|
Der Feldwert wird für die Bestimmung des [Freigabevermerks](#freigabevermerk) benötigt
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
|
||||||
>**Widget:**
|
|
||||||
>**Typ:** Entry
|
|
||||||
|
|
||||||
|
|
||||||
#### **Migration**
|
|
||||||
>**Spaltenname Impfdatei:** Wird nicht in Impfdatei berücksichtigt
|
|
||||||
|
|
||||||
- Wird für die Bestimmung des [Freigabevermerks](#freigabevermerk) benötigt
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Änderungsindex
|
### Änderungsindex
|
||||||
>**Pflichtfeld:** Nein
|
>**Pflichtfeld:** Ja
|
||||||
---
|
---
|
||||||
#### **Spalte 2: SIVAS-Werte**
|
#### **Spalte 2: SIVAS-Werte**
|
||||||
>**Widget:**
|
>**Widget:**
|
||||||
@@ -1687,14 +1690,27 @@ Erfolgt eine Wertänderung in der ComboBox des Feldes [Werkstofftyp](#werkstofft
|
|||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** Entry
|
>**Widget:**
|
||||||
|
>**Typ:** Entry
|
||||||
|
>**state:** disabled
|
||||||
|
|
||||||
|
**Logik, die steuert, welcher Defaultwert gilt:**
|
||||||
|
|
||||||
|
IF Wert in Spalte "AktuellerIndex" in "from_siv.csv" == "" (leer):
|
||||||
|
Defaultwert = "A"
|
||||||
|
|
||||||
|
ELSE IF Wert in Spalte "AktuellerIndex" in "from_siv.csv" == Kleinbuchstabe:
|
||||||
|
Defaultwert = Großbuchstabe (des Buchstabens, der in Spalte "AktuellerIndex" steht)
|
||||||
|
|
||||||
|
Beispiel für diesen Fall:
|
||||||
|
In Spalte "AktuellerIndex" steht der Kleinbuchstabe "b". Dann soll in das Entry-Feld der Großbuchstabe "B" eingetragen werden
|
||||||
|
|
||||||
|
ELSE:
|
||||||
|
Defaultwert = "" (leer)
|
||||||
|
|
||||||
#### **Migration**
|
#### **Migration**
|
||||||
>**Spaltenname Impfdatei:** StartRevision
|
>**Spaltenname Impfdatei:** StartRevision
|
||||||
|
|
||||||
Liegt kein Änderungsindex vor, muss "A" in die Impfdatei eingetragen werden (siehe [Impfdateierstellung](#tätigkeiten-im-rahmen-der-impfdateierstellung))
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Änderungstext
|
### Änderungstext
|
||||||
@@ -1707,18 +1723,19 @@ Liegt kein Änderungsindex vor, muss "A" in die Impfdatei eingetragen werden (si
|
|||||||
>**Wert:** Aus Spalte "Aenderungstext" in "from_siv.csv"
|
>**Wert:** Aus Spalte "Aenderungstext" in "from_siv.csv"
|
||||||
|
|
||||||
**Aufgaben beim Einlesen des Wertes aus "from_siv.csv":**
|
**Aufgaben beim Einlesen des Wertes aus "from_siv.csv":**
|
||||||
- Semikolon (einschließlich vor- und nachgesetztem Leerzeichen) sollen durch ein Slash mit vor- und nachgesetztem Leerzeichen (" / ") ersetzt werden. Beispiel:
|
- Semikolon (einschließlich gegebenenfalls vor- und nachgesetztem Leerzeichen) sollen durch ein Slash mit vor- und nachgesetztem Leerzeichen (" / ") ersetzt werden. Beispiel:
|
||||||
- Änderungstext in "from_siv.csv": "Gewindebohrung auf M5 vergrößert (war M4); Fasen entfernt"
|
- Änderungstext in "from_siv.csv": "Gewindebohrung auf M5 vergrößert (war M4); Fasen entfernt"
|
||||||
- Änderungstext nach dem Einlesen: "Gewindebohrung auf M5 vergrößert (war M4) / Fasen entfernt"
|
- Änderungstext nach dem Einlesen: "Gewindebohrung auf M5 vergrößert (war M4) / Fasen entfernt"
|
||||||
|
|
||||||
- Wenn die Spalte "Aenderungstext" in "from_siv.csv" einen Wert enthält, soll der Textbaustein "(von {Wert aus Spalte "Indexerfasser in 'from_siv.csv'})" angehängt werden, Beispiel:
|
- Wenn die Spalte "Aenderungstext" in "from_siv.csv" einen Wert enthält, soll der Textbaustein " (von {Wert aus Spalte "Indexerfasser" in 'from_siv.csv'})" angehängt werden, Beispiel:
|
||||||
- Änderungstext in "from_siv.csv": "Biegeradius auf R5 vergrößert (war R4)"
|
- Änderungstext in "from_siv.csv": "Biegeradius auf R5 vergrößert (war R4)"
|
||||||
- Änderungstext nach dem Einlesen: "Biegeradius auf R5 vergrößert (war R4) (von M.SCHNEIDER)"
|
- Änderungstext nach dem Einlesen: "Biegeradius auf R5 vergrößert (war R4) (von M.SCHNEIDER)"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** Text (mehrzeilig)
|
>**Widget:**
|
||||||
|
>**Typ:** Text (mehrzeilig)
|
||||||
>**Zeichenbegrenzung:** 400
|
>**Zeichenbegrenzung:** 400
|
||||||
|
|
||||||
**Bestimmung der Zeichenbegrenzung:**
|
**Bestimmung der Zeichenbegrenzung:**
|
||||||
@@ -1726,23 +1743,23 @@ Wenn die Länge des Änderungstextes in der Spalte "SIVAS-Werte" die Zeichengren
|
|||||||
|
|
||||||
**Logik, die steuert, welcher Defaultwert gilt:**
|
**Logik, die steuert, welcher Defaultwert gilt:**
|
||||||
|
|
||||||
IF Wert aus Spalte "Aenderungstext" in "from_siv.csv" == "":
|
IF Wert aus Spalte "Aenderungstext" in "from_siv.csv" == "" (leer):
|
||||||
|
|
||||||
IF PDM-Kategorie == "Kaufteil":
|
IF Wert aus Spalte "AktuellerIndex" in "from_siv.csv" == "" (leer):
|
||||||
Defaultwert = "Erstanlage"
|
Defaultwert = "Erstanlage"
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
Defaultwert = "Erstanlage (von {Indexerfasser})"
|
Defaultwert = "Erstanlage (von {Wert aus Spalte "Indexerfasser" in "from_siv.csv"})"
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
Defaultwert = ""
|
Defaultwert = "" (leer)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **Migration**
|
#### **Migration**
|
||||||
>**Spaltenname in Impfdatei:** Änderungsbeschreibung
|
>**Spaltenname in Impfdatei:** Änderungsbeschreibung
|
||||||
|
|
||||||
Es muss vor Erstellung der Impfdatei eine Längenprüfung durchgeführt werden, siehe [Tätigkeiten vor Erstellung der Impfdatei](#tätigkeiten-vor-erstellung-der-impfdatei)
|
Es muss vor Erstellung der Impfdatei eine Längenprüfung durchgeführt werden, siehe [Feldprüfung Änderungstext](#änderungstext)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -1756,43 +1773,44 @@ Es muss vor Erstellung der Impfdatei eine Längenprüfung durchgeführt werden,
|
|||||||
>**Wert:** Aus Spalte "Freigabevermerk" in "from_siv.csv"
|
>**Wert:** Aus Spalte "Freigabevermerk" in "from_siv.csv"
|
||||||
|
|
||||||
**Aufgaben beim Einlesen des Wertes aus "from_siv.csv":**
|
**Aufgaben beim Einlesen des Wertes aus "from_siv.csv":**
|
||||||
- Semikolon (einschließlich vor- und nachgesetztem Leerzeichen) sollen durch ein Slash mit vor- und nachgesetztem Leerzeichen (" / ") ersetzt werden. Beispiel:
|
- Semikolon (einschließlich gegebenenfalls vor- und nachgesetztem Leerzeichen) sollen durch ein Slash mit vor- und nachgesetztem Leerzeichen (" / ") ersetzt werden. Beispiel:
|
||||||
- Freigabevermerk in "from_siv.csv": "Verringerte Rissgefahr durch größeren Biegeradius; Kostenreduktion durch geringere Blechstärke"
|
- Freigabevermerk in "from_siv.csv": "Verringerte Rissgefahr durch größeren Biegeradius; Kostenreduktion durch geringere Blechstärke"
|
||||||
- Freigabevermerk nach dem Einlesen: "Verringerte Rissgefahr durch größeren Biegeradius / Kostenreduktion durch geringere Blechstärke"
|
- Freigabevermerk nach dem Einlesen: "Verringerte Rissgefahr durch größeren Biegeradius / Kostenreduktion durch geringere Blechstärke"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **Spalte 3: Überschriebene Werte**
|
#### **Spalte 3: Überschriebene Werte**
|
||||||
>**Widget-Typ:** Text (mehrzeilig)
|
>**Widget:**
|
||||||
|
>**Typ:** Text (mehrzeilig)
|
||||||
>**Zeichenbegrenzung:** 400
|
>**Zeichenbegrenzung:** 400
|
||||||
|
|
||||||
**Bestimmung der Zeichenbegrenzung:**
|
**Bestimmung der Zeichenbegrenzung:**
|
||||||
Wie beim Feld [Änderungstext](#änderungstext)
|
Wie beim Feld [Änderungstext](#aenderungstext)
|
||||||
|
|
||||||
**Logik, die steuert, welcher Defaultwert gilt:**
|
**Logik, die steuert, welcher Defaultwert gilt:**
|
||||||
|
|
||||||
IF Wert aus Spalte "Freigabevermerk" in "from_siv.csv" == "":
|
IF Wert aus Spalte "Freigabevermerk" in "from_siv.csv" == "":
|
||||||
|
|
||||||
IF PDM-Kategorie == "Kaufteil":
|
IF PDM-Kategorie == "Kaufteil":
|
||||||
Defaultwert = ""
|
Defaultwert = "" (leer)
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
|
|
||||||
IF Wert aus Spalte "Version" in "from_siv.csv" == 6 aufeinanderfolgende Zahlen:
|
IF Wert aus Spalte "Version" in "from_siv.csv" == genau 6 aufeinanderfolgende Zahlen:
|
||||||
Freigabevermerk = "Anpassung an neues Indexsystem, Zeichnung mit Versionsnummer {Wert aus Feld 'Version'} weiterhin gültig"
|
Freigabevermerk = "Anpassung an neues Indexsystem, Zeichnung mit Versionsnummer {Wert aus Spalte 'Version' in "from_siv.csv"} weiterhin gültig"
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
Defaultwert = ""
|
Defaultwert = "" (leer)
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
Defaultwert = ""
|
Defaultwert = "" (leer)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **Migration**
|
#### **Migration**
|
||||||
>**Spaltenname in Impfdatei:** Freigabevermerk
|
>**Spaltenname in Impfdatei:** Freigabevermerk
|
||||||
|
|
||||||
Es muss vor Erstellung der Impfdatei eine Längenprüfung durchgeführt werden, siehe [Tätigkeiten vor Erstellung der Impfdatei](#tätigkeiten-vor-erstellung-der-impfdatei)
|
Es muss vor Erstellung der Impfdatei eine Längenprüfung durchgeführt werden, siehe [Feldprüfung Freigabevermerk](#freigabevermerk-1)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -1802,45 +1820,45 @@ Es muss vor Erstellung der Impfdatei eine Längenprüfung durchgeführt werden,
|
|||||||
>**Widget:**
|
>**Widget:**
|
||||||
>**Typ:** Text (mehrzeilig)
|
>**Typ:** Text (mehrzeilig)
|
||||||
>**Zeichenbegrenzung:** 400
|
>**Zeichenbegrenzung:** 400
|
||||||
>**disabled:** Ja
|
>**state:** readonly
|
||||||
|
|
||||||
**Logik, die steuert, welche vordefinierten Textblöcke je nach Situation in das Textfeld eingetragen werden sollen:**
|
**Logik, die steuert, welcher vordefinierte Textblock je nach Situation in das Textfeld eingetragen werden soll:**
|
||||||
|
|
||||||
Hinweis:
|
- Die nachfolgend aufgeführten Sektionen "EinzelTextblöcke" und "ComboTextblöcke" sind in der cfg-Datei [Zusatzinformationen.cfg](../cfg/Zusatzinformationen.cfg) enthalten.
|
||||||
Die nachfolgend aufgeführten Sektionen "EinzelTextblöcke" und "ComboTextblöcke" sind in der cfg-Datei [Zusatzinformationen.cfg](../cfg/Zusatzinformationen.cfg) enthalten.
|
- Wenn in den nachfolgenden aufgelisteten Fällen der Fall "Text = Sektion "EinzelTextblöcke" -> Key "Kleinbuchstabe" gilt, muss der Text "{"Änderungsindex"}", der sich innerhalb des zutreffenden Textblockes in [Zusatzinformationen.cfg](../cfg/Zusatzinformationen.cfg) befindet, durch den Wert aus "self.aenderungsindex_neu" ersetzt werden (also den Wert aus dem Feld [Änderungsindex](#änderungsindex) in der GUI-Spalte "Überschrieberne Werte")
|
||||||
|
|
||||||
IF Version == Kleinbuchstabe:
|
IF Änderungsindex == Kleinbuchstabe:
|
||||||
|
|
||||||
IF Trümmer == True OR Rüstcode == "":
|
IF Trümmer == True OR Rüstcode == "":
|
||||||
Text = Sektion "ComboTextblöcke" -> Key "VersionTruemmer"
|
Text = Sektion "ComboTextblöcke" -> Key "KleinbuchstabeTruemmer"
|
||||||
|
|
||||||
IF Teilenummer in Blacklist:
|
IF Teilenummer in Blacklist:
|
||||||
Text = Sektion "ComboTextblöcke" -> Key "VersionTruemmerBlacklist"
|
Text = Sektion "ComboTextblöcke" -> Key "KleinbuchstabeTruemmerBlacklist"
|
||||||
|
|
||||||
ELSE IF Teilenummer in Blacklist:
|
ELSE IF Teilenummer in Blacklist:
|
||||||
Text = Sektion "ComboTextblöcke" -> Key "VersionBlacklist"
|
Text = Sektion "ComboTextblöcke" -> Key "KleinbuchstabeBlacklist"
|
||||||
|
|
||||||
ELSE IF Werkstoffdiskrepanz == True:
|
ELSE IF Werkstoffdiskrepanz == True:
|
||||||
Text = Sektion "ComboTextblöcke" -> Key "VersionWerkstoffdiskrepanz"
|
Text = Sektion "ComboTextblöcke" -> Key "KleinbuchstabeWerkstoffdiskrepanz"
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
Text = Sektion "EinzelTextblöcke" -> Key "Version"
|
Text = Sektion "EinzelTextblöcke" -> Key "Kleinbuchstabe"
|
||||||
|
|
||||||
ELSE IF Trümmer == True OR "Rüstcode" == "":
|
ELSE IF Trümmer == True OR "Rüstcode" == "":
|
||||||
|
|
||||||
IF Teilenummer in Blacklist:
|
IF Teilenummer in Blacklist:
|
||||||
Text = Sektion "ComboTextblöcke" -> Key "TruemmerBlacklist"
|
Text = Sektion "ComboTextblöcke" -> Key "TruemmerBlacklist"
|
||||||
|
|
||||||
ELSE IF Werkstoffdiskrepanz == True:
|
ELSE IF Werkstoffdiskrepanz == True:
|
||||||
Text = Sektion "ComboTextblöcke" -> Key "TruemmerWerkstoffdiskrepanz"
|
Text = Sektion "ComboTextblöcke" -> Key "TruemmerWerkstoffdiskrepanz"
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
Text = Sektion "EinzelTextblöcke" -> Key "Truemmer"
|
Text = Sektion "EinzelTextblöcke" -> Key "Truemmer"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **Migration**
|
#### **Migration**
|
||||||
>**Spaltenname Impfdatei:** keine eigene Spalte -> Wird zur Definierung des Wertes in der Spalte "ZusaetzlicheInformationen" benötigt, siehe [Impfdateierstellung](#tätigkeiten-im-rahmen-der-impfdateierstellung)
|
>**Spaltenname Impfdatei:** keine eigene Spalte -> Wird zur Definierung des Wertes in der Spalte "ZusaetzlicheInformationen" benötigt, siehe [Impfdateierstellung - Zusätzliche Informationen](#zusaetzlicheinformationen)
|
||||||
|
|
||||||
|
|
||||||
### Benutzerdefinierte Zusatzinformationen
|
### Benutzerdefinierte Zusatzinformationen
|
||||||
@@ -1848,18 +1866,19 @@ Die nachfolgend aufgeführten Sektionen "EinzelTextblöcke" und "ComboTextblöck
|
|||||||
|
|
||||||
>**Widget:**
|
>**Widget:**
|
||||||
>**Typ:** Text (mehrzeilig)
|
>**Typ:** Text (mehrzeilig)
|
||||||
>**disabled:** Nein
|
>**state:** keiner
|
||||||
|
|
||||||
**Bestimmung der Zeichenbegrenzung:**
|
**Bestimmung der Zeichenbegrenzung:**
|
||||||
Die Zeichenbegrenzung berechnet sich wie folgt:
|
Die Zeichenbegrenzung berechnet sich wie folgt:
|
||||||
|
|
||||||
Zeichenbegrenzung = 400 - Aktuelle Anzahl an Zeichen im Textfeld [Automatische Zusatzinformationen](#automatische-zusatzinformationen)
|
Zeichenbegrenzung = 400 - Aktuelle Anzahl an Zeichen im Textfeld [Automatische Zusatzinformationen](#automatische-zusatzinformationen)
|
||||||
|
|
||||||
|
Sobald die Zeichenbegrenzung erreicht ist soll der User keine weiteren Zeichen eintippen können, bzw. wenn der User weitere Zeichen eintippt, sollen diese nicht mehr dargestellt werden.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **Migration**
|
#### **Migration**
|
||||||
>**Spaltenname Impfdatei:** keine eigene Spalte -> Wird zur Definierung des Wertes in der Spalte "ZusaetzlicheInformationen" benötigt, siehe [Impfdateierstellung](#tätigkeiten-im-rahmen-der-impfdateierstellung)
|
>**Spaltenname Impfdatei:** keine eigene Spalte -> Wird zur Definierung des Wertes in der Spalte "ZusaetzlicheInformationen" benötigt, siehe [Impfdateierstellung - Zusätzliche Informationen](#zusaetzlicheinformationen)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Button Migrieren
|
## Button Migrieren
|
||||||
@@ -1878,7 +1897,7 @@ Zeichenbegrenzung = 400 - Aktuelle Anzahl an Zeichen im Textfeld [Automatische Z
|
|||||||
|
|
||||||
#### Allgemeine Prüfungen:
|
#### Allgemeine Prüfungen:
|
||||||
- Solange nicht alle Pflichtfelder einen Wert aufweisen, muss beim Klick auf den Button "Migrieren" eine ERROR-Messagebox erscheinen, in der alle Pflichtfelder aufgelistet sind, die keinen Wert aufweisen
|
- Solange nicht alle Pflichtfelder einen Wert aufweisen, muss beim Klick auf den Button "Migrieren" eine ERROR-Messagebox erscheinen, in der alle Pflichtfelder aufgelistet sind, die keinen Wert aufweisen
|
||||||
- Es muss bei allen Feldern geprüft werden, ob sie ein unzulässiges Zeichen enthalten. Die Zeichen sind in der ini-Datei [ERP_Item.ini](\\ruledesigner\RDF_Daten\Konfigurator\CustomVaulting\ERP_Item.ini) in Sektion "Settings" unter dem Key "InvalidCharacters" aufgelistet:
|
- Es muss bei allen Feldern (unabhängig davon, ob es sich um ein Pflichtfeld handelt oder nicht) geprüft werden, ob sie unzulässgie Zeichen enthalten. Die unzulässigen Zeichen sind in der ini-Datei [ERP_Item.ini](\\ruledesigner\RDF_Daten\Konfigurator\CustomVaulting\ERP_Item.ini) in Sektion "Settings" unter dem Key "InvalidCharacters" aufgelistet:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -1894,7 +1913,7 @@ Zeichenbegrenzung = 400 - Aktuelle Anzahl an Zeichen im Textfeld [Automatische Z
|
|||||||
|
|
||||||
- "{Zeichentyp}" muss durch das eigentliche, unzulässige Zeichen ersetzt werden, z.B. ";"
|
- "{Zeichentyp}" muss durch das eigentliche, unzulässige Zeichen ersetzt werden, z.B. ";"
|
||||||
- "{Feldname}" muss durch den individuellen Feldnamen ersetzt werden.
|
- "{Feldname}" muss durch den individuellen Feldnamen ersetzt werden.
|
||||||
- Falls mehrere unzulässige Zeichen gleichzeitig auftreten, sollen diese untereinander aufgelistet werden.
|
- Falls mehrere unzulässige Zeichen gleichzeitig auftreten, können diese entweder untereinander in einer Messagebox aufgelistet werden. Alternativ (falls einfacher implementierbar) kann auch für jedes Feld, in dem ein unzulässiges Zeichen festgestellt wurde, eine eigene Messagebox ausgegeben werden
|
||||||
|
|
||||||
---
|
---
|
||||||
#### Bezeichnung 1
|
#### Bezeichnung 1
|
||||||
@@ -2152,11 +2171,23 @@ Tritt eine der nachfolgenden aufgelisteten Fälle auf, soll eine ERROR-Messagebo
|
|||||||
Teilenummer kann nicht ohne festgelegte Farbe migriert werden!
|
Teilenummer kann nicht ohne festgelegte Farbe migriert werden!
|
||||||
|
|
||||||
---
|
---
|
||||||
#### Änderungstext und Freigabevermerk
|
#### Aenderungstext
|
||||||
Wenn die Länge des Änderungstextes oder Freigabevermerks eine Länge von 400 Zeichen überschreitet und in der Spalte "Überschriebene Werte" kein kürzerer Änderungstext eingetragen wurde, muss beim Klick auf den Button "Migrieren" eine ERROR-Messagebox erscheinen. Beim Feld Änderungstext, z.B. mit Text "*Änderungstext weist {Länge Änderungstext in Spalte 'SIVAS-Werte'} auf. Bitte auf 400 Zeichen verkürzen!*". Beim Feld "Freigabevermerk, z.B. mit Text "*Freigabevermerk weist {Länge Freigabevermerk in Spalte 'SIVAS-Werte'} auf. Bitte auf 400 Zeichen verkürzen!*" erscheinen.
|
Wenn die Länge des Textes im Feld [Änderungstext](#änderungstext) eine Länge von 400 Zeichen überschreitet und in der Spalte "Überschriebene Werte" kein kürzerer Änderungstext eingetragen wurde, muss beim Klick auf den Button "Migrieren" eine ERROR-Messagebox (siehe nachfolgendes Bild) erscheinen:
|
||||||
Beispiel für Änderungstext:
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
**messagebox-Text:**
|
||||||
|
|
||||||
|
Änderungstext bitte auf 400 Zeichen verkürzen!
|
||||||
|
|
||||||
|
#### Freigabevermerk
|
||||||
|
Wenn die Länge des Textes im Feld [Freigabevermerk](#freigabevermerk) eine Länge von 400 Zeichen überschreitet und in der Spalte "Überschriebene Werte" kein kürzerer Freigabevermerk eingetragen wurde, muss beim Klick auf den Button "Migrieren" eine ERROR-Messagebox (siehe nachfolgendes Bild) erscheinen:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**messagebox-Text:**
|
||||||
|
|
||||||
|
Freigabevermerk bitte auf 400 Zeichen verkürzen!
|
||||||
|
|
||||||
|
|
||||||
### Tätigkeiten im Rahmen der Impfdateierstellung
|
### Tätigkeiten im Rahmen der Impfdateierstellung
|
||||||
@@ -2413,8 +2444,6 @@ Der eingetragene Wert im Feld [Dispolaufgruppe](#dispolaufgruppe) muss als gemap
|
|||||||
#### ZusaetzlicheInformationen
|
#### ZusaetzlicheInformationen
|
||||||
Die Werte aus den Feldern [Automatische Zusatzinformationen](#automatische-zusatzinformationen) und [Benutzerdefinierte Zusatzinformationen](#benutzerdefinierte-zusatzinformationen) müssen vor dem Eintragen in die Impfdatei zusammengesetzt werden
|
Die Werte aus den Feldern [Automatische Zusatzinformationen](#automatische-zusatzinformationen) und [Benutzerdefinierte Zusatzinformationen](#benutzerdefinierte-zusatzinformationen) müssen vor dem Eintragen in die Impfdatei zusammengesetzt werden
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Tätigkeiten nach der Impfdateierstellung
|
### Tätigkeiten nach der Impfdateierstellung
|
||||||
|
|
||||||
1. Kopieren des aktuellen Standes der RuleDesigner-Datenbank (nachdem RDX-Prozess ausgeführt wurde).
|
1. Kopieren des aktuellen Standes der RuleDesigner-Datenbank (nachdem RDX-Prozess ausgeführt wurde).
|
||||||
|
|||||||
+27
-83
@@ -2,75 +2,12 @@ import tkinter as tk
|
|||||||
#import ttkbootstrap as ttk
|
#import ttkbootstrap as ttk
|
||||||
#from ttkbootstrap.constants import *
|
#from ttkbootstrap.constants import *
|
||||||
from gui import App
|
from gui import App
|
||||||
from caditem import CadItem
|
from caditem import CadItem, GuiLogic
|
||||||
from controller import Controller, GuiLogic
|
from controller import Controller
|
||||||
from manage_configs import Configs
|
from manage_configs import Configs
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
demo_data = """
|
|
||||||
{
|
|
||||||
"parent_children_mapping": {
|
|
||||||
"400102130": [ "400102142" ],
|
|
||||||
"400102167": [ "821116004" ],
|
|
||||||
"400102168": [ "821116001" ],
|
|
||||||
"400102195": [ "822066075", "822066216", "822066154", "822066101",
|
|
||||||
"822064090", "822066196", "400102129", "822066217", "822066160",
|
|
||||||
"822066215", "913041045", "913011009", "911011057", "822064035",
|
|
||||||
"925011006", "911091041", "913051040", "911021112", "911021166",
|
|
||||||
"825006003", "912041005", "911011014", "911011009", "911021144",
|
|
||||||
"911021001", "913011016", "929055170", "913011010", "911021035",
|
|
||||||
"829416065", "712000151", "712000100" ],
|
|
||||||
"400102196": [ "400102125", "400102126", "400102130", "400102161",
|
|
||||||
"400102163", "400102165", "400102166", "400102167", "400102168",
|
|
||||||
"400102190", "400102195", "400102198", "400102246", "400102247",
|
|
||||||
"400102267", "400102272", "400102274", "400102275", "400102277",
|
|
||||||
"400102278", "400102282", "400102284", "400102417", "720002003",
|
|
||||||
"721001034", "821114025", "822064091", "822066085", "822996075",
|
|
||||||
"829416061", "829516004", "911021113", "911021181", "911021259",
|
|
||||||
"911091054", "911091096", "911091097", "911251013", "912011009",
|
|
||||||
"919050006", "924031058", "924031081" ],
|
|
||||||
"400102235": [ "400102236", "400102237", "400102238", "400102239",
|
|
||||||
"400102268", "911021143", "911021054", "911021055" ],
|
|
||||||
"400102236": [ "MA0000006" ],
|
|
||||||
"400102267": [ "400102235", "829416159", "829416077", "829416079",
|
|
||||||
"911021260", "911021147", "911251014" ],
|
|
||||||
"400102282": [ "822066026", "822066089", "919010052" ],
|
|
||||||
"821114025": [ "911081007", "821116053" ],
|
|
||||||
"821116004": [ "822026004" ],
|
|
||||||
"822064035": [ "822066065" ],
|
|
||||||
"822064091": [ "822066212", "822064093", "822066220", "822066200",
|
|
||||||
"912011010", "911021156", "822066201", "911071027", "913011109",
|
|
||||||
"911011070", "913011001", "710005021", "919010055", "720000008", "720000007" ],
|
|
||||||
"822064093": [ "822066204", "822066205", "822066206", "822066207", "822066208" ],
|
|
||||||
"822066075": [ "822066157", "822066162", "911261023" ],
|
|
||||||
"822066160": [ "MA0000004" ],
|
|
||||||
"822066162": [ "822064013" ],
|
|
||||||
"822066196": [ "MA0000008" ],
|
|
||||||
"822066220": [ "924031033" ],
|
|
||||||
"829416159": [ "829416089" ]
|
|
||||||
},
|
|
||||||
"red_ids": [ "400102274", "400102275", "400102190", "400102198", "400102161",
|
|
||||||
"400102277", "400102163", "400102278", "400102282", "400102284",
|
|
||||||
"400102195", "MA0000008", "MA0000004", "929055170", "400102267",
|
|
||||||
"400102235", "400102236", "MA0000006", "400102237", "400102238",
|
|
||||||
"400102239", "400102268", "829416159", "924031058", "924031081",
|
|
||||||
"822064091", "822066199", "822066200" ],
|
|
||||||
"gui_data": {
|
|
||||||
"asm_id": "400102190",
|
|
||||||
"teilenummer": "400102195",
|
|
||||||
"pdm_kategorie_neu": "Einzelteil",
|
|
||||||
"neuaufbau": "False",
|
|
||||||
"lebenszyklus_status_neu": "Serie",
|
|
||||||
"aus_halbzeug_neu": "True",
|
|
||||||
"zusatzinfos_auto_text": "Dies sind neue Zusatzinfos",
|
|
||||||
"cb_lebenszyklus_status_neu": ["Serie", "Prototyp"],
|
|
||||||
"cb_werkstofftyp_neu": ["Stahl", "Aluminium", "Kunst-/ Verbundstoff", "Schwermetall"]
|
|
||||||
},
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
#"teilenummer": "400102195", assembly
|
|
||||||
|
|
||||||
class Environment:
|
class Environment:
|
||||||
|
|
||||||
@@ -79,18 +16,22 @@ class Environment:
|
|||||||
self.data_dir = os.environ.get('CREMIG_DATA')
|
self.data_dir = os.environ.get('CREMIG_DATA')
|
||||||
self.out_dir = os.environ.get('CREMIG_WORK')
|
self.out_dir = os.environ.get('CREMIG_WORK')
|
||||||
self.cfg_dir = os.environ.get('CREMIG_CFG')
|
self.cfg_dir = os.environ.get('CREMIG_CFG')
|
||||||
|
self.log_dir = os.environ.get('CREMIG_LOG')
|
||||||
self.ruledesigner_csv_filename = os.environ.get('RD_DATABASE_NAME')
|
self.ruledesigner_csv_filename = os.environ.get('RD_DATABASE_NAME')
|
||||||
|
|
||||||
def build_gui(model, configs):
|
def build_gui(model, configs, env, sivasid=None, uselocal=True):
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
#root = ttk.Window()
|
#root = ttk.Window()
|
||||||
app = App(root, configs)
|
app = App(root, configs)
|
||||||
|
|
||||||
controller = Controller(model, app)
|
controller = Controller(model, app)
|
||||||
controller.set_env(configs.get_env())
|
controller.set_env(env)
|
||||||
|
controller.set_config(configs)
|
||||||
|
if sivasid:
|
||||||
|
controller.get_csv_files_of_asm(sivasid, load_local_bom=uselocal, load_local_teilestamm=uselocal, load_local_rd_ids=uselocal)
|
||||||
|
|
||||||
logic = GuiLogic(model, configs)
|
logic = GuiLogic(model, configs)
|
||||||
controller.add_logic(logic)
|
model.add_logic(logic)
|
||||||
|
|
||||||
# um ohne Observer pattern auch Rückmeldungen geben zu können
|
# um ohne Observer pattern auch Rückmeldungen geben zu können
|
||||||
app.set_controller(controller)
|
app.set_controller(controller)
|
||||||
@@ -98,33 +39,36 @@ def build_gui(model, configs):
|
|||||||
|
|
||||||
# Daten des Modells in der Oberfläche darstellen
|
# Daten des Modells in der Oberfläche darstellen
|
||||||
controller.refresh_gui()
|
controller.refresh_gui()
|
||||||
|
|
||||||
app.mainloop()
|
app.mainloop()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='Das Programm ermöglicht einw graphisch unterstützte Migration eines Teiles oder Assemblies von Creo nach SolidEdge. Erzeugt eine korrekte Impfdatei.', prog='CreoMigrateGui')
|
parser = argparse.ArgumentParser(description='Das Programm ermöglicht einw graphisch unterstützte Migration eines Teiles oder Assemblies von Creo nach SolidEdge. Erzeugt eine korrekte Impfdatei.', prog='CreoMigrateGui')
|
||||||
parser.add_argument('-s', '--sivasid', action='store', help='Eingabe der SIVAS-Teilenummer, für die der Migrationsstatus angezeigt werden soll', metavar="id")
|
parser.add_argument('-s', '--sivasid', action='store', help='Eingabe der SIVAS-Teilenummer, für die der Migrationsstatus angezeigt werden soll')
|
||||||
parser.add_argument('-d', '--demo', action='store_true', help='arbeitet ohne Server. Lädt Testdaten ein um nur eine Oberfläche darzustellen')
|
parser.add_argument('-d', '--demo', action='store_true', help='arbeitet ohne Server. Lädt Testdaten ein um nur eine Oberfläche darzustellen')
|
||||||
|
parser.add_argument('-l', '--uselocal', action='store_true', help='Verbinde dich nicht zur Datenbank. Benutzer alle lokalen Dateien (falls vorhanden) für die gegebene asm-id')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
environment = Environment()
|
environment = Environment()
|
||||||
output_dir = environment.out_dir
|
|
||||||
|
data_dir = environment.data_dir
|
||||||
configs = Configs(environment.cfg_dir)
|
configs = Configs(environment.cfg_dir)
|
||||||
configs.set_env(environment)
|
configs.set_data_dir(data_dir)
|
||||||
|
|
||||||
|
|
||||||
model = CadItem()
|
model = CadItem()
|
||||||
if args.demo:
|
if args.sivasid:
|
||||||
model.from_json(demo_data)
|
sivasid = args.sivasid.strip()
|
||||||
build_gui(model, configs)
|
|
||||||
|
|
||||||
elif args.sivasid:
|
output_dir = environment.out_dir
|
||||||
id = args.sivasid
|
assembl_path = os.path.join(output_dir, sivasid + '.json')
|
||||||
path = os.path.join(output_dir, id + '.json')
|
if os.path.exists(assembl_path):
|
||||||
if os.path.exist(path):
|
# wenn schon einmal das assembly als json abgespeichert wurde, dann dieses laden
|
||||||
model.load(demo_data)
|
model.load(assembl_path)
|
||||||
build_gui(model, configs)
|
else:
|
||||||
|
# die Gui aufbauen
|
||||||
|
build_gui(model, configs, environment, sivasid, args.uselocal)
|
||||||
else:
|
else:
|
||||||
parser.print_help()
|
build_gui(model, configs, environment)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2434
-77
File diff suppressed because it is too large
Load Diff
+339
-311
@@ -1,271 +1,136 @@
|
|||||||
import update_database
|
from manage_configs import SivasBOM, RuleDesignerDatabaseConfig, MigrationStatus, SivasTeilestamm, BOMConfig
|
||||||
|
|
||||||
import warnings
|
|
||||||
#Wegen Pandas Deprecation eingebaut
|
|
||||||
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import json
|
|
||||||
import pandas as pd
|
|
||||||
import openpyxl
|
import openpyxl
|
||||||
|
from itertools import zip_longest
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dieses Programm kann:
|
Dieses Programm kann:
|
||||||
- eine Excel-Datei exportieren, in der alle Teilenummern aufgelistet sind, die in Verbindung mit einer angegebenen Nummer migriert werden müssen.
|
- eine Excel-Datei exportieren, in der alle Teilenummern aufgelistet sind, die in Verbindung mit einer angegebenen Nummer migriert werden müssen.
|
||||||
Sie gibt dabei Auskunft darüber, welche Teilenummern bereits migriert wurden und welche noch migriert werden müssen.
|
Sie gibt dabei Auskunft darüber, welche Teilenummern bereits migriert wurden und welche noch migriert werden müssen.
|
||||||
- die oben beschriebene Darstellung in einer Excel-Datei auch als Treeview auf der Kommandozeile darstellen
|
- die oben Darstellung in der Excel-Datei als Baum in der Konsole ausgeben
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Environment:
|
class GetExcludedIDsFromCFG(argparse.Action):
|
||||||
|
def __call__(self, parser, namespace, values, option_string = None):
|
||||||
|
bom_config = BOMConfig(os.path.dirname(values[0]), os.path.basename(values[0]))
|
||||||
|
excluded_ids = bom_config.get_excluded_ids(values[1])
|
||||||
|
setattr(namespace, self.dest, excluded_ids)
|
||||||
|
|
||||||
def __init__(self):
|
class LStrip(argparse.Action):
|
||||||
self.lib_dir = os.environ.get('CREMIG_LIB')
|
def __call__(self, parser, namespace, values, option_string = None):
|
||||||
self.data_dir = os.environ.get('CREMIG_DATA')
|
setattr(namespace, self.dest, values.lstrip())
|
||||||
self.out_dir = os.environ.get('CREMIG_WORK')
|
|
||||||
self.ruledesigner_csv_filename = os.environ.get('RD_DATABASE_NAME')
|
|
||||||
self.vba_macro_filename = os.environ.get('VBA_MACRO_NAME')
|
|
||||||
self.vba_macro_filepath = os.path.join(self.lib_dir, self.vba_macro_filename)
|
|
||||||
|
|
||||||
|
class LocateSQLCredentials(argparse.Action):
|
||||||
class Partnumbers:
|
def __call__(self, parser, namespace, values, option_string = None):
|
||||||
|
if not os.path.isfile(os.environ.get("RD_SQL_DATABASE_CREDENTIALS")):
|
||||||
def __init__(self, filename: str, file_dir: str):
|
print(f"ACHTUNG: Blau hinterlegte Nummern (Teilenummern die ins PDM migriert wurden, aber aktuell nicht freigegeben sind) werden nicht dargestellt, da nicht auf die Login-Daten für die RD-SQL-Datenbank zugegriffen werden kann. Bitte prüfen, ob die Login-Datei '{os.environ.get("RD_SQL_DATABASE_CREDENTIALS")}' existiert. Auch prüfen, ob die Netzlaufwerke verbunden sind!")
|
||||||
self.file_dir = file_dir
|
setattr(namespace, self.dest, True)
|
||||||
self.filename = filename.rsplit(".")[0]
|
|
||||||
|
|
||||||
def load_from_json(self):
|
|
||||||
|
|
||||||
"""Reads partnumbers from a json-file"""
|
|
||||||
|
|
||||||
config_path = os.path.join(self.file_dir, self.filename + ".json")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(config_path, encoding='utf-8') as json_file:
|
|
||||||
return json.load(json_file)
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
update_database.get_sivas_dbase(self.filename, self.file_dir)
|
|
||||||
return self.load_from_json()
|
|
||||||
|
|
||||||
def load_from_csv(self):
|
|
||||||
|
|
||||||
"""Reads partnumbers from a csv-file"""
|
|
||||||
|
|
||||||
config_path = os.path.join(self.file_dir, self.filename + ".csv")
|
|
||||||
|
|
||||||
try:
|
|
||||||
df = pd.read_csv(config_path, sep=';', converters={"Teilenummern":str})
|
|
||||||
return tuple(df["Teilenummern"])
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
update_database.get_rd_dbase(self.file_dir)
|
|
||||||
return self.load_from_csv()
|
|
||||||
|
|
||||||
|
|
||||||
class SivasPartnumbers(Partnumbers):
|
|
||||||
|
|
||||||
def __init__(self, main_sivas_id: str, file_dir: str):
|
|
||||||
self.file_dir = file_dir
|
|
||||||
self.main_sivas_id = main_sivas_id
|
|
||||||
self._partnumbers = None
|
|
||||||
|
|
||||||
super().__init__(file_dir=self.file_dir, filename=self.main_sivas_id)
|
|
||||||
|
|
||||||
|
|
||||||
def lazy_partnumber_init(function):
|
|
||||||
|
|
||||||
"""Decorator prevents time-consuming initialization of sivas partnumbers if method doesn't require them"""
|
|
||||||
|
|
||||||
def wrapper(self):
|
|
||||||
if self._partnumbers is None:
|
|
||||||
self._partnumbers = self.__class__.mro()[1].load_from_json(self) # Using super() isn't possible here
|
|
||||||
return function(self)
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
@lazy_partnumber_init
|
|
||||||
def get_partnumbers(self) -> set:
|
|
||||||
|
|
||||||
"""Returns all partnumbers (id's) of the provided json-file"""
|
|
||||||
|
|
||||||
ids = set()
|
|
||||||
for child_id, top_level_assemblies_of_child in self._partnumbers.items():
|
|
||||||
ids.add(child_id)
|
|
||||||
for top_level_assembly in top_level_assemblies_of_child:
|
|
||||||
top_level_assembly_id = top_level_assembly["Parent"]
|
|
||||||
ids.add(top_level_assembly_id)
|
|
||||||
|
|
||||||
return ids
|
|
||||||
|
|
||||||
def get_longest_partnumber(self) -> str:
|
|
||||||
|
|
||||||
"""Returns the longest partnumber in the provided json-file"""
|
|
||||||
|
|
||||||
return max(self.get_partnumbers())
|
|
||||||
|
|
||||||
@lazy_partnumber_init
|
|
||||||
def get_ordered_parent_children(self, no_duplicates: bool = False) -> dict:
|
|
||||||
|
|
||||||
"""Replicates the partnumber structure of the given BOM (bill of material) from sivas. The Order of the partnumbers is identical to the position numbers in the BOM"""
|
|
||||||
|
|
||||||
unordered_parent_children = {}
|
|
||||||
|
|
||||||
for parents in self._partnumbers:
|
|
||||||
for children in self._partnumbers[parents]:
|
|
||||||
|
|
||||||
if children["Parent"] not in unordered_parent_children:
|
|
||||||
unordered_parent_children[children["Parent"]] = {}
|
|
||||||
|
|
||||||
pos = children["Position"].lstrip(".").split("/")[0]
|
|
||||||
pos_in_list = int(pos)
|
|
||||||
unordered_parent_children[children["Parent"]][pos_in_list] = parents
|
|
||||||
|
|
||||||
# Second dict necessary, because children aren't sorted according to their position numbers in the SIVAS-BOM
|
|
||||||
ordered_parent_children = {}
|
|
||||||
for key, values in unordered_parent_children.items():
|
|
||||||
for subkey, subvalue in sorted(values.items()):
|
|
||||||
if key not in ordered_parent_children:
|
|
||||||
ordered_parent_children[key] = []
|
|
||||||
ordered_parent_children[key].append(subvalue)
|
|
||||||
|
|
||||||
return ordered_parent_children
|
|
||||||
|
|
||||||
@lazy_partnumber_init
|
|
||||||
def get_max_bom_depth(self) -> int:
|
|
||||||
|
|
||||||
"""Returns the maximum nesting-depth (level) of the provided assembly partnumber as an integer"""
|
|
||||||
|
|
||||||
bom_levels = []
|
|
||||||
for values in self._partnumbers.values():
|
|
||||||
for value in values:
|
|
||||||
current_bom_level = value["Position"].count(".")
|
|
||||||
bom_levels.append(current_bom_level)
|
|
||||||
|
|
||||||
return max(bom_levels)
|
|
||||||
|
|
||||||
@lazy_partnumber_init
|
|
||||||
def get_partnumber_descriptions(self) -> dict:
|
|
||||||
descriptions = {}
|
|
||||||
for parent, values in self._partnumbers.items():
|
|
||||||
for value in values:
|
|
||||||
descriptions[parent] = value["Bezeichnung"]
|
|
||||||
return descriptions
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RuleDesignerPartnumbers(Partnumbers):
|
|
||||||
|
|
||||||
def __init__(self, ruledesigner_ids_dir: str, ruledesigner_ids_filename: str):
|
|
||||||
|
|
||||||
self.ruledesigner_ids_dir = ruledesigner_ids_dir
|
|
||||||
self.ruledesigner_ids_filename = ruledesigner_ids_filename
|
|
||||||
|
|
||||||
super().__init__(file_dir=self.ruledesigner_ids_dir, filename=self.ruledesigner_ids_filename)
|
|
||||||
|
|
||||||
|
|
||||||
def get_partnumbers(self):
|
|
||||||
return super().load_from_csv()
|
|
||||||
|
|
||||||
def update_database(self):
|
|
||||||
return update_database.get_rd_dbase(self.ruledesigner_ids_dir)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SivasRuleDesignerComparison:
|
|
||||||
|
|
||||||
def __init__(self, sivas_ids_dir, sivas_main_id, rd_ids_dir, rd_ids_filename):
|
|
||||||
self.sivas = SivasPartnumbers(main_sivas_id=sivas_main_id, file_dir=sivas_ids_dir)
|
|
||||||
self.ruledesigner = RuleDesignerPartnumbers(ruledesigner_ids_dir=rd_ids_dir, ruledesigner_ids_filename=rd_ids_filename)
|
|
||||||
|
|
||||||
def get_migration_status(self) -> dict:
|
|
||||||
|
|
||||||
"""Checks if given sivas-partnumbers have been migrated been migrated into RuleDesigner"""
|
|
||||||
|
|
||||||
sivas_ids = self.sivas.get_partnumbers()
|
|
||||||
ruledesigner_ids = self.ruledesigner.get_partnumbers()
|
|
||||||
|
|
||||||
migration_completed = {}
|
|
||||||
for sivas_partnumber in sivas_ids:
|
|
||||||
migration_completed[sivas_partnumber] = True if sivas_partnumber in ruledesigner_ids else False
|
|
||||||
|
|
||||||
return migration_completed
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExcelExport:
|
class ExcelExport:
|
||||||
|
|
||||||
def __init__(self, main_id, sivas_ids_file_dir, rd_ids_file_dir, rd_ids_filename):
|
def __init__(self,
|
||||||
self.main_id = main_id
|
asm_id,
|
||||||
self.environment = Environment()
|
asm_json_dir,
|
||||||
self._sivas = SivasPartnumbers(main_sivas_id=main_id, file_dir=sivas_ids_file_dir)
|
asm_json_filename,
|
||||||
self._ruledesigner = RuleDesignerPartnumbers(ruledesigner_ids_dir=rd_ids_file_dir, ruledesigner_ids_filename=rd_ids_filename)
|
asm_csv_dir,
|
||||||
self._comparison = SivasRuleDesignerComparison(sivas_ids_dir=sivas_ids_file_dir, sivas_main_id=main_id, rd_ids_dir=rd_ids_file_dir, rd_ids_filename=rd_ids_filename)
|
asm_csv_filename,
|
||||||
self._parent_children = self._sivas.get_ordered_parent_children()
|
rd_dbase_dir,
|
||||||
self._ruledesigner_ids = self._ruledesigner.get_partnumbers()
|
rd_dbase_filename,
|
||||||
|
load_local_asm_json,
|
||||||
|
load_local_asm_csv,
|
||||||
|
load_local_rd_dbase,
|
||||||
|
no_blue_ids):
|
||||||
|
self.asm_id = asm_id
|
||||||
|
self.asm_data = SivasBOM(asm_json_dir, asm_json_filename, load_local_asm_json)
|
||||||
|
self.asm_metadata = SivasTeilestamm(asm_csv_dir, asm_csv_filename, load_local_asm_csv)
|
||||||
|
self.rd_data = RuleDesignerDatabaseConfig(rd_dbase_dir, rd_dbase_filename, load_local_rd_dbase)
|
||||||
|
self._migration_status = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def migration_status(self):
|
||||||
|
if self._migration_status is None:
|
||||||
|
self._migration_status = MigrationStatus(self.asm_data.child_ids, self.rd_data.ids)
|
||||||
|
return self._migration_status
|
||||||
|
|
||||||
def write_excel(self):
|
def write_excel(self):
|
||||||
|
|
||||||
data = self._create_excel_data()
|
data = self._create_excel_data()
|
||||||
output_dir = environment.out_dir
|
out_dir = os.environ.get("CREMIG_WORK")
|
||||||
|
out_path = os.path.join(out_dir, self.asm_id + ".xlsm")
|
||||||
|
|
||||||
destiny_filepath = os.path.join(output_dir, self.main_id + ".xlsm")
|
workbook_path = os.path.join(os.environ.get("CREMIG_LIB"), os.environ.get("VBA_MACRO_NAME"))
|
||||||
|
workbook = openpyxl.load_workbook(workbook_path, keep_vba=True)
|
||||||
workbook = openpyxl.load_workbook(self.environment.vba_macro_filepath, keep_vba=True)
|
|
||||||
worksheet = workbook.active
|
worksheet = workbook.active
|
||||||
|
|
||||||
# Headers
|
# Spaltenüberschriften
|
||||||
for header, column in zip(data, worksheet.iter_cols(min_row=1, max_col=len(data), max_row=1)):
|
for header, column in zip(data, worksheet.iter_cols(min_row=1, max_col=len(data), max_row=1)):
|
||||||
for cell in column:
|
for cell in column:
|
||||||
cell.value = header
|
cell.value = header
|
||||||
|
|
||||||
# Values below Headers
|
# Werte unter Spaltenüberschriften
|
||||||
for value, column in zip(data.values(), worksheet.iter_cols(min_row=2, max_col=len(data), max_row=len(data["Sortierung"])+1)):
|
for value, column in zip(data.values(), worksheet.iter_cols(min_row=2, max_col=len(data), max_row=len(data["Sortierung"])+1)):
|
||||||
for cell, element in zip(column, value):
|
for cell, element in zip(column, value):
|
||||||
cell.value = element
|
cell.value = element
|
||||||
|
|
||||||
# Renaming the sheet is necessary, because it triggers the execution of the VBA-Macro
|
# Umbenennung des Blattes erforderlich, da die Umbenennung die Ausführung des VBA-Makros triggert.
|
||||||
# The renaming must be performed AFTER inserting the data into the spreadsheet, because the conditional formatting, which is part of the macro, can't be performed
|
# Die Umbenennung muss NACH dem Einfügen der Daten in das Blatt erfolgen, da die bedingte Formatierung,
|
||||||
# when no data is in the spreadsheet
|
# die ebenfalls Bestandteil des Makros ist, nicht ausgeführt werden kann, solange sich keine Daten im Blatt befinden
|
||||||
worksheet.title = "Ergebnis"
|
worksheet.title = "Ergebnis"
|
||||||
|
|
||||||
workbook.save(destiny_filepath)
|
workbook.save(out_path)
|
||||||
print(f"Excel-Datei erfolgreich in '{output_dir}' geschrieben...")
|
print(f"Excel-Datei erfolgreich in '{out_dir}' geschrieben...")
|
||||||
|
|
||||||
def _create_excel_data(self) -> dict:
|
def _create_excel_data(self) -> dict:
|
||||||
|
|
||||||
# Columns in excel-spreadsheet: Sortierung, Teilenummer, Bezeichnung, Bestandsabfrage, Teilebeurteilung, Zusatzbemerkung
|
# Spalten im Arbeitsblatt: Sortierung, Teilenummer, Bezeichnung, Bestandsabfrage, Teilebeurteilung, Zusatzbemerkung
|
||||||
# Sortierung: Minus-separated hierarchy of the partnumber in the BOM structure
|
# Sortierung: Minus-separierte Hierarchie der Teilenummern in der Stücklistenstruktur
|
||||||
# Teilenummer: SIVAS-partnumber
|
# Teilenummer: SIVAS-Teilenummer
|
||||||
# Bezeichnung: SIVAS-description of the partnumber
|
# Bezeichnung: SIVAS-Bezeichnung der Teilenummer
|
||||||
# Migrationsstatus: "IMPORTIEREN" = partnumber hasn't been migrated yet, "VERFÜGBAR" = partnumber has been migrated
|
# Migrationsstatus: "IMPORTIEREN" = Migration ausstehend, "VERFÜGBAR" = Migration abgeschlossen
|
||||||
# All the other columns remain empty, because their values are entered in the excel spreadsheet
|
# Alle weiteren Spalten bleiben leer, da sie händisch vom User zu befüllen sind
|
||||||
|
|
||||||
sorting = self._create_sorting_string()
|
sorting = self._create_sorting_string()
|
||||||
migrated = self._comparison.get_migration_status()
|
migrated_ids = self.migration_status.ids_in_rd
|
||||||
descriptions = self._sivas.get_partnumber_descriptions()
|
child_descriptions:dict = self.asm_data.get_prop_val_for_all_ids("Bezeichnung")
|
||||||
|
parent_description:str = self.asm_metadata.get_property_values("Bezeichnung1")
|
||||||
|
|
||||||
|
descriptions = child_descriptions.copy()
|
||||||
|
descriptions[asm_id] = parent_description
|
||||||
|
|
||||||
prt_num = []
|
prt_num = []
|
||||||
description = []
|
description = []
|
||||||
migration_status = []
|
migration_status = []
|
||||||
evaluation = []
|
assessment = []
|
||||||
comment = []
|
comment = []
|
||||||
|
|
||||||
for partnumber_string in sorting:
|
for id_str in sorting:
|
||||||
partnumber = partnumber_string.split("-")[-1]
|
id = id_str.split("-")[-1]
|
||||||
prt_num.append(partnumber)
|
prt_num.append(id)
|
||||||
if partnumber not in descriptions:
|
assessment.append('')
|
||||||
description.append("")
|
|
||||||
else:
|
|
||||||
description.append(descriptions[partnumber])
|
|
||||||
migration_status.append("VERFÜGBAR" if migrated[partnumber] is True else "IMPORTIEREN")
|
|
||||||
evaluation.append('')
|
|
||||||
comment.append('')
|
comment.append('')
|
||||||
|
|
||||||
|
if id not in descriptions:
|
||||||
|
description.append("")
|
||||||
|
else:
|
||||||
|
description.append(descriptions[id])
|
||||||
|
|
||||||
|
if id in migrated_ids:
|
||||||
|
if id in self.migration_status.ids_in_progress:
|
||||||
|
migration_status.append("PDM-Migration abgeschlossen")
|
||||||
|
else:
|
||||||
|
migration_status.append("Migration abgeschlossen (freigegeben)")
|
||||||
|
|
||||||
|
else:
|
||||||
|
migration_status.append("Migration ausstehend")
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"Sortierung": sorting,
|
"Sortierung": sorting,
|
||||||
"Teilenummer": prt_num,
|
"Teilenummer": prt_num,
|
||||||
"Bezeichnung": description,
|
"Bezeichnung": description,
|
||||||
"Migrationsstatus": migration_status,
|
"Migrationsstatus": migration_status,
|
||||||
"Beurteilung": evaluation,
|
"Beurteilung": assessment,
|
||||||
"Bemerkung": comment
|
"Bemerkung": comment
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
@@ -284,21 +149,21 @@ class ExcelExport:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if parent is None:
|
if parent is None:
|
||||||
parent = self.main_id
|
parent = self.asm_id
|
||||||
if sorting_strings is None:
|
if sorting_strings is None:
|
||||||
sorting_strings = [parent]
|
sorting_strings = [parent]
|
||||||
|
|
||||||
children = self._parent_children[parent]
|
parent_children = self.asm_data.parent_children
|
||||||
|
children = parent_children[parent]
|
||||||
|
|
||||||
for child in children:
|
for child in children:
|
||||||
|
|
||||||
sorting_strings.append(f"{previous_parents}-{parent}-{child}".lstrip("-"))
|
sorting_strings.append(f"{previous_parents}-{parent}-{child}".lstrip("-"))
|
||||||
|
|
||||||
if child in self._parent_children:
|
if child in parent_children:
|
||||||
self._create_sorting_string(parent=child, previous_parents=previous_parents + f"-{parent}", sorting_strings=sorting_strings)
|
self._create_sorting_string(parent=child, previous_parents=previous_parents + f"-{parent}", sorting_strings=sorting_strings)
|
||||||
|
|
||||||
return sorting_strings
|
return sorting_strings
|
||||||
|
|
||||||
|
|
||||||
class Treeview:
|
class Treeview:
|
||||||
|
|
||||||
@@ -315,144 +180,307 @@ class Treeview:
|
|||||||
|
|
||||||
console_colors = {"RED": "\033[41m",
|
console_colors = {"RED": "\033[41m",
|
||||||
"GREEN": "\033[42m",
|
"GREEN": "\033[42m",
|
||||||
|
"BLUE": "\033[44m",
|
||||||
"RESET": "\033[0m"
|
"RESET": "\033[0m"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, main_partnumber, sivas_src_file, rd_src_dir, rd_src_file):
|
def __init__(self,
|
||||||
self.main_partnumber = main_partnumber
|
asm_id:str,
|
||||||
self._sivas = SivasPartnumbers(main_sivas_id=main_partnumber, file_dir=sivas_src_file)
|
asm_json_dir:str,
|
||||||
self._ruledesigner = RuleDesignerPartnumbers(ruledesigner_ids_dir=rd_src_dir, ruledesigner_ids_filename=rd_src_file)
|
asm_json_filename:str,
|
||||||
self._sivas_rd_comparison = SivasRuleDesignerComparison(sivas_main_id=main_partnumber, sivas_ids_dir=sivas_src_file, rd_ids_dir=rd_src_dir, rd_ids_filename=rd_src_file)
|
asm_csv_dir:str,
|
||||||
self._parent_children = self._sivas.get_ordered_parent_children()
|
asm_csv_filename:str,
|
||||||
self._descriptions = self._sivas.get_partnumber_descriptions()
|
rd_dbase_dir:str,
|
||||||
self._max_tree_depth = self._sivas.get_max_bom_depth()
|
rd_dbase_filename:bool=False,
|
||||||
self._longest_partnumber = self._sivas.get_longest_partnumber()
|
load_local_asm_json:bool=False,
|
||||||
self._migration_status = self._sivas_rd_comparison.get_migration_status()
|
load_local_asm_csv:bool=False,
|
||||||
|
load_local_rd_dbase:bool=False,
|
||||||
|
no_blue_ids:bool=False,
|
||||||
|
excluded_bom_ids:list=None,
|
||||||
|
excluded_summary_ids:list=None):
|
||||||
|
|
||||||
|
self.asm_id = asm_id
|
||||||
|
self.asm_bom = SivasBOM(asm_id, asm_json_dir, asm_json_filename, load_local_asm_json, excluded_bom_ids)
|
||||||
|
self.asm_teilestamm = SivasTeilestamm(asm_csv_dir, asm_csv_filename, load_local_asm_csv)
|
||||||
|
self.rd_data = RuleDesignerDatabaseConfig(rd_dbase_dir, rd_dbase_filename, load_local_rd_dbase)
|
||||||
|
self.all_excluded_summary_ids = excluded_summary_ids
|
||||||
|
self._excluded_summary_ids_in_bom = None
|
||||||
|
self.no_blue_ids = no_blue_ids
|
||||||
|
self._migration_status = None
|
||||||
|
self._longest_entry = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def migration_status(self):
|
||||||
|
if self._migration_status is None:
|
||||||
|
self._migration_status = MigrationStatus(self.asm_bom.child_ids, self.rd_data.ids)
|
||||||
|
return self._migration_status
|
||||||
|
|
||||||
|
@property
|
||||||
|
def longest_entry(self):
|
||||||
|
|
||||||
|
if self._longest_entry is None:
|
||||||
|
longest_color_code = max(Treeview.console_colors.values(), key=len)
|
||||||
|
longest_connector_symbol = max(Treeview.connector_symbols.values(), key=len)
|
||||||
|
|
||||||
|
padding_after_id = 2
|
||||||
|
|
||||||
|
if self._longest_entry is None:
|
||||||
|
|
||||||
|
self._longest_entry = (self.asm_bom.max_bom_depth) * len(Treeview.prefix_types["PIPE"]) \
|
||||||
|
+ len(longest_connector_symbol) \
|
||||||
|
+ len(longest_color_code) \
|
||||||
|
+ len(self.asm_bom.longest_child_id) \
|
||||||
|
+ len(Treeview.console_colors["RESET"]) \
|
||||||
|
+ padding_after_id
|
||||||
|
return self._longest_entry
|
||||||
|
|
||||||
|
|
||||||
|
def _add_asm_id_to_bom(self):
|
||||||
|
"""Standardmäßig ist die oberste Baugruppennummer kein Bestandteil der JSON-Datei, in der die Baugruppenstruktur aufgelistet ist und
|
||||||
|
die über das Programm 'Sivas2Json' von Hr. Jakob generiert wird. Damit der Baum die Bezeichnung der obersten Baugruppennummer im
|
||||||
|
Baum angezeigt wird ist es jedoch erforderlich, dass die Nummer mitsamt ihrer Bezeichnung in der JSON enthalten ist"""
|
||||||
|
|
||||||
|
metadata = {"Bezeichnung": self.asm_teilestamm.get_property_values("Bezeichnung1"),
|
||||||
|
"Parent": None,
|
||||||
|
"Position": "10/0"}
|
||||||
|
|
||||||
|
self.asm_bom.extend_asm_bom(self.asm_id, metadata)
|
||||||
|
|
||||||
|
|
||||||
def generate_tree(self):
|
def generate_tree(self):
|
||||||
self._tree_header()
|
self._add_asm_id_to_bom()
|
||||||
self._tree_body()
|
self._print_tree()
|
||||||
self._tree_summary()
|
self._print_summary()
|
||||||
|
|
||||||
def _tree_header(self):
|
|
||||||
|
|
||||||
"""Prints root number (number for which the user wants to see the tree) to the console"""
|
|
||||||
|
|
||||||
background_color = self._set_text_background_color(self.main_partnumber)
|
def _print_tree(self, parent_id=None, prefix=""):
|
||||||
print(f"{background_color}{self.main_partnumber}{Treeview.console_colors['RESET']}")
|
|
||||||
|
|
||||||
def _tree_body(self, parent_id=None, prefix=""):
|
"""Gibt die Baugruppenstruktur in Form eines Baumes in der Konsole aus"""
|
||||||
|
|
||||||
"""Prints the body (all partnumbers except root/main-partnumber) of the tree to the console"""
|
parent_children = self.asm_bom.parent_children
|
||||||
|
children_ids = parent_children[parent_id]
|
||||||
|
|
||||||
if parent_id is None:
|
for i, id in enumerate(children_ids):
|
||||||
parent_id = self.main_partnumber
|
|
||||||
|
|
||||||
children_ids = self._parent_children[parent_id]
|
|
||||||
|
|
||||||
for index, child_id in enumerate(children_ids):
|
|
||||||
|
|
||||||
is_last_assembly_child = self._last_child_check(index, children_ids)
|
last_child = self._last_child_check(i, children_ids)
|
||||||
|
connector_symbol = self._set_connector_symbol(id, last_child)
|
||||||
|
background_color = self._set_background_color(id)
|
||||||
|
|
||||||
connector_symbol = self._set_connector_symbol(is_last_assembly_child)
|
self._print_entry(id, prefix, connector_symbol, background_color)
|
||||||
partnumber_background_color = self._set_text_background_color(child_id)
|
|
||||||
|
|
||||||
self._print_entry(child_id, prefix, connector_symbol, partnumber_background_color)
|
if id in parent_children:
|
||||||
|
next_prefix = self._set_next_prefix(prefix, id, last_child)
|
||||||
|
self._print_tree(parent_id=id, prefix=next_prefix)
|
||||||
|
|
||||||
if child_id in self._parent_children:
|
def _remove_ids_from_summary_amount(self, ids: list) -> list:
|
||||||
next_prefix = self._prefix(prefix, is_last_assembly_child)
|
"""
|
||||||
self._tree_body(parent_id=child_id, prefix=next_prefix)
|
Reduziert die Anzahl in der Zusammenfassung (z.B. der nicht migrierten Teilenummern),
|
||||||
|
um die Anzahl an Teilenummern, die vom User aus der Zusammenfassung ausgeschlossen wurden
|
||||||
|
"""
|
||||||
|
|
||||||
def _tree_summary(self):
|
if self.all_excluded_summary_ids is None:
|
||||||
|
return ids
|
||||||
|
return list(filter(lambda id: id not in self.excluded_summary_ids_in_bom, ids))
|
||||||
|
|
||||||
amount_all_sivas_ids = len(self._migration_status)
|
@property
|
||||||
amount_migrated_ids = sum(migration_status == True for migration_status in self._migration_status.values())
|
def excluded_summary_ids_in_bom(self) -> list:
|
||||||
amount_unmigrated_ids = amount_all_sivas_ids - amount_migrated_ids
|
""" Gibt alle Teilenummern zurück, die im Baum vorliegen, aber nicht in der Anzahl der Zusammenfassung enthalten sein sollen"""
|
||||||
|
|
||||||
progress = int(amount_migrated_ids / amount_all_sivas_ids * 100)
|
if self._excluded_summary_ids_in_bom is None:
|
||||||
|
self._excluded_summary_ids_in_bom = list(filter(lambda id: id in self.asm_bom.bom_data, self.all_excluded_summary_ids))
|
||||||
|
return self._excluded_summary_ids_in_bom
|
||||||
|
|
||||||
|
def _print_summary(self):
|
||||||
|
|
||||||
|
ids_in_rd = self.migration_status.ids_in_rd
|
||||||
|
ids_pending = self.migration_status.ids_pending
|
||||||
|
|
||||||
|
amount_in_rd = len(self._remove_ids_from_summary_amount(ids_in_rd))
|
||||||
|
amount_pending = len(self._remove_ids_from_summary_amount(ids_pending))
|
||||||
|
|
||||||
|
if not self.no_blue_ids:
|
||||||
|
ids_in_progress = self.migration_status.ids_in_progress
|
||||||
|
amount_in_work = len(self._remove_ids_from_summary_amount(ids_in_progress))
|
||||||
|
amount_released = amount_in_rd - amount_in_work
|
||||||
|
|
||||||
|
child_ids = self.asm_bom.child_ids
|
||||||
|
progress = int(amount_in_rd / len(self._remove_ids_from_summary_amount(child_ids)) * 100)
|
||||||
|
|
||||||
column_width = 5
|
column_width = 5
|
||||||
border_padding = "".ljust(column_width, "─")
|
border_padding = "".ljust(column_width, "─")
|
||||||
empty_padding = "".ljust(column_width, " ")
|
empty_padding = "".ljust(column_width, " ")
|
||||||
|
|
||||||
print(f"""
|
|
||||||
╭─────────────────────────────────────{border_padding}╮
|
red_entry = f"│{Treeview.console_colors['RED'] } {Treeview.console_colors['RESET']}│ Migration ausstehend │ {str(amount_pending).ljust(column_width)}│"
|
||||||
│ Auswertung {empty_padding}│
|
|
||||||
├───────────────────────────────────┬─{border_padding}┤
|
if not self.no_blue_ids:
|
||||||
│ Anzahl abgeschlossene Migrationen │ {str(amount_migrated_ids).ljust(column_width)}│
|
blue_entry = f"│{Treeview.console_colors['BLUE'] } {Treeview.console_colors['RESET']}│ PDM-Migration abgeschlossen │ {str(amount_in_work).ljust(column_width)}│\n"
|
||||||
│ Anzahl fehlende Migrationen │ {str(amount_unmigrated_ids).ljust(column_width)}│
|
green_entry = f"│{Treeview.console_colors['GREEN']} {Treeview.console_colors['RESET']}│ Migration abgeschlossen (Freigegeben) │ {str(amount_released).ljust(column_width)}│\n"
|
||||||
├───────────────────────────────────┼─{border_padding}┤
|
|
||||||
│ Migrationsfortschritt │ {f"{progress}%".ljust(column_width)}│
|
else:
|
||||||
╰───────────────────────────────────┴─{border_padding}╯
|
blue_entry = ""
|
||||||
""")
|
green_entry = f"│{Treeview.console_colors['GREEN']} {Treeview.console_colors['RESET']}│ Migration abgeschlossen │ {str(amount_in_rd).ljust(column_width)}│\n"
|
||||||
|
red_entry = f"│{Treeview.console_colors['RED'] } {Treeview.console_colors['RESET']}│ Migration ausstehend │ {str(amount_pending).ljust(column_width)}│"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
header = f"""
|
||||||
|
╭───────────────────────────────────────────{border_padding}╮
|
||||||
|
│ Auswertung {empty_padding}│
|
||||||
|
├─┬───────────────────────────────────────┬─{border_padding}┤
|
||||||
|
"""
|
||||||
|
progress_segment = f"""
|
||||||
|
├─┴───────────────────────────────────────┼─{border_padding}┤
|
||||||
|
│ Migrationsfortschritt │ {f"{progress}%".ljust(column_width)}│
|
||||||
|
"""
|
||||||
|
|
||||||
|
bottom_row = f"╰─────────────────────────────────────────┴─{border_padding}╯"
|
||||||
|
|
||||||
|
|
||||||
|
exclusion_description = ""
|
||||||
|
excluded_id_list = ""
|
||||||
|
|
||||||
|
if self.asm_bom.excluded_ids_in_bom or self.excluded_summary_ids_in_bom:
|
||||||
|
|
||||||
|
exclusion_description = f"""├─────────────────────────────────────────┴─{border_padding}┤
|
||||||
|
│ {empty_padding}│
|
||||||
|
├───────────────────────────────────────────{border_padding}┤
|
||||||
|
│ Ausgeschlossene Teilenummern {empty_padding}│
|
||||||
|
│──────────────────────┬────────────────────{border_padding}┤
|
||||||
|
│ Baum │ Auswertung {empty_padding}│
|
||||||
|
├──────────────────────┼────────────────────{border_padding}┤
|
||||||
|
"""
|
||||||
|
|
||||||
|
for bom_id, smry_id in zip_longest(self.asm_bom.excluded_ids_in_bom, self.excluded_summary_ids_in_bom, fillvalue=9*" "):
|
||||||
|
excluded_id_list += f"│ { bom_id} │ {smry_id} {empty_padding}│\n"
|
||||||
|
|
||||||
|
bottom_row = f"╰──────────────────────┴────────────────────{border_padding}╯"
|
||||||
|
|
||||||
|
|
||||||
|
print(header + green_entry + blue_entry + red_entry + progress_segment + exclusion_description + excluded_id_list + bottom_row)
|
||||||
|
|
||||||
def _print_entry(self, child_id, prefix, connector, color):
|
def _print_entry(self, child_id, prefix, connector, color):
|
||||||
|
|
||||||
"""Prints tree entry"""
|
"""Eintrag in die Konsole drucken"""
|
||||||
|
|
||||||
# Necessary for calculating the padding-width after the partnumber
|
text_before_description = f"{prefix}{connector}{color}{child_id}{Treeview.console_colors['RESET']}".ljust(self.longest_entry)
|
||||||
longest_entry = self._max_tree_depth * len(Treeview.prefix_types["PIPE"]) \
|
description = self.asm_bom.get_prop_val_for_single_id(child_id, "Bezeichnung")
|
||||||
+ len(connector) \
|
|
||||||
+ len(self._longest_partnumber) \
|
|
||||||
+ len(Treeview.console_colors["RESET"]) \
|
|
||||||
+ len(Treeview.console_colors["RED"]) # other color codes (ansi escape sequences) could have been used instead since they all have the same length
|
|
||||||
|
|
||||||
text_before_description = f"{prefix}{connector}{color}{child_id}{Treeview.console_colors['RESET']}".ljust(longest_entry)
|
print(f"{text_before_description}{description}")
|
||||||
description = self._descriptions[child_id]
|
|
||||||
|
|
||||||
print(f"{text_before_description} {description}")
|
|
||||||
|
|
||||||
|
|
||||||
def _last_child_check(self, child_index, children):
|
def _last_child_check(self, child_idx, children_ids):
|
||||||
|
|
||||||
"""Checks, if current child is the last child of the assembly"""
|
"""Prüft, ob aktuelle ID das letzte Kind der Baugruppe ist"""
|
||||||
|
|
||||||
return True if child_index == len(children) - 1 else False
|
return True if child_idx == len(children_ids) - 1 else False
|
||||||
|
|
||||||
|
|
||||||
def _set_connector_symbol(self, child_is_last_child):
|
def _set_connector_symbol(self, child_id, last_child):
|
||||||
|
|
||||||
"""Chooses connector symbol for current tree entry"""
|
"""Legt Verbindungssymbol für aktuellen Eintrag im Baum fest"""
|
||||||
|
|
||||||
return Treeview.connector_symbols["ELBOW"] if child_is_last_child else Treeview.connector_symbols["T"]
|
if child_id == self.asm_id: # Oberste Baugruppennummer wird immer ohne Verbindersymbol dargestellt
|
||||||
|
return ""
|
||||||
|
|
||||||
|
if not last_child:
|
||||||
|
return Treeview.connector_symbols["T"]
|
||||||
|
|
||||||
|
return Treeview.connector_symbols["ELBOW"]
|
||||||
|
|
||||||
|
|
||||||
def _prefix(self, prefix, child_is_last_child):
|
def _set_next_prefix(self, prefix, child_id, last_child):
|
||||||
|
|
||||||
"""Creates prefix (part before the connector symbol) for each tree entry"""
|
"""Legt den Teil VOR dem Verbindersymbol für den nächsten Eintrag im Baum fest"""
|
||||||
|
|
||||||
prefix += Treeview.prefix_types["EMPTY"] if child_is_last_child else Treeview.prefix_types["PIPE"]
|
if child_id == self.asm_id: # Erste Stücklistenposition der obersten Baugruppennummer hat nie Präfix
|
||||||
|
return ""
|
||||||
|
|
||||||
|
prefix += Treeview.prefix_types["EMPTY"] if last_child else Treeview.prefix_types["PIPE"]
|
||||||
return prefix
|
return prefix
|
||||||
|
|
||||||
|
|
||||||
def _set_text_background_color(self, partnumber):
|
def _set_background_color(self, id):
|
||||||
|
|
||||||
"""Sets background color of partnumber in console depending on its migration status
|
"""Legt Hintergrundfarbe der Teilenummer basierend auf ihrem Migrationsstatus fest:
|
||||||
- Migration completed: green
|
|
||||||
- Migration pending: red"""
|
|
||||||
|
|
||||||
return Treeview.console_colors["GREEN"] if self._migration_status[partnumber] is True else Treeview.console_colors["RED"]
|
- grün: Migration vollständig abgeschlossen und freigegeben
|
||||||
|
- blau: Migration ins PDM abgeschlossen
|
||||||
|
- rot: Migration ausstehend"""
|
||||||
|
|
||||||
|
if id in self.migration_status.ids_pending:
|
||||||
|
return Treeview.console_colors["RED"]
|
||||||
|
|
||||||
|
if not self.no_blue_ids:
|
||||||
|
if id in self.migration_status.ids_in_progress:
|
||||||
|
return Treeview.console_colors["BLUE"]
|
||||||
|
|
||||||
|
return Treeview.console_colors["GREEN"]
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='Das Programm gibt Auskunft über den aktuellen Migrationsstand', prog='compare_lists')
|
|
||||||
parser.add_argument('-n', '--number', action='store', required=True, help='Eingabe der SIVAS-Teilenummer, für die der Migrationsstatus angezeigt werden soll', metavar="id")
|
def main():
|
||||||
parser.add_argument('-t', '--tree', action='store_true', help='Erzeugt Baumdarstellung aller Teilenummern. grün = Teilenummer vorhanden, rot = Migration ausstehend')
|
|
||||||
parser.add_argument('-e', '--excel', action='store_true', help='Erzeugt Excel-Datei in der alle Teilenummern, die migriert werden müssen, aufgelistet sind')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
parser = argparse.ArgumentParser(description='Programm gibt Auskunft über den aktuellen Migrationsstand einer SIVAS-Teilenummer',
|
||||||
|
prog='compare_lists',
|
||||||
|
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=50)) # Hilfetext auch bei längeren Argumenten in gleicher Zeile wie Argument darstellen
|
||||||
|
|
||||||
environment = Environment()
|
# Custom Actions
|
||||||
|
parser.register("action", "GetIDsFromCFG", GetExcludedIDsFromCFG)
|
||||||
|
parser.register("action", "lstrip", LStrip)
|
||||||
|
parser.register("action", "LocateSQLCredentials", LocateSQLCredentials)
|
||||||
|
|
||||||
if args.excel:
|
parser.add_argument('sivas_id', action='lstrip', help='Teilenummer, für die Migrationsüberblick generiert werden soll.', metavar="SIVAS-Teilenummer")
|
||||||
num = args.number.lstrip()
|
parser.add_argument('output_type', choices=["tree", "excel"], help="'tree' = Darstellung des Überblicks als Baum in der Konsole. 'excel' = Export des Überblicks als Excel")
|
||||||
excel_comparison = ExcelExport(num, environment.data_dir, environment.data_dir, environment.ruledesigner_csv_filename)
|
parser.add_argument('--rd_ids_filepath', action='store', default=os.path.join(os.environ.get("CREMIG_DATA"), "RD_Teilenummern.csv"), help='Verzeichnis der CSV-Datei mit den RuleDesigner-Nummern. Default: $CREMIG_DATA', metavar="filepath")
|
||||||
excel_comparison.write_excel()
|
parser.add_argument('--local_rd_ids', action='store_true', default=False, help='Lokales laden der CSV mit den RuleDesigner-Nummern (RD-Teilenummer.csv) statt Kopieren von Server')
|
||||||
elif args.tree:
|
parser.add_argument('--bom_filedir', action='store', default=os.environ.get("CREMIG_DATA"),help='Verzeichnis der JSON-Datei mit den Stücklisteninformationen. Default: $CREMIG_DATA', metavar='dir')
|
||||||
num = args.number.lstrip()
|
parser.add_argument('--local_bom', action='store_true', default=False, help='Lokales laden der JSON mit den Stücklisteninformationen statt Generierung')
|
||||||
treeview_comparison = Treeview(num, environment.data_dir, environment.data_dir, environment.ruledesigner_csv_filename)
|
parser.add_argument('--teilestamm_filedir', action='store', default=os.environ.get("CREMIG_DATA"), help='Verzeichnis der CSV mit den SIVAS-Teilestamminformationen. Default: $CREMIG_DATA', metavar='dir')
|
||||||
treeview_comparison.generate_tree()
|
parser.add_argument('--local_teilestamm', action='store_true', default=False, help='Lokales Laden der CSV mit den Teilestamminformationen statt Generierung')
|
||||||
else:
|
parser.add_argument('--no_blue_ids', action="store_true", default=False, help='Nummern, die in RD vorliegen, aber nicht freigegeben sind, gleich wie freigegeben Nummern einfärben')
|
||||||
parser.print_help()
|
|
||||||
|
exclude_from_overview = parser.add_mutually_exclusive_group()
|
||||||
|
exclude_from_overview.add_argument('--rm_bom_ids_str', action="store", nargs="*", default=None, dest="excluded_bom_ids", help="Angabe aller Nummern, die vom Migrationsüberblick ausgeschlossen sein sollen", metavar="id1 id2")
|
||||||
|
exclude_from_overview.add_argument('--rm_bom_ids_cfg', action="GetIDsFromCFG", nargs=2, default=None, dest="excluded_bom_ids", help="cfg-Pfad & Sektion, in der Nummern aufgelistet sind, die nicht im Überblick dargestellt sein sollen", metavar=("path", "section"))
|
||||||
|
|
||||||
|
exclude_from_summary = parser.add_mutually_exclusive_group()
|
||||||
|
exclude_from_summary.add_argument('--rm_summary_ids_str', action="store", nargs="*", default=None, dest="excluded_summary_ids", help="Angabe aller Nummern, die von der Zusammenfassung ausgeschlossen sein sollen", metavar="id1 id2")
|
||||||
|
exclude_from_summary.add_argument('--rm_summary_ids_cfg', action="GetIDsFromCFG", nargs=2, default=None, dest="excluded_summary_ids", help="cfg-Pfad & Sektion, in der Nummern aufgelistet sind, die von der Zusammenfassung ausgeschlossen sein sollen", metavar=("path", "section"))
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
match args.output_type:
|
||||||
|
case "excel":
|
||||||
|
excel_comparison = ExcelExport(asm_id=args.sivas_id,
|
||||||
|
asm_json_dir=args.bom_filedir,
|
||||||
|
asm_json_filename=f'{args.sivas_id}.json',
|
||||||
|
asm_csv_dir=args.teilestamm_filedir,
|
||||||
|
asm_csv_filename=f"{args.sivas_id}.csv",
|
||||||
|
rd_dbase_dir=os.path.dirname(args.rd_ids_filepath),
|
||||||
|
rd_dbase_filename=os.path.basename(args.rd_ids_filepath),
|
||||||
|
load_local_asm_json=args.local_bom,
|
||||||
|
load_local_asm_csv=args.local_teilestamm,
|
||||||
|
load_local_rd_dbase=args.local_rd_ids,
|
||||||
|
no_blue_ids=args.no_blue_ids)
|
||||||
|
|
||||||
|
excel_comparison.write_excel()
|
||||||
|
case "tree":
|
||||||
|
treeview_comparison = Treeview(asm_id=args.sivas_id,
|
||||||
|
asm_json_dir=args.bom_filedir,
|
||||||
|
asm_json_filename=f'{args.sivas_id}.json',
|
||||||
|
asm_csv_dir=args.teilestamm_filedir,
|
||||||
|
asm_csv_filename=f'{args.sivas_id}.csv',
|
||||||
|
rd_dbase_dir=os.path.dirname(args.rd_ids_filepath),
|
||||||
|
rd_dbase_filename=os.path.basename(args.rd_ids_filepath),
|
||||||
|
load_local_asm_json=args.local_bom,
|
||||||
|
load_local_asm_csv=args.local_teilestamm,
|
||||||
|
load_local_rd_dbase=args.local_rd_ids,
|
||||||
|
no_blue_ids=args.no_blue_ids,
|
||||||
|
excluded_bom_ids=args.excluded_bom_ids,
|
||||||
|
excluded_summary_ids=args.excluded_summary_ids)
|
||||||
|
|
||||||
|
treeview_comparison.generate_tree()
|
||||||
|
|
||||||
|
main()
|
||||||
+290
-375
@@ -1,17 +1,24 @@
|
|||||||
import os
|
import os
|
||||||
|
from tkinter import messagebox
|
||||||
|
import update_database
|
||||||
|
|
||||||
|
from manage_configs import SivasBOM, SivasTeilestamm, RuleDesignerDatabaseConfig, MigrationStatus
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Contains the logic for the MVC of CreoMigrate Gui
|
Contains the logic for the MVC of CreoMigrate Gui
|
||||||
"""
|
"""
|
||||||
# Infos und Fehlermeldungen die ausgelöst werden können
|
# Infos und Fehlermeldungen die ausgelöst werden können
|
||||||
messages = {
|
messages = {
|
||||||
|
"pdm_kategorie_definiert": "PDM-Kategorie nicht definiert",
|
||||||
"rüstcode_infos": 'Bitte Rüstcode auswählen!',
|
"rüstcode_infos": 'Bitte Rüstcode auswählen!',
|
||||||
"beschaffungsart_infos": ' Komponenten der Schweißbaugruppe müssen eigene Teilenummern erhalten, falls diese aktuell als Underline-Nummern in der Creo-Baugruppe vorliegen, aber keine eigenen Teilenummern in SIVAS besitzen!',
|
"beschaffungsart_infos": ' Komponenten der Schweißbaugruppe müssen eigene Teilenummern erhalten, falls diese aktuell als Underline-Nummern in der Creo-Baugruppe vorliegen, aber keine eigenen Teilenummern in SIVAS besitzen!',
|
||||||
"mengeneinheit_infos":'Bitte prüfen, ob Mengeneinheit ≠ "M - Meter" korrekt ist!',
|
"mengeneinheit_infos":'Bitte prüfen, ob Mengeneinheit ≠ "M - Meter" korrekt ist!',
|
||||||
"material_infos":'Werkstoffvorschlag nicht möglich, da das Material nicht in der Mappingdatei "Materialübersetzung.json" enthalten ist.\nBitte Werkstoff in dieser Datei nachfpflegen und prüfen, ob der Werkstoff in den nachfolgenden Systemen vorhanden ist:\n- RuleDesigner\n- SIVAS-Produktiv- und Schulungsdatenbank\n- Solid Edge\nWenn nicht, bitte in diesen Systemen ebenfalls nachpflegen!',
|
"material_infos":'Werkstoffvorschlag nicht möglich, da das Material nicht in der Mappingdatei "Materialübersetzung.json" enthalten ist.\nBitte Werkstoff in dieser Datei nachfpflegen und prüfen, ob der Werkstoff in den nachfolgenden Systemen vorhanden ist:\n- RuleDesigner\n- SIVAS-Produktiv- und Schulungsdatenbank\n- Solid Edge\nWenn nicht, bitte in diesen Systemen ebenfalls nachpflegen!',
|
||||||
"unzulaessige_zeichen":'Unzulässige Zeichen identifiziert:\nZeichen: {Zeichentyp} -> Feld: {Feldname}',
|
"unzulaessige_zeichen":"Unzulässige Zeichen identifiziert:\nZeichen: '{Zeichentyp}' -> Feld: '{Feldname}'",
|
||||||
"bezeichnung_zu_gross":'Bezeichnung besitzt mehr als 50 Zeichen. Bitte verkürzen!',
|
"bezeichnung_zu_gross_50":'Bezeichnung besitzt mehr als 50 Zeichen. Bitte verkürzen!',
|
||||||
|
"bezeichnung_zu_gross_45":'Bezeichnung besitzt mehr als 45 Zeichen. Bitte verkürzen!',
|
||||||
"konflikt_ruestcode_saegeliste":'In Sivas prüfen, wieso Haken bei "Halbzeug ohne Sägeliste" trotz Rüstcode "SRC Standard Rüstcode" gesetzt ist.',
|
"konflikt_ruestcode_saegeliste":'In Sivas prüfen, wieso Haken bei "Halbzeug ohne Sägeliste" trotz Rüstcode "SRC Standard Rüstcode" gesetzt ist.',
|
||||||
"teilenummre_ohne_ruestcode":'Teilenummer darf nicht ohne Rüstcode migriert werden!',
|
"teilenummer_ohne_ruestcode":'Teilenummer darf nicht ohne Rüstcode migriert werden!',
|
||||||
"fertigungsart":'Fertigungsart falsch. Bitte berichtigen!',
|
"fertigungsart":'Fertigungsart falsch. Bitte berichtigen!',
|
||||||
"fos_gruppe":'FOS-Gruppe falsch. Bitte berichtigen!',
|
"fos_gruppe":'FOS-Gruppe falsch. Bitte berichtigen!',
|
||||||
"kalkulations_art":'Kalkulationsart falsch. Bitte berichtigen!',
|
"kalkulations_art":'Kalkulationsart falsch. Bitte berichtigen!',
|
||||||
@@ -21,168 +28,199 @@ messages = {
|
|||||||
"tos_gruppe_not_exist":'TOS-Gruppe exisitert nicht. Bitte eingetragene Gruppennummer korrigieren oder ergänzen!',
|
"tos_gruppe_not_exist":'TOS-Gruppe exisitert nicht. Bitte eingetragene Gruppennummer korrigieren oder ergänzen!',
|
||||||
"dispo_not_exist":'Datensatz kann nicht ohne Dispogruppe migriert werden. Bitte nachpflegen!',
|
"dispo_not_exist":'Datensatz kann nicht ohne Dispogruppe migriert werden. Bitte nachpflegen!',
|
||||||
"dispolauf_not_exist":'Datensatz kann nicht ohne Dispolaufgruppe migriert werden. Bitte nachpflegen!',
|
"dispolauf_not_exist":'Datensatz kann nicht ohne Dispolaufgruppe migriert werden. Bitte nachpflegen!',
|
||||||
"teilenummer_not_exist_infos":'Ersetzte Teilenummer {Ersetzte Teilenummer} exisitert noch nicht in RuleDesigner. Migration trotzdem durchführen?',
|
"teilenummer_not_exist_infos":"Ersetzte Teilenummer '{teilenummer}' exisitert noch nicht in RuleDesigner. Migration trotzdem durchführen?",
|
||||||
"ersatzteilenummer_not_exist_infos":'Ersatz-Teilenummer {Ersatz-Teilenummer} exisitert noch nicht in RuleDesigner. Migration trotzdem durchführen?',
|
"ersatzteilenummer_not_exist_infos":"Ersatz-Teilenummer '{teilenummer}' exisitert noch nicht in RuleDesigner. Migration trotzdem durchführen?",
|
||||||
"werkstofftyp_not_exist":'Eingetragener Werkstofftyp exisitert nicht. Bitte korrigeren!',
|
"hersteller": "Hersteller nicht in RuleDesigner enthalten. Bitte nachpflegen!",
|
||||||
|
"werkstofftyp_not_exist":'Eingetragener Werkstofftyp existiert nicht. Bitte korrigeren!',
|
||||||
"werkstoff_not_exist":'Werkstoff falsch. Bitte korrigieren!',
|
"werkstoff_not_exist":'Werkstoff falsch. Bitte korrigieren!',
|
||||||
"color_not_defined":'Teilenummer kann nicht ohne festgelegte Farbe migriert werden!',
|
"color_not_defined":'Teilenummer kann nicht ohne festgelegte Farbe migriert werden!',
|
||||||
"aenderungstext_too_long":'Änderungstext_weist zu viele Zeichen auf. Bitte auf 400 Zeichen verkürzen!',
|
"aenderungstext_too_long":'Änderungstext_weist zu viele Zeichen auf. Bitte auf 400 Zeichen verkürzen!',
|
||||||
|
"missing_data":'Fehlende Angaben in der Oberfläche: {Labels}',
|
||||||
|
"sivas_db_error":'Diese Assembly existiert nicht. Eventuell ist es nur ein Teil?',
|
||||||
|
"export_sucessful":'Export der Migrationsdatei erfolgreich. Siehe {path}',
|
||||||
|
"export_not_sucessful":'Export der Migrationsdatei fehlgeschlagen. Überprüfe Schreibrechte für {path}.',
|
||||||
|
"export_not_sucessful_file_open":'Export fehlgeschlagen. Datei offen?',
|
||||||
|
"blacklist_not_exist": 'Bitte Blacklist vom Server holen',
|
||||||
|
"wrong_impftool_path": 'Pfad zur DataPrepUtility.exe nicht gefunden. Bitte Pfad unter ...\\bin\\cremig_setenv.bat prüfen.',
|
||||||
|
"too_many_logfiles":'Keine eindeutige Logdatei zum aktuellen DataPrep Prozess gefunden. Bitte löschen Sie die überflüssigen .log files',
|
||||||
|
"some_error_in_log":'Log Datei enthält einen Fehler. Bitte prüfen.',
|
||||||
|
"preparation_sucessful":'Preparation mit der Datei {path} erfolgreich',
|
||||||
|
"missing_in_blacklist":"{teilenummer} fehlt in der Blacklist, da sich in dessen Stückliste beigestellte oder dispo-inaktive Positionen befinden.\n\nBitte {teilenummer} in die Blacklist aufnehmen! \n\nDiese befindet sich in folgender Datei:\n//ruledesigner\\RDF_Daten\\Konfigurator\\CustomVaulting\\ERP_BOM.ini\n\nDanach dieses Programm erneut starten um die aktualisierte Blacklist zu laden",
|
||||||
|
"halbzeug_not_in_RDids":"Halbzeug-Teilenummer '{halbzeug_id}' fehlt in '{rdids_path}'.\n\nEntweder wurde das Halbzeug noch nicht migriert, oder der aktuelle Stand von RD_Teilenummern.csv muss geladen werden.\n\nZum Laden des aktuellen Standes von RD_Teilenummern.csv auf 'Suche' unter dem Eingabefeld der Baugruppennummer klicken und dieses Programm neu starten"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# die folgende Hash ist nur für schnelleres Editieren hier
|
# Der Beobachter
|
||||||
gui_data_keys = [
|
class Observer:
|
||||||
"asm_id",
|
def __init__(self):
|
||||||
"teilenummer",
|
pass
|
||||||
"datenbank",
|
|
||||||
"pdm_kategorie_neu",
|
def attach(self, observable):
|
||||||
"neuaufbau",
|
observable.subscribe(self)
|
||||||
"aus_halbzeug_neu",
|
|
||||||
"halbzeugnummer_neu",
|
def notify(self, observable, *args, **kwargs):
|
||||||
"halbzeuglaenge_neu",
|
#print(f"Got {args} {kwargs} from {observable}")
|
||||||
"halbzeugoberflaeche_neu",
|
dependent_cbs = self._model.get_dependent(args[0])
|
||||||
"lebenszyklus_status_neu",
|
for cb in dependent_cbs:
|
||||||
"bezeichnung1_sivas", "bezeichnung1_neu",
|
model_values = self._model.callback(cb, None)
|
||||||
"bezeichnung2_sivas", "bezeichnung2_neu",
|
if model_values:
|
||||||
"halbzeugOhneSaege_sivas", "halbzeugOhneSaege_neu",
|
self.set_gui_dict(model_values)
|
||||||
"ruestcode_sivas", "ruestcode_neu",
|
self.refresh_gui()
|
||||||
"fertigungsart_sivas", "fertigungsart_neu",
|
|
||||||
"allgemeintoleranz_sivas", "allgemeintoleranz_neu",
|
|
||||||
"fosGruppe_sivas", "fosGruppe_neu",
|
|
||||||
"kalkulationsart_sivas", "kalkulationsart_neu",
|
|
||||||
"beschaffungsart_sivas", "beschaffungsart_neu",
|
|
||||||
"mengeneinheit_sivas", "mengeneinheit_neu",
|
|
||||||
"halbzeug_sivas", "halbzeug_neu",
|
|
||||||
"tosgruppe_sivas", "tosgruppe_neu",
|
|
||||||
"dispogruppe_sivas", "dispogruppe_neu",
|
|
||||||
"dispolaufgruppe_sivas","dispolaufgruppe_neu",
|
|
||||||
"hersteller_sivas", "hersteller_neu",
|
|
||||||
"ersatzfuer_sivas", "ersatzfuer_neu",
|
|
||||||
"ersetztdurch_sivas", "ersetztdurch_neu",
|
|
||||||
"herstteilenr_sivas", "herstteilenr_neu",
|
|
||||||
"werkstoffdiskr_sivas",
|
|
||||||
"werkstofftyp_sivas", "werkstofftyp_neu",
|
|
||||||
"material_sivas", "material_neu",
|
|
||||||
"oberflaeche_neu",
|
|
||||||
"farbe_neu",
|
|
||||||
"version_sivas", "version_neu",
|
|
||||||
"aenderungsindex_sivas", "aenderungsindex_neu",
|
|
||||||
"aenderungstext_sivas", "aenderungstext_neu",
|
|
||||||
"freigabevermerk_sivas", "freigabevermerk_neu",
|
|
||||||
"zusatzinfos_auto_text",
|
|
||||||
"zusatzinfos_bendef_text",
|
|
||||||
# Felder der Comboboxen. benannt wie deren callbacks
|
|
||||||
"cb_pdm_kategorie_neu",
|
|
||||||
"cb_halbzeug_neu",
|
|
||||||
"cb_halbzeugoberflaeche",
|
|
||||||
"cb_halbzeugfarbe",
|
|
||||||
"cb_lebenszyklus_status_neu",
|
|
||||||
"cb_3Dmodel_neu",
|
|
||||||
"cb_halbzeugOhneSaege_neu",
|
|
||||||
"cb_ruestcode_neu",
|
|
||||||
"cb_fertigungsart_neu",
|
|
||||||
"cb_allgemeintoleranz_neu",
|
|
||||||
"cb_fosGruppe_neu",
|
|
||||||
"cb_kalkulationsart_neu",
|
|
||||||
"cb_beschaffungsart_neu",
|
|
||||||
"cb_mengeneinheit_neu",
|
|
||||||
"cb_dispogruppe_neu",
|
|
||||||
"cb_dispolaufgruppe_neu",
|
|
||||||
"cb_hersteller_neu",
|
|
||||||
"cb_werkstofftyp_neu",
|
|
||||||
"cb_material_neu",
|
|
||||||
"cb_oberflaeche_neu",
|
|
||||||
"cb_farbe_neu",
|
|
||||||
# buttons
|
|
||||||
"cb_speichern",
|
|
||||||
"cb_migrieren",
|
|
||||||
"cb_zurücksetzen",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class Controller():
|
|
||||||
|
|
||||||
|
|
||||||
|
class Controller(Observer):
|
||||||
"""
|
"""
|
||||||
Class for manipulating the model and returning data for the view
|
Class for manipulating the model and returning data for the view
|
||||||
"""
|
"""
|
||||||
def __init__(self, model, view):
|
def __init__(self, model, view):
|
||||||
|
self._environment = None
|
||||||
|
self._config = None
|
||||||
self.set_model(model)
|
self.set_model(model)
|
||||||
self.set_view(view)
|
self.set_view(view)
|
||||||
self.logic = None
|
|
||||||
self.env = None
|
|
||||||
|
|
||||||
def set_env(self, env):
|
def set_env(self, env):
|
||||||
self.environment = env
|
self._environment = env
|
||||||
|
|
||||||
def get_env(self, env_path):
|
def get_env(self, env_path):
|
||||||
if self.environment == None:
|
if self._environment == None:
|
||||||
raise Exception("No environment set")
|
raise Exception("No environment set")
|
||||||
if env_path == "lib":
|
if env_path == "lib":
|
||||||
ret = self.environment.lib_dir
|
ret = self._environment.lib_dir
|
||||||
elif env_path == "data":
|
elif env_path == "data":
|
||||||
ret = self.environment.data_dir
|
ret = self._environment.data_dir
|
||||||
elif env_path == "out":
|
elif env_path == "out":
|
||||||
ret = self.environment.out_dir
|
ret = self._environment.out_dir
|
||||||
elif env_path == "cfg":
|
elif env_path == "cfg":
|
||||||
ret = self.environment.cfg_dir
|
ret = self._environment.cfg_dir
|
||||||
|
elif env_path == "log":
|
||||||
|
ret = self._environment.log_dir
|
||||||
|
elif env_path == "rd_dbase_filename":
|
||||||
|
ret = self._environment.ruledesigner_csv_filename
|
||||||
else:
|
else:
|
||||||
raise Exception("this path is not defined "+env_path)
|
raise Exception("this path is not defined "+env_path)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def add_logic(self, logic):
|
def set_config(self, config):
|
||||||
self.logic = logic
|
self._config = config
|
||||||
def remove_logic(self):
|
def get_config(self):
|
||||||
self.logic = None
|
return self._config
|
||||||
|
|
||||||
|
def get_orange_ids(self, red_ids):
|
||||||
|
"""just check which files have already been worked with, so data has been added"""
|
||||||
|
orange = dict()
|
||||||
|
work = self.get_env('out')
|
||||||
|
for red in red_ids:
|
||||||
|
if os.path.exists(os.path.join(work, red +'.json')):
|
||||||
|
orange[red] = True
|
||||||
|
return orange
|
||||||
|
|
||||||
|
def get_csv_files_of_asm(self, asm_id, load_local_bom=False, load_local_teilestamm=False, load_local_rd_ids=False):
|
||||||
|
|
||||||
|
""" Holt sich die Metadaten der Stücklistenpositionen als CSV"""
|
||||||
|
data_dir = self.get_env("data")
|
||||||
|
rd_dbase_filename = self.get_env("rd_dbase_filename")
|
||||||
|
|
||||||
|
excluded_bom_ids = self._config.bom_config.get_excluded_ids("ExcludedPartnumbersInBOM") # Artikelnummern wie z.B. "MA0000006" sollen nicht im Baum dargestellt werden
|
||||||
|
|
||||||
|
sivas_bom = SivasBOM(asm_id, data_dir, asm_id + '.json', load_local_bom, excluded_bom_ids)
|
||||||
|
|
||||||
|
sivas_bom.extend_asm_bom(asm_id, {"Parent": None, "Position": "10/0"}) # Ergänzt Stücklistendaten um eine fiktive Baugruppe "None", in der die Haupt-Teilenummer als Pos. 1 vorliegt. Dadurch können auch Teilenummern ohne Stückliste korrekt abgebildet werden
|
||||||
|
|
||||||
|
rd_data = RuleDesignerDatabaseConfig(data_dir, rd_dbase_filename, load_local_rd_ids)
|
||||||
|
|
||||||
|
migration_status = MigrationStatus(sivas_bom.child_ids, rd_data.ids)
|
||||||
|
pending_ids = migration_status.ids_pending
|
||||||
|
|
||||||
|
sivas_teilestamm = SivasTeilestamm(data_dir, asm_id + '.csv', load_local_csv=load_local_teilestamm)
|
||||||
|
sivas_teilestamm.create_csvs(pending_ids)
|
||||||
|
|
||||||
|
self._model.set_red_ids(pending_ids)
|
||||||
|
self._model.set_parent_children(sivas_bom.parent_children)
|
||||||
|
self._model.set_asm_id(asm_id)
|
||||||
|
self._model.set_bom_properties(sivas_bom.all_bom_properties)
|
||||||
|
|
||||||
def set_model(self, model):
|
def set_model(self, model):
|
||||||
self.model = model
|
self._model = model
|
||||||
|
self.attach(model)
|
||||||
|
|
||||||
def set_view(self, view):
|
def set_view(self, view):
|
||||||
self.view = view
|
self._view = view
|
||||||
|
|
||||||
def refresh_gui(self):
|
def refresh_gui(self):
|
||||||
self.view.data_from_model()
|
self._view.data_from_model()
|
||||||
def data_from_model(self):
|
self._view.set_states()
|
||||||
self.view.data_from_model()
|
# def data_from_model(self):
|
||||||
|
# self._view.data_from_model()
|
||||||
|
def data_from_view(self, key=None):
|
||||||
|
return self._view.data_from_view(key)
|
||||||
|
|
||||||
def get_current_asm_id(self):
|
def get_current_asm_id(self):
|
||||||
self.model.get_current_asm_id()
|
self._model.get_asm_id()
|
||||||
def set_current_asm_id(self, asm_id):
|
def set_current_asm_id(self, asm_id, load_local_bom=False, load_local_teilestamm=False, load_local_rd_ids=False):
|
||||||
self.model.set_current_asm_id(asm_id)
|
# TODO save current given data. In case, ask whether you should save or drop
|
||||||
|
self._model.set_asm_id(asm_id)
|
||||||
|
# hole alle Daten vom Server
|
||||||
|
self.get_csv_files_of_asm(asm_id, load_local_bom, load_local_teilestamm, load_local_rd_ids)
|
||||||
|
|
||||||
def set_current_item_id(self, cid):
|
def set_current_item_id(self, cid):
|
||||||
self.set_gui_data('teilenummer', cid)
|
"""setze eine neue Item ID """
|
||||||
|
# check before. change to given item just in case it is valid, e.g. name is a number of 9 digits
|
||||||
loaded_csv = self.model.sivas_data_from_csv(cid)
|
if not cid.isnumeric():
|
||||||
gui_dict = self.logic.csv2guidata(loaded_csv)
|
return
|
||||||
self.model.set_gui_dict(gui_dict)
|
# nur die red-id Daten können geladen werden.
|
||||||
|
# red_ids = self._model.get_red_ids()
|
||||||
|
# if not cid in red_ids:
|
||||||
|
# return
|
||||||
|
|
||||||
|
# TODO save current given data. In case, ask whether you should save or drop
|
||||||
|
self._model.set_current_item_id(cid)
|
||||||
|
self._load_cid_data2model(cid)
|
||||||
|
|
||||||
|
def get_current_item_id(self):
|
||||||
|
return self._model.get_current_item_id()
|
||||||
|
|
||||||
|
def _load_cid_data2model(self, cid):
|
||||||
|
"""lädt alle nötigen Daten für diese ID """
|
||||||
|
# falls eine .json Datei davon im Work Ordner existiert, dann diese zuerst versuchen ins Modell zu laden
|
||||||
|
self._view.clear_rightframes()
|
||||||
|
self._model.clear()
|
||||||
|
saved_json_exists = self._model.from_json_file(self.get_env("out"), cid)
|
||||||
|
if saved_json_exists == False:
|
||||||
|
# ansonsten die .csv Datei mit den SIVAS Infos aus data holen
|
||||||
|
loaded = self._model.sivas_data_from_csv(cid)
|
||||||
|
if loaded == None:
|
||||||
|
print("no file found "+ cid)
|
||||||
|
else:
|
||||||
|
# und diese in der Gui setzen
|
||||||
|
set_data = self._model.csv2guidata(loaded)
|
||||||
|
self.set_gui_dict(set_data)
|
||||||
|
self._model.set_gui_defaults()
|
||||||
self.refresh_gui()
|
self.refresh_gui()
|
||||||
|
|
||||||
|
|
||||||
def set_red_ids(self, red_ids):
|
def set_red_ids(self, red_ids):
|
||||||
self.model.set_red_ids(red_ids)
|
self._model.set_red_ids(red_ids)
|
||||||
def get_red_ids(self):
|
def get_red_ids(self):
|
||||||
return self.model.get_red_ids()
|
return self._model.get_red_ids()
|
||||||
|
|
||||||
def set_parent_children(self, parent_children_mapping):
|
def set_parent_children(self, parent_children_mapping):
|
||||||
self.model.set_parent_children(parent_children_mapping)
|
self._model.set_parent_children(parent_children_mapping)
|
||||||
def get_parent_children(self):
|
def get_parent_children(self):
|
||||||
return self.model.get_parent_children()
|
return self._model.get_parent_children()
|
||||||
|
|
||||||
# merkt sich die reinen Daten zum Impfen
|
# # merkt sich die reinen Daten zum Impfen
|
||||||
def set_data_dict(self, data:dict):
|
# def set_data_dict(self, data:dict):
|
||||||
"""merken der Daten zum Impfen"""
|
# """merken der Daten zum Impfen"""
|
||||||
for k,v in data:
|
# for k,v in data:
|
||||||
self.set_data(k,v)
|
# self.set_data(k,v)
|
||||||
def set_data(self, key, value):
|
# def set_data(self, key, value):
|
||||||
"""merken der Daten zum Impfen"""
|
# """merken der Daten zum Impfen"""
|
||||||
self.model.set_data(key, value)
|
# self._model.set_data(key, value)
|
||||||
|
|
||||||
def get_data(self, key):
|
# def get_data(self, key):
|
||||||
return self.model.get_data(key)
|
# return self._model.get_data(key)
|
||||||
def get_all_data(self):
|
# def get_all_data(self):
|
||||||
return self.model.get_all_data()
|
# return self._model.get_all_data()
|
||||||
|
|
||||||
# merkt sich die Nutzereingaben, bzw. Daten für die GUI
|
# merkt sich die Nutzereingaben, bzw. Daten für die GUI
|
||||||
def set_gui_dict(self, data:dict):
|
def set_gui_dict(self, data:dict):
|
||||||
@@ -191,274 +229,151 @@ class Controller():
|
|||||||
self.set_gui_data(k,v)
|
self.set_gui_data(k,v)
|
||||||
def set_gui_data(self, key, value):
|
def set_gui_data(self, key, value):
|
||||||
"""merken der Eingaben des Nutzers der GUI """
|
"""merken der Eingaben des Nutzers der GUI """
|
||||||
self.model.set_gui_data(key, value)
|
self._model.set_gui_data(key, value)
|
||||||
|
|
||||||
def get_gui_data(self, key):
|
def get_gui_data(self, key):
|
||||||
return self.model.get_gui_data(key)
|
return self._model.get_gui_data(key)
|
||||||
def get_all_gui_data(self):
|
def get_all_gui_data(self):
|
||||||
return self.model.get_all_gui_data()
|
return self._model.get_all_gui_data()
|
||||||
|
|
||||||
|
def get_gui_states(self):
|
||||||
|
return self._model.get_states()
|
||||||
|
def get_configuration(self):
|
||||||
|
return self._model.get_configuration()
|
||||||
|
|
||||||
|
def message_info(self, title, key, values):
|
||||||
|
text = messages[key]
|
||||||
|
if 'halbzeug_id' in values:
|
||||||
|
text = text.format(halbzeug_id=values['halbzeug_id'], rdids_path=values['rdids_path'])
|
||||||
|
if 'path' in values:
|
||||||
|
text = text.format(path=values['path'])
|
||||||
|
return messagebox.showinfo(title, text)
|
||||||
|
def message_question(self, title, key, values={}):
|
||||||
|
text = messages[key]
|
||||||
|
if 'teilenummer' in values:
|
||||||
|
text = text.format(teilenummer=values['teilenummer'])
|
||||||
|
default = messagebox.NO
|
||||||
|
if 'default' in values and values['default'] == 'yes':
|
||||||
|
default = messagebox.YES
|
||||||
|
return messagebox.askquestion(title, text, type=messagebox.YESNO, default=default)
|
||||||
|
def message_error(self, title, key, values={}):
|
||||||
|
text = messages[key]
|
||||||
|
if 'Labels' in values:
|
||||||
|
text = text.format(Labels=values['Labels'])
|
||||||
|
if 'Zeichentyp' in values:
|
||||||
|
text = text.format(Zeichentyp=values['Zeichentyp'], Feldname=values['Feldname'] )
|
||||||
|
if 'path' in values:
|
||||||
|
text = text.format(path=values['path'])
|
||||||
|
if 'teilenummer' in values:
|
||||||
|
text = text.format(teilenummer=values['teilenummer'])
|
||||||
|
return messagebox.showerror(title, text)
|
||||||
|
|
||||||
def callback(self, key, value):
|
def callback(self, key, value):
|
||||||
if not self.logic:
|
if not self._model:
|
||||||
return
|
raise Exception("no model yet added")
|
||||||
model_values = self.logic.callback(key, value)
|
|
||||||
if model_values:
|
# Aktionen der Knöpfe
|
||||||
self.set_gui_dict(model_values)
|
if key == 'cb_speichern':
|
||||||
self.refresh_gui()
|
data = self.data_from_view()
|
||||||
|
self._model.set_gui_dict(data)
|
||||||
class GuiLogic():
|
self._model.save_to_file()
|
||||||
"""
|
|
||||||
Class for business logic. implementing the dependencies between different user inputs
|
|
||||||
"""
|
|
||||||
def __init__(self, model, configs):
|
|
||||||
# das Modell soll hier nur verwendet werden um aktuell Zustände abzufragen!
|
|
||||||
# alles weitere zum Setzen von Daten etc. muss über den Controller laufen, also zurück gegeben werden.
|
|
||||||
self.model = model
|
|
||||||
# hier holt man die Daten der Configs
|
|
||||||
self.config = configs
|
|
||||||
# hier sind alle Callbacks bzw. deren Comboboxen
|
|
||||||
self.callbacks = [
|
|
||||||
'cb_pdm_kategorie_neu',
|
|
||||||
'cb_neuaufbau',
|
|
||||||
'cb_aus_halbzeug_neu',
|
|
||||||
'cb_lebenszyklus_status_neu',
|
|
||||||
'cb_3Dmodel_neu',
|
|
||||||
'cb_halbzeugOhneSaege_neu',
|
|
||||||
'cb_ruestcode_neu',
|
|
||||||
'cb_fertigungsart_neu',
|
|
||||||
'cb_allgemeintoleranz_neu',
|
|
||||||
'cb_fosGruppe_neu',
|
|
||||||
'cb_kalkulationsart_neu',
|
|
||||||
'cb_beschaffungsart_neu',
|
|
||||||
'cb_mengeneinheit_neu',
|
|
||||||
'cb_halbzeug_neu',
|
|
||||||
'cb_dispogruppe_neu',
|
|
||||||
'cb_dispolaufgruppe_neu',
|
|
||||||
'cb_hersteller_neu',
|
|
||||||
'cb_werkstoffdiskrepanz',
|
|
||||||
'cb_werkstofftyp_neu',
|
|
||||||
'cb_material_neu',
|
|
||||||
'cb_oberflaeche_neu',
|
|
||||||
'cb_farbe_neu',
|
|
||||||
'cb_speichern',
|
|
||||||
'cb_migrieren',
|
|
||||||
'cb_zurücksetzen',
|
|
||||||
'cb_suche_asm'
|
|
||||||
]
|
|
||||||
# dies sind die Excel Headel der SIVAS csv Export Datei
|
|
||||||
# und wie diese in das Datenmodell der Gui integriert werden kann
|
|
||||||
self.excel_to_gui = {
|
|
||||||
"Teilenummer":"teilenummer",
|
|
||||||
"Bezeichnung1":"bezeichnung1_sivas",
|
|
||||||
"Bezeichnung2":"bezeichnung2_sivas",
|
|
||||||
"Beschaffungsart":"beschaffungsart_sivas",
|
|
||||||
"Mengeneinheit":"mengeneinheit_sivas",
|
|
||||||
"Halbzeug":"halbzeug_sivas",
|
|
||||||
"TOS_Gruppe":"tosgruppe_sivas",
|
|
||||||
"Dispogruppe":"dispolaufgruppe_sivas",
|
|
||||||
"Dispolaufgruppe":"dispolaufgruppe_sivas",
|
|
||||||
"ErsatzFuer":"ersatzfuer_neu",
|
|
||||||
"ErsetztDurch":"ersetztdurch_neu",
|
|
||||||
"AktuellerIndex":"aenderungsindex_sivas",
|
|
||||||
"Hersteller":"hersteller_sivas",
|
|
||||||
"HerstellerTeilenummer":"herstteilenr_sivas",
|
|
||||||
"Version":"version_sivas",
|
|
||||||
"HalbzeugExtern":"halbzeug_sivas",
|
|
||||||
"Werkstoff":"werkstofftyp_sivas",
|
|
||||||
"Oberfläche":"cb_oberflaeche_neu",
|
|
||||||
# "Truemmer":"truemmer",
|
|
||||||
# "HzOhneSaegeliste":"",
|
|
||||||
"Ruestcode":"ruestcode_sivas",
|
|
||||||
"Fertigungsart":"fertigungsart_sivas",
|
|
||||||
"FosGruppe":"fosGruppe_sivas",
|
|
||||||
"Kalkulationsart":"kalkulationsart_sivas",
|
|
||||||
#"Indexerfasser":"",
|
|
||||||
"Aenderungstext":"aenderungstext_sivas",
|
|
||||||
"Freigabevermerk":"freigabevermerk_sivas",
|
|
||||||
# "Indexbearbeiter":"in"
|
|
||||||
}
|
|
||||||
|
|
||||||
def csv2guidata(self, data):
|
|
||||||
ret = dict()
|
|
||||||
for k,v in data.items():
|
|
||||||
if k in self.excel_to_gui and v is not None:
|
|
||||||
ret[self.excel_to_gui[k]] = v
|
|
||||||
|
|
||||||
# Spezial: Befüllung von Änderungstext mit dem Author, falls in der .csv vorhanden
|
|
||||||
if "Indexerfasser" in data and "Aenderungstext" in data:
|
|
||||||
ret["aenderungstext_sivas"] = '{aenderungstext} (von {author})'.format(aenderungstext=data["Aenderungstext"], author=data["Indexerfasser"])
|
|
||||||
# Indexerfasser wird nicht in der gui verwaltet. Deshalb Modifikation aus den Rohdaten
|
|
||||||
|
|
||||||
# set defaults from given logic
|
|
||||||
r1 = self.callback("cb_neuaufbau", None)
|
|
||||||
ret.update(r1)
|
|
||||||
r2 = self.callback("cb_aus_halbzeug_neu", None)
|
|
||||||
ret.update(r2)
|
|
||||||
|
|
||||||
# add entry dependencies
|
|
||||||
dep = self.entry_dependencies(ret)
|
|
||||||
ret.update(dep)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def entry_dependencies(self, data):
|
|
||||||
ret = dict()
|
|
||||||
|
|
||||||
halbzeugoberflaeche = data["halbzeugoberflaeche_neu"]
|
|
||||||
if data["aus_halbzeug_neu"] == True:
|
|
||||||
if halbzeugoberflaeche == "eloxieren" or halbzeugoberflaeche == "lackieren" or halbzeugoberflaeche == "pulverbeschichten":
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
ret["halbzeugoberflaeche_neu"] = ''
|
|
||||||
else:
|
|
||||||
ret["halbzeugoberflaeche_neu"] = ''
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def callback(self, key, value):
|
|
||||||
"""gibt ein dict zurück, welches neu im Modell gesetzt wird"""
|
|
||||||
if key not in self.callbacks:
|
|
||||||
raise Exception("this callback does not exist "+key)
|
|
||||||
if key == 'cb_pdm_kategorie_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_neuaufbau':
|
|
||||||
return self.neuaufbau(value)
|
|
||||||
elif key == 'cb_aus_halbzeug_neu':
|
|
||||||
return self.aus_halbzeug_neu(value)
|
|
||||||
elif key == 'cb_lebenszyklus_status_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_3Dmodel_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_halbzeugOhneSaege_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_ruestcode_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_fertigungsart_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_allgemeintoleranz_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_fosGruppe_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_kalkulationsart_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_beschaffungsart_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_mengeneinheit_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_halbzeug_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_dispogruppe_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_dispolaufgruppe_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_hersteller_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_werkstoffdiskrepanz':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_werkstofftyp_neu':
|
|
||||||
return self.werkstofftyp(value)
|
|
||||||
elif key == 'cb_material_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_oberflaeche_neu':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_farbe_neu':
|
|
||||||
return self.farbe(value)
|
|
||||||
elif key == 'cb_speichern':
|
|
||||||
pass
|
|
||||||
elif key == 'cb_migrieren':
|
elif key == 'cb_migrieren':
|
||||||
pass
|
data = self.data_from_view()
|
||||||
|
self._model.set_gui_dict(data)
|
||||||
|
self.migrieren()
|
||||||
elif key == 'cb_zurücksetzen':
|
elif key == 'cb_zurücksetzen':
|
||||||
pass
|
self.zuruecksetzen()
|
||||||
elif key == 'cb_suche_asm':
|
elif key == 'cb_suche_asm':
|
||||||
pass
|
# hole dir die in die GUI eingetragene Nummer
|
||||||
|
update_database.get_blacklist(self.get_env("data"))
|
||||||
|
current_asmid = self.data_from_view('asm_id')
|
||||||
|
if current_asmid != '':
|
||||||
|
self.set_current_asm_id(current_asmid)
|
||||||
|
elif key == 'cb_ladelokal_asm':
|
||||||
|
# hole dir nur die lokalen Daten. Keine Datenbankabfrage außer Blacklist
|
||||||
|
update_database.get_blacklist(self.get_env("data"))
|
||||||
|
current_asmid = self.data_from_view('asm_id')
|
||||||
|
if current_asmid != '':
|
||||||
|
self.set_current_asm_id(current_asmid, load_local_bom=True, load_local_teilestamm=True, load_local_rd_ids=True)
|
||||||
|
elif key == 'cb_3dsuchen':
|
||||||
|
self.suche_3d()
|
||||||
|
|
||||||
|
# callbacks der gui zur
|
||||||
else:
|
else:
|
||||||
raise Exception("this callback does not exist "+key)
|
# Logik um neue Werte in Oberfläche oder Modell zu füllen
|
||||||
|
model_values = self._model.callback(key, value)
|
||||||
|
if model_values:
|
||||||
|
self.set_gui_dict(model_values)
|
||||||
|
|
||||||
def neuaufbau(self, trueOrfalse):
|
# gib dem observer Bescheid, was aufgerufen wurde
|
||||||
ret = dict()
|
self.notify(self._model, key,value)
|
||||||
pdm_kat = self.model.get_gui_data("pdm_kategorie_neu")
|
self.refresh_gui()
|
||||||
if pdm_kat != "Einzelteil" or pdm_kat != "Kaufteil":
|
|
||||||
ret["neuaufbau"] = False
|
def migrieren(self):
|
||||||
return ret
|
self._view.reset_labels()
|
||||||
|
|
||||||
|
# Pruefung ob Pflichtfelder befuellt
|
||||||
|
(ok, missing) = self._model.check_pflichtfelder()
|
||||||
|
if ok == False:
|
||||||
|
labels = ', '.join(missing)
|
||||||
|
self.message_error('Fehlende Angaben', 'missing_data', {'Labels':labels})
|
||||||
|
self._view.highlight_labels(missing)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Pruefung ob assembly-id in Blacklist fehlt
|
||||||
|
update_database.get_blacklist(self.get_env("data"))
|
||||||
|
(ok, missing_blacklist_id) = self._model.check_blacklist_completeness()
|
||||||
|
if ok == False:
|
||||||
|
id = ''.join(missing_blacklist_id)
|
||||||
|
self.message_error('Fehlend in Blacklist', 'missing_in_blacklist', {'teilenummer': id})
|
||||||
|
return
|
||||||
|
|
||||||
|
# Pruefung, ob unzulaessige Zeichen vorhanden
|
||||||
|
invalid_chars = self._config.InvalidChars.get()
|
||||||
|
(ok, wrongchars) = self._model.check_improper_chars(invalid_chars)
|
||||||
|
if ok == False:
|
||||||
|
for label,achars in wrongchars.items():
|
||||||
|
chars = ''.join(achars)
|
||||||
|
self.message_error('Unzulässige Zeichen', 'unzulaessige_zeichen', {'Zeichentyp': chars, 'Feldname':label})
|
||||||
|
self._view.highlight_labels(wrongchars)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Pruefung Feldinhalte
|
||||||
|
ok = self._model.check_content()
|
||||||
|
if ok == True:
|
||||||
|
data = self._model.create_migration_data()
|
||||||
|
try:
|
||||||
|
infos = self._model.create_migration_file(data)
|
||||||
|
except PermissionError:
|
||||||
|
self.message_error('export of excel', 'export_not_sucessful_file_open')
|
||||||
|
except FileExistsError:
|
||||||
|
self.message_error('export of excel', 'export_not_sucessful')
|
||||||
|
else:
|
||||||
|
self.message_info('export of excel', 'export_sucessful', {'path': infos['path']})
|
||||||
|
self._model.call_prep_tool(infos['path'])
|
||||||
|
|
||||||
def aus_halbzeug_neu(self, trueOrfalse):
|
|
||||||
ret = dict()
|
|
||||||
pdm_kat = self.model.get_gui_data("pdm_kategorie_neu")
|
|
||||||
if pdm_kat == "Einzelteil":
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
ret["aus_halbzeug_neu"] = False
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def werkstofftyp(self, selected_werkstoff):
|
|
||||||
"""bekommt Aluminium, Stahl etc. und setzt dann die anderen Felder der Oberfläche"""
|
|
||||||
|
|
||||||
# Logik, die steuert, welcher Defaultwert gilt:
|
def zuruecksetzen(self):
|
||||||
|
cid = self.get_current_item_id()
|
||||||
# In den nachfolgenden Fällen darf kein Defaultwert eingetragen
|
self._model.clear()
|
||||||
# werden (selbst wenn in from_siv.csv ein Wert in der Spalte
|
self._view.clear_rightframes()
|
||||||
# "Werkstoff" eingetragen sein sollte):
|
csv_data = self._model.sivas_data_from_csv(str(cid))
|
||||||
# PDM-Kategorie == "Baugruppe"
|
# transform the csv keys into keys used behind the gui
|
||||||
# PDM-Kategorie == "Schweissbaugruppe"
|
gui_data = self._model.csv2guidata(csv_data)
|
||||||
# PDM-Kategorie == "Einzelteil" und Aus Halbzeug == True (Haken gesetzt)
|
self.set_gui_dict(gui_data)
|
||||||
|
# create dropdown and other defaults
|
||||||
# Gilt PDM-Kategorie == "Kaufteil" soll der Defaultwert "siehe
|
self._model.set_gui_defaults()
|
||||||
# Hersteller" eingetragen werden
|
|
||||||
|
|
||||||
# Gilt PDM-Kategorie == "Einzelteil" und Aus Halbzeug == False (kein
|
|
||||||
# Haken), dann wird der Defaultwert wie folgt bestimmt:
|
|
||||||
ret = dict()
|
|
||||||
# das Feld selbst mit dem Selektierten beschreiben
|
|
||||||
ret['werkstofftyp_neu']= selected_werkstoff
|
|
||||||
|
|
||||||
pdm_kat = self.model.get_gui_data("pdm_kategorie_neu")
|
|
||||||
aus_halbzeug = self.model.get_gui_data("aus_halbzeug_neu")
|
|
||||||
|
|
||||||
if pdm_kat == 'Einzelteil' and aus_halbzeug is False:
|
|
||||||
wnamen = self.config.Werkstoffe.get_werkstoffe_of_name(selected_werkstoff)
|
|
||||||
# setze die Inhalte der abhängigen Comboboxen neu und den Wert im Modell
|
|
||||||
ret = {
|
|
||||||
# das Feld selbst mit dem Selektierten beschreiben
|
|
||||||
'werkstofftyp_neu': selected_werkstoff,
|
|
||||||
# die neuen Inhalte der comboboxen setzen
|
|
||||||
'cb_material_neu': wnamen,
|
|
||||||
# der angezeigte Wert der Combos sollte anfangs dem ersten der Liste entsprechen
|
|
||||||
'material_neu': wnamen[0],
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def oberfläche(self, selected):
|
|
||||||
|
|
||||||
ret = dict()
|
|
||||||
# das Feld selbst mit dem Selektierten beschreiben
|
|
||||||
ret['oberflaeche_neu']= selected
|
|
||||||
|
|
||||||
pdm_kat = self.model.get_gui_data("pdm_kategorie_neu")
|
|
||||||
aus_halbzeug = self.model.get_gui_data("aus_halbzeug_neu")
|
|
||||||
|
|
||||||
if pdm_kat == 'Einzelteil' and aus_halbzeug is False:
|
|
||||||
onamen = self.config.Oberfläche.get_oberfläche_of_type(selected)
|
|
||||||
# setze die Inhalte der abhängigen Comboboxen neu und den Wert im Modell
|
|
||||||
ret = {
|
|
||||||
# die neuen Inhalte der comboboxen setzen
|
|
||||||
'cb_oberflaeche_neu': onamen,
|
|
||||||
# der angezeigte Wert der Combos sollte anfangs dem ersten der Liste entsprechen
|
|
||||||
'oberflaeche_neu': onamen[0],
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def farbe(self, selected):
|
|
||||||
farben_alle = self.config.Farben.get_farbauswahl()
|
|
||||||
farben_elox = self.config.Farben.get_farben_eloxieren()
|
|
||||||
# setze die Inhalte der abhängigen Comboboxen neu und den Wert im Modell
|
|
||||||
ret = {
|
|
||||||
# das Feld selbst mit dem Selektierten beschreiben
|
|
||||||
'farbe_neu': selected,
|
|
||||||
# die neuen Inhalte der comboboxen setzen
|
|
||||||
'cb_farben': farben_alle,
|
|
||||||
# der angezeigte Wert der Combos sollte anfangs dem ersten der Liste entsprechen
|
|
||||||
'farbe_neu': farben_alle[0],
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
def suche_3d(self):
|
||||||
|
pdm_kategorie_neu = self._model.get_gui_data("pdm_kategorie_neu")
|
||||||
|
aus_halbzeug = self._model.get_gui_data("aus_halbzeug_neu")
|
||||||
|
neuaufbau = self._model.get_gui_data("neuaufbau")
|
||||||
|
# Suche Knopf darf nur bei Einzelteilen funktionieren und wenn Halbzeug/NEuaufbau nicht angehakt sind
|
||||||
|
if pdm_kategorie_neu == "Einzelteil" and not (aus_halbzeug == True or neuaufbau == True):
|
||||||
|
newpath = self._view.suche_3d()
|
||||||
|
if newpath:
|
||||||
|
self._model.set_gui_data('model3d_neu', newpath)
|
||||||
|
self._model.set_gui_data('cb_3Dmodel_neu', '')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import argparse
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
"""
|
|
||||||
Dieses Programm:
|
|
||||||
- Holt sich alle notwendigen Einzelteil-Informationen aus SIVAS in Tabellenform
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def get_sivas_teilestamm(sivas_id, out_dir):
|
|
||||||
sivas_id = sivas_id.strip()
|
|
||||||
sivas_teilestamm_exe = os.environ.get('SIVAS_TEILESTAMM')
|
|
||||||
|
|
||||||
if os.path.isfile(sivas_teilestamm_exe):
|
|
||||||
|
|
||||||
if os.path.isdir(out_dir):
|
|
||||||
print(f"Attempting to generate a json-file of all parts to be migrated in relation with '{sivas_id}'")
|
|
||||||
source_path = os.path.join(os.path.expandvars("%USERPROFILE%"), "AppData", "Local", "Temp", "from_siv.csv")
|
|
||||||
to_path = os.path.join(out_dir, sivas_id + ".csv")
|
|
||||||
if os.path.isfile(os.path.join(source_path)):
|
|
||||||
print("file already there. done")
|
|
||||||
exit
|
|
||||||
|
|
||||||
subprocess.run(f"{sivas_teilestamm_exe} userid=sivas password=forte database=sivas program=ExcelUeb LFDNR=500 EINSTIEG=SQL PARAMETER1={sivas_id}")
|
|
||||||
if os.path.isfile(os.path.join(source_path)):
|
|
||||||
shutil.move(source_path, to_path)
|
|
||||||
print("done")
|
|
||||||
else:
|
|
||||||
print(f"Failure - Couldn't generate {sivas_id}.json. Check for any spelling/typing errors. Otherwise given number is a part without a BOM.")
|
|
||||||
exit()
|
|
||||||
else:
|
|
||||||
print(f"'Output directory for .json-file {out_dir}' doesn't exist.")
|
|
||||||
else:
|
|
||||||
print(f"Can't execute SIVAS-database query. Check if you have established a VPN connection to the company's network and check the path of %SIVAS_DATABASE_QUERY% in cremig_setenv.bat")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = argparse.ArgumentParser(description='fetches data from sivas or ruledesigner fusion', prog='update_database')
|
|
||||||
parser.add_argument('-s', '--sivasid', action='store', help='fetch data of this id from sivas fo local database folder', metavar='id')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
out_dir = os.environ.get('CREMIG_DATA')
|
|
||||||
|
|
||||||
if args.sivasid:
|
|
||||||
get_sivas_teilestamm(args.sivasid, out_dir)
|
|
||||||
|
|
||||||
else:
|
|
||||||
parser.print_help()
|
|
||||||
+1159
-516
File diff suppressed because it is too large
Load Diff
+521
-125
@@ -1,21 +1,27 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from configparser import ConfigParser
|
import pymssql
|
||||||
|
from configparser import ConfigParser
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
import update_database
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Diese Lib verwaltet alle Config dateien (als .cfg oder als .json) von CreoMigrate
|
Diese Lib verwaltet alle Config dateien (als .cfg oder als .json) von CreoMigrate
|
||||||
"""
|
"""
|
||||||
class JsonBasedConfig:
|
class JsonBasedConfig:
|
||||||
"""Klasse mit generellen Methoden für alle Config Objekte mit json files"""
|
"""Klasse mit generellen Methoden für alle Config Objekte mit json files"""
|
||||||
def __init__(self, config_dir, config_file):
|
def __init__(self, config_dir: str, config_file: str):
|
||||||
"""merke dir den Pfad zu den Configdateien"""
|
"""merke dir den Pfad zu den Configdateien"""
|
||||||
self.config_path = os.path.join(config_dir, config_file)
|
self._config_dir = config_dir
|
||||||
|
self._config_file = config_file
|
||||||
|
self._config_path = os.path.join(config_dir, config_file)
|
||||||
|
|
||||||
def load_json_from_file(self):
|
def load_json_from_file(self):
|
||||||
"""lade das json file vom gegeben Pfad in ein json Objekt"""
|
"""lade das json file vom gegeben Pfad in ein json Objekt"""
|
||||||
with open(self.config_path, 'r', encoding='utf-8') as fh:
|
with open(self._config_path, 'r', encoding='utf-8') as fh:
|
||||||
return json.loads(fh.read())
|
content = fh.read()
|
||||||
|
return json.loads(content)
|
||||||
|
|
||||||
def from_json(self, json_str):
|
def from_json(self, json_str):
|
||||||
"""nimm den Json String zur Initialisierung des Objektes"""
|
"""nimm den Json String zur Initialisierung des Objektes"""
|
||||||
@@ -24,127 +30,423 @@ class JsonBasedConfig:
|
|||||||
|
|
||||||
class CSVBasedConfig:
|
class CSVBasedConfig:
|
||||||
|
|
||||||
def __init__(self, config_dir, config_file):
|
def __init__(self, config_dir: str, config_file: str):
|
||||||
"""merke dir den Pfad zu den Configdateien"""
|
"""merke dir den Pfad zu den Configdateien"""
|
||||||
self.config_path = os.path.join(config_dir, config_file)
|
self._config_dir = config_dir
|
||||||
|
self._config_file = config_file
|
||||||
|
self._config_path = os.path.join(config_dir, config_file)
|
||||||
|
|
||||||
def load_csv_from_file(self):
|
def load_csv_from_file(self):
|
||||||
"""lade die csv aus dem angegebenen Dateipfad in ein Dataframe"""
|
"""lade die csv aus dem angegebenen Dateipfad in ein Dataframe"""
|
||||||
return pd.read_csv(self.config_path, sep=";", dtype="object")
|
return pd.read_csv(self._config_path, sep=";", dtype="object")
|
||||||
|
|
||||||
|
|
||||||
class SivasAssemblyData(JsonBasedConfig):
|
class SQLBasedConfig:
|
||||||
|
def __init__(self, server, user, pw, dbase):
|
||||||
|
self._server = server
|
||||||
|
self._user = user
|
||||||
|
self._pw = pw
|
||||||
|
self._dbase = dbase
|
||||||
|
|
||||||
|
def query_db(self, sql_statement) -> list:
|
||||||
|
|
||||||
|
"""Führt Datenbankabfrage aus und gibt Daten zurück"""
|
||||||
|
with pymssql.connect(self._server, self._user, self._pw, self._dbase) as conn:
|
||||||
|
with conn.cursor(as_dict=True) as cursor:
|
||||||
|
try:
|
||||||
|
cursor.execute(sql_statement)
|
||||||
|
except pymssql.ProgrammingError:
|
||||||
|
print("SQL-Statement konnte nicht verarbeitet werden!")
|
||||||
|
raise
|
||||||
|
ret = cursor.fetchall()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
class RuleDesignerSQLData(SQLBasedConfig):
|
||||||
|
def __init__(self,
|
||||||
|
server=os.environ.get("RD_SQL_DATABASE_SERVER"),
|
||||||
|
user=os.environ.get("RD_SQL_DATABASE_USER"),
|
||||||
|
pw=os.environ.get("RD_SQL_DATABASE_PW"),
|
||||||
|
dbase=os.environ.get("RD_SQL_DATABASE_NAME")):
|
||||||
|
super().__init__(server, user, pw, dbase)
|
||||||
|
self._rd_statuses = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rd_statuses(self) -> dict:
|
||||||
|
"""Gibt Teilenummer und zugehörigen Status zurück"""
|
||||||
|
|
||||||
|
if self._rd_statuses is None:
|
||||||
|
|
||||||
|
# Datenbankabfrage aller Teilenummern (codCodice) und der zugehörigen Status (codStatus)
|
||||||
|
sql_statement = "SELECT [codCodice] AS ID, [codStatus] AS STATUS FROM [FUSION_PDM].[dbo].[CODICI]"
|
||||||
|
sql_data = self.query_db(sql_statement)
|
||||||
|
|
||||||
|
# Jeder Teilenummer den sprechenden Stsatusnamen, statt der internen Statusnummer zuweisen
|
||||||
|
# Dafür laden der Mapping-Datei für die Statusnummern (z.B. 3 = "FREIGEGEBEN")
|
||||||
|
rd_status_cfg = IniBasedConfig(os.environ.get("CREMIG_CFG"), "RuleDesignerStatusnamen.cfg")
|
||||||
|
rd_status_sections = rd_status_cfg.sections()
|
||||||
|
rd_status_names = rd_status_cfg.get_dict(rd_status_sections[0])
|
||||||
|
|
||||||
|
|
||||||
|
self._rd_statuses = {}
|
||||||
|
for id_status_dict in sql_data:
|
||||||
|
id = id_status_dict["ID"]
|
||||||
|
status = id_status_dict["STATUS"]
|
||||||
|
self._rd_statuses[id] = rd_status_names[str(status)]
|
||||||
|
|
||||||
|
return self._rd_statuses
|
||||||
|
|
||||||
|
|
||||||
|
class SivasBOM(JsonBasedConfig):
|
||||||
"""Auslesen der Assembly-Informationen zu einer angegebenen Baugruppennummer"""
|
"""Auslesen der Assembly-Informationen zu einer angegebenen Baugruppennummer"""
|
||||||
|
|
||||||
def __init__(self, config_dir, config_file):
|
def __init__(self,
|
||||||
|
asm_id,
|
||||||
|
config_dir: str,
|
||||||
|
config_file: str,
|
||||||
|
load_local_json=False,
|
||||||
|
excluded_ids: list=None):
|
||||||
|
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
self.assembly_data = None
|
|
||||||
|
|
||||||
def _lazy_init_assembly_data(func):
|
self.main_id = asm_id
|
||||||
"""Sorgt dafür, dass json-Datei der Baugruppe nur 1x geladen wird"""
|
self._load_local_json = load_local_json
|
||||||
|
self.excluded_ids_by_user = excluded_ids
|
||||||
|
self._excluded_ids_in_bom = None
|
||||||
|
self._bom_data = None
|
||||||
|
self._child_ids = None
|
||||||
|
self._parent_children = None
|
||||||
|
self._longest_child_id = None
|
||||||
|
self._max_bom_depth = None
|
||||||
|
self._all_bom_properties = None
|
||||||
|
|
||||||
def wrapper(self, *args, **kwargs):
|
def create_asm_json(self) -> bool:
|
||||||
if self.assembly_data is None:
|
"""Erstellt JSON mit den aktuellen Baugruppeninformationen"""
|
||||||
self.assembly_data = self.load_json_from_file()
|
|
||||||
return func(self, *args, **kwargs)
|
if not self._load_local_json:
|
||||||
return wrapper
|
update_database.get_sivas_bom(self._config_file.removesuffix(".json"))
|
||||||
|
|
||||||
@_lazy_init_assembly_data
|
|
||||||
def get_assembly_ids(self):
|
@property
|
||||||
|
def bom_data(self) -> dict:
|
||||||
|
""" Liest die JSON-Datei der Baugruppenstückliste ein und speichert die Informationen als dict. """
|
||||||
|
|
||||||
|
if self._bom_data is None:
|
||||||
|
|
||||||
|
"""
|
||||||
|
Falls die JSON nicht existiert oder nicht generiert werden kann, soll die Möglichkeit bestehen,
|
||||||
|
diese eigenständig zu erweitern, da in der JSON z.B. die Nummer der obersten Baugruppe standardmäßig
|
||||||
|
nicht vorliegt. Generierungs- und Einlese-Fehler werden daher bewusst ignoriert, um stattdessen ein leeres
|
||||||
|
dict zurückzugeben, das anschließend erweitert werden kann.
|
||||||
|
|
||||||
|
Die Möglichkeit zur Erweiterung der Stückliste ermöglicht es zudem, Teilenummern ohne Stückliste abzubilden.
|
||||||
|
Das funktioniert, indem man die Teilenummer ohne eigene Stückliste als Kind einer fiktiven Baugruppe "None"
|
||||||
|
ansieht / definiert. Dadurch ist keine separate Logik erforderlich, die sich nur mit Teilenummern
|
||||||
|
ohne Stückliste befasst.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._bom_data = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.create_asm_json()
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._bom_data = self.load_json_from_file()
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if self.excluded_ids_by_user is not None:
|
||||||
|
self._remove_excluded_ids_from_bom()
|
||||||
|
|
||||||
|
return self._bom_data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def child_ids(self) -> set:
|
||||||
"""Gibt alle Teilenummern der Stückliste zurück (auch Teilenummern aus tieferen Baugruppenebenen)"""
|
"""Gibt alle Teilenummern der Stückliste zurück (auch Teilenummern aus tieferen Baugruppenebenen)"""
|
||||||
|
|
||||||
assembly_ids = set()
|
if self._child_ids is None:
|
||||||
for child_id, parent_properties in self.assembly_data.items():
|
self._child_ids = set(self.bom_data.keys())
|
||||||
assembly_ids.add(child_id)
|
return self._child_ids
|
||||||
for parent_property in parent_properties:
|
|
||||||
parent_id = parent_property["Parent"]
|
|
||||||
assembly_ids.add(parent_id)
|
|
||||||
return assembly_ids
|
|
||||||
|
|
||||||
@_lazy_init_assembly_data
|
@property
|
||||||
def get_parent_children(self) -> dict:
|
def parent_children(self) -> dict:
|
||||||
"""Ordnet Stücklistenpositionen (Kinder) den Baugruppennummern (Eltern) zu. Die Kinder sind entsprechend ihrer Positionsnummern in den Stücklisten sortiert."""
|
"""Ordnet Stücklistenpositionen (Kinder) den Baugruppennummern (Eltern) zu. Die Kinder sind entsprechend ihrer Positionsnummern in den Stücklisten sortiert."""
|
||||||
|
|
||||||
unordered_parent_children = {}
|
if self._parent_children is None:
|
||||||
|
unordered_parent_children = {}
|
||||||
|
|
||||||
for child_id, parent_properties in self.assembly_data.items():
|
for child_id, parent_properties in self.bom_data.items():
|
||||||
for parent_property in parent_properties:
|
for parent_property in parent_properties:
|
||||||
parent_id = parent_property["Parent"]
|
parent_id = parent_property["Parent"]
|
||||||
child_posnr_in_parent_bom = int(parent_property["Position"].lstrip(".").split("/")[0])
|
child_posnr_in_parent_bom = int(parent_property["Position"].lstrip(".").split("/")[0])
|
||||||
|
|
||||||
if parent_id not in unordered_parent_children:
|
if parent_id not in unordered_parent_children:
|
||||||
unordered_parent_children[parent_id] = {}
|
unordered_parent_children[parent_id] = {}
|
||||||
|
|
||||||
unordered_parent_children[parent_id][child_posnr_in_parent_bom] = child_id
|
unordered_parent_children[parent_id][child_posnr_in_parent_bom] = child_id
|
||||||
|
|
||||||
|
ordered_parent_children = {}
|
||||||
|
for parent, children in unordered_parent_children.items():
|
||||||
|
for pos_nr, child in sorted(children.items()):
|
||||||
|
if parent not in ordered_parent_children:
|
||||||
|
ordered_parent_children[parent] = []
|
||||||
|
ordered_parent_children[parent].append(child)
|
||||||
|
self._parent_children = ordered_parent_children
|
||||||
|
return self._parent_children
|
||||||
|
|
||||||
|
def extend_asm_bom(self, id, metadata:dict) -> dict:
|
||||||
|
"""Ergänzt die Stückliste um eine weitere Teilenummer unter Berücksichtigung des vorgegebenen Formats der ausgegebenen JSON
|
||||||
|
des Programms 'Sivas2Json' von Hr. Jakob
|
||||||
|
Aktuell ist die JSON wie folgt aufgebaut:
|
||||||
|
{
|
||||||
|
"Stücklistenposition 1": [{Metadaten aus 1. SIVAS-Stammstückliste, in der die Stücklistenposition verbaut ist},
|
||||||
|
{Metadaten aus 2. SIVAS-Stammstückliste, in der die Stücklistenposition verbaut ist (falls die oberste Baugruppe weitere Unterbaugruppen enthält, in denen diese Nummer ebenfalls verbaut ist)},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"Stücklistenposition 2": [{...},
|
||||||
|
{...}
|
||||||
|
]
|
||||||
|
}"""
|
||||||
|
|
||||||
|
if id not in self.bom_data:
|
||||||
|
self._bom_data[id] = []
|
||||||
|
|
||||||
ordered_parent_children = {}
|
self._bom_data[id].append(metadata)
|
||||||
for parent, children in unordered_parent_children.items():
|
return self._bom_data
|
||||||
for pos_nr, child in sorted(children.items()):
|
|
||||||
if parent not in ordered_parent_children:
|
|
||||||
ordered_parent_children[parent] = []
|
|
||||||
ordered_parent_children[parent].append(child)
|
|
||||||
return ordered_parent_children
|
|
||||||
|
|
||||||
def get_longest_assembly_id(self) -> str:
|
def _remove_excluded_ids_from_bom(self) -> None:
|
||||||
|
"""Entfernt ID's aus den Stücklistendaten, die nicht enthalten sein sollen"""
|
||||||
|
|
||||||
|
# Ausgeschlossene Teilenummern, die vom User angegeben wurden, können nicht einfach aus der Stückliste entfernt werden.
|
||||||
|
# Sie müssen zunächst aufbereiten werden, denn:
|
||||||
|
# - Ausgeschlossene Nummern, die kein Bestandteil der aktuellen Baugruppe sind, sind nicht von Interesse
|
||||||
|
# - Kinder von ausgeschlossenen Teilenummern, die vom User nicht angegeben wurden sind ggf. von Interesse, müssen aber zunächst
|
||||||
|
# ermittelt werden
|
||||||
|
|
||||||
|
ids_to_remove = self.excluded_ids_in_bom
|
||||||
|
|
||||||
|
if not ids_to_remove:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.main_id in ids_to_remove:
|
||||||
|
raise ValueError(f"Haupt-Teilenummer '{self.main_id}' darf nicht ausgeschlossen sein. Bitte $CREMIG_CFG/BOM-Settings.cfg -> Sektion 'ExcludedPartnumbersInBOM' prüfen, falls diese Datei zur Definition der ausgeschlossenen Teilenummern verwendet wurde")
|
||||||
|
|
||||||
|
filtered_bom_data = {}
|
||||||
|
for id, usages in self.bom_data.items():
|
||||||
|
|
||||||
|
if id in ids_to_remove:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for properties in usages:
|
||||||
|
|
||||||
|
if properties["Parent"] in ids_to_remove:
|
||||||
|
continue
|
||||||
|
if id not in filtered_bom_data:
|
||||||
|
filtered_bom_data[id] = []
|
||||||
|
|
||||||
|
filtered_bom_data[id].append(properties)
|
||||||
|
|
||||||
|
self._bom_data = filtered_bom_data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def excluded_ids_in_bom(self) -> list:
|
||||||
|
|
||||||
|
""" Gibt alle Teilenummern zurück, die in der SIVAS-Stückliste vorliegen, aber davon ausgeschlossen sein sollen. """
|
||||||
|
|
||||||
|
if self._excluded_ids_in_bom is None:
|
||||||
|
|
||||||
|
excluded_ids_by_user = self.excluded_ids_by_user
|
||||||
|
|
||||||
|
to_remove = {}
|
||||||
|
for id, usages in self.bom_data.items():
|
||||||
|
|
||||||
|
# Teilenummern zunächst als ausgeschlossen anzusehen und das später zu widerrufen erleichtert die Definition der Logik
|
||||||
|
to_remove[id] = True
|
||||||
|
|
||||||
|
# Teilenummern, die vom User ausgeschlossen wurden, aber kein Bestandteil dieser Baugruppe sind, interessieren uns nicht!
|
||||||
|
if id in excluded_ids_by_user:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Kinder von ausgeschlossenen Teilenummern werden ebenfalls als ausgeschlossen betrachtet, außer sie sind Kinder von
|
||||||
|
# weiteren Teilenummern, die nicht augeschlossen sein sollen
|
||||||
|
# Hinweis:
|
||||||
|
# Für die Prüfung, ob das Kind in weiteren Teilenummern verbaut ist, würde sich die Methode "parent_children" anbieten.
|
||||||
|
# Die ist aber Lazy, sprich, wenn wir die jetzt aufrufen, arbeitet sie mit den Stücklistendaten, vor dem die Teilenummern
|
||||||
|
# entfernt wurden. Die Laziness dafür zu entfernen macht aber auch keinen Sinn, weil diese Methode bei der Erstellung von
|
||||||
|
# baumförmigen Migrationsübersichten ständig aufgerufen wird, d.h. die Performance würde darunter stark leiden!
|
||||||
|
|
||||||
|
for properties in usages:
|
||||||
|
if properties["Parent"] not in excluded_ids_by_user:
|
||||||
|
to_remove[id] = False
|
||||||
|
|
||||||
|
self._excluded_ids_in_bom = list(filter(lambda id: to_remove[id] is True, to_remove))
|
||||||
|
return self._excluded_ids_in_bom
|
||||||
|
|
||||||
|
@property
|
||||||
|
def longest_child_id(self) -> str:
|
||||||
"""Gibt die längste Teilenummer von allen Stücklistenpositionen zurück"""
|
"""Gibt die längste Teilenummer von allen Stücklistenpositionen zurück"""
|
||||||
|
|
||||||
return max(self.get_assembly_ids())
|
if self._longest_child_id is None:
|
||||||
|
self._longest_child_id = max(self.child_ids)
|
||||||
|
return self._longest_child_id
|
||||||
|
|
||||||
@_lazy_init_assembly_data
|
@property
|
||||||
def get_max_bom_depth(self) -> int:
|
def max_bom_depth(self) -> int:
|
||||||
"""Gibt die tiefste Stücklistenebene zurück (0 = höchste Ebene)"""
|
"""Gibt die tiefste Stücklistenebene zurück (0 = höchste Ebene)"""
|
||||||
|
|
||||||
bom_levels = []
|
if self._max_bom_depth is None:
|
||||||
for parents in self.assembly_data.values():
|
bom_levels = []
|
||||||
for parent in parents:
|
for parents in self.bom_data.values():
|
||||||
current_bom_level = parent["Position"].count(".")
|
for parent in parents:
|
||||||
bom_levels.append(current_bom_level)
|
current_bom_level = parent["Position"].count(".")
|
||||||
return max(bom_levels)
|
bom_levels.append(current_bom_level)
|
||||||
|
self._max_bom_depth = max(bom_levels)
|
||||||
|
return self._max_bom_depth
|
||||||
|
|
||||||
@_lazy_init_assembly_data
|
def get_prop_val_for_single_id(self, id:str, property_name:str) -> str:
|
||||||
def get_property_names(self) -> list:
|
"""Gibt eine Eigenschaft von einer einzelnen Teilenummer aus der Stückliste zurück"""
|
||||||
"""Gibt alle Eigenschaftsnamen zurück, die in der Assembly-json-Datei enthalten sind"""
|
|
||||||
|
|
||||||
for parent_data in self.assembly_data.values():
|
if id not in self.bom_data:
|
||||||
return list(parent_data[0])
|
raise ValueError("Teilenummer befindet sich nicht in der Baugruppe!")
|
||||||
|
|
||||||
@_lazy_init_assembly_data
|
|
||||||
def get_property(self, property) -> dict:
|
|
||||||
"""Gibt eine Eigenschaft zu den Teilenummern der Stückliste zurück (z.B. Bezeichnung)"""
|
|
||||||
|
|
||||||
if property not in self.get_property_names():
|
if property_name not in self.bom_data[id][0]:
|
||||||
raise ValueError("Angegebener Eigenschaftsname exisitert nicht!")
|
return
|
||||||
|
|
||||||
|
return self.bom_data[id][0][property_name]
|
||||||
|
|
||||||
|
def get_prop_val_for_all_ids(self, property_name) -> dict:
|
||||||
|
"""Gibt eine Eigenschaft zu allen Teilenummern der Stückliste zurück (z.B. Bezeichnung)"""
|
||||||
|
|
||||||
id_property_mapping = {}
|
id_property_mapping = {}
|
||||||
for child, parent_data in self.assembly_data.items():
|
for child_id, asm_usages in self.bom_data.items():
|
||||||
for properties in parent_data:
|
child_properties = asm_usages[0]
|
||||||
id_property_mapping[child] = properties[property]
|
id_property_mapping[child_id] = None if property_name not in child_properties else child_properties[property_name]
|
||||||
|
|
||||||
return id_property_mapping
|
return id_property_mapping
|
||||||
|
|
||||||
|
@property
|
||||||
|
def all_bom_properties(self) -> dict:
|
||||||
|
"""Gibt alle Eigenschaften zu den Teilenummern der Stückliste zurück (z.B. Bezeichnung)"""
|
||||||
|
|
||||||
|
if self._all_bom_properties is None:
|
||||||
|
|
||||||
|
self._all_bom_properties = {}
|
||||||
|
|
||||||
|
for child_id, asm_usages in self.bom_data.items():
|
||||||
|
child_properties = asm_usages[0]
|
||||||
|
for property_name, property_val in child_properties.items():
|
||||||
|
if property_name not in self._all_bom_properties:
|
||||||
|
self._all_bom_properties[property_name] = {}
|
||||||
|
self._all_bom_properties[property_name][child_id] = property_val
|
||||||
|
|
||||||
|
return self._all_bom_properties
|
||||||
|
|
||||||
|
|
||||||
class RuleDesignerDatabaseConfig(CSVBasedConfig):
|
class RuleDesignerDatabaseConfig(CSVBasedConfig):
|
||||||
"""Auslesen der Angaben aus der RuleDesigner-Datenbank-CSV"""
|
"""Auslesen der CSV-Datei, in der alle RuleDesigner-Teilenummern aufgelistet sind"""
|
||||||
def __init__(self, config_dir=".", config_file="RD_Teilenummern.csv"):
|
def __init__(self, config_dir=".", config_file="RD_Teilenummern.csv", load_local_csv=False):
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
|
self._load_local_csv = load_local_csv
|
||||||
|
self._ids = None
|
||||||
|
|
||||||
def get_ruledesigner_ids(self):
|
def copy_csv_from_server(self):
|
||||||
return tuple(self.load_csv_from_file()['Teilenummern'])
|
"""Kopiert CSV-Datei vom Server, in der alle Teilenummern, die sich in RuleDesigner befinden"""
|
||||||
|
try:
|
||||||
|
update_database.get_ruledesigner_ids()
|
||||||
|
except:
|
||||||
|
raise ValueError("CSV mit RuleDesigner-Teilenummern konnte nicht ins lokale Verzeichnis kopiert werden!")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ids(self):
|
||||||
|
if self._ids is None:
|
||||||
|
|
||||||
|
if not self._load_local_csv:
|
||||||
|
self.copy_csv_from_server()
|
||||||
|
|
||||||
|
self._ids = tuple(self.load_csv_from_file()['Teilenummern'])
|
||||||
|
return self._ids
|
||||||
|
|
||||||
|
|
||||||
class MigrationStatus:
|
class MigrationStatus:
|
||||||
def __init__(self, file_dir, assembly_json):
|
"""Klasse gibt Informationen zum aktuellen Migrationsstand zurück, indem geprüft wird, ob die Nummern aus Sivas, auch in RuleDesigner vorliegen"""
|
||||||
self.sivas_assembly_data = SivasAssemblyData(file_dir, assembly_json)
|
def __init__(self, asm_child_ids: tuple, rd_ids: tuple):
|
||||||
self.ruledesigner_data = RuleDesignerDatabaseConfig(file_dir)
|
self.asm_child_ids = asm_child_ids
|
||||||
|
self.rd_ids = rd_ids
|
||||||
def get_migration_status(self):
|
self._rd_statuses = None
|
||||||
"""Gibt zurück, ob die Teilenummern der Baugruppe bereits migriert wurden, oder nicht"""
|
self._overview = None
|
||||||
sivas_assembly_ids = self.sivas_assembly_data.get_assembly_ids()
|
self._ids_in_rd = None
|
||||||
ruledesigner_ids = self.ruledesigner_data.get_ruledesigner_ids()
|
self._ids_in_progress = None
|
||||||
|
self._ids_pending = None
|
||||||
|
|
||||||
migration_status = {}
|
@property
|
||||||
for sivas_assembly_id in sivas_assembly_ids:
|
def id_status(self) -> dict:
|
||||||
migration_status[sivas_assembly_id] = True if sivas_assembly_id in ruledesigner_ids else False
|
"""Gibt zurück, ob die Stücklistenpositionen der Baugruppe migriert sind, oder nicht"""
|
||||||
return migration_status
|
if self._overview is None:
|
||||||
|
self._overview = {}
|
||||||
|
for child_id in self.asm_child_ids:
|
||||||
|
self._overview[child_id] = True if child_id in self.rd_ids else False
|
||||||
|
return self._overview
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ids_in_rd(self) -> list:
|
||||||
|
"""Gibt alle Stücklistenpositionen zurück, die migriert sind"""
|
||||||
|
|
||||||
|
if self._ids_in_rd is None:
|
||||||
|
self._ids_in_rd = [id for id, status in self.id_status.items() if status is True]
|
||||||
|
return self._ids_in_rd
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ids_in_progress(self) -> list:
|
||||||
|
"""Gibt migrierte Stücklistenpositionen zurück, die aktuell eine Freigabe der Baugruppe verhindern, da sie sich in Arbeit befinden"""
|
||||||
|
|
||||||
|
|
||||||
|
if self._ids_in_progress is None:
|
||||||
|
|
||||||
|
rd_sql_data = RuleDesignerSQLData()
|
||||||
|
rd_statuses = rd_sql_data.rd_statuses
|
||||||
|
|
||||||
|
self._ids_in_progress = []
|
||||||
|
for id in self.ids_in_rd:
|
||||||
|
if rd_statuses[id] != "FREIGEGEBEN":
|
||||||
|
self._ids_in_progress.append(id)
|
||||||
|
return self._ids_in_progress
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ids_pending(self) -> list:
|
||||||
|
"""Gibt alle Stücklistenpositionen zurück, die noch nicht migriert sind"""
|
||||||
|
|
||||||
|
if self._ids_pending is None:
|
||||||
|
self._ids_pending = [id for id, status in self.id_status.items() if status is False]
|
||||||
|
return self._ids_pending
|
||||||
|
|
||||||
|
|
||||||
|
class SivasTeilestamm(CSVBasedConfig):
|
||||||
|
def __init__(self, config_dir, config_file, load_local_csv=False):
|
||||||
|
super().__init__(config_dir, config_file)
|
||||||
|
self._load_local_csv = load_local_csv
|
||||||
|
self._data = None
|
||||||
|
|
||||||
|
def create_csvs(self, ids):
|
||||||
|
"""Erstellt CSV-Datei(en) mit den Teilestamminformationen zu der / den angegebenen Teilenummer(n)"""
|
||||||
|
|
||||||
|
if not self._load_local_csv:
|
||||||
|
update_database.get_sivas_teilestamm(ids)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def teilestamm_data(self):
|
||||||
|
"""Gibt CSV-Daten als Dataframe zurück"""
|
||||||
|
|
||||||
|
if self._data is None:
|
||||||
|
self.create_csvs(self._config_file.removesuffix(".csv"))
|
||||||
|
self._data = self.load_csv_from_file()
|
||||||
|
|
||||||
|
return self._data
|
||||||
|
|
||||||
|
def get_property_values(self, property_name) -> str:
|
||||||
|
"""Gibt Wert aus der CSV für den angegebenen Spaltennamen zurück"""
|
||||||
|
ret = self.teilestamm_data[property_name][0]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class TOSGroupsConfig(JsonBasedConfig):
|
class TOSGroupsConfig(JsonBasedConfig):
|
||||||
@@ -169,6 +471,25 @@ class TOSGroupsConfig(JsonBasedConfig):
|
|||||||
for cId in childIds:
|
for cId in childIds:
|
||||||
self.get_children_keys(tos_hierarchy, cId, result)
|
self.get_children_keys(tos_hierarchy, cId, result)
|
||||||
|
|
||||||
|
def get_Id2TosGroup(self):
|
||||||
|
"hole alle ids zur jeweiligen Gruppe"
|
||||||
|
# lazy. nur einmal laden, wenn noch nicht geschehen
|
||||||
|
if not self.tos_hierarchy:
|
||||||
|
self.tos_hierarchy = super().load_json_from_file()
|
||||||
|
tos_hierarchy = self.tos_hierarchy
|
||||||
|
|
||||||
|
num2refId = dict()
|
||||||
|
num2child = dict()
|
||||||
|
allkwds = self.get_all_keywords()
|
||||||
|
for kw in allkwds.keys():
|
||||||
|
refids = tos_hierarchy[kw]["reference-ids"]
|
||||||
|
for cId in refids.keys():
|
||||||
|
num2refId[cId] = refids[cId]
|
||||||
|
children = tos_hierarchy[kw]["children"]
|
||||||
|
for cId in children.keys():
|
||||||
|
num2child[cId] = children[cId]
|
||||||
|
return (num2refId, num2child)
|
||||||
|
|
||||||
def get_all_keywords(self):
|
def get_all_keywords(self):
|
||||||
"""hole alle TOS Keywords, welche in der config Datei definiert sind"""
|
"""hole alle TOS Keywords, welche in der config Datei definiert sind"""
|
||||||
|
|
||||||
@@ -201,29 +522,29 @@ class MaterialTransConfig(JsonBasedConfig):
|
|||||||
"""Auslesen der Config zu allen Materialangaben"""
|
"""Auslesen der Config zu allen Materialangaben"""
|
||||||
|
|
||||||
def __init__(self, config_dir='.', config_file='Materialübersetzung.json'):
|
def __init__(self, config_dir='.', config_file='Materialübersetzung.json'):
|
||||||
self.materials = None
|
self._materials = None
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
def from_json(self, json_str):
|
def from_json(self, json_str):
|
||||||
"""lade den Json String zur Initialisierung des Objektes"""
|
"""lade den Json String zur Initialisierung des Objektes"""
|
||||||
self.materials = super().from_json(json_str)
|
self._materials = super().from_json(json_str)
|
||||||
|
|
||||||
def get_all_materials(self):
|
def get_all_materials(self):
|
||||||
"""hole alle Materialien, welche in der config Datei definiert sind"""
|
"""hole alle Materialien, welche in der config Datei definiert sind"""
|
||||||
|
|
||||||
if not self.materials:
|
if not self._materials:
|
||||||
self.materials = super().load_json_from_file()
|
self._materials = super().load_json_from_file()
|
||||||
ret = list()
|
ret = list()
|
||||||
for k in self.materials.keys():
|
for k in self._materials.keys():
|
||||||
ret.append(k)
|
ret.append(k)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_material_of_type(self, mat):
|
def get_material_of_type(self, mat):
|
||||||
"""hole alle Materialien, welche in der config Datei definiert sind"""
|
"""hole alle Materialien, welche zu diesem Werkstofftyp existieren"""
|
||||||
if not self.materials:
|
if not self._materials:
|
||||||
self.load_materials()
|
self.load_materials()
|
||||||
return self.materials[mat]
|
return self._materials[mat]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IniBasedConfig:
|
class IniBasedConfig:
|
||||||
@@ -233,39 +554,44 @@ class IniBasedConfig:
|
|||||||
self.config_path = os.path.join(config_dir, config_file)
|
self.config_path = os.path.join(config_dir, config_file)
|
||||||
if not os.path.exists(self.config_path):
|
if not os.path.exists(self.config_path):
|
||||||
raise Exception("path does not exist")
|
raise Exception("path does not exist")
|
||||||
self.isInitalized = False
|
self._isInitalized = False
|
||||||
self.config = ConfigParser(allow_no_value=True)
|
self._config = ConfigParser(allow_no_value=True, delimiters=("="))
|
||||||
self.config.optionxform = lambda option: option # preserve case for letters
|
self._config.optionxform = lambda option: option # preserve case for letters
|
||||||
|
|
||||||
def from_cfg_str(self, cfg_str):
|
def from_cfg_str(self, cfg_str):
|
||||||
"""nimm den config String zur Initialisierung des Objektes"""
|
"""nimm den config String zur Initialisierung des Objektes"""
|
||||||
self.config.read_string(cfg_str)
|
self._config.read_string(cfg_str)
|
||||||
self.isInitalized = True
|
self._isInitalized = True
|
||||||
|
|
||||||
def load_cfg_from_file(self):
|
def load_cfg_from_file(self):
|
||||||
"""lade das config file vom gegeben Pfad"""
|
"""lade das config file vom gegeben Pfad"""
|
||||||
self.config.read(self.config_path, encoding='utf-8')
|
self._config.read(self.config_path, encoding='utf-8')
|
||||||
self.isInitalized = True
|
self._isInitalized = True
|
||||||
|
|
||||||
def get_section_options(self, section_name):
|
def get_section_options(self, section_name):
|
||||||
if not self.isInitalized:
|
if not self._isInitalized:
|
||||||
self.load_cfg_from_file()
|
self.load_cfg_from_file()
|
||||||
return self.config.options(section_name)
|
return self._config.options(section_name)
|
||||||
|
|
||||||
def sections(self):
|
def sections(self):
|
||||||
if not self.isInitalized:
|
if not self._isInitalized:
|
||||||
self.load_cfg_from_file()
|
self.load_cfg_from_file()
|
||||||
return self.config.sections()
|
return self._config.sections()
|
||||||
|
|
||||||
def get_int(self, section_name, option):
|
def get(self, section_name, option):
|
||||||
if not self.isInitalized:
|
if not self._isInitalized:
|
||||||
self.load_cfg_from_file()
|
self.load_cfg_from_file()
|
||||||
return self.config.getint(section_name, option)
|
return self._config.get(section_name, option)
|
||||||
|
|
||||||
|
def get_int(self, section_name, option):
|
||||||
|
if not self._isInitalized:
|
||||||
|
self.load_cfg_from_file()
|
||||||
|
return self._config.getint(section_name, option)
|
||||||
|
|
||||||
def get_dict(self, section_name):
|
def get_dict(self, section_name):
|
||||||
if not self.isInitalized:
|
if not self._isInitalized:
|
||||||
self.load_cfg_from_file()
|
self.load_cfg_from_file()
|
||||||
return dict(self.config.items(section_name))
|
return dict(self._config.items(section_name))
|
||||||
|
|
||||||
class AllgemeinConfig(IniBasedConfig):
|
class AllgemeinConfig(IniBasedConfig):
|
||||||
"""Auslesen der Config für alle allgemeinen Angaben"""
|
"""Auslesen der Config für alle allgemeinen Angaben"""
|
||||||
@@ -287,7 +613,7 @@ class BezeichnerConfig(IniBasedConfig):
|
|||||||
def __init__(self, config_dir='.', config_file='Bezeichner.cfg'):
|
def __init__(self, config_dir='.', config_file='Bezeichner.cfg'):
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
def get(self):
|
def get_all(self):
|
||||||
"""hole alle möglichen Bezeichner """
|
"""hole alle möglichen Bezeichner """
|
||||||
return super().get_section_options("Bezeichner")
|
return super().get_section_options("Bezeichner")
|
||||||
|
|
||||||
@@ -320,19 +646,19 @@ class FertigungsartConfig(IniBasedConfig):
|
|||||||
"""
|
"""
|
||||||
return super().sections()
|
return super().sections()
|
||||||
|
|
||||||
def get_normen_of_type(self, ftype):
|
def get_list_in_section(self, section):
|
||||||
"""hole alle möglichen Oberflächen Behandlungsarten zum gegebenen Material
|
"""hole alle möglichen Oberflächen Behandlungsarten zum gegebenen Material
|
||||||
Allgemeintoleranz3DDruck ftype
|
Allgemeintoleranz3DDruck ftype
|
||||||
-> [ISO 2768:1991-fH, ISO 2768:1991-fK, ISO 2768:1991-fL, ISO 2768:1991-mH, , ...]
|
-> [ISO 2768:1991-fH, ISO 2768:1991-fK, ISO 2768:1991-fL, ISO 2768:1991-mH, , ...]
|
||||||
"""
|
"""
|
||||||
return super().get_section_options(ftype)
|
return super().get_section_options(section)
|
||||||
|
|
||||||
class HerstellerConfig(IniBasedConfig):
|
class HerstellerConfig(IniBasedConfig):
|
||||||
"""Auslesen der Config zu allen möglichen Hersteller"""
|
"""Auslesen der Config zu allen möglichen Hersteller"""
|
||||||
def __init__(self, config_dir='.', config_file='Hersteller.cfg'):
|
def __init__(self, config_dir='.', config_file='Hersteller.cfg'):
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
def get(self):
|
def get_all(self):
|
||||||
"""hole alle möglichen Bezeichner """
|
"""hole alle möglichen Bezeichner """
|
||||||
return super().get_section_options("Hersteller")
|
return super().get_section_options("Hersteller")
|
||||||
|
|
||||||
@@ -364,6 +690,10 @@ class OberflächeConfig(IniBasedConfig):
|
|||||||
"""hole alle Oberflächen, welche als Sektionen in der config gegeben
|
"""hole alle Oberflächen, welche als Sektionen in der config gegeben
|
||||||
sind, also OberflächenbehandlungStahl, OberflächenbehandlungAluminium, ... """
|
sind, also OberflächenbehandlungStahl, OberflächenbehandlungAluminium, ... """
|
||||||
return super().sections()
|
return super().sections()
|
||||||
|
|
||||||
|
def get_oberflächen_behandlungen(self):
|
||||||
|
"""hole alle möglichen Arten von Oberflächenbehandlungen"""
|
||||||
|
return super().get_section_options('Oberflaechenbehandlungen')
|
||||||
|
|
||||||
def get_oberfläche_of_type(self, otype):
|
def get_oberfläche_of_type(self, otype):
|
||||||
"""hole alle möglichen Oberflächen Behandlungsarten zum gegebenen Material
|
"""hole alle möglichen Oberflächen Behandlungsarten zum gegebenen Material
|
||||||
@@ -385,6 +715,13 @@ class WerkstoffeConfig(IniBasedConfig):
|
|||||||
"""
|
"""
|
||||||
return super().get_section_options('Werkstofftyp')
|
return super().get_section_options('Werkstofftyp')
|
||||||
|
|
||||||
|
def get_all(self):
|
||||||
|
ret = list()
|
||||||
|
l = self.get_werkstoff_namen()
|
||||||
|
for item in l:
|
||||||
|
ltemp = self.get_werkstoffe_of_name(l)
|
||||||
|
ret.append(ltemp)
|
||||||
|
return ret
|
||||||
|
|
||||||
def get_werkstoffe_of_name(self, wName):
|
def get_werkstoffe_of_name(self, wName):
|
||||||
"""hole alle Werkstoffe unter der gegebenen Sektion
|
"""hole alle Werkstoffe unter der gegebenen Sektion
|
||||||
@@ -399,15 +736,59 @@ class PfadConfig(IniBasedConfig):
|
|||||||
def __init__(self, config_dir='.', config_file='Zielpfade.cfg'):
|
def __init__(self, config_dir='.', config_file='Zielpfade.cfg'):
|
||||||
super().__init__(config_dir, config_file)
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
def get(self):
|
class ZusatzConfig(IniBasedConfig):
|
||||||
"""hole alle möglichen Bezeichner """
|
"""Auslesen der Zusatzinformationen die aus dem Änderungsindex abgeleitet werden"""
|
||||||
return super().get_section_options("Zielpfade")
|
def __init__(self, config_dir='.', config_file='Zusatzinformationen.cfg'):
|
||||||
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
|
class InvaldCharsConfig():
|
||||||
|
"""Auslesen der Zusatzinformationen die aus dem Änderungsindex abgeleitet werden"""
|
||||||
|
def __init__(self, config_dir='.', config_file='InvalidCharacters.txt'):
|
||||||
|
self.config_path = os.path.join(config_dir, config_file)
|
||||||
|
if not os.path.exists(self.config_path):
|
||||||
|
raise Exception("path does not exist")
|
||||||
|
self._isInitalized = False
|
||||||
|
file = open(self.config_path,'r')
|
||||||
|
line = file.read()
|
||||||
|
line = line.rstrip()
|
||||||
|
self._characters = line.split(',')
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self._characters
|
||||||
|
|
||||||
|
class GuiConfig(IniBasedConfig):
|
||||||
|
"""Auslesen der Zusatzinformationen die aus dem Änderungsindex abgeleitet werden"""
|
||||||
|
def __init__(self, config_dir='.', config_file='gui.cfg'):
|
||||||
|
username = os.environ.get("USERNAME")
|
||||||
|
spezific_file = 'gui-' + username + '.cfg'
|
||||||
|
spezific_path = os.path.join(config_dir,spezific_file)
|
||||||
|
if os.path.exists(spezific_path):
|
||||||
|
config_file=spezific_file
|
||||||
|
super().__init__(config_dir, config_file=config_file)
|
||||||
|
|
||||||
|
class BOMConfig(IniBasedConfig):
|
||||||
|
def __init__(self, config_dir=os.environ.get("CREMIG_CFG"), config_file="BOM-Settings.cfg"):
|
||||||
|
self._config_dir = config_dir
|
||||||
|
self.config_file = config_file
|
||||||
|
super().__init__(config_dir, config_file)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def config_dir(self):
|
||||||
|
return self._config_dir
|
||||||
|
|
||||||
|
@config_dir.setter
|
||||||
|
def config_dir(self, directory):
|
||||||
|
if not os.path.isdir(directory):
|
||||||
|
raise ValueError("Verzeichnis existiert nicht!")
|
||||||
|
self._config_dir = directory
|
||||||
|
|
||||||
|
def get_excluded_ids(self, section_name:str="ExcludedPartnumbersInBOM") -> tuple:
|
||||||
|
return tuple(self.get_section_options(section_name))
|
||||||
|
|
||||||
class Configs:
|
class Configs:
|
||||||
"""Sammlung aller Configdateien """
|
"""Sammlung aller Configdateien """
|
||||||
def __init__(self, cfg_dir):
|
def __init__(self, cfg_dir):
|
||||||
self.cfg_dir = cfg_dir
|
self._cfg_dir = cfg_dir
|
||||||
self.Allgemein = AllgemeinConfig(cfg_dir)
|
self.Allgemein = AllgemeinConfig(cfg_dir)
|
||||||
self.Bezeichner = BezeichnerConfig(cfg_dir)
|
self.Bezeichner = BezeichnerConfig(cfg_dir)
|
||||||
self.Farben = FarbenConfig(cfg_dir)
|
self.Farben = FarbenConfig(cfg_dir)
|
||||||
@@ -417,19 +798,34 @@ class Configs:
|
|||||||
self.Oberfläche = OberflächeConfig(cfg_dir)
|
self.Oberfläche = OberflächeConfig(cfg_dir)
|
||||||
self.Pfade = PfadConfig(cfg_dir)
|
self.Pfade = PfadConfig(cfg_dir)
|
||||||
self.Werkstoffe = WerkstoffeConfig(cfg_dir)
|
self.Werkstoffe = WerkstoffeConfig(cfg_dir)
|
||||||
|
self.Zusatz = ZusatzConfig(cfg_dir)
|
||||||
|
self.InvalidChars = InvaldCharsConfig(cfg_dir)
|
||||||
|
self.Gui = GuiConfig(cfg_dir)
|
||||||
|
|
||||||
self.TOSGruppen = TOSGroupsConfig(cfg_dir)
|
self.TOSGruppen = TOSGroupsConfig(cfg_dir)
|
||||||
self.Materialien = MaterialTransConfig(cfg_dir)
|
self.Materialien = MaterialTransConfig(cfg_dir)
|
||||||
self.env = None
|
self.bom_config = BOMConfig(cfg_dir)
|
||||||
|
self._teilenummern = None
|
||||||
|
|
||||||
def get_cfg_path(self):
|
def get_cfg_path(self):
|
||||||
return self.cfg_dir
|
return self._cfg_dir
|
||||||
|
|
||||||
def set_env(self, env):
|
def set_data_dir(self, data_dir):
|
||||||
self.env = env
|
self._data_dir = data_dir
|
||||||
|
def get_data_dir(self):
|
||||||
|
return self._data_dir
|
||||||
|
|
||||||
def get_env(self):
|
def get_ruledesigner_ids(self):
|
||||||
if self.env:
|
if not self._data_dir:
|
||||||
return self.env
|
raise Exception("set_data_dir not called. path not set")
|
||||||
return None
|
if not self._teilenummern:
|
||||||
|
self._teilenummern = RuleDesignerDatabaseConfig(self._data_dir, load_local_csv=True).ids
|
||||||
|
return self._teilenummern
|
||||||
|
|
||||||
|
def get_blacklist(self):
|
||||||
|
if not self._data_dir:
|
||||||
|
raise Exception("set_data_dir not called. path not set")
|
||||||
|
with open(os.path.join(self._data_dir, 'blacklist.txt')) as f:
|
||||||
|
lines = f.read().splitlines()
|
||||||
|
self._blacklist = lines
|
||||||
|
return self._blacklist
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
numpy==1.26.1
|
et_xmlfile==2.0.0
|
||||||
pandas==2.1.1
|
numpy==2.2.3
|
||||||
python-dateutil==2.8.2
|
openpyxl==3.1.5
|
||||||
pytz==2023.3.post1
|
pandas==2.2.3
|
||||||
six==1.16.0
|
pymssql==2.3.2
|
||||||
tzdata==2023.3
|
python-dateutil==2.9.0.post0
|
||||||
et-xmlfile==1.1.0
|
pytz==2025.1
|
||||||
openpyxl==3.1.2
|
six==1.17.0
|
||||||
|
tzdata==2025.1
|
||||||
|
|||||||
+124
-63
@@ -4,102 +4,163 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import csv
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dieses Programm:
|
Diese Library erzeugt Dateien mit RuleDesigner-, bzw. SIVAS-Informationen,
|
||||||
- Kopiert die CSV-Datei mit allen RuleDesigner-Nummern
|
bzw. stellt diese durch Kopieren / Verschieben von bereits vorhandenen
|
||||||
- Fragt Sivas ab und generiert dabei eine json-Datei, in der alle Teilenummern aufgelistet sind,
|
Dateien auf Netzlaufwerken bereit
|
||||||
die in Verbindung mit einer angegebenen Teilenummer migriert werden müssen.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_blacklist(outdir):
|
def get_blacklist(outdir):
|
||||||
"""read out list of sivas Ids which are not allowed from network drive
|
|
||||||
'//ruledesigner//DF_Daten//onfigurator//ustomVaulting//RP_BOM.ini'
|
|
||||||
within the section 'Settings'
|
|
||||||
in the key 'PartNumbersToDrop'
|
|
||||||
"""
|
"""
|
||||||
|
Schreibt Teilenummern aus der nachfolgenden .ini-Datei in eine .txt-Datei:
|
||||||
|
|
||||||
|
-> Dateipfad: //ruledesigner/RDF_Daten/Configurator/CustomVaulting/ERP_BOM.ini'
|
||||||
|
-> Abschnitt: 'Settings'
|
||||||
|
-> Schlüssel: 'PartNumbersToDrop'
|
||||||
|
|
||||||
|
Bei diesen Teilenummern darf keine Stücklistenübergabe an SIVAS erfolgen, da sich die Stücklistenstruktur
|
||||||
|
zwischen dem CAD und SIVAS unterscheidet (vorrangig bei Baugruppen mit Lieferantenbeistellungen)
|
||||||
|
"""
|
||||||
|
|
||||||
blacklist_net_share = os.environ.get("BLACKLIST_DATABASE_SOURCE")
|
blacklist_net_share = os.environ.get("BLACKLIST_DATABASE_SOURCE")
|
||||||
blacklist_ini_filename = os.environ.get("BLACKLIST_DATABASE_NAME")
|
blacklist_ini_filename = os.environ.get("BLACKLIST_DATABASE_NAME")
|
||||||
blacklist_source_path = os.path.join(blacklist_net_share, blacklist_ini_filename)
|
blacklist_source_path = os.path.join(blacklist_net_share, blacklist_ini_filename)
|
||||||
config = configparser.RawConfigParser()
|
config = configparser.RawConfigParser()
|
||||||
|
|
||||||
|
if not os.path.isfile(blacklist_source_path):
|
||||||
|
raise FileNotFoundError(f"Kein Zugriff auf ini-Datei '{blacklist_source_path}' mit den Blacklist-Teilenummern möglich. Bitte $BLACKLIST_DATABASE_SOURCE & $BLACKLIST_DATABASE_NAME in cremig_setenv.bat sowie VPN-Verbindung prüfen")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
config.read(blacklist_source_path)
|
config.read(blacklist_source_path)
|
||||||
except configparser.DuplicateOptionError:
|
except configparser.DuplicateOptionError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
content = config.get('Settings','PartNumbersToDrop')
|
content = config.get('Settings','PartNumbersToDrop')
|
||||||
blacklist_str = content[0] # warum das als Liste erkannt wird wissen die Götter...
|
|
||||||
if len(blacklist_str) == 0 or len(content) == 0:
|
|
||||||
print(f"import of '{blacklist_ini_filename}' from '{blacklist_net_share}' failed")
|
|
||||||
exit
|
|
||||||
|
|
||||||
blacklist = blacklist_str.split(';')
|
if isinstance(content, list):
|
||||||
|
content = content[0] # Manchmal wird String mit den Blacklist-Nummern in einer Liste geschrieben - warum wissen die Götter...
|
||||||
|
|
||||||
|
if len(content) == 0:
|
||||||
|
raise ValueError(f"Öffnen der Blacklist-Datei'{blacklist_ini_filename}' in '{blacklist_net_share}' fehlgeschlagen")
|
||||||
|
|
||||||
|
blacklist = content.split(';')
|
||||||
|
|
||||||
print("writing txt-file of blacklist ids...")
|
|
||||||
outfile = os.path.join(outdir, 'blacklist.txt')
|
outfile = os.path.join(outdir, 'blacklist.txt')
|
||||||
|
|
||||||
|
print(f"Schreibe Blacklist-Teilenummern in '{outfile}'...")
|
||||||
with open(outfile, 'w', encoding='utf-8') as fh:
|
with open(outfile, 'w', encoding='utf-8') as fh:
|
||||||
fh.write('\n'.join(blacklist))
|
fh.write('\n'.join(blacklist))
|
||||||
print("done")
|
|
||||||
|
|
||||||
def get_rd_dbase(out_dir):
|
def get_ruledesigner_ids(out_dir=os.environ.get('CREMIG_DATA')):
|
||||||
|
"""Kopiert CSV-Datei, in der alle RuleDesigner-Teilenummern aufgelistet sind, vom Netzlaufwerk in ein lokales Verzeichnis"""
|
||||||
|
|
||||||
rd_csv_source_dir = os.environ.get("RD_DATABASE_SOURCE")
|
rd_csv_source_dir = os.environ.get("RD_DATABASE_SOURCE")
|
||||||
rd_csv_filename = os.environ.get("RD_DATABASE_NAME")
|
rd_csv_filename = os.environ.get("RD_DATABASE_NAME")
|
||||||
csv_source_path = os.path.join(rd_csv_source_dir, rd_csv_filename)
|
csv_source_path = os.path.join(rd_csv_source_dir, rd_csv_filename)
|
||||||
|
csv_destiny_path = os.path.join(out_dir, rd_csv_filename)
|
||||||
|
|
||||||
if os.path.isfile(csv_source_path):
|
if not os.path.isfile(csv_source_path):
|
||||||
csv_destiny_path = os.path.join(out_dir, rd_csv_filename)
|
raise FileNotFoundError(f"CSV-Datei mit RuleDesigner-Teilenummern existiert nicht unter '{csv_source_path}'. Bitte $RD_DATABASE_SOURCE & $RD_DATABASE_NAME in cremig_setenv.bat prüfen.")
|
||||||
|
|
||||||
if os.path.isdir(out_dir):
|
if not os.path.isdir(out_dir):
|
||||||
print("Copying CSV-file of RuleDesigner database...")
|
raise NotADirectoryError(f"Zielverzeichnis '{out_dir}' für CSV-Datei mit RuleDesigner-Teilenummern existiert nicht. Bitte $CREMIG_DATA in cremig_setenv.bat und VPN-Verbindung prüfen")
|
||||||
shutil.copyfile(csv_source_path, csv_destiny_path)
|
|
||||||
print("done")
|
|
||||||
else:
|
|
||||||
print(f"Can't copy RuleDesigner-database, because output directory ${out_dir} doesn't exist. Check %CREMIG_DATA% in cremig_setenv.bat")
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
print(f"File with ruldesigner-partnumbers ${csv_source_path} doesn't exist. Check VPN connection and %RD_DATABASE_SOURCE% + %RD_DATABASE_NAME% in cremig_setenv.bat")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
print(f"Kopiere '{rd_csv_source_dir}\\{rd_csv_filename}'...")
|
||||||
|
shutil.copyfile(csv_source_path, csv_destiny_path)
|
||||||
|
|
||||||
def get_sivas_dbase(sivas_id, out_dir):
|
def get_sivas_bom(sivas_id, out_dir=os.environ.get('CREMIG_DATA')):
|
||||||
sivas_exe_path = os.environ.get('SIVAS_DATABASE_QUERY')
|
"""Generiert JSON-Datei, in der die Stücklisteninformationen zu einer SIVAS-Teilenummer mit Stammstückliste gespeichert sind.
|
||||||
|
Die Erstellung der JSON-Datei erfolgt unter Verwendung des externen Sivas2Json-Programms von Hr. Jakob"""
|
||||||
|
|
||||||
if os.path.isfile(sivas_exe_path):
|
sivas2json_exe_path = os.environ.get('SIVAS_BOM')
|
||||||
|
sivas_id = sivas_id.replace(".json", "")
|
||||||
if os.path.isdir(out_dir):
|
|
||||||
print(f"Attempting to generate a json-file of all parts to be migrated in relation with '{sivas_id}'")
|
if not os.path.isfile(sivas2json_exe_path):
|
||||||
subprocess.run(f"{sivas_exe_path} -o {out_dir} --format json -number {sivas_id}")
|
raise FileNotFoundError(f"Programmpfad '{sivas2json_exe_path}' nicht erreichbar. Bitte prüfen, ob Zugriff auf Laufwerk Y: besteht. Andernfalls $SIVAS_BOM in cremig_setenv.bat sowie VPN-Verbindung prüfen")
|
||||||
|
|
||||||
if os.path.isfile(os.path.join(out_dir, sivas_id + ".json")):
|
if not os.path.isdir(out_dir):
|
||||||
print("done")
|
raise NotADirectoryError(f"Ausgabeverzeichnis '{out_dir}' für die Stücklisten-JSON existiert nicht. Bitte $SIVAS_BOM in cremig_setenv.bat oder VPN-Verbindung prüfen.")
|
||||||
else:
|
|
||||||
print(f"Failure - Couldn't generate {sivas_id}.json. Check for any spelling/typing errors. Otherwise given number is a part without a BOM.")
|
print(f"Erstelle JSON mit Stücklisteninformationen...")
|
||||||
sys.exit(0)
|
subprocess.run(f'{sivas2json_exe_path} -o {out_dir} --format json -number "{sivas_id}"')
|
||||||
else:
|
|
||||||
print(f"'Output directory for .json-file {out_dir}' doesn't exist. Check cremig_setenv.bat or VPN connection.")
|
if not os.path.isfile(os.path.join(out_dir, sivas_id + ".json")):
|
||||||
sys.exit(0)
|
raise ValueError(f"{sivas_id}.json konnte nicht erzeugt werden. Evtl. Nummer ohne Stückliste.")
|
||||||
else:
|
|
||||||
print(f"Can't execute SIVAS-database query. Check VPN connection and check the path of %SIVAS_DATABASE_QUERY% in cremig_setenv.bat")
|
def get_sivas_teilestamm(sivas_ids, out_dir=os.environ.get('CREMIG_DATA'), overwrite=True):
|
||||||
sys.exit(0)
|
|
||||||
|
"""
|
||||||
|
Generiert für jede angegebene SIVAS-Teilenummer eine CSV-Datei, in der die Teilestamm-Informationen gespeichert sind
|
||||||
|
Es kann eine oder mehrere Nummern angegeben werden. Mehrere Nummern sind entweder als kommaseparierter String oder
|
||||||
|
in Form einer Liste anzugeben
|
||||||
|
"""
|
||||||
|
|
||||||
|
sivas_teilestamm_exe = os.environ.get('SIVAS_TEILESTAMM')
|
||||||
|
if not os.path.isfile(sivas_teilestamm_exe):
|
||||||
|
raise FileNotFoundError(f"Programmpfad '{sivas_teilestamm_exe}' nicht erreichbar. Bitte prüfen, ob Zugriff auf Laufwerk Y: besteht. Andernfalls $SIVAS_TEILESTAMM in cremig_setenv.bat sowie VPN-Verbindung prüfen")
|
||||||
|
|
||||||
|
if not os.path.isdir(out_dir):
|
||||||
|
raise NotADirectoryError(f"Ausgabeverzeichnis '{out_dir}' für die Teilestamm-CSV existiert nicht. Bitte $SIVAS_TEILESTAMM in cremig_setenv.bat oder VPN-Verbindung prüfen.")
|
||||||
|
|
||||||
|
if isinstance(sivas_ids, str):
|
||||||
|
sivas_ids = list(set(sivas_ids.strip().split(",")))
|
||||||
|
|
||||||
|
ids_to_generate = []
|
||||||
|
for id in sivas_ids:
|
||||||
|
if not overwrite and os.path.isfile(os.path.join(out_dir, id + ".csv")):
|
||||||
|
continue
|
||||||
|
ids_to_generate.append(id)
|
||||||
|
|
||||||
|
if len(ids_to_generate) == 0:
|
||||||
|
print("CSV-Datei(en) existieren bereits oder angegebene Teilenummer(n) sind bereits migriert")
|
||||||
|
return
|
||||||
|
|
||||||
|
ids_to_generate_str = ",".join([f'"{id}"' for id in ids_to_generate]) # Anführungszeichen erforderlich, damit Art.Nr. mit Leerzeichen, z.B. "TOS Auswahl ILS" funktionieren
|
||||||
|
|
||||||
|
os.environ["SIVAS_EXCEL_EXPORT_DIR"] = out_dir # Umgebungsvariable legt Ausgabeverzeichnis der CSV-Dateien im Programm 'KSbExcelExportSivasTeilestamm' fest. Der Variablenname ist durch genanntes Programm vorgegeben, siehe help-Text des Programms!
|
||||||
|
print(f"Erstelle CSV(s) mit Teilestamminformationen...")
|
||||||
|
subprocess.run(f'{sivas_teilestamm_exe} -teilenr={ids_to_generate_str} -open_target_dir=n')
|
||||||
|
|
||||||
|
# Prüft Existenz der angegebenen SIVAS-Nummern, indem geschaut wird, ob die CSV-Dateien 2 Zeilen aufweisen
|
||||||
|
# Nicht über Returncode des Subprocess ermittelbar, da dieser immer 0 ist, auch wenn die Nr. nicht in SIVAS existiert
|
||||||
|
for id in ids_to_generate:
|
||||||
|
csv_path = os.path.join(out_dir, id + ".csv")
|
||||||
|
with open(csv_path, encoding="utf-8", newline="") as csv_file:
|
||||||
|
csv_data = csv.reader(csv_file, delimiter=";")
|
||||||
|
line_nums = sum(1 for row in csv_data)
|
||||||
|
if line_nums != 2:
|
||||||
|
raise ValueError(f"SIVAS-Teilenummer '{id}' existiert nicht! Bitte prüfen, ob Nummer korrekt geschrieben wurde!")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='fetches data from sivas or ruledesigner fusion', prog='update_database')
|
|
||||||
parser.add_argument('-s', '--sivasid', action='store', help='fetch data of this id from sivas fo local database folder', metavar='id')
|
parser = argparse.ArgumentParser(description='Erzeugt Dateien mit RuleDesigner-, bzw. SIVAS-Informationen, bzw. stellt diese bereit', prog='update_database')
|
||||||
parser.add_argument('-r', '--rd', action='store_true', help='fetch list of existing parts from network drive')
|
parser.add_argument('-b', '--blacklist', action='store_true', help='Schreibe .txt-Datei mit allen Teilenummern, bei denen keine Stücklistenübergabe aus dem CAD nach SIVAS erfolgen darf')
|
||||||
parser.add_argument('-b', '--blacklist', action='store_true', help='fetch list of not allowed parts from network drive')
|
parser.add_argument('-d', '--out_dir', action='store', default=os.environ.get('CREMIG_DATA'), help='Ausgabeverzeichnis für Datei', metavar="dir")
|
||||||
|
parser.add_argument('-m', '--bom', action='store_true', help='Schreibe Stückliste einer SIVAS-Teilenummer als JSON-Datei')
|
||||||
|
parser.add_argument('-o', '--overwrite', action='store_true', default=False, help='Überschreibe Datei, wenn diese bereits in Zielverzeichnis vorliegt')
|
||||||
|
parser.add_argument('-r', '--rd_ids', action='store_true' ,help='Kopiere CSV-Datei, in der alle RuleDesigner-Teilenummern aufgelistet sind')
|
||||||
|
parser.add_argument('-s', '--sivasid', action='store', help='SIVAS-Teilenummer', metavar='id')
|
||||||
|
parser.add_argument('-t', '--teilestamm', action='store_true', help='Schreibe Teilestamm-Medataten einer SIVAS-Teilenummer als CSV-Datei')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
out_dir = os.environ.get('CREMIG_DATA')
|
if len(sys.argv) == 1:
|
||||||
|
|
||||||
if args.rd:
|
|
||||||
get_rd_dbase(out_dir)
|
|
||||||
|
|
||||||
elif args.sivasid:
|
|
||||||
get_sivas_dbase(args.sivasid, out_dir)
|
|
||||||
|
|
||||||
elif args.blacklist:
|
|
||||||
get_blacklist(out_dir)
|
|
||||||
|
|
||||||
else:
|
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
|
|
||||||
|
if args.rd_ids:
|
||||||
|
get_ruledesigner_ids(args.out_dir)
|
||||||
|
|
||||||
|
if args.blacklist:
|
||||||
|
get_blacklist(args.out_dir)
|
||||||
|
|
||||||
|
if args.sivasid:
|
||||||
|
if args.teilestamm:
|
||||||
|
get_sivas_teilestamm(args.sivasid, args.out_dir, overwrite = True)
|
||||||
|
|
||||||
|
if args.bom:
|
||||||
|
get_sivas_bom(args.sivasid, args.out_dir)
|
||||||
Binary file not shown.
Reference in New Issue
Block a user