needlogin = true;
$me = new User();
$me->loadMe();
$this->me = $me;
$this->layout()->set("me", $me);
$isApiWhitelist = (isset($_GET['do']) && $_GET['do'] === 'getFCPsForCampaign' && $this->action === 'Api');
if (!$me->is(["Admin", "netowner", "salespartner", "preorderfront"]) && !$me->can("Preorder")) {
if (!$isApiWhitelist) {
$this->redirect("Dashboard");
}
}
}
protected function indexAction() {
$this->layout()->setTemplate("Preorder/Index");
if($this->request->resetFilter) {
unset($_SESSION[MFAPPNAME . '-Preorder-filter']);
foreach($_SESSION as $key => $s) {
if(preg_match('/^' . MFAPPNAME . '-Preorder-filter-campaign-\d+$/', $key)) {
unset($_SESSION[$key]);
}
}
}
$filter = [];
if(is_array($this->request->filter)) {
$filter = $this->request->filter;
if(isset($this->request->filter["preordercampaign_id"]) && $this->request->filter["preordercampaign_id"]) {
$filter_po_id = $filter["preordercampaign_id"];
if(count($this->request->filter) == 1 && isset($_SESSION[MFAPPNAME . '-Preorder-filter-campaign-' . $filter_po_id])) {
$filter = $_SESSION[MFAPPNAME . '-Preorder-filter-campaign-' . $filter_po_id];
} else {
$_SESSION[MFAPPNAME . '-Preorder-filter-campaign-' . $filter["preordercampaign_id"]] = $filter;
}
} else {
$_SESSION[MFAPPNAME . '-Preorder-filter'] = $filter;
}
} else {
if(array_key_exists(MFAPPNAME . '-Preorder-filter', $_SESSION) && count($_SESSION[MFAPPNAME . '-Preorder-filter'])) {
$filter = $_SESSION[MFAPPNAME . '-Preorder-filter'];
if(isset($filter['preordercampaign_id'])) {
$filter_po_id = $filter['preordercampaign_id'];
if(isset($_SESSION[MFAPPNAME . '-Preorder-filter-campaign-' . $filter_po_id])) {
//var_dump("blah");
$filter = $_SESSION[MFAPPNAME . '-Preorder-filter-campaign-' . $filter_po_id];
}
}
}
}
//var_dump($_SESSION, $filter);exit;
$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);
}
$my_networks = [];
$my_campaigns = [];
$my_campaign_ids = [];
$this->layout()->set("campaign", new Preordercampaign());
if($this->me->is("Admin")) {
if($filter['preordercampaign_id']) {
$this->layout()->set("campaign", new Preordercampaign($filter['preordercampaign_id']));
} else {
$my_campaigns = PreordercampaignModel::getAll();
}
$this->layout()->set("my_campaigns", PreordercampaignModel::getAll());
} else {
if($this->me->is("preorderfront")) {
$pns = json_decode($this->me->getFlag("preorder_networks"));
if(is_array($pns) && count($pns)) {
foreach($pns as $pn_id) {
$my_networks[] = new Network($pn_id);
}
} else {
$my_networks = $this->me->myNetworks(['netowner', 'salespartner']);
}
//var_dump($my_networks);exit;
} else {
$my_networks = $this->me->myNetworks(["netowner", "salespartner"]);
}
// check users allowed networks
$user_network_ids = $this->me->getFlag("preorder_networks")->value();
if($user_network_ids) {
$user_network_ids = json_decode($user_network_ids);
}
if(is_array($user_network_ids) && count($user_network_ids)) {
if(!$my_networks) {
foreach($user_network_ids as $mnid) {
$my_networks[] = new Network($mnid);
}
} else {
//var_dump($user_network_ids, $my_networks);exit;
$new_my_networks = [];
foreach($my_networks as $network) {
if(in_array($network->id, $user_network_ids)) {
$new_my_networks[$network->id] = $network;
}
}
$my_networks = $new_my_networks;
}
}
foreach($my_networks as $network) {
foreach(PreordercampaignModel::search(['network_id' => $network->id]) as $campaign) {
$my_campaigns[] = $campaign;
if(!in_array($campaign->id, $my_campaign_ids)) $my_campaign_ids[] = $campaign->id;
}
}
//var_dump($my_network_ids,$my_campaign_ids);exit;
$this->layout()->set("my_campaigns", $my_campaigns);
if($filter['preordercampaign_id'] && in_array($filter['preordercampaign_id'], $my_campaign_ids)) {
$campaign_id = $filter['preordercampaign_id'];
if(is_numeric($campaign_id) && $campaign_id > 0) {
$campaign = new Preordercampaign($campaign_id);
$this->layout()->set("campaign", $campaign);
if($campaign->network->owner_id != $this->me->address_id && NetworkAddressModel::getFirst(["network_id" => $campaign->network_id, "address_id" => $this->me->address_id, "addresstype" => "salespartner"])) {
$filter["operator_id"] = $this->me->address_id;
}
}
} else {
$filter['preordercampaign_id'] = $my_campaign_ids;
if(NetworkAddressModel::getFirst(["address_id" => $this->me->address_id, "addresstype" => "salespartner"])) {
$filter["operator_id"] = $this->me->address_id;
}
}
if(!$filter['preordercampaign_id']) $filter['preordercampaign_id'] = 0;
}
//var_dump($filter["preordercampaign_id"], $filter);exit;
if($filter['addon_services']) {
$pagination['maxItems'] = PreorderModel::countOrderedAddonservices($filter);
$preorders = PreorderModel::searchOrderedAddonservices($filter, $pagination);
} else {
$pagination['maxItems'] = PreorderModel::countActive($filter);
$preorders = PreorderModel::searchActive($filter, $pagination);
}
$this->layout()->set("pagination", $pagination);
$this->layout()->set("preorders", $preorders);
$this->layout()->set("partners", PreorderModel::getAllPartners());
}
private function getPreparedFilter($filter) {
$new_filter = [];
/*if(array_key_exists("show_deleted", $filter)) {
if($filter['show_deleted'] == "show") {
$new_filter['deleted'] = null;
} elseif($filter['show_deleted'] == "only") {
$new_filter['deleted'] = 1;
} else {
$new_filter['deleted'] = null;
}
} else {
$new_filter['deleted'] = null;
}*/
$new_filter['add-where'] = "";
if(array_key_exists("magic_search", $filter) && trim($filter['magic_search'])) {
$search = trim($filter['magic_search']);
$new_filter['add-where'] .= " AND (";
$new_filter['add-where'] .= " adb_hausnummer.gemeinde like '%$search%' OR adb_hausnummer.plz like '%$search%' OR adb_hausnummer.strasse like '%$search%'
OR adb_hausnummer.hausnummer like '%$search%' OR CONCAT (adb_hausnummer.strasse, ' ', adb_hausnummer.hausnummer) like '%$search%'
OR CONCAT (adb_hausnummer.strasse, ' ', adb_hausnummer.hausnummer) like '%" . str_replace(" ", "%", $search) . "%'";
$new_filter['add-where'] .= " OR company like '%$search%' OR firstname like '%$search%' OR lastname like '%$search%' OR concat(firstname, ' ', lastname) like '%$search%' OR concat(lastname, ' ', firstname) like '%$search%' OR street like '%$search%' OR zip like '%$search%' OR city like '%$search%' OR email like '%$search%' OR phone like '%$search%'";
$new_filter['add-where'] .= " OR tt_preorder.ucode like '%$search%' OR tt_preorder.oaid like '%$search%'";
$new_filter['add-where'] .= " OR adb_wohneinheit.extref like '%$search%'";
$new_filter['add-where'] .= " OR adb_hausnummer.hausnummer_extref like '%$search%'";
$new_filter['add-where'] .= " OR adb_hausnummer.adrcd like '%$search%'";
$new_filter['add-where'] .= " OR adb_hausnummer.grund_nr like '%$search%'";
$new_filter['add-where'] .= " OR adb_hausnummer.rimo_fcp_name like '%$search%'";
$new_filter['add-where'] .= " OR workorder.rimo_status like '%$search%'";
$new_filter['add-where'] .= " OR workorder.rimo_name like '%$search%'";
//$new_filter['add-where'] .= " OR ";
$new_filter['add-where'] .= " )";
}
//echo $new_filter['add-where'];exit;
if(array_key_exists("address", $filter) && $filter["address"]) {
$address = $this->db()->escape($filter['address']);
$new_filter['add-where'] .= " AND (adb_hausnummer.gemeinde like '%$address%' OR adb_hausnummer.plz like '%$address%' OR adb_hausnummer.strasse like '%$address%'
OR adb_hausnummer.hausnummer like '%$address%' OR CONCAT (adb_hausnummer.strasse, ' ', adb_hausnummer.hausnummer) like '%$address%'
OR CONCAT (adb_hausnummer.strasse, ' ', adb_hausnummer.hausnummer) like '%" . str_replace(" ", "%", $address) . "%')";
}
if(array_key_exists("hausnummer", $filter) && $filter["hausnummer"]) {
$hausnummer = $this->db()->escape($filter['hausnummer']);
$new_filter['hausnummer'] = $hausnummer;
}
if(array_key_exists("kunde", $filter) && $filter["kunde"]) {
$kunde = $this->db()->escape($filter['kunde']);
$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%' OR street like '%$kunde%' OR zip like '%$kunde%' OR city like '%$kunde%' OR phone like '%$kunde%' OR email like '%$kunde%')";
}
$new_filter['addon_services'] = false;
if(array_key_exists("addon_services", $filter) && $filter['addon_services'] == 1) {
$new_filter['addon_services'] = true;
}
if(array_key_exists("borderpoint", $filter) && $filter['borderpoint'] === 'with') {
$new_filter['add-where'] .= " AND (adb_hausnummer.borderpoint_lat IS NOT NULL AND adb_hausnummer.borderpoint_long IS NOT NULL)";
} elseif(array_key_exists("borderpoint", $filter) && $filter['borderpoint'] === 'without') {
$new_filter['add-where'] .= " AND (adb_hausnummer.borderpoint_lat IS NULL OR adb_hausnummer.borderpoint_long IS NULL)";
}
if(array_key_exists("address_source", $filter)) {
if($filter['address_source'] == "manual") {
$new_filter['address_created'] = true;
}
if($filter['address_source'] == "addressdb") {
$new_filter['address_created'] = null;
}
}
if(array_key_exists("unit_missing", $filter)) {
if($filter['unit_missing'] == "yes") {
$new_filter['adb_wohneinheit_id'] = null;
} elseif($filter['unit_missing'] == "no") {
$new_filter['adb_wohneinheit_id'] = true;
}
unset($filter['unit_missing']);
}
if(array_key_exists("rimo_home_extref", $filter)) {
if($filter['rimo_home_extref'] == "1") {
$new_filter['add-where'] .= " AND (adb_wohneinheit.id IS NOT NULL AND adb_wohneinheit.extref IS NOT NULL AND adb_wohneinheit.extref like 'SDIHome_%')";
} elseif($filter['rimo_home_extref'] == "0") {
$new_filter['add-where'] .= " AND (adb_wohneinheit.extref IS NULL OR adb_wohneinheit.extref NOT LIKE 'SDIHome_%')";
}
}
if(array_key_exists("rimo_workorder", $filter)) {
if($filter["rimo_workorder"] == "1") {
$new_filter['rimo_workorder'] = true;
} elseif($filter["rimo_workorder"] == "0") {
$new_filter['rimo_workorder'] = false;
}
unset($filter['rimo_workorder']);
}
if(array_key_exists("rimo_workorder_status", $filter) && $filter['rimo_workorder_status']) {
$new_filter["rimo_workorder_status"] = $filter['rimo_workorder_status'];
}
if(array_key_exists("rimo_workorder_name", $filter) && $filter['rimo_workorder_name']) {
$new_filter["rimo_workorder_name"] = $filter['rimo_workorder_name'];
}
if(array_key_exists("ucode", $filter) && $filter['ucode']) {
$new_filter['ucode'] = "%" . $filter['ucode'] . "%";
unset($filter['ucode']);
}
if(array_key_exists("oaid", $filter) && $filter['oaid']) {
$new_filter['oaid'] = "%" . $filter['oaid'] . "%";
unset($filter['oaid']);
}
if(array_key_exists("status", $filter) && is_array($filter['status']) && count($filter['status'])) {
$new_filter['status_id'] = [];
foreach($filter["status"] as $s) {
if(is_numeric($s) && $s > 0) {
$new_filter['status_id'][] = $s;
}
}
}
if(is_array($filter) && count($filter)) {
foreach($filter as $name => $value) {
$new_filter[$name] = $value;
}
}
//var_dump($new_filter);exit;
return $new_filter;
}
protected function addAction() {
$this->layout()->setTemplate("Preorder/Form");
if($this->me->isAdmin()) {
$this->layout()->set("networks", NetworkModel::getAll());
} else {
$this->layout()->set("networks", $this->me->my_networks);
}
if(!$this->request->preordercampaign_id) {
$this->layout()->setFlash("Keine Kampagne ausgewählt!", "warn");
}
$campaign_id = $this->request->preordercampaign_id;
$campaign = new Preordercampaign($campaign_id);
$this->layout()->set("campaign", $campaign);
$products = [];
foreach(ProductNetworkModel::search(["network_id" => $campaign->network_id]) as $pn) {
if(!$pn->product->active) continue;
if(!array_key_exists($pn->product_id, $products)) {
if(is_array($pn->product->attributes) && !array_key_exists("presales", $pn->product->attributes)) {
$products[$pn->product_id] = $pn->product;
}
}
}
//var_dump($products);exit;
$this->layout()->set("products", $products);
$partners = AddressModel::search(['addresstype' => ['netowner', 'salespartner']]);
$this->layout()->set("partners", $partners);
}
protected function editAction() {
$id = $this->request->id;
if(!is_numeric($id) || $id < 1) {
$this->layout()->setFlash("Vorbestellung nicht gefunden", "error");
$this->redirect("Preordercampaign");
}
$preorder = new Preorder($id);
if(!$preorder->id) {
$this->layout()->setFlash("Vorbestellung nicht gefunden", "error");
$this->redirect("Preordercampaign");
}
$this->request->set("preordercampaign_id", $preorder->preordercampaign_id); // needed in addAction()
$this->layout()->set("preorder", $preorder);
//var_dump($preorder->building->street);exit;
return $this->addAction();
}
protected function saveAction() {
$r = $this->request;
//var_dump($r);exit;
/*
* add or edit
*/
$id = $r->id;
if(is_numeric($id) && $id > 0) {
$mode = "edit";
$preorder = new Preorder($id);
if(!$preorder->id) {
$this->layout()->setFlash("Vorbestellung nicht gefunden", "error");
$this->redirect("Preordercampaign");
}
} else {
$id = false;
$mode = "add";
}
$data = [];
if($mode == "add" || !$preorder->adb_wohneinheit_id || !is_array($preorder->adb_wohneinheit->rimo_workorders) || !count($preorder->adb_wohneinheit->rimo_workorders)) {
$data['preordercampaign_id'] = $r->campaign_id;
$data['building_id'] = ($r->building_id) ? $r->building_id : null;
$data['adb_hausnummer_id'] = $r->adb_hausnummer_id;
$data['adb_wohneinheit_id'] = ($r->adb_wohneinheit_id) ? $r->adb_wohneinheit_id : null;
$data['termination_id'] = ($r->termination_id) ? $r->termination_id : null;
}
$campaign = new Preordercampaign($r->campaign_id);
if(!$campaign->id) {
$this->layout()->setFlash("Keine Kampagne ausgewählt!", "error");
$this->redirect("Preordercampaign");
}
if($mode == "add") {
$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;
}
if(!$r->product_id) {
$data['product_id'] = null;
}
if($campaign->product_type != "no_setup") {
$data['setup_product_id'] = $r->setup_product_id;
}
if(!$r->setup_product_id) {
$data['setup_product_id'] = null;
}
switch($r->type) {
case "interest":
$data['type'] = "interest";
break;
case "provision":
$data['type'] = "provision";
break;
case "order":
$data['type'] = "order";
break;
case "reorder":
$data["type"] = "reorder";
break;
case "legacytransfer":
$data["type"] = "legacytransfer";
break;
}
switch($r->connection_type) {
case "single-dwelling":
$data['connection_type'] = "single-dwelling";
break;
case "multi-dwelling":
$data['connection_type'] = "multi-dwelling";
break;
case "apartment-building":
$data['connection_type'] = "apartment-building";
break;
case "apartment":
$data['connection_type'] = "apartment";
break;
case "business":
$data['connection_type'] = "business";
break;
}
$data['connection_count'] = (intval($r->connection_count)) ? intval($r->connection_count) : 1;
$data['accept_agb'] = 1;
$data['accept_dsgvo'] = 1;
$data['accept_withdrawal'] = 1;
$data['accept_marketing'] = 0;
if($r->accept_marketing == 1) {
$data['accept_marketing'] = 1;
}
$data['accept_digging'] = 0;
if($r->accept_digging == 1) {
$data['accept_digging'] = 1;
}
$data['price'] = ($r->price) ? Layout::commaToDot($r->price) : 0;
$data['price_setup'] = ($r->price_setup) ? Layout::commaToDot($r->price_setup) : 0;
$data['price_nne'] = ($r->price_nne) ? Layout::commaToDot($r->price_nne) : 0;
$data['price_nbe'] = ($r->price_nbe) ? Layout::commaToDot($r->price_nbe) : 0;
$data['billing_delay'] = ($r->billing_delay) ? $r->billing_delay : 0;
//var_dump($r->partner_id);exit;
if($r->partner_id) {
$data['partner_id'] = $r->partner_id;
} else {
$data['partner_id'] = null;
}
$data['company'] = (trim($r->company)) ? trim($r->company) : null;
$data['uid'] = (trim($r->uid)) ? trim($r->uid) : null;
$data['firstname'] = trim($r->firstname);
$data['lastname'] = trim($r->lastname);
$data['street'] = (trim($r->street)) ? trim($r->street) : null;
$data['housenumber'] = (trim($r->housenumber)) ? trim($r->housenumber) : null;
$data['block'] = (trim($r->block)) ? trim($r->block) : null;
$data['stiege'] = (trim($r->stiege)) ? trim($r->stiege) : null;
$data['stock'] = (trim($r->stock)) ? trim($r->stock) : null;
$data['tuer'] = (trim($r->tuer)) ? trim($r->tuer) : null;
$data['zip'] = (trim($r->zip)) ? trim($r->zip) : null;
$data['city'] = (trim($r->city)) ? trim($r->city) : null;
$data['phone'] = (trim($r->phone)) ? trim($r->phone) : null;
$data['email'] = (trim($r->email)) ? trim($r->email) : null;
$data['note'] = (trim($r->note)) ? trim($r->note) : null;
$data['edit_by'] = $this->me->id;
if($mode == "add") {
$data['create_by'] = $this->me->id;
$preorder = PreorderModel::create($data);
} else {
// if new wohneinheit -> remove oaid from Preorder
if($r->adb_wohneinheit_id && $preorder->adb_wohneinheit_id != $r->adb_wohneinheit_id) {
$preorder->oaid = null;
}
if(!$r->adb_wohneinheit_id && $preorder->oaid) {
$preorder->oaid = null;
}
$preorder->update($data);
}
//var_dump($preorder, $r);exit;
// handle new address creation
if(!$preorder->adb_hausnummer_id) {
// check if new address was submitted
$this->log->debug("check if new address was submitted");
if($r->new_address_street && $r->new_address_housenumber && $r->new_address_zip && $r->new_address_city && $r->new_address_district) {
$city_search = trim($r->new_address_city);
$district_search = trim($r->new_address_district);
$zip_search = trim($r->new_address_zip);
$street_search = trim($r->new_address_street);
$housenumber_search = trim($r->new_address_housenumber);
$block = trim($r->new_address_block);
$stiege = trim($r->new_address_stiege);
$stock = trim($r->new_address_stock);
$tuer = trim($r->new_address_tuer);
$preorder->new_address_city = $city_search;
$preorder->new_address_district = $district_search;
$preorder->new_address_zip = $zip_search;
$preorder->new_address_street = $street_search;
$preorder->new_address_housenumber = $housenumber_search;
$netzgebiet_ids = [];
foreach($campaign->salesclusters as $scluster) {
$netzgebiet_ids[] = $scluster->id;
}
$netzgebiet_id = $netzgebiet_ids[0];
if(!$netzgebiet_id) {
$this->layout()->setFlash("Kann Adresse nicht updaten: Kampagne hat kein Netzgebiet", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
$netzgebiet = new ADBNetzgebiet($netzgebiet_id);
if(!$netzgebiet->id) {
$this->layout()->setFlash("Neztgebiet nicht gefunden", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
$city = ADBGemeindeModel::getFirst(['name' => $city_search, 'netzgebiet_id' => $netzgebiet_id]);
if(!$city) {
$this->layout()->setFlash("Gemeinde nicht Adress-DB gefunden", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
$district = ADBOrtschaftModel::getFirst(['name' => $district_search, 'netzgebiet_id' => $netzgebiet_id]);
if(!$district) {
$this->layout()->setFlash("Ortsteil nicht Adress-DB gefunden", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
$zip = ADBPlzModel::getFirst(['plz' => $zip_search, 'gemeinde_id' => $city->id]);
if(!$zip) {
$this->layout()->setFlash("PLZ nicht Adress-DB gefunden", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
$street = ADBStrasseModel::getFirst(['name' => $street_search, 'gemeinde_id' => $city->id]);
if(!$street) {
$this->log->debug("create street");
$street = ADBStrasseModel::create([
'ortschaft_id' => $district->id,
'gemeinde_id' => $city->id,
'name' => $street_search
]);
if(!$street->save()) {
$this->layout()->setFlash("Fehler beim Speichern der neuen Straße", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
}
$this->log->debug("search hausnummer");
$hausnummer = ADBHausnummerModel::getFirst(['netzgebiet_id' => $netzgebiet_ids, 'ortschaft_id' => $district_search, 'gemeinde_id' => $city->id, 'plz_id' => $zip->id, 'strasse_id' => $street->id, 'hausnummer' => $housenumber_search]);
if($hausnummer) {
// hausnummer gibts scho!
$this->layout()->setFlash("Adresse war schon vorhanden!", "warn");
$preorder->adb_hausnummer_id = $hausnummer->id;
} else {
// try with empty netzgebiet
$this->log->debug("search hausnummer mit empty netzgebiet");
$hausnummer = ADBHausnummerModel::getFirst(['netzgebiet_id' => null, 'ortschaft_id' => $district_search, 'gemeinde_id' => $city->id, 'plz_id' => $zip->id, 'strasse_id' => $street->id, 'hausnummer' => $housenumber_search]);
if($hausnummer) {
// Hausnummer ohne Netzgebiet gefunden -> update netzgebiet_id
$this->log->debug("hausnummer id: updated netzgebiet from NULL to " . $netzgebiet_ids);
$hausnummer->netzgebiet_id = $netzgebiet_id;
$hausnummer->save();
$preorder->adb_hausnummer_id = $hausnummer->id;
} else {
// try with any netzgebiet
$this->log->debug("search hausnummer with ohne netzgebiet");
$hausnummer = ADBHausnummerModel::getFirst(['ortschaft_id' => $district_search, 'gemeinde_id' => $city->id, 'plz_id' => $zip->id, 'strasse_id' => $street->id, 'hausnummer' => $housenumber_search]);
if($hausnummer) {
$this->log->debug("Hausnummer " . $hausnummer->id . " in Netzgebiet (" . implode(",", $netzgebiet_ids) . " gesucht, aber in " . $hausnummer->netzgebiet_id) . " gefunden";
$this->layout()->setFlash("Neue Adresse ist bereits im Netzgebiet " . $hausnummer->netzgebiet->name . " vorhanden", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
} else {
// hausnummer anlegen
$hausnummer = ADBHausnummerModel::create([
'netzgebiet_id' => $netzgebiet_id,
'ortschaft_id' => $district->id,
'plz_id' => $zip->id,
'strasse_id' => $street->id,
'hausnummer' => $housenumber_search,
'freigabe' => $netzgebiet->freigabe,
'manual_add' => date('U'),
'manual_add_by' => $this->me->id,
'manual_add_info' => "thetool user " . $this->me->username . " via Preorder create"
]);
if(!$hausnummer->save()) {
$this->layout()->setFlash("Fehler beim Speichern der neuen Adresse", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
$preorder->adb_hausnummer_id = $hausnummer->id;
$preorder->address_created = date('U');
$preorder->address_created_by = $this->me->id;
$preorder->adb_wohneinheit_id = null;
// create wohneinheit
$wohneinheit = ADBWohneinheitModel::create([
'hausnummer_id' => $hausnummer->id,
'num' => 1,
'block' => ($block) ? $block : null,
'stiege' => ($stiege) ? $stiege : null,
'stock' => ($stock) ? $stock : null,
'tuer' => ($tuer) ? $tuer : null
]);
if($wohneinheit->save()) {
$preorder->adb_wohneinheit_id = $wohneinheit->id;
} else {
$this->layout()->setFlash("Konnte Wohneinheit nicht speichern", "warn");
}
}
}
}
}
} else {
// if $preorder->adb_wohneinheit_id
//if($preorder->_old)
}
/*
* validation
*/
if(!array_key_exists($data['type'], $campaign->types)) {
$this->layout()->setFlash("Bitte Vorbestelltyp auswählen!", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
if($data['product_id']) {
$product = new Product($data['product_id']);
if(!$product->id) {
$this->layout()->setFlash("Bitte Produkt auswählen!", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
$preorder->billing_period = $product->billing_period;
if(!$this->me->isAdmin()) {
$preorder->price_nne = $product->price_nne;
$preorder->price_nbe = $product->price_nbe;
}
if(!strlen($preorder->price)
|| !strlen($preorder->price_setup)
|| !strlen($preorder->price_nne)
|| !strlen($preorder->price_nbe)
|| !strlen($preorder->price_nne)) {
$this->layout()->setFlash("Bitte alle benötigten Produktdaten ausfüllen!", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
if(!strlen($preorder->firstname)
|| !strlen($preorder->lastname)
|| !strlen($preorder->street)
|| !strlen($preorder->zip)
|| !strlen($preorder->city)) {
$this->layout()->setFlash("Bitte alle benötigten Kundendaten ausfüllen!", "error");
$this->layout()->set("preorder", $preorder);
$this->layout()->set("campaign", $campaign);
return $this->addAction();
}
} else {
$preorder->billing_period = 0;
}
//var_dump($preorder);exit;
// unset temporary properties
unset($preorder->new_address_city);
unset($preorder->new_address_district);
unset($preorder->new_address_zip);
unset($preorder->new_address_street);
unset($preorder->new_address_housenumber);
/*
* generate ucode and save
*/
if(!$preorder->ucode) {
$preorder->createUcode();
}
$new_id = $preorder->save();
if(!$new_id) {
$this->layout()->setFlash("Fehler beim Speichern", "error");
$this->layout()->set("preorder", $preorder);
return $this->addAction();
}
$qs = ['filter' => ['preordercampaign_id' => $preorder->preordercampaign_id]];
$qs = http_build_query($qs);
$this->layout()->setFlash("Vorbestellung erfolgreich gespeichert!", "success");
$this->redirect("Preorder", "Index", $qs);
}
public function deleteAction() {
$qs = "";
if(is_array($this->request->filter) && count($this->request->filter)) {
$qs = ['filter' => $this->request->filter];
$qs = http_build_query($qs);
}
if(!$this->me->isAdmin()) {
$this->redirect("Preorder", "Index", $qs);
}
$id = $this->request->id;
if(!is_numeric($id) || $id < 1) {
$this->layout()->setFlash("Vorbestellung nicht gefunden!", "error");
$this->redirect("Preorder", "Index", $qs);
}
$preorder = new Preorder($id);
if(!$preorder->id) {
$this->layout()->setFlash("Vorbestellung nicht gefunden!", "error");
$this->redirect("Preorder", "Index", $qs);
}
//$preorder->deleted = date('U');
$preorder->deleted_by = $this->me->id;
$preorder->status_id = 23; // 910 - Cancelled (ohne weitere Begründung)
$preorder->save();
$this->layout()->setFlash("Vorbestellung erfolgreich gelöscht!", "success");
$this->redirect("Preorder", "Index", $qs);
}
protected function statusupdateimport() {
$this->layout()->setTemplate("Preorder/Statusupdateimport");
}
protected function saveStatusupdateimport() {
$headline_included = $this->request->headline;
if(is_array($_FILES) && array_key_exists("statusupdate_csv", $_FILES) && !$_FILES['statusupdate_csv']['error']) {
// look for uploaded import file
try {
// returns File object or throws Exception on error
$file = mfUpload::handleFormUpload("statusupdate_csv");
} catch(Exception $ex) {
$this->layout()->setFlash("Fehler beim Dateiupload: " . $ex->getMessage(), "error");
$this->redirect("Preorder", "statusupdateimport");
}
$i = 0;
$forbidden = 0;
$notfound = 0;
$invalidcode = 0;
$nochange = 0;
$saved = 0;
$flags_saved = 0;
$statusflags = [];
$filename = $file->getFullPath();
$input = fopen($filename, "r");
while($csv = fgetcsv($input, 0, ";")) {
$i++;
if($i == 1 && $headline_included) {
// get statusflag order in header
$col = 2;
while(array_key_exists($col, $csv) && trim($csv[$col])) {
$code = trim($csv[$col]);
if(!is_numeric($code)) {
$this->layout()->setFlash("Ungültige Überschrift für Spalte " . ++$col, "error");
$this->redirect("Preorder", "statusupdateimport");
}
$sflag = PreorderStatusflagModel::getFirst(["code" => $code]);
if(!$sflag) {
$this->layout()->setFlash("Statusflag mit Code $code nicht gefunden", "error");
$this->redirect("Preorder", "statusupdateimport");
}
$sflag->col = $col;
$statusflags[$code] = $sflag;
$col++;
}
continue;
}
if(!trim($csv[0])) {
continue;
}
$oaid = trim($csv[0]);
$new_status_code = trim($csv[1]);
$preorder = PreorderModel::getFirstActive(["oaid" => $oaid]);
if(!$preorder) {
$notfound++;
continue;
}
if($preorder->campaign->network->owner_id != $this->me->address_id) {
$forbidden++;
continue;
}
if($preorder->status->code != $new_status_code) {
$new_status = PreorderstatusModel::getFirst(["code" => $new_status_code]);
if(!$new_status_code) {
$invalidcode++;
continue;
}
$preorder->status_id = $new_status->id;
$preorder->save();
$preorder->resetSaveNesting();
$saved++;
} else {
$nochange++;
}
if(count($statusflags)) {
foreach($statusflags as $code => $origin_sflag) {
$this->log->debug(__METHOD__ . ": $oaid - testing flag $code for update.");
$sflag = clone($origin_sflag);
$sflag->preorder_id = $preorder->id;
if(!$sflag->col) {
$this->layout()->setFlash("Kann Statusflagcode $code nicht zuordnen. Line $i col " . $sflag->col, "error");
$this->redirect("Preorder", "statusupdateimport");
}
if(!array_key_exists($sflag->col, $csv)) {
$this->log->debug(__METHOD__ . ": no col.");
continue;
}
$value = trim($csv[$sflag->col]);
if(!strlen($value)) {
$this->log->debug(__METHOD__ . ": no val");
continue;
}
if($value) {
$sflag->value->value = 1;
} else {
$sflag->value->value = 0;
}
$this->log->debug(__METHOD__ . ": $oaid - saving flag value $code value: " . $sflag->value->value . " ($value)");
$sflag->value->save();
$flags_saved++;
//$this->log->debug(__METHOD__.": $oaid - loading preorder again");
}
$preorder = PreorderModel::getFirstActive(["oaid" => $oaid]);
$preorder->resetSaveNesting();
$preorder->afterSave();
$preorder = PreorderModel::getFirstActive(["oaid" => $oaid]);
$preorder->resetSaveNesting();
}
}
$message = "Import erfolgreich. $saved Statusupdates importiert";
if($flags_saved) {
$message .= "
$flags_saved Statusflags upgedatet";
}
if($notfound) {
$message .= "
$notfound Bestellungen nicht gefunden";
}
if($forbidden) {
$message .= "
$forbidden Bestellungen in falschem Netzgebiet";
}
/*if($nochange) {
$message .= "
$nochange Bestelllungen haben bereits den neuen Status";
}*/
if($invalidcode) {
$message .= "
$invalidcode ungültige Statuscodes";
}
$this->layout()->setFlash($message);
$this->redirect("Preorder", "statusupdateimport");
} else {
$this->layout()->setFlash("Nichts importiert!", "info");
$this->redirect("Preorder", "statusupdateimport");
}
}
protected function exportAction() {
$rfilter = $this->request->filter;
if(!is_array($rfilter)) {
$rfilter = [];
}
$filter = $this->getPreparedFilter($rfilter);
if($this->me->is("Admin")) {
$my_networks = NetworkModel::getAll();
} else {
$my_networks = $this->me->myNetworks(["netowner", "salespartner"]);
}
//var_dump($my_networks);exit;
$netzgebiet_ids = [];
$my_adb_networks = [];
foreach($my_networks as $network) {
if($network->adb_netzgebiet_id && !in_array($network->id, $netzgebiet_ids)) {
$netzgebiet_ids[] = $network->id;
$adb_network = new ADBNetzgebiet($network->adb_netzgebiet_id);
if(!$adb_network->isLoaded()) continue;
$my_adb_networks[$network->adb_netzgebiet_id] = $adb_network;
}
}
unset($filter['network_id']);
$preorder_filter = $filter;
$campaign_ids = [];
foreach(PreordercampaignModel::search(["network_id" => $netzgebiet_ids]) as $campaign) {
if(!in_array($campaign->id, $campaign_ids)) {
$campaign_ids[] = $campaign->id;
}
}
if($this->me->is("Admin")) {
if(array_key_exists("preordercampaign_id", $filter) && $filter['preordercampaign_id']) {
$preorder_filter["preordercampaign_id"] = $filter['preordercampaign_id'];
}
} else {
if(array_key_exists("preordercampaign_id", $filter) && in_array($filter['preordercampaign_id'], $campaign_ids)) {
$preorder_filter["preordercampaign_id"] = $filter['preordercampaign_id'];
} else {
$preorder_filter["preordercampaign_id"] = $campaign_ids;
}
if($preorder_filter['preordercampaign_id'] && in_array($preorder_filter['preordercampaign_id'], $campaign_ids)) {
$campaign_id = $preorder_filter['preordercampaign_id'];
if(is_numeric($campaign_id) && $campaign_id > 0) {
$campaign = new Preordercampaign($campaign_id);
$this->layout()->set("campaign", $campaign);
if($campaign->network->owner_id != $this->me->address_id && NetworkAddressModel::getFirst(["network_id" => $campaign->network_id, "address_id" => $this->me->address_id, "addresstype" => "salespartner"])) {
$preorder_filter["operator_id"] = $this->me->address_id;
}
}
} else {
$preorder_filter['preordercampaign_id'] = $campaign_ids;
if(NetworkAddressModel::getFirst(["address_id" => $this->me->address_id, "addresstype" => "salespartner"])) {
$preorder_filter["operator_id"] = $this->me->address_id;
}
}
}
//$preorder_filter['layout()->setTemplate("Preorder/export.csv");
$this->layout()->set("res", $res);
$this->layout()->set("no_filename", false);
}
protected function createOrderFromPreorderAction() {
$preorder_id = $this->request->preorder_id;
if(!is_numeric($preorder_id) || $preorder_id < 1) {
$this->layout()->setFlash("Vorbestellung nicht gefunden!", "error");
$this->redirect("Preorder", "Index");
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
$this->layout()->setFlash("Vorbestellung nicht gefunden!", "error");
$this->redirect("Preorder", "Index");
}
$order_data = [];
$order_data["preorder_id"] = $preorder->id;
$owner_data = [];
foreach(["company","uid","firstname","lastname","street","zip","city","phone","email"] as $field) {
if(!trim($preorder->$field)) {
$owner_data[$field] = "";
}
$owner_data[$field] = trim($preorder->$field);
}
// search owner in Address and add owner_id ...
$owner = false;
$owners = AddressModel::search($owner_data);
foreach($owners as $o) {
if(!$this->me->is("employee")) {
// external salespartners must not use addresses with customer_number
if($o->customer_number) continue;
// otherwise use with address
$owner = $o;
} else {
// every address can be used as fallback
$owner = $o;
// if we are employees, customers with customer_number and fibu_primary_account have precedence
// but still use addresses with only customer_number as fallback
if($o->customer_number) {
$owner = $o;
if($o->fibu_primary_account) {
break;
}
}
}
}
if($owner && $owner->id) {
$order_data["owner_id"] = $owner->id;
$order_data["owner"] = $owner;
} else {
foreach($owner_data as $field => $value) {
if(!$preorder->$field) continue;
$order_data["owner_".$field] = $value;
}
$order_data["new_owner"] = 1;
}
if($preorder->order_date) {
$order_data["order_date"] = $preorder->order_date;
} else {
$order_data["order_date"] = $preorder->create;
}
$operator = false;
$campaign = $preorder->campaign;
if(is_array($campaign->active_operators) && count($campaign->active_operators)) {
$campaign_operator = reset($campaign->active_operators);
$operator = $campaign_operator->operator;
}
if(!$operator) {
$this->layout()->setFlash("Kampagne hat keinen Netzbetreiber!", "error");
$this->redirect("Preorder", "Index", ["filter" => ["preordercampaign_id" => $campaign->id]], "preorder=$preorder_id");
}
// try product with correct network id
$product = ProductModel::getFirst([
"external_id" => $operator->id,
"network_id" => $campaign->network_id,
"productgroup_id" => TT_PRODUCTGROUP_ID_INTERNET_ACCESS_RESI,
"name" => "%OAN%",
"active" => true
]);
if(!$product) {
// else use any product from operator
$product = ProductModel::getFirst([
"external_id" => $operator->id,
"productgroup_id" => TT_PRODUCTGROUP_ID_INTERNET_ACCESS_RESI,
"name" => "%OAN%",
"active" => true
]);
}
if(!$product) {
// else use any product from operator
$product = ProductModel::getFirst([
"external_id" => $operator->id,
"productgroup_id" => TT_PRODUCTGROUP_ID_INTERNET_ACCESS_RESI,
"active" => true
]);
}
if($operator->id == 1) {
if(!$product) {
$product = ProductModel::getFirst([
"external" => 0,
"productgroup_id" => TT_PRODUCTGROUP_ID_INTERNET_ACCESS_RESI,
"network_id" => $campaign->network_id,
"active" => true
]);
}
if(!$product) {
$product = ProductModel::getFirst([
"external" => 0,
"productgroup_id" => TT_PRODUCTGROUP_ID_INTERNET_ACCESS_RESI,
"name" => "%OAN%",
"active" => true
]);
}
}
//var_dump($product);exit;
if(!$product) {
$this->layout()->setFlash("Keine Produkte für Netzbetreiber gefunden!", "error");
$this->redirect("Preorder", "Index", ["filter" => ["preordercampaign_id" => $campaign->id]], "preorder=$preorder_id");
}
$product_data = [];
$product_data["preorder_id"] = $preorder->id;
$product_data["oaid"] = $preorder->oaid;
$product_data["product_id"] = $product->id;
$product_data['amount'] = 1;
$product_data["pos"] = 1;
$product_data["description"] = "";
$product_data["price"] = trim($product->price) ? Layout::commaToDot(trim($product->price)) : 0;
$product_data["price_setup"] = trim($product->price_setup) ? Layout::commaToDot(trim($product->price_setup)) : 0;
$product_data["billing_delay"] = ($product->billing_delay) ? $product->billing_delay : 0;
if($product_data["billing_delay"] > 6) {
$product_data["billing_delay"] = 6;
}
$product_data["billing_period"] = $product->billing_period;
$product_data["contract_term"] = $product->contract_term;
if($this->me->is("Admin")) {
$product_data["price_nne"] = $product->price_nne;
$product_data["price_nbe"] = $product->price_nbe;
}
$order_data["products"] = [1 => OrderProductModel::create($product_data)];
//var_dump($order_data["products"]);exit;
$order = new Order();
$order->update($order_data);
//var_dump($owner_data);exit;
$oc = new OrderController();
$this->layout()->set("order", $order);
return $oc->addAction();
}
protected function apiAction() {
$do = $this->request->do;
$data = [];
switch($do) {
case "getLoggedEmail":
$return = $this->getLoggedEmail();
break;
case "saveAttribute":
$return = $this->saveAttributeApi();
break;
case "getFCPsForCampaign":
$return = $this->getFCPsForCampaignApi();
break;
case "getFilteredPreorders":
$return = $this->getFilteredPreordersApi();
break;
case "updateStatus":
$return = $this->updateStatusApi();
break;
case "createWorkorder":
$return = $this->createWorkorderApi();
break;
case "deleteWorkorder":
$return = $this->deleteWorkorderApi();
break;
case "savePatchposition":
$return = $this->savePatchpositionApi();
break;
case "setStatusFlag":
$return = $this->setStatusFlagApi();
break;
case "addWorkorderRemark":
$return = $this->addWorkorderRemarkApi();
break;
case "saveBorderpointStatus":
$return = $this->saveBorderpointStatusApi();
break;
case "saveOrderdate":
$return = $this->saveOrderdateApi();
break;
case "saveActivationdate":
$return = $this->saveActivationdateApi();
break;
case "setBilled":
$return = $this->setBilledApi();
break;
case "updateBilled":
$return = $this->updateBilledApi();
break;
case "saveStatusJournal":
$return = $this->saveStatusJournalApi();
break;
case "approveCancelRequest":
$return = $this->approveCancelRequest();
break;
case "denyCancelRequest":
$return = $this->denyCancelRequest();
break;
case "getRimoFcpStats":
$return = $this->getRimoFcpStatsApi();
break;
default:
$return = false;
}
if(!is_array($return) || !count($return)) {
$data = ["status" => "error"];
$this->returnJson($data);
}
if(mfResponse::isResponse($return)) {
$this->returnJson($return);
} else {
$data['status'] = "OK";
$data['result'] = $return;
$this->returnJson($data);
}
}
protected function approveCancelRequest() {
return true; // disabled
$preorder_id = $this->request->pid;
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
$this->log->debug(__METHOD__.": Preorder $preorder_id not found");
return false;
}
if(!$preorder->cancel_request) {
$this->log->debug(__METHOD__.": Preorder $preorder_id has no cancel request");
return false;
}
}
protected function denyCancelRequest() {
return true; // disabled
$preorder_id = $this->request->pid;
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
$this->log->debug(__METHOD__.": Preorder $preorder_id not found");
return false;
}
if(!$preorder->cancel_request) {
$this->log->debug(__METHOD__.": Preorder $preorder_id has no cancel request");
return false;
}
// empty all cancel request fields
$preorder->cancel_request = null;
$preorder->cancel_request_by = null;
$preorder->cancel_request_status_code = null;
$preorder->cancel_request_execution_date = null;
$preorder->save();
return ["message" => "Cancel request removed"];
}
protected function saveStatusJournalApi() {
$preorder_id = $this->request->preorder_id;
$text = $this->request->text;
if(!$preorder_id || !$text) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
$journal = PreorderstatusJournal::create([
"preorder_id" => $preorder_id,
"text" => $text,
]);
if(!$journal->save()) {
return false;
}
return [
"preorder_id" => $preorder_id,
"create" => (new DateTime("@".$journal->create))->setTimezone(new DateTimeZone("Europe/Vienna"))->format("Y-m-d H:i:s"),
"creator" => $journal->creator->name,
"text" => htmlentities($journal->text),
];
}
protected function getLoggedEmail() {
$preorder_id = $this->request->pid;
$emaillog_id = $this->request->eid;
if(!is_numeric($preorder_id) || $preorder_id < 1) {
return false;
}
if(!is_numeric($emaillog_id) || $emaillog_id < 1) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
$emaillog = new EmailLog($emaillog_id);
if(!$emaillog->id) {
return false;
}
if($emaillog->object_type != "Preorder" || $emaillog->object_id != $preorder->id) {
return false;
}
$return = [
"preorder_id" => $preorder_id,
"emaillog_id" => $emaillog_id,
"from" => $emaillog->from,
"to" => $emaillog->to,
"subject" => $emaillog->subject,
"body" => ($emaillog->body_html) ? $emaillog->body_html : $emaillog->body_text,
"bodyIsHtml" => (bool) $emaillog->body_html,
"sent" => date("d.m.Y H:i", $emaillog->create),
"headers" => json_decode($emaillog->headers),
"attachments" => [],
];
if(is_array($emaillog->attachments) && count($emaillog->attachments)) {
foreach($emaillog->attachments as $attachment) {
$return["attachments"][] = [
"id" => $attachment->id,
"hash" => $attachment->content->sha256,
"filename" => $attachment->filename,
"filesize" => ($attachment->content) ? $attachment->content->filesize : 0,
"mimetype" => ($attachment->content) ? $attachment->content->mimetype : "",
];
}
}
return $return;
}
protected function saveBorderpointStatusApi() {
$preorder_id = $this->request->preorder_id;
$status_type = $this->request->status_type;
$value = $this->request->value;
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
if(!$value) {
$preorder->update(["borderpoint_status" => null]);
} else {
$preorder->update(["borderpoint_status" => $status_type]);
}
$this->log->debug(__METHOD__.": $preorder_id - borderpoint status updated to $status_type");
$preorder->save();
return mfResponse::Ok();
}
protected function getFCPsForCampaignApi(): array {
$campaign = new Preordercampaign($this->request->campaign_id);
if (!$campaign->id) return [];
$fcps = ADBRimoFcp::getAll(["netzgebiet_id" => intval($campaign->network->adb_netzgebiet_id)]) ?? [];
if (empty($fcps)) return [];
$filter = $this->request->filter ?? [];
// We want to count preorders matching ALL other filters, but ignoring the current FCP filter
if (isset($filter['fcp'])) {
unset($filter['fcp']);
}
$statsMap = PreorderModel::countActiveGroupedByFcp($filter);
$result = array_map(
fn($fcp) => [
"real_id" => $fcp->id,
"id" => $fcp->name ?? null,
"text" => $fcp->name ?? null,
'lat' => $fcp->gps_lat ?? null,
'lng' => $fcp->gps_long ?? null,
'preorder_count' => $statsMap[$fcp->id] ?? 0
],
$fcps
);
usort($result, fn($a, $b) => $b['preorder_count'] <=> $a['preorder_count']);
return $result;
}
public function getRimoFcpStatsApi()
{
$this->postData = json_decode(file_get_contents("php://input"), true);
$fcpIds = $this->postData['fcp_ids'] ?? [];
$stats = ADBRimoFcp::getRimoFcpStatistics($fcpIds);
foreach ($stats as &$item)
if (isset($item['counts_by_rimo_type']) && is_string($item['counts_by_rimo_type']))
$item['counts_by_rimo_type'] = json_decode($item['counts_by_rimo_type']);
unset($item);
return array_values($stats);
}
private function setBilledApi() {
$preorder_id = $this->request->id;
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
if(!$preorder->adb_wohneinheit_id) {
return false;
}
$today = new DateTime();
$today->setTimezone(new DateTimeZone("Europe/Vienna"));
$preorder->adb_wohneinheit->enduser_setup_invoice_date = $today->format("Y-m-d");
$preorder->adb_wohneinheit->save();
return ["message" => "Billed status updated", "pid" => $preorder_id, "date" => $today->format("Y-m-d")];
}
private function saveOrderdateApi() {
$preorder_id = $this->request->id;
$order_date = $this->request->order_date;
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
$this->log->debug(__METHOD__.": preorder ($preorder_id) not found");
return false;
}
try {
$orderdate_dt = DateTime::createFromFormat("d.m.Y", $order_date);
$orderdate_dt->setTime(4, 0, 0);
$preorder->order_date = $orderdate_dt->getTimestamp();
//$orderdate_ts = Layout::dateToInt($order_date);
if(!$preorder->save()) {
$this->log->debug(__METHOD__ . ": error saving orderdate");
return false;
}
} catch (Exception $e) {
$this->log->debug(__METHOD__.": Exception: ".$e->getMessage());
return false;
}
if($preorder->status->code < 500 || !$preorder->adb_wohneinheit->enduser_setup_invoice_date) {
// remove from 300-custom-new-order log if exitisting, so the email will be sent again
foreach(PreorderStatusnotificationLog::search(["preorder_id" => $preorder->id, "email_type" => "300-custom-new-order"]) as $psnl) {
$psnl->delete();
}
}
return ["message" => "Orderdate saved successfully", "preorder_id" => $preorder_id, "order_date" => $order_date];
}
private function saveActivationdateApi() {
$preorder_id = $this->request->id;
$activation_date = $this->request->activation_date;
$activation_billing = $this->request->activation_billing ? 1 : 0;
$this->log->debug(print_r($this->request->get(), true));
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
$this->log->debug(__METHOD__.": preorder ($preorder_id) not found");
return false;
}
try {
$activationdate = DateTime::createFromFormat("d.m.Y", $activation_date, new DateTimeZone("Europe/Vienna"));
$activationdate->getTimestamp();
} catch(Exception $e) {
return false;
}
$history = PreorderHistoryModel::getLastStatusChangeTo($preorder->id, 500);
if(!$history) {
return false;
}
$history->changed = $activationdate->getTimestamp();
$history->save();
//$this->log->debug(print_r($preorder, true));
$this->log->debug(print_r($activation_billing, true));
if($preorder->activation_billing != $activation_billing) {
$preorder->activation_billing = $activation_billing;
$this->log->debug(print_r($preorder, true));
$preorder->save();
}
return ["message" => "Activationdate saved successfully", "preorder_id" => $preorder_id, "activation_date" => $activation_date, "activation_billing" => $activation_billing];
}
private function addWorkorderRemarkApi() {
$preorder_id = $this->request->preorder_id;
$workorder_id = $this->request->workorder_id;
$new_remark = $this->request->remark;
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
$this->log->debug(__METHOD__.": preorder ($preorder_id) not found");
return false;
}
$workorder = new RimoWorkorder($workorder_id);
if(!$workorder->id) {
$this->log->debug(__METHOD__.": workorder ($workorder_id) not found");
return false;
}
if(!$new_remark) return false;
$new_remark = date("d.m.Y").": ".$new_remark;
$api_creds = $preorder->getNetownerRimoApiCredentials();
$this->log->debug(__METHOD__.": Rimo Api Creds: ".print_r($api_creds, true));
if(!$api_creds) return false;
$apikey = $api_creds["prod"]["key"];
// upload remark to Rimo
if(!Rimoapi::addRemark($apikey, $workorder->rimo_id, $new_remark)) {
return false;
}
$remarks = $new_remark;
if($workorder->remarks) {
$remarks = $workorder->remarks."\n$new_remark";
}
$workorder->remarks = $remarks;
$workorder->save();
return ["message" => "Remark added successfully", "preorder_id" => $preorder_id, "workorder_id" => $workorder_id, "remark" => $workorder->remarks];
}
private function setStatusFlagApi() {
$preorder_id = $this->request->preorder_id;
$code = $this->request->code;
$value = $this->request->value;
if(!$preorder_id || !$code) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) return false;
$sflag = PreorderStatusflagModel::getFirst(["code" => $code]);
if(!$sflag) {
return false;
}
$sflag->preorder_id = $preorder->id;
if ($code == 145) {
$attribute = "inhouse_cabling_supplied"; // = Starterpaket erhalten
$attribs = $preorder->attribute;
if(!$attribs) {
$attribs = [];
}
$attribs[$attribute] = $value ? 1 : 0;
$preorder->attributes = json_encode($attribs);
if($preorder->save()) {
//return ["id" => $preorder_id, "attribute" => $attribute, "update" => date("d.m.Y H:i", $preorder->edit)];
} else {
//$this->returnJson(["status" => "error", "result" => ["id" => $preorder_id, "attribute" => $attribute]]);
}
}
$sflag->value->value = ($value) ? 1 : 0;
//var_dump($flagvalue);exit;
try {
if(!$sflag->value->save()) {
return false;
}
} catch(Exception $e) {
$this->log->debug($e->getTraceAsString());
}
$this->log->debug("===== Setting Hausnummer Flag Value $code -> ".($value ? 1 : 0));
if($preorder->adb_hausnummer_id) {
$preorder->adb_hausnummer->setStatusflag($code, ($value ? 1 : 0));
}
return ["message" => "Statusflag saved successfully"];
}
private function getFilteredPreordersApi() {
$preorders = [];
$fttxlocations = [];
$filter = [];
$type = ["preorders", "fttx"];
if(is_array($this->request->filter)) {
$filter = $this->request->filter;
}
if($this->request->type == "preorders") {
$type = ["preorders"];
}
if($this->request->type == "fttxlocations") {
$type = ["fttx"];
}
$filter = $this->getPreparedFilter($filter);
$my_campaign_ids = [];
if($this->me->is("Admin")) {
$my_networks = NetworkModel::getAll();
} else {
if($this->me->is("preorderfront")) {
$pns = json_decode($this->me->getFlag("preorder_networks"));
if(is_array($pns) && count($pns)) {
foreach($pns as $pn_id) {
$my_networks[] = new Network($pn_id);
}
} else {
$my_networks = $this->me->myNetworks(['netowner', 'salespartner']);
}
//var_dump($my_networks);exit;
} else {
$my_networks = $this->me->myNetworks(['netowner', 'salespartner']);
}
// check users allowed networks
$user_network_ids = $this->me->getFlag("preorder_networks")->value();
if($user_network_ids) {
$user_network_ids = json_decode($user_network_ids);
}
if(is_array($user_network_ids) && count($user_network_ids)) {
if(!$my_networks) {
foreach($user_network_ids as $mnid) {
$my_networks[] = new Network($mnid);
}
} else {
//var_dump($user_network_ids, $my_networks);exit;
$new_my_networks = [];
foreach($my_networks as $network) {
if(in_array($network->id, $user_network_ids)) {
$new_my_networks[$network->id] = $network;
}
}
$my_networks = $new_my_networks;
}
}
foreach($my_networks as $network) {
foreach(PreordercampaignModel::search(['network_id' => $network->id]) as $campaign) {
$my_campaigns[] = $campaign;
if(!in_array($campaign->id, $my_campaign_ids)) $my_campaign_ids[] = $campaign->id;
}
}
if(array_key_exists("preordercampaign_id", $filter)) {
if(!in_array($filter['preordercampaign_id'], $my_campaign_ids)) {
$filter['preordercampaign_id'] = $my_campaign_ids;
}
} else {
$filter['preordercampaign_id'] = $my_campaign_ids;
}
}
if(!array_key_exists("preordercampaign_id", $filter) || !$filter['preordercampaign_id']) $filter['preordercampaign_id'] = 0;
if(in_array("preorders", $type)) {
$this->log->debug(__METHOD__.": requested preorders");
//var_dump($filter);exit;
$results = PreorderModel::searchActive($filter);
foreach($results as $preorder) {
//$this->log->debug("building status: ".print_r($building->status,true));
$data = clone($preorder->data);
unset($data->workorder_export_data);
unset($data->submit_request);
unset($data->addon_services);
$data->id = $preorder->id;
$data->status_code = $preorder->status->code;
$data->adrcd = $preorder->adb_hausnummer->adrcd;
$data->extref = $preorder->adb_hausnummer->extref;
$data->adb_strasse = $preorder->adb_hausnummer->strasse->name;
$data->adb_hausnummer = $preorder->adb_hausnummer->hausnummer;
$data->adb_plz = $preorder->adb_hausnummer->plz->plz;
$data->adb_ort = $preorder->adb_hausnummer->ortschaft->name;
$data->adb_gemeinde = $preorder->adb_hausnummer->strasse->gemeinde->name;
$data->adb_ex_state = $preorder->adb_hausnummer->rimo_ex_state;
$data->adb_op_state = $preorder->adb_hausnummer->rimo_op_state;
$data->gps_lat = $preorder->adb_hausnummer->gps_lat;
$data->gps_long = $preorder->adb_hausnummer->gps_long;
if($this->me->is("Admin")) {
$data->borderpoint_lat = ($preorder->adb_hausnummer->borderpoint_lat) ? json_decode($preorder->adb_hausnummer->borderpoint_lat) : null;
$data->borderpoint_long = ($preorder->adb_hausnummer->borderpoint_long) ? json_decode($preorder->adb_hausnummer->borderpoint_long) : null;
//$data->trenches = ($preorder->adb_hausnummer->trenches) ? json_decode($preorder->adb_hausnummer->trenches) : null;
$data->home_trench = ($preorder->adb_hausnummer->home_trench) ? json_decode($preorder->adb_hausnummer->home_trench) : null;
}
$data->type_label = __($data->type, "preorder");
$data->connection_type_label = __($data->connection_type, "preorder");
$preorders[] = $data;
}
}
if(in_array("fttx", $type)) {
$this->log->debug(__METHOD__.": requested fttxlocations");
// get all fttp locations in current campaign network with status
if($filter["preordercampaign_id"]) {
$my_adb_networks = [];
$campaign = new Preordercampaign($filter["preordercampaign_id"]);
if($campaign->id) {
$salesclusters = $campaign->salesclusters;
if(is_array($salesclusters) && count($salesclusters)) {
foreach($salesclusters as $sc) {
$my_adb_networks[] = new ADBNetzgebiet($sc->id);
}
} else {
$my_adb_networks[] = $campaign->adb_netzgebiet;
}
}
foreach($my_adb_networks as $adb_network) {
if(!$adb_network->isLoaded()) continue;
/*foreach(ADBHausnummerModel::search(['netzgebiet_id' => $adb_network->id]) as $hausnummer) {
$loc = [];
$loc["street"] = $hausnummer->strasse->name . " " . $hausnummer->hausnummer;
$loc["zip"] = $hausnummer->plz->plz;
$loc["city"] = $hausnummer->strasse->gemeinde->name;
$loc["gps_lat"] = $hausnummer->gps_lat;
$loc["gps_long"] = $hausnummer->gps_long;
$loc["ex_state"] = $hausnummer->rimo_ex_state;
$loc["op_state"] = $hausnummer->rimo_op_state;
$fttxlocations[] = $loc;
}*/
$adb = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
$sql = "SELECT * FROM view_hausnummer WHERE netzgebiet_id=".$adb_network->id;
$res = $adb->query($sql);
while($data = $adb->fetch_object($res)) {
$loc = [];
$loc["street"] = $data->strasse . " " . $data->hausnummer;
$loc["zip"] = $data->plz;
$loc["city"] = $data->gemeinde;
$loc["gps_lat"] = $data->gps_lat;
$loc["gps_long"] = $data->gps_long;
$loc["ex_state"] = $data->rimo_ex_state;
$loc["op_state"] = $data->rimo_op_state;
$fttxlocations[] = $loc;
}
}
}
}
return [
"preorders" => $preorders,
"fttxlocations" => $fttxlocations
];
}
private function saveAttributeApi() {
$preorder_id = $this->request->id;
if(!is_numeric($preorder_id) || $preorder_id < 1) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
$attribute = $this->request->attribute;
if(!$attribute) {
return false;
}
$value = $this->request->value;
$attribs = $preorder->attribute;
if(!$attribs) {
$attribs = [];
}
$attribs[$attribute] = $value ? 1 : 0;
$preorder->attributes = json_encode($attribs);
if($preorder->save()) {
return ["id" => $preorder_id, "attribute" => $attribute, "update" => date("d.m.Y H:i", $preorder->edit)];
} else {
$this->returnJson(["status" => "error", "result" => ["id" => $preorder_id, "attribute" => $attribute]]);
}
}
private function updateStatusApi() {
$preorder_id = $this->request->id;
if(!is_numeric($preorder_id) || $preorder_id < 1) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
$status_id = $this->request->status_id;
if(!is_numeric($status_id) || $status_id < 1) {
return false;
}
$status = new Preorderstatus($status_id);
if(!$status->id) {
return false;
}
$preorder->status_id = $status_id;
$preorder->edit_by = $this->me->id;
$preorder->save();
$update = [];
foreach(PreorderModel::searchActive(["adb_hausnummer_id" => $preorder->adb_hausnummer_id]) as $affected_preorder) {
$up = [
"id" => $affected_preorder->id,
"sid" => $affected_preorder->status_id,
"code" => $affected_preorder->status->code,
"text" => $affected_preorder->status->name,
"bcode" => $affected_preorder->adb_hausnummer->status->code,
"btext" => $affected_preorder->adb_hausnummer->status->name,
"ciftoken" => $affected_preorder->ciftoken,
"cifurl" => $affected_preorder->cifurl,
"cifcableurl" => $affected_preorder->cifcableurl,
];
if($preorder->adb_wohneinheit_id) {
$up["ucode"] = $affected_preorder->adb_wohneinheit->status->code;
$up["utext"] = $affected_preorder->adb_wohneinheit->status->name;
}
$update[] = $up;
}
return ["message" => "Status saved successfully", "id" => $preorder_id, "updates" => $update];
}
private function savePatchpositionApi() {
$preorder_id = $this->request->id;
$cluster = $this->request->cluster;
$shelf = $this->request->shelf;
$module = $this->request->module;
$port = $this->request->port;
if(!is_numeric($preorder_id) || $preorder_id < 1) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
if(!$preorder->adb_wohneinheit_id) {
return false;
}
$we = $preorder->adb_wohneinheit;
if($cluster && $cluster != $we->cluster) {
$we->patch_cluster = $cluster;
}
$we->patch_shelf = $shelf;
$we->patch_module = $module;
$we->patch_port = $port;
$we->save();
$preorder->save();
return ["message" => "Patchposition saved successfully", "id" => $preorder->id];
}
private function createWorkorderApi() {
$preorder_id = $this->request->id;
if(!is_numeric($preorder_id) || $preorder_id < 1) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
/*if($preorder->type != "legacytransfer") {
return false;
}*/
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;
}
$return = [
"id" => $workorder->id,
"name" => $workorder->rimo_name,
"external_id" => $workorder->rimo_id,
"status" => $workorder->rimo_status,
"assigned_to" => $workorder->rimo_team_name,
"created" => date("d.m.Y H:i", $workorder->create),
"preorder_id" => $preorder_id
];
return $return;
}
private function deleteWorkorderApi() {
if(!$this->me->is("Admin") && !$this->me->can("preorder")) {
$this->log->debug(__METHOD__.": no permission");
return false;
}
$preorder_id = $this->request->id;
$wo_id = $this->request->wid;
if(!is_numeric($preorder_id) || $preorder_id < 1) {
return false;
}
$preorder = new Preorder($preorder_id);
if(!$preorder->id) {
return false;
}
if(!$preorder->adb_wohneinheit_id) {
return false;
}
if(!is_numeric($wo_id) || $wo_id < 1) {
return false;
}
$workorder = new RimoWorkorder($wo_id);
if(!$workorder->id) {
return false;
}
if($preorder->adb_wohneinheit_id != $workorder->adb_wohneinheit_id) {
$this->log->warning(__METHOD__ . ": wohneinheit_id not equal");
return false;
}
$workorder->delete();
return ["message" => "Workorder deleted successfully", "id" => $preorder->id, "wid" => $wo_id];
}
private function updateBilledApi() {
$preorder_id = $this->request->id;
if (!is_numeric($preorder_id) || $preorder_id < 1) return false;
$preorder = new Preorder($preorder_id);
if (!$preorder->id) return false;
$billed = $this->request->billed ? (string)time() : "0";
$preorder->billed = $billed;
$preorder->billed_by = $this->me->id;
if (!$preorder->save()) return false;
return [
"message" => "Billed status updated successfully",
"id" => $preorder_id,
"billed" => $billed,
"billed_by_name" => $this->me->name,
"billed_by_id" => $this->me->id,
"billed_date" => date("d.m.Y H:i", $preorder->billed ? $preorder->billed : time())
];
}
public function custom300Action() {
// Ensure PreorderModel is available or include it if necessary.
// For this example, assuming PreorderModel exists and getAll300CustomPreorders is defined.
$preorders = PreorderModel::getAll300CustomPreorders();
// Prepare JS variables to be sent to the frontend.
// The data from getAll300CustomPreorders is already in a suitable format (objects with specific properties),
// so we can pass it directly.
$JSGlobals = [
"BASE_URL" => self::getUrl(""),
"MFAPPNAME" => MFAPPNAME_SLUG,
"PAGE_TITLE" => "Custom Preorders (300)",
"PATH" => [
["text" => MFAPPNAME_SLUG, "href" => self::getUrl("Dashboard")],
["text" => "Custom Preorders (300)", "href" => self::getUrl("Preorder/custom300")] // Adjust URL if module is different
],
"PREORDERS_DATA" => $preorders, // Directly pass the fetched data
"IS_ADMIN" => $this->me->is(["Admin"]), // Pass admin status if needed in frontend
];
// Ensure the additionalJS array includes your custom Vue component file.
// This assumes PreorderCustom300.js is located in public/js/pages/Preorder/.
$this->layout()->set('additionalJS', array_merge($this->additionalJS ?? [], ['js/pages/Preorder/PreorderCustom300.js']));
// Set layout for Vue view.
$this->layout()->set("vueViewName", "PreorderCustom300"); // Name of the Vue component
$this->layout()->set("JSGlobals", $JSGlobals);
$this->layout()->setTemplate("VueViews/Vue"); // Assuming a generic Vue template
}
public function RimoTypeMapAction() {
Helper::renderVue($this, "PreorderRimoTypeMap", "Rimo Typen Karte", [
"MAPBOX_KEY" => TT_MAPBOX_TILE_API_TOKEN,
"USER_ID" => $this->me->id,
"ALL_USERS" => array_map(fn($u) => ["id" => $u->id, "name" => $u->name], UserModel::getAll()),
"ALL_CAMPAIGNS" => array_map(fn($c) => ["id" => $c->id, "name" => $c->name], Helper::getPreorderCampaignFromUser($this->me, true)),
"PATH" => [
["text" => MFAPPNAME_SLUG, "href" => self::getUrl("Dashboard")],
["text" => "Rimo Typen Karte", "href" => self::getUrl("Preorder/RimoTypeMap")]
]
]);
}
public function RimoTypeMapDataAction() {
$input = json_decode(file_get_contents('php://input'), true);
$campaignId = $input['campaignId'] ?? null;
$allowedCampaigns = Helper::getPreorderCampaignFromUser($this->me);
if (!$campaignId || !in_array($campaignId, $allowedCampaigns)) self::sendError('Ungültige oder keine Kampagne ausgewählt.');
$data = PreorderModel::getPreorderRimoTypeData($campaignId);
self::returnJson(['success' => true, 'data' => $data]);
}
public function RimoTypeMapSaveFaultsAction() {
$input = json_decode(file_get_contents('php://input'), true);
$campaignId = $input['campaignId'] ?? null;
$faults = $input['faults'] ?? [];
$allowedCampaigns = Helper::getPreorderCampaignFromUser($this->me);
if (!$campaignId || !in_array($campaignId, $allowedCampaigns)) self::sendError('Ungültige oder keine Kampagne ausgewählt.');
if (!is_array($faults) || !count($faults)) self::sendError('Keine Fehlerdaten übermittelt.');
$campaign = new Preordercampaign($campaignId);
if (!$campaign->id) self::sendError('Kampagne nicht gefunden.');
$campaign->rimo_type_map_faults = json_encode($faults);
if (!$campaign->save()) self::sendError('Fehler beim Speichern der Fehlerdaten.');
self::returnJson(['success' => true, 'message' => 'Fehlerdaten erfolgreich gespeichert.']);
}
public function RimoTypeMapGetFaultsAction() {
$campaignId = $this->request->preordercampaign_id ?? null;
$allowedCampaigns = Helper::getPreorderCampaignFromUser($this->me);
if (!$campaignId || !in_array($campaignId, $allowedCampaigns)) self::sendError('Ungültige oder keine Kampagne ausgewählt.');
$campaign = new Preordercampaign($campaignId);
if (!$campaign->id) self::sendError('Kampagne nicht gefunden.');
$faults = $campaign->rimo_type_map_faults ? json_decode($campaign->rimo_type_map_faults, true) : [];
self::returnJson(['success' => true, 'faults' => $faults]);
}
protected function generateTemplate(string $templateName, array $replacements): string {
$path = BASEDIR . "/Layout/default/{$templateName}.html";
if (!file_exists($path)) self::sendError("Template nicht gefunden: {$templateName}");
$content = file_get_contents($path);
foreach ($replacements as $key => $value) $content = str_replace("{{ {$key} }}", $value ?? '', $content);
return $content;
}
public function RimoTypeMapFaultsPDFAction() {
if (empty($this->request->preordercampaign_id)) self::sendError('Kampagnen-ID fehlt.');
$campaignId = $this->request->preordercampaign_id;
if (!in_array($campaignId, Helper::getPreorderCampaignFromUser($this->me))) self::sendError('Zugriff auf diese Kampagne verweigert.');
$campaign = new Preordercampaign($campaignId);
if (!$campaign->id) self::sendError('Kampagne nicht gefunden.');
$faults = json_decode($campaign->rimo_type_map_faults, true) ?? [];
$allAddressesById = array_column(PreorderModel::getPreorderRimoFaultsData((int)$campaignId), null, 'hausnummer_id');
$faultReasonMap = [
'building_type' => 'Gebäudetyp falsch',
'home_count' => 'Homeanzahl falsch',
'not_existent' => 'Gebäude nicht existent',
'other' => 'Sonstiges',
'graz_umgebung' => 'Ort/Gemeinde nicht existent'
];
$faultyEntriesData = [];
foreach ($faults as $hausnummerId => $faultData) {
if (!isset($allAddressesById[$hausnummerId])) continue;
if (!empty($faultData['done']) && ($faultData['done'] === true || $faultData['done'] === 1 || $faultData['done'] === 'true')) continue;
$addressInfo = $allAddressesById[$hausnummerId];
$reasons = array_map(fn($key) => $faultReasonMap[$key] ?? $key, $faultData['reasons'] ?? []);
$faultyEntriesData[$hausnummerId] = [
'address' => $addressInfo,
'faults' => [
'reasons' => $reasons,
'other' => htmlspecialchars($faultData['other'] ?? '')
]
];
}
$faultyEntries = [];
foreach ($faultyEntriesData as $hausnummerId => $data) {
$addressInfo = $allAddressesById[$hausnummerId];
$faultyEntries[] = [
'address' => $addressInfo,
'faults' => $data['faults'],
'addressDbLink' => "https://thetool.xinon.at/AddressDB/View?id={$hausnummerId}",
'googleMapsLink' => "https://maps.google.com/?q={$addressInfo['gps_lat']},{$addressInfo['gps_long']}"
];
}
$tempDir = BASEDIR . "/var/temp";
is_dir($tempDir) || mkdir($tempDir, 0775, true);
$replacements = [
'basedir' => BASEDIR,
'campaignName' => htmlspecialchars($campaign->name),
'creationDate' => date("d.m.Y"),
];
$headerFile = tempnam($tempDir, 'pdf_header_') . '.html';
$footerFile = tempnam($tempDir, 'pdf_footer_') . '.html';
file_put_contents($headerFile, $this->generateTemplate('Preorder/PDF_HEADER', $replacements));
file_put_contents($footerFile, $this->generateTemplate('Preorder/PDF_FOOTER', $replacements));
$pdf = new PdfForm("Preorder/PDF_MAIN", [
"campaignName" => $campaign->name,
"faultyEntries" => $faultyEntries,
]);
$options = "--header-html {$headerFile} --footer-html {$footerFile} --margin-top 35 --margin-bottom 25";
$filename = $pdf->render($options);
unlink($headerFile);
unlink($footerFile);
if (!file_exists($filename)) self::sendError('Generierte PDF-Datei nicht gefunden.');
$outputFilename = "Fehlerprotokoll_" . preg_replace('/[^a-zA-Z0-9_-]/', '_', $campaign->name) . ".pdf";
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . $outputFilename . '"');
header('Content-Length: ' . filesize($filename));
readfile($filename);
unlink($filename);
exit;
}
protected function uploadDocumentsAction() {
if (empty($_FILES['files']) || empty($_POST['preorderId']) || empty($_POST['descriptions'])) {
self::sendError('Erforderliche Daten fehlen (Dateien, preorderId oder Beschreibungen).');
}
$preorderId = $_POST['preorderId'];
$descriptions = $_POST['descriptions'];
if (count($_FILES['files']['name']) !== count($descriptions)) {
self::sendError('Anzahl der Dateien und Beschreibungen stimmt nicht überein.');
}
$preorder = new Preorder($preorderId);
if (!$preorder->id) {
self::sendError('Bestellung nicht gefunden.');
}
$fileObjects = json_decode($preorder->files, true);
if (!is_array($fileObjects)) $fileObjects = [];
foreach ($_FILES['files']['name'] as $index => $name) {
if ($_FILES['files']['error'][$index] !== UPLOAD_ERR_OK) continue;
$extension = pathinfo($name, PATHINFO_EXTENSION);
$name = preg_replace('/[^a-zA-Z0-9_-]/', '_', substr($descriptions[$index], 0, 50));
if ($extension) {
$name .= '.' . $extension;
}
$_FILES['file'] = [
'name' => $name,
'type' => $_FILES['files']['type'][$index],
'tmp_name' => $_FILES['files']['tmp_name'][$index],
'error' => $_FILES['files']['error'][$index],
'size' => $_FILES['files']['size'][$index]
];
$description = trim($descriptions[$index]);
if (empty($description)) continue;
try {
$uploaded = mfUpload::handleFormUpload("file", false, "/PreorderDocuments");
$fileObjects[] = ["id" => $uploaded->id, "description" => $description];
} catch (Exception $e) {}
}
$db = FronkDB::singleton();
$escapedFilesJson = $db->escape(json_encode($fileObjects));
$sql = "UPDATE `" . FRONKDB_DBNAME . "`.Preorder SET files = '$escapedFilesJson' WHERE id = " . (int)$preorder->id;
$db->query($sql);
self::returnJson([
'success' => true,
'message' => "Datei(en) erfolgreich hochgeladen.",
'fileObjects' => $fileObjects
]);
}
}