diff --git a/application/Api/v1/PreorderApicontroller.php b/application/Api/v1/PreorderApicontroller.php index 390b15758..d0a9b308c 100644 --- a/application/Api/v1/PreorderApicontroller.php +++ b/application/Api/v1/PreorderApicontroller.php @@ -21,6 +21,7 @@ class PreorderApicontroller extends mfBaseApicontroller { $this->addRoute("/preorder", "submitPreorder", "POST"); $this->addRoute("/preorder/:code", "getPreorder", "GET"); + $this->addRoute("/preorder/:code", "cancelPreorder", "DELETE"); $this->allowMissingOrigin = true; } @@ -103,6 +104,45 @@ class PreorderApicontroller extends mfBaseApicontroller { } + 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"]); + } + } + + // 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; + if(!$preorder->save()) { + return mfResponse::InternalServerError(); + } + + return mfResponse::Ok(['message' => "Cancellation request submited"]); + + } + protected function submitPreorder() { //var_dump($this->post);exit; if(!$this->campaigns) { @@ -147,7 +187,12 @@ class PreorderApicontroller extends mfBaseApicontroller { return mfResponse::BadRequest(['message' => "customer data missing"]); } - /* + $is_additional_order = false; + if(array_key_exists("isAdditionalOrder", $this->post) && $this->post['isAdditionalOrder']) { + $is_additional_order = true; + } + + /************************************************************ * check address */ if(!property_exists($this->post['address'],"street") || !$this->post['address']->street || @@ -191,7 +236,7 @@ class PreorderApicontroller extends mfBaseApicontroller { } $unit_search = []; - foreach(['block','stiege','stock','tuer'] as $key) { + foreach(['block','stiege','stock','tuer','unit_id'] as $key) { if(property_exists($this->post['address'], $key) && trim($this->post['address']->$key)) { $unit_search[$key] = trim($this->post['address']->$key); } @@ -214,7 +259,7 @@ class PreorderApicontroller extends mfBaseApicontroller { return mfResponse::BadRequest(['message' => "Mandatory customer fields missing"]); } - /* + /************************************************************** * search address in AddressDB */ $where = "1=1 "; @@ -237,7 +282,7 @@ class PreorderApicontroller extends mfBaseApicontroller { $address = $this->db()->fetch_object($res); //var_dump($address);exit; - /* + /* ************************************************************** * search wohneinheit */ $update_unit = false; @@ -246,11 +291,14 @@ class PreorderApicontroller extends mfBaseApicontroller { $unit = false; if(count($unit_search)) { //var_dump($unit_search);exit; - foreach($unit_search as $field => $value) { - if($field == "stock") continue; // only check for block, stiege and tuer - $where .= " AND `$field` = '$value'"; + if(array_key_exists("unit_id", $unit_search)) { + $where .= " AND bezeichner LIKE '".$unit_search['unit_id']."'"; + } 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).")"; @@ -267,7 +315,7 @@ class PreorderApicontroller extends mfBaseApicontroller { } 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)"; + $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 NLL)"; if($zusatz) { $where .= " AND zusatz='$zusatz'"; } else { @@ -289,11 +337,11 @@ class PreorderApicontroller extends mfBaseApicontroller { } } - if($this->exist_is_error) { + if($this->exist_is_error && !$is_additional_order) { /* * check if there is an existing preorder for this unit already */ - if($unit) { + if($unit && $unit->wohneinheit_id) { $existing_preorder = PreorderModel::getFirst(['adb_wohneinheit_id' => $unit->wohneinheit_id]); if($existing_preorder) { return mfResponse::Forbidden(['message' => "Für diese Wohneinheit liegt bereits eine Bestellung vor"]); @@ -355,6 +403,14 @@ class PreorderApicontroller extends mfBaseApicontroller { $preorder_data['accept_withdrawal'] = 1; } + if($is_additional_order) { + $preorder_data['is_additional_order'] = 1; + } else { + $preorder_data['is_additional_order'] = 0; + } + $preorder_data['technology'] = ($this->post['technology']) ? $this->post['technology'] : null; + $preorder_data['patchposition'] = ($this->post['patchposition']) ? $this->post['patchposition'] : null; + /* * setup price */ @@ -442,8 +498,10 @@ class PreorderApicontroller extends mfBaseApicontroller { //var_dump($this->allow_unit_update, $update_unit);exit; - // update wohneinheit if allowed - // and unit search data was submitted + /************************************************** + * update wohneinheit if allowed + * and unit search data was submitted + */ $unit_changed = false; @@ -465,10 +523,11 @@ class PreorderApicontroller extends mfBaseApicontroller { } // get units excluding unavailable units $where = "hausnummer_id=".$address->hausnummer_id; - $where .= " AND block IS NULL"; - $where .= " AND stiege IS NULL"; - $where .= " AND stock IS NULL"; - $where .= " AND tuer IS NULL"; + $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).")"; @@ -488,7 +547,7 @@ class PreorderApicontroller extends mfBaseApicontroller { //echo "blah";exit; $change_note_data = []; - foreach(['block','stiege','stock','tuer'] as $unit_address_part) { + foreach(['block','stiege','stock','tuer','bezeichner'] as $unit_address_part) { if($unit_search[$unit_address_part]) { $unit->$unit_address_part = $unit_search[$unit_address_part]; $unit_changed = true; diff --git a/application/Preorder/Preorder.php b/application/Preorder/Preorder.php index a85c1a0f7..6ff03d006 100644 --- a/application/Preorder/Preorder.php +++ b/application/Preorder/Preorder.php @@ -73,7 +73,7 @@ class Preorder extends mfBaseModel { $customer['firstnam'] = ($this->firstname) ? $this->firstname : null; $customer['lastname'] = ($this->lastname) ? $this->lastname : null; $customer['street'] = ($this->street) ? $this->street : null; - $customer['housenumber'] = ($this->hausnummer) ? $this->housenumber : null; + $customer['housenumber'] = ($this->housenumber) ? $this->housenumber : null; $customer['zip'] = ($this->zip) ? $this->zip : null; $customer['city'] = ($this->city) ? $this->city : null; $customer['block'] = ($this->block) ? $this->block : null; diff --git a/application/Preorder/PreorderModel.php b/application/Preorder/PreorderModel.php index 0ad92be16..caee40441 100644 --- a/application/Preorder/PreorderModel.php +++ b/application/Preorder/PreorderModel.php @@ -43,11 +43,19 @@ class PreorderModel { public $city; public $phone; public $email; + public $technology; + public $patchposition; + public $is_additional_order; public $shipping_address; public $addon_services; public $addon_data; public $submit_type; public $submit_request; + + public $cancel_request; + public $cancel_request_by; + public $cancel_approved; + public $cancel_approved_by; public $deleted; public $deleted_by; @@ -104,11 +112,26 @@ class PreorderModel { } - public static function getFirst($filter = false) { + public static function getFirst($filter = false, $order = false) { $db = FronkDB::singleton(); $where = self::getSqlFilter($filter); - $res = $db->select("Preorder", "*", "$where ORDER BY lastname, firstname"); + + $orderBy = "lastname, firstname"; + if($order) $orderBy = $order; + + $sql = "SELECT tt_preorder.* FROM `".FRONKDB_DBNAME."`.Preorder tt_preorder + LEFT JOIN `".FRONKDB_DBNAME."`.Preorderstatus tt_preorderstatus ON (tt_preorder.status_id = tt_preorderstatus.id) + LEFT JOIN `".ADDRESSDB_DBNAME."`.view_hausnummer as adb_hausnummer ON (tt_preorder.adb_hausnummer_id = adb_hausnummer.hausnummer_id) + WHERE $where + ORDER BY $orderBy + LIMIT 1 + "; + + mfLoghandler::singleton()->debug($sql); + + $res = $db->query($sql); + if($db->num_rows($res)) { $data = $db->fetch_object($res); $item = new Preorder($data); @@ -212,6 +235,7 @@ class PreorderModel { $where = self::getSqlFilter($filter); $sql = "SELECT tt_preorder.* FROM `".FRONKDB_DBNAME."`.Preorder tt_preorder + LEFT JOIN `".FRONKDB_DBNAME."`.Preorderstatus tt_preorderstatus ON (tt_preorder.status_id = tt_preorderstatus.id) LEFT JOIN `".ADDRESSDB_DBNAME."`.view_hausnummer as adb_hausnummer ON (tt_preorder.adb_hausnummer_id = adb_hausnummer.hausnummer_id) WHERE $where ORDER BY lastname, firstname @@ -248,6 +272,57 @@ class PreorderModel { } } + if(array_key_exists("partner_id", $filter)) { + $partner_id = $filter['partner_id']; + if(is_numeric($partner_id)) { + $where .= " AND partner_id=$partner_id"; + } + } + + if(array_key_exists("status_id", $filter)) { + $status_id = $filter['status_id']; + if(is_numeric($status_id)) { + $where .= " AND status_id=$status_id"; + } + } + + if(array_key_exists("status_id", $filter)) { + $status_id = $filter['>status_id']; + if(is_numeric($status_id)) { + $where .= " AND status_id > $status_id"; + } + } + + + if(array_key_exists("status_code", $filter)) { + $status_code = $filter['status_code']; + if(is_numeric($status_code)) { + $where .= " AND tt_preorderstatus.code=$status_code"; + } + } + + if(array_key_exists("status_code", $filter)) { + $status_code = $filter['>status_code']; + if(is_numeric($status_code)) { + $where .= " AND tt_preorderstatus.code > $status_code"; + } + } + + if(array_key_exists("preordercampaign_id", $filter)) { $preordercampaign_id = $filter['preordercampaign_id']; if(is_numeric($preordercampaign_id)) { @@ -305,10 +380,16 @@ class PreorderModel { if(array_key_exists("ucode", $filter)) { $ucode = FronkDB::singleton()->escape($filter['ucode']); if($ucode) { - $where .= " AND ucode like '%$ucode%'"; + $where .= " AND ucode = '$ucode'"; } } + if(array_key_exists("oaid", $filter)) { + $oaid = FronkDB::singleton()->escape($filter['oaid']); + if($oaid) { + $where .= " AND tt_preorder.oaid = '$oaid'"; + } + } if(array_key_exists("gemeinde", $filter)) { $gemeinde = FronkDB::singleton()->escape($filter['gemeinde']); diff --git a/application/Preordercampaign/PreordercampaignModel.php b/application/Preordercampaign/PreordercampaignModel.php index 4b4f18976..b742e7331 100644 --- a/application/Preordercampaign/PreordercampaignModel.php +++ b/application/Preordercampaign/PreordercampaignModel.php @@ -14,6 +14,8 @@ class PreordercampaignModel { public $district_is_city; public $hausnummer_add_zusatz; public $exist_is_error; + public $require_connectiontype; + public $allow_unit_update; public $note; public $create_by; diff --git a/public/docs/preorder-api.yaml b/public/docs/preorder-api.yaml index fc315143b..7b9d69cc6 100644 --- a/public/docs/preorder-api.yaml +++ b/public/docs/preorder-api.yaml @@ -356,10 +356,19 @@ paths: description: | Registriert eine (Vor-)bestellung. Bestellungsart wird mit `preorderType` definiert. - --- - Parameter `address`: Anschlussadresse. Soll Starterkit an Anschlussadresse gesendet werden, muss `address.is_shipping` auf true gestellt werden, bei false wird das Starterkit an Vertragsinhaber (`customer`) gesendet. + Handelt es sich um einen zusätzlichen Anschluss in der Wohneinheit muss der Paramerter `isAdditionalOrder` auf `true` gestellt werden, da sonst ein Fehler zurückgegeben wird. - Parameter `address_info`: **(Optional)** Zusätzliche Informationen zur Adresse + --- + + Parameter `address`: Anschlussadresse. + + Soll Starterkit an Anschlussadresse gesendet werden, muss `address.is_shipping` auf true gestellt werden, bei false wird das Starterkit an Vertragsinhaber (`customer`) gesendet. + + Wohneinheitsidentifikation (Block, Stiege, Stock, Tür) kann strukturiert mit jeweils einem eigenen Feld übergeben werden oder alle Wohneinheitsdaten in einem einzigen String (`unit_id`). + + --- + + Parameter `address_info`: **(Optional)** Zusätzliche Informationen zur Anschlusssdresse Parameter `customer`: Vertragsinhaber @@ -498,6 +507,7 @@ paths: | 260 | ONT picked up or shipped | ONT abgeholt oder versandt | | 300 | ONT installed | ONT in Betrieb | | 500 | Finished | Fertiggestellt | + | 899 | Cancelled | Storniert/Gekündigt | content: application/json: schema: @@ -787,6 +797,9 @@ components: street: type: string description: Straße Kunde + housenumber: + type: string + description: Hausnummer Kunde zip: type: string description: PLZ Kunde @@ -846,10 +859,16 @@ components: default: 1 description: Anzahl Anschlüsse bei mehreren Anschlüssen in Mehrfamilienhaus nullable: true + isAdditionalOrder: + type: bolean + default: false + description: wenn es sich um eine Zweitbestellung auf einer Wohneinheit handelt, muss `isAdditonalOrder` auf `true` gestellt werden, damit die Bestellung akzeptiert wird. + nullable: true technology: type: string default: gpon description: Bei Provider eingesetzte Technologie (optional, falls für Patchpunkt im POP nötig) + example: gpon nullable: true patchposition: type: string