db(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME); $this->addRoute("/preorder/open", "getOpenPreorders", "GET"); $this->addRoute("/preorder", "submitPreorder", "POST"); $this->addRoute("/preorder/:code", "getPreorder", "GET"); $this->addRoute("/preorder/:code", "cancelPreorder", "DELETE"); $this->allowMissingOrigin = true; } protected function authenticated() { 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) { 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; } } foreach(PreordercampaignOriginhostnameModel::search(['preordercampaign_id' => $campaign->id]) as $origin) { $this->addAllowedOrigin($origin->hostname); } } $this->allowed_preordertypes = array_unique($this->allowed_preordertypes); //var_dump($campaign, $this->allowed_origins);exit; } protected function getOpenPreorders() { $ts = $this->get['ts']; $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'); } } } // nicht auf cluster einschränken, sondern auf partner_id /* $preorder_search = []; if(count($this->filter_salescluster_ids)) { $preorder_search['netzgebiet_id'] = $this->filter_salescluster_ids; }*/ $preorder_search = []; $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['getApiArray(); } 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) { /* $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, ' 800]); if(!$preorder) { // try oan id $preorder = PreorderModel::getFirst(['oaid' => $code, 'partner_id' => $this->me->address_id, 'deleted' => 0, ' 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, ' 800]); if(!$preorder) { // try oan id $preorder = PreorderModel::getFirst(['oaid' => strtolower($code), 'partner_id' => $this->me->address_id, 'deleted' => 0, ' 800]); } if(!$preorder) { // try as extref $preorder = PreorderModel::getFirst(['extref' => $code, 'partner_id' => $this->me->address_id, 'deleted' => 0, ' 800]); } 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"]); } } // set cancel_date and canceller $preorder->cancel_request = date('U'); $preorder->cancel_request_by = $this->me->id; $preorder->status_id = 15; // 899 - Cancelled if(!$preorder->save()) { return mfResponse::InternalServerError(); } return mfResponse::Ok(['message' => "Cancellation request submited"]); } protected function submitPreorder() { //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]; } } } $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)); } } $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','stiege','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['stiege'] || $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)) { 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; $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)) { // try with Ortschaft in front of strasse (liezen gwr issue) $where = "1=1 "; foreach($address_search as $field => $value) { if($field == "ortschaft" || $field == "gemeinde") 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; $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 (stiege = '' OR stiege 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); if($this->db()->num_rows($res)) { $unit = $this->db()->fetch_object($res); } else { // XXX - If there are no units without unit data maybe try finding a fitting unit without an order //$assign_unit = true; } } if($this->exist_is_error && !$is_additional_order) { /* * check if there is an existing preorder for this unit already */ if($unit && $unit->wohneinheit_id) { $existing_preorder = PreorderModel::getFirst(['adb_wohneinheit_id' => $unit->wohneinheit_id, 'deleted' => 0]); if($existing_preorder) { 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->from > date('U') || $this->campaign->to < date('U')) { return mfResponse::Forbidden(['message' => "Bestellung in diesem Netzgebiet/Cluster nicht erlaubt"]); } /* * 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($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; $preorder_data['patchposition'] = (trim($this->post['patchposition'])) ? trim($this->post['patchposition']) : 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; } } /* * 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::search(['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(); //var_dump($preorder);exit; $preorder_id = $preorder->save(); if(!$preorder_id || !$preorder->ucode) { 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($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); } }