From 4e4c5a9c18e22c2be1de5d481b69095e68a6b8c0 Mon Sep 17 00:00:00 2001 From: Frank Schubert Date: Mon, 19 Jan 2026 16:29:22 +0100 Subject: [PATCH] Button to create Order from Preorder --- Layout/default/Order/Form.php | 15 +- Layout/default/Order/Index.php | 1 + .../Preorder/include/preorder-detail.php | 16 +- application/Order/OrderController.php | 14 +- application/OrderProduct/OrderProduct.php | 8 +- .../OrderProduct/OrderProductModel.php | 9 ++ application/Preorder/Preorder.php | 8 + application/Preorder/PreorderController.php | 151 ++++++++++++++++++ application/Product/ProductModel.php | 16 +- ...152525_order_product_add_preorder_data.php | 33 ++++ 10 files changed, 254 insertions(+), 17 deletions(-) create mode 100644 db/migrations/20260116152525_order_product_add_preorder_data.php diff --git a/Layout/default/Order/Form.php b/Layout/default/Order/Form.php index f09c3a82c..356b9747c 100644 --- a/Layout/default/Order/Form.php +++ b/Layout/default/Order/Form.php @@ -437,7 +437,7 @@
- order_date) : ""?>" /> + order_date) : $order->order_date ?>" />
@@ -553,7 +553,6 @@
-

Produkte

