Files
thetool/application/Api/v1/PreorderApicontroller.php

1171 lines
47 KiB
PHP

<?php
require_once(APPDIR . "/Api/v1/Modules/Preorder/Cif.php");
require_once(APPDIR . "/Api/v1/Modules/Preorder/Activation.php");
use application\Api\v1\Modules;
class PreorderApicontroller extends mfBaseApicontroller {
//private $filter_gemeinde_ids = [];
//private $campaign;
private $campaign;
private $campaigns = [];
private $filter_salescluster_ids = [];
private $campaigns_by_scluster = [];
private $allowed_preordertypes = [];
private $district_is_city = false;
private $hausnummer_add_zusatz = false;
private $exist_is_error = false;
private $require_connectiontype = false;
private $allow_unit_update = false;
protected function init() {
$db = $this->db(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
$this->allowMissingOrigin = true;
}
protected function registerRoutes() {
/*
* TODO: Load Api Modules automatically in mfBaseApiController
*/
$modules = [];
foreach(["Cif", "Activation"] as $moduleName) {
$classname = "application\\Api\\v1\\Modules\\Preorder\\" . $moduleName;
$modules[$moduleName] = new $classname([
"get" => $this->get,
"post" => $this->post,
"db" => $this->db(),
"me" => $this->me
]);
}
$this->addRoute("/preorder", "submitPreorder", "POST");
$this->addRoute("/preorder/open", "getOpenPreorders", "GET");
$this->addRoute("/preorder/all", "getAllPreorders", "GET");
$this->addRoute("/preorder/customerInstallationFeedback", [$modules["Cif"], "getCifData"], "GET");
$this->addRoute("/preorder/customerInstallationFeedback", [$modules["Cif"], "userSetCif"], "POST");
$this->addRoute("/preorder/fullexport", "exportPreorders", "GET");
$this->addRoute("/preorder/:code/clientInstallationFinished", [$modules["Cif"], "providerSetCif"], "POST");
$this->addRoute("/preorder/:code/serviceActivated", [$modules["Activation"], "setServiceActive"], "POST");
$this->addRoute("/preorder/:code", "getPreorder", "GET");
$this->addRoute("/preorder/:code", "cancelPreorder", "DELETE");
}
/*
* is called after User is authenticated by API Key
*/
protected function authenticated() {
$this->registerRoutes();
/*if($this->me->is("preorderaddressreporting")) {
return mfResponse::Forbidden();
}*/
$campaignApiusers = PreordercampaignApiuserModel::search(["worker_id" => $this->me->id]);
foreach($campaignApiusers as $campaignApiuser) {
$campaign = new Preordercampaign($campaignApiuser->preordercampaign_id);
if($campaign->id) {
foreach(PreordercampaignSalesclusterModel::search(['preordercampaign_id' => $campaign->id]) as $campain_scluster) {
if(!in_array($campain_scluster->salescluster_id, $this->filter_salescluster_ids)) {
$this->filter_salescluster_ids[] = $campain_scluster->salescluster_id;
}
$this->campaigns_by_scluster[$campain_scluster->salescluster_id] = $campaign->id;
}
$this->campaigns[$campaign->id] = $campaign;
// get allowed preordertypes
if(is_array($campaign->types) && count($campaign->types)) {
foreach($campaign->types as $type) {
$this->allowed_preordertypes[] = $type->type;
}
}
if($campaign->district_is_city == 1) {
$this->district_is_city = true;
}
if($campaign->hausnummer_add_zusatz == 1) {
$this->hausnummer_add_zusatz = true;
}
if($campaign->exist_is_error == 1) {
$this->exist_is_error = true;
}
if($campaign->require_connectiontype == 1) {
$this->require_connectiontype = true;
}
if($campaign->allow_unit_update == 1) {
$this->allow_unit_update = true;
}
} else {
$this->log->debug(__METHOD__ . ": campaign not found (PreordercampaignApiuser::preordercampaign_id " . $campaignApiuser->preordercampaign_id . ")");
$this->log->debug(print_r($campaignApiuser, true));
}
foreach(PreordercampaignOriginhostnameModel::search(['preordercampaign_id' => $campaign->id]) as $origin) {
$this->addAllowedOrigin($origin->hostname);
}
}
$this->allowed_preordertypes = array_unique($this->allowed_preordertypes);
}
protected function exportPreorders() {
if($this->me->username != 'r.eschner@rmlinfrastruktur.at' && $this->me->username != 'e.grundner@rmlinfrastruktur.at') {
return mfResponse::Forbidden();
}
if($this->me->is("Admin")) {
$my_networks = NetworkModel::getAll();
} else {
$my_networks = $this->me->myNetworks(["netowner", "salespartner"]);
}
$netzgebiet_ids = [];
$my_adb_networks = [];
foreach($my_networks as $network) {
if($network->adb_netzgebiet_id && !in_array($network->adb_netzgebiet_id, $netzgebiet_ids)) {
$netzgebiet_ids[] = $network->id;
$my_adb_networks[$network->adb_netzgebiet_id] = new ADBNetzgebiet($network->adb_netzgebiet_id);
}
}
$preorder_filter = [];
$campaign_ids = [];
foreach(PreordercampaignModel::search(["network_id" => $netzgebiet_ids]) as $campaign) {
if(!in_array($campaign->id, $campaign_ids)) {
$campaign_ids[] = $campaign->id;
}
}
$preorder_filter["preordercampaign_id"] = $campaign_ids;
// Get mysqli resource from Model, so layout can output data as it's retrieved
// Works around lousy performance and horrendous memory usage
$res = PreorderModel::searchActive($preorder_filter, [], true);
$tpl = new Layout();
$tpl->setTemplate("Preorder/export.csv");
$tpl->set("res", $res);
$tpl->set("no_filename", true);
$tpl->display();
//$csv = $tpl->render();
//echo $csv;
exit;
}
protected function getOpenPreorders() {
$ts = $this->get['ts'];
$update_ts = 0;
if($ts) {
if(is_numeric($ts)) {
$update_ts = $ts;
} else {
try {
$update_date = new DateTime($ts);
} catch(\Exception $e) {
return mfResponse::BadRequest(["message" => "Invalid Timestamp format"]);
}
if($update_date) {
$update_ts = $update_date->format('U');
}
}
}
// auf cluster und partner_id einschränken
$preorder_search = [];
if(count($this->filter_salescluster_ids)) {
$preorder_search['netzgebiet_id'] = $this->filter_salescluster_ids;
}
$preorder_search = [];
if($this->me->is("preorderaddressreporting")) {
$user_networks_json = $this->me->getFlag("preorder_networks");
$user_networks = json_decode($user_networks_json);
if(!is_array($user_networks) || !count($user_networks)) {
return mfResponse::Forbidden();
}
$user_campaigns = [];
foreach($user_networks as $un) {
$uc = PreordercampaignModel::getFirst(["network_id" => $un]);
if($uc) {
$user_campaigns[] = $uc->id;
}
}
$preorder_search['preordercampaign_id'] = $user_campaigns;
} else {
$preorder_search['partner_id'] = $this->me->address_id;
}
if($update_ts) {
$preorder_search['add-where'] = "AND tt_preorder.`edit` > $update_ts";
} else {
// if no timestamp, return only open orders (500 == finished)
$preorder_search['<status_code'] = 500;
}
$return = [];
foreach(PreorderModel::searchActive($preorder_search) as $preorder) {
$return[] = $preorder->getApiArray();
}
//$this->requestLog->debug(print_r($return, true));
return mfResponse::Ok(["preorders" => $return]);
}
protected function getAllPreorders() {
$ts = $this->get['ts'];
$include_deleted = false;
if(array_key_exists("include_deleted", $this->get) && $this->get["include_deleted"]) {
$include_deleted = true;
}
$update_ts = 0;
if($ts) {
if(is_numeric($ts)) {
$update_ts = $ts;
} else {
$update_date = new DateTime($ts);
if($update_date) {
$update_ts = $update_date->format('U');
}
}
}
$preorder_search = [];
if($this->me->is("preorderaddressreporting")) {
if(!$include_deleted) {
$preorder_search["deleted"] = 0;
}
$user_networks_json = $this->me->getFlag("preorder_networks");
$user_networks = json_decode($user_networks_json);
if(!is_array($user_networks) || !count($user_networks)) {
return mfResponse::Forbidden();
}
$user_campaigns = [];
foreach($user_networks as $un) {
$uc = PreordercampaignModel::getFirst(["network_id" => $un]);
if($uc) {
$user_campaigns[] = $uc->id;
}
}
$preorder_search['preordercampaign_id'] = $user_campaigns;
} else {
$preorder_search["deleted"] = 0;
$preorder_search['partner_id'] = $this->me->address_id;
if(count($this->filter_salescluster_ids)) {
$preorder_search['netzgebiet_id'] = $this->filter_salescluster_ids;
}
}
if($update_ts) {
$preorder_search['add-where'] = "AND tt_preorder.`edit` > $update_ts";
}
$return = [];
foreach(PreorderModel::search($preorder_search) as $preorder) {
$return[] = $preorder->getApiArray();
}
//$this->requestLog->debug(print_r($return, true));
return mfResponse::Ok(["preorders" => $return]);
}
protected function getPreorder($code) {
$code = trim($code);
if(!$code) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
$preorder = PreorderModel::getFirst(['ucode' => strtoupper($code), 'partner_id' => $this->me->address_id]);
if(!$preorder) {
// try as extref
$preorder = PreorderModel::getFirst(['extref' => $code, 'partner_id' => $this->me->address_id]);
}
if(!$preorder) {
// try oan id
$preorder = PreorderModel::getFirst(['oaid' => strtolower($code), 'partner_id' => $this->me->address_id], "`create` DESC");
}
if(!$preorder) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
if($preorder->partner_id != $this->me->address_id) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
$return = $preorder->getApiArray();
if(!$return) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
return mfResponse::Ok($return);
}
protected function cancelPreorder($code) {
if($this->me->is("Preorderreadonly")) return \mfResponse::Forbidden();
/*
$code = trim(strtoupper($code));
if(!$code) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
$preorder = PreorderModel::getFirst(['ucode' => $code, 'partner_id' => $this->me->address_id, 'deleted' => 0, '<status_code' => 800]);
if(!$preorder) {
// try oan id
$preorder = PreorderModel::getFirst(['oaid' => $code, 'partner_id' => $this->me->address_id, 'deleted' => 0, '<status_code' => 800]);
if(!$preorder) {
return mfResponse::NotFound(["message" => "Preorder not found or cancelled already"]);
}
}*/
$code = trim($code);
if(!$code) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
$preorder = PreorderModel::getFirst(['ucode' => strtoupper($code), 'partner_id' => $this->me->address_id, 'deleted' => 0]);
if(!$preorder) {
// try oan id
$preorder = PreorderModel::getFirst(['oaid' => strtolower($code), 'partner_id' => $this->me->address_id, 'deleted' => 0]);
}
if(!$preorder) {
// try as extref
$preorder = PreorderModel::getFirst(['extref' => $code, 'partner_id' => $this->me->address_id, 'deleted' => 0]);
}
if(!$preorder) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
// check if user owns preorder
if($preorder->partner_id != $this->me->address_id) {
return mfResponse::Forbidden(["message" => "Permission denied"]);
}
/*
if($preorder->cancel_request) {
if($preorder->cancel_approved) {
return mfResponse::Forbidden(["message" => "Order already cancelled"]);
} else {
return mfResponse::Forbidden(["message" => "Cancellation request was already submitted"]);
}
}
*/
if($preorder->deleted || $preorder->cancel_request || $preorder->status->code >= 899) {
return mfResponse::Forbidden(["message" => "Order already cancelled"]);
}
if(array_key_exists("status", $this->get)) {
$status_code = $this->get["status"];
if($status_code < 899 || $status_code > 999) {
return mfResponse::BadRequest(["message" => "Status code out of bounds"]);
}
$status = PreorderstatusModel::getFirst(["code" => $status_code]);
if(!$status) {
return mfResponse::BadRequest(["message" => "Invalid Status code"]);
}
} else {
//910 - Cancelled (ohne weitere Begründung)
$status = PreorderstatusModel::getFirst(["code" => TT_PREORDER_DEFAULT_CANCEL_STATUSCODE]);
if(!$status) {
return mfResponse::InternalServerError();
}
}
// set cancel_date and canceller
/*$preorder->cancel_request = date('U');
$preorder->cancel_request_by = $this->me->id;
$preorder->cancel_approved = $this->me->id;
$preorder->deleted = date('U');
$preorder->deleted_by = $this->me->id;*/
$preorder->status_id = $status->id;
$preorder->edit_by = $this->me->id;
if(!$preorder->save()) {
return mfResponse::InternalServerError();
}
return mfResponse::Ok(['message' => "Order successfully canceled"]);
}
protected function submitPreorder() {
if($this->me->is("Preorderreadonly")) return \mfResponse::Forbidden();
//var_dump($this->post);exit;
if(!$this->campaigns) {
$this->log->debug("disallowed request because no campaign for apikey");
return mfResponse::Forbidden();
}
$type = $this->post['preorderType'];
if($type != "interest" && $type != "provision" && $type != "order" && $type != "reorder") {
return mfResponse::BadRequest(["message" => "Invalid preorderType"]);
}
$connection_type = null;
switch($this->post['connectionType']) {
case "single-dwelling":
$connection_type = "single-dwelling";
break;
case "multi-dwelling":
$connection_type = "multi-dwelling";
break;
case "apartment-building":
$connection_type = "apartment-building";
break;
case "apartment":
$connection_type = "apartment";
break;
case "business":
$connection_type = "business";
break;
default:
if($this->require_connectiontype) {
return mfResponse::BadRequest(["message" => "Invalid connectionType"]);
}
}
if(!array_key_exists("address", $this->post)) {
return mfResponse::BadRequest(['message' => "address missing"]);
}
if(!array_key_exists("customer", $this->post)) {
return mfResponse::BadRequest(['message' => "customer data missing"]);
}
$request_oaid = false;
$request_oaid_hausnummer = false;
$request_oaid_unit = false;
if(property_exists($this->post['address'], "oaid")) {
$request_oaid = trim($this->post['address']->oaid);
$m = [];
if($request_oaid && preg_match('/^([a-z]{2}-\d+-[0-9a-f]+)(:?\.(\d+))?/i', $request_oaid, $m)) {
if(array_key_exists(1, $m)) {
$request_oaid_hausnummer = $m[1];
}
if(array_key_exists(2, $m)) {
$request_oaid_unit = "$request_oaid_hausnummer" . $m[2];
}
} elseif(strlen($request_oaid) == 8) {
$request_oaid_hausnummer = $request_oaid;
$request_oaid_unit = $request_oaid;
}
}
$is_additional_order = false;
if(array_key_exists("isAdditionalOrder", $this->post) && $this->post['isAdditionalOrder']) {
$is_additional_order = true;
}
/************************************************************
* check address
*/
//var_dump($request_oaid_unit);exit;
if(!$request_oaid_hausnummer) {
if(!property_exists($this->post['address'], "street") || !$this->post['address']->street ||
!property_exists($this->post['address'], "housenumber") || !$this->post['address']->housenumber ||
!property_exists($this->post['address'], "zip") || !$this->post['address']->zip ||
!property_exists($this->post['address'], "city") || !$this->post['address']->city
) {
return mfResponse::BadRequest(['message' => "Mandatory address fields missing"]);
}
}
$shipping_address = "customer";
if(property_exists($this->post['address'], "is_shipping") && $this->post['address']->is_shipping) {
$shipping_address = "address";
}
$address_search = [];
$address_search_fields = [
'street' => 'strasse',
'housenumber' => "hausnummer",
'zip' => "plz"
];
if($this->district_is_city) {
$address_search_fields['city'] = "ortschaft";
} else {
$address_search_fields['city'] = "gemeinde";
}
foreach($address_search_fields as $key => $field_name) {
if(property_exists($this->post['address'], $key)) {
$address_search[$field_name] = $this->db()->escape(trim($this->post['address']->$key));
}
}
if(property_exists($this->post['address'], "stiege") && trim($this->post['address']->stiege)) {
$address_search["hausnummer_stiege"] = $this->db()->escape(trim($this->post['address']->stiege));
} else {
$address_search["hausnummer_stiege"] = null;
}
$zusatz = false;
if($this->hausnummer_add_zusatz) {
$m = [];
if(preg_match('/^(.*) \((.+)\)$/', trim($address_search['hausnummer']), $m)) {
$address_search['hausnummer'] = $this->db()->escape($m[1]);
$zusatz = $m[2];
}
}
$unit_search = [];
foreach(['block', 'stock', 'tuer', 'unit_string'] as $key) {
if(property_exists($this->post['address'], $key) && trim($this->post['address']->$key)) {
$unit_search[$key] = trim($this->post['address']->$key);
}
}
// ignore unit_string if the specific fields were provided
if($unit_search['block'] || $unit_search['stock'] || $unit_search['tuer']) {
unset($unit_search['unit_string']);
}
if($zusatz) {
$unit_search['zusatz'] = $zusatz;
}
/*
* check customer
*/
$customer = $this->post['customer'];
if(!property_exists($customer, "firstname") || !$customer->firstname ||
!property_exists($customer, "lastname") || !$customer->lastname ||
!property_exists($customer, "street") || !$customer->street ||
!property_exists($customer, "zip") || !$customer->zip ||
!property_exists($customer, "city") || !$customer->city
) {
return mfResponse::BadRequest(['message' => "Mandatory customer fields missing"]);
}
/**************************************************************
* search address in AddressDB
*/
if($request_oaid_hausnummer) {
$where = "oaid='$request_oaid_hausnummer'";
if(count($this->filter_salescluster_ids)) {
$where .= " AND netzgebiet_id IN (" . implode(',', $this->filter_salescluster_ids) . ")";
}
$res = $this->db()->select("view_hausnummer", "*", $where);
if(!$this->db()->num_rows($res)) {
// search for oaid in wohneinheit
$hausnummer_unit = ADBWohneinheitModel::getFirst(["oaid" => $request_oaid_hausnummer]);
if($hausnummer_unit) {
$hausnummer_id = $hausnummer_unit->hausnummer_id;
$where = "hausnummer_id=$hausnummer_id";
if(count($this->filter_salescluster_ids)) {
$where .= " AND netzgebiet_id IN (" . implode(',', $this->filter_salescluster_ids) . ")";
}
$res = $this->db()->select("view_hausnummer", "*", $where);
}
}
if(!$this->db()->num_rows($res)) {
return mfResponse::NotFound(["message" => "OAID not found"]);
}
$address = $this->db()->fetch_object($res);
} else {
$where = "1=1 ";
foreach($address_search as $field => $value) {
if($field == "ortschaft" || $field == "gemeinde") continue;
if($field == "hausnummer_stiege" && !$value) {
$where .= " AND (`hausnummer_stiege` = '' OR hausnummer_stiege IS NULL)";
continue;
}
$where .= " AND `$field` = '$value'";
}
// filter salesclusters
if(count($this->filter_salescluster_ids)) {
$where .= " AND netzgebiet_id IN (" . implode(',', $this->filter_salescluster_ids) . ")";
}
$sql = "SELECT * FROM view_hausnummer WHERE $where";
//$this->log->debug($sql);
$res = $this->db()->query($sql);
// If not found, try with Ortschaft in front of strasse (liezen gwr issue)
if(!$this->db()->num_rows($res)) {
$where = "1=1 ";
foreach($address_search as $field => $value) {
if($field == "ortschaft" || $field == "gemeinde") continue;
if($field == "hausnummer_stiege" && !$value) {
$where .= " AND (`hausnummer_stiege` = '' OR hausnummer_stiege IS NULL)";
continue;
}
if($field == "strasse") {
$prefix = ($address_search['ortschaft']) ? $address_search['ortschaft'] : $address_search['gemeinde'];
if(strpos($value, "$prefix ") === 0) {
$str = substr($value, strlen($prefix) + 1);
} else {
$str = $value;
}
$where .= " AND `strasse` = '$str'";
} else {
$where .= " AND `$field` = '$value'";
}
}
// filter salesclusters
if(count($this->filter_salescluster_ids)) {
$where .= " AND netzgebiet_id IN (" . implode(',', $this->filter_salescluster_ids) . ")";
}
$sql = "SELECT * FROM view_hausnummer WHERE $where";
//$this->log->debug($sql);
$res = $this->db()->query($sql);
if(!$this->db()->num_rows($res)) {
return mfResponse::NotFound(['message' => "Adresse nicht gefunden"]);
}
}
$address = $this->db()->fetch_object($res);
}
//var_dump($address);exit;
/* **************************************************************
* search wohneinheit
*/
$update_unit = false;
$assign_unit = false;
$where = "1=1 ";
$unit = false;
// We ignore Stock when matching units
$unit_search_count_without_stock = count($unit_search);
if(array_key_exists("stock", $unit_search) && $unit_search['stock']) {
$unit_search_count_without_stock--;
}
if($request_oaid_unit) {
$where = "wohneinheit_oaid='$request_oaid_unit'";
if(count($this->filter_salescluster_ids)) {
$where .= " AND netzgebiet_id IN (" . implode(',', $this->filter_salescluster_ids) . ")";
}
//$unit = ADBWohneinheitModel::getFirst(["oaid" => $request_oaid_unit]);
$res = $this->db()->select("view_wohneinheit", "*", $where);
if($this->db()->num_rows($res)) {
$unit = $this->db()->fetch_object($res);
}
if(!$unit) {
return mfResponse::NotFound(["message" => "Wohneinheit nicht gefunden"]);
}
if(count($unit_search)) {
$update_unit = true;
}
} elseif($unit_search_count_without_stock > 0) {
//var_dump($unit_search);exit;
if(array_key_exists("unit_string", $unit_search)) {
$where .= " AND bezeichner LIKE '" . $unit_search['unit_string'] . "'";
} else {
foreach($unit_search as $field => $value) {
if($field == "stock") continue; // only check for block, stiege and tuer
$where .= " AND `$field` = '$value'";
}
}
// filter salesclusters
if(count($this->filter_salescluster_ids)) {
$where .= " AND netzgebiet_id IN (" . implode(',', $this->filter_salescluster_ids) . ")";
}
$sql = "SELECT * FROM view_wohneinheit WHERE $where AND hausnummer_id=" . $address->hausnummer_id;
//$this->log->debug($sql);
$res = $this->db()->query($sql);
if($this->db()->num_rows($res)) {
$unit = $this->db()->fetch_object($res);
} else {
$update_unit = true;
}
} else {
// if all unit values are empty try to find the unit with all empty values
// failure is not an error, but must be checked by a human at some point
$where = "hausnummer_id=" . $address->hausnummer_id . " AND (block = '' OR block IS NULL) AND (stock = '' OR stock IS NULL) AND (tuer = '' OR tuer IS NULL) AND (bezeichner = '' OR bezeichner IS NULL)";
if($zusatz) {
$where .= " AND zusatz='$zusatz'";
} else {
$where .= " AND (zusatz = '' OR zusatz IS NULL)";
}
// filter salesclusters
if(count($this->filter_salescluster_ids)) {
$where .= " AND netzgebiet_id IN (" . implode(',', $this->filter_salescluster_ids) . ")";
}
$sql = "SELECT * FROM view_wohneinheit WHERE $where";
//$this->log->debug($sql);
$res = $this->db()->query($sql);
$found_units_count = $this->db()->num_rows($res);
if($found_units_count) {
// check if unit has active preorder already and try next unit
$existing_preorder = false;
while($unit = $this->db()->fetch_object($res)) {
// check if there is an existing preorder
$existing_preorder = PreorderModel::getFirstActive(['adb_wohneinheit_id' => $unit->wohneinheit_id]);
if(!$existing_preorder) {
break;
}
}
if($existing_preorder && $this->exist_is_error && !$is_additional_order) {
return mfResponse::Forbidden(['message' => "Für diese Wohneinheit liegt bereits eine Bestellung vor"]);
}
} else {
// XXX - If there are no units without unit data maybe try finding a fitting unit without an order
//$assign_unit = true;
}
}
/*
* check if there is an existing preorder for this unit already
*/
if($unit && $unit->wohneinheit_id) {
$existing_preorder = PreorderModel::getFirstActive(['adb_wohneinheit_id' => $unit->wohneinheit_id]);
if($existing_preorder) {
if($this->exist_is_error && !$is_additional_order) {
return mfResponse::Forbidden(['message' => "Für diese Wohneinheit liegt bereits eine Bestellung vor"]);
}
}
}
$address_info = $this->db()->escape(trim($this->post['address_info']));
// get correct campaign by salescluster
if(!array_key_exists($address->netzgebiet_id, $this->campaigns_by_scluster)) {
return mfResponse::NotFound(['message' => "Adresse nicht gefunden"]);
}
$campaign_id = $this->campaigns_by_scluster[$address->netzgebiet_id];
$this->campaign = new Preordercampaign($campaign_id);
if(!$this->campaign->id) {
$this->log->debug("=================================================================");
$this->log->debug(__METHOD__ . ": Campaign not found");
$this->log->debug(print_r($address, true));
$this->log->debug(print_r($this->campaigns_by_scluster, true));
$this->log->debug("campaign id: $campaign_id");
$this->log->debug(print_r($this->campaign, true));
$this->log->debug("=================================================================");
return mfResponse::InternalServerError(['message' => "Ein Interner Fehler ist aufgetreten"]);
}
if($this->campaign->from > date('U') || $this->campaign->to < date('U')) {
return mfResponse::Forbidden(['message' => "Bestellung in diesem Netzgebiet/Cluster nicht erlaubt"]);
}
// check for allowed PreorderType in address
$allowed_freigabe = json_decode($address->freigabe);
if(!is_array($allowed_freigabe) || !count($allowed_freigabe)) {
return mfResponse::Forbidden(['message' => "Adresse (noch) nicht bestellbar"]);
}
if(!in_array($type, $allowed_freigabe)) {
return mfResponse::Forbidden(['message' => "Adresse (noch) nicht bestellbar"]);
}
// check for allowed PreorderType in campaign
$allowed_campaigntypes = $this->campaign->types;
if(!is_array($allowed_campaigntypes) || !count($allowed_campaigntypes)) {
return mfResponse::Forbidden(['message' => "PreorderType not allowed"]);
}
if(!array_key_exists($type, $allowed_campaigntypes)) {
return mfResponse::Forbidden(['message' => "PreorderType not allowed"]);
}
// if FCP is on blacklist, don't allow order
if($address->rimo_fcp_name && is_array($this->campaign->banned_fcps) && count($this->campaign->banned_fcps) && in_array($address->rimo_fcp_name, $this->campaign->banned_fcps)) {
return mfResponse::Forbidden(['message' => "PreorderType not allowed"]);
}
/*
* build fields
*/
$preorder_data = [];
$preorder_data['preordercampaign_id'] = $campaign_id;
$preorder_data['type'] = $type;
$preorder_data['connection_type'] = $connection_type;
$preorder_data['connection_count'] = (intval($this->post['connectionCount'])) ? intval($this->post['connectionCount']) : 1;
$preorder_data['submit_type'] = "api";
if($this->request_json) {
$preorder_data['submit_request'] = $this->request_json;
}
$preorder_data['adb_hausnummer_id'] = $address->hausnummer_id;
$preorder_data['partner_id'] = $this->me->address_id;
if($unit) {
$preorder_data['adb_wohneinheit_id'] = $unit->wohneinheit_id;
$preorder_data['oaid'] = $unit->wohneinheit_oaid;
}
if($address_info) {
$preorder_data['address_info'] = $address_info;
}
if(property_exists($this->post['address'], "district") && $this->post['address']->district) {
$preorder_data['address_district'] = $this->post['address']->district;
}
if($this->post['acceptAgb'] === true) {
$preorder_data['accept_agb'] = 1;
}
if($this->post['acceptDsgvo'] === true) {
$preorder_data['accept_dsgvo'] = 1;
}
if($this->post['acceptMarketing'] === true) {
$preorder_data['accept_marketing'] = 1;
}
if($this->post['acceptWithdrawal'] === true) {
$preorder_data['accept_withdrawal'] = 1;
}
if($this->post['acceptDigging'] === true) {
$preorder_data['accept_digging'] = 1;
}
if(trim($this->post['orderDate'])) {
try {
$order_date = new DateTime(trim($this->post['orderDate']));
$order_date->setTime(4, 0, 0);
$order_date->setTimezone(new DateTimeZone('Europe/Vienna'));
// cannot be older than 14 days
$now = new DateTime();
$now->setTime(4, 0, 0);
$now->setTimezone(new DateTimeZone('Europe/Vienna'));
$diff = $now->diff($order_date);
if($diff->days > 14) {
return mfResponse::BadRequest(["message" => "orderDate cannot be older than 14 days"]);
}
$preorder_data['order_date'] = $order_date->getTimestamp();
} catch(Exception $e) {
$this->log->debug(__METHOD__.": Error parsing orderDate: " . $e->getMessage());
// ignore
}
/*$order_date = trim($this->post['orderDate']);
$m = [];
if(preg_match('/^(\d\d\d\d)-(\d\d)-(\d\d)$/', $order_date, $m)) {
$preorder_data['order_date'] = mktime(4, 0, 0, $m[2], $m[3], $m[1]);
}*/
}
if($is_additional_order) {
$preorder_data['is_additional_order'] = 1;
} else {
$preorder_data['is_additional_order'] = 0;
}
$preorder_data['extref'] = (trim($this->post['extref'])) ? trim($this->post['extref']) : null;
$preorder_data['technology'] = (trim($this->post['technology'])) ? trim($this->post['technology']) : null;
/*
* patchposition now comes from RIMO
$preorder_data['equipment_name'] = (trim($this->post['equipment_name'])) ? trim($this->post['equipment_name']) : null;
$preorder_data['equipment_port'] = (trim($this->post['equipment_port'])) ? trim($this->post['equipment_port']) : null;*/
/*
* setup price
*/
$product = false;
if($type == "provision") {
$product = $this->campaign->setup_products['provision'][0];
}
if($type == "order") {
$product = $this->campaign->setup_products['activation'][0];
}
if($type == "reorder") {
$product = $this->campaign->setup_products['reorder'][0];
}
if($product) {
$preorder_data['setup_product_id'] = $product->id;
$preorder_data['price_setup'] = $product->price_setup;
if($connection_type == "multi-dwelling") {
if($preorder_data['connection_count'] == 2) {
//$preorder_data['price_setup'] = round($product->price_setup * 2 - (($product->price_setup * 2) / 100) * TT_PREORDER_DISCOUNT_2);
$preorder_data['price_setup'] = ($product->attributes["presales_setup_price2"]->value) ? $product->attributes["presales_setup_price2"]->value : $product->price_setup;
}
if($connection_type == "multi-dwelling" && $preorder_data['connection_count'] == 3) {
//$preorder_data['price_setup'] = round($product->price_setup * 3 - (($product->price_setup * 3) / 100) * TT_PREORDER_DISCOUNT_3);
$preorder_data['price_setup'] = ($product->attributes["presales_setup_price3"]->value) ? $product->attributes["presales_setup_price3"]->value : $product->price_setup;
}
}
if($connection_type == "apartment" && $type == "order") {
//$preorder_data['price_setup'] = round($product->price_setup - (($product->price_setup) / 100) * TT_PREORDER_DISCOUNT_APART);
$preorder_data['price_setup'] = ($product->attributes["presales_setup_price4"]->value) ? $product->attributes["presales_setup_price4"]->value : $product->price_setup;
}
if($connection_type == "business") {
//$preorder_data['price_setup'] = round($product->price_setup - (($product->price_setup) / 100) * TT_PREORDER_DISCOUNT_BUSINESS);
$preorder_data['price_setup'] = ($product->attributes["presales_setup_price_business"]->value) ? $product->attributes["presales_setup_price_business"]->value : $product->price_setup;
}
if($preorder_data['price_setup']) {
$preorder_data['price_setup'] = str_replace(',', '.', $preorder_data['price_setup']);
}
}
/*
* get customer data
*/
foreach(['company', 'uid', 'firstname', 'lastname', 'street', 'housenumber', 'zip', 'city', 'phone', 'email', 'block', 'stiege', 'stock', 'tuer', 'unit_string'] as $key) {
if(property_exists($customer, $key)) {
$preorder_data[$key] = (trim($customer->$key)) ? trim($customer->$key) : null;
}
}
/*
* check optional required fields
*/
if(is_array($this->campaign->required_fields) && count($this->campaign->required_fields)) {
if(in_array("contact_type", $this->campaign->required_fields)) {
if($customer->type == "tenant") {
$preorder_data['contact_type'] = "tenant";
} elseif($customer->type == "owner") {
$preorder_data['contact_type'] = "owner";
} else {
return mfResponse::BadRequest(["message" => "customer type must be 'tenant' or 'owner'"]);
}
}
}
/*
* check for addon services
*/
if(array_key_exists("addonServices", $this->post)) {
$addon_services = $this->post['addonServices'];
if($addon_services) {
$preorder_data['addon_services'] = json_encode($addon_services);
}
}
/*
* check for addon data
*/
if(array_key_exists("additionalData", $this->post)) {
$addon_data = $this->post['additionalData'];
if($addon_data) {
$preorder_data['addon_data'] = json_encode($addon_data);
}
}
//var_dump($this->allow_unit_update, $update_unit);exit;
/**************************************************
* update wohneinheit if allowed
* and unit search data was submitted
*/
$unit_changed = false;
if($this->allow_unit_update && $update_unit) {
//var_dump($unit_search);
//var_dump($unit);
//exit;
if($request_oaid_unit) {
// if unit oaid is set, we know our unit already
$unit = new ADBWohneinheit($unit->wohneinheit_id);
if($unit->block || $unit->stiege || $unit->stock || $unit->tuer) {
foreach(["block", "stiege", "stock", "tuer"] as $type) {
if($unit->$type && $unit->$type != $unit_search[$type]) {
return mfResponse::Forbidden(['message' => "Überschreiben von Wohneinheitsdaten nicht erlaubt"]);
}
}
}
} else {
// else get available units with no unit data, so we can update it
$exclude_wohneinheit_ids = [];
$preorders_in_hausnummer = PreorderModel::searchActive(['adb_hausnummer_id' => $address->hausnummer_id]);
if(count($preorders_in_hausnummer)) {
foreach($preorders_in_hausnummer as $pih) {
if($pih->adb_wohneinheit_id) {
$exclude_wohneinheit_ids[] = $pih->adb_wohneinheit_id;
}
}
}
// get units excluding unavailable units
$where = "hausnummer_id=" . $address->hausnummer_id;
$where .= " AND ( block = '' OR block IS NULL)";
$where .= " AND ( stiege = '' OR stiege IS NULL)";
$where .= " AND ( stock = '' OR stock IS NULL)";
$where .= " AND ( tuer = '' OR tuer IS NULL)";
$where .= " AND ( bezeichner = '' OR bezeichner IS NULL)";
if(count($exclude_wohneinheit_ids)) {
$where .= " AND wohneinheit_id NOT IN (" . implode(",", $exclude_wohneinheit_ids) . ")";
}
$sql = "SELECT * FROM view_wohneinheit WHERE $where";
//$this->log->debug($sql);
$res = $this->db()->query($sql);
if(!$this->db()->num_rows($res)) {
return mfResponse::Forbidden(['message' => "Keine Wohneinheiten verfügbar"]);
}
$unit_row = $this->db()->fetch_object($res);
$unit = new ADBWohneinheit($unit_row->wohneinheit_id);
}
if(!$unit->id) {
return mfResponse::InternalServerError(['message' => "unit not found"]);
}
//echo "blah";exit;
$change_note_data = [];
foreach(['block', 'stiege', 'stock', 'tuer', 'bezeichner'] as $unit_address_part) {
if($unit_search[$unit_address_part] && $unit_search[$unit_address_part] != $unit->$unit_address_part) {
$unit->$unit_address_part = $unit_search[$unit_address_part];
$unit_changed = true;
$change_note_data[] = [
'field' => $unit_address_part,
'from' => $unit->_old_data->$unit_address_part,
'to' => $unit_search[$unit_address_part]
];
}
}
if($unit_changed) {
$change_note_text = ($unit->note) ? $unit->note : "";
$change_note_text .= date("Y-m-d H:i:s") . ": ";
foreach($change_note_data as $cn) {
$field = $cn['field'];
$from = ($cn['from'] === null) ? "NULL" : "'" . $cn['from'] . "'";
$to = ($cn['to'] === null) ? "NULL" : "'" . $cn['to'] . "'";
$change_note_text .= "$field from $from to $to; ";
}
$change_note_text .= "\n";
$unit->note = $change_note_text;
$unit->startTransaction();
$unit->save();
}
//var_dump($unit);exit;
$preorder_data['adb_wohneinheit_id'] = $unit->id;
$preorder_data['oaid'] = $unit->oaid;
}
// assign next wohneinheit if no unit search data was submitted
/*
if($this->allow_unit_update && $assign_unit) {
var_dump($unit_search);
var_dump($unit);
exit;
}*/
/*
* create preorder record
*/
$preorder = PreorderModel::create($preorder_data);
$preorder->createUcode();
/*
* set status based on building or unit status
*/
$new_status = false;
if($preorder->adb_wohneinheit_id) {
$new_status = PreorderstatusModel::getFirst(["code" => $preorder->adb_wohneinheit->status->code]);
if($preorder->adb_hausnummer->status->code > $preorder->adb_wohneinheit->status->code) {
$new_status = PreorderstatusModel::getFirst(["code" => $preorder->adb_hausnummer->status->code]);
}
} elseif($preorder->adb_hausnummer_id) {
$new_status = PreorderstatusModel::getFirst(["code" => $preorder->adb_hausnummer->status->code]);
}
if($new_status) {
$preorder->status_id = $new_status->id;
} else {
$preorder->status_id = 1;
}
try {
$preorder_id = $preorder->save();
} catch(\Exception $e) {
$err_id = uniqid('err');
$this->log->error(__METHOD__ . ": [$err_id] Caught Exception while saving Preorder: " . $e->getMessage() . "\n" . $e->getTraceAsString());
if($unit_changed) $unit->rollbackTransaction();
return mfResponse::InternalServerError(["error_id" => $err_id, "message" => "error id: $err_id"]);
}
if(!$preorder_id || !$preorder->ucode) {
$err_id = uniqid('err');
$this->log->error(__METHOD__ . ": [$err_id] Error saving Preorder");
if($unit_changed) $unit->rollbackTransaction();
return mfResponse::InternalServerError();
}
if($unit_changed) $unit->commitTransaction();
$return = ["code" => $preorder->ucode];
if($preorder->oaid) {
$return['oaid'] = $preorder->oaid;
}
if($preorder->extref) {
$return['extref'] = $preorder->extref;
}
if($preorder->order_date) {
$return['orderDate'] = date("Y-m-d", $preorder->order_date);
}
$return['status'] = $preorder->status->getApiArray();
foreach($preorder->statusflags as $sflag) {
$return['status']['flags'][] = [
"code" => (int)$sflag->code,
"text" => $sflag->name,
"value" => ($sflag->value->value == 1)
];
}
//var_dump($return['status']);exit;
if($addon_data) {
$return["additionalData"] = $addon_data;
}
$return['created'] = date("c", $preorder->create);
$return['created_ts'] = (int)$preorder->create;
$return['updated'] = date("c", $preorder->edit);
$return['updated_ts'] = (int)$preorder->edit;
return mfResponse::Ok($return);
}
}