Zefix_search/index.php

433 lines
17 KiB
PHP

<?php
include "zefixAPI.php";
?>
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap first, then your overrides -->
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/custom.css?v=1.3">
<title>Silias Zefix Export</title>
<style>
/* Nice input for the search box */
#sitzInput {
box-sizing: border-box;
font-size: 16px;
border: 1px solid #dee2e6;
border-radius: .5rem;
padding: .6rem .8rem;
width: 100%;
}
.scrollWindow {
max-height: 320px;
overflow-y: auto;
border: 1px solid #dee2e6;
border-radius: .75rem;
background: #fff;
padding: .75rem;
}
.button-small {
font-size: 0.8rem;
padding: .35rem .6rem;
border-radius: .5rem;
}
.gemeindeeintrag { margin-bottom: .25rem; }
</style>
</head>
<body class="bg-light">
<nav class="navbar navbar-light bg-white border-bottom">
<div class="container">
<span class="navbar-brand mb-0 h1">Silias • ZEFIX Export</span>
</div>
</nav>
<main class="container py-4 py-md-5">
<div class="row justify-content-center">
<div class="col-lg-10 col-xl-9">
<div class="card shadow-sm">
<div class="card-body p-4 p-md-5">
<div class="d-flex flex-column flex-md-row align-items-md-start justify-content-between gap-2 mb-3">
<div>
<h1 class="h3 mb-1">Silias Zefix Suche</h1>
<p class="text-muted mb-0">
Exportiere Firmen als Excel (xlsx) aus dem Zentralen Firmenindex (ZEFIX).
</p>
</div>
<span class="badge bg-primary-subtle text-primary border border-primary-subtle align-self-md-center">
Export via E-Mail Link
</span>
</div>
<hr class="my-4">
<form action="submit.php" method="post" class="needs-validation" novalidate>
<!-- Firmenname -->
<div class="mb-4">
<label for="firma" class="form-label">Firmenname</label>
<div class="form-text mb-2">* kann als Platzhalter verwendet werden</div>
<input type="text" id="firma" name="firma" class="form-control" placeholder="z.B. Silias*">
</div>
<!-- Kanton -->
<div class="mb-4">
<label class="form-label">Kanton</label>
<div class="alert alert-warning py-2 mb-2" role="alert" style="font-size: .95rem;">
Die Kantonsauswahl wird vom Export ignoriert und dient nur zum Filtern der Ortschaften.
Für Export nach Kanton: gewünschte Kantone wählen und dann bei Ortschaften auf
<b>Alle Ergebnisse auswählen</b> klicken.
</div>
<div id="kantonauswahl" class="scrollWindow" onclick="filterFunction()"></div>
</div>
<!-- Sitz / Ort -->
<div class="mb-4">
<label class="form-label">Sitz (Ort)</label>
<div class="card border-0 bg-white">
<div class="card-body p-0">
<div class="d-flex flex-column flex-lg-row gap-2 mb-2">
<div class="flex-grow-1">
<input type="text"
placeholder="Suchen (Ort)"
id="sitzInput"
onkeyup="filterFunction()"
onchange="filterFunction()"
name="sitzfilter"
autocomplete="off">
</div>
<div class="d-flex flex-wrap gap-2">
<button type="button" class="btn btn-outline-primary button-small" onclick="gefundeneGemeindenAuswählen()">
Alle Ergebnisse auswählen
</button>
<button type="button" class="btn btn-outline-secondary button-small" onclick="ausgewählteGemeindenLöschen()">
Auswahl löschen
</button>
<button type="button" class="btn btn-outline-secondary button-small" onclick="alleGemeindenAnzeigen()">
Alle anzeigen
</button>
<button type="button" class="btn btn-outline-secondary button-small" onclick="nurAusgewählteGemeindenAnzeigen()">
Nur ausgewählte
</button>
</div>
</div>
<div id="sitzauswahl" class="scrollWindow"></div>
</div>
</div>
</div>
<!-- Rechtsform -->
<div class="mb-4">
<label class="form-label">Rechtsform</label>
<div id="rechtsformenauswahl" class="scrollWindow"></div>
</div>
<!-- Optionen -->
<div class="mb-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="exakteSuche" name="exakteSuche" disabled>
<label class="form-check-label" for="exakteSuche">Exakte Suche (noch in Entwicklung)</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="geloeschteRechtseinheiten" name="geloeschteRechtseinheiten">
<label class="form-check-label" for="geloeschteRechtseinheiten">Gelöschte Rechtseinheiten suchen</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="inBisherigenFirmen" name="inBisherigenFirmen" disabled>
<label class="form-check-label" for="inBisherigenFirmen">In bisherigen Firmen/Namen suchen (noch in Entwicklung)</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="phonetischeSuche" name="phonetischeSuche" disabled>
<label class="form-check-label" for="phonetischeSuche">Phonetische Suche (noch in Entwicklung)</label>
</div>
</div>
<!-- Email -->
<div class="mb-4">
<label for="email" class="form-label">Ihre E-Mail Adresse</label>
<div class="form-text mb-2">
Das Aufbereiten der Daten kann länger dauern. Sie erhalten einen Download-Link per E-Mail sobald die Daten bereit sind.
</div>
<input type="email" id="email" name="email" class="form-control" required placeholder="name@firma.ch">
<div class="invalid-feedback">Bitte eine gültige E-Mail Adresse eingeben.</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg">Export starten</button>
</div>
</form>
<script>
// Bootstrap validation (optional)
(function () {
'use strict'
const forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})();
</script>
<script>
// CSV data injected by PHP
let communityCsvData;
let legalFormsCsvData;
<?php
include 'gemeinden.php';
include 'legalForms.php';
?>
// --- Helpers to create nicer checkbox rows (Bootstrap form-check) ---
function addCheckboxRow(container, checkboxName, checkboxValue, labelText) {
const wrapper = document.createElement('div');
wrapper.className = "form-check";
const input = document.createElement('input');
input.className = "form-check-input";
input.type = "checkbox";
input.name = checkboxName;
input.value = checkboxValue;
const label = document.createElement('label');
label.className = "form-check-label";
label.textContent = labelText;
wrapper.appendChild(input);
wrapper.appendChild(label);
container.appendChild(wrapper);
return input;
}
// --- Legal forms ---
const legalFormslines = legalFormsCsvData.trim().split('\n');
const legalFormsheaders = legalFormslines[0].split(',');
const legalformIdIndex = legalFormsheaders.indexOf('id');
const legalformNameIndex = legalFormsheaders.indexOf('name');
const rechtsformenauswahl = document.getElementById("rechtsformenauswahl");
for (let i = 1; i < legalFormslines.length; i++) {
const cells = legalFormslines[i].split(',');
const id = (cells[legalformIdIndex] || '').trim();
const name = (cells[legalformNameIndex] || '').trim();
if (!id || !name) continue;
addCheckboxRow(rechtsformenauswahl, "rechtsformen[]", id, " " + name);
}
// --- Communities + Cantons ---
const lines = communityCsvData.trim().split('\n');
const headers = lines[0].split(',');
const gemeindeNameIndex = headers.indexOf('Gemeindename');
const bfsIdIndex = headers.indexOf('id');
const kantonIndex = headers.indexOf('Kanton');
const registryOfCommerceIdIndex = headers.indexOf('registryOfCommerceId');
const sitze = [];
const kantone = [];
const kantonauswahl = document.getElementById("kantonauswahl");
const sitzauswahl = document.getElementById("sitzauswahl");
for (let i = 1; i < lines.length; i++) {
const cells = lines[i].split(',');
if (!cells || cells.length < 4) continue;
const bfsId = (cells[bfsIdIndex] || '').trim();
const gemeindeName = (cells[gemeindeNameIndex] || '').trim();
const kanton = (cells[kantonIndex] || '').trim();
const registryOfCommerceId = (cells[registryOfCommerceIdIndex] || '').trim();
if (!bfsId || !gemeindeName) continue;
// Add canton if new
if (kanton && !kantone.includes(kanton)) {
kantone.push(kanton);
addCheckboxRow(kantonauswahl, "kantone[]", kanton, " " + kanton);
}
// Store row for filtering logic
sitze.push(cells);
// Create nicer entry
const gemeindeEintrag = document.createElement("div");
gemeindeEintrag.classList.add("gemeindeeintrag");
const wrapper = document.createElement('div');
wrapper.className = "form-check";
const input = document.createElement('input');
input.className = "form-check-input";
input.type = "checkbox";
input.name = "sitze[]";
input.value = bfsId;
const label = document.createElement('label');
label.className = "form-check-label";
label.textContent = " " + gemeindeName;
wrapper.appendChild(input);
wrapper.appendChild(label);
gemeindeEintrag.appendChild(wrapper);
sitzauswahl.appendChild(gemeindeEintrag);
}
const sitzInput = document.getElementById('sitzInput');
function kantoneAusgewählt() {
const checkboxes = document.querySelectorAll('input[name="kantone[]"]');
let countChecked = 0;
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) countChecked++;
}
return countChecked;
}
function filterFunction() {
const numKantoneAusgewählt = kantoneAusgewählt();
const filter = (sitzInput.value || "").toUpperCase();
const entries = sitzauswahl.getElementsByClassName("gemeindeeintrag");
for (let i = 0; i < entries.length; i++) {
const txtValue = entries[i].textContent || entries[i].innerText;
const selectedCheckbox = entries[i].querySelector('input[type="checkbox"]');
const isSelected = selectedCheckbox ? selectedCheckbox.checked : false;
// map entry->sitz row index: still aligned because we push sitze once per entry
const row = sitze[i];
const rowKanton = row ? row[kantonIndex] : "";
let cantonOk = true;
if (numKantoneAusgewählt > 0 && rowKanton) {
const cantonBox = document.querySelector('input[name="kantone[]"][value="' + rowKanton + '"]');
cantonOk = cantonBox ? cantonBox.checked : false;
}
const matchesText = txtValue.toUpperCase().indexOf(filter) > -1;
if ((matchesText && (cantonOk || numKantoneAusgewählt === 0)) || isSelected) {
entries[i].style.display = "";
} else {
entries[i].style.display = "none";
}
}
}
function alleGemeindenAnzeigen() {
sitzInput.value = "";
filterFunction();
}
function nurAusgewählteGemeindenAnzeigen() {
sitzInput.value = "(nur ausgewählte)";
filterFunction();
}
function ausgewählteGemeindenLöschen() {
sitzauswahl.querySelectorAll('input[type="checkbox"]').forEach(function(cb) {
cb.checked = false;
});
filterFunction();
}
function gefundeneGemeindenAuswählen() {
sitzauswahl.querySelectorAll('input[type="checkbox"]').forEach(function(cb) {
// show/hide is on the gemeindeeintrag wrapper
const entry = cb.closest('.gemeindeeintrag');
if (entry && entry.style.display !== "none") cb.checked = true;
});
filterFunction();
}
</script>
</div>
</div>
</div>
</div>
</main>
<footer class="border-top bg-white">
<div class="container py-4">
<div class="row g-4">
<div class="col-md-4">
<h2 class="h6 mb-2">Impressum</h2>
<div class="text-muted" style="font-size:.95rem;">
Silias KLG<br>
Toggenburgstrasse 31<br>
8245 Feuerthalen<br>
<a href="https://www.silias.ch" target="_blank" rel="noopener">www.silias.ch</a><br>
<a href="mailto:info@silias.ch">info@silias.ch</a><br>
<a href="https://gitea.silias.ch/Silias-Public/Zefix_search">Projekt Repository</a>
</div>
</div>
<div class="col-md-4">
<h2 class="h6 mb-2">Datenquelle</h2>
<div class="text-muted" style="font-size:.95rem;">
Zentraler Firmenindex<br>
Eidgenössisches Justiz- und Polizeidepartement (EJPD)<br>
Bundesamt für Justiz (BJ)<br>
Eidgenössisches Amt für das Handelsregister (EHRA)<br>
Bundesrain 20, 3003 Bern<br>
<a href="https://www.zefix.admin.ch" target="_blank" rel="noopener">www.zefix.admin.ch</a><br>
<a href="tel:+41584624197">+41 (0) 58 462 41 97</a><br>
<a href="mailto:zefix@bj.admin.ch">zefix@bj.admin.ch</a>
</div>
</div>
<div class="col-md-4">
<h2 class="h6 mb-2">Warteliste</h2>
<div class="text-muted" style="font-size:.95rem;">
<script>
const deleteFiles = function () {
let taskDeletePassword = prompt("Passwort eingeben:");
if (taskDeletePassword === null) return;
let formdata = new FormData();
formdata.append('taskDeletePassword', taskDeletePassword);
fetch("deleteFiles.php", { method: "POST", body: formdata })
.then(() => location.reload());
}
</script>
Momentan sind
<b><?php $taskDir = 'tasks'; echo count(scandir($taskDir)) - 2 ?></b>
Aufträge in der Warteliste.<br>
<a href="#" onclick="deleteFiles(); return false;">alle löschen</a>
</div>
</div>
</div>
<div class="text-center text-muted mt-4" style="font-size:.9rem;">
© <?php echo date('Y'); ?> Silias KLG
</div>
</div>
</footer>
</body>
</html>