Files
assetmgt/assets/functions.php
2024-12-20 16:11:27 +01:00

2916 lines
101 KiB
PHP

<?php
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// PDF creator +++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// include autoloader
require_once dirname(__FILE__).'/dompdf/autoload.inc.php';
// reference the Dompdf namespace
use Dompdf\Dompdf;
// instantiate and use the dompdf class
use Dompdf\Options;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Generated PDF ++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function generatedPDF($input,$historyID,$email){
$options = new Options();
$options->set('isRemoteEnabled', true);
$dompdf = new Dompdf($options);
$dompdf->loadHtml($input);
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'portrait');
// Render the HTML as PDF
$dompdf->render();
$attachment = $dompdf->output();
$to = $email;
$subject = 'Servicereport -'.$historyID;
$message = $input;
$attachment_name = 'Servicereport -'.$historyID.'.pdf';
//Send email
if (!empty($email)){
send_mail($to, $subject, $message, $attachment, $attachment_name);
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// include PHP Mailer
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require dirname(__FILE__).'/mail/PHPMailer.php';
require dirname(__FILE__).'/mail/SMTP.php';
require dirname(__FILE__).'/mail/Exception.php';
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Send Mail via PHPMailer++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function send_mail($to, $subject, $message, $attachment, $attachment_name){
include_once dirname(__FILE__,2).'/settings/config.php';
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
//$mail->isSMTP(); // Use SMTP protocol
$mail->Host = email_host_name; // Specify SMTP server
$mail->SMTPAuth = true; // Auth. SMTP
$mail->Username = email; // Mail who send by PHPMailer
$mail->Password = email_outgoing_pw; // your pass mail box
$mail->SMTPSecure = email_outgoing_security; // Accept SSL
$mail->Port = email_outgoing_port; // port of your out server
$mail->setFrom(email, mail_from); // Mail to send at
$mail->addAddress($to); // Add sender
$mail->addReplyTo(email_reply_to); // Adress to reply
$mail->isHTML(true); // use HTML message
$mail->Subject = $subject;
$mail->Body = $message;
if (!empty($attachment) || $attachment != ''){
$mail->AddStringAttachment($attachment, $attachment_name, 'base64', 'application/pdf');
}
// SEND
if( !$mail->send() ){
// render error if it is
$tab = array('error' => 'Mailer Error: '.$mail->ErrorInfo );
echo json_encode($tab);
exit;
}
else{
// return true if message is send
return true;
}
}
//------------------------------------------
// Global functions
//------------------------------------------
function dbConnect($dbcon) {
include dirname(__FILE__,2).'/settings/settings.php';
try {
// Connect to the MySQL database using the PDO interface
$pdo = new PDO('mysql:host=' . $db . ';dbname=' . $dbcon . ';charset=utf8', $dbuser, $dbpw);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch (PDOException $exception) {
// Could not connect to the MySQL database! If you encounter this error, ensure your db settings are correct in the config file!
exit('Failed to connect to database!');
}
}
//------------------------------------------
// Determine URL function
//------------------------------------------
function url($url) {
if (rewrite_url) {
$url = preg_replace('/\&(.*?)\=/', '/', str_replace(['index.php?page=', 'index.php'], '', $url));
}
return base_url . $url;
}
//------------------------------------------
// Routing function
//------------------------------------------
function routes($urls) {
foreach ($urls as $url => $file_path) {
$url = '/' . ltrim($url, '/');
$prefix = dirname($_SERVER['PHP_SELF']);
$uri = $_SERVER['REQUEST_URI'];
if (substr($uri, 0, strlen($prefix)) == $prefix) {
$uri = substr($uri, strlen($prefix));
}
$uri = '/' . ltrim($uri, '/');
$path = explode('/', parse_url($uri)['path']);
$routes = explode('/', $url);
$values = [];
foreach ($path as $pk => $pv) {
if (isset($routes[$pk]) && preg_match('/{(.*?)}/', $routes[$pk])) {
$var = str_replace(['{','}'], '', $routes[$pk]);
$routes[$pk] = preg_replace('/{(.*?)}/', $pv, $routes[$pk]);
$values[$var] = $pv;
}
}
if ($routes === $path && rewrite_url) {
foreach ($values as $k => $v) {
$_GET[$k] = $v;
}
return file_exists($file_path) ? $file_path : 'dashboard.php';
}
}
if (rewrite_url) {
header('Location: ' . url('index.php'));
exit;
}
return null;
}
//------------------------------------------
// Menu Builder
//------------------------------------------
function menu($selected,$selected_child){
include dirname(__FILE__,2).'/settings/settings.php';
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
$profile = explode(',',$_SESSION['profile']);
//Define Menu
$menu = '';
foreach ($main_menu as $menu_item){
if (in_array($item = $menu_item, $profile,)){
//Main URL
$menu .= '<a href="index.php?page='.$urls[$item]['url'].'"' . ($selected == $urls[$item]['selected'] ? ' class="selected"' : '') . '><i class="'.$urls[$item]['icon'].'"></i>'.ucfirst((${$urls[$item]['name']}?? 'not specified')).'</a>';
//DEFINE SUBMENU
$sub_menu = $item.'_sub' ?? '';
$sub_menu = (isset($$sub_menu) && $$sub_menu !='')? $$sub_menu : 0;
//CHECK IF SUBMENU EXIST
if ($sub_menu !=0){
$menu .= '<div class="sub" ' . ($selected == $urls[$item]['selected'] ? ' class="selected"' : '') . '>';
foreach($sub_menu as $key){
//CHECK IF USER IS ALLOWED
if (in_array($key,$profile)){
$menu .= '<a href="index.php?page='.$urls[$key]['url'].'"' . ($selected == $urls[$key]['selected'] && $selected_child == 'view' ? ' class="selected"' : '') . '><span>&#9724;</span>'.ucfirst((${$urls[$key]['name']}?? 'not specified')).'</a>';
}
}
$menu .= '</div>';
}
}
}
return $menu;
}
//------------------------------------------
// Template Header
//------------------------------------------
function template_header($title, $selected = 'assets', $selected_child = 'view') {
$base_url = 'https://'.$_SERVER['SERVER_NAME'].'/';
$site_name = site_name;
$site_name_footer = site_name_footer;
$icon_image = icon_image;
$admin_links = menu($selected,$selected_child);
$user = ucfirst($_SESSION['username']);
if (filter_var($user, FILTER_VALIDATE_EMAIL)){
$user = substr($user, 0, strpos($user, "@"));
}
if (isset($_SESSION['id'])){$id = $_SESSION['id'];} else{$id='';}
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
$profile = $general_profile;
$logout = $general_logout;
$veliti_analytics = '';
if (veliti_analytics){
$veliti_analytics = '<script src="./assets/analytics.js"></script>';
}
echo <<<EOT
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1">
<title>$title</title>
<link rel="icon" type="image/png" href="$icon_image">
<link href="./style/admin.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="./style/leaflet.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v6.6.0/css/all.css">
<script src="./assets/leaflet.js"></script>
<script src="./assets/charts.js"></script>
$veliti_analytics
</head>
<body class="admin">
<aside class="responsive-width-100 responsive-hidden">
<h1></h1>
$admin_links
<div class="footer">
$site_name_footer
</div>
</aside>
<main class="responsive-width-100">
<header>
<a class="responsive-toggle" href="#">
<i class="fas fa-bars"></i>
</a>
<div class="space-between"></div>
<div class="dropdown right">
<div>
<i class="fas fa-user-circle"></i>
$user
</div>
<div class="list">
<a href="index.php?page=profile">$profile</a>
<a href="index.php?page=logout">$logout</a>
</div>
</div>
</header>
EOT;
}
//------------------------------------------
// Template footer
//------------------------------------------
function template_footer($js_script = '') {
$js_script = $js_script ? '<script>' . $js_script . '</script>' : '';
$lancode = $_SESSION['language'] ?? 'US';
$user_mail = $_SESSION['email'] ?? '';
$veliti_cim = '';
if (veliti_cim){
$veliti_cim = '<iframe src="https://change.veliti.nl/request_popup.php?language='.$lancode.'&email='.$user_mail.'" style="border: solid 1px;border-radius: 5px;min-width:400px;min-height:400px;"></iframe>';
}
// DO NOT INDENT THE BELOW CODE
echo <<<EOT
</main>
<button id="support_btn" class="btn" style="opacity: 0.8;position: fixed;bottom: 23px;right: 28px;background:#4a79b400;font-size:36px;z-index:999;" onclick="openForm()"><img src="./assets/images/tss-persoon.svg" alt="tss-persoon" height="115"></button>
<div class="form-popup" id="request">$veliti_cim
<div class="close">
<button type="button" style="border: solid 1px;" onclick="closeForm()">X</button>
</div>
</div>
<script src="./assets/admin.js"></script>
{$js_script}
<script>
function openForm() {
document.getElementById("request").style.display = "block";
}
function closeForm() {
document.getElementById("request").style.display = "none";
}
</script>
</body>
</html>
EOT;
}
//------------------------------------------
// Secure Payload
//------------------------------------------
function generate_payload($payload) {
include dirname(__FILE__,2).'/settings/settings.php';
$headers = array('alg'=>'HS256','typ'=>'payload');
$payload = array('payload'=>$payload,'exp'=>(time() + 1200));
$headers_encoded = base64url_encode(json_encode($headers));
$payload_encoded = base64url_encode(json_encode($payload));
$signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $secret, true);
$signature_encoded = base64url_encode($signature);
$payload_input = "$headers_encoded.$payload_encoded.$signature_encoded";
return $payload_input;
}
//------------------------------------------
//ENCRYPT PAYLOAD
//------------------------------------------
function encrypt($input, $password) {
//CHECK IF INPUT IS ARRAY => THEN SERIALIZE INPUT
if (is_array($input)){
$input = serialize($input);
}
$method = "AES-256-CBC";
$key = hash('sha256', $password, true);
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv);
$hash = hash_hmac('sha256', $ciphertext . $iv, $key, true);
return $iv . $hash . $ciphertext;
}
//------------------------------------------
// Decode Payload
//------------------------------------------
function decode_payload($payload_input) {
include dirname(__FILE__,2).'/settings/settings.php';
// split the jwt
$tokenParts = explode('.', $payload_input);
$header = base64_decode($tokenParts[0]);
$payload = base64_decode($tokenParts[1]);
$signature_provided = $tokenParts[2];
$expiration = json_decode($payload)->exp;
$is_token_expired = ($expiration - time()) < 0;
// build a signature based on the header and payload using the secret
$base64_url_header = base64url_encode($header);
$base64_url_payload = base64url_encode($payload);
$signature = hash_hmac('SHA256', $base64_url_header . "." . $base64_url_payload, $secret, true);
$base64_url_signature = base64url_encode($signature);
// verify it matches the signature provided in the jwt
$is_signature_valid = ($base64_url_signature === $signature_provided);
if ($is_token_expired || !$is_signature_valid) {
return FALSE;
} else {
$tokenParts = explode('.', $payload_input);
$payload = base64_decode($tokenParts[1]);
return $payload_decoded = json_decode($payload)->payload;
}
}
//------------------------------------------
// Decrypt payload
//------------------------------------------
function decrypt($ivHashCiphertext, $password) {
$method = "AES-256-CBC";
$iv = substr($ivHashCiphertext, 0, 16);
$hash = substr($ivHashCiphertext, 16, 32);
$ciphertext = substr($ivHashCiphertext, 48);
$key = hash('sha256', $password, true);
if (!hash_equals(hash_hmac('sha256', $ciphertext . $iv, $key, true), $hash)) return null;
$decrypted = openssl_decrypt($ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv);
//UNSERIALE AND CHECK IF
$data = @unserialize($decrypted);
if ($data !== false) {
$decrypted = unserialize($decrypted);
}
//RETURN DECRYPTED DATA
return $decrypted;
}
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
//------------------------------------------
// JWT Function for CommunicationTOken
//------------------------------------------
function generate_jwt($headers, $payload) {
include dirname(__FILE__,2).'/settings/settings.php';
$headers_encoded = base64url_encode(json_encode($headers));
$payload_encoded = base64url_encode(json_encode($payload));
$signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $secret, true);
$signature_encoded = base64url_encode($signature);
$jwt = "$headers_encoded.$payload_encoded.$signature_encoded";
return $jwt;
}
function is_jwt_valid($jwt) {
include dirname(__FILE__,2).'/settings/settings.php';
// split the jwt
$tokenParts = explode('.', $jwt);
$header = base64_decode($tokenParts[0]);
$payload = base64_decode($tokenParts[1]);
$signature_provided = $tokenParts[2];
$expiration = json_decode($payload)->exp;
$is_token_expired = ($expiration - time()) < 0;
// build a signature based on the header and payload using the secret
$base64_url_header = base64url_encode($header);
$base64_url_payload = base64url_encode($payload);
$signature = hash_hmac('SHA256', $base64_url_header . "." . $base64_url_payload, $secret, true);
$base64_url_signature = base64url_encode($signature);
// verify it matches the signature provided in the jwt
$is_signature_valid = ($base64_url_signature === $signature_provided);
if ($is_token_expired || !$is_signature_valid) {
return FALSE;
} else {
return TRUE;
}
}
//------------------------------------------
// createCommunicationToken
//------------------------------------------
function createCommunicationToken($input){
$headers = array('alg'=>'HS256','typ'=>'JWT');
$payload = array('token'=>$input, 'exp'=>(time() + 2100));
$token = generate_jwt($headers, $payload);
return $token;
}
//------------------------------------------
// getUserKey
//------------------------------------------
function getUserKey($jwt){
include dirname(__FILE__,2).'/settings/settings.php';
$tokenParts = explode('.', $jwt);
$payload = base64_decode($tokenParts[1]);
$token = json_decode($payload)->token;
return $token;
}
//------------------------------------------
// get_bearer_token
//------------------------------------------
function get_authorization_header(){
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER["Authorization"]);
} else if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
} else if (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
return $headers;
}
function get_bearer_token() {
$headers = get_authorization_header();
if (!empty($headers)) {
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
return $matches[1];
}
}
return null;
}
//------------------------------------------
// APIto/fromServer
//------------------------------------------
function ioServer($api_call, $data){
include dirname(__FILE__,2).'/settings/settings.php';
$token = $_SESSION['userkey'] ?? 'authorization_request';
$bearertoken = createCommunicationToken($token);
$url = $baseurl.$api_call;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"Authorization: Bearer $bearertoken",
"Content-Type: application/json",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
$resp = curl_exec($curl);
$http_status = curl_getinfo($curl) ?? '200';
curl_close($curl);
//Check If errorcode is returned
if($http_status['http_code'] == '403' || $http_status['http_code'] == '400') {$resp = generate_payload('NOK');}
if (debug){
$message = $date.';'.$api_call;
debuglog($message);
}
//Response
return $resp;
}
//------------------------------------------
// API TO API version 1
//------------------------------------------
function ioAPI($api_call, $data, $token){
include dirname(__FILE__,2).'/settings/settings.php';
$bearertoken = createCommunicationToken($token);
$url = $baseurl.$api_call;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"Authorization: Bearer $bearertoken",
"Content-Type: application/json",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
$resp = curl_exec($curl);
$http_status = curl_getinfo($curl) ?? '200';
curl_close($curl);
//Check If errorcode is returned
if($http_status['http_code'] == '403' || $http_status['http_code'] == '400') {$resp = generate_payload('NOK');}
if (debug){
$message = $date.';'.$api_call;
debuglog($message);
}
//Response
return $resp;
}
//------------------------------------------
// API TO API version 2
//------------------------------------------
function ioAPIv2($api_call, $data, $token){
include dirname(__FILE__,2).'/settings/settings.php';
$token = (!empty($token) || $token !='')? $token : 'authorization_request';
$bearertoken = createCommunicationToken($token);
$url = $baseurl.$api_call;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"Authorization: Bearer $bearertoken",
"Content-Type: application/json",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
$resp = curl_exec($curl);
$http_status = curl_getinfo($curl) ?? '200';
curl_close($curl);
//Check If errorcode is returned
if($http_status['http_code'] == '403' || $http_status['http_code'] == '400') {$resp = json_encode('NOK');}
if (debug){
$message = $date.';'.$api_call;
debuglog($message);
}
//Response
return $resp;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//get user profile||$profile=settings, $permision = userright()
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getProfile($profile, $permission){
include_once dirname(__FILE__,2).'/settings/config.php';
if ($profile != ''){
$profile = (defined($profile)) ? constant($profile) : standard_profile;
}
else {
switch ($permission) {
case '4': //Admin++
$profile = adminplus_profile;
break;
case '3': //Admin
$profile = admin_profile;
break;
case '2': //Super User
$profile = superuser_profile;
break;
default: // Readonly & create&update
$profile = standard_profile;
break;
}
}
return $profile;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Is allowed (yes=1)++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function isAllowed($page,$profile,$permission,$action){
//Include settingsa
include dirname(__FILE__,2).'/settings/settings.php';
//GET ALLOWED ACTIONS
$user_permission = ${'permission_'.$permission};
//CHECK ALLOWED
$page_action = str_contains($user_permission,$action) > 0 ? 1 : 0;
$page_access = str_contains($profile,$page) > 0 ? 1 : 0;
//RETURN CODE
if ($page_access == 1 && $page_action == 1){
$user_access = 1;
} else {
//Not Allowed
$user_access = 0;
}
return $user_access;
}
//------------------------------------------
// userRight standaridazation helper
//------------------------------------------
function userRights($input){
// From User assigned view gets allowed data view level
// Admin and Admin+ = all - levels
// SuperUser = soldto - and lower
// CreateUpdate = shipto and lower
// Read-only = shipto and lower
$permission = '';
switch ($input) {
case '1':
//SuperUser
$permission = 2;
break;
case '2':
//create & update
$permission = 1;
break;
case '3':
//read-only
$permission = 0;
break;
case '4':
//admin
$permission = 3;
break;
case '5':
//admin
$permission = 4;
break;
}
return $permission;
}
//------------------------------------------
// Retrieve all $_GET from URL
//------------------------------------------
function urlGETdetails($input){
//GET Details from URL
if(isset($input) && !empty($input)){
$GET_VALUES = '';
foreach ($input as $KEY => $VALUE){
$GET_VALUES .= $KEY.'='.$VALUE;
$GET_VALUES .= '&';
}
return $GET_VALUES = rtrim($GET_VALUES, "&");
}
else {
return $GET_VALUES = '';
}
}
//------------------------------------------
// Retrieve all $_GET from URL for FILTER AND SORT
//------------------------------------------
function urlGETdetailsFilter($input){
if(isset($input) && !empty($input)){
$view = '';
foreach ($_GET as $key => $value){
if ($key != 'search'){
$view .= '<input type="hidden" name="'.$key.'" value="'.$value.'">';
}
}
return $view;
}
else {
return $view = '';
}
}
//------------------------------------------
// Translate name of Partner
//------------------------------------------
function getPartnerName($str){
if (!empty($str)){
$prefix = strtok($str, '-').'-';
if (str_starts_with($str, $prefix)) {
$str2 = substr($str, strlen($prefix));
}
else {
$str2 = $str;
}
return $str2;
}
}
//------------------------------------------
// overview Indicators
//------------------------------------------
function overviewIndicators($warranty, $service, $sw_version, $sw_version_latest){
include dirname(__FILE__,2).'/settings/settings.php';
include dirname(__FILE__,2).'/settings/systemfirmware.php';
$indicator ='';
//In warranty
if (!empty($warranty ) && $warranty > $warrantydate){
$indicator .= '<span class="dot" style="background-color: #13b368;">W</span>';
} else {
$indicator .= '<span class="dot" style="background-color: #eb8a0d;">W</span>';
}
//Out of Service
if (!empty($service) && $service < $servicedate){
$indicator .= '<span class="dot" style="background-color: #eb8a0d;">S</span>';
} else {
$indicator .= '<span class="dot" style="background-color: #13b368;">S</span>';
}
//Firmware
if (isset($sw_version_latest)){
if($sw_version_latest == 1){
$indicator .= '<span class="dot" style="background-color: #13b368;">F</span>';
} else {
if ($sw_version == ''){
$indicator .= '<span class="dot" style="background-color: #81848a">F</span>';
} else {
$indicator .= '<span class="dot" style="background-color: #eb8a0d;">F</span>';
}
}
}
return $indicator;
}
//------------------------------------------
// Check service status
//------------------------------------------
function warrantyStatus($input){
include dirname(__FILE__,2).'/settings/settings.php';
//INCLUDE TRANSLATION FILE
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
$warranty_date_due ='<span class="status">Unknown</span>';
if (!empty($input) && $input < $warrantydate){
$warranty_date_due = '<span class="status warranty_outdated">'.$warranty_outdated_text.'</span>';
} else {
$warranty_date_due ='<span class="status warranty">'.$warranty_recent.' ('.date('Y-m-d', strtotime($input. ' + 365 days')).')</span>';
}
return $warranty_date_due;
}
//------------------------------------------
// Check service status
//------------------------------------------
function serviceStatus($input){
include dirname(__FILE__,2).'/settings/settings.php';
//INCLUDE TRANSLATION FILE
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
$service_date_due ='<span class="status">Unknown</span>';
if (!empty($input) && $input < $servicedate){
$service_date_due = '<span class="status service_renewal">'.$service_renewal_text.'</span>';
} else {
$service_date_due ='<span class="status service">'.$service_recent.' ('.date('Y-m-d', strtotime($input. ' + 365 days')).')</span>';
}
return $service_date_due;
}
//------------------------------------------
// Check available firmware
//------------------------------------------
function availableFirmware($sw_version,$sw_version_latest){
//INCLUDE TRANSLATION FILE
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
switch ($sw_version_latest) {
case 1:
$message = '<span class="status firmware_recent">'.$firmware_recent_text.'</span>';
break;
case 0:
$message = '<span class="status firmware_update">'.$firmware_update_text.'</span>';
break;
default:
$message ='<span class="status">Unknown</span>';
break;
}
return $message;
}
//------------------------------------------
// show serviceEvents available
//------------------------------------------
function serviceEvents ($messages,$page){
include dirname(__FILE__,2).'/settings/settings.php';
//INCLUDE TRANSLATION FILE
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
$view_header = '<table class="sortable">
<thead>
<tr>
<th>'.$equipment_label2.'</th>
<th>'.$equipment_label8.'</th>
<th>'.$equipment_label9.'</th>
<th>'.$equipment_label3.'</th>
<th>'.$general_createdby.'</th>
<th>'.$general_created.'</th>
<th>'.$view_asset_actions.'</th>
</tr>
</thead>
<tbody>';
$view_data = '';
foreach ($messages as $message){
if ($message->type == $type14 && str_contains($message->description, 'serialnumber')){
//Get service date
$service_date = (new DateTime($message->created))->format('Y-m-d');
$service_renewal_date = (new DateTime($message->created))->modify('+365 days')->format('Y-m-d');
$TETS = json_decode($message->description);
$test = $TETS->maintenance_test ?? '';
//+++++++++++++++++++++++++++++++++++++++++++++++
// Maintenance Test
//++++++++++++++++++++++++++++++++++++++++++++++
//GET from DB
$pdo = dbConnect($dbname);
$sql = 'SELECT description FROM equipment_history WHERE rowID = "'.$test.'"';
$stmt = $pdo->query($sql);
$stmt->execute();
$result = $stmt->fetch();
$test_string = $result['description'] ?? '';
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Check if false test found
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (str_contains($test_string, "false")){
$service_status = '<span class="status warranty_outdated">'.$service_report_outcome_attention.'</span>';
$service_renewal_date = $service_report_outcome_attention; // leave service-renewal empty when errors are found
} else {
$service_status = '<span class="status warranty">'.$service_report_outcome_good.'</span>';
}
$view_data .= '<tr>
<td>'.$TETS->serialnumber.'</td>
<td>'.$service_date.'</td>
<td>'.$service_renewal_date.'</td>
<td>'.$service_status.'</td>
<td>'.$message->createdby.'</td>
<td>'.getRelativeTime($message->created).'</td>
<td><a href="index.php?page=servicereport&equipmentID='.$message->equipmentID.'&historyID='.$message->historyID.'" class="btn_link">'.$general_view.'</a></td>
<td><a href="index.php?page=render_service_report&historyID='.$message->historyID.'" class="btn_link">PDF</a></td>
</tr>';
}
}
//CHECK IF OUTPUT IS MORE THAN X (config setting)
if (count($messages) == $page_rows_equipment_servicereporst && $page == 'equipment'){
$view_data .= '<tr>
<td><a href="index.php?page=servicereports&equipmentid='.$message->h_equipmentid.'" class="btn_link">'.$general_actions_more.'</a></td>
</tr>';
}
if ($view_data == ''){
$view_data = '<tr>
<td colspan="4" style="text-align:center;">'.$service_report_no_text.'</td>
</tr>';
}
$view_data .= '</tbody>';
$view_footer = '</table>';
$view = $view_header.$view_data.$view_footer;
return $view;
}
//------------------------------------------
// Service report //Input = servicereport
//------------------------------------------
function serviceReport($history, $request, $country_code)
{
if(isset($country_code) && $country_code != ''){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($country_code).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
include dirname(__FILE__,2).'/settings/settings.php';
include dirname(__FILE__,2).'/settings/systemservicetool.php';
$json_array = json_decode($history->description);
$service_exe_date = (new DateTime($history->created))->format('Y-m-d');
$service_renewal_date = (new DateTime($history->created))->modify('+365 days')->format('Y-m-d');
if (isset($json_array->maintenance_test)) {
//Get Maintenance Test directly from DB
$pdo = dbConnect($dbname);
$stmt = $pdo->prepare('SELECT description FROM equipment_history WHERE rowID = ?');
$stmt->execute([$json_array->maintenance_test]);
$maintenance_test = $stmt->fetch();
$test_fail = $maintenance_test['description'];
$maintenance_test = json_decode($maintenance_test['description']);
//check if maintenance test has false test and update renewal date
if (str_contains($test_fail, "false")){
$service_renewal_date = $service_report_outcome_attention; ;
}
}
$servicereport = ''; //empty string
if ($request != 'display'){
$servicereport .= '
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
@page {margin: 220px 50px; }
body {
font-family: "DejaVu Sans", system-ui, sans-serif;
color: #035754;
font-size: 18px;
line-height: 1.5;
}
.servicereport {
border-collapse: collapse;
width: 100%;
border-radius: 5px;
border-style: hidden;
margin: auto;
background-color: #fff;
margin-top: 20px;
}
.servicereport.fs-normal td {
font-size: 18px;
}
.servicereport.fs-small td {
font-size: 14px;
}
.servicereport thead {
background-color: #2fac66;
color: #fff;
}
.servicereport td {
padding: 5px 15px;
}
.servicereport thead td {
font-weight: bold;
}
.servicereport tbody td.success {
text-decoration: underline;
text-decoration-thickness: 2px;
text-decoration-color: #3ead48;
text-underline-offset: 2px;
}
.servicereport tbody td.warning {
text-decoration: underline;
text-decoration-thickness: 2px;
text-decoration-color: #ffc107;
text-underline-offset: 2px;
}
.servicereport tbody td.error {
text-decoration: underline;
text-decoration-thickness: 2px;
text-decoration-color: #d1232a;
text-underline-offset: 2px;
}
.servicereport .col-key {
width: 70%;
}
.servicereport .col-value {
width: 30%;
}
.servicereport--details tbody tr {
border-bottom: 1px solid #035754;
}
.servicereport--striped tbody tr:nth-child(odd) {
background-color: #f3fafa;
}
.servicereport--striped tbody tr:nth-child(even) {
background-color: #e7f6f6;
}
.servicereport--striped tbody tr {
border-bottom: 1px solid #9bdcd9;
}
.service_summary {
background-image: linear-gradient(#e7f6f6, #fafdfd);
margin-top: 20px;
padding-bottom: 15px;
}
.service_summary__title {
background-color: #035754;
color: #fff;
font-weight: bold;
padding: 5px 15px;
}
.service_notes {
margin: 15px 15px 0 15px;
padding: 15px;
background-color: #fff;
color: #035754;
}
#content {
width: 100%;
margin: auto;
}
#header {
position: fixed;
left: -50px;
top: -220px;
right: -50px;
height: 200px;
text-align: center;
border-radius: 5px;
}
#header h1 {
color: #fff;
font-weight: bold;
margin: auto;
}
#header img {
width: 100%;
}
#footer {
position: fixed;
left: -50px;
bottom: -280px;
right: -50px;
height: 150px;
border-radius: 5px;
}
#footer img {
width: 100%;
}
#footer .page:after {
content: counter(page, upper-roman);
}
.page-break {
page-break-before: always;
}
.text-center {
text-align: center;
}
h4 {
margin-top: 0;
}
h4.label {
padding: 5px 15px;
background-color: #035754;
color: #fff;
margin-top: 20px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div id="header">
<img src="https://'.$portalURL.'/assets/images/servicereport.png" alt="Service report">
</div>
<div id="footer">
<img src="https://'.$portalURL.'/assets/images/servicereport-footer.png" alt="Service report">
</div>';
}
$servicereport .= '
<div id="content">
<table id="" class="fs-normal servicereport servicereport--details">
<thead>
<tr>
<td class="col-key">'.$service_report_item.'</td>
<td class="col-value">&nbsp;</td>
</tr>
</thead>
<tbody>
<tr>
<td class="col-key">'.$service_report_id.'</td>
<td class="col-value">'.$history->historyID.'</td>
</tr>
<tr>
<td class="col-key">'.$service_serialnumber.'</td>
<td class="col-value">'.$json_array->serialnumber.'</td>
</tr>
<tr>
<td class="col-key">'.$service_date.'</td>
<td class="col-value">'.$service_exe_date.'</td>
</tr>
<tr>
<td class="col-key">'.$service_renewal.'</td>
<td class="col-value">'.$service_renewal_date.'</td>
</tr>
<tr>
<td class="col-key">'.$service_performed_by.'</td>
<td class="col-value">'.$history->createdby.'</td>
</tr>
</tbody>
</table>
<div id="service_summary" class="service_summary">
<div class="service_summary__title">'.$summary_label1.'</div>
<ul>
';
$actions = 0;
$repairs = 0;
//Check New Report or Legacy
if (str_contains($history->description, "service_mandatory_question")) {
// New Report
foreach ($json_array->final as $final) {
if ($final->id == "service_action_clean" && $final->value == 1) {
$servicereport .= '<li>' . $service_action_clean . '</li>';
$actions++;
}
if ($final->id == "service_action_battery" && $final->value == 1) {
$servicereport .= '<li>' . $service_action_battery . '</li>';
$actions++;
}
}
} elseif (str_contains($history->description, "question25") && !str_contains($history->description, "newHistory")) {
foreach ($json_array->final as $final) {
if (($final->id == "action_clean" ||$final->id == "action_serial") && $final->value == 'Yes'){
$servicereport .= '<li>' . ${$final->id . '_description'}. '</li>';
$actions++;
}
}
}
if ($actions == 0) {$servicereport .= '<li>'.$message1.'</li>';}
$servicereport .= '
</ul>
<div class="service_summary__title">'.$group_header_8.'</div>
<ul>
';
if (str_contains($history->description, "service_mandatory_question")) {
foreach ($json_array->final as $final) {
if ($final->id == "service_action_serial" && $final->value == 1) {
$servicereport .= '<li>' . $service_action_serial . '</li>';
$repairs++;
}
if ($final->id == "service_action_cover" && $final->value == 1) {
$servicereport .= '<li>' . $service_action_cover . '</li>';
$repairs++;
}
if ($final->id == "service_action_spudger" && $final->value == 1) {
$servicereport .= '<li>' . $service_action_spudger . '</li>';
$repairs++;
}
if ($final->id == "service_action_case" && $final->value == 1) {
$servicereport .= '<li>' . $service_action_case . '</li>';
$repairs++;
}
if ($final->id == "service_action_instructions" && $final->value == 1) {
$servicereport .= '<li>' . $service_action_instructions . '</li>';
$repairs++;
}
}
} elseif (str_contains($history->description, "question25") && !str_contains($history->description, "newHistory")) {
foreach ($json_array->final as $final) {
if (strpos($final->id, "action_repaired") !==false && $final->value == 'Yes') {
$servicereport .= '<li>' . ${$final->id . '_description'}. '</li>';
$repairs++;
}
if (strpos($final->id, "action_replacement") !==false && $final->value == 'Yes') {
$servicereport .= '<li>' . ${$final->id . '_description'}. '</li>';
$repairs++;
}
}
}
if ($repairs == 0) {$servicereport .= '<li>' . $message2 . '</li>';}
$servicereport .='</ul>';
if (str_contains($history->description, "service_mandatory_question")) {
//GET NOTES from JSON
$notes ='';
foreach ($json_array->final as $final){
if ($final->id == "service_notes"){
$notes = $final->value;
}
}
$servicereport .='
<div class="service_summary__title">'.$group_header_7.'</div>';
if ($notes != '') {
$servicereport .= '<div id="service_notes" class="service_notes">'.$notes.'</div>';
} else {
$servicereport .= '<div id="service_notes" class="service_notes">'.$service_report_no_comments.'</div>'; }
}
$servicereport .= '</div>';
//+++++++++++++++++++++++++++++++++++++++++++++++
// Maintenance Test
//++++++++++++++++++++++++++++++++++++++++++++++
if (isset($json_array->maintenance_test)) {
if (!empty($maintenance_test)) {
$servicereport .='
<div class="page_break"></div>
<table id="" class="fs-small servicereport servicereport--striped">
<thead>
<tr>
<td class="col-key">'.$service_report_maintenance_test.'</td>
<td class="col-value text-center">'.$service_report_maintenance_test_status.'</td>
</tr>
</thead>
';
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Check for measurements ++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Check if false test found +++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
$servicereport .= '<tbody>';
//Check double test values
foreach($maintenance_test->doubletestvalues as $key => $value)
{
//If test is not passed or not
if($value->pass == false){
$text = $service_maintenance_test_fail;
$style = 'error';
}
else
{
$text = $service_maintenance_test_pass;
$style = 'success';
}
$servicereport .='
<tr>
<td class="col-key">'.$value->name.'</td>
<td class="col-value text-center '.$style.'">'.$text.'</td>
</tr>
';
}
//Check string test values
foreach($maintenance_test->stringtestvalues as $key => $value)
{
//If test is not passed or not
if($value->pass == false){
$text = $service_maintenance_test_fail;
$style = 'error';
}
else
{
$text = $service_maintenance_test_pass;
$style = 'success';
}
$servicereport .='
<tr>
<td class="col-key">'.$value->name.'</td>
<td class="col-value text-center '.$style.'">'.$text.'</td>
</tr>
';
}
//Check boolean test values
foreach($maintenance_test->booleantestvalues as $key => $value)
{
//If test is not passed or not
if($value->pass == false){
$text = $service_maintenance_test_fail;
$style = 'error';
}
else
{
$text = $service_maintenance_test_pass;
$style = 'success';
}
$servicereport .='
<tr>
<td class="col-key">'.$value->name.'</td>
<td class="col-value text-center '.$style.'">'.$text.'</td>
</tr>
';
}
$servicereport .= '
</tbody>
</table>
';
}
}
//++++++++++++++++++++++++++++++++++++++++++++++
//GEt visualinspection
//++++++++++++++++++++++++++++++++++++++++++++++
if (isset($json_array->visualinspection)) {
//Get visualinspection directly from DB
$pdo = dbConnect($dbname);
$stmt = $pdo->prepare('SELECT description FROM equipment_history WHERE rowID = ?');
$stmt->execute([$json_array->visualinspection]);
$visualinspection = $stmt->fetch();
$visualinspection_legacy = $visualinspection['description'];
$visualinspection = json_decode($visualinspection['description']);
if (!empty($visualinspection)) {
//Check if visualinspection comes from ServiceTool else inhouse
if (isset($visualinspection->serviceReport->questionItems)) {
$visualinspection_array = $visualinspection->serviceReport->questionItems;
}
else {
//inhousetool
$visualinspection_array = $visualinspection;
}
//Check Legacy API
if (str_contains($visualinspection_legacy, "question1")) {
//Legacy API Questions
$question_array = $arrayQuestions_legacy;
}
else
{ // New Report
$question_array = $arrayQuestions_visual;
}
$servicereport .= '
<h4 class="label">' . $summary_label2 . '</h4>';
foreach ($question_array as $key){
if ($key['Group_sequence'] == '3'){
$servicereport .= '<div class="page_break"></div>'; // pagebreak
}
$servicereport .= '
<table id="" class="fs-small servicereport servicereport--striped">
<thead>
<tr>
<td class="col-key">'.$key['Group'].'</td>
<td class="col-value text-center">'.$service_report_maintenance_test_status.'</td>
</tr>
</thead>
<tbody>';
foreach ($key['Questions_in_group'] as $questions){
$servicereport .= '<tr>
<td class="col-key">';
$response = (substr(${$questions['QuestionID']}, -1) == '?') ? substr(${$questions['QuestionID']}, 0, strpos(${$questions['QuestionID']}, "?")) : ${$questions['QuestionID']};
//$response = $questions['QuestionID'];
$servicereport .= ' '.$response.'
</td>';
foreach ($visualinspection_array as $inspection){
if ($inspection->id == $questions['QuestionID']){
if (isset($inspection->responseID)){
if (in_array($inspection->responseID,$negative_results)){
$style2 = 'error';
}
else
{
$style2 = 'success';
}
$translated_value = ${'service_allowed_label'.$inspection->responseID};
}else{
if (in_array($inspection->id,$negative_results)){
$style2 = 'error';
}
else
{
$style2 = 'success';
}
$translated_value = $inspection->value;
}
$servicereport .= '<td class="col-value text-center '.$style2.'">'.$translated_value.'</td>';
}
}
$servicereport .= '
</tr>';
}
$servicereport .= '</tbody></table>';
}
}
}
//++++++++++++++++++++++++++++++++++++++++++++++
//Legacy Code
//++++++++++++++++++++++++++++++++++++++++++++++
if (isset($json_array->question25) && isset($json_array->newHistory)) {
$servicereport .= '
<h4>'.$summary_label2.'</h4>
<table class="fs-normal servicereport servicereport--details">
<thead>
<tr>
<td>&nbsp;</td>
<td>'.$summary_label3.'</td>
<td>'.$summary_label4.'</td>
</tr>
</thead>
<tbody>
<tr>
<td>'.$question10.'</td>
<td>
'.$service_allowed_label9.'
</td>
<td>
'; if (isset($json_array->{$question10.'b'})){$servicereport .= $json_array->{$question10.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question11.'</td>
<td>
'; if (isset($json_array->{$question11.'a'})){$servicereport .= $json_array->{$question11.'a'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
<td>
'; if (isset($json_array->{$question11.'b'})){$servicereport .= $json_array->{$question11.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question12.'</td>
<td>
'; if (isset($json_array->{$question12.'a'})){$servicereport .= $json_array->{$question12.'a'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
<td>
'; if (isset($json_array->{$question12.'b'})){$servicereport .= $json_array->{$question12.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question13.'</td>
<td>
'; if (isset($json_array->{$question13.'a'})){$servicereport .= $json_array->{$question13.'a'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
<td>
'; if (isset($json_array->{$question13.'b'})){$servicereport .= $json_array->{$question13.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question14.'</td>
<td>
'; if (isset($json_array->{$question14.'a'})){$servicereport .= $json_array->{$question14.'a'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
<td>
'; if (isset($json_array->{$question14.'b'})){$servicereport .= $json_array->{$question14.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question15.'</td>
<td>
'.$service_allowed_label9.'
</td>
<td>
'; if (isset($json_array->{$question15.'b'})){$servicereport .= $json_array->{$question15.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question16.'</td>
<td>
'.$service_allowed_label9.'
</td>
<td>
'; if (isset($json_array->{$question16.'b'})){$servicereport .= $json_array->{$question16.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question17.'</td>
<td>
'.$service_allowed_label9.'
</td>
<td>
'; if (isset($json_array->{$question17.'b'})){$servicereport .= $json_array->{$question17.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
<tr>
<td>'.$question18.'</td>
<td>
'; if (isset($json_array->{$question18.'a'})){$servicereport .= $json_array->{$question18.'a'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
<td>
'; if (isset($json_array->{$question18.'b'})){$servicereport .= $json_array->{$question18.'b'};} else {$servicereport .= $servicereport5;} $servicereport .= '
</td>
</tr>
</tbody>
</table>';
}
$servicereport .='</div>';
if ($request != 'display'){
$servicereport .= '
</body>
</html>';
}
return $servicereport;
}
//------------------------------------------
// LIST PARTNER
//------------------------------------------
function listPartner($partnertype, $user_right, $input)
{
include dirname(__FILE__,2).'/settings/settings.php';
//BASED ON USERRIGHT DEFINE SQL AND DATA RETURNED
if ($user_right != 3 || $user_right !=4) {
//NOT ADMIN USER
$partner = json_decode($_SESSION['partnerhierarchy']);
//SoldTo is empty
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
//BUILD CONDITION
$condition = '__salesid___'.$partner->salesid.'___soldto___'.substr($partner->soldto, 0, strpos($partner->soldto, "-")).$soldto_search;
$whereclause = 'AND salesID like ?';
}
else {//ADMIN USERS
$whereclause = '';
}
$pdo = dbConnect($dbname);
$sql = 'SELECT distinct partnerID, partnername FROM partner WHERE partnertype = ? AND status = 1 '.$whereclause.'';
$stmt = $pdo->prepare($sql);
$stmt->execute([$partnertype, $condition]);
$partners = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($input !='' && !empty($input)){
$partner_available = '<option value="'.$input.'" selected>'.$input.'</option><option value=" "> </option>';
} else {
$partner_available = '<option></option>';
}
$view ='
<input list="'.$partnertype.'" name="'.$partnertype.'" placeholder="'.$input.'" class="datalist">
<datalist id="'.$partnertype.'">
'.$partner_available.'
';
foreach ($partners as $row) {
$view .= '<option value="'.$row["partnerID"].'-'.$row["partnername"].'">'.$row["partnerID"].' - '.$row["partnername"].'</option>';
}
$view .= '</datalist>
';
return $view;
}
//------------------------------------------
// LIST ACCOUNTS
//------------------------------------------
function listAccounts($type, $user_right, $input)
{
include dirname(__FILE__,2).'/settings/settings.php';
//BASED ON USERRIGHT DEFINE SQL AND DATA RETURNED
if ($user_right != 3 || $user_right !=4) {
//NOT ADMIN USER
$partner = json_decode($_SESSION['partnerhierarchy']);
//SoldTo is empty
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
//BUILD CONDITION
$condition = '__salesid___'.$partner->salesid.'___soldto___'.substr($partner->soldto, 0, strpos($partner->soldto, "-")).$soldto_search;
$whereclause = 'AND salesID like ?';
}
else {//ADMIN USERS
$whereclause = '';
}
$pdo = dbConnect($dbname);
$sql = 'SELECT distinct partnerID, partnername FROM partner WHERE partnertype = ? AND status = 1 '.$whereclause.'';
$stmt = $pdo->prepare($sql);
$stmt->execute(['soldto', $condition]);
$partners = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($input !='' && !empty($input)){
$partner_available = '<option value="'.$input.'" selected>'.$input.'</option><option value=" "> </option>';
} else {
$partner_available = '<option></option>';
}
$view ='
<input list="'.$type.'" name="'.$type.'" placeholder="'.$input.'" class="datalist">
<datalist id="'.$type.'">
'.$partner_available.'
';
foreach ($partners as $row) {
$view .= '<option value="'.$row["partnerID"].'-'.$row["partnername"].'">'.$row["partnerID"].' - '.$row["partnername"].'</option>';
}
$view .= '</datalist>
';
return $view;
}
//------------------------------------------
// UPLOAD PICTURE for PRODUCTS
//------------------------------------------
function uploadProduct($name){
$target_dir = dirname(__FILE__)."/images/products/";
$input_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$imageFileType = strtolower(pathinfo($input_file,PATHINFO_EXTENSION));
$target_file = $target_dir . $name.'.jpg';
$file_input_check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
//Do when JPG or PNG or JPEG or GIF and smaller than 5MB
if(($imageFileType == "jpg" || $imageFileType == "png" || $imageFileType == "jpeg" || $imageFileType == "gif" || $imageFileType == "png") && $_FILES["fileToUpload"]["size"] < 5000000 && $file_input_check !== false) {
//Upload picture
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "Done";
} else {
echo "Error";
}
//}
}
}
//------------------------------------------
// UPLOAD PICTURE for PRODUCTS
//------------------------------------------
function uploadrequest($key){
$target_dir = dirname(__FILE__)."/images/cartests/";
$input_file = $target_dir . basename($_FILES["fileToUpload"]["name"][$key]);
$imageFileType = strtolower(pathinfo($input_file,PATHINFO_EXTENSION));
$file_input_check = getimagesize($_FILES["fileToUpload"]["tmp_name"][$key]);
$location = "./assets/images/cartests/".basename($_FILES["fileToUpload"]["name"][$key]);
//Do when JPG or PNG or JPEG or GIF and smaller than 5MB
if(($imageFileType == "jpg" || $imageFileType == "png" || $imageFileType == "jpeg" || $imageFileType == "gif" || $imageFileType == "png") && $_FILES["fileToUpload"]["size"][$key] < 5000000 && $file_input_check !== false) {
//Upload picture
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"][$key], $input_file)) {
//ADD FILELOCATION TO POST VARIABLE
$_POST['questions'][$key] = $location;
} else {
}
}
}
//------------------------------------------
// displayImages
//------------------------------------------
function displayImages($requestid,$request_type){
include dirname(__FILE__,2).'/settings/settings.php';
$pdo = dbConnect($dbname);
switch ($request_type) {
case 'request':
$whereclause = 'requestid = "'.$requestid.'"';
break;
case 'request_line':
$whereclause = 'request_line_id = "'.$requestid.'"';
break;
default:
# code...
break;
}
$sql = 'SELECT * FROM images WHERE '.$whereclause;
$stmt = $pdo->prepare($sql);
$stmt->execute();
$images = $stmt->fetchAll(PDO::FETCH_ASSOC);
$output = '';
if($images){
$output .= '<div class="content-block media-page">
<div class="media">';
foreach ($images as $image){
$output .= '<img class="image" src="./assets/images/requests/'.$image['image_name'].'" loading="lazy">';
}
$output .= ' </div>
</div>';
}
return $output;
}
//------------------------------------------
// debuglog
//------------------------------------------
function debuglog($error){
include_once dirname(__FILE__,2).'/settings/config.php';
$test = $error.PHP_EOL;
$filelocation = dirname(__FILE__,2).'/log/log_'.date('d').'.txt';
error_log($test, 3, $filelocation);
}
//------------------------------------------
// getRowID
//------------------------------------------
function getrowID($database, $id, $table, $where){
// Connect to DB
$pdo = dbConnect($database);
// Define query $where f.e. sn=2423
$sql = 'SELECT '.$id.' from '.$table.' where '.$where.'';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$rowid = $stmt->fetch();
//ReturnId
return $rowid;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// downloader ++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function downloadFile($file) {
if (!isset($_SESSION['loggedin']) && $_SESSION['loggedin'] !== false) {
header('location: index.php');
exit;
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream, application/download, application/force-download');
header('Content-Disposition: attachment; filename=' . basename($file));
ob_clean();
flush();
readfile($file);
exit;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// visual forecast for service and warranty+++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function serviceforecast($messages,$type){
if ($messages){
$number = (($type == 'warranty')? 1 : 1);
//GET TOTAL SERVICE COUNT
$totalcount = 0;
$year_in_scope = date("Y") - 1;
foreach ($messages as $message){
if ($message['year'] >= $year_in_scope){
$totalcount += $message['count'];
}
}
$view = '<div style="margin-bottom: 30px;">
<ul style="width: 100%;max-width:100%" class="chart">
';
foreach ($messages as $message){
if ($message['year'] >= $year_in_scope){
$height = ($message['count'] / $totalcount) * 100;
$fc_year = $message['year'] + $number;
$title = 'Q'.$message['quarter'].' '.$fc_year;
$view .='<li style="text-align:center;">' . $message['count'] . '<span style="height:' . $height . '%" title="' . $title . '"></span></li>';
}
}
$view .='</ul></div>';
return $view;
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// changelog
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function changelog($database,$object,$objectID,$object_field,$object_value,$createdby){
/*
database = database to connect to
object = data object being changed (table name)
object_field = field being changed
object_value = new value
*/
// Connect to DB
$pdo = dbConnect($database);
//Update query
$sql = 'INSERT INTO changelog (object,objectID,object_field,object_value,createdby) VALUES (?,?,?,?,?)';
//Prepare SQL AND EXECUTE
$stmt = $pdo->prepare($sql);
$stmt->execute([$object,$objectID,$object_field,$object_value,$createdby]);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// show changelog (front-end only)
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function showlog($object,$objectID){
//INCLUDE TRANSLATIONS
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
include dirname(__FILE__,2).'/settings/settings.php';
// Connect to DB
$pdo = dbConnect($dbname);
//Update query
$sql = 'SELECT * FROM changelog WHERE object = ? AND objectID = ?';
//Prepare SQL AND EXECUTE
$stmt = $pdo->prepare($sql);
$stmt->execute([$object,$objectID]);
$changes = $stmt->fetchAll(PDO::FETCH_ASSOC);
$view = '<label for="productcode">Changelog</label>';
foreach($changes as $change){
$object_value = $change['object_value'];
//UPDATE TO HUMANREADABLE STATUS
if ($object == 'equipment' && $change['object_field'] == 'status'){
$object_text = 'status'.$change['object_value'].'_text';
$object_value = $$object_text;
}
$view .= '<input id="name" type="text" value="'.$change['object_field'].' - '.$object_value.' - '.$change['created'].' - '.$change['createdby'].'" readonly>';
}
return $view;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// visual changelog +++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function changeLogVisual($totals,$details){
if ($totals){
//GET TOTAL COUNT
$totalcount = 0;
foreach ($totals as $total){
$totalcount += $total['total'];
}
$view = '<div style="margin-bottom: 30px;">
<ul style="width: 100%;max-width:100%" class="chart">
';
foreach ($totals as $total){
//GET SERIALNUMBERS
$url_input = ''; //used to collect serialnumber for onclick event
foreach ($details as $detail){
if ($detail['WoW'] == $total['WoW'] && $detail['DoW'] == $total['DoW']){
$url_input .= $detail['serialnumber'].',';
}
}
$height = ($total['total'] / $totalcount) * 100;
$title = $total['DoW'].'/'.$total['WoW'];
$view .='<li style="text-align:center;" onclick="location.href=\'index.php?page=equipments&serialnumber='.substr($url_input,0,-1).'\'">' . $total['total'] . '<span style="height:' . $height . '%" title="' . $title . '"></span></li>';
}
$view .='</ul></div>';
return $view;
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// download to excell function
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function downloadToExcel($collection, $data_input){
//Conver to ARRAY
$data_input = json_decode(json_encode($data_input), true);
// Excel file name for download
$fileName = $collection.date('Y-m-d').".xls";
//GET KEYS of first row returned
$header_fields = array_keys($data_input[0]);
// Display column names as first row
$excelData = implode("\t", array_values($header_fields)) . "\n";
// Fetch records from database
if($data_input){
// Output each row of the data
foreach ($data_input as $data_row){
//array_walk($message, 'filterData');
$excelData .= implode("\t", array_values($data_row)) . "\n";
}
}
// Headers for download
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=\"$fileName\"");
// Render excel data
echo $excelData;
exit;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Create Partner - when not exists
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function createPartner($user_salesid,$user_soldto,$p_name,$p_type, $token){
$p_return = '';
//BUILD POST DATA
$data = json_encode(array("partnerID" => '' , "salesid" => $user_salesid , "soldto" => $user_soldto, "partnername" => $p_name, "partnertype" => $p_type , "partnernotes" => 'system generated'), JSON_UNESCAPED_UNICODE);
//Secure data
$payload = generate_payload($data);
//API call
$responses = ioAPI('/v1/partners', $payload, $token);
if ($responses === 'NOK'){
// Do Nothing
}
else {
//GET PARTNER DATA - CALL TO API WITH PARTNERNAME
$api_url = '/v1/partners/partnername='.$p_name;
$responses = ioAPI($api_url,'',$token);
//Decode Payload
if (!empty($responses)){
//If response received, check END of array for latest partner details
$responses = decode_payload($responses);
$p_responses = end($responses);
$p_return = $p_responses->partnerID.'-'.$p_responses->partnername;
}
}
return $p_return;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Update GEOlOCATION
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function geolocationUpdate($token){
include dirname(__FILE__,2).'/settings/settings.php';
//GET ALL WARRANTY REGISTRATIONS WHERE NO GEOLOCATION SET
$sql = 'SELECT h.equipmentid, h.description FROM equipment e join equipment_history h on e.rowID = h.equipmentid where h.type = "Warranty" AND e.geolocation is Null';
$pdo = dbConnect($dbname);
$stmt = $pdo->prepare($sql);
$stmt->execute();
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
//FOR ALL RECORDS RETURN FIND GEOLOCATION AT OSM
foreach ($messages as $message){
$warranty = json_decode($message['description']);
//API URL OSM
$api_url = 'https://nominatim.openstreetmap.org/search?format=json&city='.urlencode($warranty->city).'&country='.urlencode($warranty->country);
$api_url = str_replace(' ','%20',$api_url);
//BUILD UP FILESTREAM
$httpOptions = [
"http" => [
"method" => "GET",
"header" => "User-Agent: Nominatim-Test"
]
];
$streamContext = stream_context_create($httpOptions);
$geo_feedback = file_get_contents($api_url, false, $streamContext);
$geo_feedback = json_decode($geo_feedback, true);
$lat = (isset($geo_feedback[0]["lat"]) && ($geo_feedback[0]["lat"] !='' || $geo_feedback[0]["lat"] != null))?$geo_feedback[0]["lat"]:0;
$long = (isset($geo_feedback[0]["lon"]) && ($geo_feedback[0]["lon"] !='' || $geo_feedback[0]["lon"] != null))?$geo_feedback[0]["lon"]:0;
if ($lat == 0){
//CHECK FOR COUNTRY
$api_url = 'https://nominatim.openstreetmap.org/search?format=json&country='.urlencode($warranty->country);
$api_url = str_replace(' ','%20',$api_url);
$streamContext = stream_context_create($httpOptions);
$geo_feedback = file_get_contents($api_url, false, $streamContext);
$geo_feedback = json_decode($geo_feedback, true);
$lat = (isset($geo_feedback[0]["lat"]) && ($geo_feedback[0]["lat"] !='' || $geo_feedback[0]["lat"] != null))?$geo_feedback[0]["lat"]:0;
$long = (isset($geo_feedback[0]["lon"]) && ($geo_feedback[0]["lon"] !='' || $geo_feedback[0]["lon"] != null))?$geo_feedback[0]["lon"]:0;
}
if ($lat !=0){
$geo_feedback = array($lat,$long);
//JSON ENCODE GEOLOCATION RECEIVED AND SENT TO EQUIPMENT API
$geo_feedback = json_encode($geo_feedback);
//BUILD POST DATA
$data = json_encode(array("rowID" => $message['equipmentid'] , "geolocation" => $geo_feedback), JSON_UNESCAPED_UNICODE);
//Secure data
$payload = generate_payload($data);
//API call
$responses = ioAPI('/v1/equipments', $payload, $token);
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// getQuestions
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getQuestions($type){
switch ($type) {
case 'cartest':
include './settings/systemcartest.php';
$arrayQuestions = $arrayQuestions_cartest;
break;
default:
$arrayQuestions = '';
break;
}
if ($arrayQuestions !=''){
foreach($arrayQuestions as $group){
//CREATE GROUP_ID
$group_id = 'group'.$group['Group_sequence'];
$view .= '<h4 onClick="showDetails(\''.$group_id.'\')">'.$group['Group'].' &#9661;</h4>
<div id="'.$group_id.'" style="'.$style.'">';
foreach($group['Questions_in_group'] as $question){
$view .= '<label for="" id="'.$question['QuestionID'].'" class="form-label">'.$question['Question'].'</label>';
switch ($question['Type']) {
case 'Dropdown':
$view .= '<select id="" name="'.$question['QuestionID'].'">';
foreach ($question['Response'] as $response){
$view .= '<option value="'.$response['response_value'].'">'.$response['response_text'].'</option>';
}
$view .= '</select>';
break;
case 'Checkbox':
$view .= '<ul>';
foreach ($question['Response'] as $response){
//ADD ARRAY OPTION '.$question['QuestionID'].'[]
$view .= '<li style="list-style:none;">
<input type="checkbox" id="" name="" value="'.$response['response_value'].'" />
<label for="">'.$response['response_text'].'</label>
</li>';
}
$view .= '</ul>';
break;
case 'slider':
//CREATE SLIDER FOR DISTANCE
$view .= '
<input type="text" id="city" placeholder="'.$city.'" value="">
<input type="text" id="country" placeholder="'.$country.'" value="" onchange="findLocation();">
<input type="hidden" name="lat" id="lat" value="0">
<input type="hidden" name="lng" id="lng" value="0">
<input type="range" name="range" id="distanceId" value="'.$question['Response'][1].'" min="'.$question['Response'][0].'" max="'.$question['Response'][2].'" oninput="distanceOutputId.value = distanceId.value"><output id="distanceOutputId">'.$question['Response'][1].'</output>';
break;
}
}
$view .= '</div>';
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// convert cartest FROM equipment_history to cartest table
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function convertCartest(){
include dirname(__FILE__,2).'/settings/settings.php';
//GET CARTEST FROM equipment_history TABLE
$pdo = dbConnect($dbname);
$sql = 'SELECT * FROM equipment_history WHERE type="cartest"';
$stmt = $pdo->prepare($sql);
//Excute Query
$stmt->execute();
//Get results
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
//FOR EACH CARTEST TRANSFER TO CARTEST TABLE
foreach ($messages as $message){
//GET VARIABLES
$cartest = json_decode($message['description'],true) ?? '';
$carbrand = ucfirst($cartest["CarBrand"] ?? 'Unknown');
$cartype = ucfirst($cartest["CarType"] ?? 'Unknown');
$questions = json_encode($cartest["Questions"] ??'');
$datapoints = json_encode($cartest["plugDataPoints"] ?? '');
$nametester = $cartest["NameTester"] ?? 'Unknown';
$plug_sn = $cartest["SN"] ?? 0;
$accounthierarchy = '';
//get header data only
unset($cartest["Questions"]);
unset($cartest["plugDataPoints"]);
$header = json_encode($cartest);
//GET ACCOUNTHIERARCHY FROM SN OF
if ($plug_sn !=0){
$sql ='SELECT accounthierarchy FROM equipment WHERE serialnumber = ?';
$stmt = $pdo->prepare($sql);
//Excute Query
$stmt->execute([$plug_sn]);
//Get results
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
$accounthierarchy = $messages[0]['accounthierarchy'];
}
//INSERT INTO CARTEST
$sql = 'INSERT INTO cartest (carbrand, cartype,header,questions,datapoints,createdby,accounthierarchy) VALUES (?,?,?,?,?,?,?)';
$stmt = $pdo->prepare($sql);
//Excute Query
$stmt->execute([$carbrand,$cartype,$header,$questions,$datapoints,$nametester,$accounthierarchy]);
//MARK HISTORY ITEM FOR DELETATION
$sql = 'UPDATE equipment_history SET type = "delete", updatedby = "system" WHERE rowID = '.$message['rowID'];
$stmt = $pdo->prepare($sql);
//Excute Query
$stmt->execute();
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ML data preparations
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function traintotalMeasurement(){
include dirname(__FILE__,2).'/settings/settings.php';
//total measurement internal array
$total_measurement = [];
//Connect to DB
$pdo = dbConnect($dbname);
//GET DATA
$sql = 'SELECT h.rowID, h.description,h.equipmentid,p.productcode,e.hw_version FROM equipment_history h JOIN equipment e ON h.equipmentid = e.rowID JOIN products p ON e.productrowid = p.rowID where p.healthindex = 1 and h.type="Maintenance_Test" and h.description like "%doubletestvalues%"';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($messages as $message){
//Cleanup input array
$dataset = json_decode($message['description'],true);
$dataset = $dataset["doubletestvalues"];
foreach ($dataset as $measure){
//Filter out correct measurements
if ($measure['pass'] === true){
$hw_version = (!empty($message['hw_version']))? $message['hw_version'] : 'blank';
$measurementid = $message['rowID'];
$total_measurement[$message['productcode']][$hw_version][$measure['name']][$measurementid] = $measure['measure'];
}
}
}
return $total_measurement;
}
function statisticalAnalyses($total_measurement){
//result array
$total_results = [];
//STATISTICAL ANALYSES INTERNAL ARRAY
foreach ($total_measurement as $productcode => $versions){
foreach ($versions as $version => $ver){
foreach ($ver as $measurement => $value){
$average = $total_results[$productcode][$version][$measurement]['average'] = average($value);
$median = $total_results[$productcode][$version][$measurement]['median'] = calculateMedian($value);
$stdev = $total_results[$productcode][$version][$measurement]['stdev'] = standDeviation($value);
$total_results[$productcode][$version][$measurement]['n'] = count($value);
//GET STDEV -/+
$total_results[$productcode][$version][$measurement]['stdev-1'] = $average - $stdev;
$total_results[$productcode][$version][$measurement]['stdev+1'] = $average + $stdev;
$total_results[$productcode][$version][$measurement]['stdev-2'] = $average - (2*$stdev);
$total_results[$productcode][$version][$measurement]['stdev+2'] = $average + (2*$stdev);
$total_results[$productcode][$version][$measurement]['stdev-3'] = $average - (3*$stdev);
$total_results[$productcode][$version][$measurement]['stdev+3'] = $average + (3*$stdev);
}
}
}
return $total_results;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Main statiscal functions for ML
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function standDeviation($arr)
{
$num_of_elements = count($arr);
$variance = 0.0;
// Calculate mean using array_sum() method
$average = array_sum($arr) / $num_of_elements;
foreach($arr as $i)
{
// Sum of squares of differences between all numbers and means.
$variance += pow(($i - $average), 2);
}
return (float)sqrt($variance / $num_of_elements);
}
function average($arr)
{
$num_of_elements = count($arr);
$average = array_sum($arr) / $num_of_elements;
return $average;
}
function calculateMedian($array) {
if (empty($array)) {
return null;
} else {
sort($array);
$lowMiddle = $array[floor((count($array) - 1) / 2)];
$highMiddle = $array[ceil((count($array) - 1) / 2)];
return ($lowMiddle + $highMiddle) / 2;
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// visual forecast for service and warranty+++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function usageView($messages){
//GET TOTAL SERVICE COUNT
$totalcount = 0;
foreach ($messages as $message){
$totalcount += $message['count'];
}
$view = '
<smaller>Service = '.$totalcount.' </smaller>
<div style="margin-bottom: 30px;">
<ul style="width: 100%;max-width:100%" class="chart">
';
foreach ($messages as $message){
$height = ($message['count'] / $totalcount) * 100;
$fc_year = $message['year'];
$dateObj = DateTime::createFromFormat('!m', $message['month']);
$title = $dateObj->format('F').' '.$fc_year;
$view .='<li style="text-align:center;">' . $message['count'] . '<span style="height:' . $height . '%" title="' . $title . '"></span></li>';
}
$view .='</ul>
</div>
';
return $view;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// overview of service events per servicekit ++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function usageBilling($messages){
// Create an array to store sums by year, quarter, and month
$totals = [];
// Loop through the data and aggregate the counts by year, quarter, and month
foreach ($messages as $entry) {
$year = $entry['year'];
$quarter = $entry['quarter'];
//$dateObj = DateTime::createFromFormat('!m', $entry['month']);
//$month = $dateObj->format('F');
$month = $entry['month'];
$count = $entry['count'];
// Initialize arrays if not already set for year, quarter, and month
if (!isset($totals[$year])) {
$totals[$year] = ['total' => 0, 'quarters' => []];
}
if (!isset($totals[$year]['quarters'][$quarter])) {
$totals[$year]['quarters'][$quarter] = ['total' => 0, 'months' => []];
}
if (!isset($totals[$year]['quarters'][$quarter]['months'][$month])) {
$totals[$year]['quarters'][$quarter]['months'][$month] = 0;
}
// Add count to the corresponding year, quarter, and month
$totals[$year]['total'] += $count;
$totals[$year]['quarters'][$quarter]['total'] += $count;
$totals[$year]['quarters'][$quarter]['months'][$month] += $count;
}
return $totals;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// close contract when expired +++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function closeContract(){
include dirname(__FILE__,2).'/settings/settings.php';
$pdo = dbConnect($dbname);
//SELECT ALL ACTIVE CONTRACTS
$sql = 'SELECT * FROM contracts WHERE status = 1';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($messages as $message){
//Calculate contract end date
$end_date = date('Y-m-d', strtotime('+'.$message['duration'].' months', strtotime($message['start_date'])));
//Validate if contract end date is in the past change contact status to closed and set users to not active
if (date("Y-m-d") > $end_date){
//Contract expired -> change status to closed (2)
$sql = 'UPDATE contracts SET status = ?, updatedby = ? WHERE rowID = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([2,"system",$message['rowID']]);
//CHECK FOR ASSIGNED USER END SET SERVICE TO INACTIVE
foreach (json_decode($message['assigned_users']) as $user_assigned){
//check user exist
$sql = 'SELECT * FROM users WHERE username = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$user_assigned]);
$user_assigned = $stmt->fetch();
if (!empty($user_assigned)){
$id_exist_user = $user_assigned['id'];
$sql = 'UPDATE users SET service = ? WHERE id = ? ';
$stmt = $pdo->prepare($sql);
//Remove serviceflag from user when status is Closed
$stmt->execute(['',$id_exist_user]);
}
}
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// store measurement data into product_version ++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function storeMeasurementProduct($total_results, $token){
include dirname(__FILE__,2).'/settings/settings.php';
$pdo = dbConnect($dbname);
//Check if product version exists (else create) => store related measurement
foreach ($total_results as $products => $product){
//Product level
foreach ($product as $versions => $version){
//Version level
//Check version exist
$sql = 'SELECT p.*, pv.rowID as versionID, pv.productrowid as productID FROM products p JOIN products_versions pv ON p.rowID = pv.productrowid WHERE p.healthindex = 1 and p.productcode = ? and version = ?;';
$stmt = $pdo->prepare($sql);
$versions = ($versions != 'blank')? $versions : '';
$stmt->execute([$products,$versions]);
$output = $stmt->fetchAll(PDO::FETCH_ASSOC);
//Prep data for api call
$api_url = '/v2/products_versions/';
$measurement = json_encode($version,JSON_UNESCAPED_UNICODE);
if (!empty($output)){
//Update version with latest measurement
$data = json_encode(array("rowID" => $output[0]['versionID'], "productrowid" => $output[0]['productID'], "status" => 1, "version" => $versions, "measurement" => $measurement), JSON_UNESCAPED_UNICODE);
ioApi($api_url,$data,$token);
}
else {
//Insert new version
//GET PRODUCT ID
$sql = 'SELECT * FROM products WHERE productcode = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$products]);
$output = $stmt->fetchAll(PDO::FETCH_ASSOC);
//CALL API
$data = json_encode(array("productrowid" => $output[0]['rowID'], "status" => 1, "version" => $versions , "measurement" => $measurement), JSON_UNESCAPED_UNICODE);
ioApi($api_url,$data,$token);
}
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// store measurement data into equipment data ++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function storeMeasurementEquipment($serialnumber){
include dirname(__FILE__,2).'/settings/settings.php';
//Connect to DB
$pdo = dbConnect($dbname);
//CHECK FOR SERIALNUMBER PROVIDED
$clause = (!empty($serialnumber) || $serialnumber !='')? 'e.serialnumber = "'.$serialnumber.'" AND': '';
//GET DATA
$sql = 'SELECT h.rowID, h.description,h.equipmentid,p.productcode,e.hw_version FROM equipment_history h JOIN equipment e ON h.equipmentid = e.rowID JOIN products p ON e.productrowid = p.rowID where '.$clause.' type="Maintenance_Test" and description like "%doubletestvalues%"';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
$tests[] ='';
foreach ($messages as $message){
$dataset = json_decode($message['description'],true);
$dataset = $dataset["doubletestvalues"];
foreach ($dataset as $measure){
//Filter out correct measurements
if ($measure['pass'] === true){
$measurementid = $message['productcode'].'||'.$message['hw_version'].'||'.$message['equipmentid'].'||'.$message['rowID'];
$tests[$measurementid] [$measure['name']]= $measure['measure'];
}
}
}
//COMPARISON -- CHECK DEVIATIONS FROM STANDARD
//LOOP over all test results
foreach ($tests as $test => $test_values){
//GET the productcode and version from Test result
if (str_contains($test,'||')){
$identification = explode('||',$test);
//GET RELATED PRODUCT DATA
$sql = 'SELECT pv.measurement FROM products_versions pv JOIN products p ON pv.productrowid = p.rowID WHERE p.productcode = ? AND pv.version = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$identification[0],$identification[1]]);
$product_measurements = $stmt->fetchAll(PDO::FETCH_ASSOC);
$product_measurements = $product_measurements[0]['measurement']?? '';
if (!empty($product_measurements)){
//Only run when there is a product version found
$product_measurements = json_decode($product_measurements,true);
$equipment_watchlist[] = '';
//Filter out non array or non objects
if (is_object($test_values) || is_array($test_values)){
//get individual test_mesurements
foreach($test_values as $test_measurement => $measured_value){
//Loop over the related product measurements
foreach($product_measurements as $product_measurement => $product_measured_values){
//Compare measured test with product measured test
if ($test_measurement == $product_measurement){
//Get the measured value from test
if (($measured_value <= $product_measured_values['stdev-3']) && ($measured_value >= $product_measured_values['stdev+3'])){
$equipment_watchlist[$test][] = array(
"measurement" => $test_measurement,
"value" => $measured_value,
"deviation" => 3
);
}
elseif ((($measured_value <= $product_measured_values['stdev-2']) && ($measured_value >= $product_measured_values['stdev-3'])) || (($measured_value >= $product_measured_values['stdev+2']) && ($measured_value <= $product_measured_values['stdev+3']))){
$equipment_watchlist[$test][] = array(
"measurement" => $test_measurement,
"value" => $measured_value,
"deviation" => 2
);
}
elseif ((($measured_value <= $product_measured_values['stdev-1']) && ($measured_value >= $product_measured_values['stdev-2'])) || (($measured_value >= $product_measured_values['stdev+1']) && ($measured_value <= $product_measured_values['stdev+2']))){
$equipment_watchlist[$test][] = array(
"measurement" => $test_measurement,
"value" => $measured_value,
"deviation" => 1
);
}
}
}
}
}
}
}
}
//STORE RESULTS IN EQUIPMENT DATA
foreach ($equipment_watchlist as $equipment => $data){
//GET the equipmentid and historyid from watchlist
if (str_contains($equipment,'||')){
$identification = explode('||',$equipment);
//Calculate healthindex
$healthindex = 100;
foreach ($data as $data_measure){
switch ($data_measure['deviation']) {
case 1:
$healthindex = $healthindex - $data_measure['deviation'];
break;
case 2:
$healthindex = $healthindex - ($data_measure['deviation']*2);
break;
case 3:
$healthindex = $healthindex - ($data_measure['deviation']*3);
break;
}
}
//json_encode array
$data = json_encode($data,JSON_UNESCAPED_UNICODE);
//Check if record exists
$sql = 'SELECT * FROM equipment_data WHERE equipmentid = ? and historyid =?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$identification[2],$identification[3]]);
$equipment_data = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($equipment_data)){
//EXIST UPDATE
$sql = 'UPDATE equipment_data SET measurement = ?, healthindex = ? WHERE equipmentid = ? and historyid = ?';
}
else {
//EXIST INSERT
$sql = 'INSERT INTO equipment_data (measurement, healthindex, equipmentid, historyid) VALUES (?,?,?,?)';
}
//EXECUTE QUERY
$stmt = $pdo->prepare($sql);
$stmt->execute([$data, $healthindex, $identification[2],$identification[3]]);
//$equipment_data = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// calculatehealthindex of asset ++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function assetHealthIndex($prof,$pem,$healthdata,$type){
$healthindex = 100;
//Allowed check
if (isAllowed('equipment_data',$prof,$pem,'R') === 1 && !empty($healthdata)){
//GET last data based on type returned
//Type
// 0 = $healthdata per equipmentid
// 1 = $healthdata per rowID of equipment_data
switch ($type) {
case 0:
$last_data_measurement = end($healthdata);
break;
default:
$last_data_measurement = $healthdata;
break;
}
//Ensure $last_data_measurement is an array
$last_data_measurement = (is_object($last_data_measurement))? (array) $last_data_measurement : $last_data_measurement;
foreach (json_decode($last_data_measurement['measurement'],true) as $data_measure){
switch ($data_measure['deviation']) {
case 1:
$healthindex = $healthindex - $data_measure['deviation'];
break;
case 2:
$healthindex = $healthindex - ($data_measure['deviation']*2);
break;
case 3:
$healthindex = $healthindex - ($data_measure['deviation']*3);
break;
}
}
}
//Not allowed or no data return 100% health
return $healthindex;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Block contracts ++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function blockContracts($token){
include dirname(__FILE__,2).'/settings/settings.php';
//CALL TO API
$api_url = '/v2/contracts/status=1&type=0';
$responses = ioAPIv2($api_url,'',$token);
//Decode Payload
if (!empty($responses)){$responses = json_decode($responses,true);}else{$responses = null;}
foreach ($responses as $response){
//GET BILLING DATA
$billing_plan = $response['billing_plan'];
$billing_max = $response['service_count'];
//DECODE ARRAYs
$servicetools = json_decode($response['servicetool'],true) ?? '';
$assigned_users = json_decode($response['assigned_users'],true) ?? '';
$ignore_lists = json_decode($response['ignore_list'],true) ?? '';
//get all assigned serialnumbers
$url_input = '';
foreach($servicetools as $service_tool){
$url_input .= $service_tool.',';
}
//get ignore list
$ignored_serialnumbers = '';
if (!empty($ignore_lists)){
foreach($ignore_lists as $list){
$ignored_serialnumbers .= $list.',';
}
$ignored_serialnumbers = '&ignore='.substr($ignored_serialnumbers,0,-1);
}
//GET END DATA
$contract_end_date = date('Y-m-d', strtotime('+'.$response['duration'].' months', strtotime($response['start_date'])));
//Return report_usage_servicereports
$api_url = '/v2/application/type=ServiceReport&serialnumber='.substr($url_input,0,-1).$ignored_serialnumbers.'&between='.$response['start_date'].'||'.$contract_end_date.'/contract_usage_servicereports';
$contract_usage_servicereports = ioAPIv2($api_url,'',$token);
//Decode Payload
if (!empty($contract_usage_servicereports)){$contract_usage_servicereports = json_decode($contract_usage_servicereports,true);}else{$contract_usage_servicereports = null;}
//GET USAGE BILLING INFORMATION
$usage_billing = usageBilling($contract_usage_servicereports);
$billing_cylce_usage = (($billing_plan == 1 && isset($usage_billing[$curYear]['quarters'][$curQuarter]['months'][$curMonth])) ? $usage_billing[$curYear]['quarters'][$curQuarter]['months'][$curMonth] : (($billing_plan == 2 && isset($usage_billing[$curYear]['quarters'][$curQuarter])) ? $usage_billing[$curYear]['quarters'][$curQuarter]: (($billing_plan == 3 && isset($usage_billing[$curYear])) ? $usage_billing[$curYear]: 0 )));
//CHECK FOR OVERRUN
if ($billing_cylce_usage >= $billing_max){
//overrun - set contract status to 3 - block and Inactivate service for all assigned users
$data = json_encode(array("rowID" => $response['rowID'], "status" => "3", "assigned_users" => $assigned_users), JSON_UNESCAPED_UNICODE);
//API call
ioAPIv2('/v2/contracts', $data,$token);
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// check date is in range ++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function dateInRange($start_date, $end_date, $date_check)
{
// Convert to timestamp
$start_ts = strtotime($start_date);
$end_ts = strtotime($end_date);
$check_ts = strtotime($date_check);
// Check that user date is between start & end
return (($check_ts >= $start_ts) && ($check_ts <= $end_ts));
}
function getLatestVersion($productcode,$token){
//CALL TO API TO GET ALL ACTIVE CONTRACTS
$api_url = '/v2/products_software/productcode='.$productcode;
$responses = ioAPIv2($api_url,'',$token);
//Decode Payload
if (!empty($responses)){$responses = json_decode($responses,true);
}
else{
$responses = $output = array(
"productcode" => "",
"version"=> "",
"mandatory"=> "",
"latest"=> "",
"software"=> "",
"source" => "",
"source_type" => ""
);
;}
//DEFAULT OUTPUT
return $responses;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Timestamp converter ++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getRelativeTime($timestamp) {
//GET TRANSLATION FILE
if(isset($_SESSION['country_code'])){
$api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php';
if (file_exists($api_file_language)){
include $api_file_language; //Include the code
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
}
else {
include dirname(__FILE__,2).'/settings/translations/translations_US.php';
}
// Ensure the timestamp is a valid integer
$timestamp = is_numeric($timestamp) ? $timestamp : strtotime($timestamp);
// Get current timestamp and calculate difference
$now = time();
$diff = $now - $timestamp;
// Define time periods
$minute = 60;
$hour = $minute * 60;
$day = $hour * 24;
$week = $day * 7;
$month = $day * 30;
$year = $day * 365;
// Handle future timestamps
if ($diff < 0) {
$diff = abs($diff);
$suffix = $time_from_now;
} else {
$suffix = $time_ago;
}
// Determine the appropriate time description
if ($diff < $minute) {
return $time_just_now;
} elseif ($diff < $hour) {
$minutes = floor($diff / $minute);
return $minutes.(($minutes != 1) ? $time_minutes : $time_minute) . " $suffix";
} elseif ($diff < $day) {
$hours = floor($diff / $hour);
return $hours.(($hours != 1) ? $time_hours : $time_hour) . " $suffix";
} elseif ($diff < $week) {
$days = floor($diff / $day);
// Special handling for today and yesterday
if ($days == 0) {
return $time_today;
} elseif ($days == 1) {
return $time_yesterday;
}
return $days.(($days != 1)?$time_days:$time_day) . " $suffix";
} elseif ($diff < $month) {
$weeks = floor($diff / $week);
return $weeks.(($weeks != 1)?$time_weeks:$time_week) . " $suffix";
} elseif ($diff < $year) {
$months = floor($diff / $month);
return $months.(($months != 1)?$time_months:$time_month) . " $suffix";
} else {
$years = floor($diff / $year);
return $years.(($years != 1)?$time_years:$time_year) . " $suffix";
}
}