added new preorderiframe
This commit is contained in:
133
application/PreorderIFrame/PreorderIFrameController.php
Normal file
133
application/PreorderIFrame/PreorderIFrameController.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
// in /controllers/PreorderIFrameController.php
|
||||
|
||||
class PreorderIFrameController extends mfBaseController
|
||||
{
|
||||
|
||||
private PreorderIFrameModel $preorderIFrameModel;
|
||||
|
||||
public function init()
|
||||
{
|
||||
// The model is autoloaded or included elsewhere
|
||||
// 'X-Requested-With': 'XMLHttpRequest', 'X-Frame-Options': 'SAMEORIGIN', 'X-Frame-Referrer': document.referrer
|
||||
$this->preorderIFrameModel = new PreorderIFrameModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves the main order form HTML.
|
||||
* This action injects the necessary configuration into the Vue app.
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$clusterId = $this->request->get('clusterId', 'NULL');
|
||||
$color = $this->request->get('color', 'blue');
|
||||
|
||||
$vue_config = [
|
||||
'baseUrl' => '/PreorderIFrame', // URL to this controller
|
||||
'clusterId' => $clusterId !== NULL ? intval($clusterId) : null,
|
||||
'color' => htmlspecialchars($color),
|
||||
];
|
||||
|
||||
$this->layout()->set("JSGlobals", $vue_config);
|
||||
$this->layout()->setTemplate("VueViews/PreorderIFrame");
|
||||
}
|
||||
|
||||
// --- API ENDPOINTS ---
|
||||
|
||||
public function getClustersAction() {
|
||||
self::returnJson(['clusters' => $this->preorderIFrameModel->getClusters($_SERVER['HTTP_X_FRAME_REFERRER'])]);
|
||||
}
|
||||
|
||||
public function findCityAction()
|
||||
{
|
||||
$allowedClusters = $this->preorderIFrameModel->getClusters($_SERVER['HTTP_X_FRAME_REFERRER']);
|
||||
|
||||
$zip = $this->request->get('zip');
|
||||
$clusterId = $this->request->get('cluster_id');
|
||||
$cities = $this->preorderIFrameModel->findCities($zip, $clusterId);
|
||||
self::returnJson(['cities' => $cities]);
|
||||
}
|
||||
|
||||
public function findStreetAction()
|
||||
{
|
||||
// $this->checkOriginAndGetCampaign(); // Security check
|
||||
$zip = $this->request->get('zip');
|
||||
$city = $this->request->get('city');
|
||||
$clusterId = $this->request->get('cluster_id');
|
||||
$streets = $this->preorderIFrameModel->findStreets($zip, $city, $clusterId);
|
||||
self::returnJson(['streets' => $streets]);
|
||||
}
|
||||
|
||||
public function findAddressAction()
|
||||
{
|
||||
$addresses = $this->preorderIFrameModel->findAddresses($_GET);
|
||||
self::returnJson(['addresses' => $addresses]);
|
||||
}
|
||||
|
||||
public function submitOrderAction()
|
||||
{
|
||||
$requestBody = file_get_contents('php://input');
|
||||
$preorderData = json_decode($requestBody, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) self::sendError("Invalid JSON data.");
|
||||
|
||||
$tt_network = NetworkModel::getFirst(['adb_network_id' => $preorderData['additionalData']['clusterId']]);
|
||||
if (!$tt_network) self::sendError("No network found for the given cluster ID.");
|
||||
|
||||
$campaign = PreordercampaignModel::getFirst(['network_id' => $tt_network->id]);
|
||||
if (!$campaign) self::sendError("No campaign found for the given cluster ID.");
|
||||
|
||||
$h = new ADBHausnummer($preorderData['address']['hausnummer_id']);
|
||||
if (!$h->id) self::sendError("Invalid house number ID provided.");
|
||||
|
||||
$w = new ADBWohneinheit($preorderData['address']['wohneinheit_id']);
|
||||
if ($preorderData['address']['wohneinheit_id'] && !$w->id) self::sendError("Invalid unit ID provided.");
|
||||
|
||||
$data = [];
|
||||
$data['preordercampaign_id'] = $campaign->id;
|
||||
$data['adb_hausnummer_id'] = $preorderData['address']['hausnummer_id'];
|
||||
$data['adb_wohneinheit_id'] = $preorderData['address']['wohneinheit_id'];
|
||||
|
||||
|
||||
$new_status = null;
|
||||
if ($data['adb_wohneinheit_id'] && $w->id) {
|
||||
$status_code = max($w->status->code, $w->hausnummer->status->code);
|
||||
$new_status = PreorderstatusModel::getFirst(["code" => $status_code]);
|
||||
} elseif ($data['adb_hausnummer_id'] && $h->id) {
|
||||
$new_status = PreorderstatusModel::getFirst(["code" => $h->status->code]);
|
||||
}
|
||||
$data["status_id"] = $new_status ? $new_status->id : 1;
|
||||
|
||||
$data['type'] = $preorderData['connectionType'] === 'vorsorge' ? 'provision' : 'order';
|
||||
$data['connection_type'] = $preorderData['customerType'] === 'business' ? 'business' : 'single-dwelling';
|
||||
|
||||
$data['accept_agb'] = $preorderData['acceptAgb'] ? 1 : 0;
|
||||
$data['accept_dsgvo'] = $preorderData['acceptDsgvo'] ? 1 : 0;
|
||||
$data['accept_marketing'] = $preorderData['acceptMarketing'] ? 1 : 0;
|
||||
$data['accept_withdrawal'] = $preorderData['acceptWithdrawal'] ? 1 : 0;
|
||||
$data['submit_request'] = json_encode($preorderData);
|
||||
|
||||
$data['firstname'] = trim($preorderData['customer']['firstname']);
|
||||
$data['lastname'] = trim($preorderData['customer']['lastname']);
|
||||
$data['company'] = (trim($preorderData['customer']['company'])) ?: null;
|
||||
$data['street'] = (trim($preorderData['customer']['street'])) ?: null;
|
||||
$data['housenumber'] = (trim($preorderData['customer']['housenumber'])) ?: null;
|
||||
$data['zip'] = (trim($preorderData['customer']['zip'])) ?: null;
|
||||
$data['city'] = (trim($preorderData['customer']['city'])) ?: null;
|
||||
$data['phone'] = (trim($preorderData['customer']['phone'])) ?: null;
|
||||
$data['email'] = (trim($preorderData['customer']['email'])) ?: null;
|
||||
|
||||
$data['edit_by'] = 1;
|
||||
$data['create_by'] = 1;
|
||||
|
||||
$preorder = PreorderModel::create($data);
|
||||
$preorder->createUcode();
|
||||
$new_id = $preorder->save();
|
||||
|
||||
if (!$new_id) {
|
||||
self::sendError("Failed to create preorder record.");
|
||||
}
|
||||
|
||||
self::returnJson(['orderCode' => $preorder->ucode, 'status' => 'success']);
|
||||
}
|
||||
}
|
||||
239
application/PreorderIFrame/PreorderIFrameModel.php
Normal file
239
application/PreorderIFrame/PreorderIFrameModel.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
class PreorderIFrameModel extends mfBaseModel
|
||||
{
|
||||
// The constructor will use the default FronkDB connection
|
||||
// No need to override __construct if mfBaseModel handles it
|
||||
|
||||
public function init() {
|
||||
// Overwrite the table name if it doesn't match the class name
|
||||
$this->table = 'Preorder'; // Set a primary table if needed, though most methods define their own
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an origin has rights for a given cluster and returns the campaign.
|
||||
* @param int $clusterId The 'adb_netzgebiet_id' from the thetool.Network table.
|
||||
* @param string|null $origin The requesting origin (e.g., https://www.example.com).
|
||||
* @return array|null The campaign data if valid, otherwise null.
|
||||
*/
|
||||
public function getCampaignByClusterIdAndOrigin(int $clusterId, ?string $origin): ?array
|
||||
{
|
||||
// A null origin is not allowed for security reasons
|
||||
if (!$origin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$query = "
|
||||
SELECT pc.*
|
||||
FROM thetool.Preordercampaign pc
|
||||
JOIN thetool.Network n ON pc.Network_id = n.id
|
||||
WHERE n.adb_netzgebiet_id = ?
|
||||
";
|
||||
$res = $this->db->query($query, [$clusterId]);
|
||||
$campaign = $this->db->fetch_assoc($res);
|
||||
|
||||
if (!$campaign || empty($campaign['iframe_origins'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$allowedOrigins = json_decode($campaign['iframe_origins'], true);
|
||||
if (is_array($allowedOrigins) && in_array($origin, $allowedOrigins)) {
|
||||
return $campaign;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getClusters($frame_referrer): array
|
||||
{
|
||||
$query = "
|
||||
SELECT n.adb_netzgebiet_id as id, ng.name
|
||||
FROM thetool.Preordercampaign pc
|
||||
JOIN thetool.Network n ON pc.Network_id = n.id
|
||||
JOIN addressdb.Netzgebiet ng ON n.adb_netzgebiet_id = ng.id
|
||||
WHERE JSON_SEARCH(pc.iframe_origins, 'one', '" . $this->db->escape($frame_referrer) . "') IS NOT NULL
|
||||
GROUP BY n.adb_netzgebiet_id, ng.name
|
||||
ORDER BY ng.name ASC
|
||||
";
|
||||
|
||||
$res = $this->db->query($query);
|
||||
return $this->db->fetch_all_assoc($res);
|
||||
}
|
||||
|
||||
public function findCities(string $zip, int $adb_network_id): array
|
||||
{
|
||||
$query = "
|
||||
SELECT DISTINCT o.name
|
||||
FROM addressdb.Plz p
|
||||
JOIN addressdb.Ortschaft o ON p.gemeinde_id = o.gemeinde_id
|
||||
JOIN addressdb.Gemeinde g ON o.gemeinde_id = g.id
|
||||
JOIN addressdb.GemeindeNetzgebiet gn ON g.id = gn.gemeinde_id
|
||||
WHERE p.plzstring = " . $this->db->escape($zip) . " AND gn.netzgebiet_id = " . intval($adb_network_id) . "
|
||||
ORDER BY o.name ASC
|
||||
";
|
||||
|
||||
$res = $this->db->query($query);
|
||||
$cities = $this->db->fetch_all_assoc($res);
|
||||
return array_column($cities, 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds streets for a given ZIP, city, and cluster.
|
||||
* @param string $zip
|
||||
* @param string $city
|
||||
* @param int $clusterId
|
||||
* @return array
|
||||
*/
|
||||
public function findStreets(string $zip, string $city, int $clusterId): array
|
||||
{
|
||||
$query = "
|
||||
SELECT DISTINCT s.name
|
||||
FROM addressdb.Strasse s
|
||||
JOIN addressdb.Gemeinde g ON s.gemeinde_id = g.id
|
||||
JOIN addressdb.Ortschaft o ON o.gemeinde_id = g.id AND o.name = '" . $this->db->escape($city) . "'
|
||||
JOIN addressdb.GemeindeNetzgebiet gn ON g.id = gn.gemeinde_id
|
||||
WHERE gn.netzgebiet_id = " . intval($clusterId) . "
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM addressdb.Plz p
|
||||
WHERE p.plzstring = " . $this->db->escape($zip) . "
|
||||
AND p.gemeinde_id = o.gemeinde_id
|
||||
)
|
||||
ORDER BY s.name ASC
|
||||
";
|
||||
$res = $this->db->query($query);
|
||||
$streets = $this->db->fetch_all_assoc($res);
|
||||
return array_column($streets, 'name');
|
||||
}
|
||||
|
||||
public function findAddresses(array $params): array
|
||||
{
|
||||
$query = "
|
||||
SELECT h.oaid, h.hausnummer, s.name as street, p.plzstring as zip, o.name as city, h.id as hausnummer_id, w.id as wohneinheit_id,
|
||||
h.stiege, h.unit_count as building_unit_count, h.tool_building_type as building_type,
|
||||
w.oaid as unit_oaid, w.stock, w.tuer, w.zusatz
|
||||
FROM addressdb.Hausnummer h
|
||||
JOIN addressdb.Strasse s ON h.strasse_id = s.id
|
||||
JOIN addressdb.Plz p ON h.plz_id = p.id
|
||||
JOIN addressdb.Ortschaft o ON s.gemeinde_id = o.gemeinde_id
|
||||
LEFT JOIN addressdb.Wohneinheit w ON w.hausnummer_id = h.id
|
||||
WHERE h.netzgebiet_id = " . intval($params['cluster_id']) . "
|
||||
AND p.plzstring = " . $this->db->escape($params['zip']) . "
|
||||
AND o.name = '" . $this->db->escape($params['city']) . "'
|
||||
AND s.name = '" . $this->db->escape($params['street']) . "'
|
||||
AND h.hausnummer = '" . $this->db->escape($params['housenumber']) . "'
|
||||
";
|
||||
|
||||
$results = $this->db->fetch_all_assoc($this->db->query($query));
|
||||
if (empty($results)) return [];
|
||||
|
||||
$addresses = [];
|
||||
$topCounter = 1;
|
||||
|
||||
if (count($results) > 1) {
|
||||
foreach ($results as $row) {
|
||||
$showText = $this->buildShowText($row, $topCounter++);
|
||||
$addresses[] = [
|
||||
'oaid' => $row['unit_oaid'],
|
||||
'street' => $row['street'],
|
||||
'housenumber' => $row['hausnummer'],
|
||||
'hausnummer_id' => $row['hausnummer_id'],
|
||||
'wohneinheit_id' => $row['wohneinheit_id'],
|
||||
'building_type' => intval($row['building_type']),
|
||||
'zip' => $row['zip'],
|
||||
'city' => $row['city'],
|
||||
'stiege' => $row['stiege'],
|
||||
'stock' => $row['stock'],
|
||||
'tuer' => $row['tuer'],
|
||||
'zusatz' => $row['zusatz'],
|
||||
'building_unit_count' => $row['building_unit_count'],
|
||||
'showText' => $showText,
|
||||
'preorderTypes' => ['order']
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$row = $results[0];
|
||||
$addresses[] = [
|
||||
'oaid' => $row['oaid'],
|
||||
'street' => $row['street'],
|
||||
'housenumber' => $row['hausnummer'],
|
||||
'hausnummer_id' => $row['hausnummer_id'],
|
||||
'wohneinheit_id' => $row['wohneinheit_id'],
|
||||
'building_type' => intval($row['building_type']),
|
||||
'zip' => $row['zip'],
|
||||
'city' => $row['city'],
|
||||
'stiege' => $row['stiege'],
|
||||
'stock' => $row['stock'],
|
||||
'tuer' => $row['tuer'],
|
||||
'zusatz' => $row['zusatz'],
|
||||
'building_unit_count' => $row['building_unit_count'],
|
||||
'showText' => $this->buildShowText($row, 1),
|
||||
'preorderTypes' => ['order']
|
||||
];
|
||||
}
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
private function buildShowText(array $row, int $counter): string
|
||||
{
|
||||
$parts = array_filter([
|
||||
$row['stiege'] ? "Stiege {$row['stiege']}" : null,
|
||||
$row['stock'] ? "Stock {$row['stock']}" : null,
|
||||
$row['tuer'] ? "Tür {$row['tuer']}" : null,
|
||||
$row['zusatz'] ?: null
|
||||
]);
|
||||
|
||||
return $parts ? implode(', ', $parts) : "Top {$counter}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new preorder record in the database.
|
||||
* @param array $data The validated preorder data from the form.
|
||||
* @param int $campaignId The ID of the associated preorder campaign.
|
||||
* @return array The result containing the new order code.
|
||||
*/
|
||||
public function createPreorder(array $data, int $campaignId): array
|
||||
{
|
||||
$customer = $data['customer'];
|
||||
$address = $data['address'];
|
||||
|
||||
// Generate a unique code for the preorder
|
||||
$ucode = strtoupper(substr(md5(uniqid(rand(), true)), 0, 10));
|
||||
|
||||
$preorderData = [
|
||||
'ucode' => $ucode,
|
||||
'thetool.Preordercampaign_id' => $campaignId,
|
||||
'oaid' => $address['oaid'],
|
||||
'type' => $data['preorderType'],
|
||||
'connection_type' => $data['connectionType'],
|
||||
'contact_type' => $customer['type'],
|
||||
'firstname' => $customer['firstname'],
|
||||
'lastname' => $customer['lastname'],
|
||||
'company' => $customer['company'] ?? null,
|
||||
'street' => $customer['street'],
|
||||
'housenumber' => $customer['housenumber'],
|
||||
'zip' => $customer['zip'],
|
||||
'city' => $customer['city'],
|
||||
'phone' => $customer['phone'],
|
||||
'email' => $customer['email'],
|
||||
'address_info' => $data['address_info'],
|
||||
'accept_agb' => $data['acceptAgb'] ? 1 : 0,
|
||||
'accept_dsgvo' => $data['acceptDsgvo'] ? 1 : 0,
|
||||
'accept_marketing' => $data['acceptMarketing'] ? 1 : 0,
|
||||
'accept_withdrawal' => $data['acceptWithdrawal'] ? 1 : 0,
|
||||
'addon_data' => json_encode($data['additionalData']),
|
||||
'submit_type' => 'api',
|
||||
'submit_request' => json_encode($data),
|
||||
'order_date' => time(),
|
||||
'create' => time(),
|
||||
'edit' => time(),
|
||||
'create_by' => 0, // System user
|
||||
'edit_by' => 0, // System user
|
||||
];
|
||||
|
||||
$this->db->insert('Preorder', $preorderData);
|
||||
|
||||
return ['code' => $ucode];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user