Warehouse project/fix

This commit is contained in:
Luca Haid
2025-12-03 14:08:44 +00:00
parent ff070bac73
commit 594a926262
10 changed files with 1560 additions and 735 deletions

View File

@@ -65,6 +65,81 @@ class WorkorderMphBaseController extends TTCrud
self::returnJson(['docs' => $responseDocs, 'journals' => $journals]);
}
/**
* Upload documentation for the Workorder itself (not Wohneinheit).
*/
protected function uploadDocumentationAction()
{
if (empty($_FILES['files']) && empty($_FILES['file'])) self::sendError('Erforderliche Daten fehlen.');
if (empty($_POST['workorderMphId'])) self::sendError('Workorder ID fehlt.');
$workorderMphId = intval($_POST['workorderMphId']);
$uploadedCount = 0;
// Handle multiple files (files[])
if (!empty($_FILES['files'])) {
foreach ($_FILES['files']['name'] as $index => $name) {
if ($_FILES['files']['error'][$index] === UPLOAD_ERR_OK) {
// Mock the $_FILES entry for handleFormUpload
$_FILES['single_upload_file'] = [
'name' => $name,
'type' => $_FILES['files']['type'][$index],
'tmp_name' => $_FILES['files']['tmp_name'][$index],
'error' => $_FILES['files']['error'][$index],
'size' => $_FILES['files']['size'][$index]
];
try {
$uploaded = mfUpload::handleFormUpload("single_upload_file", false, "/WorkorderMph");
WorkorderMphDocumentationModel::create([
'workorderMphId' => $workorderMphId,
'fileId' => $uploaded->id,
'description' => $_POST['description'] ?? '',
'documentType' => $_POST['documentType'] ?? 'other',
'create' => time(),
'createBy' => $this->user->id
]);
$uploadedCount++;
} catch (Exception $e) {
// Log error
}
}
}
}
// Handle single file (file) - fallback or primary if JS sends single
elseif (!empty($_FILES['file'])) {
try {
$uploaded = mfUpload::handleFormUpload("file", false, "/WorkorderMph");
WorkorderMphDocumentationModel::create([
'workorderMphId' => $workorderMphId,
'fileId' => $uploaded->id,
'description' => $_POST['description'] ?? '',
'documentType' => $_POST['documentType'] ?? 'other',
'create' => time(),
'createBy' => $this->user->id
]);
$uploadedCount++;
} catch (Exception $e) {
self::sendError("Upload fehlgeschlagen: " . $e->getMessage());
}
}
if ($uploadedCount > 0) {
self::returnJson(['success' => true, 'message' => "$uploadedCount Datei(en) erfolgreich hochgeladen."]);
} else {
self::sendError("Keine Dateien wurden hochgeladen.");
}
}
/**
* Delete Workorder documentation
*/
protected function deleteDocumentationAction()
{
if (empty($this->postData['documentationId'])) self::sendError("Dokumentations-ID fehlt.");
WorkorderMphDocumentationModel::delete($this->postData['documentationId']);
self::returnJson(['success' => true, 'message' => 'Dokument gelöscht.']);
}
/**
* Adds a new entry to a workorder's journal.
*/
@@ -139,14 +214,15 @@ class WorkorderMphBaseController extends TTCrud
$sql = "SELECT w.id, w.zusatz, w.tuer, w.contact, w.oaid, w.note, w.status_id, w.splice_hak_completed
FROM Wohneinheit w
WHERE w.hausnummer_id = $hausnummerId
ORDER BY w.zusatz";
ORDER BY w.oaid ASC";
$result = $db->query($sql);
$wohneinheiten = $result ? $result->fetch_all(MYSQLI_ASSOC) : [];
// Get Preorders for this Hausnummer to fallback contact info
$preorders = [];
if (class_exists('PreorderModel')) {
$preorderList = PreorderModel::search(['adb_hausnummer_id' => $workorder->hausnummerId, 'deleted' => 0]);
// Use searchActive to filter out canceled preorders (status_code = 20)
$preorderList = PreorderModel::searchActive(['adb_hausnummer_id' => $workorder->hausnummerId]);
foreach ($preorderList as $preorder) {
if ($preorder->adb_wohneinheit_id) {
$preorders[$preorder->adb_wohneinheit_id] = $preorder;
@@ -161,21 +237,30 @@ class WorkorderMphBaseController extends TTCrud
$contact = $we['contact'];
$preorderContact = null;
$preorderUcode = null;
if (isset($preorders[$we['id']])) {
$p = $preorders[$we['id']];
$preorderUcode = $p->ucode;
$pContact = trim($p->firstname . ' ' . $p->lastname);
if ($p->phone) $pContact .= ' (' . $p->phone . ')';
$preorderContact = $pContact;
// If address contact is empty, use preorder contact
if (empty($contact)) {
$contact = $pContact;
}
}
// Get document count for this Wohneinheit
$docCountSql = "SELECT COUNT(*) as cnt FROM WohneinheitDocumentation WHERE wohneinheit_id = " . $db->escape($we['id']);
$docCountResult = $db->query($docCountSql);
$documentCount = 0;
if ($docCountResult) {
$docCountRow = $docCountResult->fetch_assoc();
$documentCount = intval($docCountRow['cnt']);
}
$response[] = [
'wohneinheitId' => intval($we['id']),
'zusatz' => $we['zusatz'],
@@ -187,6 +272,7 @@ class WorkorderMphBaseController extends TTCrud
'status' => intval($we['status_id']),
'spliceCompleted' => intval($we['splice_hak_completed'] ?? 0),
'note' => $we['note'],
'documentCount' => $documentCount,
];
}
@@ -214,6 +300,11 @@ class WorkorderMphBaseController extends TTCrud
$tuer = $post['tuer'] ?? null;
$zusatz = $post['zusatz'] ?? null;
// Validate that "Tür" field is not empty if it's being set
if ($tuer !== null && trim($tuer) === '') {
self::sendError("Das Feld 'Tür' darf nicht leer sein.");
}
$db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
$escapedWohneinheitId = $db->escape($wohneinheitId);
@@ -315,6 +406,93 @@ class WorkorderMphBaseController extends TTCrud
}
}
/**
* Get documents for a specific Wohneinheit
*/
protected function getWohneinheitDocumentsAction()
{
if (empty($this->request->wohneinheitId)) self::sendError("Wohneinheit-ID fehlt.");
$wohneinheitId = intval($this->request->wohneinheitId);
$db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
$sql = "SELECT * FROM WohneinheitDocumentation WHERE wohneinheit_id = " . $db->escape($wohneinheitId) . " ORDER BY `create` ASC";
$result = $db->query($sql);
$docs = $result ? $result->fetch_all(MYSQLI_ASSOC) : [];
$responseDocs = [];
foreach ($docs as $doc) {
$file = new File($doc['fileId']);
$responseDocs[] = [
'id' => $doc['id'],
'fileId' => $doc['fileId'],
'fileName' => $file->orig_filename ?? $file->filename,
'description' => $doc['description'],
'documentType' => $doc['documentType'],
'userName' => UserModel::getOne($doc['createBy'])->name ?? 'Unbekannt',
'mimetype' => $file->mimetype ?? 'application/octet-stream',
'create' => $doc['create']
];
}
self::returnJson(['docs' => $responseDocs]);
}
/**
* Upload document for a specific Wohneinheit
*/
protected function uploadWohneinheitDocumentAction()
{
if (empty($_FILES['file']) || empty($_POST['wohneinheitId'])) {
self::sendError("Datei und Wohneinheit-ID sind erforderlich.");
}
$wohneinheitId = intval($_POST['wohneinheitId']);
$documentType = $_POST['documentType'] ?? 'photo';
$description = $_POST['description'] ?? null;
// Upload file using mfUpload handleFormUpload for proper handling
try {
$upload = mfUpload::handleFormUpload("file", false, "/WorkorderMph/Wohneinheit");
$file = $upload; // handleFormUpload returns the File object
} catch (Exception $e) {
self::sendError("Datei-Upload fehlgeschlagen: " . $e->getMessage());
return;
}
// Insert into WohneinheitDocumentation table in addressdb
$db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
$escapedWohneinheitId = $db->escape($wohneinheitId);
$escapedFileId = $db->escape($file->id);
$escapedDescription = $description ? "'" . $db->escape($description) . "'" : "NULL";
$escapedDocumentType = "'" . $db->escape($documentType) . "'";
$escapedCreateBy = $db->escape($this->user->id);
$escapedCreate = time();
$sql = "INSERT INTO WohneinheitDocumentation (wohneinheit_id, fileId, description, documentType, `create`, createBy)
VALUES ($escapedWohneinheitId, $escapedFileId, $escapedDescription, $escapedDocumentType, $escapedCreate, $escapedCreateBy)";
$db->query($sql);
self::returnJson(['success' => true, 'message' => 'Dokument erfolgreich hochgeladen.', 'fileId' => $file->id]);
}
/**
* Delete document for a specific Wohneinheit
*/
protected function deleteWohneinheitDocumentAction()
{
if (empty($this->postData['documentationId'])) self::sendError("Dokumentations-ID fehlt.");
$documentationId = intval($this->postData['documentationId']);
$db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
$escapedId = $db->escape($documentationId);
$sql = "DELETE FROM WohneinheitDocumentation WHERE id = $escapedId";
$db->query($sql);
self::returnJson(['success' => true, 'message' => 'Dokument gelöscht.']);
}
/**
* Update checkbox documentation fields
*/
@@ -327,17 +505,25 @@ class WorkorderMphBaseController extends TTCrud
if (!$workorder) self::sendError("Arbeitsauftrag nicht gefunden.");
$changes = [];
$checkboxFields = ['easement', 'btb', 'fttxLocationSupplied', 'conduitToHuepLaid', 'huepMounted', 'dropCableAvailable', 'spliceCompleted'];
$checkboxFields = [
'easement' => 'Leitungsrecht',
'btb' => 'Bautechnische Begehung',
'fttxLocationSupplied' => 'FTTx Location mit Leerrohr versorgt',
'conduitToHuepLaid' => 'Leerrohr bis HÜP/HAK verlegt',
'huepMounted' => 'HÜP/HAK montiert',
'dropCableAvailable' => 'Dropkabel vorhanden',
'spliceCompleted' => 'Spleiß abgeschlossen'
];
$updateHausnummerStatus = false;
foreach ($checkboxFields as $field) {
foreach ($checkboxFields as $field => $fieldLabel) {
if (array_key_exists($field, $post)) {
$oldValue = $workorder->$field;
$newValue = $post[$field] ? 1 : 0;
if ($oldValue !== $newValue) {
$workorder->$field = $newValue;
$changes[] = "$field: " . ($newValue ? 'ja' : 'nein');
$changes[] = "$fieldLabel: " . ($newValue ? 'ja' : 'nein');
// Check for FTTx Location mit Leerrohr versorgt
if ($field === 'fttxLocationSupplied' && $newValue === 1) {
@@ -374,4 +560,4 @@ class WorkorderMphBaseController extends TTCrud
self::returnJson(['success' => true, 'message' => 'Dokumentation aktualisiert.']);
}
//endregion
}
}