diff --git a/Layout/default/Address/View.php b/Layout/default/Address/View.php index 58e854665..591b4d778 100644 --- a/Layout/default/Address/View.php +++ b/Layout/default/Address/View.php @@ -27,6 +27,7 @@ $address->id, 's' => $s, 'f' => "view"])?>" class="btn btn-outline-success"> Adresse bearbeiten
+ $address->id])?>" class="btn btn-purple mr-1"> Tickets $address->id])?>" class="btn btn-purple mr-1"> Rechungsübersicht
diff --git a/Layout/default/Building/Index.php b/Layout/default/Building/Index.php index efff4a2d8..d38976c79 100644 --- a/Layout/default/Building/Index.php +++ b/Layout/default/Building/Index.php @@ -148,6 +148,7 @@ Einheiten Status + Erstellt
Bearbeitet @@ -164,6 +165,10 @@ units?> status->name."-b")?> + + create)?> (creator->name?>)
+ edit)?> (editor->name?>) + $building->id])?>"> $building->id])?>" class="text-danger" onclick="if(!confirm('Objekt wirklich löschen?')) return false;" title="Objekt Löschen"> diff --git a/Layout/default/ConstructionConsentProject/Form.php b/Layout/default/ConstructionConsentProject/Form.php index 610ced431..2dc324781 100644 --- a/Layout/default/ConstructionConsentProject/Form.php +++ b/Layout/default/ConstructionConsentProject/Form.php @@ -90,6 +90,21 @@
+

Berechtigungen

+ +
+ +
+ +
+
+ +
+
@@ -120,12 +135,6 @@ closeOnSelect: false }); - $('#adb_hausnummer_id').on('select2:close', function(e) { - if(!$('#adb_hausnummer_id').val()) { - $('#new-address-toggle').show(); - } - - }); \ No newline at end of file diff --git a/Layout/default/Invoice/Index.php b/Layout/default/Invoice/Index.php index 9e22ad4cb..5f269cc04 100644 --- a/Layout/default/Invoice/Index.php +++ b/Layout/default/Invoice/Index.php @@ -55,7 +55,7 @@ $pagination_entity_name = "Rechnungen"; "/>
- + "/>
@@ -474,4 +474,4 @@ $pagination_entity_name = "Rechnungen"; - \ No newline at end of file + diff --git a/Layout/default/Preorder/Index.php b/Layout/default/Preorder/Index.php index ab4232cf0..1e4677ea4 100644 --- a/Layout/default/Preorder/Index.php +++ b/Layout/default/Preorder/Index.php @@ -423,9 +423,7 @@ $pagination_entity_name = "Vorbestellungen"; Partner Attribute Erstellt
Bearbeitet - is(["Admin","netowner"])): ?> - - + @@ -479,9 +477,7 @@ $pagination_entity_name = "Vorbestellungen"; edit)?> - is(["Admin", "netowner"])): ?> - adb_wohneinheit_id && is_array($preorder->adb_wohneinheit->rimo_workorders) && count($preorder->adb_wohneinheit->rimo_workorders)):?> - + adb_wohneinheit_id && is_array($preorder->adb_wohneinheit->rimo_workorders) && count($preorder->adb_wohneinheit->rimo_workorders)):?>
is(["preorderfront"]) && !$me->is("preorderreadonly")): ?> @@ -742,7 +738,9 @@ $pagination_entity_name = "Vorbestellungen"; var marker_popup_content = ''; // popup fields + const preorder_view_url = `/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], diff --git a/Layout/default/Preorder/include/preorder-detail.php b/Layout/default/Preorder/include/preorder-detail.php index c444060d7..7ef1633aa 100644 --- a/Layout/default/Preorder/include/preorder-detail.php +++ b/Layout/default/Preorder/include/preorder-detail.php @@ -428,8 +428,8 @@ - adb_wohneinheit_id && $me->is("Admin")): ?> - + +
diff --git a/Layout/default/Preorder/include/preorder_popup.php b/Layout/default/Preorder/include/preorder_popup.php index e32a66709..9c580d8ab 100644 --- a/Layout/default/Preorder/include/preorder_popup.php +++ b/Layout/default/Preorder/include/preorder_popup.php @@ -37,6 +37,11 @@ ob_start(); Email: {{EMAIL}} - + + + + Bestellung ansehen + + \ No newline at end of file diff --git a/Layout/default/Preordercampaign/Form.php b/Layout/default/Preordercampaign/Form.php index 30479998d..8db2ea694 100644 --- a/Layout/default/Preordercampaign/Form.php +++ b/Layout/default/Preordercampaign/Form.php @@ -158,6 +158,9 @@ +
@@ -377,73 +380,81 @@

Emailbenachrichtigungen

-
-
-

Absender

-
- -
- -
-
-
- -
- -
-
- -

Emailtemplates

- -
"> - - + +
+
+

Absender

+
+
-
-
-
-
- code?> + +
+
+
+ +
+ +
+
+ +

Emailtemplates

+ +
"> + + +
+
+
+
+
+ code?> +
+
-
-
-
-
-
- @ -
- -
- +
+
+
+ @ +
+ +
+ +
-
-
-
-
- +
+
+
+ +
+
-
- - + +
-
+ +
+
+ Verfügbar nach Speichern... +
+
+

API-User

