App/obj/prozesse/object.php

579 lines
19 KiB
PHP

<?php
namespace Prozesse;
class Schritt
{
private $ID;
private $Sektion;
private $Name;
private $Optional;
private $Verantwortlich;
private $Von;
private $Wann;
private $Vornamen;
private $Nachnamen;
private $Notiz;
private $Unzutreffend;
private $VerantwortlicheName;
private $Indikatoren;
private $Helfer;
public $Nachfolger = [];
public $Vorgänger = [];
private $parent;
private $db;
private $man;
public function __construct($parent, $database, $manager, $data) {
$this->parent = $parent;
$this->db = $database;
$this->man = $manager;
$this->ID = $data["ID"];
$this->Sektion = $data["Sektion"];
$this->Name = $data["Name"];
$this->Optional = $data["Optional"];
$this->Verantwortlich = $data["Verantwortlich"];
$this->Von = null;
$this->Wann = is_null($data["Wann"]) ? null : date("d.m.Y", strtotime($data["Wann"]));
$this->Vornamen = $data["Vornamen"];
$this->Nachnamen = $data["Nachnamen"];
$this->Notiz = $data["Notiz"];
$this->Unzutreffend = $data["Unzutreffend"];
$this->VerantwortlicheName = $data["VerantwortlicheName"];
$this->Indikatoren = json_decode(""!=$data["Indikatoren"] ? $data["Indikatoren"] : "[]", true);
$this->Helfer = json_decode(""!=$data["Helfer"] ? $data["Helfer"] : "[]", true);
}
public function ID() {return $this->ID;}
public function Sektion() {return $this->Sektion;}
public function IsVerantwortlich() {return 1==$this->Verantwortlich;}
public function IsFertig() {return null!==$this->Wann;}
public function IsAktiv() {
foreach ($this->Vorgänger as $pre) {
if (!$pre["Vorgänger"]->IsFertig()) {
return false;
} }
return true;
}
private function getVorbedingungen() {
$ret = "";
foreach ($this->Vorgänger as $pre) {
if ($ret!="") {
$ret.= ", ";
}
$ret.= $pre["Vorgänger"]->Name;
}
return $ret;
}
private function getIndikatoren() {
$ret = [];
foreach ($this->Indikatoren as $indikator) {
switch ($indikator["check"]) {
case "PNRRANGE":
$success = true;
if (isset($indikator["max"]) && $this->parent->Pnr() > $indikator["max"]) {
$success = false;
}
if (isset($indikator["max"]) && $this->parent->Pnr() > $indikator["max"]) {
$success = false;
}
$ret[] = ["ERFOLG" => $success, "NAME" => $indikator["name"] ?? ""];
break;
} }
return $ret;
}
public function DoHelfer($id) {
$helfer = $this->Helfer[$id];
switch ($helfer["action"]) {
case "update":
switch ($helfer["table"]) {
case "Personal":
$qry = "UPDATE Personal SET ".$helfer["field"]." = ? WHERE ID=".$this->parent->ID();
$this->man->AddMessage($qry." - ".$this->man->input["helferValue"]);
$helferInput = $this->man->input["helferInput"][0] ?? "";
if ($stmt = $this->db->prepare($qry)) {
$stmt->bind_param("s", $this->man->input["helferValue"]);
if ($stmt->execute()) {
}
return 200;
} else {
$this->man->AddMessage("Mysql error: ".$this->db->error);
return 500;
}
}
break;
}
return 404;
}
private function getHelfer() {
$ret = [];
$id = 0;
foreach ($this->Helfer as $helfer) {
switch ($helfer["action"]) {
case "update":
$ret[] = ["ID" => $id, "NAME" => $helfer["name"]];
break;
}
$id++;
}
return $ret;
}
private function isReversierbar() {
foreach ($this->Nachfolger as $post) {
if ($post["Nachfolger"]->IsFertig() && !$post["Nachfolger"]->IsUnzutreffend()) {
return false;
} }
return true;
}
public function IsUnzutreffend() {return 1==$this->Optional && 1==$this->Unzutreffend;}
private function isOptional() {return 1==$this->Optional;}
public function Get() {
return [
"ID" => $this->ID,
"STATUS" => "__CASE__:".($this->IsFertig() ? ($this->IsUnzutreffend() ? "UNZUTREFFEND" : "FERTIG") : ($this->IsAktiv() ? "AKTIV" : "INAKTIV")),
"NAME" => $this->Name,
"VON" => (is_null($this->Vornamen) ? "" : preg_replace("/(?<![ -])\p{Ll}+/u", ".", $this->Vornamen)).$this->Nachnamen,
"WANN" => $this->Wann,
"NOTIZ" => $this->Notiz,
"REVERSIERBAR" => $this->isReversierbar(),
"OPTIONAL" => $this->isOptional(),
"TODO" => $this->IsVerantwortlich(),
"VORBEDINGUNG" => $this->getVorbedingungen(),
"INDIKATOREN" => $this->getIndikatoren(),
"HELFER" => $this->getHelfer(),
];
}
public function CheckStep($check) {
$Unzutreffend = $this->man->input["Unzutreffend"] ?? 0;
if ($check && ($this->IsAktiv() || 1==$Unzutreffend)) {
$qry = "INSERT INTO Prozesse_Fortschritte (Personal, Schritt, Wann, Von, Notiz, Unzutreffend) VALUES (?, ?, NOW(), ?, ?, ?)";
if ($stmt = $this->db->prepare($qry)) {
$Notiz = $this->man->input["Notiz"] ?? "";
$UserID = $this->man->user->ID();
$Personal = $this->parent->ID();
$stmt->bind_param("iiisi", $Personal, $this->ID, $UserID, $Notiz, $Unzutreffend);
$stmt->execute();
if (1==$stmt->affected_rows) {
$this->Von = $UserID;
$this->Wann = date("d.m.Y");
$this->Vornamen = $this->man->user->Vornamen();
$this->Nachnamen = $this->man->user->Nachnamen();
$this->Notiz = $Notiz;
$this->Unzutreffend = $Unzutreffend;
if (1==$Unzutreffend) {
foreach ($this->Nachfolger as $post) {
if (1==$post["Bedingung"]) {
$post["Nachfolger"]->CheckStep(true);
} } } }
} else {
$this->man->AddMessage("Mysql error: ".$this->db->error);
return 500;
}
} elseif (!$check && $this->IsFertig() && $this->isReversierbar()) {
$qry = "DELETE FROM Prozesse_Fortschritte WHERE Personal = ? AND Schritt = ?";
if ($stmt = $this->db->prepare($qry)) {
$Personal = $this->parent->ID();
$stmt->bind_param("ii", $Personal, $this->ID);
$stmt->execute();
if (1==$stmt->affected_rows) {
$this->Von = null;
$this->Wann = null;
$this->Vornamen = null;
$this->Nachnamen = null;
$this->Notiz = null;
$this->Unzutreffend = null;
}
} else {
$this->man->AddMessage("Mysql error: ".$this->db->error);
return 500;
} }
return 200;
}
}
class Person
{
private $ID;
private $Nachnamen;
private $Vornamen;
private $OFnr;
private $Pnr;
private $parent;
private $db;
private $man;
private $sektionen = [];
private $schritte = [];
public function __construct($parent, $database, $manager, $data) {
$this->parent = $parent;
$this->db = $database;
$this->man = $manager;
$this->ID = $data["ID"];
$this->Nachnamen = $data["Nachnamen"];
$this->Vornamen = $data["Vornamen"];
$this->OFnr = $data["OFnr"];
$this->Pnr = $data["Pnr"];
$this->loadSchritte();
$this->loadHierarchie();
}
public function ID() {return $this->ID;}
public function Pnr() {return $this->Pnr;}
private function loadSchritte() {
$qry = "SELECT zs.ID, zs.Sektion, zs.Name, zs.Optional, zs.Indikatoren, zs.Helfer, IF(pv.Personal IS NULL, 0, 1) Verantwortlich, zf.Wann, "
."p.Vornamen, p.Nachnamen, zf.Notiz, zf.Unzutreffend, sv.Name VerantwortlicheName "
."FROM Prozesse_Schritte zs "
."LEFT JOIN Prozesse_Fortschritte zf ON zf.Schritt=zs.ID AND zf.Personal=".$this->ID." "
."LEFT JOIN Personal p ON p.ID=zf.Von "
."LEFT JOIN Personal_Verwalter pv ON pv.Verwalter=zs.Verantwortliche AND pv.Personal=".$this->man->user->ID()." "
."LEFT JOIN Struktur_Verwalter sv ON sv.ID=zs.Verantwortliche "
."WHERE zs.Prozess = ".$this->parent->ID()." "
."ORDER BY zs.Sektion ASC ";
if ($res = $this->db->query($qry)) {
while ($schritt = $res->fetch_assoc()) {
$this->schritte[$schritt["ID"]] = new Schritt($this, $this->db, $this->man, $schritt);
$this->sektionen[$schritt["Sektion"]] = array();
}
} else {
$this->man->AddMessage("Mysql error: ".$this->db->error);
}
}
private function loadHierarchie() {
$qry = "SELECT zh.Schritt, zh.Vorgänger, zh.Bedingung "
."FROM Prozesse_Hierarchie zh "
."LEFT JOIN Prozesse_Schritte zs ON zs.ID=zh.Schritt "
."WHERE zs.Prozess = ".$this->parent->ID();
if ($res = $this->db->query($qry)) {
while ($schritt = $res->fetch_assoc()) {
if (array_key_exists($schritt["Schritt"], $this->schritte) && array_key_exists($schritt["Vorgänger"], $this->schritte)) {
$this->schritte[$schritt["Schritt"]]->Vorgänger[] = array(
"Vorgänger" => &$this->schritte[$schritt["Vorgänger"]],
"Bedingung" => $schritt["Bedingung"],
);
$this->schritte[$schritt["Vorgänger"]]->Nachfolger[] = array(
"Nachfolger" => &$this->schritte[$schritt["Schritt"]],
"Bedingung" => $schritt["Bedingung"],
);
}
}
} else {
$this->man->AddMessage("Mysql error: ".$this->db->error);
}
$selectedIDs = array();
for ($i = 0; $i<count($this->schritte); $i++) {
foreach ($this->schritte as $ID => $values) {
if (!in_array($ID, $selectedIDs)) {
//Not selected yet. Check if pre-conditions have been selected
$pass = true;
foreach ($this->schritte[$ID]->Vorgänger as $pre) {
if (!in_array($pre["Vorgänger"]->ID(), $selectedIDs)) {
$pass = false;
} }
if ($pass) {
$this->sektionen[$values->Sektion()][] = &$this->schritte[$ID];
$selectedIDs[] = $ID;
break;
} } } } }
private function isVollständig() {
foreach ($this->schritte as $schritt) {
if (!$schritt->IsFertig()) {
return false;
} }
return true;
}
private function canFehlschlagen() {
return (sizeof($this->parent->Fehlschlag())>0);
}
public function hasTodo() {
foreach ($this->schritte as $schritt) {
if ($schritt->IsVerantwortlich() && $schritt->IsAktiv()) {
return true;
} }
return false;
}
private function getFortschritt() {
$gesamt = 0;
$fertig = 0;
foreach ($this->schritte as $schritt) {
$gesamt++;
if ($schritt->IsFertig()) {
$fertig++;
} }
return $fertig."/".$gesamt;
}
public function Get() {
$ret = [
"ID" => $this->parent->ID()."_".$this->ID,
"MAIN" => [
"NACHNAMEN" => $this->Nachnamen,
"VORNAMEN" => $this->Vornamen,
"FORTSCHRITT" => $this->getFortschritt(),
"TODO" => $this->hasTodo(),
],
"SUB" => [
"SEKTION" => [],
"ERFOLG" => $this->isVollständig(),
"FEHLSCHLAG" => $this->canFehlschlagen()
]
];
foreach ($this->sektionen as $sektion => $sekschritte) {
$ret_sektion = ["NAME" => $sektion, "SCHRITT" => []];
foreach ($sekschritte as $schritt) {
$ret_sektion["SCHRITT"][] = $schritt->Get();
}
$ret["SUB"]["SEKTION"][] = $ret_sektion;
}
return $ret;
}
public function Finish($mode) {
$liste = [];
$protokoll = [];
switch ($mode) {
case "Success":
if (!$this->isVollständig()) {
$this->man->AddMessage("Der Prozess ist noch nicht vollständig abgeschlossen!");
return 403;
}
$liste = $this->parent->Erfolg();
$protokoll[] = "Prozess ".$this->parent->Name()." erfolgreich für ".$this->Vornamen." ".$this->Nachnamen;
break;
case "Fail":
$liste = $this->parent->Fehlschlag();
$protokoll[] = "Prozess ".$this->parent->Name()." abgebrochen für ".$this->Vornamen." ".$this->Nachnamen;
break;
default:
return 400;
}
if (sizeof($liste)==0) {
$this->man->AddMessage("Keine Aktionen definiert. Dieser Prozess lässt sich so nicht beenden!");
return 400;
}
$protokoll[] = "";
$protokoll[] = "<h3>Ausgeführte Aktionen:</h3>";
foreach ($liste as $aktion) {
switch ($aktion["action"]) {
case "group_add":
$this->db->query("INSERT INTO Personal_Gruppen (Personal, Gruppen) VALUES (".$this->ID.", ".$aktion["group"].")");
$this->man->AddMessage("Die Person wurde einer neuen Gruppe zugeordnet. Ist sie dadurch in einem neuen Prozess, "
."wird dieser erst bei Aktualisieren der Seite angezeigt");
$protokoll[] = "Personal wurde Gruppe mit ID ".$aktion["group"]." zugeordnet.";
break;
case "group_remove":
$this->db->query("DELETE FROM Personal_Gruppen WHERE Personal=".$this->ID." AND Gruppen=".$aktion["group"]);
$protokoll[] = "Personal wurde aus Gruppe mit ID ".$aktion["group"]." entfernt.";
break;
case "user_remove":
$this->db->query("DELETE FROM Personal WHERE ID=".$this->ID);
$this->man->AddMessage("Die Person wurde vollständig aus dem System gelöscht!");
$protokoll[] = "Personal wurde vollständig aus System gelöscht.";
break;
case "user_chgcategory":
$this->db->query("UPDATE Personal SET Kategorie='".$aktion["category"]."' WHERE ID=".$this->ID);
$this->man->AddMessage("Personal wurde in andere Kategroie verschoben!");
$protokoll[] = "Personal wurde vollständig aus System gelöscht.";
break;
}
}
$protokoll[] = "";
$protokoll[] = "<h3>Protokoll der Prozesschritte:</h3>";
foreach ($this->sektionen as $sektion => $sekschritte) {
$protokoll[] = "<u>Sektion: ".$sektion."</u>";
foreach ($sekschritte as $schritt) {
$data = $schritt->Get();
$status = explode(":", $data["STATUS"])[1];
$protokoll[] = $data["NAME"].": "
.($status=="AKTIV" || $status=="INAKTIV"
? "<span color='red'>Nicht abgeschlossen</span>"
: "<span color='green'>".$status."</span>, Von: ".$data["VON"].", Wann: ".$data["WANN"].", Notiz: ".$data["NOTIZ"]);
} }
emlSendEmail("nils.otterpohl@feuerwehr-bs.net", $protokoll[0], implode("<br/>", $protokoll));
emlSendEmail("verwaltung@fw-innenstadt.de", $protokoll[0], implode("<br/>", $protokoll));
return 200;
}
public function CheckStep($schritt, $check) {
return (isset($this->schritte[$schritt]) ? $this->schritte[$schritt]->CheckStep($check) : 404);
}
public function DoHelfer($schritt, $helfer) {
return (isset($this->schritte[$schritt]) ? $this->schritte[$schritt]->DoHelfer($helfer) : 404);
}
}
class Prozess
{
private $parent;
private $db;
private $man;
private $personen = [];
private $ID;
private $Name;
private $Erfolg;
private $Fehlschlag;
public function __construct($parent, $database, $manager, $data, $id) {
$this->parent = $parent;
$this->db = $database;
$this->man = $manager;
$this->ID = $data["ID"];
$this->Name = $data["Name"];
$this->Erfolg = json_decode(""!=$data["Erfolg"] ? $data["Erfolg"] : "[]", true);
$this->Fehlschlag = json_decode(""!=$data["Fehlschlag"] ? $data["Fehlschlag"] : "[]", true);
$qry = "SELECT p.ID, p.OFnr, p.Pnr, p.Nachnamen, p.Vornamen "
."FROM Personal p "
.$this->getWhereFromTarget($id, $data["Ziel"])
."ORDER BY Nachnamen ASC, Vornamen ASC ";
if ($res = $this->db->query($qry)) {
$i = 0;
while ($person = $res->fetch_assoc()) {
$this->personen[$person["ID"]] = new Person($this, $database, $manager, $person);
}
} else {
echo $this->db->error;
}
}
public function ID() {return $this->ID;}
public function Name() {return $this->Name;}
public function Erfolg() {return $this->Erfolg;}
public function Fehlschlag() {return $this->Fehlschlag;}
private function getWhereFromTarget($id, $target) {
$joins = [];
$wheres = [];
$ret = "";
if (null!==$id) {
$wheres[] = "p.ID=".$id;
}
$json = json_decode($target, true);
foreach ($json as $val) {
switch ($val["condition"]) {
case "group_member":
$joins[] = "LEFT JOIN Personal_Gruppen pg ON pg.Personal=p.ID";
$wheres[] = "pg.Gruppen=".$val["group"];
break;
case "cat_member":
$wheres[] = "p.Kategorie=".$val["category"];
break;
} }
foreach ($joins as $join) {$ret.= $join." ";}
foreach ($wheres as $num => $where) {$ret.= ($num==0 ? "WHERE " : "AND ").$where." ";}
return $ret;
}
public function Get() {
$ret = [];
foreach ($this->personen as $person) {
$entry = $person->Get();
$entry["MAIN"]["PROZESS"] = $this->Name;
$entry["GROUP"] = $this->Name;
$ret[] = $entry;
}
return $ret;
}
public function Finish($id, $mode) {
if (isset($this->personen[$id])) {
return $this->personen[$id]->Finish($mode);
}
$this->man->AddMessage("Personal nicht gefunden!");
return 404;
}
public function CheckStep($schritt, $check) {
$key = array_key_first($this->personen);
return $this->personen[$key]->CheckStep($schritt, $check);
}
public function DoHelfer($schritt, $helfer) {
$key = array_key_first($this->personen);
return $this->personen[$key]->DoHelfer($schritt, $helfer);
}
}
class Liste
{
private $db;
private $man;
private $prozesse = [];
public function __construct($database, $manager, $id = null) {
$this->db = $database;
$this->man = $manager;
$split_id = isset($id) ? explode("_", $id) : [null, null];
$qry = "SELECT ID, Name, Ziel, Erfolg, Fehlschlag FROM Prozesse".(is_null($split_id[0]) ? "" : " WHERE ID=".$split_id[0]);
if ($res = $this->db->query($qry)) {
while ($prozess = $res->fetch_assoc()) {
$this->prozesse[$prozess["ID"]] = new Prozess($this, $database, $manager, $prozess, $split_id[1] ?? null);
}
}
}
public function Get() {
$ret = [];
foreach ($this->prozesse as $ID => $prozess) {
$ret[] = ["ID" => $prozess->Name(), "ENTRIES" => $prozess->Get()];
//$ret = array_merge($ret, $prozess->Get());
}
return (null!==$this->man->Main() && sizeof($ret)>0 ? $ret[0]["ENTRIES"][0] : $ret);
}
public function Finish($id, $mode) {
$split_id = isset($id) ? explode("_", $id) : [null, null];
if (isset($split_id[0], $split_id[1], $this->prozesse[$split_id[0]])) {
return $this->prozesse[$split_id[0]]->Finish($split_id[1], $mode);
}
$this->man->AddMessage("Prozess nicht gefunden! ".$id." ".$this->man->ArrayToString($split_id));
return (isset($split_id[0]) ? 404 : 400);
}
public function CheckStep($schritt, $check) {
$key = array_key_first($this->prozesse);
return $this->prozesse[$key]->CheckStep($schritt, $check);
}
public function DoHelfer($schritt, $helfer) {
$key = array_key_first($this->prozesse);
return $this->prozesse[$key]->DoHelfer($schritt, $helfer);
}
}