From 00c46270232d381c7ee05baac551dbfbfc119bf2 Mon Sep 17 00:00:00 2001 From: Luca Haid Date: Mon, 6 Oct 2025 10:21:14 +0200 Subject: [PATCH] overhauled preorderlogistics --- .../PreorderlogisticsController.php | 631 +++++++++--------- .../PreorderLogistics/PreorderLogistics.css | 9 + .../PreorderLogistics/PreorderLogistics.js | 223 +++++++ 3 files changed, 550 insertions(+), 313 deletions(-) create mode 100644 public/js/pages/PreorderLogistics/PreorderLogistics.css create mode 100644 public/js/pages/PreorderLogistics/PreorderLogistics.js diff --git a/application/Preorderlogistics/PreorderlogisticsController.php b/application/Preorderlogistics/PreorderlogisticsController.php index d815575f0..03b2fea92 100644 --- a/application/Preorderlogistics/PreorderlogisticsController.php +++ b/application/Preorderlogistics/PreorderlogisticsController.php @@ -3,322 +3,327 @@ include_once(BASEDIR."/lib/QRCode/QRCode.php"); use Apirone\Lib\PhpQrCode\QrCode; class PreorderlogisticsController extends mfBaseController { - - protected function init() { - $this->needlogin=true; - $me = new User(); - $me->loadMe(); - $this->me = $me; - $this->layout()->set("me",$me); - - if(!$me->is(["Preorderlogistics"])) { - $this->redirect("Dashboard"); - } - } - - protected function indexAction() { - $this->layout()->setTemplate("Preorderlogistics/Index"); - - $this->layout->set("filter", $this->request->filter); - - $filter = []; - if($this->request->filter) { - $filter = $this->getPreparedFilter($this->request->filter); - } else { - $filter = $this->getPreparedFilter([]); - } - - // pagination defaults - $pagination = []; - $pagination['start'] = 0; - $pagination['count'] = 25; - $pagination['maxItems'] = 0; - - if(is_numeric($this->request->s)) { - $pagination['start'] = intval($this->request->s); - } - - $my_networks = []; - $my_network_ids = []; - $my_campaign_ids = []; - - $user_network_ids = $this->me->getFlag("preorder_networks")->value(); - if($user_network_ids) { - $user_network_ids = json_decode($user_network_ids); - } - - if(is_array($user_network_ids) && count($user_network_ids)) { - foreach($user_network_ids as $mnid) { - $my_networks[] = new Network($mnid); - } - } - - foreach($my_networks as $network) { - $my_network_ids[] = $network->id; - } - - foreach($my_networks as $network) { - foreach(PreordercampaignModel::search(['network_id' => $network->id]) as $campaign) { - $my_campaigns[] = $campaign; - if(!in_array($campaign->id, $my_campaign_ids)) $my_campaign_ids[] = $campaign->id; - } - } - //var_dump($my_network_ids,$my_campaign_ids);exit; - $this->layout()->set("my_campaigns", $my_campaigns); + private User $me; - if(array_key_exists("preordercampaign_id", $filter) && $filter['preordercampaign_id'] && in_array($filter['preordercampaign_id'], $my_campaign_ids)) { - $campaign_id = $filter['preordercampaign_id']; - if(is_numeric($campaign_id) && $campaign_id > 0) { - $campaign = new Preordercampaign($campaign_id); - $this->layout()->set("campaign", $campaign); - } - } else { - $filter['preordercampaign_id'] = $my_campaign_ids; - } - - $filter['network_id'] = $my_network_ids; - - $filter["status_code"] = 140; - //$filter[" "145"]); - if ($filter['sent'] !== true) { - $filter["preorder_status_flags_disabled"] = [$installation_kit_status_flag->id]; - } - - $pagination['maxItems'] = PreorderModel::countWithLogistics($filter); - $preorders = PreorderModel::searchWithLogistics($filter, $pagination); - - $this->layout()->set("pagination", $pagination); - $this->layout()->set("preorders", $preorders); - } - - private function getPreparedFilter($filter) { - $new_filter = []; - - $new_filter['add-where'] = ""; - - if(array_key_exists("name", $filter) && $filter['name']) { - $new_filter['name%'] = "%".$filter['name']; - unset($filter['name']); - } - if(array_key_exists("area", $filter) && $filter['area']) { - $new_filter['area%'] = "%".$filter['area']; - unset($filter['area']); - } - - if(array_key_exists("search",$filter) && trim($filter['search'])) { - $search = trim($filter['search']); - $new_filter['add-where'] .= " AND ("; - $new_filter['add-where'] .= " adb_hausnummer.gemeinde like '%$search%' OR adb_hausnummer.plz like '%$search%' OR adb_hausnummer.strasse like '%$search%'"; - $new_filter['add-where'] .= " OR company like '%$search%' OR firstname like '%$search%' OR lastname like '%$search%' OR concat(firstname, ' ', lastname) like '%$search%' OR concat(lastname, ' ', firstname) like '%$search%' OR street like '%$search%' OR zip like '%$search%' OR city like '%$search%' OR email like '%$search' OR phone like '%$search'"; - $new_filter['add-where'] .= " OR ucode like '%$search' OR oaid like '%$search'"; - } - - if(array_key_exists("address", $filter) && $filter["address"]) { - $address = $this->db()->escape($filter['address']); - $new_filter['add-where'] .= " AND (adb_hausnummer.gemeinde like '%$address%' OR adb_hausnummer.plz like '%$address%' OR adb_hausnummer.strasse like '%$address%' - OR adb_hausnummer.hausnummer like '%$address%' OR CONCAT (adb_hausnummer.strasse, ' ', adb_hausnummer.hausnummer) like '%$address%' - OR CONCAT (adb_hausnummer.strasse, ' ', adb_hausnummer.hausnummer) like '%".str_replace(" ", "%", $address)."%')"; - } - - if(array_key_exists("hausnummer", $filter) && $filter["hausnummer"]) { - $hausnummer = $this->db()->escape($filter['hausnummer']); - $new_filter['hausnummer'] = $hausnummer; - } - - if(array_key_exists("kunde", $filter) && $filter["kunde"]) { - $kunde = $this->db()->escape($filter['kunde']); - $new_filter['add-where'] .= " AND (company like '%$kunde%' OR firstname like '%$kunde%' OR lastname like '%$kunde%' OR concat(firstname, ' ', lastname) like '%$kunde%' OR concat(lastname, ' ', firstname) like '%$kunde%' OR street like '%$kunde%' OR zip like '%$kunde%' OR city like '%$kunde%' OR phone like '%$kunde%' OR email like '%$kunde%')"; - } - - if(array_key_exists("ucode", $filter) && $filter['ucode']) { - $new_filter['ucode'] = "%".$filter['ucode']."%"; - unset($filter['ucode']); - } - - if(array_key_exists("oaid", $filter) && $filter['oaid']) { - $new_filter['oaid'] = "%".$filter['oaid']."%"; - unset($filter['oaid']); - } - - $new_filter["sent"] = false; - if(array_key_exists("sent", $filter)) { - if($filter['sent'] == "yes") { - $new_filter["sent"] = true; - } - if($filter['sent'] == "no") { - $new_filter["sent"] = false; - } - if($filter['sent'] == "all") { - unset($new_filter["sent"]); - } - unset($filter['sent']); - } - - - $new_filter['deleted'] = 0; - - foreach($filter as $name => $value) { - $new_filter[$name] = $value; - } - - return $new_filter; - } - - protected function printAction() { - $this->layout()->setTemplate("Preorderlogistics/Print.template"); - $id = $this->request->id; - if(!is_numeric($id) || $id < 1) { - $this->layout()->setFlash("Vorbestellung nicht gefunden", "error"); - $this->redirect("Preorderlogistics"); - } - - $preorder = new Preorder($id); - if(!$preorder->id) { - $this->layout()->setFlash("Vorbestellung nicht gefunden", "error"); - $this->redirect("Preorderlogistics"); - } - - $user_network_ids_json = $this->me->getFlag("preorder_networks")->value(); - $user_network_ids = json_decode($user_network_ids_json); - if(!is_array($user_network_ids) || !count($user_network_ids)) { - $this->layout()->setFlash("Vorbestellung nicht gefunden (3)", "error"); - $this->redirect("Preorderlogistics"); - } - //var_dump($preorder->adb_hausnummer->netzgebiet_id, $user_network_ids);exit; - - $network = NetworkModel::getFirst(["adb_network_id" => $preorder->adb_hausnummer->netzgebiet_id]); - if(!$network) { - $this->layout()->setFlash("Vorbestellung nicht gefunden (4)", "error"); - $this->redirect("Preorderlogistics"); - } - - if(!in_array($network->id, $user_network_ids)) { - $this->layout()->setFlash("Vorbestellung nicht gefunden (2)", "error"); - $this->redirect("Preorderlogistics"); - } - - - /* - * generate QR code - */ - if(!$preorder->ciftoken) { - $preorder->createCiftoken(); - $preorder->save(); - } - if(!$preorder->cifurl) { - $preorder->cifurl = $preorder->generateCifUrl(); - $preorder->save(); - } - if(!$preorder->cifcableurl) { - $preorder->cifcableurl = $preorder->generateCifCableUrl(); - $preorder->save(); - } - - - $plog = PreorderlogisticsModel::getFirst(["preorder_id" => $preorder->id]); - if(!$plog) { - $plog = PreorderlogisticsModel::create([ - "preorder_id" => $preorder->id, - "sent" => 0 - ]); - if(!$plog->save()) { - $this->layout()->setFlash("Eintrag konnte nicht gespeichert werden"); - } - } - - $qr = QRCode::init($preorder->cifurl); // $data & $options are optional - - $image_encoded = $qr->base64(); - - $this->layout()->set("qr_url", $image_encoded); - $this->layout()->set("preorder", $preorder); - - } - - protected function apiAction() { - if(!$this->me->is(["Preorderlogistics"])) { - $this->redirect("Dashboard"); - } - $do = $this->request->do; - $data = []; - - switch($do) { - case "saveSent": - $return = $this->saveSentApi(); - break; - default: - $return = false; - } - - if(!is_array($return) || !count($return)) { - $data = ["status" => "error"]; - $this->returnJson($data); - } - $data['status'] = "OK"; - $data['result'] = $return; - $this->returnJson($data); - } - - - private function saveSentApi() { - if(!$this->me->is(["Preorderlogistics"])) return false; - - $preorder_id = $this->request->id; - if(!is_numeric($preorder_id) || $preorder_id < 1) { - return false; - } - - $preorder = new Preorder($preorder_id); - if(!$preorder->id) return false; - - $plog = PreorderlogisticsModel::getFirst(["preorder_id" => $preorder->id]); - if(!$plog) { - $plog = PreorderlogisticsModel::create([ - "preorder_id" => $preorder->id, - "sent" => 0 - ]); - - } - - $sent = intval($this->request->sent); - if($sent < 0 || $sent > 1) return false; - - $installation_kit_status_flag = PreorderStatusflagModel::getFirst(["code" => "145"]); - $flagvalue = PreorderStatusflagValueModel::getFirst(["preorder_id" => $preorder_id, "flag_id" => $installation_kit_status_flag->id]); -// var_dump($flagvalue); -// exit; - if(!$flagvalue) { - $flagvalue = PreorderStatusflagValueModel::create([ - "preorder_id" => $preorder_id, - "flag_id" => $installation_kit_status_flag->id - ]); - } - $value = ($sent) ? 1 : 0; - $flagvalue->value = $value; - try { - if(!$flagvalue->save()) { - return false; - } - } catch(Exception $e) { - $this->log->debug($e->getTraceAsString()); - die("hi"); + if (!$me->is(["Preorderlogistics"])) { + $this->redirect("Dashboard"); } - - if($sent) { - $plog->sent_by = $this->me->id; - $plog->sent = date('U'); - - } else { - $plog->sent_by = null; - $plog->sent = 0; } - if(!$plog->save()) return false; - return ["preorder_id" => $preorder->id]; - } + protected function indexAction() { + $my_campaigns = []; + $user_network_ids = json_decode($this->me->getFlag("preorder_networks")->value() ?: '[]', true); + + if (is_array($user_network_ids) && count($user_network_ids)) { + $campaign_objects = PreordercampaignModel::search(['network_id' => $user_network_ids]); + if(is_array($campaign_objects)){ + foreach($campaign_objects as $campaign) { + $my_campaigns[] = ['value' => $campaign->id, 'text' => $campaign->name]; + } + } + } + + $js_variables = [ + 'CRUD_CONFIG' => [ + 'CAMPAIGNS' => $my_campaigns, + ] + ]; + + Helper::renderVue($this, 'PreorderLogistics', 'Versandlogistik', $js_variables); + } + + protected function getPreordersAction() { + $postData = json_decode(file_get_contents('php://input'), true); + $filter = $this->getPreparedFilter($postData['filters'] ?? []); + $pagination = $postData['pagination'] ?? ['page' => 1, 'per_page' => 25]; + // The 'order' parameter is received but not passed to searchWithLogistics, as it's not supported by the custom model method. + // $order = $postData['order'] ?? ['key' => 'id', 'order' => 'DESC']; + + $my_campaign_ids = $this->getUserCampaignIds(); + if (empty($my_campaign_ids)) { + self::returnJson(['rows' => [], 'pagination' => ['total_rows' => 0]]); + return; + } + + if (empty($filter['preordercampaign_id'])) { + $filter['preordercampaign_id'] = $my_campaign_ids; + } else { + // Ensure the filtered campaign is one the user has access to + if (!in_array($filter['preordercampaign_id'], $my_campaign_ids)) { + self::returnJson(['rows' => [], 'pagination' => ['total_rows' => 0]]); + return; + } + } + + $totalCount = PreorderModel::countWithLogistics($filter); + // FIX: Removed the $order parameter from the call, as the custom model method does not support it. + $preorders = PreorderModel::searchWithLogistics($filter, ['start' => ($pagination['page'] - 1) * $pagination['per_page'], 'count' => $pagination['per_page']]); + + $rows = []; + if (is_array($preorders)) { + foreach ($preorders as $preorder) { + // Ensure we are working with an object, as expected by relation accessors + if (!is_object($preorder)) continue; + + $row = (array)$preorder->data; + // FIX: Added null-safe checks for related properties to prevent warnings + $row['status_code'] = $preorder->status ? $preorder->status->code : null; + $row['display_address'] = $this->getFormattedAddress($preorder); + $row['sent'] = ($preorder->logistics && $preorder->logistics->sent); + $row['id'] = $preorder->id; // Ensure ID is included + $rows[] = $row; + } + } + + self::returnJson([ + 'rows' => $rows, + 'pagination' => [ + 'page' => $pagination['page'], + 'per_page' => $pagination['per_page'], + 'total_rows' => intval($totalCount), + 'total_pages' => ceil($totalCount / $pagination['per_page']), + 'filtered_available' => intval($totalCount) + ] + ]); + } + + protected function getFCPsForCampaignAction() { + if (empty($this->request->campaign_id)) { + self::returnJson([]); + return; + } + + $apiUrl = self::getUrl("Preorder", "Api"); + $response = mf::get_url_content($apiUrl . "?do=getFCPsForCampaign&campaign_id=" . intval($this->request->campaign_id)); + $data = json_decode($response, true); + + if (isset($data['status']) && $data['status'] == 'OK' && is_array($data['result'])) { + self::returnJson($data['result']); + } else { + self::returnJson([]); + } + } + + protected function saveSentAction() { + $postData = json_decode(file_get_contents('php://input'), true); + $this->saveSentStatus($postData['id'], $postData['sent']); + self::returnJson(['success' => true]); + } + + protected function printAction() { + $this->layout()->setTemplate("Preorderlogistics/Print.template"); + $id = $this->request->id; + if (!is_numeric($id) || $id < 1) { + $this->layout()->setFlash("Vorbestellung nicht gefunden", "error"); + $this->redirect("Preorderlogistics"); + } + + $preorder = new Preorder($id); + if (!$preorder->id || !$this->isUserAllowedForPreorder($preorder)) { + $this->layout()->setFlash("Vorbestellung nicht gefunden oder keine Berechtigung", "error"); + $this->redirect("Preorderlogistics"); + } + + if (!$preorder->cifurl) { + $preorder->createCiftoken(); + $preorder->cifurl = $preorder->generateCifUrl(); + $preorder->cifcableurl = $preorder->generateCifCableUrl(); + $preorder->save(); + } + + $qr = QRCode::init($preorder->cifurl); + $this->layout()->set("qr_url", $qr->base64()); + $this->layout()->set("preorder", $preorder); + } + + protected function printAllAction() { + $preorders = $this->getFilteredPreordersFromRequest(); + $combinedHtml = ''; + foreach ($preorders as $preorder) { + ob_start(); + $this->printActionContent($preorder->id); + $combinedHtml .= ob_get_clean() . '
'; + } + echo $combinedHtml; + exit; + } + + protected function csvExportAction() { + $preorders = $this->getFilteredPreordersFromRequest(); + $this->generateAndDownloadCsv($preorders, "export-versand.csv"); + } + + protected function csvExportAndMarkAsSentAction() { + $preorders = $this->getFilteredPreordersFromRequest(); + foreach ($preorders as $preorder) $this->saveSentStatus($preorder->id, true); + + $this->generateAndDownloadCsv($preorders, "export-versand-markiert.csv"); + } + + private function getFilteredPreordersFromRequest() { + $postData = json_decode(file_get_contents('php://input'), true); + $filter = $this->getPreparedFilter($postData['filters'] ?? []); + + $my_campaign_ids = $this->getUserCampaignIds(); + if (empty($my_campaign_ids)) return []; + + if (empty($filter['preordercampaign_id'])) { + $filter['preordercampaign_id'] = $my_campaign_ids; + } elseif (!in_array($filter['preordercampaign_id'], $my_campaign_ids)) { + return []; + } + + // Return objects for methods that expect them + return PreorderModel::searchWithLogistics($filter, []); + } + + private function generateAndDownloadCsv($preorders, $filename) { + header('Content-Type: text/csv; charset=utf-8'); + header('Content-Disposition: attachment; filename=' . $filename); + $output = fopen('php://output', 'w'); + fputcsv($output, ["ucode", "oaid", "addr_name", "addr_street", "addr_zip", "addr_city", "phone", "email"], ";"); + + foreach ($preorders as $preorder) { + fputcsv($output, [ + $preorder->ucode, + $preorder->oaid, + $preorder->company ?: "{$preorder->firstname} {$preorder->lastname}", + $preorder->adb_hausnummer_id && $preorder->adb_hausnummer && $preorder->adb_hausnummer->strasse ? "{$preorder->adb_hausnummer->strasse->name} {$preorder->adb_hausnummer->hausnummer}" : trim("{$preorder->street} {$preorder->housenumber}"), + $preorder->adb_hausnummer_id && $preorder->adb_hausnummer && $preorder->adb_hausnummer->plz ? $preorder->adb_hausnummer->plz->plz : $preorder->zip, + $preorder->adb_hausnummer_id && $preorder->adb_hausnummer && $preorder->adb_hausnummer->ortschaft ? $preorder->adb_hausnummer->ortschaft->name : $preorder->city, + $preorder->phone, + $preorder->email + ], ";"); + } + fclose($output); + exit; + } + + private function printActionContent($id) { + $preorder = new Preorder($id); + if (!$preorder->id) return; + + if (!$preorder->cifurl) { + $preorder->createCiftoken(); + $preorder->cifurl = $preorder->generateCifUrl(); + $preorder->cifcableurl = $preorder->generateCifCableUrl(); + $preorder->save(); + } + + $qr = QRCode::init($preorder->cifurl); + + $layout = new mfLayout(); + $layout->setTemplate("Preorderlogistics/Print.template"); + $layout->set("qr_url", $qr->base64()); + $layout->set("preorder", $preorder); + echo $layout->render(false); + } + + private function saveSentStatus($preorder_id, $isSent) { + if (!is_numeric($preorder_id) || $preorder_id < 1) return false; + $preorder = new Preorder($preorder_id); + if (!$preorder->id || !$this->isUserAllowedForPreorder($preorder)) return false; + + $installation_kit_status_flag = PreorderStatusflagModel::getFirst(["code" => "145"]); + if (!$installation_kit_status_flag) return false; + + $flagvalue = PreorderStatusflagValueModel::getFirst(["preorder_id" => $preorder_id, "flag_id" => $installation_kit_status_flag->id]); + if (!$flagvalue) { + $flagvalue = PreorderStatusflagValueModel::create([ + "preorder_id" => $preorder_id, + "flag_id" => $installation_kit_status_flag->id + ]); + } + $flagvalue->value = $isSent ? 1 : 0; + $flagvalue->save(); + + $plog = PreorderlogisticsModel::getFirst(["preorder_id" => $preorder->id]); + if (!$plog) { + $plog = PreorderlogisticsModel::create(["preorder_id" => $preorder->id]); + } + $plog->sent = $isSent ? time() : 0; + $plog->sent_by = $isSent ? $this->me->id : null; + return $plog->save(); + } + + private function getFormattedAddress(Preorder $preorder) { + if ($preorder->adb_hausnummer_id && $preorder->adb_hausnummer) { + $address = $preorder->company ? htmlspecialchars($preorder->company) . "
" . htmlspecialchars(trim("{$preorder->firstname} {$preorder->lastname}")) : htmlspecialchars(trim("{$preorder->firstname} {$preorder->lastname}")); + if ($preorder->adb_hausnummer->strasse) { + $address .= "
" . htmlspecialchars($preorder->adb_hausnummer->strasse->name) . " " . htmlspecialchars($preorder->adb_hausnummer->hausnummer); + } + $address .= ($preorder->adb_wohneinheit_id && $preorder->adb_wohneinheit && (string)$preorder->adb_wohneinheit) ? "
" . htmlspecialchars((string)$preorder->adb_wohneinheit) : ""; + if ($preorder->adb_hausnummer->plz && $preorder->adb_hausnummer->ortschaft) { + $address .= "
" . htmlspecialchars($preorder->adb_hausnummer->plz->plz) . " " . htmlspecialchars($preorder->adb_hausnummer->ortschaft->name); + } + if ($preorder->adb_hausnummer->strasse && $preorder->adb_hausnummer->strasse->gemeinde) { + $address .= "
" . htmlspecialchars($preorder->adb_hausnummer->strasse->gemeinde->name); + } + } else { + $address = htmlspecialchars($preorder->company ?: "{$preorder->firstname} {$preorder->lastname}"); + $address .= "
" . htmlspecialchars(trim("{$preorder->street} {$preorder->housenumber}")); + $address .= "
" . htmlspecialchars($preorder->zip) . " " . htmlspecialchars($preorder->city); + } + return $address; + } + + private function getUserCampaignIds() { + $user_network_ids = json_decode($this->me->getFlag("preorder_networks")->value() ?: '[]', true); + if (!is_array($user_network_ids) || count($user_network_ids) === 0) return []; + + $campaigns = PreordercampaignModel::search(['network_id' => $user_network_ids]); + if(!is_array($campaigns)) return []; + return array_map(fn($c) => $c->id, $campaigns); + } + + private function isUserAllowedForPreorder(Preorder $preorder) { + $user_campaign_ids = $this->getUserCampaignIds(); + return in_array($preorder->preordercampaign_id, $user_campaign_ids); + } + + private function getPreparedFilter($filter) { + $new_filter = ['add-where' => ""]; + + if (!empty($filter['ucode'])) $new_filter['ucode%'] = "%" . $filter['ucode'] . "%"; + if (!empty($filter['oaid'])) $new_filter['oaid%'] = "%" . $filter['oaid'] . "%"; + if (!empty($filter['preordercampaign_id'])) $new_filter['preordercampaign_id'] = $filter['preordercampaign_id']; + // FIX: Corrected filter key for FCP + if (!empty($filter['fcp'])) $new_filter['fcp_id'] = $filter['fcp']; + + if(!empty($filter['address'])) { + $address = $this->db()->escape($filter['address']); + $new_filter['add-where'] .= " AND (adb_hausnummer.gemeinde like '%$address%' OR adb_hausnummer.plz like '%$address%' OR adb_hausnummer.strasse like '%$address%' OR adb_hausnummer.hausnummer like '%$address%' OR CONCAT(adb_hausnummer.strasse, ' ', adb_hausnummer.hausnummer) like '%$address%')"; + } + + if(!empty($filter['kunde'])) { + $kunde = $this->db()->escape($filter['kunde']); + $new_filter['add-where'] .= " AND (company like '%$kunde%' OR firstname like '%$kunde%' OR lastname like '%$kunde%' OR concat(firstname, ' ', lastname) like '%$kunde%' OR concat(lastname, ' ', firstname) like '%$kunde%')"; + } + + $installation_kit_status_flag = PreorderStatusflagModel::getFirst(["code" => "145"]); + if ($installation_kit_status_flag) { + $installation_kit_status_flag_id = $installation_kit_status_flag->id; + if (isset($filter['sent'])) { + if ($filter['sent'] == "yes") $new_filter["preorder_status_flags_enabled"] = [$installation_kit_status_flag_id]; + if ($filter['sent'] == "no") $new_filter["preorder_status_flags_disabled"] = [$installation_kit_status_flag_id]; + // if 'all', do nothing to apply no filter for sent status + } else { + // Default to 'not sent' if filter is not set + $new_filter["preorder_status_flags_disabled"] = [$installation_kit_status_flag_id]; + } + } + + $new_filter["status_code"] = 140; + $new_filter["deleted"] = 0; + $new_filter["unit_count<="] = 2; + + return $new_filter; + } } \ No newline at end of file diff --git a/public/js/pages/PreorderLogistics/PreorderLogistics.css b/public/js/pages/PreorderLogistics/PreorderLogistics.css new file mode 100644 index 000000000..965d81d64 --- /dev/null +++ b/public/js/pages/PreorderLogistics/PreorderLogistics.css @@ -0,0 +1,9 @@ +.sent-checkbox-wrapper { + display: flex; + align-items: center; + justify-content: center; +} + +.sent-checkbox-wrapper .fa-check { + font-size: 1.2rem; +} \ No newline at end of file diff --git a/public/js/pages/PreorderLogistics/PreorderLogistics.js b/public/js/pages/PreorderLogistics/PreorderLogistics.js new file mode 100644 index 000000000..3eadd4cd6 --- /dev/null +++ b/public/js/pages/PreorderLogistics/PreorderLogistics.js @@ -0,0 +1,223 @@ +Vue.component('preorder-logistics', { + template: ` + +
+
+

Filter

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + +
+
+
+
+ + + + + + + + +
+ `, + data() { + return { + window: window, + loading: false, + isPrinting: false, + isExporting: false, + isExportingAndMarking: false, + campaigns: [{value: '', text: 'Alle'}], + fcps: [], + sentStatusOptions: [ + {value: 'no', text: 'Noch nicht versendet'}, + {value: 'yes', text: 'Versendet'}, + {value: 'all', text: 'Alle'} + ], + filters: { + preordercampaign_id: '', + ucode: '', + oaid: '', + sent: 'no', + address: '', + kunde: '', + fcp: [] + }, + tableConfig: { + key: 'preorderlogistics', + tableHeader: 'Bestellungen', + headers: [ + {key: 'actions', text: '', sortable: false, filter: false}, + {key: 'sent', text: 'Versandt', sortable: false, filter: false}, + {key: 'status_code', text: 'Status', sortable: false, filter: false}, + {key: 'shipping_address', text: 'Versandadresse', sortable: false, filter: false}, + {key: 'oaid', text: 'OAID', sortable: false, filter: false}, + {key: 'ucode', text: 'Bestellcode', sortable: false, filter: false}, + ] + } + } + }, + async mounted() { + this.campaigns.push(...window.TT_CONFIG.CRUD_CONFIG.CAMPAIGNS); + if (this.campaigns.length === 2) { // 'Alle' + one campaign + this.filters.preordercampaign_id = this.campaigns[1].value; + } + await this.fetchFcps(); + }, + watch: { + 'filters.preordercampaign_id': 'fetchFcps' + }, + methods: { + async fetchFcps() { + if (!this.filters.preordercampaign_id) { + this.fcps = []; + this.filters.fcp = []; + return; + } + try { + const response = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/getFCPsForCampaign`, { + params: {campaign_id: this.filters.preordercampaign_id} + }); + this.fcps = response.data; + } catch (e) { + console.error("Could not fetch FCPs", e); + this.fcps = []; + } + }, + applyFilters() { + this.$refs.table.filters = {...this.filters}; + this.$refs.table.refreshTable(); + }, + resetFilters() { + this.filters = { + preordercampaign_id: '', ucode: '', oaid: '', sent: 'no', address: '', kunde: '', fcp: [] + }; + this.applyFilters(); + }, + async saveSent(id, sent) { + try { + const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/saveSentAction`, { + id, + sent + }); + if (response.data.success) { + window.notify('success', 'Status gespeichert.'); + this.$refs.table.refreshTable(); + } else { + window.notify('error', 'Fehler beim Speichern.'); + } + } catch (e) { + console.error("Error saving sent status:", e); + window.notify('error', 'Ein Fehler ist aufgetreten.'); + this.$refs.table.refreshTable(); + } + }, + printSlip(row) { + const w = window.open(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/print?id=${row.id}`, "_blank", "popup=yes"); + w.addEventListener('load', () => w.print()); + }, + async printAll() { + this.isPrinting = true; + try { + const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/printAllAction`, { + filters: this.filters + }, {responseType: 'text'}); + + const printWindow = window.open("", "_blank"); + printWindow.document.write(response.data); + printWindow.document.close(); + setTimeout(() => { + printWindow.focus(); + printWindow.print(); + }, 500); + + } catch (e) { + console.error("Error printing all slips:", e); + window.notify('error', 'Fehler beim Drucken.'); + } finally { + this.isPrinting = false; + } + }, + async exportCsv(markAsSent) { + const action = markAsSent ? 'csvExportAndMarkAsSentAction' : 'csvExportAction'; + if (markAsSent) this.isExportingAndMarking = true; else this.isExporting = true; + + try { + const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/${action}`, { + filters: this.filters + }, {responseType: 'blob'}); + + const url = window.URL.createObjectURL(new Blob([response.data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', markAsSent ? 'export-versand-markiert.csv' : 'export-versand.csv'); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + + if (markAsSent) { + window.notify('success', 'CSV exportiert und Einträge als versendet markiert.'); + this.$refs.table.refreshTable(); + } else { + window.notify('success', 'CSV erfolgreich exportiert.'); + } + + } catch (e) { + console.error("Error exporting CSV:", e); + window.notify('error', 'Fehler beim CSV-Export.'); + } finally { + if (markAsSent) this.isExportingAndMarking = false; else this.isExporting = false; + } + } + } +}); \ No newline at end of file