Merge branch 'ConstructionConsent/fix-addr-search' into 'master'

added construction consent owner import

See merge request fronk/thetool!1238
This commit is contained in:
Luca Haid
2025-04-22 15:46:41 +00:00
4 changed files with 125 additions and 3 deletions

View File

@@ -164,8 +164,11 @@ $pagination_entity_name = "Zustimmungserklärungen";
<div class="col">
<button type="submit" class="btn btn-primary"><i class="far fa-search fa-fw"></i> Filter anwenden</button>
<a class="btn btn-secondary" href="<?=self::getUrl("ConstructionConsent", "", ["resetFilter" => 1, "filter" => ["project_id" => (is_array($filter) && array_key_exists("project_id", $filter) ? $filter["project_id"] : "")]])?>"><i class="far fa-xmark fa-fw"></i> Filter zurücksetzen</a>
<input type="file" id="csvFileInput" accept=".csv" class="d-none">
<?php if ($me->isAdmin() && is_array($filter) && array_key_exists("project_id", $filter) && !empty($filter["project_id"])): ?>
<label style="margin-bottom: 0; cursor: pointer" for="csvFileInput" class="btn btn-info"><i class="fas fa-upload fa-fw"></i> Eigentümer-CSV Import</label>
<?php endif; ?>
</div>
<!-- create a div that is on the right side of the row-->
<div class="col text-right">
<a class="btn btn-success" href="<?=self::getUrl("ConstructionConsent", "downloadMultiple", ["filter" => $filter])?>"><i class="fas fa-download"></i> Zustimmungserklärungen herunterladen</a>
</div>
@@ -449,4 +452,60 @@ $pagination_entity_name = "Zustimmungserklärungen";
background-color: #337ab7; /* Blue */
}
</style>
<script>
document.addEventListener('DOMContentLoaded', () => {
const csvFileInput = document.getElementById('csvFileInput');
const apiUrl = '<?=self::getUrl("ConstructionConsent", "importConstructionConsentOwners", ["project_id" => (is_array($filter) && array_key_exists("project_id", $filter) ? $filter["project_id"] : "")])?>';
const csvToJson = csv => {
let [headerLine, ...lines] = csv.trim().split(/\r?\n/).filter(Boolean);
if (!headerLine || lines.length === 0) return [];
const headers = headerLine.split(';').map(h => h.trim());
return lines.map(row => {
const values = row.split(';').map(v => v.trim().replaceAll('"', ''));
return headers.reduce((obj, key, i) => ({ ...obj, [key]: values[i] || '' }), {});
});
};
csvFileInput.addEventListener('change', async e => {
const file = e.target.files[0];
e.target.value = ''; // Clear input immediately
if (!file || !file.name.toLowerCase().endsWith('.csv')) {
return window.notify('warning', "Bitte wählen Sie eine gültige CSV-Datei aus.");
}
try {
const fileContent = await file.text();
const jsonData = csvToJson(fileContent);
if (jsonData.length === 0) {
return window.notify('warning', "CSV-Datei ist leer oder ungültig.");
}
if (!confirm("Sind Sie sicher, dass Sie die CSV-Daten importieren möchten?")) return;
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify(jsonData)
});
if (!response.ok) throw new Error(`HTTP error ${response.status}`);
const result = await response.json(); // Expect { created: N, updated: M, skipped: K }
window.notify('success', `Import erfolgreich: ${result.counts.created || 0} erstellt, ${result.counts.updated || 0} aktualisiert, ${result.counts.skipped || 0} übersprungen.`);
console.log("Response:", result);
} catch (error) {
console.error("Import Error:", error);
window.notify('error', 'Fehler beim Verarbeiten oder Importieren der CSV-Daten.');
}
});
});
</script>
<?php include(realpath(dirname(__FILE__)."/../../$mfLayoutPackage")."/footer.php"); ?>