@@ -585,6 +584,12 @@
+ preorder_id): ?> + + + oaid): ?> + +
@@ -596,9 +601,11 @@
-
+ preorder_id): ?> +
-
+
+
diff --git a/Layout/default/Order/Index.php b/Layout/default/Order/Index.php index 35974b831..07afc242f 100644 --- a/Layout/default/Order/Index.php +++ b/Layout/default/Order/Index.php @@ -290,6 +290,7 @@ edit)?> editor->name?> + waiting == 1): ?> $order->id, "unset" => "1", "filter" => $filter, "s" => $pagination['start']])?>"> diff --git a/Layout/default/Preorder/include/preorder-detail.php b/Layout/default/Preorder/include/preorder-detail.php index 6329d86f8..f3edfdfd8 100644 --- a/Layout/default/Preorder/include/preorder-detail.php +++ b/Layout/default/Preorder/include/preorder-detail.php @@ -36,7 +36,9 @@
Details
- + + +
diff --git a/application/Order/OrderController.php b/application/Order/OrderController.php index c8da669e9..993cb2274 100644 --- a/application/Order/OrderController.php +++ b/application/Order/OrderController.php @@ -359,7 +359,7 @@ class OrderController extends mfBaseController { return $new_filter; } - protected function addAction() { + public function addAction() { //var_dump($this->request->filter);exit; @@ -393,9 +393,9 @@ class OrderController extends mfBaseController { $products[$pn->product_id] = $pn->product; } } - + } - + $order = $this->layout()->get("order"); if($order) { foreach($order->products as $op) { @@ -404,7 +404,7 @@ class OrderController extends mfBaseController { } } } - + $this->layout()->set("products", $products); $countries = CountryModel::getAll(); @@ -969,6 +969,12 @@ class OrderController extends mfBaseController { } $product_data = []; + if(array_key_exists("preorder_id", $p) && $p["preorder_id"]) { + $product_data["preorder_id"] = $p["preorder_id"]; + } + if(array_key_exists("oaid", $p) && $p["oaid"]) { + $product_data["oaid"] = $p["oaid"]; + } $product_data["order_id"] = $new_id; $product_data["product_id"] = $p["product_id"]; $product_data['amount'] = (!empty($p['amount'])) ? $p['amount'] : 1; diff --git a/application/OrderProduct/OrderProduct.php b/application/OrderProduct/OrderProduct.php index ea1cc5ec1..b8ad6a22b 100644 --- a/application/OrderProduct/OrderProduct.php +++ b/application/OrderProduct/OrderProduct.php @@ -48,11 +48,7 @@ class OrderProduct extends mfBaseModel { public function getProperty($name) { if($this->$name == null) { - - if(!$this->id) { - return null; - } - + if($name == "cpeprovisioning") { $this->cpeprovisioning = CpeprovisioningModel::getFirst(["orderproduct_id" => $this->id]); return $this->cpeprovisioning; @@ -128,7 +124,7 @@ class OrderProduct extends mfBaseModel { } return $this->editor; } - + $classname = ucfirst($name); $idfield = $name."_id"; $this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-".$this->$idfield); diff --git a/application/OrderProduct/OrderProductModel.php b/application/OrderProduct/OrderProductModel.php index e9ab464d6..5b417b684 100644 --- a/application/OrderProduct/OrderProductModel.php +++ b/application/OrderProduct/OrderProductModel.php @@ -5,6 +5,8 @@ class OrderProductModel public $order_id; public $product_id; public $termination_id; + public $oaid; + public $preorder_id; public $voicenumber; public $voiceplan_id; public $domain; @@ -212,6 +214,13 @@ class OrderProductModel } } + if (array_key_exists("preorder_id", $filter)) { + $preorder_id = $filter['preorder_id']; + if (is_numeric($preorder_id)) { + $where .= " AND preorder_id=$preorder_id"; + } + } + if (array_key_exists("voicenumber", $filter)) { $voicenumber = FronkDB::singleton()->escape($filter['voicenumber']); if ($voicenumber) { diff --git a/application/Preorder/Preorder.php b/application/Preorder/Preorder.php index af01ffe27..b4d18c772 100644 --- a/application/Preorder/Preorder.php +++ b/application/Preorder/Preorder.php @@ -26,6 +26,7 @@ class Preorder extends mfBaseModel { private $statusjournals; private $cancel_request_status; private $cancel_request_creator; + private $orderproduct; protected function beforeUpdate($data) { if(!array_key_exists("edit_by", $data)) { @@ -1690,6 +1691,13 @@ class Preorder extends mfBaseModel { return $this->editor; } + if($name == "orderproduct") { + $op = OrderProductModel::getFirst(["preorder_id" => $this->id]); + if(!$op) return null; + $this->orderproduct = $op; + return $this->orderproduct; + } + if($name == "creator") { $user = mfValuecache::singleton()->get("Worker-id-" . $this->create_by); if($user) { diff --git a/application/Preorder/PreorderController.php b/application/Preorder/PreorderController.php index 2cd55e6ec..822ad3617 100644 --- a/application/Preorder/PreorderController.php +++ b/application/Preorder/PreorderController.php @@ -1048,6 +1048,157 @@ class PreorderController extends mfBaseController { $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 { + // ... otherwise add owner data to order + 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]); + 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, + "attributename" => "termination_required", + "attributevalue" => 0, + "active" => true + ]); + } + if(!$product) { + $product = ProductModel::getFirst([ + "external" => 0, + "productgroup_id" => TT_PRODUCTGROUP_ID_INTERNET_ACCESS_RESI, + "name" => "%OAN%", + "attributename" => "termination_required", + "attributevalue" => 0, + "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 = []; diff --git a/application/Product/ProductModel.php b/application/Product/ProductModel.php index eafe20bd4..5cd22046c 100644 --- a/application/Product/ProductModel.php +++ b/application/Product/ProductModel.php @@ -105,6 +105,7 @@ class ProductModel { LEFT JOIN ProductAttribute ON (ProductAttribute.product_id = Product.id) LEFT JOIN Producttech ON (Product.producttech_id = Producttech.id) LEFT JOIN ProducttechAttribute ON (ProducttechAttribute.producttech_id = Producttech.id) + LEFT JOIN ProductNetwork ON (ProductNetwork.product_id = Product.id) WHERE $where GROUP BY Product.id ORDER BY Productgroup.name,Producttech.name,Product.name LIMIT 1 @@ -135,6 +136,7 @@ class ProductModel { LEFT JOIN ProductAttribute ON (ProductAttribute.product_id = Product.id) LEFT JOIN Producttech ON (Product.producttech_id = Producttech.id) LEFT JOIN ProducttechAttribute ON (ProducttechAttribute.producttech_id = Producttech.id) + LEFT JOIN ProductNetwork ON (ProductNetwork.product_id = Product.id) WHERE $where GROUP BY Product.id ) as p @@ -160,6 +162,7 @@ class ProductModel { LEFT JOIN ProductAttribute ON (ProductAttribute.product_id = Product.id) LEFT JOIN Producttech ON (Product.producttech_id = Producttech.id) LEFT JOIN ProducttechAttribute ON (ProducttechAttribute.producttech_id = Producttech.id) + LEFT JOIN ProductNetwork ON (ProductNetwork.product_id = Product.id) WHERE $where GROUP BY Product.id ORDER BY Productgroup.name,Producttech.name,Product.name @@ -169,7 +172,7 @@ class ProductModel { if(is_array($limit) && count($limit)) { if(is_numeric($limit['start']) && is_numeric($limit['count'])) { $sql .= " LIMIT ".$limit['start'].", ".$limit['count']; - } elseif(is_numeric($count)) { + } elseif(is_numeric($limit['count'])) { $sql .= " LIMIT ".$limit['count']; } } @@ -232,6 +235,15 @@ class ProductModel { $where .= " AND Product.sla_id IN (". implode(",", $sla_id).")"; } } + + if(array_key_exists("network_id", $filter)) { + $network_id = $filter['network_id']; + if(is_numeric($network_id)) { + $where .= " AND ProductNetwork.network_id=$network_id"; + } elseif(is_array($network_id) && count($network_id)) { + $where .= " AND ProductNetwork.network_id IN (". implode(",", $network_id).")"; + } + } if(array_key_exists("name", $filter)) { $name = $db->escape($filter['name']); @@ -284,7 +296,7 @@ class ProductModel { if(array_key_exists("attributevalue", $filter)) { $attributevalue = $db->escape($filter['attributevalue']); - if($attributevalue) { + if(strlen($attributevalue)) { $where .= " AND ProductAttribute.value = '$attributevalue'"; } } diff --git a/db/migrations/20260116152525_order_product_add_preorder_data.php b/db/migrations/20260116152525_order_product_add_preorder_data.php new file mode 100644 index 000000000..60a97d35b --- /dev/null +++ b/db/migrations/20260116152525_order_product_add_preorder_data.php @@ -0,0 +1,33 @@ +getEnvironment() == "thetool") { + $table = $this->table("OrderProduct"); + $table->addColumn("oaid", "string", ["null" => true, "default" => null, "limit" => 255, "after" => "termination_id"]); + $table->addColumn("preorder_id", "integer", ["null" => true, "default" => null, "after" => "preorder_id"]); + $table->addColumn("snopp_order_id", "integer", ["null" => true, "default" => null, "after" => "oaid"]); + $table->update(); + } + + if($this->getEnvironment() == "addressdb") { + + } + } + + public function down(): void + { + if($this->getEnvironment() == "thetool") { + + } + + if($this->getEnvironment() == "addressdb") { + + } + } +}