@@ -566,30 +577,32 @@ background: "bg-danger" }); - function sendTestStatusEmail(status_code) { - if(!status_code) return; + + 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("", - { - do: "sendStatusEmail", - campaign_id: 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("", + { + do: "sendStatusEmail", + campaign_id: 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" + ); + } + \ No newline at end of file diff --git a/Layout/default/WarehouseOrder/PDF_FOOTER.html b/Layout/default/WarehouseOrder/PDF_FOOTER.html new file mode 100644 index 000000000..0a984b7d6 --- /dev/null +++ b/Layout/default/WarehouseOrder/PDF_FOOTER.html @@ -0,0 +1,43 @@ + + + + Xinon Rechnung + + + + + + +
+
+ XINON GmbH | Fladnitz 150 | 8322 Studenzen
+ Tel.: +43 3115 40800 | E-Mail: office@xinon.at
+ UID: ATU68711968 | FN: 416556h | LG: Feldbach
+ IBAN: {{ bank_iban }} | BIC: {{ bank_bic }}
+
+ +
Seite von
+ +
+ + diff --git a/Layout/default/WarehouseOrder/PDF_HEADER.html b/Layout/default/WarehouseOrder/PDF_HEADER.html new file mode 100644 index 000000000..21802f9d5 --- /dev/null +++ b/Layout/default/WarehouseOrder/PDF_HEADER.html @@ -0,0 +1,92 @@ + + + + XINON Shipping Note Header + + + + + +
+ +
+ Xinon Logo +
+ + + + + + + +
+

Lieferant

+
{{ addressLine_1 }}
+
{{ addressLine_2 }}
+
{{ addressLine_3 }}
+
{{ addressLine_4 }}
+
+
{{ externalReference }}
+
+

Rechnungsadresse

+
{{ billingAddressLine_1 }}
+
{{ billingAddressLine_2 }}
+
{{ billingAddressLine_3 }}
+
{{ billingAddressLine_4 }}
+
{{ billingAddressLine_5 }}
+
{{ billingAddressLine_6 }}
+
+
{{ shippingAddressLine_1 }}
+
{{ shippingAddressLine_2 }}
+
{{ shippingAddressLine_3 }}
+
{{ shippingAddressLine_4 }}
+
+ + +
+ + + diff --git a/Layout/default/WarehouseOrder/PDF_MAIN.php b/Layout/default/WarehouseOrder/PDF_MAIN.php new file mode 100644 index 000000000..144555322 --- /dev/null +++ b/Layout/default/WarehouseOrder/PDF_MAIN.php @@ -0,0 +1,133 @@ +setReturnValue(['filename' => $order["id"] . ".pdf"]); +?> + + + + + Bestellung + + + + + + +
+ +

XINON Lieferantenbestellung vom

+ + + + + + + + + + + + + "> + + + + + + + + + + + + + + + + + +
PositionArtikelArt.-Nr. LieferantMengeEinzelpreisGesamtpreis
Summe
+ +
+

Anmerkungen

+

+ +

+
+ + \ No newline at end of file diff --git a/Layout/default/menu.php b/Layout/default/menu.php index 75cc6e347..0acf0392f 100644 --- a/Layout/default/menu.php +++ b/Layout/default/menu.php @@ -198,7 +198,7 @@ is(["Admin","salespartner"]) && $me->can("Order")): ?>
  • "> Bestellungen
  • - is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209])): ?> + is(["Admin","netowner","salespartner"]) && in_array($me->address_id, [1,209,5908])): ?>
  • "> Zustimmungserklärungen
  • diff --git a/application/ADBWohneinheit/ADBWohneinheit.php b/application/ADBWohneinheit/ADBWohneinheit.php index 363449209..552ef9c6b 100644 --- a/application/ADBWohneinheit/ADBWohneinheit.php +++ b/application/ADBWohneinheit/ADBWohneinheit.php @@ -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(); diff --git a/application/Address/AddressController.php b/application/Address/AddressController.php index 26c0fed77..cdb9f1543 100644 --- a/application/Address/AddressController.php +++ b/application/Address/AddressController.php @@ -1,659 +1,678 @@ needlogin=true; - $me = new User(); - $me->loadMe(); - $this->me = $me; - $this->layout()->set("me",$me); - - if(!$me->is(["Admin", "salespartner"])) { - $this->redirect("Dashboard"); - } - } - - protected function indexAction() { - $rfilter = $this->request->filter; - iF(!is_array($rfilter)) { - $rfilter = []; - } - if(!array_key_exists("addresstype", $rfilter)) { - $rfilter["addresstype"] = []; - } - - if($this->request->resetFilter) { - unset($_SESSION[MFAPPNAME.'-Address-filter']); - } - - $filter = []; - if(is_array($this->request->filter)) { - $filter = $this->request->filter; - $_SESSION[MFAPPNAME.'-Address-filter'] = $filter; - } else { - if(array_key_exists(MFAPPNAME.'-Address-filter', $_SESSION) && count($_SESSION[MFAPPNAME.'-Address-filter'])) { - $filter = $_SESSION[MFAPPNAME.'-Address-filter']; - } - } - - $this->layout->set("filter", $filter); - $filter = $this->getPreparedFilter($filter); - - // pagination defaults - $pagination = []; - $pagination['start'] = 0; - $pagination['count'] = 25; - $pagination['maxItems'] = 0; - - if(is_numeric($this->request->s)) { - $pagination['start'] = intval($this->request->s); - } - //var_dump($filter);exit; - $pagination['maxItems'] = AddressModel::count($filter); - $addresses = AddressModel::search($filter, $pagination); - - $this->layout()->set("addresses", $addresses); - $this->layout()->set("request", $this->request); - $this->layout()->set("pagination", $pagination); - - - $last_export = false; - $bmd_export_ts = new mfConfig("bmd.export.ts"); - if($bmd_export_ts->value()) { - $last_export = $bmd_export_ts->value(); - } - $this->layout()->set("last_bmd_export", $last_export); - - return true; - } - - - private function getPreparedFilter($filter) { - $new_filter = []; - - if(is_array($filter) && count($filter)) { - - $new_filter['add-where'] = ""; - - if(array_key_exists("kunde", $filter) && $filter["kunde"]) { - $kunde = $this->db()->escape($filter['kunde']); - // if kunde contains ß or ss we want to search both cases but not with % because it can lead to wrong results - if (strpos($kunde, "ß") !== false || strpos($kunde, "ss") !== false) { - $kundeWithSS = str_replace("ß", "ss", $kunde); - $kundeWithoutSS = str_replace("ss", "ß", $kunde); - $new_filter['add-where'] .= " AND (company like '%$kundeWithoutSS%' OR firstname like '%$kundeWithoutSS%' OR lastname like '%$kundeWithoutSS%' OR concat(firstname, ' ', lastname) like '%$kundeWithoutSS%' OR concat(lastname, ' ', firstname) like '%$kundeWithoutSS%')"; - $new_filter['add-where'] .= " OR (company like '%$kundeWithSS%' OR firstname like '%$kundeWithSS%' OR lastname like '%$kundeWithSS%' OR concat(firstname, ' ', lastname) like '%$kundeWithSS%' OR concat(lastname, ' ', firstname) like '%$kundeWithSS%')"; - } else { - $new_filter['add-where'] .= " AND (company like '%$kunde%' OR firstname like '%$kunde%' OR lastname like '%$kunde%' OR concat(firstname, ' ', lastname) like '%$kunde%' OR concat(lastname, ' ', firstname) like '%$kunde%')"; + private $filter; + + protected function init() { + $this->needlogin = true; + $me = new User(); + $me->loadMe(); + $this->me = $me; + $this->layout()->set("me", $me); + + if (!$me->is(["Admin", "salespartner"])) { + $this->redirect("Dashboard"); } - } - - if(!array_key_exists("parents_only", $filter)) { - $new_filter["parents_only"] = 1; - } - - if(array_key_exists("fibu_account_number", $filter) && $filter['fibu_account_number']) { - $new_filter['fibu_or_supplier_account_number'] = $filter['fibu_account_number']."%"; - unset($filter['fibu_account_number']); - } - - - if(!array_key_exists("customer_number", $filter) || !$filter["customer_number"]) { - if(array_key_exists("type", $filter)) { - if($filter["type"] == "systemowner") { - $new_filter["customer_or_fibu_numbers"] = true; - } elseif($filter["type"] == "others") { - $new_filter["customer_or_fibu_numbers"] = false; - } + } + + protected function indexAction() { + $rfilter = $this->request->filter; + iF(!is_array($rfilter)) { + $rfilter = []; + } + if (!array_key_exists("addresstype", $rfilter)) { + $rfilter["addresstype"] = []; + } + + if ($this->request->resetFilter) { + unset($_SESSION[MFAPPNAME . '-Address-filter']); + } + + $filter = []; + if (is_array($this->request->filter)) { + $filter = $this->request->filter; + $_SESSION[MFAPPNAME . '-Address-filter'] = $filter; } else { - if(defined("TT_ADDRESS_FILTER_DEFAULT_SYSOWNER") && TT_ADDRESS_FILTER_DEFAULT_SYSOWNER) { - $new_filter["customer_or_fibu_numbers"] = true; // default + if (array_key_exists(MFAPPNAME . '-Address-filter', $_SESSION) && count($_SESSION[MFAPPNAME . '-Address-filter'])) { + $filter = $_SESSION[MFAPPNAME . '-Address-filter']; } } - unset($filter["type"]); - unset($filter["customer_number"]); - } - - foreach($filter as $name => $value) { - $new_filter[$name] = $value; - } - } - return $new_filter; - } - - protected function addAction() { - $this->layout()->setTemplate("Address/Form"); + $this->layout->set("filter", $filter); + $filter = $this->getPreparedFilter($filter); - $this->layout->set("filter", $this->request->filter); - - //$parents = AddressModel::search(['parent_id' => null]); - //$this->layout()->set("parents", $parents); - } - - protected function viewAction() { - $this->layout()->setTemplate("Address/View"); - - $this->layout->set("filter", $this->request->filter); - $this->layout->set("f", $this->request->f); - $this->layout->set("s", $this->request->s); - - $address = new Address($this->request->id); - $this->layout()->set("address", $address); + // pagination defaults + $pagination = []; + $pagination['start'] = 0; + $pagination['count'] = 25; + $pagination['maxItems'] = 0; - //var_dump($address->links_to);exit; - - if(!$address->id) { - $this->layout()->setFlash("Addresse nicht gefunden", "error"); - $this->redirect("Address"); - } - - } + if (is_numeric($this->request->s)) { + $pagination['start'] = intval($this->request->s); + } + //var_dump($filter);exit; + $pagination['maxItems'] = AddressModel::count($filter); + $addresses = AddressModel::search($filter, $pagination); - protected function invoiceAction() { - $this->layout()->setTemplate("Address/invoice"); - - $address_id = $this->request->address_id; - if(!is_numeric($address_id) || $address_id < 1) { - $this->layout()->setFlash("Addresse nicht gefunden", "error"); - $this->redirect("Address"); - } - - $address = new Address($address_id); - if(!$address->id) { - $this->layout()->setFlash("Addresse nicht gefunden", "error"); - $this->redirect("Address"); - } - - $invoices = InvoiceModel::search(["owner_or_billingaddress_id" => $address->id], false, "invoice_date DESC"); - $this->layout()->set("invoices", $invoices); - $this->layout()->set("address", $address); + $this->layout()->set("addresses", $addresses); + $this->layout()->set("request", $this->request); + $this->layout()->set("pagination", $pagination); + $last_export = false; + $bmd_export_ts = new mfConfig("bmd.export.ts"); + if ($bmd_export_ts->value()) { + $last_export = $bmd_export_ts->value(); + } + $this->layout()->set("last_bmd_export", $last_export); - } - - protected function editAction() { - $address = new Address($this->request->id); - - $this->layout->set("filter", $this->request->filter); - $this->layout->set("f", $this->request->f); - $this->layout->set("s", $this->request->s); - - $this->layout()->set("address", $address); - - if(!$address->id) { - $this->layout()->setFlash("Addresse nicht gefunden", "error"); - return $this->addAction(); + return true; } - - return $this->addAction(); - } - - protected function deleteLink() { - $id = $this->request->id; - - if(!is_numeric($id) || !$id) { - $this->layout()->setFlash("Addresse nicht gefunden", "error"); - $this->redirect("Address"); - } - - $link = new AddressLink($id); - if(!$link->id) { - $this->layout()->setFlash("Addresse nicht gefunden", "error"); - $this->redirect("Address"); - } - - $address_id = $link->origin_address_id; - $link->delete(); - $this->layout()->setFlash("Verknüpfung erfolgreich entfernt", "success"); - $this->redirect("Address", "edit", ['id' => $address_id]); - - } - - protected function exportBmdAction() { - if(!$this->me->can("Fibu")) { - $this->layout()->setFlash("Sicha ned!", "error"); - $this->redirect("Address"); - } - - $return = Address::runBmdExport($this->request->type); - - if($return === 10) { - $this->layout()->setFlash("Export Pfad (".TT_ADDRESS_BMD_EXPORT_PATH.") nicht gefunden!", "error"); - $this->redirect("Address"); - } - - if($return === 11) { - $this->layout()->setFlash("Keine geänderten Adressdatensätze gefunden. Export abgebrochen.", "warn"); - $this->redirect("Address"); - } - - if($return === 19) { - $this->layout()->setFlash("Datei ".TT_ADDRESS_BMD_EXPORT_PATH."/".TT_ADDRESS_BMD_EXPORT_FILENAME." konnte nicht gespeichert werden!", "error"); - $this->redirect("Address"); - } - - if($return === true) { - $this->layout()->setFlash("Adressen erfolgreich exportiert", "success"); - $this->redirect("Address"); - } - - - } - - protected function saveAction() { - $r = $this->request; - $id = $r->id; - //var_dump($r->get());exit; - if(is_numeric($id) && $id > 0) { - $mode = "edit"; - $address = new Address($id); - if(!$address->id) { - $this->layout()->setFlash("Addresse nicht gefunden", "error"); - $this->redirect("Address"); - } - } else { - $mode = "add"; - } - - //var_dump($r->addresstypes);exit; - - $data = []; - $data['parent_id'] = (!$r->parent_id) ? null : $r->parent_id; - $data['company'] = trim($r->company); - $data['firstname'] = trim($r->firstname); - $data['lastname'] = trim($r->lastname); - $data['street'] = trim($r->street); - $data['zip'] = trim($r->zip); - $data['city'] = trim($r->city); - $data['country_id'] = $r->country_id; - $data['phone'] = trim($r->phone); - $data['fax'] = trim($r->fax); - $data['mobile'] = trim($r->mobile); - $data['email'] = trim($r->email); - $data['note'] = trim($r->note); - $data['uid'] = trim($r->uid); - if(trim($r->birthdate)) { - try { - $data["birthdate"] = (DateTime::createFromFormat("d.m.Y", trim($r->birthdate)))->format("Y-m-d"); - } catch(Exception $e) { - $this->layout()->setFlash("Ungültiges Geburtsdaum", "warning"); + + private function getPreparedFilter($filter) { + $new_filter = []; + + if (is_array($filter) && count($filter)) { + + $new_filter['add-where'] = ""; + + if (array_key_exists("kunde", $filter) && $filter["kunde"]) { + $kunde = $this->db()->escape($filter['kunde']); + // if kunde contains ß or ss we want to search both cases but not with % because it can lead to wrong results + if (strpos($kunde, "ß") !== false || strpos($kunde, "ss") !== false) { + $kundeWithSS = str_replace("ß", "ss", $kunde); + $kundeWithoutSS = str_replace("ss", "ß", $kunde); + $new_filter['add-where'] .= " AND (company like '%$kundeWithoutSS%' OR firstname like '%$kundeWithoutSS%' OR lastname like '%$kundeWithoutSS%' OR concat(firstname, ' ', lastname) like '%$kundeWithoutSS%' OR concat(lastname, ' ', firstname) like '%$kundeWithoutSS%')"; + $new_filter['add-where'] .= " OR (company like '%$kundeWithSS%' OR firstname like '%$kundeWithSS%' OR lastname like '%$kundeWithSS%' OR concat(firstname, ' ', lastname) like '%$kundeWithSS%' OR concat(lastname, ' ', firstname) like '%$kundeWithSS%')"; + } else { + $new_filter['add-where'] .= " AND (company like '%$kunde%' OR firstname like '%$kunde%' OR lastname like '%$kunde%' OR concat(firstname, ' ', lastname) like '%$kunde%' OR concat(lastname, ' ', firstname) like '%$kunde%')"; + } + } + + if (!array_key_exists("parents_only", $filter)) { + $new_filter["parents_only"] = 1; + } + + if (array_key_exists("fibu_account_number", $filter) && $filter['fibu_account_number']) { + $new_filter['fibu_or_supplier_account_number'] = $filter['fibu_account_number'] . "%"; + unset($filter['fibu_account_number']); + } + + + if (!array_key_exists("customer_number", $filter) || !$filter["customer_number"]) { + if (array_key_exists("type", $filter)) { + if ($filter["type"] == "systemowner") { + $new_filter["customer_or_fibu_numbers"] = true; + } elseif ($filter["type"] == "others") { + $new_filter["customer_or_fibu_numbers"] = false; + } + } else { + if (defined("TT_ADDRESS_FILTER_DEFAULT_SYSOWNER") && TT_ADDRESS_FILTER_DEFAULT_SYSOWNER) { + $new_filter["customer_or_fibu_numbers"] = true; // default + } + } + unset($filter["type"]); + unset($filter["customer_number"]); + } + + foreach ($filter as $name => $value) { + $new_filter[$name] = $value; + } + } + + return $new_filter; + } + + protected function addAction() { + $this->layout()->setTemplate("Address/Form"); + + $this->layout->set("filter", $this->request->filter); + + //$parents = AddressModel::search(['parent_id' => null]); + //$this->layout()->set("parents", $parents); + } + + protected function viewAction() { + $this->layout()->setTemplate("Address/View"); + + $this->layout->set("filter", $this->request->filter); + $this->layout->set("f", $this->request->f); + $this->layout->set("s", $this->request->s); + + $address = new Address($this->request->id); + $this->layout()->set("address", $address); + + //var_dump($address->links_to);exit; + + if (!$address->id) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + $this->redirect("Address"); } } + protected function invoiceAction() { + $this->layout()->setTemplate("Address/invoice"); - if($this->me->can("Fibu")) { - $data["sepa_date"] = ($r->sepa_date) ? Layout::dateToInt($r->sepa_date) : null; - - $data['fibu_account_number'] = ($r->fibu_account_number) ? trim($r->fibu_account_number) : null; - $data['fibu_supplier_number'] = ($r->fibu_supplier_number) ? trim($r->fibu_supplier_number) : null; - if($r->fibu_primary_account) { - $data['fibu_primary_account'] = 1; - } else { - $data['fibu_primary_account'] = 0; - } - - if($r->fibu_supplier_paymentblock) { - $data['fibu_supplier_paymentblock'] = 1; - } else { - $data['fibu_supplier_paymentblock'] = 0; - } - - $data['fibu_supplier_due'] = ($r->fibu_supplier_due) ? trim($r->fibu_supplier_due) : null; - $data['fibu_supplier_skonto'] = ($r->fibu_supplier_skonto) ? trim($r->fibu_supplier_skonto) : null; - $data['fibu_supplier_skonto_rate'] = ($r->fibu_supplier_skonto_rate) ? trim($r->fibu_supplier_skonto_rate) : null; - } - - - // billing data - // validate sepa - if(!$r->billing_type) { - $this->layout()->setFlash("Ungültige Verrechnungsart."); - $this->layout()->set("order", $r); - return $this->add(); - } - - if($r->billing_type == "sepa") { - foreach(['owner', 'iban', 'bic'] as $required) { - if(!$r->{"bank_account_$required"}) { - $this->layout()->setFlash("Bitte Bankdaten für SEPA ausfüllen.", "warn"); - $this->layout()->set("address", $r); - return $this->add(); + $address_id = $this->request->address_id; + if (!is_numeric($address_id) || $address_id < 1) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + $this->redirect("Address"); } - } - } - - if($r->billing_type == "sepa") { - $data['billing_type'] = "sepa"; - if(!$r->sepa_date) { - if($mode == "add" || ($mode == "edit" && !$address->sepa_date)) { - $data['sepa_date'] = date('U'); + + $address = new Address($address_id); + if (!$address->id) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + $this->redirect("Address"); } - } else { - $data['sepa_date'] = Layout::dateToInt($r->sepa_date); - } - } else { - $data['billing_type'] = "invoice"; + + $invoices = InvoiceModel::search(["owner_or_billingaddress_id" => $address->id], false, "invoice_date DESC"); + $this->layout()->set("invoices", $invoices); + $this->layout()->set("address", $address); + + } - - if($r->billing_delivery == "paper") { - $data['billing_delivery'] = "paper"; - } else { - $data['billing_delivery'] = "email"; + + protected function editAction() { + $address = new Address($this->request->id); + + $this->layout->set("filter", $this->request->filter); + $this->layout->set("f", $this->request->f); + $this->layout->set("s", $this->request->s); + + $this->layout()->set("address", $address); + + if (!$address->id) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + return $this->addAction(); + } + + return $this->addAction(); } - - - $data['bank_account_bank'] = trim($r->bank_account_bank); - $data['bank_account_owner'] = trim($r->bank_account_owner); - $data['bank_account_iban'] = trim($r->bank_account_iban); - $data['bank_account_bic'] = trim($r->bank_account_bic); - $data['allow_contact'] = ($r->allow_contact) ? 1 : 0; - $data['allow_spin'] = ($r->allow_spin) ? 1 : 0; - - if($mode == "add") { - $address = AddressModel::create($data); - } else { - $address->update($data); + + protected function deleteLink() { + $id = $this->request->id; + + if (!is_numeric($id) || !$id) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + $this->redirect("Address"); + } + + $link = new AddressLink($id); + if (!$link->id) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + $this->redirect("Address"); + } + + $address_id = $link->origin_address_id; + $link->delete(); + $this->layout()->setFlash("Verknüpfung erfolgreich entfernt", "success"); + $this->redirect("Address", "edit", ['id' => $address_id]); + } - - //var_dump($address);exit; - - $new_id = $address->save(); - if(!$new_id) { - $this->layout()->setFlash("Fehler beim Speichern", "error"); - $this->layout()->set("address", $address); - return $this->add(); + + protected function exportBmdAction() { + if (!$this->me->can("Fibu")) { + $this->layout()->setFlash("Sicha ned!", "error"); + $this->redirect("Address"); + } + + $return = Address::runBmdExport($this->request->type); + + if ($return === 10) { + $this->layout()->setFlash("Export Pfad (" . TT_ADDRESS_BMD_EXPORT_PATH . ") nicht gefunden!", "error"); + $this->redirect("Address"); + } + + if ($return === 11) { + $this->layout()->setFlash("Keine geänderten Adressdatensätze gefunden. Export abgebrochen.", "warn"); + $this->redirect("Address"); + } + + if ($return === 19) { + $this->layout()->setFlash("Datei " . TT_ADDRESS_BMD_EXPORT_PATH . "/" . TT_ADDRESS_BMD_EXPORT_FILENAME . " konnte nicht gespeichert werden!", "error"); + $this->redirect("Address"); + } + + if ($return === true) { + $this->layout()->setFlash("Adressen erfolgreich exportiert", "success"); + $this->redirect("Address"); + } + + } - - // check for multiple primary fibu accounts, and remove from any other than this one - if($address->fibu_primary_account && $address->fibu_account_number) { - foreach(AddressModel::search(["fibu_primary_account" => true, "fibu_account_number" => $address->fibu_account_number]) as $fibu_primary) { - if($fibu_primary->id == $address->id) continue; - $fibu_primary->fibu_primary_account = 0; - $fibu_primary->save(); - } - } - - - // save address types - $new_types = $r->addresstypes; - if(is_array($new_types)) { - foreach($address->types as $existing_type) { - //var_dump($existing_type); - //var_dump($new_types); - //echo $existing_type->type; - if(!in_array($existing_type->type, $new_types)) { - $existing_type->delete(); + + protected function saveAction() { + $r = $this->request; + $id = $r->id; + //var_dump($r->get());exit; + if (is_numeric($id) && $id > 0) { + $mode = "edit"; + $address = new Address($id); + if (!$address->id) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + $this->redirect("Address"); + } } else { - // remove existing type from new_types array (dont need to create again) - $new_types = array_diff($new_types, [$existing_type->type]); - //unset($new_types[$existing_type]); + $mode = "add"; } - } - //exit; - foreach($new_types as $type) { - $type_object = AddresstypeModel::create(['address_id' => $address->id, 'type' => $type]); - $type_object->save(); - $address->types[$type] = $type_object; - } - } - - // generate new supplier account number if is supplier and supplier num empty - //var_dump($mode, $address->fibu_supplier_number, $address->types);exit; - if(!$address->fibu_supplier_number && array_key_exists("supplier", $address->types)) { - $supplier_num = Address::getNextSupplierNumber(); - if(!$supplier_num) { - $this->layout()->setFlash("Lieferantennummer konnte nicht generiert werden."); - } else { - $this->log->debug("new supplier number: ". $supplier_num); - $address->fibu_supplier_number = $supplier_num; - $address->save(); - } - } - - $attribs = $r->attributes; - //var_dump($attribs);exit; - if(is_array($attribs) && count($attribs)) { - foreach($attribs as $attrib => $value) { - $aa = AddressattributeModel::getFirst(["address_id" => $new_id, "name" => $attrib]); - - if(!$aa) { - $aa = AddressattributeModel::create(["address_id" => $new_id, "name" => $attrib]); + + //var_dump($r->addresstypes);exit; + + $data = []; + $data['parent_id'] = (!$r->parent_id) ? null : $r->parent_id; + $data['company'] = trim($r->company); + $data['firstname'] = trim($r->firstname); + $data['lastname'] = trim($r->lastname); + $data['street'] = trim($r->street); + $data['zip'] = trim($r->zip); + $data['city'] = trim($r->city); + $data['country_id'] = $r->country_id; + $data['phone'] = trim($r->phone); + $data['fax'] = trim($r->fax); + $data['mobile'] = trim($r->mobile); + $data['email'] = trim($r->email); + $data['note'] = trim($r->note); + $data['uid'] = trim($r->uid); + + if (trim($r->birthdate)) { + try { + $data["birthdate"] = (DateTime::createFromFormat("d.m.Y", trim($r->birthdate)))->format("Y-m-d"); + } catch (Exception $e) { + $this->layout()->setFlash("Ungültiges Geburtsdaum", "warning"); + } + } - $aa->value = $value; - $aa->save(); - } - } - - - //$address->deleteLinks(); - - $existing_links = []; - foreach(AddressLinkModel::search(['origin_address_id', $new_id]) as $elink) { - $existing_links[$elink->address_id] = $elink; - } - - //var_dump($r->links);exit; - if(is_array($r->links) && count($r->links)) { - //var_dump($r->links);exit; - foreach($r->links as $linknum => $link) { - if(!$link['type'] || !$link['address_id']) { - continue; + + + if ($this->me->can("Fibu")) { + $data["sepa_date"] = ($r->sepa_date) ? Layout::dateToInt($r->sepa_date) : null; + + $data['fibu_account_number'] = ($r->fibu_account_number) ? trim($r->fibu_account_number) : null; + $data['fibu_supplier_number'] = ($r->fibu_supplier_number) ? trim($r->fibu_supplier_number) : null; + if ($r->fibu_primary_account) { + $data['fibu_primary_account'] = 1; + } else { + $data['fibu_primary_account'] = 0; + } + + if ($r->fibu_supplier_paymentblock) { + $data['fibu_supplier_paymentblock'] = 1; + } else { + $data['fibu_supplier_paymentblock'] = 0; + } + + $data['fibu_supplier_due'] = ($r->fibu_supplier_due) ? trim($r->fibu_supplier_due) : null; + $data['fibu_supplier_skonto'] = ($r->fibu_supplier_skonto) ? trim($r->fibu_supplier_skonto) : null; + $data['fibu_supplier_skonto_rate'] = ($r->fibu_supplier_skonto_rate) ? trim($r->fibu_supplier_skonto_rate) : null; } - if(array_key_exists($link['address_id'], $existing_links)) { - continue; + + + // billing data + // validate sepa + if (!$r->billing_type) { + $this->layout()->setFlash("Ungültige Verrechnungsart."); + $this->layout()->set("order", $r); + return $this->add(); } - $l = AddressLinkModel::create([ - 'origin_address_id' => $new_id, - 'type' => $link['type'], - 'address_id' => $link['address_id'] - ]); - $l->save(); - - } + + if ($r->billing_type == "sepa") { + foreach (['owner', 'iban', 'bic'] as $required) { + if (!$r->{"bank_account_$required"}) { + $this->layout()->setFlash("Bitte Bankdaten für SEPA ausfüllen.", "warn"); + $this->layout()->set("address", $r); + return $this->add(); + } + } + } + + if ($r->billing_type == "sepa") { + $data['billing_type'] = "sepa"; + if (!$r->sepa_date) { + if ($mode == "add" || ($mode == "edit" && !$address->sepa_date)) { + $data['sepa_date'] = date('U'); + } + } else { + $data['sepa_date'] = Layout::dateToInt($r->sepa_date); + } + } else { + $data['billing_type'] = "invoice"; + } + + if ($r->billing_delivery == "paper") { + $data['billing_delivery'] = "paper"; + } else { + $data['billing_delivery'] = "email"; + } + + + $data['bank_account_bank'] = trim($r->bank_account_bank); + $data['bank_account_owner'] = trim($r->bank_account_owner); + $data['bank_account_iban'] = trim($r->bank_account_iban); + $data['bank_account_bic'] = trim($r->bank_account_bic); + $data['allow_contact'] = ($r->allow_contact) ? 1 : 0; + $data['allow_spin'] = ($r->allow_spin) ? 1 : 0; + + if ($mode == "add") { + $address = AddressModel::create($data); + } else { + $address->update($data); + } + + //var_dump($address);exit; + + $new_id = $address->save(); + if (!$new_id) { + $this->layout()->setFlash("Fehler beim Speichern", "error"); + $this->layout()->set("address", $address); + return $this->add(); + } + + // check for multiple primary fibu accounts, and remove from any other than this one + if ($address->fibu_primary_account && $address->fibu_account_number) { + foreach (AddressModel::search(["fibu_primary_account" => true, "fibu_account_number" => $address->fibu_account_number]) as $fibu_primary) { + if ($fibu_primary->id == $address->id) continue; + $fibu_primary->fibu_primary_account = 0; + $fibu_primary->save(); + } + } + + + // save address types + $new_types = $r->addresstypes; + if (is_array($new_types)) { + foreach ($address->types as $existing_type) { + //var_dump($existing_type); + //var_dump($new_types); + //echo $existing_type->type; + if (!in_array($existing_type->type, $new_types)) { + $existing_type->delete(); + } else { + // remove existing type from new_types array (dont need to create again) + $new_types = array_diff($new_types, [$existing_type->type]); + //unset($new_types[$existing_type]); + } + } + //exit; + foreach ($new_types as $type) { + $type_object = AddresstypeModel::create(['address_id' => $address->id, 'type' => $type]); + $type_object->save(); + $address->types[$type] = $type_object; + } + } + + // generate new supplier account number if is supplier and supplier num empty + //var_dump($mode, $address->fibu_supplier_number, $address->types);exit; + if (!$address->fibu_supplier_number && array_key_exists("supplier", $address->types)) { + $supplier_num = Address::getNextSupplierNumber(); + if (!$supplier_num) { + $this->layout()->setFlash("Lieferantennummer konnte nicht generiert werden."); + } else { + $this->log->debug("new supplier number: " . $supplier_num); + $address->fibu_supplier_number = $supplier_num; + $address->save(); + } + } + + $attribs = $r->attributes; + //var_dump($attribs);exit; + if (is_array($attribs) && count($attribs)) { + foreach ($attribs as $attrib => $value) { + $aa = AddressattributeModel::getFirst(["address_id" => $new_id, "name" => $attrib]); + + if (!$aa) { + $aa = AddressattributeModel::create(["address_id" => $new_id, "name" => $attrib]); + } + $aa->value = $value; + $aa->save(); + } + } + + + //$address->deleteLinks(); + + $existing_links = []; + foreach (AddressLinkModel::search(['origin_address_id', $new_id]) as $elink) { + $existing_links[$elink->address_id] = $elink; + } + + //var_dump($r->links);exit; + if (is_array($r->links) && count($r->links)) { + //var_dump($r->links);exit; + foreach ($r->links as $linknum => $link) { + if (!$link['type'] || !$link['address_id']) { + continue; + } + if (array_key_exists($link['address_id'], $existing_links)) { + continue; + } + $l = AddressLinkModel::create([ + 'origin_address_id' => $new_id, + 'type' => $link['type'], + 'address_id' => $link['address_id'] + ]); + $l->save(); + + } + } + + // run afterSave() again in case anything importand has changed + $address->afterSave(); + + $sq = ""; + $query = []; + if ($r->s) { + $query['s'] = $r->s; + } + if ($r->return != "index") { + $query['id'] = $new_id; + } + + $qs = http_build_query($query); + + $this->layout()->setFlash("Adresse erfolgreich gespeichert.", "success"); + if ($r->return == "index") { + $this->redirect("Address", "Index", $qs); + } + if ($r->f == "view") { + $this->redirect("Address", "View", $qs); + } + $this->redirect("Address", "Edit", $qs); } - // run afterSave() again in case anything importand has changed - $address->afterSave(); - - $sq = ""; - $query = []; - if($r->s) { - $query['s'] = $r->s; - } - if($r->return != "index") { - $query['id'] = $new_id; - } - - $qs = http_build_query($query); - - $this->layout()->setFlash("Adresse erfolgreich gespeichert.", "success"); - if($r->return == "index") { - $this->redirect("Address", "Index", $qs); - } - if($r->f == "view") { - $this->redirect("Address", "View", $qs); - } - $this->redirect("Address", "Edit", $qs); - } - - - protected function apiAction() { - if(!$this->me->is(["Admin","salespartner"])) { - $this->redirect("Dashboard"); - } - $do = $this->request->do; - $data = []; - - switch($do) { - case "getAddress": - $return = $this->getAddressApi(); - break; - case "findAddress": - $return = $this->findAddressApi(); - break; - case "validateIbanBic": - $return = $this->validateIbanBicApi(); - break; - default: - $return = false; - } - - if(!is_array($return) || !count($return)) { - $data = ["status" => "error"]; - $this->returnJson($data); - } - $data['status'] = "OK"; - $data['result'] = $return; - $this->returnJson($data); - } - - private function getAddressApi() { - $id = trim($this->request->id); - if(!is_numeric($id) || !$id) { - return false; - } - - $address = new Address($id); - if(!$address->id) { - return false; - } - - $a = $address->toArray(); - $a['name'] = $address->getCompanyOrName(); - - return ['address' => $a]; - } - - private function findAddressApi() { - $search = trim($this->request->q); - $autocomplete = $this->request->autocomplete; - if($autocomplete && $this->request->searchedID) { - $address = new Address($this->request->searchedID); - if($address->id) { - $result = [ - 'value' => $address->id, - 'text' => str_replace("'", "\\'", str_replace(["\n", "\r"], " ",$address->getCompanyOrName()))." (".$address->zip." ".$address->city.", ".$address->street.")".(($address->customer_number) ? " [".$address->customer_number."]" : "") - ]; + protected function apiAction() { + if (!$this->me->is(["Admin", "salespartner"])) { + $this->redirect("Dashboard"); + } + $do = $this->request->do; + $data = []; + + switch ($do) { + case "getAddress": + $return = $this->getAddressApi(); + break; + case "findAddress": + $return = $this->findAddressApi(); + break; + case "validateIbanBic": + $return = $this->validateIbanBicApi(); + break; + default: + $return = false; + } + + if (!is_array($return) || !count($return)) { + $data = ["status" => "error"]; + $this->returnJson($data); + } + $data['status'] = "OK"; + $data['result'] = $return; + $this->returnJson($data); + } + + private function getAddressApi() { + $id = trim($this->request->id); + if (!is_numeric($id) || !$id) { + return false; + } + + $address = new Address($id); + if (!$address->id) { + return false; + } + + $a = $address->toArray(); + $a['name'] = $address->getCompanyOrName(); + + return ['address' => $a]; + } + + private function findAddressApi() { + $search = trim($this->request->q); + $autocomplete = $this->request->autocomplete; + + if ($autocomplete && $this->request->searchedID) { + $address = new Address($this->request->searchedID); + if ($address->id) { + $result = [ + 'value' => $address->id, + 'text' => str_replace("'", "\\'", str_replace(["\n", + "\r"], " ", $address->getCompanyOrName())) . " (" . $address->zip . " " . $address->city . ", " . $address->street . ")" . (($address->customer_number) ? " [" . $address->customer_number . "]" : "") + ]; + $results[] = $result; + $this->returnJson($results); + die(); + } + } + + $po = 1; + $role = false; + // if searching for billingaddress, set role and parents_only to 0 + if ($this->request->role == "billingaddress") { + $role = "billing"; + $po = 0; + } + if ($this->request->role == "techcontact") { + $role = "techcontact"; + $po = 0; + } + + $this->log->debug(print_r($this->request->get(), true)); + + $addresses = []; + + if (is_numeric($search)) { + $cnumbers = AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "customer_number" => $search]); + if ($cnumbers) { + $addresses = array_merge($addresses, $cnumbers); + } + } + + + if (isset($_GET['fibu_primary_account'])) { + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, + "addresstype" => [$role], + "mergedName" => $search, + "fibu_primary_account" => true])); + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, + "addresstype" => [$role], + "company" => $search, + "fibu_primary_account" => true])); + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, + "addresstype" => [$role], + "firstname" => $search, + "fibu_primary_account" => true])); + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, + "addresstype" => [$role], + "lastname" => $search, + "fibu_primary_account" => true])); + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, + "addresstype" => [$role], + "street" => $search, + "fibu_primary_account" => true])); + + } else { + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "mergedName" => $search])); + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "company" => $search])); + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "firstname" => $search])); + $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "lastname" => $search])); + } + + if (!is_array($addresses) || !count($addresses)) { + return false; + } + + $all_addresses = []; + + // remove duplicates + foreach ($addresses as $address) { + if (!array_key_exists($address->id, $all_addresses)) { + $all_addresses[$address->id] = $address; + } + } + + $results = []; + + if (!$autocomplete) { + foreach ($all_addresses as $id => $address) { + $results[$id] = str_replace("'", "\\'", str_replace(["\n", + "\r"], " ", $address->getCompanyOrName())) . " (" . $address->zip . " " . $address->city . ", " . $address->street . ")" . (($address->customer_number) ? " [" . $address->customer_number . "]" : ""); + if (count($results) > 15) { + $results["more"] = "..."; + break; + } + } + + return ["addresses" => $results]; + } + + // return bootstrap-autocomplete format + foreach ($all_addresses as $id => $address) { + $result = ['value' => $id, + 'text' => str_replace("'", "\\'", str_replace(["\n", + "\r"], " ", $address->getCompanyOrName())) . " (" . $address->zip . " " . $address->city . ", " . $address->street . ")" . (($address->customer_number) ? " [" . $address->customer_number . "]" : "")]; $results[] = $result; - $this->returnJson($results); - die(); + if (count($results) > 15) { + $results[] = ['value' => 0, + 'text' => "  -->   Mehr Suchergebnisse vorhanden. Bitte Suchbegriff genauer definieren   <--"]; + break; + } } + + $this->returnJson($results); } - $po = 1; - $role = false; - // if searching for billingaddress, set role and parents_only to 0 - if($this->request->role == "billingaddress") { - $role = "billing"; - $po = 0; - } - if($this->request->role == "techcontact") { - $role = "techcontact"; - $po = 0; - } - - $this->log->debug(print_r($this->request->get(),true)); - - $addresses = []; - - if(is_numeric($search)) { - $cnumbers = AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "customer_number" => $search]); - if($cnumbers) { - $addresses = array_merge($addresses, $cnumbers); - } - } - + private function validateIbanBicApi() { + $iban = trim($this->request->iban); + $bic = trim($this->request->bic); - if (isset($_GET['fibu_primary_account'])) { - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "mergedName" => $search, "fibu_primary_account" => true])); - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "company" => $search, "fibu_primary_account" => true])); - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "firstname" => $search, "fibu_primary_account" => true])); - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "lastname" => $search, "fibu_primary_account" => true])); - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "street" => $search, "fibu_primary_account" => true])); - - } else { - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "mergedName" => $search])); - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "company" => $search])); - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "firstname" => $search])); - $addresses = array_merge($addresses, AddressModel::search(["parents_only" => $po, "addresstype" => [$role], "lastname" => $search])); - } - - if(!is_array($addresses) || !count($addresses)) { - return false; - } - - $all_addresses = []; - - // remove duplicates - foreach($addresses as $address) { - if(!array_key_exists($address->id, $all_addresses)) { - $all_addresses[$address->id] = $address; - } - } - - $results = []; - - if(!$autocomplete) { - foreach($all_addresses as $id => $address) { - $results[$id] = str_replace("'", "\\'", str_replace(["\n", "\r"], " ",$address->getCompanyOrName()))." (".$address->zip." ".$address->city.", ".$address->street.")".(($address->customer_number) ? " [".$address->customer_number."]" : ""); - if(count($results) > 15) { - $results["more"] = "..."; - break; + if (!$iban) { + return false; } - } - return ["addresses" => $results]; - } - - // return bootstrap-autocomplete format - foreach($all_addresses as $id => $address) { - $result = ['value' => $id, 'text' => str_replace("'", "\\'", str_replace(["\n", "\r"], " ",$address->getCompanyOrName()))." (".$address->zip." ".$address->city.", ".$address->street.")".(($address->customer_number) ? " [".$address->customer_number."]" : "")]; - $results[] = $result; - if(count($results) > 15) { - $results[] = ['value' => 0, 'text' => "  -->   Mehr Suchergebnisse vorhanden. Bitte Suchbegriff genauer definieren   <--"]; - break; - } + $result = IbanValidator::validate($iban, $bic); + if (is_array($result) && $result) { + return $result; + } + + return false; + } - $this->returnJson($results); - } - - private function validateIbanBicApi() { - $iban = trim($this->request->iban); - $bic = trim($this->request->bic); - - if(!$iban) { - return false; - } - - $result = IbanValidator::validate($iban, $bic); - if(is_array($result) && $result) { - return $result; - } - - return false; - - } - - public function createTicketAction() { + public function createTicketAction() { // die('{"derivedStartDate":null,"derivedDueDate":null,"spentTime":"PT0S","laborCosts":"0,00 EUR","materialCosts":"0,00 EUR","overallCosts":"0,00 EUR","_embedded":{"attachments":{"_type":"Collection","total":0,"count":0,"_embedded":{"elements":[]},"_links":{"self":{"href":"/api/v3/work_packages/6664/attachments"}}},"relations":{"_type":"Collection","total":0,"count":0,"_embedded":{"elements":[]},"_links":{"self":{"href":"/api/v3/work_packages/6664/relations"}}},"type":{"_type":"Type","id":12,"name":"Störung","color":"#FF3300","position":4,"isDefault":true,"isMilestone":false,"createdAt":"2023-02-22T20:19:25Z","updatedAt":"2023-02-23T11:59:16Z","_links":{"self":{"href":"/api/v3/types/12","title":"Störung"}}},"priority":{"_type":"Priority","id":8,"name":"Residential","position":2,"color":"#74C0FC","isDefault":true,"isActive":true,"_links":{"self":{"href":"/api/v3/priorities/8","title":"Residential"}}},"project":{"_type":"Project","id":10,"identifier":"storungen-and-support","name":"Störungen & Support","active":true,"public":false,"description":{"format":"markdown","raw":"","html":""},"createdAt":"2023-02-22T19:45:24Z","updatedAt":"2024-01-19T19:56:27Z","statusExplanation":{"format":"markdown","raw":"","html":""},"_links":{"self":{"href":"/api/v3/projects/10","title":"Störungen & Support"},"createWorkPackage":{"href":"/api/v3/projects/10/work_packages/form","method":"post"},"createWorkPackageImmediately":{"href":"/api/v3/projects/10/work_packages","method":"post"},"workPackages":{"href":"/api/v3/projects/10/work_packages"},"categories":{"href":"/api/v3/projects/10/categories"},"versions":{"href":"/api/v3/projects/10/versions"},"memberships":{"href":"/api/v3/memberships?filters=%5B%7B%22project%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%2210%22%5D%7D%7D%5D"},"types":{"href":"/api/v3/projects/10/types"},"schema":{"href":"/api/v3/projects/schema"},"status":{"href":null},"ancestors":[{"href":"/api/v3/projects/5","title":"XINON"}],"parent":{"href":"/api/v3/projects/5","title":"XINON"}}},"status":{"_type":"Status","id":1,"name":"Neu","isClosed":false,"color":"#1098AD","isDefault":true,"isReadonly":false,"defaultDoneRatio":null,"position":1,"_links":{"self":{"href":"/api/v3/statuses/1","title":"Neu"}}},"author":{"_type":"User","id":30,"name":"Luca Haid","createdAt":"2024-02-05T11:35:52Z","updatedAt":"2024-10-21T06:32:44Z","login":"luca.haid@xinon.eu","firstName":"Luca","lastName":"Haid","email":"luca.haid@xinon.eu","avatar":"https://secure.gravatar.com/avatar/37a35a87af3c506c1ce722826834ce38?default=404&secure=true","status":"active","identityUrl":null,"language":"de","_links":{"self":{"href":"/api/v3/users/30","title":"Luca Haid"},"memberships":{"href":"/api/v3/memberships?filters=%5B%7B%22principal%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%2230%22%5D%7D%7D%5D","title":"Mitglieder"},"showUser":{"href":"/users/30","type":"text/html"}}},"customActions":[],"costsByType":{"_type":"Collection","total":0,"count":0,"_embedded":{"elements":[]},"_links":{"self":{"href":"/api/v3/work_packages/6664/summarized_costs_by_type"}}}},"_type":"WorkPackage","id":6664,"lockVersion":1,"subject":"tes","description":{"format":"markdown","raw":"ttest","html":"

    ttest

    "},"scheduleManually":false,"startDate":null,"dueDate":null,"estimatedTime":null,"derivedEstimatedTime":null,"duration":null,"ignoreNonWorkingDays":false,"percentageDone":0,"createdAt":"2024-10-31T12:48:27Z","updatedAt":"2024-10-31T12:48:27Z","readonly":false,"remainingTime":null,"customField1":null,"customField2":"4 Quality GmbH & Co KG","customField3":"Grazerstraße 87, 8111 Judendorf-Straßengel","customField4":"test","customField5":"office@4quality.at","customField6":"2215","customField7":"ZE4889","_links":{"attachments":{"href":"/api/v3/work_packages/6664/attachments"},"addAttachment":{"href":"/api/v3/work_packages/6664/attachments","method":"post"},"self":{"href":"/api/v3/work_packages/6664","title":"tes"},"update":{"href":"/api/v3/work_packages/6664/form","method":"post"},"schema":{"href":"/api/v3/work_packages/schemas/10-12"},"updateImmediately":{"href":"/api/v3/work_packages/6664","method":"patch"},"logTime":{"href":"/api/v3/time_entries","title":"Log time on tes"},"move":{"href":"/work_packages/6664/move/new","type":"text/html","title":"Move tes"},"copy":{"href":"/work_packages/6664/copy","title":"Copy tes"},"pdf":{"href":"/work_packages/6664.pdf","type":"application/pdf","title":"Export as PDF"},"atom":{"href":"/work_packages/6664.atom","type":"application/rss+xml","title":"Atom feed"},"availableRelationCandidates":{"href":"/api/v3/work_packages/6664/available_relation_candidates","title":"Potential work packages to relate to"},"activities":{"href":"/api/v3/work_packages/6664/activities"},"availableWatchers":{"href":"/api/v3/work_packages/6664/available_watchers"},"relations":{"href":"/api/v3/work_packages/6664/relations"},"revisions":{"href":"/api/v3/work_packages/6664/revisions"},"watchers":{"href":"/api/v3/work_packages/6664/watchers"},"addWatcher":{"href":"/api/v3/work_packages/6664/watchers","method":"post","payload":{"user":{"href":"/api/v3/users/{user_id}"}},"templated":true},"removeWatcher":{"href":"/api/v3/work_packages/6664/watchers/{user_id}","method":"delete","templated":true},"addRelation":{"href":"/api/v3/work_packages/6664/relations","method":"post","title":"Add relation"},"addChild":{"href":"/api/v3/projects/storungen-and-support/work_packages","method":"post","title":"Add child of tes"},"changeParent":{"href":"/api/v3/work_packages/6664","method":"patch","title":"Change parent of tes"},"addComment":{"href":"/api/v3/work_packages/6664/activities","method":"post","title":"Add comment"},"previewMarkup":{"href":"/api/v3/render/markdown?context=/api/v3/work_packages/6664","method":"post"},"timeEntries":{"href":"/api/v3/time_entries?filters=%5B%7B%22work_package_id%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%226664%22%5D%7D%7D%5D","title":"Time entries"},"category":{"href":null},"type":{"href":"/api/v3/types/12","title":"Störung"},"priority":{"href":"/api/v3/priorities/8","title":"Residential"},"project":{"href":"/api/v3/projects/10","title":"Störungen & Support"},"status":{"href":"/api/v3/statuses/1","title":"Neu"},"author":{"href":"/api/v3/users/30","title":"Luca Haid"},"responsible":{"href":null},"assignee":{"href":null},"version":{"href":null},"logCosts":{"href":"/work_packages/6664/cost_entries/new","type":"text/html","title":"Log costs on tes"},"showCosts":{"href":"/projects/10/cost_reports?fields%5B%5D=WorkPackageId&operators%5BWorkPackageId%5D=%3D&set_filter=1&values%5BWorkPackageId%5D=6664","type":"text/html","title":"Show cost entries"},"costsByType":{"href":"/api/v3/work_packages/6664/summarized_costs_by_type"},"github_pull_requests":{"href":"/api/v3/work_packages/6664/github_pull_requests","title":"GitHub pull requests"},"unwatch":{"href":"/api/v3/work_packages/6664/watchers/30","method":"delete"},"ancestors":[],"parent":{"href":null,"title":null},"customActions":[]}}'); - // subject: test - //description: test - //customer_name: 4 Quality GmbH & Co KG - //customer_number: 2215 - //customer_address: Grazerstraße 87, 8111 Judendorf-Straßengel - //customer_phone_number: 0664 - //customer_email: office@4quality.at - //customer_service_pin: ZE4889 + // subject: test + //description: test + //customer_name: 4 Quality GmbH & Co KG + //customer_number: 2215 + //customer_address: Grazerstraße 87, 8111 Judendorf-Straßengel + //customer_phone_number: 0664 + //customer_email: office@4quality.at + //customer_service_pin: ZE4889 - $subject = $this->request->subject; + $subject = $this->request->subject; $description = $this->request->description; $customer_name = $this->request->customer_name; $customer_number = $this->request->customer_number; @@ -661,12 +680,29 @@ class AddressController extends mfBaseController { $customer_phone_number = $this->request->customer_phone_number; $customer_email = $this->request->customer_email; $customer_service_pin = $this->request->customer_service_pin; - $user_api_key = (string)$this->me->getFlag('project_api_key'); + $user_api_key = (string) $this->me->getFlag('project_api_key'); $xinon_project = new XinonProject(); $response = $xinon_project->createNewFaultTicket($subject, $description, $customer_name, $customer_number, $customer_address, $customer_phone_number, $customer_email, $customer_service_pin, $user_api_key); die($response); - } + } + + protected function ticketsAction() { + $address_id = $this->request->address_id; + + $address = new Address($address_id); + if (!$address->id) { + $this->layout()->setFlash("Addresse nicht gefunden", "error"); + $this->redirect("Address"); + } + + $xinon_project = new XinonProject(); + $tickets = $xinon_project->searchSupportTickets('', 0, ['pageSize' => 100, + 'filters' => json_encode([['customField6' => ['operator' => '=', 'values' => [$address->customer_number]]]])]); + + Helper::renderVue($this,"AddressTickets", + "Tickets von Kunden: " . $address->getCompanyOrName() . '(' . $address->customer_number . ')', ["TICKETS" => $tickets]); + } } diff --git a/application/AddressDB/AddressDBController.php b/application/AddressDB/AddressDBController.php index abb0e9048..409dccfcf 100644 --- a/application/AddressDB/AddressDBController.php +++ b/application/AddressDB/AddressDBController.php @@ -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; } diff --git a/application/Api/v1/AddressdbApicontroller.php b/application/Api/v1/AddressdbApicontroller.php index 41bfb98e8..dbdfccecc 100644 --- a/application/Api/v1/AddressdbApicontroller.php +++ b/application/Api/v1/AddressdbApicontroller.php @@ -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']; diff --git a/application/Building/Building.php b/application/Building/Building.php index ea0e41dd3..abf734f3a 100644 --- a/application/Building/Building.php +++ b/application/Building/Building.php @@ -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); diff --git a/application/ConstructionConsent/ConstructionConsentController.php b/application/ConstructionConsent/ConstructionConsentController.php index fd39c11e7..7ed55d299 100644 --- a/application/ConstructionConsent/ConstructionConsentController.php +++ b/application/ConstructionConsent/ConstructionConsentController.php @@ -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 { diff --git a/application/ConstructionConsentContact/ConstructionConsentContactController.php b/application/ConstructionConsentContact/ConstructionConsentContactController.php index 84d215b9d..afaf61e7d 100644 --- a/application/ConstructionConsentContact/ConstructionConsentContactController.php +++ b/application/ConstructionConsentContact/ConstructionConsentContactController.php @@ -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() diff --git a/application/ConstructionConsentJournal/ConstructionConsentJournalController.php b/application/ConstructionConsentJournal/ConstructionConsentJournalController.php index f7203f25f..98cab83af 100644 --- a/application/ConstructionConsentJournal/ConstructionConsentJournalController.php +++ b/application/ConstructionConsentJournal/ConstructionConsentJournalController.php @@ -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() { diff --git a/application/ConstructionConsentOwner/ConstructionConsentOwnerController.php b/application/ConstructionConsentOwner/ConstructionConsentOwnerController.php index 08c08f7fb..c9c1eb425 100644 --- a/application/ConstructionConsentOwner/ConstructionConsentOwnerController.php +++ b/application/ConstructionConsentOwner/ConstructionConsentOwnerController.php @@ -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() { diff --git a/application/ConstructionConsentProject/ConstructionConsentProject.php b/application/ConstructionConsentProject/ConstructionConsentProject.php index d80a96606..00d4ac2ed 100644 --- a/application/ConstructionConsentProject/ConstructionConsentProject.php +++ b/application/ConstructionConsentProject/ConstructionConsentProject.php @@ -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; diff --git a/application/ConstructionConsentProject/ConstructionConsentProjectController.php b/application/ConstructionConsentProject/ConstructionConsentProjectController.php index 47bdd40a2..fa6b13769 100644 --- a/application/ConstructionConsentProject/ConstructionConsentProjectController.php +++ b/application/ConstructionConsentProject/ConstructionConsentProjectController.php @@ -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"); - - } diff --git a/application/Device/DeviceController.php b/application/Device/DeviceController.php index b55d259a0..ac050b9b0 100644 --- a/application/Device/DeviceController.php +++ b/application/Device/DeviceController.php @@ -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) { diff --git a/application/Preorder/Preorder.php b/application/Preorder/Preorder.php index 2454c2426..ff7480d07 100644 --- a/application/Preorder/Preorder.php +++ b/application/Preorder/Preorder.php @@ -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) { diff --git a/application/Preorder/PreorderController.php b/application/Preorder/PreorderController.php index f354215ec..e2588193e 100644 --- a/application/Preorder/PreorderController.php +++ b/application/Preorder/PreorderController.php @@ -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; } diff --git a/application/Preordercampaign/PreordercampaignController.php b/application/Preordercampaign/PreordercampaignController.php index 4c606bbcd..fbc8494f0 100644 --- a/application/Preordercampaign/PreordercampaignController.php +++ b/application/Preordercampaign/PreordercampaignController.php @@ -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; diff --git a/application/Termination/Termination.php b/application/Termination/Termination.php index 8f19c38e6..112a0b3df 100644 --- a/application/Termination/Termination.php +++ b/application/Termination/Termination.php @@ -183,7 +183,6 @@ class Termination extends mfBaseModel { } $bcode = $this->getProperty("building")->code; - var_dump($bcode); if(!$bcode) { return false; } diff --git a/application/WarehouseArticle/WarehouseArticleController.php b/application/WarehouseArticle/WarehouseArticleController.php index 77c80a59e..93eae95cc 100644 --- a/application/WarehouseArticle/WarehouseArticleController.php +++ b/application/WarehouseArticle/WarehouseArticleController.php @@ -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'], diff --git a/application/WarehouseEShopOrder/WarehouseEShopOrderController.php b/application/WarehouseEShopOrder/WarehouseEShopOrderController.php index 18d5bf81c..85af3dd82 100644 --- a/application/WarehouseEShopOrder/WarehouseEShopOrderController.php +++ b/application/WarehouseEShopOrder/WarehouseEShopOrderController.php @@ -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'], diff --git a/application/WarehouseOffer/WarehouseOffer.php b/application/WarehouseOffer/WarehouseOffer.php new file mode 100644 index 000000000..7aff40082 --- /dev/null +++ b/application/WarehouseOffer/WarehouseOffer.php @@ -0,0 +1,9 @@ + '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)); + } +} diff --git a/application/WarehouseOffer/WarehouseOfferModel.php b/application/WarehouseOffer/WarehouseOfferModel.php new file mode 100644 index 000000000..c49405483 --- /dev/null +++ b/application/WarehouseOffer/WarehouseOfferModel.php @@ -0,0 +1,52 @@ + '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 }}","Ihre Referenz: ". $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 }}", "Referenz: ". $order["orderNumber"] . "", $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)); - } + } \ No newline at end of file diff --git a/application/WarehouseOrder/WarehouseOrderModel.php b/application/WarehouseOrder/WarehouseOrderModel.php index 84070625f..ac4677800 100644 --- a/application/WarehouseOrder/WarehouseOrderModel.php +++ b/application/WarehouseOrder/WarehouseOrderModel.php @@ -1,5 +1,5 @@ '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; + } +} \ No newline at end of file diff --git a/application/WarehouseProject/WarehouseProjectModel.php b/application/WarehouseProject/WarehouseProjectModel.php new file mode 100644 index 000000000..a1aa8f680 --- /dev/null +++ b/application/WarehouseProject/WarehouseProjectModel.php @@ -0,0 +1,15 @@ +$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; diff --git a/db/migrations/20250204190000_warehouse_modify_12.php b/db/migrations/20250204190000_warehouse_modify_12.php new file mode 100644 index 000000000..028289ce1 --- /dev/null +++ b/db/migrations/20250204190000_warehouse_modify_12.php @@ -0,0 +1,21 @@ +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();; + } + } +} diff --git a/db/migrations/20250205150003_create_construction_consent_project_address.php b/db/migrations/20250205150003_create_construction_consent_project_address.php new file mode 100644 index 000000000..836f5361f --- /dev/null +++ b/db/migrations/20250205150003_create_construction_consent_project_address.php @@ -0,0 +1,36 @@ +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") { + + } + } +} diff --git a/lib/Helper/Helper.php b/lib/Helper/Helper.php index 3668e1b8d..aa31b8c6e 100644 --- a/lib/Helper/Helper.php +++ b/lib/Helper/Helper.php @@ -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] === "%") { diff --git a/lib/SNOPP/SNOPP.php b/lib/SNOPP/SNOPP.php new file mode 100644 index 000000000..d995ea3e5 --- /dev/null +++ b/lib/SNOPP/SNOPP.php @@ -0,0 +1,36 @@ + [ + '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; + } + +} +?> diff --git a/lib/TTCrud/TTCrud.php b/lib/TTCrud/TTCrud.php index 8288b6123..daca7bbcc 100644 --- a/lib/TTCrud/TTCrud.php +++ b/lib/TTCrud/TTCrud.php @@ -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); } } diff --git a/lib/TTCrudBaseModel/TTCrudBaseModel.php b/lib/TTCrudBaseModel/TTCrudBaseModel.php index 3184ffa10..4815dde9f 100644 --- a/lib/TTCrudBaseModel/TTCrudBaseModel.php +++ b/lib/TTCrudBaseModel/TTCrudBaseModel.php @@ -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"); } diff --git a/lib/XinonProject/XinonProject.php b/lib/XinonProject/XinonProject.php index 9fdd63394..f32895350 100644 --- a/lib/XinonProject/XinonProject.php +++ b/lib/XinonProject/XinonProject.php @@ -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), diff --git a/public/js/pages/AddressTickets/AddressTickets.js b/public/js/pages/AddressTickets/AddressTickets.js new file mode 100644 index 000000000..8103c0a9d --- /dev/null +++ b/public/js/pages/AddressTickets/AddressTickets.js @@ -0,0 +1,55 @@ +Vue.component('AddressTickets', { + template: ` + +
    + + + + + + + + + + + + + + + + + + + +
    KundennummerErstellt amBetreffLetztes UpdateAktion
    {{ ticket.customField7 }}{{ formatDate(ticket.createdAt) }}{{ ticket.subject }}{{ formatDate(ticket.updatedAt) }} + + + Ticket anzeigen + +
    +
    +
    + `, + 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'); + } + } +}); diff --git a/public/js/pages/Radius/Radius.css b/public/js/pages/Radius/Radius.css index 66f1a5ee1..ac8f00c41 100644 --- a/public/js/pages/Radius/Radius.css +++ b/public/js/pages/Radius/Radius.css @@ -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; diff --git a/public/js/pages/Radius/Radius.js b/public/js/pages/Radius/Radius.js index 182f7a37b..bb57045ca 100644 --- a/public/js/pages/Radius/Radius.js +++ b/public/js/pages/Radius/Radius.js @@ -273,6 +273,45 @@ Vue.component('radius-ont-parser', { } }); +Vue.component('radius-online-state', { + props: ['username'], + template: ` +
    + + +
    + `, + 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', { +
    @@ -301,6 +341,7 @@ Vue.component('radius', { Kundennummer Username Info + Status Aktionen @@ -317,6 +358,11 @@ Vue.component('radius', { {{ user.info }} + + + @@ -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'); } diff --git a/public/js/pages/WarehouseOffer/WarehouseOffer.css b/public/js/pages/WarehouseOffer/WarehouseOffer.css new file mode 100644 index 000000000..7951745f0 --- /dev/null +++ b/public/js/pages/WarehouseOffer/WarehouseOffer.css @@ -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; + } +} \ No newline at end of file diff --git a/public/js/pages/WarehouseOffer/WarehouseOffer.js b/public/js/pages/WarehouseOffer/WarehouseOffer.js new file mode 100644 index 000000000..fe1365051 --- /dev/null +++ b/public/js/pages/WarehouseOffer/WarehouseOffer.js @@ -0,0 +1,178 @@ +Vue.component('warehouse-offer-modal', { + props: { + id: {type: [String, Number], required: true}, + mode: {type: String, default: 'edit'} + }, + template: ` + +

    Angebotdetails

    + + + + +
    +

    Kundenadresse

    +
    + + + + + +
    +
    +

    Positionen

    + +
    +

    Alternative Artikel

    + +
    + + + + +
    + +
    +
    + `, + 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('
    ') : 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: ` + + + + + + + + `, + data() { + return { + window: window, + offerModalId: null, + } + }, +}); diff --git a/public/js/pages/WarehouseOrder/WarehouseOrder.css b/public/js/pages/WarehouseOrder/WarehouseOrder.css index 878a34a77..9b3746d82 100644 --- a/public/js/pages/WarehouseOrder/WarehouseOrder.css +++ b/public/js/pages/WarehouseOrder/WarehouseOrder.css @@ -24,4 +24,29 @@ grid-template-columns: 1fr 1fr !important; grid-gap: 10px; } -} \ No newline at end of file +} + + +/* 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; +} + diff --git a/public/js/pages/WarehouseOrder/WarehouseOrder.js b/public/js/pages/WarehouseOrder/WarehouseOrder.js index fcd97373a..c9b937d86 100644 --- a/public/js/pages/WarehouseOrder/WarehouseOrder.js +++ b/public/js/pages/WarehouseOrder/WarehouseOrder.js @@ -16,6 +16,7 @@ Vue.component('warehouse-order-modal', { sm row v-model="order.editor"/> +

    Positionen

    @@ -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('
    ') : 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('
    ') : 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: ` - - - - - - - `, data() { - return { - window: window, - orderModalId: null, + + + + + + + `, + props: { + id: {type: [String, Number], required: true} + }, + data() { + return { + window: window, + order: {}, + loading: true } }, -}) \ No newline at end of file + 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: ` + + + + + + + + + + + + `, + 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); + } + } +}); diff --git a/public/js/pages/WarehouseProject/WarehouseProject.css b/public/js/pages/WarehouseProject/WarehouseProject.css new file mode 100644 index 000000000..7951745f0 --- /dev/null +++ b/public/js/pages/WarehouseProject/WarehouseProject.css @@ -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; + } +} \ No newline at end of file diff --git a/public/js/pages/WarehouseProject/WarehouseProject.js b/public/js/pages/WarehouseProject/WarehouseProject.js new file mode 100644 index 000000000..3bfeb5578 --- /dev/null +++ b/public/js/pages/WarehouseProject/WarehouseProject.js @@ -0,0 +1,161 @@ +Vue.component('warehouse-project-modal', { + props: { + id: { type: [String, Number], required: true }, + mode: { type: String, default: 'edit' } + }, + template: ` + +
    +

    Projektübersicht

    + + + +
    +

    Zeitraum

    +
    + + +
    + +
    +

    Beteiligte Personen

    + + + +
    +

    Projektübersicht

    + + + +
    +

    Lagerort

    + + +
    + +
    +
    + `, + 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('
    ') : 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: ` + + + + + + + + `, + data() { + return { + window: window, + projectModalId: null, + } + }, +}); diff --git a/public/plugins/vue/tt-components/tt-position-manager.js b/public/plugins/vue/tt-components/tt-position-manager.js index 182f5b04e..7d8996bbd 100644 --- a/public/plugins/vue/tt-components/tt-position-manager.js +++ b/public/plugins/vue/tt-components/tt-position-manager.js @@ -33,6 +33,13 @@ Vue.component('tt-positions-manager', { :api-url="window.TT_CONFIG['BASE_PATH'] + field.apiUrl" sm /> + + {{ window.moment(row[key] * 1000).format('DD.MM.YYYY HH:mm:ss') }} diff --git a/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php b/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php index f08c8d242..dfaa0fec4 100644 --- a/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php +++ b/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php @@ -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)) { diff --git a/scripts/adb-rimo-import/adb-rimo-import-broker.php b/scripts/adb-rimo-import/adb-rimo-import-broker.php new file mode 100644 index 000000000..c66e3296a --- /dev/null +++ b/scripts/adb-rimo-import/adb-rimo-import-broker.php @@ -0,0 +1,353 @@ +#!/usr/bin/php +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; +} \ No newline at end of file diff --git a/scripts/adb-rimo-import/rimo-import.php b/scripts/adb-rimo-import/rimo-import.php index 59d850d8e..9705d9c16 100755 --- a/scripts/adb-rimo-import/rimo-import.php +++ b/scripts/adb-rimo-import/rimo-import.php @@ -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); } diff --git a/scripts/construction/colors b/scripts/construction/colors new file mode 100644 index 000000000..a167d1522 --- /dev/null +++ b/scripts/construction/colors @@ -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", diff --git a/scripts/construction/import-lesky.php b/scripts/construction/import-lesky.php index 7903007ab..32054a40a 100644 --- a/scripts/construction/import-lesky.php +++ b/scripts/construction/import-lesky.php @@ -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"); + } + } + +} -} \ No newline at end of file diff --git a/scripts/construction/source/Export Ly 04022025.csv b/scripts/construction/source/Export Ly 04022025.csv new file mode 100644 index 000000000..9590d588a --- /dev/null +++ b/scripts/construction/source/Export Ly 04022025.csv @@ -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