Merge-Konflikt in DeviceController.php behoben

This commit is contained in:
Daniel Spitzer
2025-02-11 15:27:26 +01:00
63 changed files with 3041 additions and 933 deletions

View File

@@ -27,6 +27,7 @@
<a href="<?=self::getUrl("Address","edit", ['id' => $address->id, 's' => $s, 'f' => "view"])?>" class="btn btn-outline-success"><i class="fas fa-edit"></i> Adresse bearbeiten</a>
</div>
<div class="float-right">
<a href="<?=self::getUrl("Address","tickets", ["address_id" => $address->id])?>" class="btn btn-purple mr-1"><i class="far fa-user-headset"></i> Tickets</a>
<a href="<?=self::getUrl("Address","invoice", ["address_id" => $address->id])?>" class="btn btn-purple mr-1"><i class="far fa-file-invoice-dollar"></i> Rechungsübersicht</a>
</div>
</div>

View File

@@ -148,6 +148,7 @@
<th>Einheiten</th>
<th>Status</th>
<!--th class="text-center"><img src="<?=self::getResourcePath()?>assets/images/snopp-sm.png" style="width: 24px; height: 24px;" /> Export</th-->
<th>Erstellt<br />Bearbeitet</th>
<th></th>
</tr>
<?php foreach($buildings as $building): ?>
@@ -164,6 +165,10 @@
<td onclick="toggleBuilding(<?=$building->id?>)"><?=$building->units?></td>
<td onclick="toggleBuilding(<?=$building->id?>)" class="text-monospace"><?=__($building->status->name."-b")?></td>
<!--td><input type="checkbox" class="form-control" id="snopp-export-<?=$building->id?>" data-building-id="<?=$building->id?>" /></td-->
<td class="text-monospace" onclick="toggleBuilding(<?=$building->id?>)">
<?=date('d.m.Y H:i:s',$building->create)?> (<?=$building->creator->name?>)<br />
<?=date('d.m.Y H:i:s',$building->edit)?> (<?=$building->editor->name?>)
</td>
<td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;">
<a href="<?=self::getUrl("Building", "edit", ["id" => $building->id])?>"><i class="far fa-edit" title="Objekt Bearbeiten"></i></a>
<a href="<?=self::getUrl("Building", "delete", ["id" => $building->id])?>" class="text-danger" onclick="if(!confirm('Objekt wirklich löschen?')) return false;" title="Objekt Löschen"><i class="fas fa-trash"></i></a>

View File

@@ -90,6 +90,21 @@
<hr class="mt-3 mb-3" />
<h4>Berechtigungen</h4>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="sender_reply_to">Berechtigte Firmen</label>
<div class="col-lg-10">
<select class="form-control select2" name="address_id[]" id="adb_hausnummer_id" multiple="multiple">
<?php foreach(AddressModel::search(["addresstype" => TT_NETWORK_ROLES_WITH_OWNER]) as $address): ?>
<option value="<?=$address->id?>" <?=(array_key_exists($address->id, $project->addresses)) ? "selected='selected'" : ""?>><?=$address->getCompanyOrName()?><?=($address->customer_number) ? " (".$address->customer_number.")" : ""?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<hr class="mt-3 mb-3" />
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="note">Interne Notiz</label>
<div class="col-lg-10">
@@ -120,12 +135,6 @@
closeOnSelect: false
});
$('#adb_hausnummer_id').on('select2:close', function(e) {
if(!$('#adb_hausnummer_id').val()) {
$('#new-address-toggle').show();
}
});
</script>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>

View File

@@ -55,7 +55,7 @@ $pagination_entity_name = "Rechnungen";
<input type="text" class="form-control" name="filter[customer_number]" id="filter_customer_number" value="<?=(array_key_exists("customer_number", $filter)) ? $filter['customer_number'] : ""?>"/>
</div>
<div class="col-1">
<label class="form-label" for="filter_fibu_account_number">FIBU Konten</label>
<label class="form-label" for="filter_fibu_account_number">FIBU</label>
<input type="text" class="form-control" name="filter[fibu_account_number]" id="filter_fibu_account_number" value="<?=(array_key_exists("fibu_account_number", $filter)) ? $filter['fibu_account_number'] : ""?>"/>
</div>
<div class="col-1">
@@ -474,4 +474,4 @@ $pagination_entity_name = "Rechnungen";
</script>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>

View File

@@ -423,9 +423,7 @@ $pagination_entity_name = "Vorbestellungen";
<th>Partner</th>
<th>Attribute</th>
<th>Erstellt<br />Bearbeitet</th>
<?php if($me->is(["Admin","netowner"])): ?>
<th></th>
<?php endif; ?>
<th></th>
<th></th>
</tr>
<?php foreach($preorders as $preorder): ?>
@@ -479,9 +477,7 @@ $pagination_entity_name = "Vorbestellungen";
<span id="update-<?=$preorder->id?>"><?=date('d.m.Y H:i', $preorder->edit)?></span>
</td>
<?php if($me->is(["Admin", "netowner"])): ?>
<td><?php if($preorder->adb_wohneinheit_id && is_array($preorder->adb_wohneinheit->rimo_workorders) && count($preorder->adb_wohneinheit->rimo_workorders)):?><i class="fas fa-r" title="Rimo Workorder erstellt"></i><?php endif; ?></td>
<?php endif; ?>
<td><?php if($preorder->adb_wohneinheit_id && is_array($preorder->adb_wohneinheit->rimo_workorders) && count($preorder->adb_wohneinheit->rimo_workorders)):?><i class="fas fa-r" title="Rimo Workorder erstellt"></i><?php endif; ?></td>
<td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;">
<div class="preorder-campaign-table-actions">
<?php if(!$me->is(["preorderfront"]) && !$me->is("preorderreadonly")): ?>
@@ -742,7 +738,9 @@ $pagination_entity_name = "Vorbestellungen";
var marker_popup_content = '<?php include(realpath(dirname(__FILE__))."/include/preorder_popup.php");?>';
// popup fields
const preorder_view_url = `<?=self::getUrl("Preorder")?>/Index?filter[ucode]=${preorder.ucode}#preorder=${preorder.id}`;
[
["PREORDER_URL", preorder_view_url],
["street", preorder.adb_strasse],
["hausnummer", preorder.adb_hausnummer],
["zip", preorder.adb_plz],

View File

@@ -428,8 +428,8 @@
</table>
<?php endforeach; ?>
<?php elseif($preorder->adb_wohneinheit_id && $me->is("Admin")): ?>
<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 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>

View File

@@ -37,6 +37,11 @@ ob_start();
<th class="font-weight-bold">Email:</th>
<td>{{EMAIL}}</td>
</tr>
</table>
<a href="{{PREORDER_URL}}" class="btn btn-primary text-white" target="_blank">
<i class="fas fa-eye"></i> Bestellung ansehen
</a>
<?=str_replace("\n"," ",ob_get_clean())?>

View File

@@ -158,6 +158,9 @@
<option value="ofaa" <?= ($campaign->oaid_origin == "ofaa") ? "selected='selected'" : "" ?>>
OFAA
</option>
<option value="other" <?= ($campaign->oaid_origin == "other") ? "selected='selected'" : "" ?>>
Andere (importieren, aber nicht verarbeiten)
</option>
</select>
</div>
</div>
@@ -377,73 +380,81 @@
</div>
<h4>Emailbenachrichtigungen</h4>
<div class="card">
<div class="card-body">
<h4 class="">Absender</h4>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="from_email_name">Name</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="from_email_name" id="from_email_name" value="<?= $campaign->from_email_name ?>"/>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="from_email">Emailadresse</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="from_email" id="from_email" value="<?= $campaign->from_email ?>"/>
</div>
</div>
<h4 class="mt-3">Emailtemplates</h4>
<?php $i=0; foreach(PreorderstatusModel::getAll() as $status): ?>
<div class="form-group row p-2 mb-0 border-bottom" id="statustemplate-<?=$status->code?>" style="background-color: #<?=($i%2 == 0) ? "fafafa" : "fff"?>">
<label class="col-lg-2 col-form-label text-right text-monospace" for="mailtemplates_<?=$status->code?>"><?=$status->name?></label>
<?php if(isset($campaign) && $campaign): ?>
<div class="card">
<div class="card-body">
<h4 class="">Absender</h4>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="from_email_name">Name</label>
<div class="col-lg-10">
<div class="row">
<div class="col-8">
<div class="input-group">
<div class="input-group-prepend text-monospace">
<span class="input-group-text" id="basic-addon1"><?=$status->code?></span>
<input type="text" class="form-control" name="from_email_name" id="from_email_name" value="<?= $campaign->from_email_name ?>"/>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="from_email">Emailadresse</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="from_email" id="from_email" value="<?= $campaign->from_email ?>"/>
</div>
</div>
<h4 class="mt-3">Emailtemplates</h4>
<?php $i=0; foreach(PreorderstatusModel::getAll() as $status): ?>
<div class="form-group row p-2 mb-0 border-bottom" id="statustemplate-<?=$status->code?>" style="background-color: #<?=($i%2 == 0) ? "fafafa" : "fff"?>">
<label class="col-lg-2 col-form-label text-right text-monospace" for="mailtemplates_<?=$status->code?>"><?=$status->name?></label>
<div class="col-lg-10">
<div class="row">
<div class="col-8">
<div class="input-group">
<div class="input-group-prepend text-monospace">
<span class="input-group-text" id="basic-addon1"><?=$status->code?></span>
</div>
<select name="mailtemplates[<?=$status->code?>][mailtemplate_id]" id="mailtemplate-<?=$status->code?>" class="form-control select2">
<option value=""></option>
<?php foreach(MailtemplateModel::search(["is_include" => "0"]) as $template): ?>
<option value="<?=$template->id?>" <?=(is_array($campaign->statusnotifcation_mailtemplates) && array_key_exists($status->code, $campaign->statusnotifcation_mailtemplates) && $campaign->statusnotifcation_mailtemplates[$status->code]->mailtemplate_id == $template->id) ? "selected='selected'" : ""?>><?=$template->name?></option>
<?php endforeach; ?>
</select>
</div>
<select name="mailtemplates[<?=$status->code?>][mailtemplate_id]" id="mailtemplate-<?=$status->code?>" class="form-control select2">
<option value=""></option>
<?php foreach(MailtemplateModel::search(["is_include" => "0"]) as $template): ?>
<option value="<?=$template->id?>" <?=(is_array($campaign->statusnotifcation_mailtemplates) && array_key_exists($status->code, $campaign->statusnotifcation_mailtemplates) && $campaign->statusnotifcation_mailtemplates[$status->code]->mailtemplate_id == $template->id) ? "selected='selected'" : ""?>><?=$template->name?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="col">
<div class="input-group">
<div class="input-group-prepend text-monospace">
<span class="input-group-text">@</span>
</div>
<input type="text" class="form-control" name="test_to" id="test-to-<?=$status->code?>" value="" placeholder="Test Emailadresse" />
<div class="input-group-append">
<button class="btn btn-outline-success" type="button" onclick="sendTestStatusEmail(<?=$status->code?>)"><i class="fas fa-envelope"></i> Testmail versenden</button>
<div class="col">
<div class="input-group">
<div class="input-group-prepend text-monospace">
<span class="input-group-text">@</span>
</div>
<input type="text" class="form-control" name="test_to" id="test-to-<?=$status->code?>" value="" placeholder="Test Emailadresse" />
<div class="input-group-append">
<button class="btn btn-outline-success" type="button" onclick="sendTestStatusEmail(<?=$status->code?>)"><i class="fas fa-envelope"></i> Testmail versenden</button>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-1">
<div class="col-lg">
<label>
<input type="checkbox" name="mailtemplates[<?=$status->code?>][allow_on_skip]" value="1" id="allow_on_skip-<?=$status->code?>" <?=(is_array($campaign->statusnotifcation_mailtemplates) && array_key_exists($status->code, $campaign->statusnotifcation_mailtemplates) && $campaign->statusnotifcation_mailtemplates[$status->code]->allow_on_skip) ? "checked='checked'" : ""?> />
Benachrichtigung darf bei Überspringen versendet werden, wenn nötig
</label><br />
<label>
<input type="checkbox" name="mailtemplates[<?=$status->code?>][prevent_previous]" value="1" id="prevent_previous-<?=$status->code?>" <?=(is_array($campaign->statusnotifcation_mailtemplates) && array_key_exists($status->code, $campaign->statusnotifcation_mailtemplates) && $campaign->statusnotifcation_mailtemplates[$status->code]->prevent_previous) ? "checked='checked'" : ""?> />
Keine vorigen Benachrichtigungen versenden, wenn dieser Status ohne Mailtemplate eintritt
</label>
<div class="row mt-1">
<div class="col-lg">
<label>
<input type="checkbox" name="mailtemplates[<?=$status->code?>][allow_on_skip]" value="1" id="allow_on_skip-<?=$status->code?>" <?=(is_array($campaign->statusnotifcation_mailtemplates) && array_key_exists($status->code, $campaign->statusnotifcation_mailtemplates) && $campaign->statusnotifcation_mailtemplates[$status->code]->allow_on_skip) ? "checked='checked'" : ""?> />
Benachrichtigung darf bei Überspringen versendet werden, wenn nötig
</label><br />
<label>
<input type="checkbox" name="mailtemplates[<?=$status->code?>][prevent_previous]" value="1" id="prevent_previous-<?=$status->code?>" <?=(is_array($campaign->statusnotifcation_mailtemplates) && array_key_exists($status->code, $campaign->statusnotifcation_mailtemplates) && $campaign->statusnotifcation_mailtemplates[$status->code]->prevent_previous) ? "checked='checked'" : ""?> />
Keine vorigen Benachrichtigungen versenden, wenn dieser Status ohne Mailtemplate eintritt
</label>
</div>
</div>
</div>
</div>
</div>
<?php $i++; endforeach; ?>
<?php $i++; endforeach; ?>
</div>
</div>
</div>
<?php else: ?>
<div class="card">
<div class="card-body">
<i>Verfügbar nach Speichern...</i>
</div>
</div>
<?php endif; ?>
<h4>API-User</h4>
@@ -566,30 +577,32 @@
background: "bg-danger"
});
function sendTestStatusEmail(status_code) {
if(!status_code) return;
<?php if(isset($campaign) && $campaign): ?>
function sendTestStatusEmail(status_code) {
if(!status_code) return;
var template_id = $("#mailtemplate-" + status_code).val();
var email_to = $("#test-to-" + status_code).val();
var template_id = $("#mailtemplate-" + status_code).val();
var email_to = $("#test-to-" + status_code).val();
$.post("<?=self::getUrl("Preordercampaign", "Api")?>",
{
do: "sendStatusEmail",
campaign_id: <?=$campaign->id?>,
template_id: template_id,
to_email: email_to
},
(success) => {
if(success.status == "OK") {
window.notify("success", "Testmail wurde versendet");
} else {
window.notify("error", "Beim versenden ist ein Fehler aufgetragen.");
}
$.post("<?=self::getUrl("Preordercampaign", "Api")?>",
{
do: "sendStatusEmail",
campaign_id: <?=$campaign->id?>,
template_id: template_id,
to_email: email_to
},
(success) => {
if(success.status == "OK") {
window.notify("success", "Testmail wurde versendet");
} else {
window.notify("error", "Beim versenden ist ein Fehler aufgetragen.");
}
console.log(success);
},
"json"
);
}
console.log(success);
},
"json"
);
}
<?php endif; ?>
</script>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<title>Xinon Rechnung</title>
<meta charset="utf-8" />
</head>
<body style="border:0; margin: 0;font-family: sans-serif, Verdana;font-size: 11px;" onload="subst()">
<script>
function subst() {
var vars = {};
var query_strings_from_url = document.location.search.substring(1).split('&');
for (var query_string in query_strings_from_url) {
if (query_strings_from_url.hasOwnProperty(query_string)) {
var temp_var = query_strings_from_url[query_string].split('=', 2);
vars[temp_var[0]] = decodeURI(temp_var[1]);
}
}
var css_selector_classes = ['page', 'frompage', 'topage', 'webpage', 'section', 'subsection', 'date', 'isodate', 'time', 'title', 'doctitle', 'sitepage', 'sitepages'];
for (var css_class in css_selector_classes) {
if (css_selector_classes.hasOwnProperty(css_class)) {
var element = document.getElementsByClassName(css_selector_classes[css_class]);
for (var j = 0; j < element.length; ++j) {
element[j].textContent = vars[css_selector_classes[css_class]];
}
}
}
}
</script>
<div style="margin-bottom: 16px;height: 1px"></div>
<div style="color:grey;text-align: center;margin-bottom: 0">
<span>XINON GmbH | Fladnitz 150 | 8322 Studenzen</span><br>
<span>Tel.: +43 3115 40800 | E-Mail: office@xinon.at</span><br>
<span>UID: ATU68711968 | FN: 416556h | LG: Feldbach</span><br>
<span>IBAN: {{ bank_iban }} | BIC: {{ bank_bic }}</span><br>
</div>
<div style="text-align: right">Seite <span class="page"></span> von <span class="topage"></span></div>
<div style="margin-top: 16px;height: 1px"></div>
</body>
</html>

View File

@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<title>XINON Shipping Note Header</title>
<meta charset="utf-8" />
<style>
body {
border: 0;
margin: 0;
font-family: sans-serif, Verdana;
font-size: 12px;
}
.info-table {
border-collapse: collapse;
width: 100%;
}
.customer-details {
vertical-align: bottom;
font-size: 14px;
padding-left: 30pt;
width: 35%;
}
.invoice-details {
border: 2px solid #e1e1e1;
padding: 6px;
}
.invoice-details td {
text-align: left;
}
.invoice-details td:first-child {
text-align: right;
}
.separator {
margin-top: 24px;
height: 1px;
}
#topSpacer {
margin-bottom: 32px;
height: 20px;
}
</style>
</head>
<body>
<div id="topSpacer"></div>
<div style="height: 50px; margin-bottom: 48px">
<img alt="Xinon Logo" src="{{ basedir }}/public/assets/images/xinon-full.png" style="text-align:left;height: 85px;">
</div>
<table style="width: 100%; border-collapse: collapse;">
<tr>
<td class="customer-details" style="float: left">
<h3>Lieferant</h3>
<div>{{ addressLine_1 }}</div>
<div>{{ addressLine_2 }}</div>
<div>{{ addressLine_3 }}</div>
<div>{{ addressLine_4 }}</div>
<div style="margin-bottom: 12pt"></div>
<div>{{ externalReference }}</div>
</td>
<td class="customer-details" align="top">
<h3>Rechnungsadresse</h3>
<div>{{ billingAddressLine_1 }}</div>
<div>{{ billingAddressLine_2 }}</div>
<div>{{ billingAddressLine_3 }}</div>
<div>{{ billingAddressLine_4 }}</div>
<div>{{ billingAddressLine_5 }}</div>
<div>{{ billingAddressLine_6 }}</div>
</td>
<td class="customer-details" style="float: right">
<div>{{ shippingAddressLine_1 }}</div>
<div>{{ shippingAddressLine_2 }}</div>
<div>{{ shippingAddressLine_3 }}</div>
<div>{{ shippingAddressLine_4 }}</div>
</td>
</tr>
</table>
<div class="separator"></div>
</body>
</html>

View File

@@ -0,0 +1,133 @@
<?php
/**
* @var string $ressourcePathPrefix
* @var WarehouseOrderModel $order
* @var Array $positions
* @var Array $textElements
*/
$this->setReturnValue(['filename' => $order["id"] . ".pdf"]);
?>
<!DOCTYPE html>
<html>
<head>
<title>Bestellung</title>
<meta charset="utf-8" />
<style>
body {
margin-top: 0;
/*padding-top: 20pt;*/
font-family: "Open Sans", sans-serif, Verdana;
font-size: 12px;
}
tr {
page-break-inside: avoid;
}
.uneven {
background-color: #ebebeb;
}
table tr td:last-child {
text-align: right;
}
.additionalRow td:first-child {
text-align: left;
padding-left: 20pt;
}
th {
height: 28px;
}
#invoiceTable tr *:nth-child(5),
#invoiceTable tr *:nth-child(4),
#invoiceTable tr *:nth-child(3) {
text-align: right;
}
#invoiceTable tr *:not(:first-child) {
padding: 4px 0;
}
#invoiceTable tr td {
font-size: 11px;
}
tr.position td {
vertical-align: top;
}
tr.position td:first-child {
vertical-align: middle !important;
padding-left: 4pt;
}
#invoiceTable tr td:first-child {
max-width: 200pt;
}
</style>
</head>
<body>
<div>
<!--
TODO: enable option for showing prices
vertauschen
Die gelieferte Ware bleibt bis zur vollständigen Bezahlung in unserem Eigentum.
-->
<h2 style="text-align: center;color: #005384">XINON Lieferantenbestellung vom <?=date("d.m.Y", $order["create"])?></h2>
<table style="border-collapse: collapse; width: 100%;" id="invoiceTable">
<tr style="font-weight: bold; border-bottom: 1px solid black;" class="uneven">
<th style="text-align: center;padding-right: 6pt">Position</th>
<th style="text-align: center;padding-right: 6pt">Artikel</th>
<th style="text-align: center;padding-right: 6pt">Art.-Nr. Lieferant</th>
<th style="text-align: right">Menge</th>
<th style="text-align: right">Einzelpreis</th>
<th style="text-align: right;padding-right: 8pt">Gesamtpreis</th>
</tr>
<?php $i = 0; foreach($order['positions'] as $p):?>
<tr class="position <?=($i%2 == 0) ? "even" : "uneven" ?>">
<td style="text-align: center;"><?= $i + 1 ?></td>
<td style="text-align: left;padding-right: 8pt"><?=$p["articleName"]?></td>
<td style="text-align: center;padding-right: 8pt"><?=$p["distributorArticleNumber"]?></td>
<td style="text-align: right"><?=$p["amount"]?></td>
<td style="text-align: right"><?=number_format($p["buyPrice"], 2, ",", ".")?> €</td>
<td style="text-align: right;padding-right: 8pt"><?=number_format($p["amount"] * $p["buyPrice"], 2, ",", ".")?> €</td>
</tr>
<?php $i++; endforeach;?>
<!-- display a grey like header sum with top border to differentiate 2nd last td = Summe , last td is the calculated value both bold-->
<tr class="uneven">
<?php
$sum = 0;
foreach($order['positions'] as $p){
$sum += $p["amount"] * $p["buyPrice"];
}
?>
<td colspan="5" style="text-align: right;border-top: 1px solid black;font-weight: bold
;border-bottom: 1px solid black;
">Summe</td>
<td style="text-align: right;border-top: 1px solid black;font-weight: bold
;border-bottom: 1px solid black;
"><?=number_format($sum, 2, ",", ".")?> €</td>
</tr>
</table>
<div>
<h3>Anmerkungen</h3>
<p>
<?=$order["note"]?>
</p>
</div>
</body>
</html>

View File

@@ -198,7 +198,7 @@
<?php if($me->is(["Admin","salespartner"]) && $me->can("Order")): ?>
<li><a href="<?=self::getUrl("Order")?>"><i class="far fa-fw fa-file-signature text-info"></i> Bestellungen</a></li>
<?php endif; ?>
<?php if($me->is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209])): ?>
<?php if($me->is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209,5908])): ?>
<li><a href="<?=self::getUrl("ConstructionConsentProject")?>"><i class="far fa-fw fa-clipboard-question text-info"></i> Zustimmungserklärungen</a></li>
<?php endif; ?>
</ul>

