Merge-Konflikt in DeviceController.php behoben
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"); ?>
|
||||
@@ -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"); ?>
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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())?>
|
||||
@@ -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"); ?>
|
||||
43
Layout/default/WarehouseOrder/PDF_FOOTER.html
Normal file
43
Layout/default/WarehouseOrder/PDF_FOOTER.html
Normal 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>
|
||||
92
Layout/default/WarehouseOrder/PDF_HEADER.html
Normal file
92
Layout/default/WarehouseOrder/PDF_HEADER.html
Normal 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>
|
||||
133
Layout/default/WarehouseOrder/PDF_MAIN.php
Normal file
133
Layout/default/WarehouseOrder/PDF_MAIN.php
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -183,7 +183,6 @@ class Termination extends mfBaseModel {
|
||||
}
|
||||
|
||||
$bcode = $this->getProperty("building")->code;
|
||||
var_dump($bcode);
|
||||
if(!$bcode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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'],
|
||||
|
||||
9
application/WarehouseOffer/WarehouseOffer.php
Normal file
9
application/WarehouseOffer/WarehouseOffer.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class WarehouseOffer extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
56
application/WarehouseOffer/WarehouseOfferController.php
Normal file
56
application/WarehouseOffer/WarehouseOfferController.php
Normal 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));
|
||||
}
|
||||
}
|
||||
52
application/WarehouseOffer/WarehouseOfferModel.php
Normal file
52
application/WarehouseOffer/WarehouseOfferModel.php
Normal 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;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
4
application/WarehouseProject/WarehouseProject.php
Normal file
4
application/WarehouseProject/WarehouseProject.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
class WarehouseProject extends mfBaseModel {
|
||||
}
|
||||
36
application/WarehouseProject/WarehouseProjectController.php
Normal file
36
application/WarehouseProject/WarehouseProjectController.php
Normal 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;
|
||||
}
|
||||
}
|
||||
15
application/WarehouseProject/WarehouseProjectModel.php
Normal file
15
application/WarehouseProject/WarehouseProjectModel.php
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
21
db/migrations/20250204190000_warehouse_modify_12.php
Normal file
21
db/migrations/20250204190000_warehouse_modify_12.php
Normal 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();;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
36
lib/SNOPP/SNOPP.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
55
public/js/pages/AddressTickets/AddressTickets.js
Normal file
55
public/js/pages/AddressTickets/AddressTickets.js
Normal 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');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -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;
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
14
public/js/pages/WarehouseOffer/WarehouseOffer.css
Normal file
14
public/js/pages/WarehouseOffer/WarehouseOffer.css
Normal 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;
|
||||
}
|
||||
}
|
||||
178
public/js/pages/WarehouseOffer/WarehouseOffer.js
Normal file
178
public/js/pages/WarehouseOffer/WarehouseOffer.js
Normal 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,
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
14
public/js/pages/WarehouseProject/WarehouseProject.css
Normal file
14
public/js/pages/WarehouseProject/WarehouseProject.css
Normal 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;
|
||||
}
|
||||
}
|
||||
161
public/js/pages/WarehouseProject/WarehouseProject.js
Normal file
161
public/js/pages/WarehouseProject/WarehouseProject.js
Normal 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,
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
353
scripts/adb-rimo-import/adb-rimo-import-broker.php
Normal file
353
scripts/adb-rimo-import/adb-rimo-import-broker.php
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
49
scripts/construction/colors
Normal file
49
scripts/construction/colors
Normal 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",
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
136
scripts/construction/source/Export Ly 04022025.csv
Normal file
136
scripts/construction/source/Export Ly 04022025.csv
Normal 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
|
||||
|
Reference in New Issue
Block a user