diff --git a/.gitea/workflows/build-push.yaml b/.gitea/workflows/build-push.yaml index 12ce352..8bc0e89 100644 --- a/.gitea/workflows/build-push.yaml +++ b/.gitea/workflows/build-push.yaml @@ -1,58 +1,47 @@ name: Docker Build & Push -run-name: ${{ gitea.actor }} zwingt es zum Laufen 🔨 - +run-name: ${{ gitea.actor }} flucht, aber baut 🔨 on: push: branches: - main - master - + jobs: build-and-push: runs-on: ubuntu-latest steps: - # ----------------------------------------------------------- - # 1. DER NETZWERK-RETTER (MUSS WIEDER REIN!) - # Ersetzt "gitea:3000" durch die IP, damit der Container es findet. - # ----------------------------------------------------------- + # 1. DER FIX (Mit dem automatischen Gitea-Token) + # ${{ gitea.token }} hat IMMER Zugriff auf das Repo, in dem der Job läuft. - name: Fix Git URL Resolution - run: git config --global url."http://172.30.1.213/".insteadOf "http://gitea:3000/" + run: git config --global url."http://${{ gitea.token }}@172.30.1.213/".insteadOf "http://gitea:3000/" - # 2. Checkout (Klappt jetzt, weil URL umgebogen wird) + # 2. Checkout - name: Checkout Code uses: actions/checkout@v3 - # 3. Login (Mit dem globalen Token aus deinen User-Settings) + # 3. Docker Login (Hier nehmen wir weiterhin deinen Runner-Token oder den Actor) + # Wenn der Login fehlschlägt, dann hat dein User keine Schreibrechte auf Packages. + # Aber probier erst mal Checkout. - name: Login bei Registry run: docker login 172.30.1.213 -u ${{ gitea.actor }} -p ${{ secrets.TOKEN_RUNNER }} - # 4. Feuer frei + # 4. Bauen - name: Build & Push run: | REPO_LOWER=$(echo "${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]') IMAGE_TAG="172.30.1.213/$REPO_LOWER:latest" - echo "Baue Image: $IMAGE_TAG" - docker build -t $IMAGE_TAG . docker push $IMAGE_TAG - + + # 5. Node-RED - name: Webhook an Node-RED if: always() run: | - # Status setzen if [ "${{ job.status }}" == "success" ]; then STATUS="success" else STATUS="failed" fi - - # JSON Payload basteln - # Wir nutzen printf, um sauberes JSON zu bauen JSON_DATA=$(printf '{"status": "%s", "repo": "%s", "actor": "%s"}' "$STATUS" "${{ gitea.repository }}" "${{ gitea.actor }}") - - # Abfeuern an Node-RED - curl -v -H "Content-Type: application/json" \ - -X POST \ - -d "$JSON_DATA" \ - http://172.30.80.246:1880/gitea-status \ No newline at end of file + curl -v -H "Content-Type: application/json" -X POST -d "$JSON_DATA" http://172.30.80.246:1880/gitea-status diff --git a/README.md b/README.md index 284a6f3..883c02c 100644 --- a/README.md +++ b/README.md @@ -206,3 +206,9 @@ Das Projekt basiert auf bewährten Web-Standards: * `packliste.sql` aktualisiert. * Anzeige-Probleme bei Dropdowns behoben. * SQL-Fehler in der Statistik-Berechnung korrigiert. + +### 11.05.2026 +* **Fixes:** + * Fehler bei der Artikelanzahl behoben: Wenn ein Artikel mehrfach im Bestand vorhanden ist (z.B. 5 Stück), verschwindet er nicht mehr aus der Auswahlliste, nachdem das erste Stück in einen Rucksack gezogen wurde. + * Bugfix für Session-Timeouts ("Headers already sent"): Die PHP-Sitzung wird nun korrekt überprüft und verarbeitet, bevor HTML-Header gesendet werden (z.B. in `backpacks.php`). + * Session Timeout (Ausloggen) auf 24 Stunden verlängert (per `.htaccess`). diff --git a/src/.htaccess b/src/.htaccess new file mode 100644 index 0000000..17ef5c4 --- /dev/null +++ b/src/.htaccess @@ -0,0 +1,3 @@ +php_value session.gc_maxlifetime 86400 +php_value session.cookie_lifetime 86400 +php_value session.cache_expire 86400 diff --git a/src/backpacks.php b/src/backpacks.php index 1282698..728eff1 100644 --- a/src/backpacks.php +++ b/src/backpacks.php @@ -2,13 +2,18 @@ // backpacks.php - Verwaltung der Rucksäcke $page_title = "Rucksäcke"; require_once 'db_connect.php'; -require_once 'header.php'; + +if (session_status() == PHP_SESSION_NONE) { + session_start(); +} if (!isset($_SESSION['user_id'])) { header("Location: login.php"); exit; } +require_once 'header.php'; + $user_id = $_SESSION['user_id']; $message = ''; diff --git a/src/manage_packing_list_items.php b/src/manage_packing_list_items.php index ddd6097..d575563 100644 --- a/src/manage_packing_list_items.php +++ b/src/manage_packing_list_items.php @@ -286,11 +286,23 @@ $conn->close(); const filterCategory = document.getElementById('filter-category').value; const filterManufacturer = document.getElementById('filter-manufacturer').value; const availableListEl = document.getElementById('available-items-list'); - const packedArticleIds = packedItems.map(item => String(item.article_id)); + + const packedQuantities = {}; + packedItems.forEach(item => { + const aid = String(item.article_id); + packedQuantities[aid] = (packedQuantities[aid] || 0) + parseInt(item.quantity || 1, 10); + }); + let html = ''; allArticles.forEach(article => { if (article.parent_article_id) return; - if (article.consumable == 1 || !packedArticleIds.includes(String(article.id))) { + + const aid = String(article.id); + const packedQty = packedQuantities[aid] || 0; + const ownedQty = parseInt(article.quantity_owned || 1, 10); + const isConsumable = article.consumable == 1; + + if (isConsumable || packedQty < ownedQty) { const matchesText = article.name.toLowerCase().includes(filterText) || (article.manufacturer_name && article.manufacturer_name.toLowerCase().includes(filterText)) || (article.product_designation && article.product_designation.toLowerCase().includes(filterText)); const matchesCategory = !filterCategory || article.category_name === filterCategory; const matchesManufacturer = !filterManufacturer || article.manufacturer_name === filterManufacturer;