loadMe(); $this->layout()->set("me", $me); $this->me = $me; if (!$this->me->isAdmin()) { $this->redirect("dashboard"); } $this->kolmisoftMore = new KolmisoftMore($this->VOICE_PORTAL_HOST, $this->VOICE_PORTAL_API_KEY, $this->VOICE_PORTAL_USERNAME); } protected function indexAction(): void { Helper::renderVue($this, "VoiceCallHistory", $this->mod, ["VOICE_CALL_HISTORY_API_URL" => $this->getUrl("VoiceCallHistory", "api")]); } protected function apiAction() { $do = $this->request->do; if (!$this->me->isAdmin()) { $this->redirect("dashboard"); } switch ($do) { case "getCalls": $return = $this->getCalls(); break; case "importCallsFromToday": $return = $this->importCallsFromToday(); break; default: $return = false; break; } if (!$return) { $return = [ "status" => "error", "message" => "Invalid request." ]; } die(json_encode($return)); } private function importCallsFromToday(): array { $startDate = strtotime(date("Y-m-d 0:00:00")); $endDate = strtotime(date("Y-m-d 23:59:59")); $callHistory = $this->kolmisoftMore->getVoiceCallHistory($startDate, $endDate); return VoiceCallHistoryModel::importCallsFromKolmisoft($callHistory); } private function getCalls(): array { $json = json_decode(file_get_contents('php://input'), true); $filters = $json['filters'] ?? []; $order = $json['order'] ?? []; $page = $json['pagination']['page'] ?? 1; $perPage = $json['pagination']['per_page'] ?? 10; if (isset($filters['start']['from']) && isset($filters['start']['to']) && is_numeric($filters['start']['to'])) { $filters['start']['from'] += 7200; $filters['start']['to'] += 7200; } $calls = VoiceCallHistoryModel::getVoiceCallHistory($filters, $perPage, $perPage * $page - $perPage, $order); $filtered_available = VoiceCallHistoryModel::countVoiceCallHistory($filters); $totalRows = VoiceCallHistoryModel::countVoiceCallHistory([]); return [ "rows" => $calls, "pagination" => [ "page" => $page, "total_pages" => ceil($filtered_available / $perPage), "per_page" => $perPage, "filtered_available" => intval($filtered_available), "total_rows" => intval($totalRows) ] ]; } public function addContractIds() { // regex format $ignore_numbers = [ "^43664", "^43677", "^43699", "^43660", "^43676", "^43650", "^4331641220846$", "^43623237705$", "^4367761737195$", "^43216720836$", "^43623237705$", "^43318528468150$", "^4312532516$", "^43720729927$", "^4334528240030$", "^4350144522120$", "^4315460050680$", "^491795058290$", "^43346221888$", "^43346244112609$", "^43345271487$", "^43318523364$", "^4953118053397$", "^433169010$", "^433163130$", "^43345276276$", "^4371119$", "^4331638513208$", "^4350808808$", "^4334562244$", "^4331638579635$", "^4334527015385$", "^4331852888$", "^436604721650$", "^43316465611$", "^43318255088$", "^433452853656$", "^4312661274381$", "^4334528682432$", "^38640616165", "^43676848456202$", ]; $unknown_numbers = []; $in_order = []; $missing_contracts = []; $update_job_error = false; $last_calls = VoiceCallHistoryModel::getVoiceCallHistoryAsEntity([[], 1, 0, ["key" => "create", "order" => "DESC"]]); $last_call = $last_calls[0]; if($last_call->create < date("U") - 86400) { $update_job_error = $last_call->create; return false; } // get calls without contract id foreach(VoiceCallHistoryModel::getVoiceCallHistoryAsEntity(["contract_id" => null, "billable" => "1", "duration" => ["from" => 1]]) as $call) { //var_dump($call);exit; //echo "\n"; $number = $call->voice_account; if(!$number) continue; $pattern = implode("|", $ignore_numbers); if(preg_match("/($pattern)/", $number)) { continue; } // server side failed/disconnected calls if($call->duration == 1 && $call->state == 38) continue; if(in_array($number, $unknown_numbers)) continue; $voicenumber = VoicenumberModel::getFirst(["number" => $number]); // TODO: Mail an office if(!$voicenumber) { $op = OrderProductModel::getFirst(["voicenumber%" => $number]); if($op) { if(!in_array($number . " (order id " . $op->order_id . ")", $in_order)) { $in_order[] = $number . " (order id " . $op->order_id . ")"; } } else { $unknown_numbers[] = $number; } $this->log->debug(__METHOD__.": Voicenumber $number not found."); continue; } if(!$voicenumber->contract_id) { $missing_contracts[] = $number; $this->log->debug(__METHOD__.": Missing Contract_ID in Voicenumber ".$voicenumber->number); continue; } $contract = new Contract($voicenumber->contract_id); if(!$contract) { $this->log->debug(__METHOD__.": No Contract with Contract_ID ".$voicenumber->contract_id." in Voicenumber ".$voicenumber->number); continue; } if($contract->isCancelled()) { // mail an office $this->log->warning(__METHOD__.": Contract ".$voicenumber->contract_id." for Voicenumber ".$voicenumber->number." is cancelled!"); } $calldate = new DateTime($call->start); $calldate->setTimezone(new DateTimeZone("Europe/Vienna")); // calls from before first IVT Import must be right, we don't have historic contract data if($calldate->format("Y-m") < "2024-08") { $call->contract_id = $contract->id; //echo "save 1\n"; if(!$call->save()) { die("Cannot save call ".$call->id); } continue; } // check if contract was active at this time ... if($calldate->getTimestamp() <= $contract->finish_date && (!$contract->cancel_date || $calldate->getTimestamp() <= $contract->cancel_date)) { // 2023-08 is the oldest we can know because of contract import in July 2024 $call->contract_id = $contract->id; //echo "save 2\n"; $call->save(); } else { //echo "Kann Zeit nicht zu contract zuordnern: ".$call->start." contract id ".$contract->id."\n"; } // TODO // ... else look for contract with this number active at that time ... // ... else use current active contract if(!$contract) { // find contract by ContractConfigValue voicenumberblock_voicenumber } $call->contract_id = $voicenumber->contract_id; $call->save(); } // set System value voicecallhistory.contact-job.ts $ts = new mfConfig("voicecallhistory.contact-job.ts"); $ts->type("int"); $ts->value(date("U")); $ts->save(); if(count($missing_contracts) || count($unknown_numbers) || count($in_order) || $update_job_error) { $to = "backoffice@xinon.at"; $from = "noreply@xinon.at"; $subject = "Rufnummern nicht zuweisbar"; if($update_job_error) { $body = "VoicecallHistory Update Job ist zuletz am ".date("Y-m-d H:i"). " gelaufen\n"; } else { $body = "Für folgende Nummern konnte kein Contract gefunden werden:"; if (count($unknown_numbers)) { $body .= "\n\nUnbekannte Nummern:\n"; foreach ($unknown_numbers as $number) { $body .= $number . "\n"; } } if (count($missing_contracts)) { $body .= "\n\nNummern in keinem Contract:\n"; foreach ($missing_contracts as $number) { $body .= $number . "\n"; } } if (count($in_order)) { $body .= "\n\nNummern in Bestellung:\n"; foreach ($in_order as $number) { $body .= $number . "\n"; } } } $email = new Emailnotification(); $email->setFrom($from); $email->setTo($to); $email->setSubject($subject); $email->setBody($body); $email->send(); } } }