Merge branch 'fronkdev' into 'master'

Added Borderpoint status to Preorder

See merge request fronk/thetool!1311
This commit is contained in:
Frank Schubert
2025-05-07 16:33:42 +00:00
9 changed files with 336 additions and 143 deletions

View File

@@ -204,6 +204,16 @@ $pagination_entity_name = "Vorbestellungen";
</select>
</div>
<div class="col-sm-12 col-md-2">
<label class="form-label" for="filter_borderpoint_status">Borderpoint Status</label>
<select name="filter[borderpoint_status]" id="filter_borderpoint_status" class="form-control">
<option></option>
<option value="need_measurement" <?=(isset($filter) && array_key_exists("borderpoint_status", $filter) && $filter["borderpoint_status"] == "need_measurement") ? "selected='selected'" : ""?>>Messung erforderlich</option>
<option value="informed" <?=(isset($filter) && array_key_exists("borderpoint_status", $filter) && $filter["borderpoint_status"] == "informed") ? "selected='selected'" : ""?>>Beauskunftet</option>
<option value="need_digging" <?=(isset($filter) && array_key_exists("borderpoint_status", $filter) && $filter["borderpoint_status"] == "need_digging") ? "selected='selected'" : ""?>>Grabung ausständig</option>
</select>
</div>
<div class="col-sm-12 col-md-2">
<label class="form-label" for="connection_type">Anschlusstyp</label>
<select name="filter[connection_type][]" id="connection_type_id" class="form-control" multiple="multiple">
@@ -1336,6 +1346,74 @@ $pagination_entity_name = "Vorbestellungen";
'json');
}
/*
* Toggle Borderpoint status radio buttons on/off
*/
// get and save initial radio button states
var bpstatus_radiostate = [];
$("input[name^='borderpoint_status_']").each(function(i) {
let match = $(this).attr("name").match(/_(\d+)$/);
let pid = match[1];
bpstatus_radiostate[pid + "-" + $(this).val()] = $(this).is(":checked");
});
// if saved value is checked => uncheck
$("input[name^='borderpoint_status_']").click(async (e) => {
var radio = $(e.target);
var val = radio.val();
console.log(radio.attr("name"));
let match = radio.attr("name").match(/_(\d+)$/);
if(!match || !match[1]) {
return;
}
let pid = match[1];
var new_status;
if(bpstatus_radiostate[pid + "-" + val]) {
new_status = false;
radio.prop("checked", false);
bpstatus_radiostate[pid + "-" + val] = false;
} else {
new_status = true;
radio.prop("checked", true);
for(const [key, value] of Object.entries(bpstatus_radiostate)) {
if(key.startsWith(pid + "-")) {
bpstatus_radiostate[key] = false;
}
}
bpstatus_radiostate[pid + "-" + val] = true;
}
// save new status
await fetch("<?=self::getUrl("Preorder", "Api")?>", {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: new URLSearchParams({
do: "saveBorderpointStatus",
preorder_id: pid,
status_type: val,
value: new_status ? 1 : 0
})
}).then(resp => {
if(resp.ok) {
return resp.json();
}
}).then((data) => {
console.log(data);
console.log(pid);
if(data.status == "OK") {
window.notify("success", "Borderpoint Status gespeichert");
} else {
window.notify("error", "Fehler beim Speichern des Borderpoint Status");
}
});
});
function createWorkorder(pid) {
if(!Number.isInteger(pid) || pid < 1) {
return false;

View File

@@ -378,131 +378,133 @@
<div class="row">
<div class="col-6">
<h3>Metadaten</h3>
<table class="table table-sm table-striped">
<tr>
<th>Building Name:</th>
<td class="text-monospace"><?=$preorder->adb_hausnummer->extref?>
</tr><tr>
<th>Building External ID:</th>
<td class="text-monospace"><?=$preorder->adb_hausnummer->rimo_id?>
</tr><tr>
<th>Building Execution State:</th>
<td class="text-monospace"><?=$preorder->adb_hausnummer->rimo_ex_state?>
</tr><tr>
<th>Building Operational State:</th>
<td class="text-monospace"><?=($preorder->adb_hausnummer->rimo_op_state != "Undefined") ? $preorder->adb_hausnummer->rimo_op_state : ""?>
</tr><tr>
<th>Home External ID:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->extref?>
</tr><tr>
<th>Home Execution State:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->rimo_ex_state?>
</tr><tr>
<th>Home Operational State:</th>
<td class="text-monospace"><?=($preorder->adb_wohneinheit->rimo_op_state != "Undefined") ? $preorder->adb_wohneinheit->rimo_op_state : ""?>
</tr>
</table>
<div class="row col">
<h3>Metadaten</h3>
<table class="table table-sm table-striped">
<tr>
<th>Building Name:</th>
<td class="text-monospace"><?=$preorder->adb_hausnummer->extref?>
</tr><tr>
<th>Building External ID:</th>
<td class="text-monospace"><?=$preorder->adb_hausnummer->rimo_id?>
</tr><tr>
<th>Building Execution State:</th>
<td class="text-monospace"><?=$preorder->adb_hausnummer->rimo_ex_state?>
</tr><tr>
<th>Building Operational State:</th>
<td class="text-monospace"><?=($preorder->adb_hausnummer->rimo_op_state != "Undefined") ? $preorder->adb_hausnummer->rimo_op_state : ""?>
</tr><tr>
<th>Home External ID:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->extref?>
</tr><tr>
<th>Home Execution State:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->rimo_ex_state?>
</tr><tr>
<th>Home Operational State:</th>
<td class="text-monospace"><?=($preorder->adb_wohneinheit->rimo_op_state != "Undefined") ? $preorder->adb_wohneinheit->rimo_op_state : ""?>
</tr>
</table>
</div>
<div class="row">
<div class="col workorder-container">
<h3>Workorder</h3>
<?php if($preorder->adb_wohneinheit_id && is_array($preorder->adb_wohneinheit->rimo_workorders) && count($preorder->adb_wohneinheit->rimo_workorders)): ?>
<?php foreach($preorder->adb_wohneinheit->rimo_workorders as $wo): ?>
<h4>
<?=$wo->rimo_name?>
<a href="<?=self::getUrl("RimoWorkorder", "downloadAh", ["id" => $wo->id])?>" onclick="event.preventDefault(); downloadWorkorderAha(<?=$wo->id?>);"><i class="fas fa-fw fa-file-download ml-2"></i> AHA Blatt</a>
</h4>
<small id="preorder-detail-<?=$preorder->id?>-workorder-<?=$wo->id?>-del"><a href="#" onclick="if(confirm('Achtung: Löscht die Workorder in thetool, aber NICHT in RIMO!')) return deleteWorkorder(<?=$preorder->id?>, <?=$wo->id?>)" class="text-danger"><i class="far fa-times-circle"></i> Workorder löschen</a></small>
<table class="table table-sm table-striped" id="preorder-detail-<?=$preorder->id?>-workorder-<?=$wo->id?>">
<tr>
<th>Name</th>
<td class="text-monospace"><?=$wo->rimo_name?></td>
</tr><tr>
<th>External ID</th>
<td class="text-monospace"><?=$wo->rimo_id?></td>
</tr><tr>
<th>Status</th>
<td><?=$wo->rimo_status?></td>
</tr>
<?php if($wo->rimo_team_name): ?>
<tr>
<th>Zugewiesen an:</th>
<td><?=$wo->rimo_team_name?></td>
</tr>
<?php endif; ?>
<tr>
<th>Erstellt</th>
<td class="text-monospace"><?=date("d.m.Y H:i:s", $wo->create)?></td>
</tr>
<tr>
<th>Bemerkung</th>
<td id="wo-remark-<?=$preorder->id?>-<?=$wo->id?>">
<div class="input-group mb-2">
<input type="text" class="form-control" name="new_remark" placeholder="Bemerkung hinzufügen" />
<div class="input-group-append">
<button class="btn btn-primary" type="button" id="button-addon2" onclick="saveRemark(<?=$preorder->id?>, <?=$wo->id?>)">Hinzufügen</button>
</div>
</div>
<div class="remark-text border p-1 text-monospace" id="preorder-detail-<?=$preorder->id?>-workorder-<?=$wo->id?>-remarks">
<?=nl2br(htmlentities($wo->remarks))?>
</div>
</td>
</tr>
</table>
<?php endforeach; ?>
<?php else: ?>
<button type="button" class="btn btn-outline-primary create-workorder" onclick="createWorkorder(<?=$preorder->id?>)"><i class="fas fa-fw fa-plus"></i> <i class="fas fa-r"></i><i class="fas fa-fw fa-gears"></i> Wokorder erstellen</button>
<?php endif; ?>
</div>
</div>
</div>
<div class="col-6">
<h3>FTU</h3>
<table class="table table-sm table-striped">
<tr>
<th>FTU Name:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->ftu_data["name"]?>
</tr><tr>
<th>FTU External ID:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->ftu_data["id"]?>
</tr>
</table>
<h3>FCP</h3>
<?php
if($preorder->fcp): ?>
<div class="row col">
<h3>FTU</h3>
<table class="table table-sm table-striped">
<tr>
<th>FCP Name:</th>
<td class="text-monospace"><?=$preorder->fcp->name?>
</tr><tr>
<th>FCP External ID:</th>
<td class="text-monospace"><?=$preorder->fcp->rimo_id?>
</tr>
<tr>
<th>FCP Execution State:</th>
<td class="text-monospace"><?=$preorder->fcp->rimo_ex_state?>
</tr><tr>
<th>FCP Operational State:</th>
<td class="text-monospace"><?=($preorder->fcp->rimo_op_state != "Undefined") ? $preorder->fcp->rimo_op_state : ""?>
</tr><tr>
<th>FCP Building Type:</th>
<td class="text-monospace"><?=$preorder->fcp->building_type?>
</tr>
<tr>
<th>FTU Name:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->ftu_data["name"]?>
</tr><tr>
<th>FTU External ID:</th>
<td class="text-monospace"><?=$preorder->adb_wohneinheit->ftu_data["id"]?>
</tr>
</table>
<?php else: ?>
<p>Kein FCP zugewiesen</p>
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col-6 workorder-container">
<h3>Workorder</h3>
<?php if($preorder->adb_wohneinheit_id && is_array($preorder->adb_wohneinheit->rimo_workorders) && count($preorder->adb_wohneinheit->rimo_workorders)): ?>
<?php foreach($preorder->adb_wohneinheit->rimo_workorders as $wo): ?>
<h4>
<?=$wo->rimo_name?>
<a href="<?=self::getUrl("RimoWorkorder", "downloadAh", ["id" => $wo->id])?>" onclick="event.preventDefault(); downloadWorkorderAha(<?=$wo->id?>);"><i class="fas fa-fw fa-file-download ml-2"></i> AHA Blatt</a>
</h4>
<small id="preorder-detail-<?=$preorder->id?>-workorder-<?=$wo->id?>-del"><a href="#" onclick="if(confirm('Achtung: Löscht die Workorder in thetool, aber NICHT in RIMO!')) return deleteWorkorder(<?=$preorder->id?>, <?=$wo->id?>)" class="text-danger"><i class="far fa-times-circle"></i> Workorder löschen</a></small>
<table class="table table-sm table-striped" id="preorder-detail-<?=$preorder->id?>-workorder-<?=$wo->id?>">
<h3>FCP</h3>
<?php
if($preorder->fcp): ?>
<table class="table table-sm table-striped">
<tr>
<th>Name</th>
<td class="text-monospace"><?=$wo->rimo_name?></td>
<th>FCP Name:</th>
<td class="text-monospace"><?=$preorder->fcp->name?>
</tr><tr>
<th>External ID</th>
<td class="text-monospace"><?=$wo->rimo_id?></td>
<th>FCP External ID:</th>
<td class="text-monospace"><?=$preorder->fcp->rimo_id?>
</tr>
<tr>
<th>FCP Execution State:</th>
<td class="text-monospace"><?=$preorder->fcp->rimo_ex_state?>
</tr><tr>
<th>Status</th>
<td><?=$wo->rimo_status?></td>
</tr>
<?php if($wo->rimo_team_name): ?>
<tr>
<th>Zugewiesen an:</th>
<td><?=$wo->rimo_team_name?></td>
</tr>
<?php endif; ?>
<tr>
<th>Erstellt</th>
<td class="text-monospace"><?=date("d.m.Y H:i:s", $wo->create)?></td>
</tr>
<tr>
<th>Bemerkung</th>
<td id="wo-remark-<?=$preorder->id?>-<?=$wo->id?>">
<div class="input-group mb-2">
<input type="text" class="form-control" name="new_remark" placeholder="Bemerkung hinzufügen" />
<div class="input-group-append">
<button class="btn btn-primary" type="button" id="button-addon2" onclick="saveRemark(<?=$preorder->id?>, <?=$wo->id?>)">Hinzufügen</button>
</div>
</div>
<div class="remark-text border p-1 text-monospace" id="preorder-detail-<?=$preorder->id?>-workorder-<?=$wo->id?>-remarks">
<?=nl2br(htmlentities($wo->remarks))?>
</div>
</td>
<th>FCP Operational State:</th>
<td class="text-monospace"><?=($preorder->fcp->rimo_op_state != "Undefined") ? $preorder->fcp->rimo_op_state : ""?>
</tr><tr>
<th>FCP Building Type:</th>
<td class="text-monospace"><?=$preorder->fcp->building_type?>
</tr>
</table>
<?php endforeach; ?>
<?php else: ?>
<p>Kein FCP zugewiesen</p>
<?php endif; ?>
<?php else: ?>
<button type="button" class="btn btn-outline-primary create-workorder" onclick="createWorkorder(<?=$preorder->id?>)"><i class="fas fa-fw fa-plus"></i> <i class="fas fa-r"></i><i class="fas fa-fw fa-gears"></i> Wokorder erstellen</button>
<?php endif; ?>
</div>
</div>
<div class="col-6">
<div class="row col">
<h3>
Patchposition
<?php if($preorder->adb_wohneinheit_id): ?>
@@ -559,6 +561,7 @@
</div>
</div>
</div>
</div>
</div>
<div id="preorder-detail-<?=$preorder->id?>-flags" class="tab-pane">
@@ -570,16 +573,47 @@
<div class="row">
<div class="col-6">
<h3>Bestellstatus</h3>
<table class="table table-sm table-striped">
<tr>
<th>Status Code</th>
<td class="text-monospace"><?=$preorder->status->code?></td>
</tr><tr>
<th>Status Text</th>
<td class="text-monospace"><?=$preorder->status->name?></td>
</tr>
</table>
<div class="row">
<div class="col">
<h3>Bestellstatus</h3>
<table class="table table-sm table-striped">
<tr>
<th>Status Code</th>
<td class="text-monospace"><?=$preorder->status->code?></td>
</tr><tr>
<th>Status Text</th>
<td class="text-monospace"><?=$preorder->status->name?></td>
</tr>
</table>
</div>
</div>
<div class="row">
<div class="col">
<h3>Borderpoint Status</h3>
<div class="row">
<div class="col-3 text-center">
<label>
<input type="radio" class="form-control" name="borderpoint_status_<?=$preorder->id?>" id="borderpoint_need_measurement" value="need_measurement" <?=($preorder->borderpoint_status == "need_measurement") ? "checked='checked'" : ""?> />
Messung erforderlich
</label>
</div>
<div class="col-3 text-center">
<label>
<input type="radio" class="form-control" name="borderpoint_status_<?=$preorder->id?>" id="borderpoint_informed" value="informed" <?=($preorder->borderpoint_status == "informed") ? "checked='checked'" : ""?> />
Beauskunftet
</label>
</div>
<div class="col-3 text-center">
<label>
<input type="radio" class="form-control" name="borderpoint_status_<?=$preorder->id?>" id="borderpoint_need_digging" value="need_digging" <?=($preorder->borderpoint_status == "need_digging") ? "checked='checked'" : ""?> />
Grabung ausständig
</label>
</div>
</div>
</div>
</div>
</div>
<div class="col-6">
<h3>Statusflags</h3>

View File

@@ -939,7 +939,7 @@ class AddressdbApicontroller extends mfBaseApicontroller {
$prices_return = [
"oaid" => $oaid,
"enduser_setup_price_net" => (float)$prices["enduser_setup"]->price_setup,
"enduser_setup_price_net" => round((float)$prices["enduser_setup"]->price_setup, 2),
"enduser_setup_price_gross" => round((float)$prices["enduser_setup"]->price_setup * 1.2, 2),
"enduser_setup_info" => $prices["enduser_setup"]->description,
"enduser_setup_is_discount" => ($prices["enduser_setup"]->end_date) ? true : false,

View File

@@ -42,15 +42,6 @@ class Building extends mfBaseModel {
return $data;
}
protected function afterSave() {
if($this->in_after_save) return true;
$this->in_after_save++;
$this->resetProperties();
$this->in_after_save--;
}
public function resetProperties() {
$this->network = null;
$this->pop = null;

View File

@@ -305,6 +305,8 @@ class PreorderController extends mfBaseController {
}
}
//var_dump($new_filter);exit;
return $new_filter;
}
@@ -1066,6 +1068,9 @@ class PreorderController extends mfBaseController {
case "addWorkorderRemark":
$return = $this->addWorkorderRemarkApi();
break;
case "saveBorderpointStatus":
$return = $this->saveBorderpointStatusApi();
break;
case "saveOrderdate":
$return = $this->saveOrderdateApi();
break;
@@ -1083,9 +1088,38 @@ class PreorderController extends mfBaseController {
$data = ["status" => "error"];
$this->returnJson($data);
}
$data['status'] = "OK";
$data['result'] = $return;
$this->returnJson($data);
if(mfResponse::isResponse($return)) {
$this->returnJson($return);
} else {
$data['status'] = "OK";
$data['result'] = $return;
$this->returnJson($data);
}
}
protected function saveBorderpointStatusApi() {
$preorder_id = $this->request->preorder_id;
$status_type = $this->request->status_type;
$value = $this->request->value;
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
if(!$value) {
$preorder->update(["borderpoint_status" => null]);
} else {
$preorder->update(["borderpoint_status" => $status_type]);
}
$this->log->debug(__METHOD__.": $preorder_id - borderpoint status updated to $status_type");
$preorder->save();
return mfResponse::Ok();
}
protected function getFCPsForCampaignApi(): array {

View File

@@ -35,6 +35,7 @@ class PreorderModel
public $accept_marketing;
public $accept_withdrawal;
public $accept_digging;
public $borderpoint_status;
public $contact_type;
public $company;
public $uid;
@@ -566,8 +567,6 @@ class PreorderModel
{
$where = "1=1 ";
//var_dump($filter);exit;
if (array_key_exists("deleted", $filter)) {
$deleted = $filter['deleted'];
if ($deleted === null || $deleted === false) {
@@ -685,6 +684,14 @@ class PreorderModel
}
if (array_key_exists("borderpoint_status", $filter)) {
$borderpoint_status = FronkDB::singleton()->escape($filter['borderpoint_status']);
if ($borderpoint_status) {
$where .= " AND tt_preorder.borderpoint_status='$borderpoint_status'";
}
}
if (array_key_exists("preordercampaign_id", $filter)) {
$preordercampaign_id = $filter['preordercampaign_id'];
if (is_numeric($preordercampaign_id)) {

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class PreorderAddBorderpointStatus extends AbstractMigration
{
public function up(): void
{
if($this->getEnvironment() == "thetool") {
$table = $this->table("Preorder");
$table->addColumn("borderpoint_status", "enum", ["null" => true, "default" => null, "values" => ["need_measurement", "informed", "need_digging"], "after" => "accept_digging"]);
$table->update();
}
if($this->getEnvironment() == "addressdb") {
}
}
public function down(): void
{
if($this->getEnvironment() == "thetool") {
$table = $this->table("Preorder");
$table->removeColumn("borderpoint_status");
$table->update();
}
if($this->getEnvironment() == "addressdb") {
}
}
}

View File

@@ -233,9 +233,9 @@ class mfBaseApicontroller {
//var_dump(mb_detect_encoding($request_body), $charset);
return $request_body;
}
// Request body is urlencoded or multipart-formdata
if(preg_match('#charset\s*=\s*["\']?([^ "\']+)["\']?\s*;?#i', $_SERVER["CONTENT_TYPE"], $m)) {
if(array_key_exists("CONTENT_TYPE", $_SERVER) && preg_match('#charset\s*=\s*["\']?([^ "\']+)["\']?\s*;?#i', $_SERVER["CONTENT_TYPE"], $m)) {
$request_charset = strtolower($m[1]);
}

View File

@@ -318,14 +318,30 @@ class mfBaseController
return $url;
}
public static function returnJson($data)
public static function returnJson($response)
{
if (is_array($data)) {
if(mfResponse::isResponse($response)) {
$code = $response['code'];
$status = $response['status'];
$data = $response['data'];
$proto = "HTTP/1.0";
if($_SERVER["SERVER_PROTOCOL"]) {
$proto = $_SERVER["SERVER_PROTOCOL"];
}
header("$proto $code $status");
header("Content-type: application/json");
//http_response_code($code);
echo json_encode(["status" => $status, "result" => $data]);
exit;
}
if (is_array($response)) {
header("Content-Type: application/json");
echo json_encode($data);
echo json_encode($response);
exit;
} else {
throw new Exception("Data not an array");
throw new Exception("Response data not an array");
}
}