overhauled preorderlogistics
This commit is contained in:
@@ -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["<status_code"] = 800;
|
||||
$filter["deleted"] = 0;
|
||||
//$filter["connection_type"] = ["single-dwelling", "business"];
|
||||
$filter["unit_count<="] = 2;
|
||||
protected function init() {
|
||||
$this->needlogin = true;
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
$this->me = $me;
|
||||
$this->layout()->set("me", $me);
|
||||
|
||||
$installation_kit_status_flag = PreorderStatusflagModel::getFirst(["code" => "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() . '<div style="page-break-after: always;"></div>';
|
||||
}
|
||||
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) . "<br />" . htmlspecialchars(trim("{$preorder->firstname} {$preorder->lastname}")) : htmlspecialchars(trim("{$preorder->firstname} {$preorder->lastname}"));
|
||||
if ($preorder->adb_hausnummer->strasse) {
|
||||
$address .= "<br/>" . htmlspecialchars($preorder->adb_hausnummer->strasse->name) . " " . htmlspecialchars($preorder->adb_hausnummer->hausnummer);
|
||||
}
|
||||
$address .= ($preorder->adb_wohneinheit_id && $preorder->adb_wohneinheit && (string)$preorder->adb_wohneinheit) ? "<br />" . htmlspecialchars((string)$preorder->adb_wohneinheit) : "";
|
||||
if ($preorder->adb_hausnummer->plz && $preorder->adb_hausnummer->ortschaft) {
|
||||
$address .= "<br/>" . htmlspecialchars($preorder->adb_hausnummer->plz->plz) . " " . htmlspecialchars($preorder->adb_hausnummer->ortschaft->name);
|
||||
}
|
||||
if ($preorder->adb_hausnummer->strasse && $preorder->adb_hausnummer->strasse->gemeinde) {
|
||||
$address .= "<br/>" . htmlspecialchars($preorder->adb_hausnummer->strasse->gemeinde->name);
|
||||
}
|
||||
} else {
|
||||
$address = htmlspecialchars($preorder->company ?: "{$preorder->firstname} {$preorder->lastname}");
|
||||
$address .= "<br/>" . htmlspecialchars(trim("{$preorder->street} {$preorder->housenumber}"));
|
||||
$address .= "<br/>" . 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;
|
||||
}
|
||||
}
|
||||
9
public/js/pages/PreorderLogistics/PreorderLogistics.css
Normal file
9
public/js/pages/PreorderLogistics/PreorderLogistics.css
Normal file
@@ -0,0 +1,9 @@
|
||||
.sent-checkbox-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sent-checkbox-wrapper .fa-check {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
223
public/js/pages/PreorderLogistics/PreorderLogistics.js
Normal file
223
public/js/pages/PreorderLogistics/PreorderLogistics.js
Normal file
@@ -0,0 +1,223 @@
|
||||
Vue.component('preorder-logistics', {
|
||||
template: `
|
||||
<tt-card>
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h4 class="header-title mb-3">Filter</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<tt-select label="Kampagne" :options="campaigns" v-model="filters.preordercampaign_id" sm/>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<tt-select label="FCP" :options="fcps" v-model="filters.fcp" sm multiple searchable/>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<tt-select label="Versandstatus" :options="sentStatusOptions" v-model="filters.sent" sm/>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<tt-input label="Bestellcode" v-model="filters.ucode" sm/>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<tt-input label="OAID" v-model="filters.oaid" sm/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-6">
|
||||
<tt-input label="Anschlussadresse" v-model="filters.address" sm/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<tt-input label="Kunde" v-model="filters.kunde" sm/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
<tt-button text="Filter anwenden" @click="applyFilters" icon="fas fa-filter"
|
||||
additional-class="btn-primary"/>
|
||||
<tt-button text="Filter zurücksetzen" @click="resetFilters" icon="fas fa-undo"
|
||||
additional-class="btn-secondary"/>
|
||||
<tt-button text="Alle drucken" @click="printAll" icon="fas fa-print" additional-class="btn-success"
|
||||
:loading="isPrinting"/>
|
||||
<tt-button text="CSV Export" @click="exportCsv(false)" icon="fas fa-file-csv"
|
||||
additional-class="btn-success" :loading="isExporting"/>
|
||||
<tt-button text="CSV Export & als versendet markieren" @click="exportCsv(true)" icon="fas fa-file-csv"
|
||||
additional-class="btn-success" :loading="isExportingAndMarking"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<tt-table
|
||||
:fetch-url="window.TT_CONFIG.BASE_PATH + '/Preorderlogistics/getPreorders'"
|
||||
:config="tableConfig"
|
||||
ref="table"
|
||||
ssr
|
||||
>
|
||||
<template v-slot:actions="{ row }">
|
||||
<tt-button @click="printSlip(row)" sm additional-class="btn-success" icon="fas fa-print" text="Drucken"/>
|
||||
</template>
|
||||
|
||||
<template v-slot:sent="{ row }">
|
||||
<div class="sent-checkbox-wrapper">
|
||||
<tt-switch :value="row.sent" :key ="'switch-' + row.id" @input="saveSent(row.id, $event)"></tt-switch>
|
||||
<i v-if="row.sent" class="fas fa-check text-success ml-2"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:shipping_address="{ row }">
|
||||
<div v-html="row.display_address"></div>
|
||||
</template>
|
||||
</tt-table>
|
||||
</tt-card>
|
||||
`,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user