View File

@@ -8,6 +8,7 @@ class ADBWohneinheit extends mfBaseModel {
private $status;
private $statusflags; // TODO
private $preorders;
private $active_preorders;
protected function init() {
$this->db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
@@ -65,6 +66,8 @@ class ADBWohneinheit extends mfBaseModel {
$gda_egenschaft = strtolower($hausnummer->rimo_type);
}
if(strtolower($gda_egenschaft) == "greenfield") continue;
if(!$gda_egenschaft) {
$unit_count_gda["sd"] += $hausnummer->unit_count;
continue;
@@ -107,11 +110,13 @@ class ADBWohneinheit extends mfBaseModel {
$old_status = new ADBStatus($this->_old_data->status_id);
$new_status = new ADBStatus($this->data->status_id);
$logstr .= "| '$key' => FROM '".$this->_old_data->$key."' TO '".$this->data->$key."' [".$old_status->code." => ".$new_status->code."]";
} elseif($key = "external_data" && $this->_old_data->external_data && $this->external_data) {
} elseif($key == "external_data" && $this->_old_data->external_data && $this->external_data) {
$old_data = json_decode($this->_old_data->external_data);
$new_data = json_decode($this->external_data);
if(json_encode($old_data) !== json_encode($new_data)) {
$logstr .= "| '$key' => FROM '".$this->_old_data->$key."' TO '".$this->data->$key."'";
} else {
continue;
}
} else {
$logstr .= "| '$key' => FROM '".$this->_old_data->$key."' TO '".$this->data->$key."'";
@@ -312,6 +317,15 @@ class ADBWohneinheit extends mfBaseModel {
return $this->preorders;
}
if($name == "active_preorders") {
$preorders = PreorderModel::searchActive(["adb_wohneinheit_id" => $this->id]);
if(!count($preorders)) {
return [];
}
$this->preorders = $preorders;
return $this->preorders;
}
if($name == "ftu_data") {
$rimo_data = $this->getExternalRimoData();

File diff suppressed because one or more lines are too long

View File

@@ -1066,7 +1066,7 @@ class AddressDBController extends mfBaseController {
$u['zusatz'] = $unit->zusatz;
$u['usage'] = $unit->nutzung;
$u['oaid'] = $unit->oaid;
$u['preorder_count'] = count($unit->preorders);
$u['preorder_count'] = count($unit->active_preorders);
$results[] = $u;
}

View File

@@ -447,6 +447,10 @@ class AddressdbApicontroller extends mfBaseApicontroller {
'sort_key' => $sort_key,
'oaid' => $data->hausnummer_oaid,
'cluster_id' => $data->netzgebiet_extref,
'rimo_external_id' => null,
'visibility' => null,
'adrcd' => null,
'subcd' => null,
'zip' => $data->plz,
'city' => $data->gemeinde,
"municipality" => "",
@@ -472,6 +476,17 @@ class AddressdbApicontroller extends mfBaseApicontroller {
} else {
unset($tmp_addresses[$address_key]['municipality']);
}
if($this->me->is("preorderaddressreporting")) {
$tmp_addresses[$address_key]['rimo_external_id'] = $data->hausnummer_rimo_id;
$tmp_addresses[$address_key]['visibility'] = $data->visibility;
$tmp_addresses[$address_key]['adrcd'] = $data->adrcd;
$tmp_addresses[$address_key]['subcd'] = $data->subcd;
} else {
unset($tmp_addresses[$address_key]['rimo_external_id']);
unset($tmp_addresses[$address_key]["visibility"]);
unset($tmp_addresses[$address_key]["adrcd"]);
unset($tmp_addresses[$address_key]["subcd"]);
}
}
$unit_data = [
@@ -589,6 +604,10 @@ class AddressdbApicontroller extends mfBaseApicontroller {
$new_address['ordered'] = $u['ordered'];
$new_address['orderType'] = $u['orderType'];
$new_address['ispName'] = $u['ispName'];
$new_address['rimo_external_id'] = $ta['rimo_external_id'];
$new_address['visibility'] = $ta['visibility'];
$new_address['adrcd'] = $ta['adrcd'];
$new_address['subcd'] = $ta['subcd'];
}
$new_address['oaid'] = $u['oaid'];
$new_address['building_oaid'] = $ta['oaid'];
@@ -743,6 +762,10 @@ class AddressdbApicontroller extends mfBaseApicontroller {
$tmp_addresses[$address_key] = [
'oaid' => $data->hausnummer_oaid,
'cluster_id' => $data->netzgebiet_extref,
'rimo_external_id' => null,
'visibility' => null,
'adrcd' => null,
'subcd' => null,
'zip' => $data->plz,
'city' => $data->gemeinde,
"municipality" => "",
@@ -768,7 +791,17 @@ class AddressdbApicontroller extends mfBaseApicontroller {
} else {
unset($tmp_addresses[$address_key]['municipality']);
}
if($this->me->is("preorderaddressreporting")) {
$tmp_addresses[$address_key]['rimo_external_id'] = $data->hausnummer_rimo_id;
$tmp_addresses[$address_key]['visibility'] = $data->visibility;
$tmp_addresses[$address_key]['adrcd'] = $data->adrcd;
$tmp_addresses[$address_key]['subcd'] = $data->subcd;
} else {
unset($tmp_addresses[$address_key]['rimo_external_id']);
unset($tmp_addresses[$address_key]["visibility"]);
unset($tmp_addresses[$address_key]["adrcd"]);
unset($tmp_addresses[$address_key]["subcd"]);
}
}
$unit_data = [
@@ -808,6 +841,10 @@ class AddressdbApicontroller extends mfBaseApicontroller {
$new_address['ordered'] = $u['ordered'];
$new_address['orderType'] = $u['orderType'];
$new_address['ispName'] = $u['ispName'];
$new_address['rimo_external_id'] = $ta['rimo_external_id'];
$new_address['visibility'] = $ta['visibility'];
$new_address['adrcd'] = $ta['adrcd'];
$new_address['subcd'] = $ta['subcd'];
}
$new_address['oaid'] = $u['oaid'];
$new_address['building_oaid'] = $ta['oaid'];

View File

@@ -15,7 +15,9 @@ class Building extends mfBaseModel {
private $workflowitems;
private $files;
private $pipework_enabler;
private $creator;
private $editor;
public function getAddress($singelLine = false) {
if(!$this->id) {
return false;
@@ -327,6 +329,28 @@ class Building extends mfBaseModel {
return $this->pipework_enabler;
}
if($name == "creator") {
$this->creator = mfValuecache::singleton()->get("Worker-id-" . $this->create_by);
if($this->creator === null) {
$this->creator = new User($this->create_by);
if($this->creator->id) {
mfValuecache::singleton()->set("Worker-id-" . $this->create_by, $this->creator);
}
}
return $this->creator;
}
if($name == "editor") {
$this->editor = mfValuecache::singleton()->get("Worker-id-" . $this->edit_by);
if($this->editor === null) {
$this->editor = new User($this->edit_by);
if($this->editor->id) {
mfValuecache::singleton()->set("Worker-id-" . $this->edit_by, $this->editor);
}
}
return $this->editor;
}
$classname = ucfirst($name);
$idfield = $name."_id";
$this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-".$this->$idfield);

View File

@@ -10,9 +10,7 @@ class ConstructionConsentController extends mfBaseController {
$this->me = $me;
$this->layout()->set("me", $me);
if (!$me->is(["Admin"])) {
$this->redirect("Dashboard");
}
if (!($me->is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209,5908]))) $this->redirect("Dashboard");
}
protected function indexAction() : void {

View File

@@ -11,9 +11,7 @@ class ConstructionConsentContactController extends mfBaseController
$this->me = $me;
$this->layout()->set("me", $me);
if (!$me->is(["Admin"])) {
$this->redirect("Dashboard");
}
if (!($me->is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209,5908]))) $this->redirect("Dashboard");
}
protected function saveAction()

View File

@@ -9,9 +9,7 @@ class ConstructionConsentJournalController extends mfBaseController {
$this->me = $me;
$this->layout()->set("me",$me);
if(!$me->is(["Admin"])) {
$this->redirect("Dashboard");
}
if (!($me->is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209,5908]))) $this->redirect("Dashboard");
}
protected function saveAction() {

View File

@@ -11,9 +11,7 @@ class ConstructionConsentOwnerController extends mfBaseController
$this->me = $me;
$this->layout()->set("me", $me);
if (!$me->is(["Admin"])) {
$this->redirect("Dashboard");
}
if (!($me->is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209,5908]))) $this->redirect("Dashboard");
}
protected function uploadDocumentAction() {

View File

@@ -4,6 +4,7 @@ class ConstructionConsentProject extends mfBaseModel {
private $consents;
private $networks;
private $adb_networks;
private $addresses;
protected function beforeUpdate($data) {
if(!array_key_exists("edit_by", $data)) {
@@ -18,11 +19,21 @@ class ConstructionConsentProject extends mfBaseModel {
public function getProperty($name) {
if($this->$name == null) {
if($name == "addresses") {
$addresses = ConstructionConsentProjectAddress::search(["constructionconsentproject_id" => $this->id]);
if(!count($addresses)) {
return [];
}
foreach($addresses as $address) {
$this->addresses[$address->address->id] = $address;
}
return $this->addresses;
}
if($name == "consents") {
$consents = ConstructionConsent::search(["constructionconsentproject_id" => $this->id]);
if(!$consents) {
return [];
}
$this->consents = $consents;
return $this->consents;

View File

@@ -10,9 +10,7 @@ class ConstructionConsentProjectController extends mfBaseController {
$this->me = $me;
$this->layout()->set("me", $me);
if (!$me->is(["Admin"])) {
$this->redirect("Dashboard");
}
if (!($me->is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209,5908]))) $this->redirect("Dashboard");
}
protected function indexAction() : void {
@@ -135,30 +133,21 @@ class ConstructionConsentProjectController extends mfBaseController {
return $this->addAction();
}
$netzgebiete = [];
if(!$project->save()) {
$this->layout()->setFlash("Fehler beim Speichern", "error");
return $this->addAction();
}
// save networks
$netzgebiete = [];
foreach($r->adb_netzgebiet_id as $netzgebiet_id) {
$netzgebiet = new ADBNetzgebiet($netzgebiet_id);
if(!$netzgebiet->id) continue;
$netzgebiete[] = $netzgebiet_id;
}
/*
if($mode == "add") {
$project = ConstructionConsentProject::create($data);
} else {
$project->update($data);
}*/
//save networks
foreach($netzgebiete as $netzgebiet_id) {
$ccn = ConstructionConsentNetwork::getFirst(["constructionconsentproject_id" => $project->id, "adb_netzgebiet_id" => $netzgebiet_id]);
if(!$ccn) {
@@ -169,17 +158,40 @@ class ConstructionConsentProjectController extends mfBaseController {
$ccn->save();
}
}
foreach(ConstructionConsentNetwork::search(["constructionconsentproject_id" => $project->id]) as $ccn) {
if(!in_array($ccn->adb_netzgebiet_id, $netzgebiete)) {
$ccn->delete();
}
}
//var_dump($r->get());exit;
// save addresses
$addresses = [];
foreach($r->address_id as $address_id) {
$address = new Address($address_id);
if(!$address->id) continue;
$addresses[] = $address_id;
}
foreach($addresses as $address_id) {
$cca = ConstructionConsentProjectAddress::getFirst(["constructionconsentproject_id" => $project->id, "address_id" => $address_id]);
if(!$cca) {
$cca = ConstructionConsentProjectAddress::create([
"constructionconsentproject_id" => $project->id,
"address_id" => $address_id
]);
$cca->save();
}
}
foreach(ConstructionConsentProjectAddress::search(["constructionconsentproject_id" => $project->id]) as $cca) {
if(!in_array($cca->address_id, $addresses)) {
$cca->delete();
}
}
$this->layout()->setFlash("Zustimmungserklärungsprojekt erfolgreich gespeichert", "success");
$this->redirect("ConstructionConsentProject");
}

View File

@@ -417,9 +417,9 @@ class DeviceController extends mfBaseController
private function getDevices()
{
if (!$this->me->is(["Admin"])) {
if ($this->allowedPops === null) return [];
}
if ($this->allowedPops === null) return [];
$devices = DeviceModel::search(['popIds' => $this->allowedPops]);
foreach ($devices as $device) {

View File

@@ -37,6 +37,12 @@ class Preorder extends mfBaseModel {
}
}
public function beforeSave() {
if(!isset($this->data->status_id)) {
$this->data->status_id = 1;
}
}
public function afterSave() {
// reset auto magic properties
$this->status = null;
@@ -111,6 +117,9 @@ class Preorder extends mfBaseModel {
}
}
$campaign = $this->getProperty("campaign");
if($campaign->oaid_origin == "other") return true;
if($this->adb_wohneinheit_id && is_array($this->getProperty("adb_wohneinheit")->rimo_workorders)) {
foreach($this->getProperty("adb_wohneinheit")->rimo_workorders as $workorder) {
Rimoapi::updateWorkorder($workorder->rimo_id, $update);
@@ -425,7 +434,7 @@ class Preorder extends mfBaseModel {
$new_status = new Preorderstatus($this->status_id);
if(!$new_status->id) {
$this->log->warning(__METHOD__ . ": Preorder has invalid status!");
$this->log->warning(__METHOD__ . ": Preorder has invalid status! ".print_r($this, true));
return true;
}
@@ -583,6 +592,23 @@ class Preorder extends mfBaseModel {
return true;
}
/*if($campaign->oaid_origin == "other") {
// oaid in wohneinheit übernehmen, falls in Preorder schon vorhanden
if($this->oaid)
// oaid aus wohneinheit übernehmen, falls vorhanden
$this->log->debug(__METHOD__.": Kampagne unterstützt keine OAIDs");
return true;
}*/
if($campaign->oaid_origin == "other") {
if($wohneinheit->oaid != $this->oaid) {
$this->oaid = $wohneinheit->oaid;
}
return true;
}
if($this->oaid) {
// If current OAID is from correct Origin then do nothing
if($campaign->oaid_origin == "thetool") {
@@ -755,6 +781,13 @@ class Preorder extends mfBaseModel {
return false;
}
$campaign = new Preordercampaign($this->preordercampaign_id);
if($campaign->oaid_origin == "other") {
$this->log->debug(__METHOD__.": Kampagne unterstützt keine OAIDs");
return false;
}
if(!$this->oaid) {
$this->setOrCreateOaid();
if(!$this->oaid) {

View File

@@ -399,6 +399,28 @@ class PreorderController extends mfBaseController {
$this->redirect("Preordercampaign");
}
$new_status = false;
if($data['adb_wohneinheit_id']) {
$unit = new ADBWohneinheit($data['adb_wohneinheit_id']);
if ($unit->id) {
$new_status = PreorderstatusModel::getFirst(["code" => $unit->status->code]);
if ($unit->hausnummer->status->code > $unit->status->code) {
$new_status = PreorderstatusModel::getFirst(["code" => $unit->hausnummer->status->code]);
}
}
} elseif($data['adb_hausnummer_id']) {
$h = new ADBHausnummer($data['adb_hausnummer_id']);
if($h->id) {
$new_status = PreorderstatusModel::getFirst(["code" => $h->status->code]);
}
}
if($new_status) {
$data["status_id"] = $new_status->id;
} else {
$data["status_id"] = 1;
}
if($campaign->product_type != "setup_only") {
$data['product_id'] = $r->product_id;
@@ -1345,12 +1367,14 @@ class PreorderController extends mfBaseController {
/*if($preorder->type != "legacytransfer") {
return false;
}*/
if(!$this->me->is("Admin")) {
if(!$this->me->is("Admin") && !$this->me->can("preorder")) {
$this->log->debug(__METHOD__.": no permission");
return false;
}
$workorder = $preorder->createRimoWorkorder();
if(!$workorder) {
$this->log->debug(__METHOD__.": error creating workorder");
return false;
}
@@ -1369,7 +1393,8 @@ class PreorderController extends mfBaseController {
}
private function deleteWorkorderApi() {
if(!$this->me->is("Admin")) {
if(!$this->me->is("Admin") && !$this->me->can("preorder")) {
$this->log->debug(__METHOD__.": no permission");
return false;
}

View File

@@ -257,8 +257,10 @@ class PreordercampaignController extends mfBaseController {
if($r->oaid_origin == "ofaa") {
$data['oaid_origin'] = "ofaa";
} else {
} elseif($r->oaid_origin == "thetool") {
$data['oaid_origin'] = "thetool";
} else {
$data['oaid_origin'] = "other";
}
if($r->product_type == "setup_only") {
@@ -776,7 +778,7 @@ class PreordercampaignController extends mfBaseController {
protected function assignOpenAccessIdsToPreordersAction() {
$this->layout()->setTemplate("Preordercampaign/Admin");
$id = $this->request->id;
if(!is_numeric($id) || !$id) {
$this->layout()->setFlash("Vorbestellkampagne nicht gefunden", "error");
@@ -788,6 +790,11 @@ class PreordercampaignController extends mfBaseController {
$this->layout()->setFlash("Vorbestellkampagne nicht gefunden", "error");
$this->redirect("Preordercampaign");
}
if($campaign->oaid_origin == "other") {
$this->layout()->setFlash("Kampagne unterstützt keine OAIDs", "warning");
$this->redirect("Preordercampaign", "Admin", ["id" => $id]);
}
$assigned_oaids = 0;
$multiple_unit = 0;
@@ -865,6 +872,11 @@ class PreordercampaignController extends mfBaseController {
$this->layout()->setFlash("Vorbestellkampagne nicht gefunden", "error");
$this->redirect("Preordercampaign");
}
if($campaign->oaid_origin == "other") {
$this->layout()->setFlash("Kampagne unterstützt keine OAIDs, somit können keine Workorders erstellt werden", "warning");
$this->redirect("Preordercampaign", "Admin", ["id" => $id]);
}
$missing_units = [];
$missing_extrefs = [];
@@ -992,6 +1004,11 @@ class PreordercampaignController extends mfBaseController {
$this->layout()->setFlash("Vorbestellkampagne nicht gefunden", "error");
$this->redirect("Preordercampaign");
}
if($campaign->oaid_origin == "other") {
$this->layout()->setFlash("Kampagne unterstützt keine OAIDs", "warning");
$this->redirect("Preordercampaign", "Admin", ["id" => $id]);
}
$oaid_assigned = 0;
$missing_units = 0;
@@ -1058,6 +1075,11 @@ class PreordercampaignController extends mfBaseController {
$this->layout()->setFlash("Vorbestellkampagne nicht gefunden", "error");
$this->redirect("Preordercampaign");
}
if($campaign->oaid_origin == "other") {
$this->layout()->setFlash("Kampagne unterstützt keine OAIDs", "warning");
$this->redirect("Preordercampaign", "Admin", ["id" => $id]);
}
$oaid_updated = 0;

View File

@@ -183,7 +183,6 @@ class Termination extends mfBaseModel {
}
$bcode = $this->getProperty("building")->code;
var_dump($bcode);
if(!$bcode) {
return false;
}

View File

@@ -24,6 +24,8 @@ class WarehouseArticleController extends TTCrud {
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 8]]
];
protected array $autocompleteColumns = ['articleNumber', 'title', 'description', 'category'];
protected array $additionalActions = [
['key' => 'openHistory','title' => 'Historie','class' => 'fas fa-history text-secondary'],
['key' => 'editDistributorEntries','title' => 'Lieferanten','class' => 'fas fa-truck text-cyan'],

View File

@@ -336,6 +336,7 @@ class WarehouseEShopOrderController extends TTCrud {
$id = WarehouseEShopOrderModel::create(['status' => 'new',
'extRef' => $json['extRef'],
'deliveryMode' => $json['deliveryMode'],
'deliveryAddressAdditional' => $json['deliveryAddressAdditional'],
'deliveryAddressName' => $json['deliveryAddressName'],
'deliveryAddressLine' => $json['deliveryAddressLine'],
'deliveryAddressPLZ' => $json['deliveryAddressPLZ'],

View File

@@ -0,0 +1,9 @@
<?php
/**
* @property mixed|null $name
*/
class WarehouseOffer extends mfBaseModel
{
}

View File

@@ -0,0 +1,56 @@
<?php
class WarehouseOfferController extends TTCrud {
protected string $headerTitle = 'Angebote';
protected bool $createText = false;
protected array $columns = [
['key' => 'id', 'text' => 'ID', 'modal' => false],
['key' => 'offerNumber', 'text' => 'Angebotsnummer', 'required' => true, 'modal' => false],
['key' => 'customerNumber', 'text' => 'Kundennummer', 'required' => true, 'modal' => false],
['key' => 'customerName', 'text' => 'Kundenname', 'required' => true, 'modal' => false],
['key' => 'customerCity', 'text' => 'Stadt', 'required' => true, 'modal' => false],
['key' => 'customerVAT', 'text' => 'UID', 'required' => true, 'modal' => false],
['key' => 'editor', 'text' => 'Sachbearbeiter', 'required' => true, 'modal' => false],
['key' => 'totalAmount', 'text' => 'Gesamtbetrag', 'required' => true, 'modal' => false],
['key' => 'status', 'text' => 'Status', 'required' => true, 'modal' => ['type' => 'select']],
['key' => 'create', 'text' => 'Erstellt', 'required' => true, 'modal' => false],
['key' => 'createBy', 'text' => 'Erstellt von', 'required' => true, 'modal' => ['type' => 'select']],
['key' => 'actions',
'text' => 'Aktionen',
'required' => false,
'modal' => false,
'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
];
protected array $permissionCheck = ['WarehouseAdmin'];
protected array $additionalActions = [
['key' => 'openHistory', 'title' => 'Historie', 'class' => 'fas fa-history text-primary'],
['key' => 'sendOffer', 'title' => 'Angebot senden', 'class' => 'fas fa-paper-plane text-success']
];
protected array $infoMessages = [
'create' => 'Angebot wurde erfolgreich erstellt.',
'update' => 'Angebot wurde aktualisiert.',
'delete' => 'Angebot wurde gelöscht',
'noChanges' => 'Keine Änderungen',
'sent' => 'Angebot wurde erfolgreich gesendet',
];
protected function beforeCreate(): bool {
$currentCount = WarehouseOfferModel::count(['create' => ['from' => strtotime(date('Y-01-01'))]]);
$this->postData['offerNumber'] = 'AN' . date('Y') . '-' . str_pad($currentCount + 1, 4, '0', STR_PAD_LEFT);
return true;
}
protected function beforeUpdate($postData): bool {
(new WarehouseHistoryController)->create($postData, $this->mod);
return true;
}
protected function getHistoryAction() {
self::returnJson((new WarehouseHistoryController)->getHistory($this->request->id, $this->mod, $this->columns));
}
}

View File

@@ -0,0 +1,52 @@
<?php
/**
* Class WarehouseOfferModel
*
* Represents a warehouse offer with customer details and related metadata.
*
* @property int $id Unique identifier for the warehouse offer
* @property string $offerNumber Unique offer number
* @property string $customerNumber Customer number
* @property string $customerName Name of the customer
* @property string $customerStreet Street address of the customer
* @property string $customerCity City of the customer
* @property string $customerZip Postal code of the customer
* @property string $customerVAT VAT number of the customer
* @property int $editor ID of the editor who last modified the offer
* @property string $purpose Purpose of the offer
* @property string $positions Details about positions in the offer
* @property string $alternativePositions Details about alternative positions in the offer
* @property float $totalDiscount Total discount applied to the offer
* @property string $paymentTerms Payment terms for the offer
* @property string $deliveryTerms Delivery terms for the offer
* @property string $closingText Closing text for the offer
* @property string $notes Additional notes for the offer
* @property string $status Current status of the offer
* @property float $totalAmount Total amount of the offer
* @property int $create Timestamp of the offer creation
* @property int $createBy ID of the user who created the offer
*/
class WarehouseOfferModel extends TTCrudBaseModel {
public int $id;
public string $offerNumber;
public string $customerNumber;
public string $customerName;
public string $customerStreet;
public string $customerCity;
public string $customerZip;
public string $customerVAT;
public int $editor;
public string $purpose;
public string $positions;
public string $alternativePositions;
public float $totalDiscount;
public string $paymentTerms;
public string $deliveryTerms;
public string $closingText;
public string $notes;
public string $status;
public float $totalAmount;
public int $create;
public int $createBy;
}

View File

@@ -1,77 +1,159 @@
<?php
//TODO: enable switching distributors in the order preview
class WarehouseOrderController extends TTCrud {
protected string $headerTitle = 'Lieferantenbestellungen';
protected bool $createText = false;
protected array $columns = [
['key' => 'id', 'text' => 'ID', 'modal' => false],
['key' => 'orderNumber', 'text' => 'Bestellnummer', 'required' => true, 'modal' => false],
['key' => 'delAddrCity', 'text' => 'Stadt', 'required' => true, 'modal' => false],
['key' => 'delAddrEMail', 'text' => 'E-Mail', 'required' => true, 'modal' => false],
['key' => 'delAddrLine', 'text' => 'Adresse', 'required' => true, 'modal' => false],
['key' => 'delAddrName', 'text' => 'Name', 'required' => true, 'modal' => false],
['key' => 'delAddrPLZ', 'text' => 'PLZ', 'required' => true, 'modal' => false],
['key' => 'editor', 'text' => 'Bearbeiter', 'required' => true, 'modal' => false],
['key' => 'note', 'text' => 'Notiz', 'required' => true, 'modal' => false],
['key' => 'positions', 'text' => 'Positionen', 'required' => true, 'modal' => false],
['key' => 'create', 'text' => 'Erstellt', 'required' => true, 'modal' => false],
['key' => 'createBy', 'text' => 'Erstellt von', 'required' => true, 'modal' => ['type' => 'select']],
['key' => 'actions',
'text' => 'Aktionen',
'required' => false,
'modal' => false,
'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
];
protected array $permissionCheck = ['WarehouseAdmin'];
protected array $additionalActions = [['key' => 'openHistory', 'title' => 'Historie', 'class' => 'fas fa-history text-primary']];
//@formatter:off
protected array $columns = [
['key' => 'id', 'text' => 'ID', 'modal' => false, 'table' => false],
['key' => 'orderNumber', 'text' => 'Bestellnummer', 'required' => true, 'modal' => false],
['key' => 'distributor', 'text' => 'Lieferant', 'required' => false, 'modal' => false, 'table' => ['filter' => false]],
['key' => 'delAddrCity', 'text' => 'Stadt', 'required' => true, 'modal' => false, 'table' => false],
['key' => 'delAddrEMail', 'text' => 'E-Mail', 'required' => true, 'modal' => false, 'table' => false],
['key' => 'delAddrLine', 'text' => 'Adresse', 'required' => true, 'modal' => false, 'table' => false],
['key' => 'delAddrName', 'text' => 'Name', 'required' => true, 'modal' => false, 'table' => false],
['key' => 'delAddrPLZ', 'text' => 'PLZ', 'required' => true, 'modal' => false, 'table' => false],
['key' => 'editor', 'text' => 'Bearbeiter', 'required' => true, 'modal' => ['type' => 'select'], 'table' => ['filter' => 'select']],
['key' => 'note', 'text' => 'Notiz', 'required' => true, 'modal' => false, 'table' => false],
['key' => 'sum', 'text' => 'Summe', 'required' => false, 'modal' => false, 'table' => ['class' => 'text-right']],
['key' => 'status', 'text' => 'Status', 'required' => false, 'modal' => ['type' => 'select', 'items' => []], 'table' => ['filter' => 'select']],
['key' => 'positions', 'text' => 'Positionen', 'required' => true, 'modal' => false, 'table' => false],
['key' => 'extReference', 'text' => 'Externe Referenz', 'required' => true, 'modal' => false],
['key' => 'createBy', 'text' => 'Erstellt von', 'required' => true, 'modal' => ['type' => 'select'], 'table' => ['filter' => 'select']],
['key' => 'create', 'text' => 'Erstellt', 'required' => true, 'modal' => false],
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
];
//@formatter:on
protected array $infoMessages = ['create' => 'Bestellung wurde erfolgreich erstellt.',
'update' => 'Bestellung wurde aktualisiert.',
'delete' => 'Bestellung wurde gelöscht',
'noChanges' => 'Keine Änderungen',];
protected function prepareCrudConfig(): void {
$editorColumnIndex = array_search('editor', array_column($this->columns, 'key'));
$this->columns[$editorColumnIndex]['modal']['items'] = array_map(function ($user) {
return ['value' => intval($user->id), 'text' => $user->name];
}, UserModel::search(['employee' => true]));
$statusIndex = array_search('status', array_column($this->columns, 'key'));
$this->columns[$statusIndex]['modal']['items'] = [
['value' => 'new', 'text' => 'Neu'],
['value' => 'accepted', 'text' => 'Akzeptiert'],
['value' => 'ordered', 'text' => 'Bestellt'],
['value' => 'sent', 'text' => 'Versendet'],
['value' => 'partiallyDelivered', 'text' => 'Teilweise geliefert'],
['value' => 'fullyDelivered', 'text' => 'Geliefert'],
['value' => 'cancelled', 'text' => 'Storniert'],
];
}
protected function beforeCreate(): bool {
$currentCount = WarehouseOrderModel::count(['create' => ['from' => strtotime(date('Y-01-01'))]]);
$this->postData['orderNumber'] = 'PO' . date('Y') . '-' . str_pad($currentCount + 1, 4, '0', STR_PAD_LEFT);
$this->postData['orderNumber'] = 'PO' . date('Y') . '-' . str_pad(WarehouseOrderModel::count(['create' => ['from' => strtotime(date('Y-01-01'))]]) + 1, 4, '0', STR_PAD_LEFT);
return true;
}
protected function getArticleDistributorDataAction() {
$data = [];
$article = $this->request->articleId;
$articleId = $this->request->articleId;
if ($this->request->allDistributor === 'true') self::returnJson(array_map(fn($d) => ['id' => $d->id,
'name' => $d->name], WarehouseDistributorModel::getAll()));
else if (!empty($articleId)) self::returnJson(array_map(fn($d) => ['id' => $d->distributorId,
'name' => WarehouseDistributorModel::get($d->distributorId)->name,
'purchasePrice' => $d->purchasePrice,
'externalArticleNumber' => $d->externalArticleNumber], WarehouseArticleDistributorModel::getAll(['articleId' => $articleId])));
else self::returnJson([]);
}
if ($this->request->allDistributor === 'true') {
foreach (WarehouseDistributorModel::getAll() as $distributor) {
$data[] = [
'id' => $distributor->id,
'name' => $distributor->name,
];
}
} elseif (!empty($article)) {
foreach (WarehouseArticleDistributorModel::getAll(['articleId' => $this->request->articleId]) as $distributor) {
$data[] = [
'id' => $distributor->distributorId,
'name' => WarehouseDistributorModel::get($distributor->distributorId)->name,
'purchasePrice' => $distributor->purchasePrice,
'externalArticleNumber' => $distributor->externalArticleNumber,
];
}
protected function getByIdParse(array $order): array {
$order['positions'] = json_decode($order['positions'], true);
foreach ($order['positions'] as &$position) {
$position['distributorName'] = WarehouseDistributorModel::get($position['distributorId'])->name;
$position['articleName'] = WarehouseArticleModel::get($position['article'])->title;
}
self::returnJson($data);
return $order;
}
protected function beforeUpdate($postData): bool {
(new WarehouseHistoryController)->create($postData, $this->mod);
return true;
protected function createPDFAction() {
$order = (array) WarehouseOrderModel::get($this->request->id);
$order['positions'] = json_decode($order['positions'], true);
// check if all positions have the same distributor
$distributorId = $order['positions'][0]['distributorId'];
foreach ($order['positions'] as $key => $position) {
if ($position['distributorId'] !== $distributorId) {
self::returnJson(['error' => 'Die Bestellung enthält Positionen von verschiedenen Lieferanten.']);
}
// we need to get the article name and distributor name for the pdf
$position['distributorName'] = WarehouseDistributorModel::get($position['distributorId'])->name;
$position['articleName'] = WarehouseArticleModel::get($position['article'])->title;
$order['positions'][$key] = $position;
}
$pdf_vars = ['order' => $order,
'distributor' => WarehouseDistributorModel::get($distributorId),
"bank_iban" => TT_INVOICE_BANK_IBAN,
"bank_bic" => TT_INVOICE_BANK_BIC,
"bank_bank" => TT_INVOICE_BANK_BANK,
"bank_owner" => TT_INVOICE_BANK_OWNER];
$countryText = CountryModel::search(['id' => WarehouseDistributorModel::get($distributorId)->countryId])[0]->name;
$headerHtml = file_get_contents(BASEDIR . "/Layout/default/WarehouseOrder/PDF_HEADER.html");
$headerHtml = str_replace("{{ basedir }}", BASEDIR, $headerHtml);
$headerHtml = str_replace("{{ externalReference }}","<strong>Ihre Referenz:</strong> ". $order['extReference'], $headerHtml);
$headerHtml = str_replace("{{ addressLine_1 }}", WarehouseDistributorModel::get($distributorId)->name, $headerHtml);
$headerHtml = str_replace("{{ addressLine_2 }}", WarehouseDistributorModel::get($distributorId)->address, $headerHtml);
$headerHtml = str_replace("{{ addressLine_3 }}", WarehouseDistributorModel::get($distributorId)->plz . " " . WarehouseDistributorModel::get($distributorId)->city, $headerHtml);
$headerHtml = str_replace("{{ addressLine_4 }}", $countryText, $headerHtml);
$headerHtml = str_replace("{{ billingAddressLine_1 }}", "Xinon GmbH", $headerHtml);
$headerHtml = str_replace("{{ billingAddressLine_2 }}", "Fladnitz im Raabtal 150", $headerHtml);
$headerHtml = str_replace("{{ billingAddressLine_3 }}", "8322 Studenzen", $headerHtml);
$headerHtml = str_replace("{{ billingAddressLine_4 }}", "Österreich", $headerHtml);
$headerHtml = str_replace("{{ billingAddressLine_5 }}", "einkauf@xinon.at", $headerHtml);
$headerHtml = str_replace("{{ billingAddressLine_6 }}", "<strong>Referenz: ". $order["orderNumber"] . "</strong>", $headerHtml);
// if order dellAddrLine is Fladnitz im Raabtal 150 we need to set all template strings to empty
$chk = $order['delAddrLine'] == "Fladnitz im Raabtal 150";
$headerHtml = str_replace("{{ shippingAddressLine_1 }}", $chk ? "" : $order['delAddrName'], $headerHtml);
$headerHtml = str_replace("{{ shippingAddressLine_2 }}", $chk ? "" : $order['delAddrLine'], $headerHtml);
$headerHtml = str_replace("{{ shippingAddressLine_3 }}", $chk ? "" : $order['delAddrPLZ'] . " " . $order['delAddrCity'], $headerHtml);
$headerHtml = str_replace("{{ shippingAddressLine_4 }}", $chk ? "" : $order['delAddrEMail'], $headerHtml);
$headerFile = BASEDIR . "/var/temp/order_header-" . date("U") . "-" . rand(1000, 9999) . ".html";
file_put_contents($headerFile, $headerHtml);
$footerHtml = file_get_contents(BASEDIR . "/Layout/default/WarehouseOrder/PDF_FOOTER.html");
$footerHtml = str_replace("{{ bank_iban }}", TT_INVOICE_BANK_IBAN_FORMATTED, $footerHtml);
$footerHtml = str_replace("{{ bank_bic }}", TT_INVOICE_BANK_BIC, $footerHtml);
$footerHtml = str_replace("{{ bank_bank }}", TT_INVOICE_BANK_BANK, $footerHtml);
$footerHtml = str_replace("{{ bank_owner }}", TT_INVOICE_BANK_OWNER, $footerHtml);
$footerFile = BASEDIR . "/var/temp/order_footer-" . date("U") . "-" . rand(1000, 9999) . ".html";
file_put_contents($footerFile, $footerHtml);
$pdf = new PdfForm("WarehouseOrder/PDF_MAIN", $pdf_vars);
$wkhtmltopdfArgs = "--header-html $headerFile --footer-html $footerFile";
$filename = $pdf->render($wkhtmltopdfArgs);
// return the pdf and die so the client sees the pdf not the filename
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
readfile($filename);
}
protected function getHistoryAction() {
self::returnJson((new WarehouseHistoryController)->getHistory($this->request->id, $this->mod, $this->columns));
}
}

View File

@@ -1,5 +1,5 @@
<?php
//TODO: migration for extReference
/**
* Class WarehouseOrderModel
*
@@ -7,6 +7,7 @@
*
* @property int $id Unique identifier for the warehouse order
* @property string $orderNumber Unique order number
* @property string $extReference External reference number
* @property int $distributorId ID of the distributor associated with the order
* @property string $delAddrCity City of the delivery address
* @property string $delAddrEMail Email associated with the delivery address
@@ -22,6 +23,7 @@
class WarehouseOrderModel extends TTCrudBaseModel {
public int $id;
public string $orderNumber;
public string $extReference;
public int $distributorId;
public string $delAddrCity;
public string $delAddrEMail;

View File

@@ -0,0 +1,4 @@
<?php
class WarehouseProject extends mfBaseModel {
}

View File

@@ -0,0 +1,36 @@
<?php
class WarehouseProjectController extends TTCrud {
protected string $headerTitle = 'Projekte';
protected string $createText = 'Neues Projekt erstellen';
//@formatter:off
protected array $columns = [
['key' => 'title', 'text' => 'Titel', 'required' => true, 'table' => ['class' => 'text-nowrap', 'priority' => 9]],
['key' => 'description', 'text' => 'Beschreibung', 'required' => true, 'table' => ['class' => 'text-nowrap']],
['key' => 'createBy', 'text' => 'Erstellt von', 'required' => true, 'type' => 'select', 'table' => ['class' => 'text-nowrap', 'filter' => 'select'], 'modal' => ['items' => [], 'type' => 'select']],
['key' => 'create', 'text' => 'Erstellt am', 'required' => true, 'table' => ['filter' => 'date', 'class' => 'text-center']],
['key' => 'address', 'text' => 'Adresse', 'required' => true, 'type' => 'autocomplete', 'table' => ['class' => 'text-nowrap', 'filter' => false], 'modal' => ['apiUrl' => '/Address/api?do=findAddress', 'items' => '/Address/api?do=findAddress', 'type' => 'autocomplete']],
['key' => 'status', 'text' => 'Status', 'required' => true, 'table' => ['filter' => 'select'], 'modal' => [ 'type' => 'select', 'items' => [ ['value' => 'erstellt', 'text' => 'Erstellt'], ['value' => 'in_bearbeitung', 'text' => 'In Bearbeitung'], ['value' => 'erledigt', 'text' => 'Erledigt'], ['value' => 'verrechnet', 'text' => 'Verrechnet']]]]
];
protected array $additionalActions = [
];
protected array $infoMessages = [
'create' => 'Projekt wurde erstellt',
'update' => 'Projekt wurde aktualisiert',
'delete' => 'Projekt wurde gelöscht',
'noChanges' => 'Keine Änderungen',
];
//@formatter:on
public function prepareCrudConfig() {
$users = array_map(function($user) {
return ['value' => $user->id, 'text' => $user->name];
}, UserModel::search(['employee' => true]));
$this->columns[1]['modal']['items'] = $users;
}
}

View File

@@ -0,0 +1,15 @@
<?php
class WarehouseProjectModel extends TTCrudBaseModel {
public int $id;
public string $title;
public string $description;
public string $startDate;
public string $endDate;
public string $status;
public string $priority;
public int $assignedTo;
public int $createBy;
public int $create;
}

View File

@@ -22,24 +22,12 @@ class Workflowitem extends mfBaseModel {
public function getProperty($name) {
if($this->$name == null) {
if($name == "value") {
if(!$this->object_id) {
$this->log->warn(__CLASS__."::getProperty('value'): Object ID not set");
$this->log->debug("[Backtrace] ================");
$this->log->debug("[Backtrace] START Backtrace");
$bt = debug_backtrace();
foreach($bt as $n => $b) {
$this->log->debug($n.") ".$b["file"]."(".$b['line']."): ".$b['class']."->".$b['function']."()" );
}
$this->log->debug("[Backtrace] $sql");
$this->log->debug("[Backtrace] END Backtrace");
return null;
}
$value = mfValuecache::singleton()->get("wfItemvalue-item-".$this->id."-object-".$this->object_id);
if($this->id == 55 && $this->object_id == 509) {
var_dump($value);exit;
}
if($value) {
$this->value = $value;
return $value;

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types = 1);
use Phinx\Migration\AbstractMigration;
final class WarehouseModify12 extends AbstractMigration {
public function up(): void {
if ($this->getEnvironment() == "thetool") {
$table = $this->table("WarehouseOrder");
$table->addColumn("extReference", "string", ["length" => 255, "null" => true]);
$table->save();;
}
}
public function down(): void {
if ($this->getEnvironment() == "thetool") {
$table = $this->table("WarehouseOrder");
$table->removeColumn("extReference");
$table->save();;
}
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class CreateConstructionConsentProjectAddress extends AbstractMigration
{
public function up(): void
{
if($this->getEnvironment() == "thetool") {
$table = $this->table("ConstructionConsentProjectAddress");
$table->addColumn("constructionconsentproject_id", "integer", ["null" => false]);
$table->addColumn("address_id", "integer", ["null" => false]);
$table->addColumn("create_by", "integer", ["null" => false]);
$table->addColumn("edit_by", "integer", ["null" => false]);
$table->addColumn("create", "integer", ["null" => false]);
$table->addColumn("edit", "integer", ["null" => false]);
$table->create();
}
if($this->getEnvironment() == "addressdb") {
}
}
public function down(): void
{
if($this->getEnvironment() == "thetool") {
$this->table("ConstructionConsentProjectAddress")->drop()->save();
}
if($this->getEnvironment() == "addressdb") {
}
}
}

View File

@@ -8,7 +8,7 @@ class Helper {
* @param string $columnName The name of the column in the database table.
* @return string The SQL condition generated based on the filter value and column name.
*/
public static function generateFilterCondition($filterValue, string $columnName, bool $exactMatch = false): string {
public static function generateFilterCondition($filterValue, $columnName, bool $exactMatch = false): string {
$sql = "";
if (is_array($filterValue)) {
@@ -30,6 +30,9 @@ class Helper {
} else if (!empty($filterValue)) {
if ($exactMatch) {
$sql .= " AND `$columnName` = '" . $filterValue . "'";
} else if (strpos($columnName, "|") !== false) {
foreach (explode(" ", $filterValue) as $item)
$sql .= " AND CONCAT(" . join(",", explode("|", $columnName)) . ") LIKE '%" . str_replace("%", "", $item) . "%'";
} else if ($filterValue[0] === "%") {
$sql .= " AND `$columnName` LIKE '" . $filterValue . "'";
} else if ($filterValue[strlen($filterValue) - 1] === "%") {

36
lib/SNOPP/SNOPP.php Normal file
View File

@@ -0,0 +1,36 @@
<?php
/**
* Represents the SNOPP API.
*/
class SNOPP {
/**
* SNOPP constructor.
*/
public function __construct() {}
/**
* Search for support tickets using the SNOPP API.
* @return array - The search results.
*/
function getSNOPPTickets(): array {
$SNOPP_API_URL = SNOPP_API_URL;
$SNOPP_API_KEY = SNOPP_API_KEY;
$ctx_opts = [
'http' => [
'method' => 'GET',
'header' => "X-Api-Key: $SNOPP_API_KEY\r\n",
]
];
$snopp_output = file_get_contents("$SNOPP_API_URL/ticket/find?provider_id=all&status=open", false, stream_context_create($ctx_opts));
$ticket_obj = json_decode($snopp_output);
$tickets = $ticket_obj->result->tickets;
return $tickets;
}
}
?>

View File

@@ -10,6 +10,8 @@
* @property array $additionalJSVariables
* @property array $infoMessages
* @property bool $onlyView
* @property array $defaultOrder
* @property array $autocompleteColumns
*/
class TTCrud extends mfBaseController {
public User $user;
@@ -82,9 +84,7 @@ class TTCrud extends mfBaseController {
* @return array
*/
protected function getCrudConfig(): array {
if (method_exists($this, 'prepareCrudConfig')) {
$this->prepareCrudConfig();
}
$column = array_search('createBy', array_column($this->columns, 'key'));
if ($column !== false) {
@@ -93,6 +93,10 @@ class TTCrud extends mfBaseController {
}, UserModel::search(['employee' => true]));
}
if (method_exists($this, 'prepareCrudConfig')) {
$this->prepareCrudConfig();
}
$columns = array_map(function ($column) {
if (isset($column['type']) && (!isset($column['modal']) || !isset($column['modal']['type']))) {
@@ -251,18 +255,20 @@ class TTCrud extends mfBaseController {
}
protected function autocompleteAction() {
$searchedID = $this->request->searchedID;
$textKey = property_exists($this->model, 'name') ? 'name' : 'title';
if (strlen($searchedID) > 0) {
$filter = ['id' => $searchedID];
if (strlen($this->request->searchedID) > 0) {
$filter = ['id' => $this->request->searchedID];
$data = $this->model::getAll($filter, 10);
} else {
$filter = [$textKey => $this->request->q . '%'];
$data = $this->model::getAll($filter, 10);
if (isset($this->autocompleteColumns) && is_array($this->autocompleteColumns)) {
$filterKey = join('|', $this->autocompleteColumns);
} else {
$filterKey = $textKey;
}
$data = [];
if (count($data) < 11) {
$filter = [$textKey => $this->request->q];
$filter = [$filterKey => '%' . $this->request->q . '%'];
$lazyData = $this->model::getAll($filter, 10);
$data = array_merge($data, $lazyData);
$data = array_unique($data, SORT_REGULAR);
@@ -270,7 +276,6 @@ class TTCrud extends mfBaseController {
}
}
self::returnJson(array_map(function ($item) use ($textKey) {
return ['value' => $item->id, 'text' => $item->$textKey];
}, $data));
@@ -285,6 +290,7 @@ class TTCrud extends mfBaseController {
}
$data = (array) $this->model::get($id);
if (method_exists($this, 'getByIdParse') && !isset($_GET['disableParse'])) $data = $this->getByIdParse($data);
self::returnJson($data);
}
}

View File

@@ -81,17 +81,13 @@ class TTCrudBaseModel {
}
public static function get($id, $die= false): TTCrudBaseModel {
public static function get($id): TTCrudBaseModel {
$FronkDB = FronkDB::singleton();
$db = $FronkDB->link;
$id = $db->real_escape_string($id);
$table = self::getTable();
$sql = "SELECT * FROM `$table` WHERE `id` = $id";
if($die) {
die($sql);
}
$result = $db->query($sql);
// as TTCRudBaseModel is abstract, we need to get the class name of the child class
$class = get_called_class();
@@ -109,16 +105,16 @@ class TTCrudBaseModel {
return $result->fetch_assoc()['count'];
}
public static function getSQLFilter($filter): string {
if (empty($filter)) {
return "";
}
public static function getSQLFilter(array $filter): string {
if (empty($filter)) return '';
$sql = 'WHERE 1=1';
$calledClass = get_called_class();
$sql = "WHERE 1=1";
foreach ($filter as $key => $value) {
if (!property_exists(get_called_class(), $key)) {
http_response_code(500);
throw new Exception("Field $key does not exist in " . get_called_class());
foreach (explode('|', $key) as $column) {
if (!property_exists($calledClass, $column)) {
throw new InvalidArgumentException("Field $column does not exist in $calledClass");
}
}
$sql .= Helper::generateFilterCondition($value, $key, gettype($value) === "integer");
}

View File

@@ -58,14 +58,13 @@ class XinonProject {
* @param int $pageSize - The number of results to return.
* @return array - The search results.
*/
public function searchSupportTickets(string $search, int $pageSize = 25): array {
public function searchSupportTickets(string $search, int $pageSize = 25, $overrideQueryParams = null): array {
$curl = curl_init();
$baseUrl = 'https://project.xinon.at/api/v3/projects/10/work_packages';
$queryParams = [
'pageSize' => 25,
'filters' => json_encode([['search' => ['operator' => '**', 'values' => [$search]]]])
];
$queryParams = ['pageSize' => $pageSize, 'filters' => json_encode([['search' => ['operator' => '**', 'values' => [$search]]]])];
if (!is_null($overrideQueryParams)) $queryParams = $overrideQueryParams;
curl_setopt_array($curl, array(
CURLOPT_URL => $baseUrl . '?' . http_build_query($queryParams),

View File

@@ -0,0 +1,55 @@
Vue.component('AddressTickets', {
template: `
<tt-card>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-light">
<tr>
<th>Kundennummer</th>
<th>Erstellt am</th>
<th>Betreff</th>
<th>Letztes Update</th>
<th>Aktion</th>
</tr>
</thead>
<tbody>
<tr v-for="ticket in parsedTickets" :key="ticket.id">
<td>{{ ticket.customField7 }}</td>
<td>{{ formatDate(ticket.createdAt) }}</td>
<td>{{ ticket.subject }}</td>
<td>{{ formatDate(ticket.updatedAt) }}</td>
<td>
<a :href="'https://project.xinon.at' + ticket.activitiesHref.replace('api/v3', 'projects/storungen-and-support').replace('activities', 'activity')" class="btn btn-primary btn-sm" target="_blank">
<i class="fas fa-external-link-alt mr-1"></i>
Ticket anzeigen
</a>
</td>
</tr>
</tbody>
</table>
</div>
</tt-card>
`,
data() {
return {
window: window,
}
},
computed: {
parsedTickets() {
return this.window.TT_CONFIG.TICKETS.map(ticket => ({
id: ticket.id,
customField7: ticket.customField7,
createdAt: ticket.createdAt,
subject: ticket.subject,
updatedAt: ticket.updatedAt,
activitiesHref: ticket._links.activities.href
}));
}
},
methods: {
formatDate(dateString) {
return this.window.moment(dateString).format('DD.MM.YYYY HH:mm');
}
}
});

View File

@@ -19,7 +19,7 @@
.filters {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
grid-gap: 15px;
margin-bottom: 20px;
justify-content: center;

View File

@@ -273,6 +273,45 @@ Vue.component('radius-ont-parser', {
}
});
Vue.component('radius-online-state', {
props: ['username'],
template: `
<div>
<template v-if="data === null">
<div class="d-flex justify-content-center align-items-center">
<div class="spinner-border spinner-border-sm text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</template>
<template v-else>
<div style="border-radius: 10px;width: 110px;text-align: center;height:22px;background-color: rgba(161,253,96,0.7)"
v-if="data.online">
<span>{{ data.ip }}</span>
</div>
<div style="border-radius: 10px;width: 110px;text-align: center;height:22px;background-color: rgba(253,96,96,0.7)"
v-else>
<span>{{ data.ip }}</span>
</div>
</template>
</div>
`,
data() {
return {
data: null,
};
},
async created() {
await this.fetchOnlineState();
},
methods: {
async fetchOnlineState() {
const response = await fetch(window.TT_CONFIG['BASE_PATH'] + '/Radius/proxyUnsecureHTTPRequestToRadius?action2=fetchRadacct&username=' + this.username);
if (response.ok) this.data = await response.json();
}
}
})
Vue.component('radius', {
template: `
@@ -292,6 +331,7 @@ Vue.component('radius', {
<tt-autocomplete sm :api-url="billAddrAutoCompleteUrl" label="Rechnungsadresse" v-model="custnum" ref="billAddr"/>
<tt-input sm label="Username" name="username" v-model="username"/>
<tt-input sm label="Info" name="info" v-model="info"/>
<tt-checkbox v-model="checkOnlineState" label="Online-Status abfragen" sm/>
<tt-button sm icon="fas fa-search" text="Suchen" additional-class="btn-primary" style="justify-self:center" @click="loadRadiusUsers"/>
</div>
@@ -301,6 +341,7 @@ Vue.component('radius', {
<th>Kundennummer</th>
<th>Username</th>
<th>Info</th>
<th>Status</th>
<th>Aktionen</th>
</tr>
</thead>
@@ -317,6 +358,11 @@ Vue.component('radius', {
</a>
</td>
<td>{{ user.info }}</td>
<td>
<template v-if="checkOnlineState === 1">
<radius-online-state :username="user.username"/>
</template>
</td>
<td>
<tt-button sm icon="fas fa-sync" text="Details" @click="fetchRadacctData(user.username)" additional-class="btn-primary"/>
</td>
@@ -419,10 +465,12 @@ Vue.component('radius', {
custnum: '',
window: window,
showRadacctModal: false,
checkOnlineState: 0,
radacctData: null,
}
},
async mounted() {
console.log("hallo");
await this.loadFreeUsers();
},
methods: {
@@ -442,7 +490,11 @@ Vue.component('radius', {
});
const response = await fetch(`${window.TT_CONFIG['BASE_PATH']}/Radius/proxyUnsecureHTTPRequestToRadius?${params.toString()}`);
if (response.ok) {
this.radiusUsers = await response.json();
const users = await response.json()
if (users.length < 6) {
this.checkOnlineState = 1;
}
this.radiusUsers = users;
} else {
console.error('Failed to load radius users');
}

View File

@@ -0,0 +1,14 @@
@media (min-width: 992px) {
.modal-lg, .modal-xl {
/*max width either 90% or 1120px*/
max-width: min(90vw, 1120px) !important;
}
}
@media (max-width: 992px) {
.warehouse-order-modal-positions-entry-container {
display: grid;
grid-template-columns: 1fr 1fr !important;
grid-gap: 10px;
}
}

View File

@@ -0,0 +1,178 @@
Vue.component('warehouse-offer-modal', {
props: {
id: {type: [String, Number], required: true},
mode: {type: String, default: 'edit'}
},
template: `
<tt-modal :show="true"
@submit="submit"
:delete="id !== 'create'"
:title="id === 'create' ? 'Angebot erstellen' : \`Angebot #\${id} bearbeiten\`"
@update:show="$emit('close')">
<div style="width: 99%"><h4 class="text-center">Angebotdetails</h4>
<tt-select label="Sachbearbeiter"
:options="window.TT_CONFIG.CRUD_CONFIG.columns.find(column => column.key === 'createBy')?.modal.items"
sm
row
v-model="offer.editor"/>
<tt-input label="Kundennummer" v-model="offer.customerNumber" sm row/>
<tt-input label="Kundenreferenz" v-model="offer.reference" sm row/>
<tt-textarea label="Angebotszweck" v-model="offer.purpose" sm row/>
<hr>
<h4 class="text-center">Kundenadresse</h4>
<div style="display: grid; grid-gap: 10px; grid-template-columns: 2fr 2fr 1fr 1fr 2fr;">
<tt-input label="Name" v-model="offer.customerName" sm/>
<tt-input label="Straße" v-model="offer.customerStreet" sm/>
<tt-input label="PLZ" v-model="offer.customerZip" sm/>
<tt-input label="Ort" v-model="offer.customerCity" sm/>
<tt-input label="UID" v-model="offer.customerVAT" sm/>
</div>
<hr>
<h4 class="text-center">Positionen</h4>
<tt-positions-manager ref="positionsManager" v-model="offer.positions" :config="positionsConfig" @updateField-article="fetchArticleData"/>
<hr>
<h4 class="text-center">Alternative Artikel</h4>
<tt-positions-manager ref="alternativePositionsManager" v-model="offer.alternativePositions" :config="alternativePositionsConfig"/>
<hr>
<tt-input label="Gesamtrabatt (%)" v-model="offer.totalDiscount" sm row type="number"/>
<tt-select label="Zahlungskonditionen" :options="paymentTerms" sm row v-model="offer.paymentTerms"/>
<tt-select label="Lieferkonditionen" :options="deliveryTerms" sm row v-model="offer.deliveryTerms"/>
<tt-select label="Schlusstext" :options="closingTexts" sm row v-model="offer.closingText"/>
<hr>
<tt-textarea label="Notizen" v-model="offer.notes" sm row/>
</div>
</tt-modal>
`,
data() {
return {
window: window,
positionsConfig: {
fields: {
article: {
type: 'autocomplete',
label: 'Artikel',
apiUrl: '/WarehouseArticle/autoComplete',
customFieldReference: 'WarehouseArticle',
},
amount: {type: 'input', label: 'Menge', inputType: 'number'},
unit: {type: 'input', label: 'Einheit'},
articleNumber: {type: 'input', label: 'Artikelnummer'},
unitPrice: {type: 'input', label: 'Einzelpreis', inputType: 'number'},
discount: {type: 'input', label: 'Rabatt (%)', inputType: 'number'},
},
validateForm: (formData) => {
const requiredFields = ['article', 'amount', 'unitPrice'];
for (const field of requiredFields) {
if (!formData[field]) {
window.notify('error', `Bitte füllen Sie ${this.positionsConfig.fields[field].label} aus`);
return false;
}
}
return true;
},
},
alternativePositionsConfig: {
fields: {
article: {type: 'input', label: 'Artikel'},
description: {type: 'textarea', label: 'Beschreibung'},
},
},
paymentTerms: [
{value: 'net30', text: '30 Tage netto'},
{value: 'net60', text: '60 Tage netto'},
{value: 'immediate', text: 'Sofort fällig'},
],
deliveryTerms: [
{value: 'ex_works', text: 'Ab Werk'},
{value: 'free_delivery', text: 'Frei Haus'},
{value: 'fob', text: 'FOB'},
],
closingTexts: [
{value: 'standard', text: 'Standardtext'},
{value: 'custom1', text: 'Angepasster Text 1'},
{value: 'custom2', text: 'Angepasster Text 2'},
],
offer: {
editor: window.TT_CONFIG['USER_ID'],
customerNumber: '',
reference: '',
purpose: '',
customerName: '',
customerStreet: '',
customerZip: '',
customerCity: '',
customerVAT: '',
positions: [],
alternativePositions: [],
totalDiscount: 0,
paymentTerms: 'net30',
deliveryTerms: 'ex_works',
closingText: 'standard',
notes: '',
}
}
},
async mounted() {
if (this.id !== 'create') {
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOffer/getById`, {params: {id: this.id}});
this.offer = response.data;
this.offer.positions = JSON.parse(this.offer.positions);
this.offer.alternativePositions = JSON.parse(this.offer.alternativePositions);
}
},
methods: {
async submit() {
if (this.offer.positions.length === 0) return window.notify('error', 'Bitte fügen Sie mindestens eine Position hinzu.');
const url = this.id === 'create'
? `${window.TT_CONFIG["BASE_PATH"]}/WarehouseOffer/create`
: `${window.TT_CONFIG["BASE_PATH"]}/WarehouseOffer/update`;
const response = await axios.post(url, this.offer);
if (response.data.success) {
window.notify('success', response.data.message ?? 'Angebot erfolgreich gespeichert');
this.$emit('close');
} else {
window.notify('error',
response.data.errors ? Object.values(response.data.errors).join('<br>') : response.data.message || 'Ein Fehler ist aufgetreten');
}
},
async fetchArticleData(article) {
if (typeof article === 'number') {
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseArticle/getById`, {params: {id: article}});
this.$refs.positionsManager.updateField('articleNumber', response.data.articleNumber);
this.$refs.positionsManager.updateField('unitPrice',
Object.values(JSON.parse(response.data.cheapestSellPrice)).find(price => price.title === 'Verkauf').price);
this.$refs.positionsManager.updateField('unit', response.data.unit);
}
},
},
});
Vue.component('warehouse-offer', {
template: `
<tt-card>
<warehouse-offer-modal v-if="offerModalId" :id="offerModalId" @close="offerModalId = null;$refs.table.$refs.table.refreshTable()"/>
<button @click="offerModalId = 'create'" class="btn btn-primary">Angebot erstellen</button>
<tt-table-crud emit-edit @edit="offerModalId = $event.id" ref="table">
<template v-slot:expandedRow="{ row }">
<div>
<h5>Notizen</h5>
<p>{{ row.notes }}</p>
<h5>Verlauf</h5>
<ul>
<li v-for="entry in row.journal">{{ entry.date }} - {{ entry.description }}</li>
</ul>
</div>
</template>
</tt-table-crud>
</tt-card>
`,
data() {
return {
window: window,
offerModalId: null,
}
},
});

View File

@@ -24,4 +24,29 @@
grid-template-columns: 1fr 1fr !important;
grid-gap: 10px;
}
}
}
/* Expanded Row Styling */
.order-summary {
padding: 1rem;
}
.position-item {
margin-bottom: 1rem;
border: 1px solid #ddd;
border-radius: 4px;
}
.position-header {
background-color: #f0f0f0;
padding: 0.5rem;
font-weight: bold;
}
.position-details {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
padding: 0.5rem;
}
.field-item {
margin-bottom: 0.5rem;
}

View File

@@ -16,6 +16,7 @@ Vue.component('warehouse-order-modal', {
sm
row
v-model="order.editor"/>
<tt-input label="Externe Referenz" v-model="order.extReference" sm row/>
<hr>
<h4 class="text-center">Positionen</h4>
@@ -80,6 +81,7 @@ Vue.component('warehouse-order-modal', {
},
},
order: {
extReference: '',
delAddrName: 'XINON GmbH',
delAddrLine: 'Fladnitz im Raabtal 150',
delAddrPLZ: '8322',
@@ -92,11 +94,13 @@ Vue.component('warehouse-order-modal', {
}
},
async mounted() {
if (this.id !== 'create') {
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/getById`, {params: {id: this.id}});
response.data.positions = JSON.parse(response.data.positions);
this.order = response.data;
}
if (this.id === 'create') return;
console.log(this.id);
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/getById?disableParse`, {params: {id: this.id}});
response.data.positions = JSON.parse(response.data.positions);
this.order = response.data;
},
methods: {
async submit() {
@@ -112,18 +116,20 @@ Vue.component('warehouse-order-modal', {
positions: this.order.positions.filter(position => position.distributorId === distributorId)
}
);
if (response.data.success) window.notify('success', response.data.message ?? 'Bestellung erfolgreich erstellt');
else window.notify('error',
if (response.data.success) {
this.$emit('close');
window.notify('success', response.data.message ?? 'Bestellung erfolgreich erstellt');
} else window.notify('error',
response.data.errors ? Object.values(response.data.errors).join('<br>') : response.data.message || 'Ein Fehler ist aufgetreten');
}
} else {
const response = await axios.post(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/update`, this.order);
if (response.data.success) window.notify('success', response.data.message ?? 'Bestellung erfolgreich aktualisiert');
else window.notify('error',
if (response.data.success) {
this.$emit('close');
window.notify('success', response.data.message ?? 'Bestellung erfolgreich aktualisiert');
} else window.notify('error',
response.data.errors ? Object.values(response.data.errors).join('<br>') : response.data.message || 'Ein Fehler ist aufgetreten');
}
this.$emit('close');
},
async fetchDistributors(article) {
const url = `${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/getArticleDistributorData`;
@@ -148,22 +154,93 @@ Vue.component('warehouse-order-modal', {
},
});
Vue.component('warehouse-order', {
Vue.component('warehouse-order-detail', {
//language=Vue
template: `
<tt-card>
<warehouse-order-modal v-if="orderModalId" :id="orderModalId" @close="orderModalId = null;$refs.table.$refs.table.refreshTable()"/>
<button @click="orderModalId = 'create'" class="btn btn-primary">Bestellung erstellen</button>
<tt-table-crud emit-edit @edit="orderModalId = $event.id" ref="table">
<template v-slot:expandedRow="{ row }"><span>Work in Progress</span></template>
</tt-table-crud>
</tt-card>
`, data() {
return {
window: window,
orderModalId: null,
<template v-slot:header><h4>Bestellungsdetails für #{{ loading ? 'Laden...' : order.orderNumber }}</h4></template>
<template v-if="loading">
<div class="d-flex justify-content-center align-items-center">
<div class="spinner-border spinner-border-sm text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</template>
<template v-else>
<h3>Lieferadresse</h3>
<div>{{order.delAddrName}}</div>
<div>{{order.delAddrEMail}}</div>
<div>{{order.delAddrLine}}</div>
<div>{{order.delAddrPLZ}} {{order.delAddrCity}}</div>
<div style="display: grid; grid-gap: 10px; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;margin-top: 24px">
<div><strong>Artikel</strong></div>
<div><strong>Menge</strong></div>
<div><strong>Preis</strong></div>
<div><strong>Lieferant</strong></div>
<div><strong>Verwendung</strong></div>
<div><strong>Summe</strong></div>
</div>
<div style="display: grid; grid-gap: 10px; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;" v-for="position in order.positions">
<div>{{ position.articleName }}</div>
<div>{{ position.amount }}</div>
<div>{{ position.buyPrice }}</div>
<div>{{ position.distributorName }}</div>
<div>{{ position.verwendung }}</div>
<div>{{ position.amount * position.buyPrice }}</div>
</div>
</template>
</tt-card>
`,
props: {
id: {type: [String, Number], required: true}
},
data() {
return {
window: window,
order: {},
loading: true
}
},
})
async mounted() {
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/getById`, {params: {id: this.id}});
this.order = response.data;
this.loading = false;
},
});
Vue.component('warehouse-order', {
template: `
<tt-card>
<warehouse-order-modal v-if="orderModalId" :id="orderModalId" @close="closeOrderModal"/>
<button @click="orderModalId = 'create'" class="btn btn-primary">Bestellung erstellen</button>
<tt-table-crud emit-edit @edit="orderModalId = $event.id" ref="table">
<template v-slot:expandedRow="{ row }">
<warehouse-order-detail :id="row['id']"/>
</template>
<template v-slot:sum="{ row }">{{ calculateSum(JSON.parse(row["positions"])).toFixed(2)}} €</template>
<!-- TODO: think of a way here prob we add it to the database as field-->
<template v-slot:distributor="{ row }">{{ row.id % 2 == 0 ? 'Triotronik' : 'Discomp' }}</template>
</tt-table-crud>
</tt-card>
`,
data() {
return {
orderModalId: null,
}
},
methods: {
closeOrderModal() {
this.orderModalId = null;
this.$refs.table.$refs.table.refreshTable();
},
calculateSum(positions) {
return positions.reduce((sum, position) => sum + position.amount * position.buyPrice, 0);
}
}
});

View File

@@ -0,0 +1,14 @@
@media (min-width: 992px) {
.modal-lg, .modal-xl {
/*max width either 90% or 1120px*/
max-width: min(90vw, 1120px) !important;
}
}
@media (max-width: 992px) {
.warehouse-order-modal-positions-entry-container {
display: grid;
grid-template-columns: 1fr 1fr !important;
grid-gap: 10px;
}
}

View File

@@ -0,0 +1,161 @@
Vue.component('warehouse-project-modal', {
props: {
id: { type: [String, Number], required: true },
mode: { type: String, default: 'edit' }
},
template: `
<tt-modal :show="true"
@submit="submit"
:delete="id !== 'create'"
:title="id === 'create' ? 'Projekt erstellen' : \`Projekt #\${id} bearbeiten\`"
@update:show="$emit('close')">
<div style="width: 99%">
<h4 class="text-center">Projektübersicht</h4>
<tt-input label="Projektnummer" v-model="project.projectNumber" sm row disabled />
<tt-textarea label="Um was handelt es sich?" v-model="project.description" sm row/>
<hr>
<h4 class="text-center">Zeitraum</h4>
<div style="display: grid; grid-gap: 10px; grid-template-columns: 1fr 1fr;">
<tt-date-picker label="Startdatum" v-model="project.startDate" sm/>
<tt-date-picker label="Enddatum" v-model="project.endDate" sm/>
</div>
<hr>
<h4 class="text-center">Beteiligte Personen</h4>
<tt-select label="Personen (XINON MT)"
:options="participantsOptions"
v-model="project.participants"
sm row />
<tt-textarea label="Freitext für weitere Personen" v-model="project.additionalParticipants" sm row/>
<hr>
<h4 class="text-center">Projektübersicht</h4>
<tt-input label="Gesamtsumme des Projekts (€)" v-model.number="project.totalSum" sm row type="number"/>
<tt-positions-manager
ref="positionsManager"
v-model="project.positions"
:config="positionsConfig"
@updateField-article="fetchArticleData"
/>
<hr>
<h4 class="text-center">Lagerort</h4>
<tt-input label="Lagerort für dieses Projekt" v-model="project.storageLocation" sm row/>
<hr>
<tt-textarea label="Notizen" v-model="project.notes" sm row/>
</div>
</tt-modal>
`,
data() {
return {
window: window,
participantsOptions: [
{ value: 1, text: 'Person A' },
{ value: 2, text: 'Person B' },
{ value: 3, text: 'Person C' }
// Add more participants as needed
],
positionsConfig: {
fields: {
article: {
type: 'autocomplete',
label: 'Artikel',
apiUrl: '/WarehouseArticle/autoComplete',
customFieldReference: 'WarehouseArticle',
},
hoursRequired: { type: 'input', label: 'Benötigte Stunden', inputType: 'number' },
amountRequired: { type: 'input', label: 'Benötigte Menge', inputType: 'number' },
description: { type: 'textarea', label: 'Beschreibung' }
},
validateForm(formData) {
const requiredFields = ['article', 'hoursRequired', 'amountRequired'];
for (const field of requiredFields) {
if (!formData[field]) {
window.notify('error', `Bitte füllen Sie ${this.positionsConfig.fields[field].label} aus`);
return false;
}
}
return true;
}
},
project: {
projectNumber: '',
description: '',
startDate: null,
endDate: null,
participants: [],
additionalParticipants: '',
totalSum: 0,
positions: [],
storageLocation: '',
notes: ''
}
};
},
async mounted() {
if (this.id !== 'create') {
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseProject/getById`, { params: { id: this.id } });
this.project = response.data;
} else {
this.project.projectNumber = await this.generateProjectNumber();
}
},
methods: {
async submit() {
if (!this.project.description) return window.notify('error', 'Bitte geben Sie eine Beschreibung ein.');
const url = this.id === 'create'
? `${window.TT_CONFIG["BASE_PATH"]}/WarehouseProject/create`
: `${window.TT_CONFIG["BASE_PATH"]}/WarehouseProject/update`;
const response = await axios.post(url, this.project);
if (response.data.success) {
window.notify('success', response.data.message ?? 'Projekt erfolgreich gespeichert');
this.$emit('close');
} else {
window.notify('error', response.data.errors ? Object.values(response.data.errors).join('<br>') : response.data.message || 'Ein Fehler ist aufgetreten');
}
},
async fetchArticleData(article) {
if (typeof article === 'number') {
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseArticle/getById`, { params: { id: article } });
this.$refs.positionsManager.updateField('description', response.data.description);
}
},
async generateProjectNumber() {
const currentCount = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseProject/count`);
return `PRJ-${new Date().getFullYear()}-${String(currentCount.data + 1).padStart(4, '0')}`;
}
}
});
Vue.component('warehouse-project', {
template: `
<tt-card>
<warehouse-project-modal v-if="projectModalId" :id="projectModalId" @close="projectModalId = null;$refs.table.$refs.table.refreshTable()"/>
<button @click="projectModalId = 'create'" class="btn btn-primary">Angebot erstellen</button>
<tt-table-crud emit-edit @edit="projectModalId = $event.id" ref="table">
<template v-slot:expandedRow="{ row }">
<div>
<h5>Notizen</h5>
<p>{{ row.notes }}</p>
<h5>Verlauf</h5>
<ul>
<li v-for="entry in row.journal">{{ entry.date }} - {{ entry.description }}</li>
</ul>
</div>
</template>
</tt-table-crud>
</tt-card>
`,
data() {
return {
window: window,
projectModalId: null,
}
},
});

View File

@@ -33,6 +33,13 @@ Vue.component('tt-positions-manager', {
:api-url="window.TT_CONFIG['BASE_PATH'] + field.apiUrl"
sm
/>
<tt-textarea
v-else-if="field.type === 'textarea'"
:label="field.label"
v-model="formData[key]"
@input="$emit('updateField-' + key, $event)"
sm
/>
<tt-checkbox
v-else-if="field.type === 'checkbox'"
:label="field.label"

View File

@@ -229,6 +229,7 @@ Vue.component('tt-table', {
.isValid() ? moment.unix(row[key]).format('DD.MM.YYYY HH:mm') : moment(row[key])
.format('DD.MM.YYYY HH:mm')) : ''
}}</span>
<span v-else-if="key === 'create'">{{ window.moment(row[key] * 1000).format('DD.MM.YYYY HH:mm:ss') }}</span>
<i v-else-if="column.filter === 'iconSelect'"
:title="columns[key].filterOptions.find(option => option.value.toString() === row[key].toString())?.text"
:class="columns[key].filterOptions.find(option => option.value.toString() === row[key].toString())?.icon"></i>

View File

@@ -71,13 +71,13 @@ class AddressHelper
if (array_key_exists(3, $m)) {
$addresszusatz = trim($m[3]);
}
} elseif (preg_match('/^(\D+)\s+(\d+[a-z0-9\/&#._-]*)(?:\s+((?:gesch(?:ae|ä)ft|werkstatt|schmiede|[^ ]*garage|betrieb und wohnungen|stg|paketlogistik|cafe|pavillon|pfarrheim|[^ ]*haus|[^ ]*geb(?:ae|ä)ude|[^ ]*halle|[^ ]*schule|Öhlmühle)(?:\s+[a-z0-9]+)?))?/i', $strasse_hausnummer, $m)) {
} elseif (preg_match('/^(.+)\s+(\d+[a-z0-9\/&#._-]*)(.+)?/i', $strasse_hausnummer, $m)) {
$strasse_name = trim($m[1]);
$hausnummer_name = trim($m[2]);
if (array_key_exists(3, $m)) {
$addresszusatz = trim($m[3]);
}
} elseif (preg_match('/^(.+)\s+(\d+[a-z0-9\/&#._-]*)(.+)?/i', $strasse_hausnummer, $m)) {
} elseif (preg_match('/^(\D+)\s+(\d+[a-z0-9\/&#._-]*)(?:\s+((?:gesch(?:ae|ä)ft|werkstatt|schmiede|[^ ]*garage|betrieb und wohnungen|stg|paketlogistik|cafe|pavillon|pfarrheim|[^ ]*haus|[^ ]*geb(?:ae|ä)ude|[^ ]*halle|[^ ]*schule|Öhlmühle)(?:\s+[a-z0-9]+)?))?/i', $strasse_hausnummer, $m)) {
$strasse_name = trim($m[1]);
$hausnummer_name = trim($m[2]);
if (array_key_exists(3, $m)) {

View File

@@ -0,0 +1,353 @@
#!/usr/bin/php
<?php
if (PHP_SAPI !== 'cli') {
die("This program can only be run on the command line.\n");
}
/*
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen('/dev/null', 'w');
$STDERR = fopen('/dev/null', 'w');
*/
require("../../config/config.php");
define('mfUI',"cli");
define('FRONKDB_SQLDEBUG',false);
define("MFBASE_BYPASS_LOGIN", true);
error_reporting(E_ALL & ~(E_NOTICE | E_STRICT | E_DEPRECATED));
if(defined('MFLOCALE_TIME')) {
setlocale(LC_TIME, MFLOCALE_TIME);
}
if(defined('MFLOCALE_MONETARY')) {
setlocale(LC_MONETARY, MFLOCALE_MONETARY);
}
if(defined('MFLOCALE_NUMERIC')) {
setlocale(LC_NUMERIC, MFLOCALE_NUMERIC);
}
require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php");
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseModel.php");
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseController.php");
$me = new User(1);
define("INTERNAL_USER_ID", $me->id);
define("INTERNAL_USER_USERNAME", $me->username);
$request = array();
// Put commandline arguments into $request
if(count($argv)) {
$args=$argv;
array_shift($args); // shift scriptname off of args array
foreach($args as $i => $arg) {
if(preg_match('/^--(.+)/',$arg,$m)) {
if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) {
$request[$m[1]] = $args[$i+1];
} else {
$request[$m[1]] = true;
}
} elseif(preg_match('/^-([a-zA-Z])(.+)/', $arg, $m)) {
$request[$m[1]] = $m[2];
} elseif(preg_match('/^-([^-])/', $arg, $m)) {
if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) {
$request[$m[1]] = $args[$i + 1];
} else {
$request[$m[1]] = true;
}
}
}
}
require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php");
$log = mfLoghandler::singleton();
cli_set_process_title("thetool-adb-rimo-import-broker");
pcntl_async_signals(true);
pcntl_signal(SIGTERM, 'signalHandler');
$forkcount = 0;
$childpids = [];
if(pidislocked()) {
echo "ADB Rimo Import Broker läuft bereits (pidfile vorhanden)\n";
exit;
}
if(!lockpid()) {
$log->error(__FILE__.": Error creating lock file!");
die("Error creating lock file!\n");
}
$max_processes = 10;
$all_pids = [];
$jobs = [];
$clusters = loadClusters();
foreach($clusters as $cluster) {
$proc = [
"cluster" => $cluster["cluster"],
"cluster_id" => $cluster["cluster"]->id,
"apiOwner" => $cluster["apiOwner"],
"apiUrl" => $cluster["apiUrl"],
"apiToken" => $cluster["apiKey"],
//"pid" => false,
"processtitle" => "ADB Import ".$cluster["cluster"]->name,
"start" => false,
];
$jobs[$cluster["cluster"]->id] = $proc;
}
$all_procs = $jobs;
$fork_delay = 0;
while(1) {
//echo "while\n";
//sleep(5);
$processes = [];
$idle_proc_count = 0;
foreach($jobs as $proc) {
if($proc["start"]) {
continue;
}
$idle_proc_count++;
$processes[] = [
"cluster_id" => $proc["cluster_id"],
"pid" => false,
"processtitle" => "ADB Import ".$proc["cluster_id"],
];
}
//echo "[parent] $idle_proc_count processes to be started\n";
// if no running processes remain -> exit
if(!$idle_proc_count && !count($all_pids)) {
echo "No more idle or running processes. Exiting.\n";
break;
}
//var_dump($processes);
foreach($processes as $key => $proc) {
if($proc["pid"]) {
// process is running already, nothing to do here
echo "[parent] ".$proc["cluster_id"]." pid exists (".$proc["pid"].")\n";
continue;
}
$cluster_id = $proc["cluster_id"];
if(isset($childpids[$cluster_id])) {
echo "[parent] job for ".$proc["cluster_id"]." exists\n";
//echo "cannot start new $taskname job, because another one is running already\n";
continue;
}
// delay for 10 minutes before forking new process
if($fork_delay) {
echo "[parent] fork delay: $fork_delay\n";
$fork_delay--;
sleep(1);
break;
}
if(count($all_pids) >= $max_processes) {
echo "[parent] max processes reached. Currently ".count($all_pids)." running processes.\n";
$fork_delay = 10;
sleep(1);
break;
}
echo "[parent] forking for $cluster_id\n";
$pid = pcntl_fork();
$fork_delay = 10;
if($pid === -1) {
$log->debug("error forking");
exit;
} elseif($pid > 0) {
// in parent
$forkcount++;
$childpids[$cluster_id] = $pid;
$proc["pid"] = $pid;
$all_pids[$pid] = $proc;
$jobs[$key]["start"] = date("d.m.Y H:i:s");
} else {
// in child
$mypid = getmypid();
echo "[$mypid] Starting import for ".$proc["cluster_id"]."\n";
try {
cli_set_process_title($proc["processtitle"]);
$script_name = __DIR__ . "/rimo-import.php";
if(!file_exists($script_name)) {
echo "[$mypid] Runner $script_name not found\n";
}
echo "[$mypid] executing $script_name ".$proc["cluster_id"]."\n";
pcntl_exec($script_name, [$proc["cluster_id"]]);
//only reachable on error
echo "[$mypid] Error exec()'ing ".$proc["processtitle"]."!\n";
} catch(\Exception $e) {
// exit child process on error
echo "$mypid caught exception: " . $e->getMessage();
echo $e->getTraceAsString()."\n";
exit;
}
exit; // make sure child exits when done
}
//sleep(5);
}
if(count($all_pids)) {
$status = false;
$return_pid = pcntl_wait($status, WNOHANG);
if($return_pid) {
echo "child $return_pid returned\n";
$pid_proc = $all_pids[$return_pid];
$pid_task = $pid_proc["cluster_id"];
$childpids[$pid_task] = null;
unset($all_pids[$return_pid]);
unset($jobs[$pid_task]);
}
}
/*echo "No more PIDs, exiting loop\n";
break;*/
//sleep(5);
}
unlockpid();
function loadClusters() {
$clusters = [];
$netowners = ["estmk", "rml"];
$apiEdition = "prod";
foreach ($netowners as $apiOwner) {
$apiData = TT_RIMO_API_CREDS[$apiOwner][$apiEdition];
$apiUrl = $apiData["url"];
$apiToken = $apiData["key"];
if (!$apiUrl || !$apiToken) {
echo "Api Daten für $apiOwner unvollständig\n";
}
$epGetClusters = $apiUrl . RIMO_API_JSON_EP_GET_CLUSTERS;
$baseParams = ['apiKey' => $apiToken];
$ctxOptsGet = [
'http' => [
'method' => 'GET',
'header' => 'accept: application/json'
]
];
/*
* Get RIMO Sales Clusters
*/
$params = $baseParams;
$qs = http_build_query($params);
$req_url = $epGetClusters . "?" . $qs;
$req_ctx = stream_context_create($ctxOptsGet);
//echo $req_url."\n";
$responseText = file_get_contents($req_url, false, $req_ctx);
if ($responseText === false) {
echo "($apiOwner) Error fetching clusters\n";
exit;
}
$clustersResponse = json_decode($responseText);
//var_dump($clustersResponse);
//exit;
if (!is_object($clustersResponse) || !property_exists($clustersResponse, "item") || !is_array($clustersResponse->item) || !count($clustersResponse->item)) {
die("($apiOwner) Invalid GetClusters Response\n");
}
foreach ($clustersResponse->item as $cluster) {
$cluster_data = ["apiOwner" => $apiOwner, "apiKey" => $apiToken, "apiUrl" => $apiUrl, "cluster" => $cluster];
$clusters[] = $cluster_data;
}
}
return $clusters;
}
function signalHandler($sig) {
//global $continue;
global $childpids;
global $invoice_job_lock;
//$continue = false;
//echo "in signal handler\n";
if(count($childpids)) {
foreach($childpids as $taskname => $pids) {
foreach($pids as $childpid) {
posix_kill($childpid, SIGTERM);
}
}
}
unlockpid();
exit;
}
function client_log($pid, $text, $severity = "notice") {
global $log;
global $is_daemon;
if($is_daemon) {
echo "[".date('Y-m-d H:i:s')."] [$pid] $text\n";
}
$log->$severity($text);
return true;
}
function pidislocked() {
$pidfile = __DIR__."/.adb-rimo-import-broker.lock";
if(file_exists($pidfile)) {
return true;
}
return false;
}
function lockpid() {
$pid = getmypid();
$pidfile = __DIR__."/.adb-rimo-import-broker.lock";
file_put_contents($pidfile, $pid);
if(file_exists($pidfile)) {
return true;
}
return false;
}
function unlockpid() {
$pidfile = __DIR__."/.adb-rimo-import-broker.lock";
if(file_exists($pidfile)) {
unlink($pidfile);
return true;
}
return false;
}

View File

@@ -46,9 +46,11 @@ if ($argc > 1) {
//$netowners = ["estmk", "rml"];
$netowners = ["estmk", "rml"];
//$netowners = ["sbidi"];
//$netowners = ["rml"];
$apiEdition = "prod";
$startdate = date("Y-m-d");
$starttime = date("Y-m-d.H-i");
$clusters = [];
@@ -188,6 +190,11 @@ foreach ($clusters as $cluster_data) {
}
}
$preorder_only_oaid = false;
$preorder_only_oaid = $adb_netzgebiet->getOption("preorder_only_oaid");
$option_wo_ignore_status = $adb_netzgebiet->getOption("wo_ignore_status");
$AddressHelper = new ADBAddressHelper\AddressHelper(["log" => $log, "db" => $adb, "netzgebiet" => $adb_netzgebiet]);
/*
@@ -436,7 +443,13 @@ foreach ($clusters as $cluster_data) {
$rimo_oaid = $home->ftus->item[0]->oaidObject->name;
$oaid = \OpenAccessIdModel::getFirst(["oaid" => $rimo_oaid]);
if (!$oaid) {
echo "!!! Home hat fremde OAID: $rimo_oaid (Home " . $unit->id . "\n";
if($preorder_only_oaid) {
// if campaign oaid handling "other" just import OAID and nothing else
$unit->oaid = $rimo_oaid;
$unit->save();
} else {
echo "!!! Home hat fremde OAID: $rimo_oaid (Home " . $unit->id . "\n";
}
} else {
$unit->oaid = $rimo_oaid;
@@ -471,7 +484,7 @@ foreach ($clusters as $cluster_data) {
}
} else {
//
// TODO maybe check if OAIDs match?
}
}
}
@@ -688,8 +701,8 @@ foreach ($clusters as $cluster_data) {
//echo "Updating Workorder $rimo_workorder_id ($workorder_home_id)\n";
if ($workorder_status != $wo->rimo_status) {
\mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0);
\mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$unit->id, 0);
//\mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0);
\mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$wo_home->id, 0);
$wo->rimo_status = $workorder_status ?: "";
$wo->save();
}
@@ -709,8 +722,10 @@ foreach ($clusters as $cluster_data) {
continue;
}
\mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0);
\mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$unit->id, 0);
//if(($option_wo_ignore_status == "Documented" && $workorder_status == "Documented") || $workorder_status == "Cancelled") continue; // dont import status > Executed
//\mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0);
\mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$wo_home->id, 0);
//echo "Creating Workorder $rimo_workorder_id ($workorder_home_id)\n";
$wo = \RimoWorkorderModel::create([
"adb_wohneinheit_id" => $wo_home->id,
@@ -731,7 +746,7 @@ foreach ($clusters as $cluster_data) {
if ($addressErrors) {
$netzname = preg_replace('/[^a-z0-9.-]/i', "_", $adb_netzgebiet->name);
$out_folder = dirname(__FILE__) . "/output/$starttime";
$out_folder = dirname(__FILE__) . "/output/$startdate";
if (!file_exists($out_folder)) {
mkdir($out_folder);
}

View File

@@ -0,0 +1,49 @@
"rot",
"gruen",
"blau",
"gelb",
"weiss",
"natur",
"grau",
"braun",
"violett",
"tuerkis",
"schwarz",
"orange",
"rosa",
"rot-1R",
"gruen-1R",
"blau-1R",
"gelb-1R",
"weiss-1R",
"grau-1R",
"braun-1R",
"violett-1R",
"tuerkis-1R",
"schwarz-1R",
"orange-1R",
"rosa-1R",
"Rot-Gelb",
"Rot-Gruen",
"Rot-Blau",
"Rot-Violett",
"Rot-Grau",
"Gelb-Blau",
"Gelb-Violett",
"Gelb-Grau",
"Gruen-Blau",
"Gruen-Violett",
"Gruen-Grau",
"Braun-Blau",
"Braun-Violett",
"Braun-Grau",
"Braun-Gruen",
"Braun-Gelb",
"Braun-Rot",
"Schwarz-Rot",
"Schwarz-Gelb",
"Schwarz-Gruen",
"Schwarz-Blau",
"Schwarz-Violett",
"Schwarz-Grau",
"Schwarz-Braun",

View File

@@ -17,9 +17,8 @@ define("INTERNAL_USER_USERNAME", $me->username);
define("MFBASE_BYPASS_LOGIN", true);
$folder = __DIR__."/source";
$filename = "$folder/Leska-fixed.csv";
$filename = "$folder/Export Ly 04022025.csv";
$db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
$log = mfLoghandler::singleton();
$input = fopen($filename, "r");
@@ -30,6 +29,67 @@ $lineworker_id = 1;
$zip = 8160;
$city = "Mortantsch";
$buildingtypes = [
1 => 1, // Einfamilienhaus
2 => 2 // Zweifamilienhaus
];
$buildingstatus = [
"geplant" => 2,
"Rohr am Grundstück" => 4,
"Rohr im Haus" => 5,
"Kabel eingeblasen" => 5,
];
$terminationstatus = [
"geplant" => 1,
"Rohr am Grundstück" => 1,
"Rohr im Haus" => 1,
"Kabel eingeblasen" => 4,
];
$colors = [
"rt" => "rot",
"gn" => "gruen",
"bl" => "blau",
"ge" => "gelb",
"ws" => "weiss",
"natur" => "natur",
"gr" => "grau",
"br" => "braun",
"vi" => "violett",
"tr" => "tuerkis",
"sw" => "schwarz",
"or" => "orange",
"rs" => "rosa",
"rt|ge" => "Rot-Gelb",
"rt|gn" => "Rot-Gruen",
"rt|bl" => "Rot-Blau",
"rt|vi" => "Rot-Violett",
"rt|gr" => "Rot-Grau",
"ge|bl" => "Gelb-Blau",
"ge|vi" => "Gelb-Violett",
"ge|gr" => "Gelb-Grau",
"gn|bl" => "Gruen-Blau",
"gn|vi" => "Gruen-Violett",
"gn|gr" => "Gruen-Grau",
"br|bl" => "Braun-Blau",
"br|vi" => "Braun-Violett",
"br|gr" => "Braun-Grau",
"br|gn" => "Braun-Gruen",
"br|ge" => "Braun-Gelb",
"br|rt" => "Braun-Rot",
"sw|rt" => "Schwarz-Rot",
"sw|ge" => "Schwarz-Gelb",
"sw|gn" => "Schwarz-Gruen",
"sw|bl" => "Schwarz-Blau",
"sw|vi" => "Schwarz-Violett",
"sw|gr" => "Schwarz-Grau",
"sw|br" => "Schwarz-Braun",
];
$existing_count = 0;
$l = 0;
while($csv = fgetcsv($input, 0)) {
$l++;
@@ -39,8 +99,6 @@ while($csv = fgetcsv($input, 0)) {
continue;
}
//var_dump($csv);exit;
$address = trim($csv[0]);
$unit_count = trim($csv[1]);
$status = trim($csv[2]);
@@ -48,6 +106,7 @@ while($csv = fgetcsv($input, 0)) {
$rohrname = trim($csv[4]);
$gps_long = trim($csv[11]);
$gps_lat = trim($csv[12]);
$contact_name = trim($csv[14]);
$farbe2 = trim($csv[18]);
$farbe3 = trim($csv[20]);
$fcp_name = trim($csv[22]);
@@ -59,7 +118,6 @@ while($csv = fgetcsv($input, 0)) {
if($address == "Leska 25 Haus 25a Altbau") continue;
$m = [];
//
if(!preg_match('/(.+)\s+(\.?\d+[a-z0-9\/&#._-]*|Ost)(.+)?/', $address, $m)) {
echo "adresse nicht gefunden\n";
continue;
@@ -79,62 +137,127 @@ while($csv = fgetcsv($input, 0)) {
echo "$address => $street - $housenumber\n";
$existing_building = BuildingModel::getFirst(["street" => $address ]);
$existing_building = BuildingModel::getFirst(["=street" => $address ]);
if($existing_building) {
echo "===========FOUND $address: ".$existing_building->street.", ".$existing_building->zip." ".$existing_building->city."\n";
$existing_count++;
$building = $existing_building;
$building_id = $existing_building->id;
//var_dump($existing_building);exit;
}
$buildingtypes = [
1 => 1, // Einfamilienhaus
2 => 2 // Zweifamilienhaus
];
$buildingstatus = [
"geplant" => 2,
"Rohr am Grundstück" => 4,
"Rohr im Haus" => 5,
"Kabel eingeblasen" => 5,
];
if(!$existing_building) {
$building_data = [
"network_id" => $network_id,
"pop_id" => $pop_id,
"type_id" => $buildingtypes[$unit_count],
"status_id" => $buildingstatus[$status],
"lineworker_id" => $lineworker_id,
"street" => $address,
"zip" => $zip,
"city" => $city,
"gps_lat" => $gps_lat,
"gps_long" => $gps_long,
"oaid" => "",
"contact" => "",
"phone" => "",
"email" => "",
"units" => 0,
"note" => "",
];
$terminationstatus = [
"geplant" => 1,
"Rohr am Grundstück" => 1,
"Rohr im Haus" => 1,
"Kabel eingeblasen" => 4,
];
$building = BuildingModel::create($building_data);
$building->code = $building->getNewObjectCode();
$building_data = [
"network_id" => $network_id,
"pop_id" => $pop_id,
"type_id" => $buildingtypes[$unit_count],
"status_id" => $buildingstatus[$status],
"lineworker_id" => $lineworker_id,
"street" => $address,
"zip" => $zip,
"city" => $city,
"gps_lat" => $gps_lat,
"gps_long" => $gps_long,
"oaid" => "",
"contact" => "",
"phone" => "",
"email" => "",
"units" => "hallo",
"note" => "",
];
$building = BuildingModel::create($building_data);
$building_id = $building->save();
if(!$building_id) {
//var_dump($building);
//var_dump($building_id);
die("Error saving building");
if(!$building->save()) {
var_dump($building);
die("Error saving building\n");
}
$building_id = $building->id;
}
// workflow stuff
foreach($building->workflowitems as $wftype => $wfitem) {
if($wfitem->value && ($wfitem->value->value_string || $wfitem->value->value_int)) continue;
$wfitem->value->create_by = $me->id;
$wfitem->value->edit_by = $me->id;
if($wftype == "rohrfarbe") {
if(!$farbe1 && !$farbe2 && !$farbe3) continue;
if($farbe3) {
$farbe = $farbe3;
} elseif($farbe2) {
$farbe = $farbe2;
} else {
$farbe = $farbe1;
}
$m = [];
if(preg_match('/^\d+-(.+)$/', $farbe, $m)) {
$fb_code = $m[1];
}
if(!$fb_code) {
echo "Keine Farbe\n";
continue;
}
if(!array_key_exists($fb_code, $colors)) {
echo "Unbekannter Farbcode\n";
continue;
}
$wfitem->value->setValue($colors[$fb_code]);
}
if($wftype == "rohrverband_name") {
$wfitem->value->setValue($rohrname);
/*$wfvalue = WorkflowvalueModel::create([
"value_string" => $rohrname,
]);*/
}
if($wftype == "anschlusspunkt_typ") {
$wfitem->value->setValue("Verteiler");
}
if($wftype == "anschlusspunkt_name") {
$wfitem->value->setValue($fcp_name);
}
if($wftype == "rohrtype") {
$wfitem->value->setValue("MR7/4");
}
if($wfitem->value && ($wfitem->value->value_string || $wfitem->value->value_int || $wfitem->value->value_text)) {
//var_dump($wfitem->value);
$wfitem->value->save();
}
}
exit;
if(!$unit_count || $existing_building) continue;
for($i = 0; $i < $unit_count; $i++) {
$unit_data = [
"building_id" => $building->id,
"status_id" => $terminationstatus[$status],
"contact" => ($contact_name) ?: null
];
$unit = TerminationModel::create($unit_data);
$unit->code = $unit->getNewObjectCode();
//var_dump($unit);exit;
if(!$unit->save()) {
var_dump($unit);
die("Error saving unit\n");
}
}
}
}

View File

@@ -0,0 +1,136 @@
Adresse,NE,Status,Abzwfarbe,Abzwrohr,UUID,VerknID,Bezirk,TTObjectID,X-GKM34,Y-GKM34, X-WGS84,Y-WGS84,TTStatus,Name,Telefon,Kommentar,Foerderung,Abzwfarbe2,FFGplan,AbzfGabG31,Spleiß_PO,FCP_Name
Leska 59,"1",Rohr im Haus,12-rs,R003,5946f2295c0b493390a18a0d017278bb},"140",WZ,,"-56145.281545406535","231663.33203257978","15.590930871898646","47.22160540259269",,,,,,,NULL,,,F011-G31
Leska 60,"1",Rohr im Haus,2-gn,R003,1301e3f777ec44aeb276a1a83c083a49},"140",WZ,,"-56153.02193021558","231653.6073107428","15.590829911419092","47.22151727359594",,,,,,,NULL,,,F011-G31
Leska 33,"1",Rohr im Haus,9-tr,R003,dc295bbb1b69473eb3544c61e5f66b62},"140",WZ,,"-56144.01784626319","231649.98266880997","15.590949237470126","47.22148544674893",,,,,,,NULL,,,F011-G31
Leska 24,"2",Rohr im Haus,7-br,R003,660986f46e1d4fdf9f989c34b5a9003e},"140",WZ,,"-56188.51234112327","231616.3600275327","15.590366076117512","47.2211792220983",,,,,,11-or,NULL,,,F011-G31
Leska 43,"1",Rohr im Haus,5-ws,R003,1656c73fa81d42e2acc04c86088fbc0d},"140",WZ,,"-56110.03239893667","231619.99135923872","15.59140168067953","47.22121862187798",,,,,,,NULL,,,F011-G31
Leska GST 221-1,"2",geplant,6-gr,R003,ac0ac5e440a24b61b912b573068e0ed4},"140",WZ,,"-56127.44718610768","231613.94992459638","15.591172538423258","47.22116279042543",,,,,,,NULL,,,F011-G31
Leska GST 221-2,"2",geplant,1-rt,R003,67af3eefdb6d4093833ff0f0aa317455},"140",WZ,,"-56139.81422640596","231585.31213539792","15.591012882746124","47.22090416000211",,,,,,,NULL,,,F011-G31
Leska 71,"2",Rohr im Haus,3-bl,R003,b14a91ebe89f4aad9516a78f734a104c},"140",WZ,,"-56115.33581461235","231577.90204806472","15.5913369691158","47.22083961483815",,,,,,,NULL,,,F011-G31
Leska 22,"2",Rohr im Haus,8-vi,R003,c41720429f2147bdbad4cb199bdd2f9c},"140",WZ,,"-56078.21026293475","231577.6259596684","15.591827118040607","47.22084031687849",,,,,,,NULL,,,F011-G31
Leska 42,"1",Rohr am Grundstück,4-ge,R003,294faff6974f45e9b19d8ca8f785ba77},"140",WZ,,"-56073.387252066736","231570.98986820615","15.591891624518428","47.22078104539795",,,,,,,NULL,,,F011-G31
Leska 41,"1",Rohr am Grundstück,10-sw,R003,7be0b75e9ffd479486c8b5e69c54497d},"140",WZ,,"-56062.84489983031","231577.227293473","15.592030014566573","47.22083804892475",,,,,,,NULL,,,F011-G31
Leska 39,"1",geplant,,R004,c630f799c91e402e90117065397ff22d},"140",WZ,,"-56040.237180976066","231614.83069778598","15.592323740398287","47.22117819265921",,,,,,,NULL,4-rt|vi,,F011-G31
Leska 35,"1",geplant,,R004,784d3bdb3e7643ccbb407c92b4515b0d},"140",WZ,,"-56013.40955121039","231606.6106540151","15.592678942187908","47.2211065602874",,,,,,,NULL,3-rt|bl,,F011-G31
Leska 40,"1",geplant,,R004,fdbef64e3c4045019169e8f55d776a03},"140",WZ,,"-55995.05955120352","231622.68065404333","15.592919171487441","47.221252665926365",,,,,,,NULL,2-rt|gn,,F011-G31
Leska Ost,"1",geplant,,R004,085a0a817b70455e8f5f9a167d2946c1},"140",WZ,,"-56022.029378532665","231580.23411969002","15.592568463910272","47.22086859076428",,,,,,,NULL,??,,F011-G31
Leska 25,"1",geplant,,,0d6b73df03d04df29e9e3b27c94b5781},"140",WZ,,"-56033.53955125866","231574.96065394953","15.592417175233328","47.22082017481332",,,,,,,NULL,,,F011-G31
Leska 25a,"1",geplant,,,87d91bc5e5e548fbb72f3b828bfcc821},"140",WZ,,"-56031.95909655142","231558.78303816915","15.592440074563145","47.22067480849041",,,,,,,NULL,,,F011-G31
Leska 37,"2",geplant,,,95951feb467e4aa89d4014729b200a23},"140",WZ,,"-56049.35955132048","231552.90065390524","15.592211102724864","47.22062041084681",,,,,,,NULL,,,F011-G31
Leska 29,"1",geplant,,,1f7005bef1714e1ca4dbee86fa179d42},"140",WZ,,"-56008.81955120256","231540.55065386742","15.592747843547063","47.22051280864163",,,,,,,NULL,,,F011-G31
Leska 49,"1",geplant,,R002,33a662f0c0c8486e9dd9aee116925407},"140",WZ,,"-55994.82065718405","231511.64122318942","15.592936283232005","47.22025399566092",,,,,,,NULL,16-br|ge,,F011-G31
Leska 67,"1",geplant,,,66d3079e1de14d3ba177aa8d58cd0dcf},"140",WZ,,"-55922.245431603376","231622.81222712528","15.593880420807363","47.221260081170186",,,,,,,NULL,,,F011-G31
Leska 68,"1",geplant,,,87cd91bc5c584e0d9c25e15740020abf},"140",WZ,,"-55892.830030556994","231618.12093306333","15.59426934111539","47.22122040283545",,,,,,,NULL,,,F011-G31
Leska 31,"1",Rohr im Haus,6-gr,R001,158b189727774bdd85fa9e66f87d8b9a},"140",WZ,,"-56028.75339456757","231660.63175547402","15.59246958398472","47.221591112317455",,Schellnegger,,,,,NULL,14-br|gr,,F011-G31
Leska 58,"1",Rohr im Haus,1-rt,R001,4bfaf68012844dccb305edc9529865db},"140",WZ,,"-56109.26356875655","231651.94038763712","15.5914078061142","47.22150603788694",,Weber,,,,,NULL,2-rt|gn,,F011-G31
Leska 36,"2",Rohr im Haus,2-gn,R001,0f458d9bb64249e89b44cf30f17fd357},"140",WZ,,"-56082.490820467734","231629.06441983432","15.591764131989601","47.221302588063715",,Wünscher K.,,,,,NULL,11-gn|gr,,F011-G31
Leska 50,"1",Rohr im Haus,3-bl,R001,4bc4e8d7864a43a5acc8e3fd0ad6a31b},"140",WZ,,"-56059.80403675831","231639.7780285044","15.592062286595974","47.22140089198985",,Stöbel,,,,,NULL,21-sw|bl,,F011-G31
Leska GST 226/5 (56),"2",geplant,5-ws,R001,ecc9b56f0e0c4b0d857866fb77c24a54},"140",WZ,,"-56066.13869770958","231653.84122362765","15.591976888389103","47.22152683342109",,,,,,,NULL,13-br|vi,,F011-G31
Leska 55 - GST 226/4,"2",Rohr am Grundstück,7-br,R001,399a61a8c6cd4984af26a2a4f451b857},"140",WZ,,"-56075.55366324877","231685.1952304519","15.591848647679308","47.22180802442859",,Schaffler,,,,,NULL,17-br|rt,,F011-G31
Leska 54,"1",Rohr im Haus,8-vi,R002,1902084715cc4ea19d7977a6fca9db0b},"140",WZ,,"-56128.72170297154","231695.11533498953","15.591145485347903","47.221892683847166",,Fladischer,,,,,NULL,22-sw|vi,,F011-G31
Leska 53,"1",Rohr im Haus,9-tr,R002,965682a626da4563b0d8d99d2de5baad},"140",WZ,,"-56163.66881100664","231703.30622472466","15.590683088165084","47.22196335178929",,Hutter,,,,,NULL,10-gn|vi,,F011-G31
Leska 52,"1",Rohr im Haus,1-rt,R002,e01be9b11cd44131b31c07f52b38de5f},"140",WZ,,"-56200.36682952387","231685.30778027754","15.590200878856832","47.22179832018924",,Mosbacher,,,,,NULL,5-rt|gr,,F011-G31
Leska 51,"1",geplant,2-gn,R002,3ccce200c78e4b48ab6292583cb6b5ca},"140",WZ,,"-56203.1534214638","231662.7213923486","15.590166940742934","47.221594938424836",,Kaufmann,,,,,NULL,20-sw|gn,,F011-G31
Leska 48,"1",geplant,4-ge,R002,7c759b0d214249e6ab9b30c475795beb},"140",WZ,,"-56206.65396634192","231645.8712405312","15.590122853713176","47.221443087047376",,Lackner,,,,,NULL,19-sw|ge,,F011-G31
Leska 32,"1",geplant,5-ws,R002,9a55c2785b4c42b8bcf4d14617ef924e},"140",WZ,,"-56242.200653718166","231622.5035638612","15.589656528234375","47.221229861210766",,Riedler,,,,,NULL,15-br|gn,,F011-G31
Leska 47,"1",geplant,3-bl,R002,f5e534a3b5f24938b04b88de8d81a262},"140",WZ,,"-56263.0744784181","231634.05625544087","15.589379500719186","47.221331970400826",,Macher,,,,,NULL,6-ge|bl,,F011-G31
Leska GST 226/6 (57),"2",Rohr im Haus,4-ge,R001,eb429601e41c43b3bf5d93b9851a141a},"140",WZ,,"-56071.312148422134","231645.525804857","15.59190963675863","47.22145160076991",,,,,,,NULL,7-ge|vi,,F011-G31
Haselbach bei Weiz 2,"1",geplant,,R007,c26e4733ffd64c779ede960601ae03c7},"155",WZ,,"-57061.24955350514","232290.60065554455","15.578758185948766","47.22716775346716",,,,,,,NULL,1-rt|ge,,F101-G31
Haselbach bei Weiz 1,"1",geplant,,R007,21654400800b44268fbb9dbaf597058a},"155",WZ,,"-57005.94955343299","232250.93065545894","15.579493393384412","47.22681578655333",,,,,,,,2-rt|gn,,F101-G31
Leska 4a,"1",geplant,,R007,b5c2dfa923234c2baeffb958783c386b},"155",WZ,,"-56929.41955319794","232035.0106549943","15.580531417406736","47.224880473910844",,,,,,,NULL,3-rt|bl,,F101-G31
Leska 4,"1",geplant,,,f215425b109849db8e35103ea07b4fe5},"155",WZ,,"-56895.2491423057","232045.87516137492","15.580981164499747","47.22498116360448",,,,,,,NULL,4-rt|vi,,F101-G31
Leska 45,"1",geplant,,,f56cf9440dcc4e63ae57667433305aa7},"155",WZ,,"-56951.989553235006","231979.7106548706","15.58024050797209","47.2243811408093",,,,,,,NULL,7-ge|vi,,F101-G31
Leska 2,"1",geplant,,R006,554270b965d546ab826b8b0ab8c198fc},"155",WZ,,"-57263.139553948975","232217.8206554018","15.576101978356826","47.226495519787896",,,,,,,NULL,1-rt|ge,,F101-G31
Leska 9,"1",geplant,,R006,73466165db08487689ce8dc56cc26687},"155",WZ,,"-57177.23955375212","232130.03065520432","15.577247377224392","47.2257134565094",,,,,,,NULL,2-rt|gn,,F101-G31
Leska 28,"1",geplant,,R006,547139ee0f5a413dbfdfe3160c8eb7d4},"155",WZ,,"-57092.95955354581","232022.58065497037","15.578373874405916","47.22475441832837",,,,,,,NULL,3-rt|bl,,F101-G31
Leska 44,"1",geplant,,R005,04a83cd9ae474b7ea1f62af297b9cf32},"155",WZ,,"-56949.74955324256","231951.56065481622","15.580273680523158","47.224128155182356",,,,,,,,3-rt|bl,,F101-G31
Leska 13,"1",geplant,,R001,cf54d54b272d4a4081f1b353cba0e3c5},"155",WZ,,"-56921.689553196265","231934.56065477896","15.580646309994998","47.2239777008744",,,,,,,NULL,3-rt|bl,,F101-G31
Leska 38,"1",geplant,,R005,ef49fc227add48989dcda96154aa0496},"155",WZ,,"-56938.31955320957","231945.11065479834","15.580425407496504","47.22407113944173",,,,,,,NULL,4-rt|vi,,F101-G31
Leska 3,"1",geplant,,R001,bb44c26dfc904879b19d56e5d86dfae9},"155",WZ,,"-56874.83717409521","231947.72491595056","15.581263187247378","47.2241001773665",,,,,,,NULL,2-rt|gn,,F101-G31
Leska 63,"1",geplant,,R001,15418070596142d8bf8f9cb0e6b40156},"155",WZ,,"-56854.22591229741","231915.34672115184","15.581539436398232","47.22381076081135",,,,,,,NULL,,,F101-G31
Leska 34,"1",geplant,,R001,628a4538a27e441994e3eeb0944fb185},"155",WZ,,"-56897.36955313191","231904.2906547077","15.580971256074722","47.2237075696472",,,,,,,NULL,7-ge|vi,,F101-G31
Leska 26a,"1",geplant,,R001,756f8806e53f4c36b4a0df236968aa7c},"155",WZ,,"-56843.269552992744","231887.32065466326","15.58168766148532","47.22355964725039",,,,,,,NULL,5-rt|gr,,F101-G31
Leska 26,"1",geplant,,R001,0faa81357e2e43d08bf055857efd507e},"155",WZ,,"-56856.32749450881","231888.16143333632","15.581515160909937","47.22356607383624",,,,,,,NULL,6-ge|bl,,F101-G31
Leska 27,"1",geplant,,R001,16b6a8995565452b8e62d096fcf2f4b3},"155",WZ,,"-56848.039553011906","231858.58065460902","15.581628355073194","47.22330074522336",,,,,,,NULL,4-rt|vi,,F101-G31
Mortantsch 24,"1",geplant,,R001,3f122b8c86cf4137a7a5fd8847819576},"157",WZ,,"-57475.41955435836","231295.25065345783","15.573418299892829","47.218179320299946",,,,,,,NULL,1-rt,,F142
Mortantsch 25,"1",geplant,,R001,7cbe6fc937e64004a7b0f8328e6fdf2f},"157",WZ,,"-57380.11955408856","231221.78065329418","15.574685799144671","47.217526900603524",,,,,,,NULL,2-gn,,F142
Leska 1,"1",geplant,,R002,9d48cc5fdbc74dd090fcd6d2ad9b02d6},"157",WZ,,"-57443.909554293605","231552.0406540064","15.573801150136687","47.22049165330622",,,,,,,NULL,?,,F142
Leska 8,"1",geplant,,R005,5f084197279a4355b9d50f8b3c1b1e73},"156",WZ,,"-56783.18918947916","231807.01277170517","15.582491090832463","47.222842579236044",,,,,,,NULL,direkt,,F080-G31
Leska 5,"2",geplant,,R004,c785c9b38ee04cf9a7e3ff915ba5f502},"156",WZ,,"-56697.37463551392","231923.92917702533","15.58360913274662","47.223901571840344",,,,,,,NULL,5-rt|gr,,F080-G31
Leska 6,"1",geplant,,R004,c0d7cdef440e498bb4e876e52a67bf07},"156",WZ,,"-56715.474530867745","231807.97961095348","15.583384936908617","47.22285715218472",,,,,,,NULL,4-rt|vi,,F080-G31
Leska 16,"1",Kabel eingeblasen,,R004,de890a54b38d4c56a599b94b16620728},"156",WZ,AT-8160-267e3e51,"-56676.26955267117","231804.76065448485","15.583902930968282","47.22283160045513",,,,,,,NULL,3-rt|bl,,F080-G31
Leska 7a,"1",geplant,,R004,68acd1dc001e496abcd880eb9ded2a25},"156",WZ,,"-56713.009552714204","231767.18065440282","15.583422674067206","47.22249042033517",,,,,,,NULL,2-rt|gn,,F080-G31
Leska 14,"1",geplant,,R004,28c54a9ad8674327a4c3daa77511d49d},"156",WZ,,"-56699.72521198267","231747.69053174648","15.583600533693598","47.22231627834308",,,,,,,NULL,1-rt|ge,,F080-G31
Leska 11,"2",geplant,8-vi,R002,b0f19181817d4a209c04b2fa963efff3},"156",WZ,,"-56794.009552900985","231574.2806540057","15.582377912378865","47.2207484478414",,,,,,,NULL,1-rt,,F080-G31
Leska 10,"1",Kabel eingeblasen,,R001,75dcee1ad24c4900af93c6cba23b0e1c},"156",WZ,AT-8160-beaffbe2,"-56774.90955290512","231723.15065431595","15.582611087354392","47.222089042773604",,,,,,,NULL,4-rt|vi,,F080-G31
Leska 46,"1",geplant,,R001,bce7ab0d0bfb42b899f810a2deea1803},"156",WZ,,"-56760.66955280146","231706.5106542781","15.582801201497816","47.22194061898817",,,,,,,NULL,11-gn|gr,,F080-G31
Leska 21,"1",geplant,,R001,0fa5394d64ce4d7d9cf8ad34d8c58911},"156",WZ,,"-56688.27981595987","231699.5109452363","15.583757765723316","47.22188394365145",,,,,,,NULL,3-rt|bl,,F080-G31
Leska 15,"1",geplant,,R001,5caf201bd3394238813dd0433b7e705a},"156",WZ,,"-56534.8195523886","231773.50065440405","15.585774322518462","47.22256269399507",,,,,,,NULL,2-rt|gn,,F080-G31
Leska 17,"1",geplant,,R001,cbceeb1312e5405d82bb703781397e9d},"156",WZ,,"-56554.17955237449","231852.5906545762","15.585508691161875","47.22327235519582",,,,,,,NULL,1-rt|ge,,F080-G31
Leska 12,"1",geplant,,R001,701fcd2493684122a88e766e8707054e},"156",WZ,,"-56731.284190049126","231643.36584271956","15.583197182277148","47.22137524495011",,,,,,,NULL,5-rt|gr,,F080-G31
Leska 7,"1",geplant,,R005,aecbe14f2b344b5ab31c61bd916cebb9},"140",WZ,,"-56417.17324315469","231604.8380298391","15.587348844322987","47.22105590332544",,,,,,,NULL,1-rt|ge,,F011-G31
Leska 29,"1",geplant,,R004,3674a9b3a077497eb8ba991f98d9f0f9},"140",WZ,,"-56008.81955120256","231540.55065386742","15.592747843547063","47.22051280864163",,,,,,,NULL,15-br|gn,,F011-G31
Leska 25 Haus 25a Altbau,"1",geplant,,R004,214e10bb74324441a76bc529127650ad},"140",WZ,,"-56031.95909655142","231558.78303816915","15.592440074563145","47.22067480849041",,,,,,,NULL,14-br|gr,,F011-G31
Leska 25 Haus 25a Altbau,"2",geplant,,R004,d679c12d47f040559366331c91143a72},"140",WZ,,"-56049.35955132048","231552.90065390524","15.592211102724864","47.22062041084681",,,,,,,NULL,13-br|vi,,F011-G31
Leska 25 Haus 25a Altbau,"1",geplant,,R004,2f81d98556fa4df78df0107eb0451cd7},"140",WZ,,"-56033.53955125866","231574.96065394953","15.592417175233328","47.22082017481332",,,,,,,NULL,12-br|bl,,F011-G31
Haselbach bei Weiz 5,"1",geplant,,R001,cfdcf3463359403b9f80a727bdcfb86d},"147",WZ,,"-57082.01056945854","233476.27946117547","15.578332059906646","47.237829901179076",,,,,,,NULL,direkt,,F098-G31
Haselbach bei Weiz 37,"1",geplant,,R001,6949c6f0cfc54c5f9547b94d85cbb6d2},"153",WZ,,"-57753.95733880909","232729.3354704734","15.569555436629136","47.231052890321024",,,,,,,NULL,2-rt|gn,,F084-G31
Haselbach bei Weiz 32,"2",geplant,,R001,d45a94a5fbfe4c80ba83b56c3728d984},"153",WZ,,"-57717.15018221865","232702.24307837244","15.570044950092079","47.23081247332972",,,,,,,NULL,3-rt|bl,,F084-G31
Haselbach bei Weiz 17,"1",geplant,,R001,4a82ca876c194ac4b1af4d907510e3f8},"153",WZ,,"-57580.9603998387","232595.13588503786","15.571857042866634","47.2298611656388",,,,,,,NULL,1-rt|ge,,F084-G31
Haselbach bei Weiz 18,"1",geplant,,R004,5ab5aec22250480e8400e973a4821c44},"153",WZ,,"-57634.42053565501","232524.17294907477","15.571160355066777","47.229218216880966",,,,,,,NULL,direkt,,F084-G31
Haselbach bei Weiz 24,"2",geplant,,R003,d80124247b6749dda14144369a56773c},"153",WZ,,"-57586.21955460679","232429.95065587852","15.57180896326422","47.22837503272411",,,,,,,NULL,5-rt|gr,,F084-G31
Haselbach bei Weiz 29,"1",geplant,,R003,f948cbb6816d4740b02efae2bb67b0b9},"153",WZ,,"-57464.11955438785","232366.7606557347","15.57342924555885","47.22781744762686",,,,,,,NULL,4-rt|vi,,F084-G31
Haselbach bei Weiz 29a,"2",geplant,,R003,a08f4bf250fc4e1b910e4854a259a57e},"153",WZ,,"-57454.979554331585","232364.90065572876","15.57355016285712","47.22780152215453",,,,,,,NULL,3-rt|bl,,F084-G31
Haselbach bei Weiz 36,"1",geplant,,R003,77422b00908948bf89f07f67f371ada0},"153",WZ,,"-57412.17955425732","232364.75065572094","15.574115279457382","47.22780393302518",,,,,,,NULL,1-rt|ge,,F084-G31
Haselbach bei Weiz 25,"1",geplant,,R003,fc0079918787478c8e53a35afae48a23},"153",WZ,,"-57411.812030537505","232335.235246568","15.574123936910448","47.22753850462234",,,,,,,NULL,2-rt|gn,,F084-G31
Haselbach bei Weiz 31,"1",geplant,,R006,b5e5f06cd8764d68ba39935f26154256},"150",WZ,,"-57910.82743111085","232827.06846855488","15.567471413838135","47.23191801819811",,,,,,,NULL,1-rt|ge,,F100-G31
Haselbach bei Weiz 16,"1",geplant,,R005,41db51a018d24507b818217953ce1bc9},"150",WZ,,"-58015.08397543966","233007.5118388962","15.566071277678736","47.23353167161626",,,,,,,NULL,1-rt|ge,,F100-G31
Haselbach bei Weiz 15,"1",geplant,,R001,7b58acb7ccb148bbb484ad7018e153d8},"150",WZ,,"-58035.322835885694","233078.13123371918","15.565794826257763","47.23416502179651",,,,,,,NULL,4-rt|vi,,F100-G31
Haselbach bei Weiz 11,"2",geplant,,R001,7cf78b5297ea49749875c66f619b586c},"150",WZ,,"-57977.76021407422","233218.54732036032","15.566536640943875","47.23543302409835",,,,,,,NULL,3-rt|bl,,F100-G31
Haselbach bei Weiz 39,"1",geplant,,R001,29009650612649ab9fafdb562fe2b6ac},"150",WZ,,"-58000.65955554244","233182.39065749664","15.566238963924755","47.23510580162416",,,,,,,NULL,2-rt|gn,,F100-G31
Haselbach bei Weiz 13,"1",geplant,,R001,87e6c020bfab496396026cca7a5cb602},"150",WZ,,"-58176.39185533597","233158.88369250204","15.56392149207657","47.2348787643806",,,,,,,NULL,1-rt|ge,,F100-G31
Haselbach bei Weiz 30,"1",geplant,,R003,17ded1703627403da8b28637b46093a5},"151",WZ,,"-57844.08311079933","233148.78836449143","15.568310922211191","47.23481745959396",,,,,,,NULL,direkt,,F007-G31
Haselbach bei Weiz 3,"1",geplant,,R001,c49ed3f3810649729eb35ab9fc6596d1},"152",WZ,,"-57185.473079312265","232898.339142506","15.577040006943928","47.232622882132574",,,,,,,NULL,2-rt|gn & 5-rt|gr,,F109-G31
Haselbach bei Weiz 4,"1",geplant,,R002,ba30c23b355c4f6c8a9b7451a42f54b2},"152",WZ,,"-57399.099554296896","232863.73065678682","15.574223657677624","47.23229289051857",,,,,,,NULL,direkt,,F109-G31
Haselbach bei Weiz 4a,"1",geplant,,R003,0ba6ebc33b464c29bede895fe8a00b3f},"152",WZ,,"-57352.77955419059","232871.1206567958","15.574834330056989","47.23236342167547",,,,,,,NULL,direkt,,F109-G31
Haselbach bei Weiz 43,"1",geplant,,R004,9c854e6aa44242b38ff72eb0d3a1a7b0},"149",WZ,,"-58178.34955597773","233370.69065791834","15.563867961031447","47.23678356815744",,,,,,,NULL,1-rt|ge,,F135-G31
Haselbach bei Weiz 10,"1",geplant,,R003,baa087af17d549c5a94f0f48ceddca24},"149",WZ,,"-58179.32077162288","233581.31506486703","15.56382760727161","47.23867782322458",,,,,,,NULL,1-rt|ge,,F135-G31
Dürntal 15,"1",geplant,,R002,2e0e7f7279db442aa43fb3b613b4c02f},"149",WZ,,"-58384.8695563939","233606.9006584352","15.561109800605275","47.23888960843309",,,,,,,NULL,1-rt|ge,,F135-G31
Dürntal,"1",geplant,,R001,a46eb12e660e4bae82dbf3821f88a06d},"149",WZ,,"-58245.78750014379","233821.36757866014","15.56291844218432","47.240830917802924",,,,,,,NULL,3-rt|bl,,F135-G31
Haselbach bei Weiz 6,"2",geplant,,R002,395dfd5f79b943d9bb61e88b8717de94},"148",WZ,,"-57783.667689126945","233467.71887913905","15.56906730515508","47.23769124684211",,,,,,,NULL,1-rt|ge,,F063-G31
Haselbach bei Weiz 6a,"1",geplant,,R002,dbd7c1cf381342a3b8e100477edbf5ce},"148",WZ,,"-57772.249555128925","233619.1506584119","15.569198434079375","47.23905422488072",,,,,,,NULL,2-rt|gn,,F063-G31
Haselbach bei Weiz 9,"1",geplant,,R001,eeb5bcd89f4d43f3b50774f0e074fbd5},"148",WZ,,"-57704.669555022614","233745.00065867696","15.570074578188333","47.24019208302092",,,,,,,NULL,1-rt|ge,,F063-G31
Haselbach bei Weiz 8,"1",geplant,,R001,4b00614234ca4ea39fc732c85c59a6fd},"148",WZ,,"-57732.70706462278","233734.48790434003","15.569705670902046","47.24009505562355",,,,,,,NULL,2-rt|gn,,F063-G31
Haselbach bei Weiz 33,"1",geplant,,R001,10c17ad4b9b94a5bb03abba7c746ab8e},"148",WZ,,"-57772.56081749461","233719.49156515114","15.569181299038465","47.23995665747072",,,,,,,NULL,3-rt|bl,,F063-G31
Haselbach bei Weiz 7,"2",geplant,,R001,ec221f22dd3840158582a1b96d78e561},"148",WZ,,"-57743.34955506207","233691.35065855365","15.569570720171205","47.23970614154055",,,,,,,NULL,4-rt|vi,,F063-G31
Haselbach bei Weiz 12,"1",geplant,,,864f8094178546f79bebc7c61e29affa},"147",WZ,,"-57118.5395537092","233632.93065838423","15.577829565028686","47.2392356240914",,,,,,,NULL,direkt,,F098-G31
Haselbach bei Weiz 23,"1",geplant,,,766a326b5f2f46d6a8ae5dcf7ada4a2c},,WZ,,"-58123.24217026618","231958.97490624484","15.564779937751615","47.22409157728648",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 23,"1",geplant,,,faea6b45022a4f518ec05733e4b6461b},,WZ,,"-58124.58241130648","231982.05683527232","15.564759231766109","47.22429905598321",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 47,"1",geplant,,,0f21a613e7ff49a38bea1927189d8a0b},,WZ,,"-58116.98771207808","232016.30743963577","15.564855030762068","47.22460777941829",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 44,"1",geplant,,,4e306d8c516947879d22d6fe7de5b702},,WZ,,"-58065.165058519546","232029.11418735425","15.56553754412244","47.224727566677814",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 22,"2",geplant,,,5c732489da174ffb81d5cb2e9257aa0e},,WZ,,"-58095.69277110432","232068.4279245366","15.565129377140833","47.2250784410389",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 21,"1",geplant,,,2f8d67a4511944ecaf6c6fc09f66c104},,WZ,,"-58049.82674439159","232080.9368409128","15.565733293406023","47.225195019212705",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 45,"1",geplant,,,c47813ba30ee4d42903b04d68c32d420},,WZ,,"-58055.63445556625","232138.71612131712","15.565649086126788","47.22571416781943",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 20,"1",geplant,,,c59a4e93108b48ebbe066e5f3fd7f0b3},,WZ,,"-58085.71542113758","232128.14310866583","15.56525331608222","47.225616403065324",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 19,"1",geplant,,,69b088ba3d68428b99a4d15a858acdf0},,WZ,,"-58139.325062749864","232170.13732792877","15.56454004615676","47.22598933244618",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 38,"2",geplant,,,7528b1e0fd78455abb9b9c79a6d2f748},,WZ,,"-58145.28168959569","232223.00239118532","15.564454501294042","47.226464268560576",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 28,"2",geplant,,,17070a0f2c3f4a71b999292d723458d1},,WZ,,"-57970.156860328905","232102.6785289","15.56678230842118","47.22539763123639",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 46,"1",geplant,,,a68d03a3011540e3b053936e45e6ec55},,WZ,,"-57891.827217306534","232044.75033282457","15.56782399148159","47.224883567303095",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 41,"2",geplant,,,6fdf5596f4e0470ea19248d1b89f96e9},,WZ,,"-57810.817092203535","232092.10551624873","15.56888737879049","47.22531664551019",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 27,"2",geplant,,,068496d5ae524c4ba7ffb76f7c3a4859},,WZ,,"-57753.03781179919","232042.36768208625","15.56965666308126","47.224874411305755",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 26,"1",geplant,,,44a394905e544c2baf6d1f469f9c3d03},,WZ,,"-57739.48648572498","232010.35081278998","15.569839724234502","47.224587649516806",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 50,"2",geplant,,,fc04947f40934ef6a0741e38738fa8fe},,WZ,,"-57775.74745164884","232061.1310566505","15.569354406061395","47.22504116214847",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 35,"2",geplant,,,6530bfbc1bf54283a8c53c1e27eb0c93},,WZ,,"-57806.49853774033","232034.92189852902","15.568951815989738","47.224802720019504",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 49,"1",geplant,,,366c8b30842441f0970364fa6a671578},,WZ,,"-57790.56456092779","232016.60527097815","15.569164559877535","47.22463938943846",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 40,"1",geplant,,,a1a7f86f84674315992abccba150969e},,WZ,,"-57819.60311680111","232022.1151508105","15.568780465862835","47.224686377932",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 42,"1",geplant,,,358880ee0af845a5914d62bcbcaeeea2},,WZ,,"-57837.77082868083","232007.37249936713","15.568542522407693","47.2245521763065",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 48,"1",geplant,,,dc93a567f94248a99242f1d841b3b12e},,WZ,,"-57808.28552579407","231996.79948671584","15.56893317085455","47.224459690471605",,,,,,,NULL,,,Connect FCP
Haselbach bei Weiz 34,"1",geplant,,,02b6f7612d4f4346a5073a27c0704d41},"151",WZ,,"-57756.229555028345","233106.36065732222","15.569476526936002","47.23444363578581",,,,,,,NULL,,,F007-G31
Haselbach bei Weiz 14,"1",geplant,,,3cf3128f1164452189942bda70c37f60},"150",WZ,,"-57981.42291541408","233091.60643278714","15.566504807077347","47.2342910002523",,,,,,,NULL,,,F100-G31
Leska 11a,"1",geplant,,,35b44c6fd08c41a592a884ecd3ea9d3e},"156",WZ,,"-56748.080405075765","231583.33512578133","15.582983091837564","47.22083387132949",,,,,,,NULL,,,F080-G31
Leska 23,"1",geplant,,,2407ee7d510846dc80864c5cf25bd981},"140",WZ,,"-55908.7916825014","231784.96694451195","15.594037678922845","47.22271965436447",,,,,,,NULL,,,F011-G31
Leska 30,"2",geplant,,,84b7f6fd594142c4a4c68ee397ed49ed},"140",WZ,,"-55987.27024119494","231565.91199225734","15.593029138252035","47.2207427545693",,,,,,,NULL,,,F011-G31
Leska 61,"1",geplant,,,a1984b654bc94f278994b6fc440167ac},"140",WZ,,"-55950.04132340864","231633.81753829954","15.593512087049575","47.221356685159755",,,,,,,NULL,,,F011-G31
Leska 66,"1",geplant,,,4165a87c4f2949e989a76e208ea16b5c},"140",WZ,,"-55923.08758693135","231593.1635600769","15.593873025215615","47.22099334843242",,,,,,,NULL,,,F011-G31
Leska 65,"1",geplant,,,0b588cfc6d5e4d7bb55adcbd17f78ed4},"140",WZ,,"-55934.25626226725","231563.67825719013","15.59372928350836","47.22072720165731",,,,,,,NULL,,,F011-G31
Leska 64,"1",geplant,,,0d7dddb01fb04cb3a20e88e4c910fed6},"140",WZ,,"-55941.85096149565","231536.12885802827","15.593632481755966","47.220478772048054",,,,,,,NULL,,,F011-G31
1 Adresse NE Status Abzwfarbe Abzwrohr UUID VerknID Bezirk TTObjectID X-GKM34 Y-GKM34 X-WGS84 Y-WGS84 TTStatus Name Telefon Kommentar Foerderung Abzwfarbe2 FFGplan AbzfGabG31 Spleiß_PO FCP_Name
2 Leska 59 1 Rohr im Haus 12-rs R003 5946f2295c0b493390a18a0d017278bb} 140 WZ -56145.281545406535 231663.33203257978 15.590930871898646 47.22160540259269 NULL F011-G31
3 Leska 60 1 Rohr im Haus 2-gn R003 1301e3f777ec44aeb276a1a83c083a49} 140 WZ -56153.02193021558 231653.6073107428 15.590829911419092 47.22151727359594 NULL F011-G31
4 Leska 33 1 Rohr im Haus 9-tr R003 dc295bbb1b69473eb3544c61e5f66b62} 140 WZ -56144.01784626319 231649.98266880997 15.590949237470126 47.22148544674893 NULL F011-G31
5 Leska 24 2 Rohr im Haus 7-br R003 660986f46e1d4fdf9f989c34b5a9003e} 140 WZ -56188.51234112327 231616.3600275327 15.590366076117512 47.2211792220983 11-or NULL F011-G31
6 Leska 43 1 Rohr im Haus 5-ws R003 1656c73fa81d42e2acc04c86088fbc0d} 140 WZ -56110.03239893667 231619.99135923872 15.59140168067953 47.22121862187798 NULL F011-G31
7 Leska GST 221-1 2 geplant 6-gr R003 ac0ac5e440a24b61b912b573068e0ed4} 140 WZ -56127.44718610768 231613.94992459638 15.591172538423258 47.22116279042543 NULL F011-G31
8 Leska GST 221-2 2 geplant 1-rt R003 67af3eefdb6d4093833ff0f0aa317455} 140 WZ -56139.81422640596 231585.31213539792 15.591012882746124 47.22090416000211 NULL F011-G31
9 Leska 71 2 Rohr im Haus 3-bl R003 b14a91ebe89f4aad9516a78f734a104c} 140 WZ -56115.33581461235 231577.90204806472 15.5913369691158 47.22083961483815 NULL F011-G31
10 Leska 22 2 Rohr im Haus 8-vi R003 c41720429f2147bdbad4cb199bdd2f9c} 140 WZ -56078.21026293475 231577.6259596684 15.591827118040607 47.22084031687849 NULL F011-G31
11 Leska 42 1 Rohr am Grundstück 4-ge R003 294faff6974f45e9b19d8ca8f785ba77} 140 WZ -56073.387252066736 231570.98986820615 15.591891624518428 47.22078104539795 NULL F011-G31
12 Leska 41 1 Rohr am Grundstück 10-sw R003 7be0b75e9ffd479486c8b5e69c54497d} 140 WZ -56062.84489983031 231577.227293473 15.592030014566573 47.22083804892475 NULL F011-G31
13 Leska 39 1 geplant R004 c630f799c91e402e90117065397ff22d} 140 WZ -56040.237180976066 231614.83069778598 15.592323740398287 47.22117819265921 NULL 4-rt|vi F011-G31
14 Leska 35 1 geplant R004 784d3bdb3e7643ccbb407c92b4515b0d} 140 WZ -56013.40955121039 231606.6106540151 15.592678942187908 47.2211065602874 NULL 3-rt|bl F011-G31
15 Leska 40 1 geplant R004 fdbef64e3c4045019169e8f55d776a03} 140 WZ -55995.05955120352 231622.68065404333 15.592919171487441 47.221252665926365 NULL 2-rt|gn F011-G31
16 Leska Ost 1 geplant R004 085a0a817b70455e8f5f9a167d2946c1} 140 WZ -56022.029378532665 231580.23411969002 15.592568463910272 47.22086859076428 NULL ?? F011-G31
17 Leska 25 1 geplant 0d6b73df03d04df29e9e3b27c94b5781} 140 WZ -56033.53955125866 231574.96065394953 15.592417175233328 47.22082017481332 NULL F011-G31
18 Leska 25a 1 geplant 87d91bc5e5e548fbb72f3b828bfcc821} 140 WZ -56031.95909655142 231558.78303816915 15.592440074563145 47.22067480849041 NULL F011-G31
19 Leska 37 2 geplant 95951feb467e4aa89d4014729b200a23} 140 WZ -56049.35955132048 231552.90065390524 15.592211102724864 47.22062041084681 NULL F011-G31
20 Leska 29 1 geplant 1f7005bef1714e1ca4dbee86fa179d42} 140 WZ -56008.81955120256 231540.55065386742 15.592747843547063 47.22051280864163 NULL F011-G31
21 Leska 49 1 geplant R002 33a662f0c0c8486e9dd9aee116925407} 140 WZ -55994.82065718405 231511.64122318942 15.592936283232005 47.22025399566092 NULL 16-br|ge F011-G31
22 Leska 67 1 geplant 66d3079e1de14d3ba177aa8d58cd0dcf} 140 WZ -55922.245431603376 231622.81222712528 15.593880420807363 47.221260081170186 NULL F011-G31
23 Leska 68 1 geplant 87cd91bc5c584e0d9c25e15740020abf} 140 WZ -55892.830030556994 231618.12093306333 15.59426934111539 47.22122040283545 NULL F011-G31
24 Leska 31 1 Rohr im Haus 6-gr R001 158b189727774bdd85fa9e66f87d8b9a} 140 WZ -56028.75339456757 231660.63175547402 15.59246958398472 47.221591112317455 Schellnegger NULL 14-br|gr F011-G31
25 Leska 58 1 Rohr im Haus 1-rt R001 4bfaf68012844dccb305edc9529865db} 140 WZ -56109.26356875655 231651.94038763712 15.5914078061142 47.22150603788694 Weber NULL 2-rt|gn F011-G31
26 Leska 36 2 Rohr im Haus 2-gn R001 0f458d9bb64249e89b44cf30f17fd357} 140 WZ -56082.490820467734 231629.06441983432 15.591764131989601 47.221302588063715 Wünscher K. NULL 11-gn|gr F011-G31
27 Leska 50 1 Rohr im Haus 3-bl R001 4bc4e8d7864a43a5acc8e3fd0ad6a31b} 140 WZ -56059.80403675831 231639.7780285044 15.592062286595974 47.22140089198985 Stöbel NULL 21-sw|bl F011-G31
28 Leska GST 226/5 (56) 2 geplant 5-ws R001 ecc9b56f0e0c4b0d857866fb77c24a54} 140 WZ -56066.13869770958 231653.84122362765 15.591976888389103 47.22152683342109 NULL 13-br|vi F011-G31
29 Leska 55 - GST 226/4 2 Rohr am Grundstück 7-br R001 399a61a8c6cd4984af26a2a4f451b857} 140 WZ -56075.55366324877 231685.1952304519 15.591848647679308 47.22180802442859 Schaffler NULL 17-br|rt F011-G31
30 Leska 54 1 Rohr im Haus 8-vi R002 1902084715cc4ea19d7977a6fca9db0b} 140 WZ -56128.72170297154 231695.11533498953 15.591145485347903 47.221892683847166 Fladischer NULL 22-sw|vi F011-G31
31 Leska 53 1 Rohr im Haus 9-tr R002 965682a626da4563b0d8d99d2de5baad} 140 WZ -56163.66881100664 231703.30622472466 15.590683088165084 47.22196335178929 Hutter NULL 10-gn|vi F011-G31
32 Leska 52 1 Rohr im Haus 1-rt R002 e01be9b11cd44131b31c07f52b38de5f} 140 WZ -56200.36682952387 231685.30778027754 15.590200878856832 47.22179832018924 Mosbacher NULL 5-rt|gr F011-G31
33 Leska 51 1 geplant 2-gn R002 3ccce200c78e4b48ab6292583cb6b5ca} 140 WZ -56203.1534214638 231662.7213923486 15.590166940742934 47.221594938424836 Kaufmann NULL 20-sw|gn F011-G31
34 Leska 48 1 geplant 4-ge R002 7c759b0d214249e6ab9b30c475795beb} 140 WZ -56206.65396634192 231645.8712405312 15.590122853713176 47.221443087047376 Lackner NULL 19-sw|ge F011-G31
35 Leska 32 1 geplant 5-ws R002 9a55c2785b4c42b8bcf4d14617ef924e} 140 WZ -56242.200653718166 231622.5035638612 15.589656528234375 47.221229861210766 Riedler NULL 15-br|gn F011-G31
36 Leska 47 1 geplant 3-bl R002 f5e534a3b5f24938b04b88de8d81a262} 140 WZ -56263.0744784181 231634.05625544087 15.589379500719186 47.221331970400826 Macher NULL 6-ge|bl F011-G31
37 Leska GST 226/6 (57) 2 Rohr im Haus 4-ge R001 eb429601e41c43b3bf5d93b9851a141a} 140 WZ -56071.312148422134 231645.525804857 15.59190963675863 47.22145160076991 NULL 7-ge|vi F011-G31
38 Haselbach bei Weiz 2 1 geplant R007 c26e4733ffd64c779ede960601ae03c7} 155 WZ -57061.24955350514 232290.60065554455 15.578758185948766 47.22716775346716 NULL 1-rt|ge F101-G31
39 Haselbach bei Weiz 1 1 geplant R007 21654400800b44268fbb9dbaf597058a} 155 WZ -57005.94955343299 232250.93065545894 15.579493393384412 47.22681578655333 2-rt|gn F101-G31
40 Leska 4a 1 geplant R007 b5c2dfa923234c2baeffb958783c386b} 155 WZ -56929.41955319794 232035.0106549943 15.580531417406736 47.224880473910844 NULL 3-rt|bl F101-G31
41 Leska 4 1 geplant f215425b109849db8e35103ea07b4fe5} 155 WZ -56895.2491423057 232045.87516137492 15.580981164499747 47.22498116360448 NULL 4-rt|vi F101-G31
42 Leska 45 1 geplant f56cf9440dcc4e63ae57667433305aa7} 155 WZ -56951.989553235006 231979.7106548706 15.58024050797209 47.2243811408093 NULL 7-ge|vi F101-G31
43 Leska 2 1 geplant R006 554270b965d546ab826b8b0ab8c198fc} 155 WZ -57263.139553948975 232217.8206554018 15.576101978356826 47.226495519787896 NULL 1-rt|ge F101-G31
44 Leska 9 1 geplant R006 73466165db08487689ce8dc56cc26687} 155 WZ -57177.23955375212 232130.03065520432 15.577247377224392 47.2257134565094 NULL 2-rt|gn F101-G31
45 Leska 28 1 geplant R006 547139ee0f5a413dbfdfe3160c8eb7d4} 155 WZ -57092.95955354581 232022.58065497037 15.578373874405916 47.22475441832837 NULL 3-rt|bl F101-G31
46 Leska 44 1 geplant R005 04a83cd9ae474b7ea1f62af297b9cf32} 155 WZ -56949.74955324256 231951.56065481622 15.580273680523158 47.224128155182356 3-rt|bl F101-G31
47 Leska 13 1 geplant R001 cf54d54b272d4a4081f1b353cba0e3c5} 155 WZ -56921.689553196265 231934.56065477896 15.580646309994998 47.2239777008744 NULL 3-rt|bl F101-G31
48 Leska 38 1 geplant R005 ef49fc227add48989dcda96154aa0496} 155 WZ -56938.31955320957 231945.11065479834 15.580425407496504 47.22407113944173 NULL 4-rt|vi F101-G31
49 Leska 3 1 geplant R001 bb44c26dfc904879b19d56e5d86dfae9} 155 WZ -56874.83717409521 231947.72491595056 15.581263187247378 47.2241001773665 NULL 2-rt|gn F101-G31
50 Leska 63 1 geplant R001 15418070596142d8bf8f9cb0e6b40156} 155 WZ -56854.22591229741 231915.34672115184 15.581539436398232 47.22381076081135 NULL F101-G31
51 Leska 34 1 geplant R001 628a4538a27e441994e3eeb0944fb185} 155 WZ -56897.36955313191 231904.2906547077 15.580971256074722 47.2237075696472 NULL 7-ge|vi F101-G31
52 Leska 26a 1 geplant R001 756f8806e53f4c36b4a0df236968aa7c} 155 WZ -56843.269552992744 231887.32065466326 15.58168766148532 47.22355964725039 NULL 5-rt|gr F101-G31
53 Leska 26 1 geplant R001 0faa81357e2e43d08bf055857efd507e} 155 WZ -56856.32749450881 231888.16143333632 15.581515160909937 47.22356607383624 NULL 6-ge|bl F101-G31
54 Leska 27 1 geplant R001 16b6a8995565452b8e62d096fcf2f4b3} 155 WZ -56848.039553011906 231858.58065460902 15.581628355073194 47.22330074522336 NULL 4-rt|vi F101-G31
55 Mortantsch 24 1 geplant R001 3f122b8c86cf4137a7a5fd8847819576} 157 WZ -57475.41955435836 231295.25065345783 15.573418299892829 47.218179320299946 NULL 1-rt F142
56 Mortantsch 25 1 geplant R001 7cbe6fc937e64004a7b0f8328e6fdf2f} 157 WZ -57380.11955408856 231221.78065329418 15.574685799144671 47.217526900603524 NULL 2-gn F142
57 Leska 1 1 geplant R002 9d48cc5fdbc74dd090fcd6d2ad9b02d6} 157 WZ -57443.909554293605 231552.0406540064 15.573801150136687 47.22049165330622 NULL ? F142
58 Leska 8 1 geplant R005 5f084197279a4355b9d50f8b3c1b1e73} 156 WZ -56783.18918947916 231807.01277170517 15.582491090832463 47.222842579236044 NULL direkt F080-G31
59 Leska 5 2 geplant R004 c785c9b38ee04cf9a7e3ff915ba5f502} 156 WZ -56697.37463551392 231923.92917702533 15.58360913274662 47.223901571840344 NULL 5-rt|gr F080-G31
60 Leska 6 1 geplant R004 c0d7cdef440e498bb4e876e52a67bf07} 156 WZ -56715.474530867745 231807.97961095348 15.583384936908617 47.22285715218472 NULL 4-rt|vi F080-G31
61 Leska 16 1 Kabel eingeblasen R004 de890a54b38d4c56a599b94b16620728} 156 WZ AT-8160-267e3e51 -56676.26955267117 231804.76065448485 15.583902930968282 47.22283160045513 NULL 3-rt|bl F080-G31
62 Leska 7a 1 geplant R004 68acd1dc001e496abcd880eb9ded2a25} 156 WZ -56713.009552714204 231767.18065440282 15.583422674067206 47.22249042033517 NULL 2-rt|gn F080-G31
63 Leska 14 1 geplant R004 28c54a9ad8674327a4c3daa77511d49d} 156 WZ -56699.72521198267 231747.69053174648 15.583600533693598 47.22231627834308 NULL 1-rt|ge F080-G31
64 Leska 11 2 geplant 8-vi R002 b0f19181817d4a209c04b2fa963efff3} 156 WZ -56794.009552900985 231574.2806540057 15.582377912378865 47.2207484478414 NULL 1-rt F080-G31
65 Leska 10 1 Kabel eingeblasen R001 75dcee1ad24c4900af93c6cba23b0e1c} 156 WZ AT-8160-beaffbe2 -56774.90955290512 231723.15065431595 15.582611087354392 47.222089042773604 NULL 4-rt|vi F080-G31
66 Leska 46 1 geplant R001 bce7ab0d0bfb42b899f810a2deea1803} 156 WZ -56760.66955280146 231706.5106542781 15.582801201497816 47.22194061898817 NULL 11-gn|gr F080-G31
67 Leska 21 1 geplant R001 0fa5394d64ce4d7d9cf8ad34d8c58911} 156 WZ -56688.27981595987 231699.5109452363 15.583757765723316 47.22188394365145 NULL 3-rt|bl F080-G31
68 Leska 15 1 geplant R001 5caf201bd3394238813dd0433b7e705a} 156 WZ -56534.8195523886 231773.50065440405 15.585774322518462 47.22256269399507 NULL 2-rt|gn F080-G31
69 Leska 17 1 geplant R001 cbceeb1312e5405d82bb703781397e9d} 156 WZ -56554.17955237449 231852.5906545762 15.585508691161875 47.22327235519582 NULL 1-rt|ge F080-G31
70 Leska 12 1 geplant R001 701fcd2493684122a88e766e8707054e} 156 WZ -56731.284190049126 231643.36584271956 15.583197182277148 47.22137524495011 NULL 5-rt|gr F080-G31
71 Leska 7 1 geplant R005 aecbe14f2b344b5ab31c61bd916cebb9} 140 WZ -56417.17324315469 231604.8380298391 15.587348844322987 47.22105590332544 NULL 1-rt|ge F011-G31
72 Leska 29 1 geplant R004 3674a9b3a077497eb8ba991f98d9f0f9} 140 WZ -56008.81955120256 231540.55065386742 15.592747843547063 47.22051280864163 NULL 15-br|gn F011-G31
73 Leska 25 Haus 25a Altbau 1 geplant R004 214e10bb74324441a76bc529127650ad} 140 WZ -56031.95909655142 231558.78303816915 15.592440074563145 47.22067480849041 NULL 14-br|gr F011-G31
74 Leska 25 Haus 25a Altbau 2 geplant R004 d679c12d47f040559366331c91143a72} 140 WZ -56049.35955132048 231552.90065390524 15.592211102724864 47.22062041084681 NULL 13-br|vi F011-G31
75 Leska 25 Haus 25a Altbau 1 geplant R004 2f81d98556fa4df78df0107eb0451cd7} 140 WZ -56033.53955125866 231574.96065394953 15.592417175233328 47.22082017481332 NULL 12-br|bl F011-G31
76 Haselbach bei Weiz 5 1 geplant R001 cfdcf3463359403b9f80a727bdcfb86d} 147 WZ -57082.01056945854 233476.27946117547 15.578332059906646 47.237829901179076 NULL direkt F098-G31
77 Haselbach bei Weiz 37 1 geplant R001 6949c6f0cfc54c5f9547b94d85cbb6d2} 153 WZ -57753.95733880909 232729.3354704734 15.569555436629136 47.231052890321024 NULL 2-rt|gn F084-G31
78 Haselbach bei Weiz 32 2 geplant R001 d45a94a5fbfe4c80ba83b56c3728d984} 153 WZ -57717.15018221865 232702.24307837244 15.570044950092079 47.23081247332972 NULL 3-rt|bl F084-G31
79 Haselbach bei Weiz 17 1 geplant R001 4a82ca876c194ac4b1af4d907510e3f8} 153 WZ -57580.9603998387 232595.13588503786 15.571857042866634 47.2298611656388 NULL 1-rt|ge F084-G31
80 Haselbach bei Weiz 18 1 geplant R004 5ab5aec22250480e8400e973a4821c44} 153 WZ -57634.42053565501 232524.17294907477 15.571160355066777 47.229218216880966 NULL direkt F084-G31
81 Haselbach bei Weiz 24 2 geplant R003 d80124247b6749dda14144369a56773c} 153 WZ -57586.21955460679 232429.95065587852 15.57180896326422 47.22837503272411 NULL 5-rt|gr F084-G31
82 Haselbach bei Weiz 29 1 geplant R003 f948cbb6816d4740b02efae2bb67b0b9} 153 WZ -57464.11955438785 232366.7606557347 15.57342924555885 47.22781744762686 NULL 4-rt|vi F084-G31
83 Haselbach bei Weiz 29a 2 geplant R003 a08f4bf250fc4e1b910e4854a259a57e} 153 WZ -57454.979554331585 232364.90065572876 15.57355016285712 47.22780152215453 NULL 3-rt|bl F084-G31
84 Haselbach bei Weiz 36 1 geplant R003 77422b00908948bf89f07f67f371ada0} 153 WZ -57412.17955425732 232364.75065572094 15.574115279457382 47.22780393302518 NULL 1-rt|ge F084-G31
85 Haselbach bei Weiz 25 1 geplant R003 fc0079918787478c8e53a35afae48a23} 153 WZ -57411.812030537505 232335.235246568 15.574123936910448 47.22753850462234 NULL 2-rt|gn F084-G31
86 Haselbach bei Weiz 31 1 geplant R006 b5e5f06cd8764d68ba39935f26154256} 150 WZ -57910.82743111085 232827.06846855488 15.567471413838135 47.23191801819811 NULL 1-rt|ge F100-G31
87 Haselbach bei Weiz 16 1 geplant R005 41db51a018d24507b818217953ce1bc9} 150 WZ -58015.08397543966 233007.5118388962 15.566071277678736 47.23353167161626 NULL 1-rt|ge F100-G31
88 Haselbach bei Weiz 15 1 geplant R001 7b58acb7ccb148bbb484ad7018e153d8} 150 WZ -58035.322835885694 233078.13123371918 15.565794826257763 47.23416502179651 NULL 4-rt|vi F100-G31
89 Haselbach bei Weiz 11 2 geplant R001 7cf78b5297ea49749875c66f619b586c} 150 WZ -57977.76021407422 233218.54732036032 15.566536640943875 47.23543302409835 NULL 3-rt|bl F100-G31
90 Haselbach bei Weiz 39 1 geplant R001 29009650612649ab9fafdb562fe2b6ac} 150 WZ -58000.65955554244 233182.39065749664 15.566238963924755 47.23510580162416 NULL 2-rt|gn F100-G31
91 Haselbach bei Weiz 13 1 geplant R001 87e6c020bfab496396026cca7a5cb602} 150 WZ -58176.39185533597 233158.88369250204 15.56392149207657 47.2348787643806 NULL 1-rt|ge F100-G31
92 Haselbach bei Weiz 30 1 geplant R003 17ded1703627403da8b28637b46093a5} 151 WZ -57844.08311079933 233148.78836449143 15.568310922211191 47.23481745959396 NULL direkt F007-G31
93 Haselbach bei Weiz 3 1 geplant R001 c49ed3f3810649729eb35ab9fc6596d1} 152 WZ -57185.473079312265 232898.339142506 15.577040006943928 47.232622882132574 NULL 2-rt|gn & 5-rt|gr F109-G31
94 Haselbach bei Weiz 4 1 geplant R002 ba30c23b355c4f6c8a9b7451a42f54b2} 152 WZ -57399.099554296896 232863.73065678682 15.574223657677624 47.23229289051857 NULL direkt F109-G31
95 Haselbach bei Weiz 4a 1 geplant R003 0ba6ebc33b464c29bede895fe8a00b3f} 152 WZ -57352.77955419059 232871.1206567958 15.574834330056989 47.23236342167547 NULL direkt F109-G31
96 Haselbach bei Weiz 43 1 geplant R004 9c854e6aa44242b38ff72eb0d3a1a7b0} 149 WZ -58178.34955597773 233370.69065791834 15.563867961031447 47.23678356815744 NULL 1-rt|ge F135-G31
97 Haselbach bei Weiz 10 1 geplant R003 baa087af17d549c5a94f0f48ceddca24} 149 WZ -58179.32077162288 233581.31506486703 15.56382760727161 47.23867782322458 NULL 1-rt|ge F135-G31
98 Dürntal 15 1 geplant R002 2e0e7f7279db442aa43fb3b613b4c02f} 149 WZ -58384.8695563939 233606.9006584352 15.561109800605275 47.23888960843309 NULL 1-rt|ge F135-G31
99 Dürntal 1 geplant R001 a46eb12e660e4bae82dbf3821f88a06d} 149 WZ -58245.78750014379 233821.36757866014 15.56291844218432 47.240830917802924 NULL 3-rt|bl F135-G31
100 Haselbach bei Weiz 6 2 geplant R002 395dfd5f79b943d9bb61e88b8717de94} 148 WZ -57783.667689126945 233467.71887913905 15.56906730515508 47.23769124684211 NULL 1-rt|ge F063-G31
101 Haselbach bei Weiz 6a 1 geplant R002 dbd7c1cf381342a3b8e100477edbf5ce} 148 WZ -57772.249555128925 233619.1506584119 15.569198434079375 47.23905422488072 NULL 2-rt|gn F063-G31
102 Haselbach bei Weiz 9 1 geplant R001 eeb5bcd89f4d43f3b50774f0e074fbd5} 148 WZ -57704.669555022614 233745.00065867696 15.570074578188333 47.24019208302092 NULL 1-rt|ge F063-G31
103 Haselbach bei Weiz 8 1 geplant R001 4b00614234ca4ea39fc732c85c59a6fd} 148 WZ -57732.70706462278 233734.48790434003 15.569705670902046 47.24009505562355 NULL 2-rt|gn F063-G31
104 Haselbach bei Weiz 33 1 geplant R001 10c17ad4b9b94a5bb03abba7c746ab8e} 148 WZ -57772.56081749461 233719.49156515114 15.569181299038465 47.23995665747072 NULL 3-rt|bl F063-G31
105 Haselbach bei Weiz 7 2 geplant R001 ec221f22dd3840158582a1b96d78e561} 148 WZ -57743.34955506207 233691.35065855365 15.569570720171205 47.23970614154055 NULL 4-rt|vi F063-G31
106 Haselbach bei Weiz 12 1 geplant 864f8094178546f79bebc7c61e29affa} 147 WZ -57118.5395537092 233632.93065838423 15.577829565028686 47.2392356240914 NULL direkt F098-G31
107 Haselbach bei Weiz 23 1 geplant 766a326b5f2f46d6a8ae5dcf7ada4a2c} WZ -58123.24217026618 231958.97490624484 15.564779937751615 47.22409157728648 NULL Connect FCP
108 Haselbach bei Weiz 23 1 geplant faea6b45022a4f518ec05733e4b6461b} WZ -58124.58241130648 231982.05683527232 15.564759231766109 47.22429905598321 NULL Connect FCP
109 Haselbach bei Weiz 47 1 geplant 0f21a613e7ff49a38bea1927189d8a0b} WZ -58116.98771207808 232016.30743963577 15.564855030762068 47.22460777941829 NULL Connect FCP
110 Haselbach bei Weiz 44 1 geplant 4e306d8c516947879d22d6fe7de5b702} WZ -58065.165058519546 232029.11418735425 15.56553754412244 47.224727566677814 NULL Connect FCP
111 Haselbach bei Weiz 22 2 geplant 5c732489da174ffb81d5cb2e9257aa0e} WZ -58095.69277110432 232068.4279245366 15.565129377140833 47.2250784410389 NULL Connect FCP
112 Haselbach bei Weiz 21 1 geplant 2f8d67a4511944ecaf6c6fc09f66c104} WZ -58049.82674439159 232080.9368409128 15.565733293406023 47.225195019212705 NULL Connect FCP
113 Haselbach bei Weiz 45 1 geplant c47813ba30ee4d42903b04d68c32d420} WZ -58055.63445556625 232138.71612131712 15.565649086126788 47.22571416781943 NULL Connect FCP
114 Haselbach bei Weiz 20 1 geplant c59a4e93108b48ebbe066e5f3fd7f0b3} WZ -58085.71542113758 232128.14310866583 15.56525331608222 47.225616403065324 NULL Connect FCP
115 Haselbach bei Weiz 19 1 geplant 69b088ba3d68428b99a4d15a858acdf0} WZ -58139.325062749864 232170.13732792877 15.56454004615676 47.22598933244618 NULL Connect FCP
116 Haselbach bei Weiz 38 2 geplant 7528b1e0fd78455abb9b9c79a6d2f748} WZ -58145.28168959569 232223.00239118532 15.564454501294042 47.226464268560576 NULL Connect FCP
117 Haselbach bei Weiz 28 2 geplant 17070a0f2c3f4a71b999292d723458d1} WZ -57970.156860328905 232102.6785289 15.56678230842118 47.22539763123639 NULL Connect FCP
118 Haselbach bei Weiz 46 1 geplant a68d03a3011540e3b053936e45e6ec55} WZ -57891.827217306534 232044.75033282457 15.56782399148159 47.224883567303095 NULL Connect FCP
119 Haselbach bei Weiz 41 2 geplant 6fdf5596f4e0470ea19248d1b89f96e9} WZ -57810.817092203535 232092.10551624873 15.56888737879049 47.22531664551019 NULL Connect FCP
120 Haselbach bei Weiz 27 2 geplant 068496d5ae524c4ba7ffb76f7c3a4859} WZ -57753.03781179919 232042.36768208625 15.56965666308126 47.224874411305755 NULL Connect FCP
121 Haselbach bei Weiz 26 1 geplant 44a394905e544c2baf6d1f469f9c3d03} WZ -57739.48648572498 232010.35081278998 15.569839724234502 47.224587649516806 NULL Connect FCP
122 Haselbach bei Weiz 50 2 geplant fc04947f40934ef6a0741e38738fa8fe} WZ -57775.74745164884 232061.1310566505 15.569354406061395 47.22504116214847 NULL Connect FCP
123 Haselbach bei Weiz 35 2 geplant 6530bfbc1bf54283a8c53c1e27eb0c93} WZ -57806.49853774033 232034.92189852902 15.568951815989738 47.224802720019504 NULL Connect FCP
124 Haselbach bei Weiz 49 1 geplant 366c8b30842441f0970364fa6a671578} WZ -57790.56456092779 232016.60527097815 15.569164559877535 47.22463938943846 NULL Connect FCP
125 Haselbach bei Weiz 40 1 geplant a1a7f86f84674315992abccba150969e} WZ -57819.60311680111 232022.1151508105 15.568780465862835 47.224686377932 NULL Connect FCP
126 Haselbach bei Weiz 42 1 geplant 358880ee0af845a5914d62bcbcaeeea2} WZ -57837.77082868083 232007.37249936713 15.568542522407693 47.2245521763065 NULL Connect FCP
127 Haselbach bei Weiz 48 1 geplant dc93a567f94248a99242f1d841b3b12e} WZ -57808.28552579407 231996.79948671584 15.56893317085455 47.224459690471605 NULL Connect FCP
128 Haselbach bei Weiz 34 1 geplant 02b6f7612d4f4346a5073a27c0704d41} 151 WZ -57756.229555028345 233106.36065732222 15.569476526936002 47.23444363578581 NULL F007-G31
129 Haselbach bei Weiz 14 1 geplant 3cf3128f1164452189942bda70c37f60} 150 WZ -57981.42291541408 233091.60643278714 15.566504807077347 47.2342910002523 NULL F100-G31
130 Leska 11a 1 geplant 35b44c6fd08c41a592a884ecd3ea9d3e} 156 WZ -56748.080405075765 231583.33512578133 15.582983091837564 47.22083387132949 NULL F080-G31
131 Leska 23 1 geplant 2407ee7d510846dc80864c5cf25bd981} 140 WZ -55908.7916825014 231784.96694451195 15.594037678922845 47.22271965436447 NULL F011-G31
132 Leska 30 2 geplant 84b7f6fd594142c4a4c68ee397ed49ed} 140 WZ -55987.27024119494 231565.91199225734 15.593029138252035 47.2207427545693 NULL F011-G31
133 Leska 61 1 geplant a1984b654bc94f278994b6fc440167ac} 140 WZ -55950.04132340864 231633.81753829954 15.593512087049575 47.221356685159755 NULL F011-G31
134 Leska 66 1 geplant 4165a87c4f2949e989a76e208ea16b5c} 140 WZ -55923.08758693135 231593.1635600769 15.593873025215615 47.22099334843242 NULL F011-G31
135 Leska 65 1 geplant 0b588cfc6d5e4d7bb55adcbd17f78ed4} 140 WZ -55934.25626226725 231563.67825719013 15.59372928350836 47.22072720165731 NULL F011-G31
136 Leska 64 1 geplant 0d7dddb01fb04cb3a20e88e4c910fed6} 140 WZ -55941.85096149565 231536.12885802827 15.593632481755966 47.220478772048054 NULL F011-G31