diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b7a4fc..3bba40d9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,35 @@ # CHANGELOG +### Version 12.0 +- Lids inventory dropped to accessories +- Minor overall UI updates +- Migrating backend scripts under a common backend api +- Import json functions update +- Added import for accessories +- Added import for bottles +- Added import for suppliers +- Added import for customers +- Droped old CSV export for suppliers +- Fixed pagination for suppliers +- Formula scaling improvements +- Added ingredient to formula backend update +- Fix invalid formula update date on empty formulas +- Update empty table message +- Rename sex to gender +- Error handling improvements +- Date Format update +- Auto update image for formulas when uploaded +- Auto update text title and description after a succesfull update for a formula +- File upload improvements +- Various wording updates +- Removed user alert to reload formula settings pages when making a changes +- Added openshift yaml manifests +- Improve db connect method +- Added a dedicated page to display in case of fatal error +- Added a session timeout to automatically logoff the user after 30 minutes of inactivity - configurable by user +- Change selected material color to yellow in formula making for better descrimination +- Various minor updates and code clean-up +- Added a function to convert session time to hours/mins + ### Version 11.9 - Added system logs access via the UI for docker/cloud installations - this comes disabled by default - Hide properties column in formulas diff --git a/VERSION.md b/VERSION.md index 675364cd..d7213f31 100755 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -11.9 +12.0 diff --git a/core/ajax-session.php b/core/ajax-session.php index fdafd087..4c1adf53 100644 --- a/core/ajax-session.php +++ b/core/ajax-session.php @@ -1,14 +1,50 @@ $session_timeout) { + session_unset(); + session_destroy(); + + echo json_encode( + array( + 'session_status' => false, + 'session_timeout' => $session_timeout, + 'session_time' => $_SESSION['parfumvault_time'] ?? null + ) + ); + return; } -if(!isset( $_SESSION['parfumvault']) || $_SESSION['parfumvault'] == false) { - //expired - echo "-1"; +if(!isset( $_SESSION['parfumvault']) || $_SESSION['parfumvault'] === false) { + //session is expired + echo json_encode( + array( + 'session_status' => false, + 'session_timeout' => $session_timeout, + 'session_time' => $_SESSION['parfumvault_time'] ?? null + ) + ); session_destroy(); } else { - //not expired - echo "1"; + //session is valid + echo json_encode( + array( + 'session_status' => true, + 'session_timeout' => $session_timeout, + 'session_time' => $_SESSION['parfumvault_time'] + ) + ); } ?> diff --git a/core/auth.php b/core/auth.php index 1196d2e8..be5ef43f 100644 --- a/core/auth.php +++ b/core/auth.php @@ -4,6 +4,12 @@ require_once(__ROOT__.'/inc/opendb.php'); +if(strtoupper(getenv('PLATFORM')) === "CLOUD"){ + $session_timeout = getenv('SYS_TIMEOUT') ?: 1800; +} else { + require_once(__ROOT__.'/inc/config.php'); +} + if($_POST['action'] == 'login'){ if(empty($_POST['email']) || empty($_POST['password'])){ @@ -20,9 +26,32 @@ if($row['id']){ if (session_status() === PHP_SESSION_NONE) { + session_set_cookie_params([ + 'lifetime' => $session_timeout, // Set cookie lifetime to 30 minutes + 'path' => '/', // Make the cookie accessible throughout the domain + 'secure' => isset($_SERVER['HTTPS']), // Secure cookie if using HTTPS + 'httponly' => true, // Prevent JavaScript from accessing the cookie + 'samesite' => 'Strict', // Protect against CSRF attacks + ]); session_start(); } + if (isset($_SESSION['parfumvault_time'])) { + if ((time() - $_SESSION['parfumvault_time']) > $session_timeout) { + session_unset(); + session_destroy(); + + $response['auth']['error'] = true; + $response['auth']['msg'] = 'Session expired. Please log in again.'; + echo json_encode($response); + return; + } else { + $_SESSION['parfumvault_time'] = time(); + } + } else { + $_SESSION['parfumvault_time'] = time(); + } + $_SESSION['parfumvault'] = true; $_SESSION['userID'] = $row['id']; if($_POST['do']){ diff --git a/core/configureSystem.php b/core/configureSystem.php index 7d2a9c35..f23cf1ff 100644 --- a/core/configureSystem.php +++ b/core/configureSystem.php @@ -94,13 +94,14 @@ $tmp_path = "/tmp/"; $allowed_ext = "pdf, doc, docx, xls, csv, xlsx, png, jpg, jpeg, gif"; $max_filesize = "4194304"; //in bytes +$session_timeout = 1800; //Time in seconds ?> '; - if (session_status() === PHP_SESSION_NONE) { - session_start(); - } - $_SESSION['parfumvault'] = true; - $_SESSION['userID'] = mysqli_insert_id($link); + if (session_status() === PHP_SESSION_NONE) { + session_start(); + } + $_SESSION['parfumvault'] = true; + $_SESSION['userID'] = mysqli_insert_id($link); }else{ $response['error'] = 'DB Schema Creation error. Make sure the database exists in your mysql server and its empty.'; diff --git a/core/core.php b/core/core.php new file mode 100644 index 00000000..85618b06 --- /dev/null +++ b/core/core.php @@ -0,0 +1,5365 @@ +File upload error: Extension not allowed, please choose a '.$allowed_ext.' file'; + echo json_encode($response); + return; + } + + if($_FILES["avatar"]["size"] > 0){ + move_uploaded_file($file_tmp,$tmp_path."/uploads/logo/".base64_encode($filename)); + $avatar = "/uploads/logo/".base64_encode($filename); + create_thumb($tmp_path.$avatar,250,250); + $docData = 'data:application/' . $file_ext . ';base64,' . base64_encode(file_get_contents($tmp_path.$avatar)); + + mysqli_query($conn, "DELETE FROM documents WHERE ownerID = '".$user['id']."' AND type = '3' AND name = 'avatar'"); + if(mysqli_query($conn, "INSERT INTO documents (ownerID,type,name,notes,docData) VALUES ('".$user['id']."','3','avatar','Main Profile Avatar','$docData')")){ + unlink($tmp_path.$avatar); + $response["success"] = array( "msg" => "User avatar updated!", "avatar" => $docData); + echo json_encode($response); + return; + } + } + + return; +} + +if($_POST['update_user_profile']){ + + if(!$_POST['user_fname'] || !$_POST['user_email'] || !$_POST['user_pass']){ + $response["error"] = "All fields are required"; + echo json_encode($response); + return; + } + + if(strlen($_POST['user_fname']) < '5'){ + $response['error'] = "Full name must be at least 5 characters long!"; + echo json_encode($response); + return; + } + + $fullName = mysqli_real_escape_string($conn, $_POST['user_fname']); + $email = mysqli_real_escape_string($conn, $_POST['user_email']); + +// $password = password_hash($password, PASSWORD_DEFAULT); + + if($password){ + if(strlen($password) < '5'){ + $response["error"] = "Password must be at least 5 characters long"; + echo json_encode($response); + return; + }else{ + $p = ",password=PASSWORD('$password')"; + } + } + + if(mysqli_query($conn, "UPDATE users SET fullName = '$fullName', email = '$email' $p")){ + $response["success"] = "User details updated"; + echo json_encode($response); + }else{ + $response["error"] = 'Failed to update user details '.mysqli_error($conn); + echo json_encode($response); + } + + + return; +} + +if($_POST['manage'] == 'general'){ + $currency = $_POST['currency']; + $currency_code = $_POST['currency_code']; + + $top_n = mysqli_real_escape_string($conn, $_POST['top_n']); + $heart_n = mysqli_real_escape_string($conn, $_POST['heart_n']); + $base_n = mysqli_real_escape_string($conn, $_POST['base_n']); + + $qStep = mysqli_real_escape_string($conn, $_POST['qStep']); + $defCatClass = mysqli_real_escape_string($conn, $_POST['defCatClass']); + $grp_formula = mysqli_real_escape_string($conn, $_POST['grp_formula']); + $pubchem_view = mysqli_real_escape_string($conn, $_POST['pubchem_view']); + $mUnit = mysqli_real_escape_string($conn, $_POST['mUnit']); + $editor = mysqli_real_escape_string($conn, $_POST['editor']); + $user_pref_eng = mysqli_real_escape_string($conn, $_POST['user_pref_eng']); + $defPercentage = $_POST['defPercentage']; + $bs_theme = $_POST['bs_theme']; + $temp_sys = $_POST['temp_sys']; + + if($_POST["chem_vs_brand"] == 'true') { + $chem_vs_brand = '1'; + }else{ + $chem_vs_brand = '0'; + } + + if($_POST["pubChem"] == 'true') { + $pubChem = '1'; + }else{ + $pubChem = '0'; + } + + if($_POST["chkVersion"] == 'true') { + $chkVersion = '1'; + }else{ + $chkVersion = '0'; + } + + if($_POST["multi_dim_perc"] == 'true') { + $multi_dim_perc = '1'; + }else{ + $multi_dim_perc = '0'; + } + + if(empty($_POST['pv_host']) || empty($_POST['currency'])){ + $response["error"] = 'Fields cannot be empty'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "UPDATE settings SET currency = '$currency', currency_code = '$currency_code', top_n = '$top_n', heart_n = '$heart_n', base_n = '$base_n', chem_vs_brand = '$chem_vs_brand', grp_formula = '$grp_formula', pubChem='$pubChem', chkVersion='$chkVersion', qStep = '$qStep', defCatClass = '$defCatClass', pubchem_view = '$pubchem_view', multi_dim_perc = '$multi_dim_perc', mUnit = '$mUnit', editor = '$editor', user_pref_eng = '$user_pref_eng', pv_host = '".$_POST['pv_host']."', defPercentage = '$defPercentage', bs_theme = '$bs_theme', temp_sys = '$temp_sys' ")){ + $response["success"] = 'Settings updated'; + }else{ + $response["error"] = 'An error occured '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +if($_POST['manage'] == 'api'){ + + $api = $_POST['api']; + $api_key = mysqli_real_escape_string($conn, $_POST['api_key']); + if(strlen($api_key) < 8){ + $response['error'] = 'API key must be at least 8 characters long'; + echo json_encode($response); + return; + } + if($_POST["api"] == 'true') { + $api = '1'; + }else{ + $api = '0'; + } + + if(mysqli_query($conn, "UPDATE settings SET api = '$api', api_key='$api_key'")){ + $response['success'] = 'API settings updated!'; + }else{ + $response['error'] = 'An error occured '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + + +//BRAND +if($_POST['manage'] == 'brand'){ + $brandName = mysqli_real_escape_string($conn, $_POST['brandName']); + $brandAddress = mysqli_real_escape_string($conn, $_POST['brandAddress']); + $brandEmail = mysqli_real_escape_string($conn, $_POST['brandEmail']); + $brandPhone = mysqli_real_escape_string($conn, $_POST['brandPhone']); + + if(mysqli_query($conn, "UPDATE settings SET brandName = '$brandName', brandAddress = '$brandAddress', brandEmail = '$brandEmail', brandPhone = '$brandPhone'")){ + $response['success'] = 'Brand details updated'; + }else{ + $response['error'] = 'Error updating brand info'; + } + echo json_encode($response); + return; +} + +//ADD CATEGORY +if($_POST['manage'] == 'category'){ + $cat = mysqli_real_escape_string($conn, $_POST['category']); + $notes = mysqli_real_escape_string($conn, $_POST['cat_notes']); + + if(empty($cat)){ + $response["error"] = 'Category name is required.'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingCategory WHERE name = '$cat'"))){ + $response["error"] = 'Category name '.$cat.' already exists!'; + echo json_encode($response); + return; + } + if(mysqli_query($conn, "INSERT INTO ingCategory (name,notes) VALUES ('$cat', '$notes')")){ + $response["success"] = 'Category '.$cat.' added!'; + echo json_encode($response); + }else{ + $response["error"] = 'Something went wrong, '.mysqli_error($conn); + echo json_encode($response); + } + return; +} + +//DELETE CATEGORY +if($_POST['action'] == 'delete' && $_POST['catId']){ + $catId = mysqli_real_escape_string($conn, $_POST['catId']); + if(mysqli_query($conn, "DELETE FROM ingCategory WHERE id = '$catId'")){ + $response["success"] = 'Category deleted'; + }else{ + $response["error"] = 'Error deleting category'; + } + echo json_encode($response); + return; +} + +//ADD INGREDIENT PROFILE +if($_POST['manage'] == 'add_ingprof'){ + $profile = mysqli_real_escape_string($conn, $_POST['profile']); + $description = mysqli_real_escape_string($conn, $_POST['description']); + + if(empty($profile)){ + $response["error"] = 'Profile name is required.'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingProfiles WHERE name = '$profile'"))){ + $response["error"] = 'Profile name '.$profile.' already exists'; + echo json_encode($response); + return; + } + if(mysqli_query($conn, "INSERT INTO ingProfiles (name,notes) VALUES ('$profile', '$description')")){ + $response["success"] = 'Profile '.$profile.' added'; + echo json_encode($response); + }else{ + $response["error"] = 'Something went wrong, '.mysqli_error($conn); + echo json_encode($response); + } + return; +} + +//DELETE INGREDIENT PROFILE +if($_POST['action'] == 'ingProfile' && $_POST['profId']){ + $profId = mysqli_real_escape_string($conn, $_POST['profId']); + if(mysqli_query($conn, "DELETE FROM ingProfiles WHERE id = '$profId'")){ + $response["success"] = 'Profile deleted'; + }else{ + $response["error"] = 'Error deleting profile'; + } + echo json_encode($response); + return; +} + +//ADD FORMULA CATEGORY +if($_POST['manage'] == 'add_frmcategory'){ + $cat = mysqli_real_escape_string($conn, $_POST['category']); + $type = mysqli_real_escape_string($conn, $_POST['cat_type']); + + if(empty($cat)){ + $response["error"] = 'Category name is required.'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM formulaCategories WHERE name = '$cat'"))){ + $response["error"] = 'Category name '.$cat.' already exists!'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO formulaCategories (name,cname,type) VALUES ('$cat', '".strtolower(str_replace(' ', '',$cat))."', '$type')")){ + $response["success"] = 'Category '.$cat.' created!'; + }else{ + $response["error"] = 'Something went wrong, '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//DELETE FORMULA CATEGORY +if($_POST['action'] == 'del_frmcategory' && $_POST['catId']){ + $catId = mysqli_real_escape_string($conn, $_POST['catId']); + if(mysqli_query($conn, "DELETE FROM formulaCategories WHERE id = '$catId'")){ + $response["success"] = 'Category deleted'; + }else{ + $response["error"] = 'Error deleting category'; + } + echo json_encode($response); + return; +} + + +//DELETE BATCH +if($_POST['action'] == 'batch' && $_POST['bid'] && $_POST['remove'] == true){ + $id = mysqli_real_escape_string($conn, $_POST['bid']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "DELETE FROM batchIDHistory WHERE id = '$id'")){ + + $response["success"] = 'Batch '.$id.' for product '.$name.' deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//UPDATE SDS DISCLAIMER +if($_POST['action'] == 'sdsDisclaimerContent'){ + $sds_disc_content = mysqli_real_escape_string($conn, $_POST['sds_disc_content']); + + if(empty($sds_disc_content)){ + $response["error"] = 'Disclaimer text is required.'; + echo json_encode($response); + return; + } + + + if(mysqli_query($conn, "UPDATE settings SET sds_disclaimer = '$sds_disc_content'")){ + $response["success"] = 'SDS Disclaimer text updated'; + }else{ + $response["error"] = 'Error '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +//DELETE SDS +if($_POST['action'] == 'delete' && $_POST['SDSID'] && $_POST['type'] == 'SDS'){ + $id = mysqli_real_escape_string($conn, $_POST['SDSID']); + + if(mysqli_query($conn, "DELETE FROM documents WHERE ownerID = '$id' AND isSDS = '1'")){ + mysqli_query($conn, "DELETE FROM sds_data WHERE id = '$id'"); + + $response["success"] = 'SDS deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//ADD INVENTORY COMPOUND +if($_POST['action'] == 'add' && $_POST['type'] == 'invCmp'){ + $name = mysqli_real_escape_string($conn, $_POST['cmp_name']); + $size = mysqli_real_escape_string($conn, $_POST['cmp_size']); + + if(empty($name)){ + $response["error"] = 'Name is required.'; + echo json_encode($response); + return; + } + if(!is_numeric($size)){ + $response["error"] = 'Size can only be numeric'; + echo json_encode($response); + return; + } + $batch_id = mysqli_real_escape_string($conn, $_POST['cmp_batch']); + $location = mysqli_real_escape_string($conn, $_POST['cmp_location']); + $description = mysqli_real_escape_string($conn, $_POST['cmp_desc']); + $label_info = mysqli_real_escape_string($conn, $_POST['cmp_label_info']); + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM inventory_compounds WHERE name = '$name'"))){ + $response["error"] = 'Error: '.$name.' already exists'; + + }elseif(mysqli_query($conn, "INSERT INTO inventory_compounds (name,description,batch_id,size,owner_id,location,label_info) VALUES ('$name', '$description', '$batch_id', '$size', '".$user['id']."', '$location', '$label_info' )")){ + $response["success"] = 'Compound '.$name.' added'; + }else{ + $response["error"] = 'Error adding compound '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +//UPDATE COMPOUND DATA +if($_POST['update_inv_compound_data']){ + + if(!$_POST['name']){ + $response["error"] = "Name is required"; + echo json_encode($response); + return; + } + + $id = $_POST['cmp_id']; + $name = $_POST['name']; + $description = $_POST['description']; + $batch_id = $_POST['batch_id']; + $size = $_POST['size']; + $location = $_POST['location'] ?: '-'; + $label_info = $_POST['label_info'] ?: '-'; + + $q = mysqli_query($conn,"UPDATE inventory_compounds SET name = '$name', description = '$description', batch_id = '$batch_id', size = '$size', location = '$location', label_info = '$label_info' WHERE id = '$id'"); + + + if($q){ + $response['success'] = "Compound updated"; + }else{ + $response['error'] = "Error updating data ".mysqli_error($conn); + } + + echo json_encode($response); + + + + return; +} + +//DELETE COMPOUND +if($_POST['action'] == 'delete' && $_POST['compoundId'] && $_POST['type'] == 'invCmp'){ + $id = mysqli_real_escape_string($conn, $_POST['compoundId']); + + if(mysqli_query($conn, "DELETE FROM inventory_compounds WHERE id = '$id'")){ + $response["success"] = 'Compound deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + + + +//WIPE OUT FROMULAS +if($_POST['formulas_wipe'] == 'true'){ + + if(mysqli_query($conn, "TRUNCATE formulas")){ + mysqli_query($conn, "TRUNCATE formulasMetaData"); + mysqli_query($conn, "TRUNCATE formula_history"); + mysqli_query($conn, "TRUNCATE formulasTags"); + mysqli_query($conn, "TRUNCATE ingredient_compounds"); + mysqli_query($conn, "TRUNCATE formulaCategories"); + mysqli_query($conn, "TRUNCATE formulasRevisions"); + mysqli_query($conn, "TRUNCATE makeFormula"); + + $response["success"] = 'Formulas and related data deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//WIPE OUT INGREDIENTS +if($_POST['ingredient_wipe'] == 'true'){ + + if(mysqli_query($conn, "TRUNCATE ingredients")){ + mysqli_query($conn, "TRUNCATE ingCategory"); + mysqli_query($conn, "TRUNCATE ingProfiles"); + mysqli_query($conn, "TRUNCATE ingReplacements"); + mysqli_query($conn, "TRUNCATE ingSafetyInfo"); + mysqli_query($conn, "TRUNCATE suppliers"); + mysqli_query($conn, "TRUNCATE synonyms"); + + $response["success"] = 'Ingredients and related data deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + + +//UPDATE CAS IFRA ENTRY +if($_REQUEST['IFRA'] == 'edit'){ + $type = $_REQUEST['type']; + if(mysqli_query($conn, "UPDATE IFRALibrary SET $type = '".$_REQUEST['value']."' WHERE id = '".$_REQUEST['pk']."'")){ + $response["success"] = 'IFRA entry updated'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//DELETE IFRA ENTRY +if($_POST['IFRA'] == 'delete' && $_POST['ID'] && $_POST['type'] == 'IFRA'){ + + if(mysqli_query($conn, "DELETE FROM IFRALibrary WHERE id = '".$_POST['ID']."'")){ + $response["success"] = 'IFRA entry deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//Merge ingredients +if($_POST['merge'] && $_POST['ingSrcID'] && $_POST['ingSrcName'] && $_POST['fid']){ + if(!$_POST['dest']){ + $response['error'] = 'Please select ingedient'; + echo json_encode($response); + return; + } + + $dest = mysqli_fetch_array(mysqli_query($conn,"SELECT ingredient FROM formulas WHERE id = '".$_POST['dest']."'")); + + if($dest['ingredient'] == $_POST['ingSrcName']){ + $response['error'] = 'Source and destination ingredients cannot be the same'; + echo json_encode($response); + return; + } + + $mq = "UPDATE formulas SET quantity = quantity + (SELECT quantity FROM formulas WHERE id ='".$_POST['ingSrcID']."' AND fid = '".$_POST['fid']."') WHERE id = '".$_POST['dest']."' AND fid = '".$_POST['fid']."'"; + + if(mysqli_query($conn,$mq)){ + mysqli_query($conn,"DELETE FROM formulas WHERE id = '".$_POST['ingSrcID']."' AND fid = '".$_POST['fid']."'"); + $response['success'] = $_POST['ingSrcName'].' merged with '.$dest['ingredient']; + }else{ + $response['error'] = 'Something went wrong..'.mysqli_error($conn); + } + + echo json_encode($response); + return; + +} + +//PVOnline Single Import +if($_POST['action'] == 'import' && $_POST['source'] == 'PVOnline' && $_POST['kind'] == 'ingredient' && $_POST['ing_id']){ + $id = mysqli_real_escape_string($conn, $_POST['ing_id']); + + $jAPI = $pvOnlineAPI.'?request=ingredients&src=PV_PRO&id='.$id; + $jsonData = json_decode(pv_file_get_contents($jAPI), true); + + if($jsonData['error']){ + $response['error'] = 'Error: '.$jsonData['error']['msg']; + echo json_encode($response); + return; + } + + $array_data = $jsonData['ingredients']; + + foreach ($array_data as $id=>$row) { + $insertPairs = array(); + unset($row['structure']); + unset($row['techData']); + unset($row['ifra']); + unset($row['IUPAC']); + unset($row['id']); + + foreach ($row as $key=>$val){ + + $insertPairs[addslashes($key)] = addslashes($val); + } + + $insertKeys = '`' . implode('`,`', array_keys($insertPairs)) . '`'; + $insertVals = '"' . implode('","', array_values($insertPairs)) . '"'; + + $query = "SELECT name FROM ingredients WHERE name = '".$insertPairs['name']."'"; + + if(!mysqli_num_rows(mysqli_query($conn, $query))){ + $jsql = "INSERT INTO ingredients ({$insertKeys}) VALUES ({$insertVals});"; + if( $qIns = mysqli_query($conn,$jsql)){ + + $response["success"] = 'Ingredient data imported'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + }else{ + $response["error"] = 'Error: ingredient already exists'; + } + } + + + + echo json_encode($response); + return; +} + + +//UPDATE BK PROVIDER +if ($_REQUEST['bkProv'] == 'update') { + if ( empty($_POST['creds']) || empty($_POST['schedule']) || empty($_POST['bkDesc']) || empty($_POST['gdrive_name'])) { + $response["error"] = 'Missing fields'; + echo json_encode($response); + return; + } + + $enabled = mysqli_real_escape_string($conn, $_POST['enabled']); + $schedule = mysqli_real_escape_string($conn, $_POST['schedule']); + $bkDesc = mysqli_real_escape_string($conn, $_POST['bkDesc']); + $creds = mysqli_real_escape_string($conn, $_POST['creds']); + $gdrive_name = mysqli_real_escape_string($conn, $_POST['gdrive_name']); + $bk_srv_host = $_POST['bk_srv_host']; + + + if (mysqli_query($conn, "UPDATE backup_provider SET credentials = '$creds', enabled = '$enabled', schedule = '$schedule', description = '$bkDesc', gdrive_name = '$gdrive_name' WHERE id = '1'")) { + mysqli_query($conn, "UPDATE settings SET bk_srv_host = '$bk_srv_host'"); + $response["success"] = 'Settings updated'; + } else { + $response["error"] = 'Error: ' . mysqli_error($conn); + } + + echo json_encode($response); + return; +} + + +//UPDATE HTML TEMPLATE +if($_REQUEST['action'] == 'htmlTmplUpdate'){ + $value = mysqli_real_escape_string($conn,$_POST['value']); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "UPDATE templates SET $name = '$value' WHERE id = '$id'")){ + $response["success"] = 'Template updated'; + }else{ + $response["error"] = mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//DELETE HTML TEMPLATE +if($_POST['action'] == 'htmlTmplDelete' && $_POST['tmplID']){ + $id = $_POST['tmplID']; + $name = $_POST['tmplName']; + + if(mysqli_query($conn, "DELETE FROM templates WHERE id = '$id'")){ + $response["success"] = 'Template '.$name.' deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//ADD NEW TEMPLATE +if($_POST['action'] == 'htmlTmplAdd'){ + + if(empty($_POST['tmpl_name'])){ + $response["error"] = 'Name is required'; + echo json_encode($response); + return; + } + + if(empty($_POST['tmpl_content'])){ + $response["error"] = 'HTML Content is required'; + echo json_encode($response); + return; + } + + if(empty($_POST['tmpl_desc'])){ + $response["error"] = 'Description is required.'; + echo json_encode($response); + return; + } + + $name = mysqli_real_escape_string($conn,$_POST['tmpl_name']); + $html = mysqli_real_escape_string($conn,$_POST['tmpl_content']); + $desc = mysqli_real_escape_string($conn,$_POST['tmpl_desc']); + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM templates WHERE name = '$name'"))){ + $response["error"] = $name.' already exists!'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO templates (name,content,description) VALUES ('$name','$html','$desc')")){ + $response["success"] = $name.' created!'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + + +//UPDATE PERFUME TYPES +if($_GET['perfType'] == 'update'){ + $value = trim(mysqli_real_escape_string($conn, $_POST['value'])); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "UPDATE perfumeTypes SET $name = '$value' WHERE id = '$id'")){ + $response["success"] = 'Perfume type updated'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//DELETE PERFUME TYPE +if($_POST['perfType'] == 'delete' && $_POST['pID']){ + $id = $_POST['pID']; + $name = $_POST['pName']; + + if(mysqli_query($conn, "DELETE FROM perfumeTypes WHERE id = '$id'")){ + $response["success"] = 'Pefume type '.$name.' deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//ADD PERFUME TYPE +if($_POST['perfType'] == 'add'){ + + if(empty($_POST['perfType_name'])){ + $response["error"] = 'Name is required'; + echo json_encode($response); + return; + } + + if(empty($_POST['perfType_conc'])){ + $response["error"] = 'Concentration is required'; + echo json_encode($response); + return; + } + + if(!is_numeric($_POST['perfType_conc'])){ + $response["error"] = 'Concentration must be integer.'; + echo json_encode($response); + return; + } + + $name = $_POST['perfType_name']; + $conc = $_POST['perfType_conc']; + $desc = $_POST['perfType_desc']; + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM perfumeTypes WHERE name = '$name'"))){ + $response["error"] = $name.' already exists!'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO perfumeTypes (name,concentration,description) VALUES ('$name','$conc','$desc')")){ + $response["success"] = $name.' created!'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//UPDATE ACCESSORY PIC +if($_GET['update_accessory_pic']){ + $allowed_ext = "png, jpg, jpeg, gif, bmp"; + + $filename = $_FILES["accessory_pic"]["tmp_name"]; + $file_ext = strtolower(end(explode('.',$_FILES['accessory_pic']['name']))); + $file_tmp = $_FILES['accessory_pic']['tmp_name']; + $ext = explode(', ',strtolower($allowed_ext)); + + if(!$filename){ + return; + } + + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0740, true); + } + + if(in_array($file_ext,$ext)===false){ + $response["error"] = 'Extension not allowed, please choose a '.$allowed_ext.' file'; + echo json_encode($response); + return; + } + $accessory = $_GET['accessory_id']; + if($_FILES["accessory_pic"]["size"] > 0){ + move_uploaded_file($file_tmp,$tmp_path.base64_encode($filename)); + $pic = base64_encode($filename); + create_thumb($tmp_path.$pic,250,250); + $docData = 'data:application/' . $file_ext . ';base64,' . base64_encode(file_get_contents($tmp_path.$pic)); + + mysqli_query($conn, "DELETE FROM documents WHERE ownerID = '".$accessory."' AND type = '5'"); + if(mysqli_query($conn, "INSERT INTO documents (ownerID,name,type,notes,docData) VALUES ('".$accessory."','-','5','-','$docData')")){ + unlink($tmp_path.$pic); + $response["success"] = array( "msg" => "Photo updated", "accessory_pic" => $docData); + echo json_encode($response); + return; + } + $response["error"] = mysqli_error($conn); + echo json_encode($response); + return; + } + + return; +} + +//UPDATE BOTTLE PIC +if($_GET['update_bottle_pic']){ + $allowed_ext = "png, jpg, jpeg, gif, bmp"; + + $filename = $_FILES["bottle_pic"]["tmp_name"]; + $file_ext = strtolower(end(explode('.',$_FILES['bottle_pic']['name']))); + $file_tmp = $_FILES['bottle_pic']['tmp_name']; + $ext = explode(', ',strtolower($allowed_ext)); + + + if(!$filename){ + //$response["error"] = 'Please choose a file to upload'; + //echo json_encode($response); + return; + } + + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0740, true); + } + + if(in_array($file_ext,$ext)===false){ + $response["error"] = 'Extension not allowed, please choose a '.$allowed_ext.' file'; + echo json_encode($response); + return; + } + $bottle = $_GET['bottle_id']; + if($_FILES["bottle_pic"]["size"] > 0){ + move_uploaded_file($file_tmp,$tmp_path.base64_encode($filename)); + $bottle_pic = base64_encode($filename); + create_thumb($tmp_path.$bottle_pic,250,250); + $docData = 'data:application/' . $file_ext . ';base64,' . base64_encode(file_get_contents($tmp_path.$bottle_pic)); + + mysqli_query($conn, "DELETE FROM documents WHERE ownerID = '".$bottle."' AND type = '4'"); + if(mysqli_query($conn, "INSERT INTO documents (ownerID,name,type,notes,docData) VALUES ('".$bottle."','-','4','-','$docData')")){ + unlink($tmp_path.$bottle_pic); + $response["success"] = array( "msg" => "File uploaded", "file" => $docData); + echo json_encode($response); + return; + } + $response["error"] = mysqli_error($conn); + echo json_encode($response); + return; + } + + return; +} + +//UPDATE BOTTLE DATA +if($_POST['update_bottle_data']){ + + if(!$_POST['name']){ + $response["error"] = "Name is required"; + echo json_encode($response); + return; + } + + if(!is_numeric($_POST['size']) || $_POST['size'] <= 0) { + $response["error"] = "Size is invalid"; + echo json_encode($response); + return; + } + + if (!is_numeric($_POST['price']) || $_POST['price'] <= 0) { + $response["error"] = "Price is invalid"; + echo json_encode($response); + return; + } + + $id = $_POST['bottle_id']; + $name = mysqli_real_escape_string($conn, $_POST['name']); + $ml = $_POST['size']; + $price = $_POST['price']; + $height = $_POST['height']; + $width = $_POST['width']; + $diameter = $_POST['diameter']; + $supplier = $_POST['supplier']; + $supplier_link = $_POST['supplier_link']; + $notes = $_POST['notes']; + $pieces = $_POST['pieces']?:0; + $weight = $_POST['weight']?:0; + + $q = mysqli_query($conn,"UPDATE bottles SET name= '$name', ml = '$ml', price = '$price', height = '$height', width = '$width', diameter = '$diameter', supplier = '$supplier', supplier_link = '$supplier_link', notes = '$notes', pieces = '$pieces', weight = '$weight' WHERE id = '$id'"); + + + if($q){ + $response['success'] = "Bottle updated"; + }else{ + $response['error'] = "Error updating bottle data ".mysqli_error($conn); + } + + echo json_encode($response); + + + + return; +} + +//UPDATE ACCESSORY DATA +if($_POST['update_accessory_data']){ + + if(!$_POST['name']){ + $response["error"] = "Name is required"; + echo json_encode($response); + return; + } + $id = $_POST['accessory_id']; + $name = $_POST['name']; + $accessory = $_POST['accessory']; + $supplier = $_POST['supplier']; + $supplier_link = $_POST['supplier_link']; + $pieces = $_POST['pieces']?:0; + + if (!is_numeric($_POST['price']) || $_POST['price'] <= 0 ) { + $response["error"] = 'Price cannot be empty or 0'; + echo json_encode($response); + return; + } + + $price = $_POST['price']; + + $q = mysqli_query($conn,"UPDATE inventory_accessories SET name = '$name', accessory = '$accessory', price = '$price', supplier = '$supplier', supplier_link = '$supplier_link', pieces = '$pieces' WHERE id = '$id'"); + + + if($q){ + $response['success'] = "Accessory updated"; + }else{ + $response['error'] = "Error updating accessory data ".mysqli_error($conn); + } + + echo json_encode($response); + + + + return; +} +//DELETE BOTTLE +if($_POST['action'] == 'delete' && $_POST['btlId'] && $_POST['type'] == 'bottle'){ + $id = mysqli_real_escape_string($conn, $_POST['btlId']); + + if(mysqli_query($conn, "DELETE FROM bottles WHERE id = '$id'")){ + mysqli_query($conn, "DELETE FROM documents WHERE ownerID = '$id' AND type = '4'"); + $response["success"] = 'Bottle deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//DELETE ACCESSORY +if($_POST['action'] == 'delete' && $_POST['accessoryId'] && $_POST['type'] == 'accessory'){ + $id = mysqli_real_escape_string($conn, $_POST['accessoryId']); + + if(mysqli_query($conn, "DELETE FROM inventory_accessories WHERE id = '$id'")){ + mysqli_query($conn, "DELETE FROM documents WHERE ownerID = '$id' AND type = '5'"); + $response["success"] = 'Accessory deleted'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//IMPORT IMAGES FROM PUBCHEM +if(isset($_GET['IFRA_PB']) && $_GET['IFRA_PB'] === 'import'){ + require_once(__ROOT__.'/func/pvFileGet.php'); + + $i = 0; + $response = []; + + $qCas = mysqli_query($conn, "SELECT cas FROM IFRALibrary WHERE image IS NULL OR image = '' OR image = '-'"); + + if(!$qCas || mysqli_num_rows($qCas) == 0){ + $response["error"] = 'IFRA Database is currently empty or there was a problem with the query.'; + echo json_encode($response); + return; + } + + $view = $settings['pubchem_view']; + + while($cas = mysqli_fetch_assoc($qCas)){ + $casNumber = trim($cas['cas']); + $imageUrl = $pubChemApi.'/pug/compound/name/'.$casNumber.'/PNG?record_type='.$view.'&image_size=small'; + $imageContent = pv_file_get_contents($imageUrl); + + if($imageContent !== false){ + $image = base64_encode($imageContent); + $stmt = $conn->prepare("UPDATE IFRALibrary SET image = ? WHERE cas = ?"); + $stmt->bind_param('ss', $image, $casNumber); + + if($stmt->execute()){ + $i++; + } else { + $response["error"] = 'Error updating image for CAS: '.$casNumber.' - '.mysqli_error($conn); + echo json_encode($response); + return; + } + + $stmt->close(); + } + + usleep(100000); // 0.1 seconds delay + } + + $response["success"] = $i.' images updated!'; + echo json_encode($response); + return; +} + + +//Update data FROM PubChem +if($_POST['pubChemData'] == 'update' && $_POST['cas']){ + $cas = trim($_POST['cas']); + $molecularWeight = $_POST['molecularWeight']; + $logP = trim($_POST['logP']); + $molecularFormula = $_POST['molecularFormula']; + $InChI = $_POST['InChI']; + $CanonicalSMILES = $_POST['CanonicalSMILES']; + $ExactMass = trim($_POST['ExactMass']); + + if($molecularWeight){ + $q = mysqli_query($conn, "UPDATE ingredients SET molecularWeight = '$molecularWeight' WHERE cas='$cas'"); + } + if($logP){ + $q.= mysqli_query($conn, "UPDATE ingredients SET logp = '$logP' WHERE cas='$cas'"); + } + if($molecularFormula){ + $q.= mysqli_query($conn, "UPDATE ingredients SET formula = '$molecularFormula' WHERE cas='$cas'"); + } + if($InChI){ + $q.= mysqli_query($conn, "UPDATE ingredients SET INCI = '$InChI' WHERE cas='$cas'"); + } + if($q){ + $response["success"] = 'Local data updated'; + }else{ + $response["error"] = 'Unable to update data'; + } + echo json_encode($response); + return; +} + +//IMPORT SYNONYMS FROM PubChem +if($_POST['synonym'] == 'import' && $_POST['method'] == 'pubchem'){ + $ing = base64_decode($_POST['ing']); + $cas = trim($_POST['cas']); + + $u = $pubChemApi.'/pug/compound/name/'.$cas.'/synonyms/JSON'; + $json = file_get_contents($u); + $json = json_decode($json); + $data = $json->InformationList->Information[0]->Synonym; + $cid = $json->InformationList->Information[0]->CID; + $source = 'PubChem'; + if(empty($data)){ + $response["error"] = 'No data found'; + echo json_encode($response); + return; + } + $i=0; + foreach($data as $d){ + $einecs = explode('EINECS ',$d); + if($einecs['1']){ + mysqli_query($conn, "UPDATE ingredients SET einecs = '".$einecs['1']."' WHERE cas = '$cas'"); + } + $fema = explode('FEMA ',$d); + if($fema['1']){ + mysqli_query($conn, "UPDATE ingredients SET FEMA = '".preg_replace("/[^0-9]/", "", $fema['1'])."' WHERE cas = '$cas'"); + } + $sql = mysqli_query($conn, "SELECT synonym FROM synonyms WHERE synonym = '$d' AND ing = '$ing'"); + if(!$sql || !mysqli_num_rows($sql)){ + $r = mysqli_query($conn, "INSERT INTO synonyms (ing,cid,synonym,source) VALUES ('$ing','$cid','$d','$source')"); + $i++; + } + } + if($r){ + $response["success"] = $i.' synonym(s) imported'; + }else{ + $response["error"] = 'Data already in sync'; + } + echo json_encode($response); + return; +} + +//ADD SYNONYM +if($_POST['synonym'] == 'add'){ + $synonym = mysqli_real_escape_string($conn, $_POST['sName']); + $source = mysqli_real_escape_string($conn, $_POST['source']); + + $ing = base64_decode($_POST['ing']); + + if(empty($synonym)){ + $response["error"] = 'Synonym name is required'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT synonym FROM synonyms WHERE synonym = '$synonym' AND ing = '$ing'"))){ + $response["error"] = $synonym.' already exists'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO synonyms (synonym,source,ing) VALUES ('$synonym','$source','$ing')")){ + $response["success"] = $synonym.' added to the list'; + echo json_encode($response); + } + + return; +} + + +//UPDATE SYNONYM +if($_GET['synonym'] == 'update'){ + $value = trim(mysqli_real_escape_string($conn, $_POST['value'])); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + $ing = base64_decode($_GET['ing']); + + if(mysqli_query($conn, "UPDATE synonyms SET $name = '$value' WHERE id = '$id' AND ing='$ing'")){ + $response["success"] = 'Synonym updated'; + } else { + $response["error"] = mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +//DELETE ING SYNONYM +if($_GET['synonym'] == 'delete'){ + $id = mysqli_real_escape_string($conn, $_GET['id']); + if(mysqli_query($conn, "DELETE FROM synonyms WHERE id = '$id'")){ + $response["success"] = 'Synonym deleted'; + } else { + $response["error"] = mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//ADD REPLACEMENT +if($_POST['replacement'] == 'add'){ + + $ing_name = base64_decode($_POST['ing_name']); + $ing_cas = trim($_POST['ing_cas']); + + if(empty($_POST['rName'])){ + $response["error"] = 'Name is required'; + echo json_encode($response); + return; + } + + if(empty($_POST['rCAS'])){ + $response["error"] = 'CAS is required'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT ing_rep_name FROM ingReplacements WHERE ing_name = '$ing_name' AND ing_rep_name = '".$_POST['rName']."'"))){ + $response["error"] = $_POST['rName'].' already exists!'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO ingReplacements (ing_id,ing_name,ing_cas,ing_rep_id,ing_rep_name,ing_rep_cas,notes) VALUES ('".$_POST['ing_id']."','$ing_name','$ing_cas','".$_POST['rIngId']."','".$_POST['rName']."','".$_POST['rCAS']."','".$_POST['rNotes']."')")){ + $response["success"] = $_POST['rName'].' added to the list!'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//UPDATE ING REPLACEMENT +if($_GET['replacement'] == 'update'){ + $value = trim(mysqli_real_escape_string($conn, $_POST['value'])); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + $ing = base64_decode($_GET['ing']); + + if(mysqli_query($conn, "UPDATE ingReplacements SET $name = '$value' WHERE id = '$id' AND ing_name='$ing'")){ + $response["success"] = $ing.' replacement updated'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + + +//DELETE ING REPLACEMENT +if($_POST['replacement'] == 'delete'){ + $id = mysqli_real_escape_string($conn, $_POST['id']); + if(mysqli_query($conn, "DELETE FROM ingReplacements WHERE id = '$id'")){ + $response["success"] = $_POST['name'].' replacement removed'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +//UPDATE ING DOCUMENT +if($_GET['action'] == 'updateDocument'){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + $ownerID = mysqli_real_escape_string($conn, $_GET['ingID']); + + if(mysqli_query($conn, "UPDATE documents SET $name = '$value' WHERE ownerID = '$ownerID' AND id='$id'")){ + $response["success"] = 'Document updated'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +//DELETE DOCUMENT +if($_GET['action'] == 'deleteDocument'){ + $id = mysqli_real_escape_string($conn, $_GET['id']); + $ownerID = mysqli_real_escape_string($conn, $_GET['ownerID']); + + if(mysqli_query($conn, "DELETE FROM documents WHERE id = '$id' AND ownerID='$ownerID'")){ + $response["success"] = 'Document deletetd'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//GET SUPPLIER PRICE +if($_POST['ingSupplier'] == 'getPrice'){ + $ingID = mysqli_real_escape_string($conn, $_POST['ingID']); + $ingSupplierID = mysqli_real_escape_string($conn, $_POST['ingSupplierID']); + $size = mysqli_real_escape_string($conn, $_POST['size']); + $supplier_link = urldecode($_POST['sLink']); + + $supp_data = mysqli_fetch_array(mysqli_query($conn, "SELECT price_tag_start,price_tag_end,add_costs,price_per_size FROM ingSuppliers WHERE id = '$ingSupplierID'")); + + if($newPrice = priceScrape($supplier_link,$size,$supp_data['price_tag_start'],$supp_data['price_tag_end'],$supp_data['add_costs'],$supp_data['price_per_size'])){ + if(mysqli_query($conn, "UPDATE suppliers SET price = '$newPrice' WHERE ingSupplierID = '$ingSupplierID' AND ingID='$ingID'")){ + $response["success"] = 'Price updated'; + echo json_encode($response); + } + }else{ + $response["error"] = 'Error getting the price from the supplier. Previous value has been retained.'; + echo json_encode($response); + } + return; +} + +//ADD ING SUPPLIER +if($_POST['ingSupplier'] == 'add'){ + if(empty($_POST['supplier_id']) || empty($_POST['supplier_link']) || empty($_POST['supplier_size']) || empty($_POST['supplier_price'])){ + $response["error"] = 'Error: Missing fields!'; + echo json_encode($response); + return; + } + + if(!is_numeric($_POST['supplier_size']) || !is_numeric($_POST['stock']) || !is_numeric($_POST['supplier_price'])){ + $response["error"] = 'Error: Only numeric values allowed in size, stock and price fields!'; + echo json_encode($response); + return; + } + + $ingID = mysqli_real_escape_string($conn, $_POST['ingID']); + $supplier_id = mysqli_real_escape_string($conn, $_POST['supplier_id']); + $supplier_link = mysqli_real_escape_string($conn, $_POST['supplier_link']); + $supplier_size = mysqli_real_escape_string($conn, $_POST['supplier_size']); + $supplier_price = mysqli_real_escape_string($conn, $_POST['supplier_price']); + $supplier_manufacturer = mysqli_real_escape_string($conn, $_POST['supplier_manufacturer']); + $supplier_name = mysqli_fetch_array(mysqli_query($conn, "SELECT name FROM ingSuppliers WHERE id = '$supplier_id'")); + $supplier_batch = mysqli_real_escape_string($conn, $_POST['supplier_batch']); + $purchased = mysqli_real_escape_string($conn, $_POST['purchased'] ?: date('Y-m-d')); + $stock = mysqli_real_escape_string($conn, $_POST['stock'] ?: 0); + $mUnit = $_POST['mUnit']; + $status = $_POST['status']; + $supplier_sku = mysqli_real_escape_string($conn, $_POST['supplier_sku']); + $internal_sku = mysqli_real_escape_string($conn, $_POST['internal_sku']); + $storage_location = mysqli_real_escape_string($conn, $_POST['storage_location']); + + + if(mysqli_num_rows(mysqli_query($conn, "SELECT ingSupplierID FROM suppliers WHERE ingSupplierID = '$supplier_id' AND ingID = '$ingID'"))){ + $response["error"] = $supplier_name['name'].' already exists'; + echo json_encode($response); + return; + } + + if(!mysqli_num_rows(mysqli_query($conn, "SELECT ingSupplierID FROM suppliers WHERE ingID = '$ingID'"))){ + $preferred = '1'; + }else{ + $preferred = '0'; + } + + if(mysqli_query($conn, "INSERT INTO suppliers (ingSupplierID,ingID,supplierLink,price,size,manufacturer,preferred,batch,purchased,stock,mUnit,status,supplier_sku,internal_sku,storage_location) VALUES ('$supplier_id','$ingID','$supplier_link','$supplier_price','$supplier_size','$supplier_manufacturer','$preferred','$supplier_batch','$purchased','$stock','$mUnit','$status','$supplier_sku','$internal_sku','$storage_location')")){ + $response["success"] = $supplier_name['name'].' added'; + }else{ + $response["error"] = mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//UPDATE ING SUPPLIER +if($_GET['ingSupplier'] == 'update'){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + $ingID = mysqli_real_escape_string($conn, $_GET['ingID']); + + if(mysqli_query($conn, "UPDATE suppliers SET $name = '$value' WHERE id = '$id' AND ingID='$ingID'")){ + $response["success"] = 'Supplier updated'; + } else { + $response["error"] = mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//UPDATE PREFERRED SUPPLIER +if($_GET['ingSupplier'] == 'preferred'){ + $sID = mysqli_real_escape_string($conn, $_GET['sID']); + $ingID = mysqli_real_escape_string($conn, $_GET['ingID']); + $status = mysqli_real_escape_string($conn, $_GET['status']); + + mysqli_query($conn, "UPDATE suppliers SET preferred = '0' WHERE ingID='$ingID'"); + if(mysqli_query($conn, "UPDATE suppliers SET preferred = '$status' WHERE ingSupplierID = '$sID' AND ingID='$ingID'")){ + $response["success"] = 'Supplier set to prefered'; + } else { + $response["error"] = mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//DELETE ING SUPPLIER +if($_GET['ingSupplier'] == 'delete'){ + + $sID = mysqli_real_escape_string($conn, $_GET['sID']); + $ingID = mysqli_real_escape_string($conn, $_GET['ingID']); + + $supplierCount = mysqli_num_rows(mysqli_query($conn, "SELECT id FROM suppliers WHERE ingID = '$ingID'")); + if ($supplierCount <= 1) { + $response["error"] = 'Cannot delete the last supplier for this ingredient'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "DELETE FROM suppliers WHERE id = '$sID' AND ingID='$ingID'")){ + $response["success"] = 'Supplier deleted'; + } else { + $response["error"] = mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//FORMULA QUANTITY MANAGEMENT +if($_POST['updateQuantity'] && $_POST['ingQuantityID'] && $_POST['ingQuantityName'] && $_POST['fid']){ + $fid = $_POST['fid']; + $value = $_POST['ingQuantity']; + $ingredient = $_POST['ingQuantityID']; + $ing_name = $_POST['ingQuantityName']; + + if(empty($_POST['ingQuantity'])){ + $response["error"] = 'Quantity cannot be empty'; + echo json_encode($response); + return; + } + if(!is_numeric($_POST['ingQuantity'])){ + $response["error"] = 'Quantity must be numeric only'; + echo json_encode($response); + return; + } + + if($_POST['curQuantity'] == $_POST['ingQuantity']){ + $response["error"] = 'Quantity is already the same'; + echo json_encode($response); + return; + } + + + if($_POST['ingReCalc'] == 'true'){ + $ingID = $_POST['ingID']; + if(!$_POST['formulaSolventID']){ + $response["error"] = 'Please select a solvent'; + echo json_encode($response); + return; + } + $formulaSolventID = $_POST['formulaSolventID']; + + if(mysqli_num_rows(mysqli_query($conn,"SELECT id FROM ingredients WHERE id = '".$ingID."' AND profile='solvent'"))){ + $response["error"] = 'You cannot exchange a solvent with a solvent'; + echo json_encode($response); + return; + } + + $slv = mysqli_fetch_array(mysqli_query($conn,"SELECT quantity FROM formulas WHERE ingredient_id = '".$formulaSolventID."' AND fid = '".$fid."'")); + + $fq = $_POST['ingQuantity'] - $_POST['curQuantity']; + + if($slv['quantity'] < $fq){ + $response["error"] = 'Not enough solvent, available: '.number_format($slv['quantity'],$settings['qStep']).$settings['mUnit'].', Requested: '.number_format($fq,$settings['qStep']).$settings['mUnit']; + echo json_encode($response); + return; + } + + //UPDATE SOLVENT + function formatVal($num){ + return sprintf("%+.4f",$num); + } + + $curV = mysqli_fetch_array(mysqli_query($conn, "SELECT quantity FROM formulas WHERE fid = '$fid' AND id = '".$ingredient."'")); + $diff = number_format($curV['quantity'] - $value , 4); + $v = formatVal($diff); + + $qs ="UPDATE formulas SET quantity = quantity $v WHERE fid = '$fid' AND ingredient_id = '".$formulaSolventID."'"; + if(!mysqli_query($conn, $qs)){ + $response["error"] = 'Error updating solvent: '.mysqli_error($conn); + $response["query"] = $qs; + echo json_encode($response); + return; + } + } + + $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT id,isProtected FROM formulasMetaData WHERE fid = '".$_POST['fid']."'")); + + if($meta['isProtected'] == FALSE){ + + if(mysqli_query($conn, "UPDATE formulas SET quantity = '$value' WHERE fid = '$fid' AND id = '$ingredient'")){ + + $lg = "CHANGED: ".$ing_name." Set $name to $value"; + mysqli_query($conn, "INSERT INTO formula_history (fid,ing_id,change_made,user) VALUES ('".$meta['id']."','$ingredient','$lg','".$user['fullName']."')"); + + $response["success"] = 'Quantity updated'; + echo json_encode($response); + + }else{ + $response["error"] = mysqli_error($conn); + echo json_encode($response); + } + + } + return; +} + +if($_POST['value'] && $_GET['formula'] && $_POST['pk']){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $formula = mysqli_real_escape_string($conn, $_GET['formula']); + $ingredient = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + $ing_name = mysqli_fetch_array(mysqli_query($conn, "SELECT ingredient FROM formulas WHERE id = '$ingredient' AND fid = '".$_GET['formula']."'")); + + $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT id,isProtected FROM formulasMetaData WHERE fid = '".$_GET['formula']."'")); + if($meta['isProtected'] == FALSE){ + + if(mysqli_query($conn, "UPDATE formulas SET $name = '$value' WHERE fid = '$formula' AND id = '$ingredient'")){ + + $lg = "CHANGED: ".$ing_name['ingredient']." Set $name to $value"; + mysqli_query($conn, "INSERT INTO formula_history (fid,ing_id,change_made,user) VALUES ('".$meta['id']."','$ingredient','$lg','".$user['fullName']."')"); + $response["success"] = 'Formula updated'; + } else { + $response["error"] = mysqli_error($conn); + } + } + echo json_encode($response); + return; +} + +if($_GET['formulaMeta']){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $formula = mysqli_real_escape_string($conn, base64_decode($_GET['formulaMeta'])); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "UPDATE formulasMetaData SET $name = '$value' WHERE id = '$id'")){ + $response["success"] = 'Formula meta updated'; + } else { + $response["error"] = mysqli_error($conn); + } + echo json_encode($response); + return; +} + +if($_GET['createRev'] == 'man'){ + require_once(__ROOT__.'/func/createFormulaRevision.php'); + $fid = $_GET['fid']; + + if($l = createFormulaRevision($fid,'Manually',$conn)){ + $response["success"] = 'Revision created (If changes detected)'; + echo json_encode($response); + }else{ + $response["error"] = 'Unable to create revision, please make sure formula exists and contains at least one ingredient.'; + echo json_encode($response); + } + return; +} + +if($_GET['protect']){ + require_once(__ROOT__.'/func/createFormulaRevision.php'); + $fid = mysqli_real_escape_string($conn, $_GET['protect']); + + if($_GET['isProtected'] == 'true'){ + $isProtected = '1'; + $l = 'locked'; + createFormulaRevision($fid,'Automatic',$conn); + }else{ + $isProtected = '0'; + $l = 'unlocked'; + } + if(mysqli_query($conn, "UPDATE formulasMetaData SET isProtected = '$isProtected' WHERE fid = '$fid'")){ + $response["success"] = 'Formula '.$l; + echo json_encode($response); + }else{ + $response["error"] = 'Something went wrong'; + echo json_encode($response); + } + return; +} + +if($_POST['formulaSettings'] && $_POST['set']){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $set = mysqli_real_escape_string($conn, $_POST['set']); + $val = mysqli_real_escape_string($conn, $_POST['val']); + + if(mysqli_query($conn, "UPDATE formulasMetaData SET $set = '$val' WHERE fid = '$fid'")){ + $response["success"] = "Formula settings updated"; + echo json_encode($response); + }else{ + $response["error"] = 'Something went wrong'; + echo json_encode($response); + } + return; +} + + + +if($_GET['action'] == 'rename' && $_GET['fid']){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $fid = mysqli_real_escape_string($conn, $_GET['fid']); + $id = $_POST['pk']; + if(!$value){ + $response["error"] = 'Formula name cannot be empty'; + echo json_encode($response); + return; + } + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM formulasMetaData WHERE name = '$value'"))){ + $response["error"] = 'Name already exists'; + echo json_encode($response); + + }else{ + mysqli_query($conn, "UPDATE formulasMetaData SET name = '$value' WHERE id = '$id'"); + if(mysqli_query($conn, "UPDATE formulas SET name = '$value' WHERE fid = '$fid'")){ + $response["success"] = 'Formula renamed'; + $response["msg"] = $value; + echo json_encode($response); + } + + } + + return; +} + +if($_GET['action'] == 'ingredientCategories'){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $cat_id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "UPDATE ingCategory SET $name = '$value' WHERE id = '$cat_id'")){ + $response["success"] = 'Ingredient category updated'; + }else{ + $response["error"] = mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +if($_GET['settings'] == 'prof'){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + mysqli_query($conn, "UPDATE ingProfiles SET $name = '$value' WHERE id = '$id'"); + return; +} + +if($_GET['settings'] == 'fcat' && $_GET['action'] == 'updateFormulaCategory' ){ + $value = mysqli_real_escape_string($conn, $_POST['value']); + $cat_id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "UPDATE formulaCategories SET $name = '$value' WHERE id = '$cat_id'")){ + $response["success"] = 'Formula actegory updated'; + } else { + $response["error"] = mysqli_error($conn); + } + echo json_encode($response); + return; +} + +if($_GET['settings'] == 'sup'){ + $value = htmlentities($_POST['value']); + $sup_id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + mysqli_query($conn, "UPDATE ingSuppliers SET $name = '$value' WHERE id = '$sup_id'"); + return; +} + +if($_POST['supp'] == 'edit'){ + $id = $_POST['id']; + + $name = mysqli_real_escape_string($conn, $_POST['name']); + $address = mysqli_real_escape_string($conn, $_POST['address']); + $po = mysqli_real_escape_string($conn, $_POST['po']); + $country = mysqli_real_escape_string($conn, $_POST['country']); + $telephone = mysqli_real_escape_string($conn, $_POST['telephone']); + $url = mysqli_real_escape_string($conn, $_POST['url']); + $email = mysqli_real_escape_string($conn, $_POST['email']); + + + if(mysqli_query($conn, "UPDATE ingSuppliers SET address = '$address', po='$po', country='$country', telephone='$telephone', url='$url', email='$email' WHERE id = '$id'")){ + $response["success"] = 'Supplier '.$name.' updated!'; + echo json_encode($response); + }else{ + $response["error"] = 'Something went wrong: '.mysqli_error($conn); + echo json_encode($response); + } + return; +} + + +if($_POST['supp'] == 'add'){ + if(!is_numeric($_POST['min_ml']) || !is_numeric($_POST['min_gr'])){ + $response["error"] = 'Only numeric values allowed in ml and grams fields!'; + echo json_encode($response); + return; + } + $description = mysqli_real_escape_string($conn, $_POST['description']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + $address = mysqli_real_escape_string($conn, $_POST['address']); + $po = mysqli_real_escape_string($conn, $_POST['po']); + $country = mysqli_real_escape_string($conn, $_POST['country']); + $telephone = mysqli_real_escape_string($conn, $_POST['telephone']); + $url = mysqli_real_escape_string($conn, $_POST['url']); + $email = mysqli_real_escape_string($conn, $_POST['email']); + $platform = mysqli_real_escape_string($conn, $_POST['platform']); + $price_tag_start = htmlentities($_POST['price_tag_start']); + $price_tag_end = htmlentities($_POST['price_tag_end']); + $add_costs = is_numeric($_POST['add_costs']); + $min_ml = mysqli_real_escape_string($conn, $_POST['min_ml']); + $min_gr = mysqli_real_escape_string($conn, $_POST['min_gr']); + + if(empty($min_ml)){ + $min_ml = 0; + } + if(empty($min_gr)){ + $min_gr = 0; + } + + if(empty($name)){ + $response["error"] = 'Error: Supplier name required'; + echo json_encode($response); + return; + } + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingSuppliers WHERE name = '$name'"))){ + $response["error"] = ''.$name.' Supplier already exists!'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO ingSuppliers (name,address,po,country,telephone,url,email,platform,price_tag_start,price_tag_end,add_costs,notes,min_ml,min_gr) VALUES ('$name','$address','$po','$country','$telephone','$url','$email','$platform','$price_tag_start','$price_tag_end','$add_costs','$description','$min_ml','$min_gr')")){ + $response["success"] = 'Supplier '.$name.' added!'; + echo json_encode($response); + }else{ + $response["error"] = 'Something went wrong: '.mysqli_error($conn); + echo json_encode($response); + } + return; +} + +if($_GET['supp'] == 'delete' && $_GET['ID']){ + $ID = mysqli_real_escape_string($conn, $_GET['ID']); + $supplier = mysqli_fetch_array(mysqli_query($conn, "SELECT name FROM ingSuppliers WHERE id = '$ID'")); + + if(mysqli_query($conn, "DELETE FROM ingSuppliers WHERE id = '$ID'")){ + $response["success"] = 'Supplier '.$supplier['name'].' deleted!'; + }else{ + $response["error"] = 'Something went wrong: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +//ADD composition +if($_POST['composition'] == 'add'){ + $allgName = mysqli_real_escape_string($conn, $_POST['allgName']); + $allgCAS = mysqli_real_escape_string($conn, $_POST['allgCAS']); + $allgEC = mysqli_real_escape_string($conn, $_POST['allgEC']); + $minPerc = rtrim(mysqli_real_escape_string($conn, $_POST['minPerc']),'%'); + $maxPerc = rtrim(mysqli_real_escape_string($conn, $_POST['maxPerc']),'%'); + $GHS = rtrim(mysqli_real_escape_string($conn, $_POST['GHS'])); + + $ing = base64_decode($_POST['ing']); + + if($_POST['addToDeclare'] == 'true'){ + $declare = '1'; + }else{ + $declare = '0'; + } + + if(empty($allgName)){ + $response["error"] = 'Name is required'; + echo json_encode($response); + return; + } + + if(empty($allgCAS)){ + $response["error"] = 'CAS number is required'; + echo json_encode($response); + return; + } + + if(empty($minPerc)){ + $response["error"] = 'Minimum percentage is required'; + echo json_encode($response); + return; + } + + if(empty($maxPerc)){ + $response["error"] = 'Max percentage is required'; + echo json_encode($response); + return; + } + + if(!is_numeric($minPerc)){ + $response["error"] = 'Minimum percentage value needs to be numeric'; + echo json_encode($response); + return; + } + + if(!is_numeric($maxPerc)){ + $response["error"] = 'Maximum percentage value needs to be numeric'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingredient_compounds WHERE name = '$allgName' AND ing = '$ing'"))){ + $response["error"] = $allgName.' already exists'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO ingredient_compounds (name, cas, ec, min_percentage, max_percentage, GHS, toDeclare, ing) VALUES ('$allgName','$allgCAS','$allgEC','$minPerc','$maxPerc','$GHS','$declare','$ing')")){ + $response["success"] = $allgName.' added to the composition'; + }else{ + $response["error"] = mysqli_error($conn); + } + + if($_POST['addToIng'] == 'true'){ + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM ingredients WHERE name = '$allgName'")))){ + mysqli_query($conn, "INSERT INTO ingredients (name,cas,einecs) VALUES ('$allgName','$allgCAS','$allgEC')"); + } + } + + echo json_encode($response); + return; +} + +//UPDATE composition +if($_GET['composition'] == 'update'){ + $value = rtrim(mysqli_real_escape_string($conn, $_POST['value']),'%'); + $id = mysqli_real_escape_string($conn, $_POST['pk']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "UPDATE ingredient_compounds SET $name = '$value' WHERE id = '$id'")){ + $response["success"] = 'Ingredient updated'; + } else { + $response["error"] = mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//DELETE composition +if($_POST['composition'] == 'delete'){ + + $id = mysqli_real_escape_string($conn, $_POST['allgID']); + //$ing = base64_decode($_POST['ing']); + + $delQ = mysqli_query($conn, "DELETE FROM ingredient_compounds WHERE id = '$id'"); + if($delQ){ + $response["success"] = $ing.' deleted'; + }else { + $response["error"] = mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//DELETE INGREDIENT +if($_POST['ingredient'] == 'delete' && $_POST['ing_id']){ + + $id = mysqli_real_escape_string($conn, $_POST['ing_id']); + $ing = mysqli_fetch_array(mysqli_query($conn, "SELECT name FROM ingredients WHERE id = '$id'")); + + if($_POST['forceDelIng'] == "false"){ + + if(mysqli_num_rows(mysqli_query($conn, "SELECT ingredient FROM formulas WHERE ingredient = '".$ing['name']."'"))){ + $response["error"] = ''.$ing['name'].' is in use by at least one formula and cannot be removed!'; + echo json_encode($response); + return; + } + } + if(mysqli_query($conn, "DELETE FROM ingredients WHERE id = '$id'")){ + mysqli_query($conn,"DELETE FROM ingredient_compounds WHERE ing = '".$ing['name']."'"); + $response["success"] = 'Ingredient '.$ing['name'].' removed from the database!'; + } + + echo json_encode($response); + return; + +} + +//CUSTOMERS - ADD +if($_POST['customer'] == 'add'){ + $name = mysqli_real_escape_string($conn, $_POST['name']); + if(empty($name)){ + $response["error"] = 'Customer name is required.'; + echo json_encode($response); + return; + } + $address = mysqli_real_escape_string($conn, $_POST['address']); + $email = mysqli_real_escape_string($conn, $_POST['email']); + $web = mysqli_real_escape_string($conn, $_POST['web']); + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM customers WHERE name = '$name'"))){ + $response["error"] = 'Error: '.$name.' already exists!'; + }elseif(mysqli_query($conn, "INSERT INTO customers (name,address,email,web,owner_id) VALUES ('$name', '$address', '$email', '$web', '".$user['id']."')")){ + $response["success"] = 'Customer '.$name.' added!'; + }else{ + $response["error"] = 'Error adding customer.'; + } + echo json_encode($response); + return; +} + +//CUSTOMERS - DELETE +if($_POST['action'] == 'delete' && $_POST['type'] == 'customer' && $_POST['customer_id']){ + $customer_id = mysqli_real_escape_string($conn, $_POST['customer_id']); + if(mysqli_query($conn, "DELETE FROM customers WHERE id = '$customer_id'")){ + $response["success"] = 'Customer deleted!'; + }else{ + $response["error"] = 'Error deleting customer '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//CUSTOMERS - UPDATE +if($_POST['update_customer_data'] && $_POST['customer_id']){ + $id = $_POST['customer_id']; + $name = mysqli_real_escape_string($conn, $_POST['name']); + if(empty($name)){ + $response["error"] = 'Name cannot be empty '; + echo json_encode($response); + return; + } + $address = mysqli_real_escape_string($conn, $_POST['address'])?:'N/A'; + $email = mysqli_real_escape_string($conn, $_POST['email'])?:'N/A'; + $web = mysqli_real_escape_string($conn, $_POST['web'])?:'N/A'; + $phone = mysqli_real_escape_string($conn, $_POST['phone'])?:'N/A'; + + if(mysqli_query($conn, "UPDATE customers SET name = '$name', address = '$address', email = '$email', web = '$web', phone = '$phone' WHERE id = '$id'")){ + $response["success"] = 'Customer details updated!'; + }else{ + $response["error"] = 'Error updating customer '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//MGM INGREDIENT +if($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'general'){ + $ing = mysqli_real_escape_string($conn, $_POST['ing']); + + $INCI = trim(mysqli_real_escape_string($conn, $_POST["INCI"])); + $cas = preg_replace('/\s+/', '', trim(mysqli_real_escape_string($conn, $_POST["cas"]))); + $einecs = preg_replace('/\s+/', '', trim(mysqli_real_escape_string($conn, $_POST["einecs"]))); + $reach = preg_replace('/\s+/', '', trim(mysqli_real_escape_string($conn, $_POST["reach"]))); + $fema = preg_replace('/\s+/', '', trim(mysqli_real_escape_string($conn, $_POST["fema"]))); + $purity = validateInput($_POST["purity"]); + $profile = mysqli_real_escape_string($conn, $_POST["profile"]); + $type = mysqli_real_escape_string($conn, $_POST["type"]); + $strength = mysqli_real_escape_string($conn, $_POST["strength"]); + $category = mysqli_real_escape_string($conn, $_POST["category"] ? $_POST['category']: '1'); + $physical_state = mysqli_real_escape_string($conn, $_POST["physical_state"]); + $odor = ucfirst(trim(mysqli_real_escape_string($conn, $_POST["odor"]))); + $notes = ucfirst(trim(mysqli_real_escape_string($conn, $_POST["notes"]))); + +// if(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM ingredients WHERE name = '".$_POST['name']."'"))){ + if(empty($_POST['name'])){ + + $query = "UPDATE ingredients SET INCI = '$INCI',cas = '$cas',solvent='".$_POST["solvent"]."', einecs = '$einecs', reach = '$reach',FEMA = '$fema',purity='$purity',profile='$profile',type = '$type',strength = '$strength', category='$category',physical_state = '$physical_state',odor = '$odor',notes = '$notes' WHERE name='$ing'"; + + if(mysqli_query($conn, $query)){ + $response["success"] = 'General details have been updated!'; + }else{ + $response["error"] = 'Unable to update database: '.mysqli_error($conn); + } + }else{ + $name = sanChar(mysqli_real_escape_string($conn, $_POST["name"])); + + $query = "INSERT INTO ingredients (name, INCI, cas, einecs, reach, FEMA, type, strength, category, profile, notes, odor, purity, solvent, physical_state) VALUES ('$name', '$INCI', '$cas', '$einecs', '$reach', '$fema', '$type', '$strength', '$category', '$profile', '$notes', '$odor', '$purity', '$solvent', '1')"; + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingredients WHERE name = '$name'"))){ + $response["error"] = $name.' already exists!'; + }else{ + if(mysqli_query($conn, $query)){ + $response["success"] = 'Ingredient '.$name.' created'; + $response["ingid"] = mysqli_insert_id($conn); + }else{ + $response["error"] = 'Failed to create ingredient'; + } + } + } + echo json_encode($response); + return; +} + + +if ($_POST['manage'] === 'ingredient' && $_POST['tab'] === 'usage_limits') { + $ingID = (int) $_POST['ingID']; + + $flavor_use = ($_POST['flavor_use'] === 'true') ? 1 : 0; + $noUsageLimit = ($_POST['noUsageLimit'] === 'true') ? 1 : 0; + $byPassIFRA = ($_POST['byPassIFRA'] === 'true') ? 1 : 0; + $allergen = ($_POST['isAllergen'] === 'true') ? 1 : 0; + + $usage_type = mysqli_real_escape_string($conn, trim($_POST['usage_type'])); + + $categories = [ + 'cat1' => (float) $_POST['cat1'], + 'cat2' => (float) $_POST['cat2'], + 'cat3' => (float) $_POST['cat3'], + 'cat4' => (float) $_POST['cat4'], + 'cat5A' => (float) $_POST['cat5A'], + 'cat5B' => (float) $_POST['cat5B'], + 'cat5C' => (float) $_POST['cat5C'], + 'cat5D' => (float) $_POST['cat5D'], + 'cat6' => (float) $_POST['cat6'], + 'cat7A' => (float) $_POST['cat7A'], + 'cat7B' => (float) $_POST['cat7B'], + 'cat8' => (float) $_POST['cat8'], + 'cat9' => (float) $_POST['cat9'], + 'cat10A' => (float) $_POST['cat10A'], + 'cat10B' => (float) $_POST['cat10B'], + 'cat11A' => (float) $_POST['cat11A'], + 'cat11B' => (float) $_POST['cat11B'], + 'cat12' => (float) $_POST['cat12'], + ]; + + $stmt = $conn->prepare( + "UPDATE ingredients SET byPassIFRA = ?, noUsageLimit = ?, flavor_use = ?, + usage_type = ?, allergen = ?, cat1 = ?, cat2 = ?, cat3 = ?, cat4 = ?, + cat5A = ?, cat5B = ?, cat5C = ?, cat5D = ?, cat6 = ?, cat7A = ?, cat7B = ?, + cat8 = ?, cat9 = ?, cat10A = ?, cat10B = ?, cat11A = ?, cat11B = ?, + cat12 = ? WHERE id = ?" + ); + + $stmt->bind_param( + 'iiisiddddddddddddddddddi', + $byPassIFRA, $noUsageLimit, $flavor_use, $usage_type, $allergen, + $categories['cat1'], $categories['cat2'], $categories['cat3'], + $categories['cat4'], $categories['cat5A'], $categories['cat5B'], + $categories['cat5C'], $categories['cat5D'], $categories['cat6'], + $categories['cat7A'], $categories['cat7B'], $categories['cat8'], + $categories['cat9'], $categories['cat10A'], $categories['cat10B'], + $categories['cat11A'], $categories['cat11B'], $categories['cat12'], $ingID + ); + + if ($stmt->execute()) { + $response["success"] = 'Usage limits have been updated!'; + } else { + $response["error"] = 'Something went wrong: ' . $stmt->error; + } + + $stmt->close(); + + echo json_encode($response); + return; +} + + +if($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'tech_data'){ + $ingID = (int)$_POST['ingID']; + $tenacity = mysqli_real_escape_string($conn, $_POST["tenacity"]); + $flash_point = mysqli_real_escape_string($conn, $_POST["flash_point"]); + $chemical_name = mysqli_real_escape_string($conn, $_POST["chemical_name"]); + $formula = mysqli_real_escape_string($conn, $_POST["formula"]); + $logp = mysqli_real_escape_string($conn, $_POST["logp"]); + $soluble = mysqli_real_escape_string($conn, $_POST["soluble"]); + $molecularWeight = mysqli_real_escape_string($conn, $_POST["molecularWeight"]); + $appearance = mysqli_real_escape_string($conn, $_POST["appearance"]); + $rdi = (int)$_POST["rdi"]?:0; + $shelf_life = mysqli_real_escape_string($conn, $_POST["shelf_life"]) ?: 0; + + + $query = "UPDATE ingredients SET tenacity='$tenacity',flash_point='$flash_point',chemical_name='$chemical_name',formula='$formula',logp = '$logp',soluble = '$soluble',molecularWeight = '$molecularWeight',appearance='$appearance',rdi='$rdi', shelf_life = '$shelf_life' WHERE id='$ingID'"; + if(mysqli_query($conn, $query)){ + $response["success"] = 'Technical data has been updated'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +if($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'note_impact'){ + $ingID = (int)$_POST['ingID']; + $impact_top = mysqli_real_escape_string($conn, $_POST["impact_top"]); + $impact_base = mysqli_real_escape_string($conn, $_POST["impact_base"]); + $impact_heart = mysqli_real_escape_string($conn, $_POST["impact_heart"]); + + $query = "UPDATE ingredients SET impact_top = '$impact_top',impact_heart = '$impact_heart',impact_base = '$impact_base' WHERE id='$ingID'"; + if(mysqli_query($conn, $query)){ + $response["success"] = 'Note impact has been updated'; + }else{ + $response["error"] = 'Error: '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +if($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'privacy'){ + $ingID = (int)$_POST['ingID']; + if($_POST['isPrivate'] == 'true'){ $isPrivate = '1'; }else{ $isPrivate = '0'; } + + $query = "UPDATE ingredients SET isPrivate = '$isPrivate' WHERE id='$ingID'"; + if(mysqli_query($conn, $query)){ + $response["success"] = 'Privacy settings has been updated!'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//ADD PICTOGRAM +if($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'safety_info' && $_POST['action'] == 'add'){ + $ingID = (int)$_POST['ingID']; + $GHS = (int)$_POST['pictogram']; + + if(mysqli_query($conn, "INSERT INTO ingSafetyInfo (GHS, ingID) VALUES ('$GHS','$ingID') ON DUPLICATE KEY UPDATE GHS = VALUES(GHS), ingID = VALUES(ingID)")){ + $response["success"] = 'Safety data has been updated!'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +//REMOVE PICTOGRAM +if($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'safety_info' && $_POST['pictogram_id'] && $_POST['action'] == 'remove'){ + $ingID = (int)$_POST['ingID']; + $GHS = (int)$_POST['pictogram_id']; + + if(mysqli_query($conn, "DELETE FROM ingSafetyInfo WHERE GHS = '$GHS' AND ingID = '$ingID'")){ + $response["success"] = 'Safety data has been updated!'; + }else{ + $response["error"] = 'Something went wrong '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + + +if($_GET['import'] == 'ingredient'){ + $name = sanChar(mysqli_real_escape_string($conn, base64_decode($_GET["name"]))); + $query = "INSERT INTO ingredients (name, INCI, cas, notes, odor) VALUES ('$name', '$INCI', '$cas', 'Auto Imported', '$odor')"; + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingredients WHERE name = '$name'"))){ + echo '
xError: '.$name.' already exists!
'; + }else{ + if(mysqli_query($conn, $query)){ + echo '
xIngredient '.$name.' added!
'; + }else{ + echo '
xError: Failed to add '.mysqli_error($conn).'
'; + } + } + return; +} + +//CLONE INGREDIENT +if($_POST['action'] == 'clone' && $_POST['old_ing_name'] && $_POST['ing_id']){ + $ing_id = mysqli_real_escape_string($conn, $_POST['ing_id']); + + $old_ing_name = mysqli_real_escape_string($conn, $_POST['old_ing_name']); + $new_ing_name = mysqli_real_escape_string($conn, $_POST['new_ing_name']); + if(empty($new_ing_name)){ + $response['error'] = 'Please provide a name'; + echo json_encode($response); + return; + } + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingredients WHERE name = '$new_ing_name'"))){ + $response['error'] = $new_ing_name.' already exists'; + echo json_encode($response); + return; + } + + $sql.=mysqli_query($conn, "INSERT INTO ingredient_compounds (ing,name,cas,min_percentage,max_percentage) SELECT '$new_ing_name',name,cas,min_percentage,max_percentage FROM ingredient_compounds WHERE ing = '$old_ing_name'"); + + $sql.=mysqli_query($conn, "INSERT INTO ingredients (name,INCI,type,strength,category,purity,cas,FEMA,reach,tenacity,chemical_name,formula,flash_point,appearance,notes,profile,solvent,odor,allergen,flavor_use,soluble,logp,cat1,cat2,cat3,cat4,cat5A,cat5B,cat5C,cat5D,cat6,cat7A,cat7B,cat8,cat9,cat10A,cat10B,cat11A,cat11B,cat12,impact_top,impact_heart,impact_base,created,usage_type,noUsageLimit,isPrivate,molecularWeight,physical_state) SELECT '$new_ing_name',INCI,type,strength,category,purity,cas,FEMA,reach,tenacity,chemical_name,formula,flash_point,appearance,notes,profile,solvent,odor,allergen,flavor_use,soluble,logp,cat1,cat2,cat3,cat4,cat5A,cat5B,cat5C,cat5D,cat6,cat7A,cat7B,cat8,cat9,cat10A,cat10B,cat11A,cat11B,cat12,impact_top,impact_heart,impact_base,created,usage_type,noUsageLimit,isPrivate,molecularWeight,physical_state FROM ingredients WHERE id = '$ing_id'"); + + if($nID = mysqli_fetch_array(mysqli_query($conn, "SELECT id,name FROM ingredients WHERE name = '$new_ing_name'"))){ + + $response['success'] = $old_ing_name.' duplicated as '.$new_ing_name.''; + echo json_encode($response); + return; + } + + return; +} + + + +//RENAME INGREDIENT +if($_POST['action'] == 'rename' && $_POST['old_ing_name'] && $_POST['ing_id']){ + $ing_id = mysqli_real_escape_string($conn, $_POST['ing_id']); + + $old_ing_name = mysqli_real_escape_string($conn, $_POST['old_ing_name']); + $new_ing_name = mysqli_real_escape_string($conn, $_POST['new_ing_name']); + if(empty($new_ing_name)){ + $response['error'] = 'Please provide a name'; + echo json_encode($response); + return; + } + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingredients WHERE name = '$new_ing_name'"))){ + $response['error'] = $new_ing_name.' already exists'; + echo json_encode($response); + return; + } + + $sql.=mysqli_query($conn, "UPDATE ingredient_compounds SET ing = '$new_ing_name' WHERE ing = '$old_ing_name'"); + + $sql.=mysqli_query($conn, "UPDATE ingredients SET name = '$new_ing_name' WHERE name = '$old_ing_name' AND id = '$ing_id'"); + $sql.=mysqli_query($conn, "UPDATE formulas SET ingredient = '$new_ing_name' WHERE ingredient = '$old_ing_name' AND ingredient_id = '$ing_id'"); + + if($nID = mysqli_fetch_array(mysqli_query($conn, "SELECT id,name FROM ingredients WHERE name = '$new_ing_name'"))){ + + $response['success']['msg'] = $old_ing_name.' renamed to '.$new_ing_name.''; + $response['success']['id'] = $nID['id']; + echo json_encode($response); + return; + } + + return; +} + + +//FIRST AID INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'faid_info') { + $ingID = (int)$_POST['ingID']; + + $first_aid_general = $_POST['first_aid_general']; + $first_aid_inhalation = $_POST['first_aid_inhalation']; + $first_aid_skin = $_POST['first_aid_skin']; + $first_aid_eye = $_POST['first_aid_eye']; + $first_aid_ingestion = $_POST['first_aid_ingestion']; + $first_aid_self_protection = $_POST['first_aid_self_protection']; + $first_aid_symptoms = $_POST['first_aid_symptoms']; + $first_aid_dr_notes = $_POST['first_aid_dr_notes']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($first_aid_general) || empty($first_aid_inhalation) || + empty($first_aid_skin) || empty($first_aid_eye) || empty($first_aid_ingestion) || + empty($first_aid_self_protection) || empty($first_aid_symptoms) || empty($first_aid_dr_notes) + ) { + $response["error"] = 'All fields are required.'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, first_aid_general, first_aid_inhalation, first_aid_skin, first_aid_eye, + first_aid_ingestion, first_aid_self_protection, first_aid_symptoms, first_aid_dr_notes + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + first_aid_general = VALUES(first_aid_general), + first_aid_inhalation = VALUES(first_aid_inhalation), + first_aid_skin = VALUES(first_aid_skin), + first_aid_eye = VALUES(first_aid_eye), + first_aid_ingestion = VALUES(first_aid_ingestion), + first_aid_self_protection = VALUES(first_aid_self_protection), + first_aid_symptoms = VALUES(first_aid_symptoms), + first_aid_dr_notes = VALUES(first_aid_dr_notes)" + ); + + // Bind the parameters + $stmt->bind_param( + 'issssssss', $ingID, $first_aid_general, $first_aid_inhalation, $first_aid_skin, $first_aid_eye, + $first_aid_ingestion, $first_aid_self_protection, $first_aid_symptoms, $first_aid_dr_notes + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'First aid data has been updated!'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + +//FIREFIGHTING +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'fire_info') { + $ingID = (int)$_POST['ingID']; + + $firefighting_suitable_media = $_POST['firefighting_suitable_media']; + $firefighting_non_suitable_media = $_POST['firefighting_non_suitable_media']; + $firefighting_special_hazards = $_POST['firefighting_special_hazards']; + $firefighting_advice = $_POST['firefighting_advice']; + $firefighting_other_info = $_POST['firefighting_other_info']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($firefighting_suitable_media) || empty($firefighting_non_suitable_media) || + empty($firefighting_special_hazards) || empty($firefighting_advice) || empty($firefighting_other_info) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, firefighting_suitable_media, firefighting_non_suitable_media, + firefighting_special_hazards, firefighting_advice, firefighting_other_info + ) VALUES (?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + firefighting_suitable_media = VALUES(firefighting_suitable_media), + firefighting_non_suitable_media = VALUES(firefighting_non_suitable_media), + firefighting_special_hazards = VALUES(firefighting_special_hazards), + firefighting_advice = VALUES(firefighting_advice), + firefighting_other_info = VALUES(firefighting_other_info)" + ); + + // Bind the parameters + $stmt->bind_param( + 'isssss', $ingID, $firefighting_suitable_media, $firefighting_non_suitable_media, + $firefighting_special_hazards, $firefighting_advice, $firefighting_other_info + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Firefighting data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + +//ACCIDENTAL RELEASE +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'save_acc_rel') { + $ingID = (int)$_POST['ingID']; + + $accidental_release_per_precautions = $_POST['accidental_release_per_precautions']; + $accidental_release_env_precautions = $_POST['accidental_release_env_precautions']; + $accidental_release_cleaning = $_POST['accidental_release_cleaning']; + $accidental_release_refs = $_POST['accidental_release_refs']; + $accidental_release_other_info = $_POST['accidental_release_other_info']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($accidental_release_per_precautions) || empty($accidental_release_env_precautions) || + empty($accidental_release_cleaning) || empty($accidental_release_refs) || empty($accidental_release_other_info) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, accidental_release_per_precautions, accidental_release_env_precautions, + accidental_release_cleaning, accidental_release_refs, accidental_release_other_info + ) VALUES (?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + accidental_release_per_precautions = VALUES(accidental_release_per_precautions), + accidental_release_env_precautions = VALUES(accidental_release_env_precautions), + accidental_release_cleaning = VALUES(accidental_release_cleaning), + accidental_release_refs = VALUES(accidental_release_refs), + accidental_release_other_info = VALUES(accidental_release_other_info)" + ); + + // Bind the parameters + $stmt->bind_param( + 'isssss', $ingID, $accidental_release_per_precautions, $accidental_release_env_precautions, + $accidental_release_cleaning, $accidental_release_refs, $accidental_release_other_info + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Accidental release data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + +//HANDLING & STORAGE +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'HS') { + $ingID = (int)$_POST['ingID']; + + $handling_protection = $_POST['handling_protection']; + $handling_hygiene = $_POST['handling_hygiene']; + $handling_safe_storage = $_POST['handling_safe_storage']; + $handling_joint_storage = $_POST['handling_joint_storage']; + $handling_specific_uses = $_POST['handling_specific_uses']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($handling_protection) || empty($handling_hygiene) || + empty($handling_safe_storage) || empty($handling_joint_storage) || empty($handling_specific_uses) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, handling_protection, handling_hygiene, + handling_safe_storage, handling_joint_storage, handling_specific_uses + ) VALUES (?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + handling_protection = VALUES(handling_protection), + handling_hygiene = VALUES(handling_hygiene), + handling_safe_storage = VALUES(handling_safe_storage), + handling_joint_storage = VALUES(handling_joint_storage), + handling_specific_uses = VALUES(handling_specific_uses)" + ); + + // Bind the parameters + $stmt->bind_param( + 'isssss', $ingID, $handling_protection, $handling_hygiene, + $handling_safe_storage, $handling_joint_storage, $handling_specific_uses + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Handling and storage data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + +//EXPOSURE DATA +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'exposure_data') { + $ingID = (int)$_POST['ingID']; + + // New fields for exposure data + $exposure_occupational_limits = $_POST['exposure_occupational_limits']; + $exposure_biological_limits = $_POST['exposure_biological_limits']; + $exposure_intented_use_limits = $_POST['exposure_intented_use_limits']; + $exposure_other_remarks = $_POST['exposure_other_remarks']; + $exposure_face_protection = $_POST['exposure_face_protection']; + $exposure_skin_protection = $_POST['exposure_skin_protection']; + $exposure_respiratory_protection = $_POST['exposure_respiratory_protection']; + $exposure_env_exposure = $_POST['exposure_env_exposure']; + $exposure_consumer_exposure = $_POST['exposure_consumer_exposure']; + $exposure_other_info = $_POST['exposure_other_info']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($exposure_occupational_limits) || empty($exposure_biological_limits) || + empty($exposure_intented_use_limits) || empty($exposure_other_remarks) || empty($exposure_face_protection) || + empty($exposure_skin_protection) || empty($exposure_respiratory_protection) || empty($exposure_env_exposure) || + empty($exposure_consumer_exposure) || empty($exposure_other_info) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, exposure_occupational_limits, exposure_biological_limits, + exposure_intented_use_limits, exposure_other_remarks, + exposure_face_protection, exposure_skin_protection, + exposure_respiratory_protection, exposure_env_exposure, + exposure_consumer_exposure, exposure_other_info + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + exposure_occupational_limits = VALUES(exposure_occupational_limits), + exposure_biological_limits = VALUES(exposure_biological_limits), + exposure_intented_use_limits = VALUES(exposure_intented_use_limits), + exposure_other_remarks = VALUES(exposure_other_remarks), + exposure_face_protection = VALUES(exposure_face_protection), + exposure_skin_protection = VALUES(exposure_skin_protection), + exposure_respiratory_protection = VALUES(exposure_respiratory_protection), + exposure_env_exposure = VALUES(exposure_env_exposure), + exposure_consumer_exposure = VALUES(exposure_consumer_exposure), + exposure_other_info = VALUES(exposure_other_info)" + ); + + // Bind the parameters + $stmt->bind_param( + 'issssssssss', $ingID, $exposure_occupational_limits, $exposure_biological_limits, + $exposure_intented_use_limits, $exposure_other_remarks, + $exposure_face_protection, $exposure_skin_protection, + $exposure_respiratory_protection, $exposure_env_exposure, + $exposure_consumer_exposure, $exposure_other_info + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Exposure data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + +//PCP +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'pcp') { + $ingID = (int)$_POST['ingID']; + + $odor_threshold = $_POST['odor_threshold']; + $pH = $_POST['pH']; + $melting_point = $_POST['melting_point']; + $boiling_point = $_POST['boiling_point']; + $flash_point = $_POST['flash_point']; + $evaporation_rate = $_POST['evaporation_rate']; + $solubility = $_POST['solubility']; + $auto_infl_temp = $_POST['auto_infl_temp']; + $decomp_temp = $_POST['decomp_temp']; + $viscosity = $_POST['viscosity']; + $explosive_properties = $_POST['explosive_properties']; + $oxidising_properties = $_POST['oxidising_properties']; + $particle_chars = $_POST['particle_chars']; + $flammability = $_POST['flammability']; + $logP = $_POST['logP']; + $soluble = $_POST['soluble']; + $color = $_POST['color']; + $low_flammability_limit = $_POST['low_flammability_limit']; + $vapour_pressure = $_POST['vapour_pressure']; + $vapour_density = $_POST['vapour_density']; + $relative_density = $_POST['relative_density']; + $pcp_other_info = $_POST['pcp_other_info']; + $pcp_other_sec_info = $_POST['pcp_other_sec_info']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($odor_threshold) || empty($pH) || + empty($melting_point) || empty($boiling_point) || empty($flash_point) || + empty($evaporation_rate) || empty($solubility) || empty($auto_infl_temp) || + empty($decomp_temp) || empty($viscosity) || empty($explosive_properties) || + empty($oxidising_properties) || empty($particle_chars) || empty($flammability) || + empty($logP) || empty($soluble) || empty($color) || empty($low_flammability_limit) || + empty($vapour_pressure) || empty($vapour_density) || empty($relative_density) || + empty($pcp_other_info) || empty($pcp_other_sec_info) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, odor_threshold, pH, melting_point, boiling_point, flash_point, + evaporation_rate, solubility, auto_infl_temp, decomp_temp, viscosity, + explosive_properties, oxidising_properties, particle_chars, flammability, + logP, soluble, color, low_flammability_limit, vapour_pressure, vapour_density, + relative_density, pcp_other_info, pcp_other_sec_info + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + odor_threshold = VALUES(odor_threshold), + pH = VALUES(pH), + melting_point = VALUES(melting_point), + boiling_point = VALUES(boiling_point), + flash_point = VALUES(flash_point), + evaporation_rate = VALUES(evaporation_rate), + solubility = VALUES(solubility), + auto_infl_temp = VALUES(auto_infl_temp), + decomp_temp = VALUES(decomp_temp), + viscosity = VALUES(viscosity), + explosive_properties = VALUES(explosive_properties), + oxidising_properties = VALUES(oxidising_properties), + particle_chars = VALUES(particle_chars), + flammability = VALUES(flammability), + logP = VALUES(logP), + soluble = VALUES(soluble), + color = VALUES(color), + low_flammability_limit = VALUES(low_flammability_limit), + vapour_pressure = VALUES(vapour_pressure), + vapour_density = VALUES(vapour_density), + relative_density = VALUES(relative_density), + pcp_other_info = VALUES(pcp_other_info), + pcp_other_sec_info = VALUES(pcp_other_sec_info)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( + 'isssssssssssssssssssssss', $ingID, $odor_threshold, $pH, $melting_point, $boiling_point, + $flash_point, $evaporation_rate, $solubility, $auto_infl_temp, $decomp_temp, + $viscosity, $explosive_properties, $oxidising_properties, $particle_chars, + $flammability, $logP, $soluble, $color, $low_flammability_limit, $vapour_pressure, + $vapour_density, $relative_density, $pcp_other_info, $pcp_other_sec_info + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Ingredient safety data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + +//SR INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'sr_info') { + $ingID = (int)$_POST['ingID']; + + + $stabillity_reactivity = $_POST['stabillity_reactivity']; + $stabillity_chemical = $_POST['stabillity_chemical']; + $stabillity_reactions = $_POST['stabillity_reactions']; + $stabillity_avoid = $_POST['stabillity_avoid']; + $stabillity_incompatibility = $_POST['stabillity_incompatibility']; + + + // Check if all fields are populated + if ( + empty($ingID) || empty($stabillity_reactivity) || empty($stabillity_chemical) || + empty($stabillity_reactions) || empty($stabillity_avoid) || empty($stabillity_incompatibility) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, stabillity_reactivity, stabillity_chemical, stabillity_reactions, stabillity_avoid, stabillity_incompatibility + ) VALUES (?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + stabillity_reactivity = VALUES(stabillity_reactivity), + stabillity_chemical = VALUES(stabillity_chemical), + stabillity_reactions = VALUES(stabillity_reactions), + stabillity_avoid = VALUES(stabillity_avoid), + stabillity_incompatibility = VALUES(stabillity_incompatibility)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( 'isssss', $ingID, $stabillity_reactivity, $stabillity_chemical, $stabillity_reactions, $stabillity_avoid, $stabillity_incompatibility ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Stability and reactivity data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + +//TOXICOLOGICAL INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'tx_info') { + $ingID = (int)$_POST['ingID']; + + $toxicological_acute_oral = $_POST['toxicological_acute_oral']; + $toxicological_acute_dermal = $_POST['toxicological_acute_dermal']; + $toxicological_acute_inhalation = $_POST['toxicological_acute_inhalation']; + $toxicological_skin = $_POST['toxicological_skin']; + $toxicological_eye = $_POST['toxicological_eye']; + $toxicological_sensitisation = $_POST['toxicological_sensitisation']; + $toxicological_organ_repeated = $_POST['toxicological_organ_repeated']; + $toxicological_organ_single = $_POST['toxicological_organ_single']; + $toxicological_carcinogencity = $_POST['toxicological_carcinogencity']; + $toxicological_reproductive = $_POST['toxicological_reproductive']; + $toxicological_cell_mutation = $_POST['toxicological_cell_mutation']; + $toxicological_resp_tract = $_POST['toxicological_resp_tract']; + $toxicological_other_info = $_POST['toxicological_other_info']; + $toxicological_other_hazards = $_POST['toxicological_other_hazards']; + + + // Check if all fields are populated + if ( + empty($ingID) || empty($toxicological_acute_oral) || empty($toxicological_acute_dermal) || + empty($toxicological_acute_inhalation) || empty($toxicological_skin) || empty($toxicological_eye) || + empty($toxicological_sensitisation) || empty($toxicological_organ_repeated) || empty($toxicological_organ_single) || + empty($toxicological_carcinogencity) || empty($toxicological_reproductive) || empty($toxicological_cell_mutation) || + empty($toxicological_resp_tract) || empty($toxicological_other_info) || empty($toxicological_other_hazards) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, toxicological_acute_oral, toxicological_acute_dermal, toxicological_acute_inhalation, toxicological_skin, toxicological_eye, toxicological_sensitisation, toxicological_organ_repeated, toxicological_organ_single, toxicological_carcinogencity, toxicological_reproductive, toxicological_cell_mutation, toxicological_resp_tract, toxicological_other_info, toxicological_other_hazards + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + toxicological_acute_oral = VALUES(toxicological_acute_oral), + toxicological_acute_dermal = VALUES(toxicological_acute_dermal), + toxicological_acute_inhalation = VALUES(toxicological_acute_inhalation), + toxicological_skin = VALUES(toxicological_skin), + toxicological_eye = VALUES(toxicological_eye), + toxicological_sensitisation = VALUES(toxicological_sensitisation), + toxicological_organ_repeated = VALUES(toxicological_organ_repeated), + toxicological_organ_single = VALUES(toxicological_organ_single), + toxicological_carcinogencity = VALUES(toxicological_carcinogencity), + toxicological_reproductive = VALUES(toxicological_reproductive), + toxicological_cell_mutation = VALUES(toxicological_cell_mutation), + toxicological_resp_tract = VALUES(toxicological_resp_tract), + toxicological_other_info = VALUES(toxicological_other_info), + toxicological_other_hazards = VALUES(toxicological_other_hazards)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( + 'issssssssssssss', $ingID, $toxicological_acute_oral, $toxicological_acute_dermal, $toxicological_acute_inhalation, $toxicological_skin, $toxicological_eye, $toxicological_sensitisation, $toxicological_organ_repeated, $toxicological_organ_single, $toxicological_carcinogencity, $toxicological_reproductive, $toxicological_cell_mutation, $toxicological_resp_tract, $toxicological_other_info, + $toxicological_other_hazards + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Toxicology data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + +//ECOLOGICAL INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'ec_info') { + $ingID = (int)$_POST['ingID']; + + $ecological_toxicity = $_POST['ecological_toxicity']; + $ecological_persistence = $_POST['ecological_persistence']; + $ecological_bioaccumulative = $_POST['ecological_bioaccumulative']; + $ecological_soil_mobility = $_POST['ecological_soil_mobility']; + $ecological_PBT_vPvB = $_POST['ecological_PBT_vPvB']; + $ecological_endocrine_properties = $_POST['ecological_endocrine_properties']; + $ecological_other_adv_effects = $_POST['ecological_other_adv_effects']; + $ecological_additional_ecotoxicological_info = $_POST['ecological_additional_ecotoxicological_info']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($ecological_toxicity) || empty($ecological_persistence) || empty($ecological_bioaccumulative) || empty($ecological_soil_mobility) || empty($ecological_PBT_vPvB) || + empty($ecological_endocrine_properties) || empty($ecological_other_adv_effects) || empty($ecological_additional_ecotoxicological_info) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, ecological_toxicity, ecological_persistence, ecological_bioaccumulative, ecological_soil_mobility, ecological_PBT_vPvB, ecological_endocrine_properties, ecological_other_adv_effects, ecological_additional_ecotoxicological_info + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + ecological_toxicity = VALUES(ecological_toxicity), + ecological_persistence = VALUES(ecological_persistence), + ecological_bioaccumulative = VALUES(ecological_bioaccumulative), + ecological_soil_mobility = VALUES(ecological_soil_mobility), + ecological_PBT_vPvB = VALUES(ecological_PBT_vPvB), + ecological_endocrine_properties = VALUES(ecological_endocrine_properties), + ecological_other_adv_effects = VALUES(ecological_other_adv_effects), + ecological_additional_ecotoxicological_info = VALUES(ecological_additional_ecotoxicological_info)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( + 'issssssss', $ingID, $ecological_toxicity, $ecological_persistence, $ecological_bioaccumulative, $ecological_soil_mobility, $ecological_PBT_vPvB, $ecological_endocrine_properties, $ecological_other_adv_effects, $ecological_additional_ecotoxicological_info + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Ecology data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + +//DISPOSE INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'dis_info') { + $ingID = (int)$_POST['ingID']; + + + $disposal_product = $_POST['disposal_product']; + $disposal_remarks = $_POST['disposal_remarks']; + + + // Check if all fields are populated + if ( empty($ingID) || empty($disposal_product) || empty($disposal_remarks) ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( ingID, disposal_product, disposal_remarks ) VALUES (?, ?, ?) + ON DUPLICATE KEY UPDATE + disposal_product = VALUES(disposal_product), + disposal_remarks = VALUES(disposal_remarks)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( 'iss', $ingID, $disposal_product, $disposal_remarks ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Dispose data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + + + +//TRANSPORTATION INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'trans_info') { + $ingID = (int)$_POST['ingID']; + + $transport_un_number = $_POST['transport_un_number']; + $transport_shipping_name = $_POST['transport_shipping_name']; + $transport_hazard_class = $_POST['transport_hazard_class']; + $transport_packing_group = $_POST['transport_packing_group']; + $transport_env_hazards = $_POST['transport_env_hazards']; + $transport_precautions = $_POST['transport_precautions']; + $transport_bulk_shipping = $_POST['transport_bulk_shipping']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($transport_un_number) || empty($transport_shipping_name) || empty($transport_hazard_class) || empty($transport_packing_group) || empty($transport_env_hazards) || + empty($transport_precautions) || empty($transport_bulk_shipping) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, transport_un_number, transport_shipping_name, transport_hazard_class, transport_packing_group, transport_env_hazards, transport_precautions, transport_bulk_shipping + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + transport_un_number = VALUES(transport_un_number), + transport_shipping_name = VALUES(transport_shipping_name), + transport_hazard_class = VALUES(transport_hazard_class), + transport_packing_group = VALUES(transport_packing_group), + transport_env_hazards = VALUES(transport_env_hazards), + transport_precautions = VALUES(transport_precautions), + transport_bulk_shipping = VALUES(transport_bulk_shipping)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( + 'isssssss', $ingID, $transport_un_number, $transport_shipping_name, $transport_hazard_class, $transport_packing_group, $transport_env_hazards, $transport_precautions, $transport_bulk_shipping + ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Transportation data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + +//LEGISLATION INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'leg_info') { + $ingID = (int)$_POST['ingID']; + + $legislation_safety = $_POST['legislation_safety']; + $legislation_eu = $_POST['legislation_eu']; + $legislation_chemical_safety_assessment = $_POST['legislation_chemical_safety_assessment']; + $legislation_other_info = $_POST['legislation_other_info']; + + + // Check if all fields are populated + if ( + empty($ingID) || empty($legislation_safety) || empty($legislation_eu) || empty($legislation_chemical_safety_assessment) || empty($legislation_other_info) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, legislation_safety, legislation_eu, legislation_chemical_safety_assessment, legislation_other_info + ) VALUES (?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + legislation_safety = VALUES(legislation_safety), + legislation_eu = VALUES(legislation_eu), + legislation_chemical_safety_assessment = VALUES(legislation_chemical_safety_assessment), + legislation_other_info = VALUES(legislation_other_info)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( 'issss', $ingID, $legislation_safety, $legislation_eu, $legislation_chemical_safety_assessment, $legislation_other_info ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Legislation data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + + +//ADDITIONAL INFO +if ($_POST['manage'] == 'ingredient' && $_POST['tab'] == 'add_info') { + $ingID = (int)$_POST['ingID']; + + $add_info_changes = $_POST['add_info_changes']; + $add_info_acronyms = $_POST['add_info_acronyms']; + $add_info_references = $_POST['add_info_references']; + $add_info_HazCom = $_POST['add_info_HazCom']; + $add_info_GHS = $_POST['add_info_GHS']; + $add_info_training = $_POST['add_info_training']; + $add_info_other = $_POST['add_info_other']; + + // Check if all fields are populated + if ( + empty($ingID) || empty($add_info_changes) || empty($add_info_acronyms) || empty($add_info_references) || empty($add_info_HazCom) || empty($add_info_GHS) || empty($add_info_training) || empty($add_info_other) + ) { + $response["error"] = 'All fields are required'; + echo json_encode($response); + return; + } + + // Prepare the SQL statement + $stmt = $conn->prepare( + "INSERT INTO ingredient_safety_data ( + ingID, add_info_changes, add_info_acronyms, add_info_references, add_info_HazCom, add_info_GHS, add_info_training, add_info_other + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + add_info_changes = VALUES(add_info_changes), + add_info_acronyms = VALUES(add_info_acronyms), + add_info_references = VALUES(add_info_references), + add_info_HazCom = VALUES(add_info_HazCom), + add_info_GHS = VALUES(add_info_GHS), + add_info_training = VALUES(add_info_training), + add_info_other = VALUES(add_info_other)" + ); + + // Check if the statement was prepared successfully + if (!$stmt) { + $response["error"] = 'Prepare failed: ' . $conn->error; + echo json_encode($response); + return; + } + + // Bind the parameters + $stmt->bind_param( 'isssssss', $ingID, $add_info_changes, $add_info_acronyms, $add_info_references, $add_info_HazCom, $add_info_GHS , $add_info_training , $add_info_other ); + + // Execute the statement + if ($stmt->execute()) { + $response["success"] = 'Additional info data has been updated'; + } else { + $response["error"] = 'Something went wrong ' . $stmt->error; + } + + // Close the statement + $stmt->close(); + + echo json_encode($response); + return; +} + + +//IMPORT MARKETPLACE FORMULA +if($_POST['action'] == 'import' && $_POST['kind'] == 'formula'){ + + $id = mysqli_real_escape_string($conn, $_POST['fid']); + + $jAPI = $pvOnlineAPI.'?request=MarketPlace&action=get&id='.$id; + $jsonData = json_decode(pv_file_get_contents($jAPI), true); + + if($jsonData['error']){ + $response['error'] = 'Error: '.$jsonData['error']['msg']; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT fid FROM formulasMetaData WHERE fid = '".$jsonData['meta']['fid']."' AND src = '1'"))){ + $response['error'] = 'Formula name '.$jsonData['meta']['name'].' already downloaded. If you want to re-download it, please remove it first.'; + echo json_encode($response); + return; + } + + $q = "INSERT INTO formulasMetaData (name,product_name,fid,profile,gender,notes,defView,catClass,finalType,status,src) VALUES ('".$jsonData['meta']['name']."','".$jsonData['meta']['product_name']."','".$jsonData['meta']['fid']."','".$jsonData['meta']['profile']."','".$jsonData['meta']['gender']."','".$jsonData['meta']['notes']."','".$jsonData['meta']['defView']."','".$jsonData['meta']['catClass']."','".$jsonData['meta']['finalType']."','".$jsonData['meta']['status']."','1')"; + + $qIns = mysqli_query($conn,$q); + $last_id = mysqli_insert_id($conn); + $source = $jsonData['meta']['source']; + mysqli_query($conn, "INSERT INTO formulasTags (formula_id, tag_name) VALUES ('$last_id','$source')"); + + $array_data = $jsonData['formula']; + foreach ($array_data as $id=>$row) { + $insertPairs = array(); + foreach ($row as $key=>$val) { + $insertPairs[addslashes($key)] = addslashes($val); + } + $getIng = mysqli_fetch_array(mysqli_query($conn, "SELECT id FROM ingredients WHERE name = '".$row['ingredient']."'")); + if(!$getIng['id']){ + mysqli_query($conn, "INSERT INTO ingredients (name) VALUES ('".$row['ingredient']."')"); + $getIng['id'] = mysqli_insert_id($conn); + } + + $insertVals = '"'.$jsonData['meta']['fid'].'",'.'"'.$jsonData['meta']['name'].'",'.'"'.$getIng['id'].'",'.'"' . implode('","', array_values($insertPairs)) . '"'; + + $jsql = "INSERT INTO formulas (`fid`,`name`,`ingredient_id`,`ingredient`,`concentration`,`dilutant`,`quantity`,`notes`) VALUES ({$insertVals});"; + $qIns.= mysqli_query($conn,$jsql); + + } + + if($qIns){ + $response['success'] = $jsonData['meta']['name'].' formula imported!'; + }else{ + $response['error'] = 'Unable to import the formula '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//CONTACT MARKETPLACE AUTHOR +if($_POST['action'] == 'contactAuthor'){ + $fname = $_POST['fname']; + $fid= $_POST['fid']; + + if(empty($contactName = $_POST['contactName'])){ + $response['error'] = 'Please provide your full name'; + echo json_encode($response); + return; + } + if(empty($contactEmail = $_POST['contactEmail'])){ + $response['error'] = 'Please provide your email'; + echo json_encode($response); + return; + } + if(empty($contactReason = $_POST['contactReason'])){ + $response['error'] = 'Please provide report details'; + echo json_encode($response); + return; + } + + + $data = [ + 'request' => 'MarketPlace', + 'action' => 'contactAuthor', + 'src' => 'marketplace', + 'fname' => $fname, + 'fid' => $fid, + 'contactName' => $contactName, + 'contactEmail' => $contactEmail, + 'contactReason' => $contactReason + ]; + + $req = json_decode(pvPost($pvOnlineAPI, $data)); + if($req->success){ + $response['success'] = $req->success; + }else{ + $response['error'] = $req->error; + } + echo json_encode($response); + return; + +} + +//REPORT MARKETPLACE FORMULA +if($_POST['action'] == 'report' && $_POST['src'] == 'pvMarket'){ + $fname = $_POST['fname']; + $fid= $_POST['fid']; + + if(empty($reporterName = $_POST['reporterName'])){ + $response['error'] = 'Please provide your full name'; + echo json_encode($response); + return; + } + if(empty($reporterEmail = $_POST['reporterEmail'])){ + $response['error'] = 'Please provide your email'; + echo json_encode($response); + return; + } + if(empty($reportReason = $_POST['reportReason'])){ + $response['error'] = 'Please provide report details'; + echo json_encode($response); + return; + } + + + $data = [ + 'request' => 'MarketPlace', + 'action' => 'report', + 'src' => 'marketplace', + 'fname' => $fname, + 'fid' => $fid, + 'reporterName' => $reporterName, + 'reporterEmail' => $reporterEmail, + 'reportReason' => $reportReason + ]; + + $req = json_decode(pvPost($pvOnlineAPI, $data)); + if($req->success){ + $response['success'] = $req->success; + }else if($req->error){ + $response['error'] = $req->error; + }else{ + $response['error'] = "Uknown error"; + } + echo json_encode($response); + return; + +} + + +if($_GET['do'] == 'userPerfClear'){ + + if(mysqli_query($conn, "DELETE FROM user_prefs WHERE owner = '".$_SESSION['userID']."'")){ + $result['success'] = "User prefernces removed"; + }else{ + $result['error'] = 'Something went wrong, '.mysqli_error($conn); + + } + unset($_SESSION['user_prefs']); + echo json_encode($result); + return; +} + + +if($_GET['do'] == 'db_update'){ + + $a_ver = trim(file_get_contents(__ROOT__.'/VERSION.md')); + $n_ver = trim(file_get_contents(__ROOT__.'/db/schema.ver')); + $c_ver = trim($pv_meta['schema_ver']); + $script = __ROOT__.'/db/scripts/update_'.$c_ver.'-'.$n_ver.'.php'; + + if(file_exists($script) == TRUE){ + require_once($script); + } + if($c_ver == $n_ver){ + $result['error'] = "No update is needed"; + echo json_encode($result); + return; + } + + foreach ( range(round($c_ver*100), round($n_ver*100), 0.1*100) as $i ) { + $c_ver = mysqli_fetch_array(mysqli_query($conn, "SELECT schema_ver FROM pv_meta")); + $u_ver = number_format($i/100,1); + $sql = __ROOT__.'/db/updates/update_'.$c_ver['schema_ver'].'-'.$u_ver.'.sql'; + + if(file_exists($sql) == TRUE){ + $cmd = "mysql -u$dbuser -p$dbpass -h$dbhost $dbname < $sql"; + passthru($cmd,$e); + } + + $q = mysqli_query($conn, "UPDATE pv_meta SET schema_ver = '$u_ver'"); + } + + if($q){ + $result['success'] = "Your database has been updated"; + echo json_encode($result); + } + + return; +} + + +if($_GET['do'] == 'backupDB'){ + if( getenv('DB_BACKUP_PARAMETERS') ){ + $bkparams = getenv('DB_BACKUP_PARAMETERS'); + } + + if($_GET['column_statistics'] === 'true'){ + $bkparams = '--column-statistics=1'; + } + + $file = 'backup_'.$ver.'_'.date("d-m-Y").'.sql.gz'; + + header( 'Content-Type: application/x-gzip' ); + header( 'Content-Disposition: attachment; filename="' .$file. '"' ); + $cmd = "mysqldump $bkparams -u $dbuser --password=$dbpass -h $dbhost $dbname | gzip --best"; + passthru($cmd); + + return; +} + +if($_GET['restore'] == 'db_bk'){ + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + $target_path = $tmp_path.basename($_FILES['backupFile']['name']); + + if(move_uploaded_file($_FILES['backupFile']['tmp_name'], $target_path)) { + $gz_tmp = basename($_FILES['backupFile']['name']); + preg_match('/_(.*?)_/', $gz_tmp, $v); + + if($ver !== $v['1']){ + $result['error'] = "Backup file is taken from a different version ".$v['1']; + echo json_encode($result); + return; + } + + system("gunzip -c $target_path > ".$tmp_path.'restore.sql'); + $cmd = "mysql -u$dbuser -p$dbpass -h$dbhost $dbname < ".$tmp_path.'restore.sql'; + passthru($cmd,$e); + + unlink($target_path); + unlink($tmp_path.'restore.sql'); + + if(!$e){ + $result['success'] = 'Database has been restored. Please refresh the page for the changes to take effect.'; + unset($_SESSION['parfumvault']); + session_unset(); + }else{ + $result['error'] = "Something went wrong..."; + } + } else { + $result['error'] = "There was an error processing backup file $target_path, please try again!"; + } + + echo json_encode($result); + return; +} + +if($_GET['action'] == 'exportIFRA'){ + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM IFRALibrary")))){ + $msg['error'] = 'No data found to export.'; + echo json_encode($msg); + return; + } + $IFRA_Data = 0; + $q = mysqli_query($conn, "SELECT * FROM IFRALibrary"); + while($ifra = mysqli_fetch_assoc($q)){ + + $r['id'] = (int)$ifra['id']; + $r['ifra_key'] = (string)$ifra['ifra_key']?: "-"; + $r['image'] = (string)$ifra['image']?: "-"; + $r['amendment'] = (string)$ifra['amendment']?: "-"; + $r['prev_pub'] = (string)$ifra['prev_pub']?: "-"; + $r['last_pub'] = (string)$ifra['last_pub']?: "-"; + $r['deadline_existing'] = (string)$ifra['deadline_existing']?: "-"; + $r['deadline_new'] = (string)$ifra['deadline_new']?: "-"; + $r['name'] = (string)$ifra['name']?: "-"; + $r['cas'] = (string)$ifra['cas']?: "-"; + $r['cas_comment'] = (string)$ifra['cas_comment']?: "-"; + $r['synonyms'] = (string)$ifra['synonyms']?: "-"; + $r['formula'] = (string)$ifra['formula']?: "-";//DEPRECATED IN IFRA 51 + $r['flavor_use'] = (string)$ifra['flavor_use']?: "-"; + $r['prohibited_notes'] = (string)$ifra['prohibited_notes'] ?: "-"; + $r['restricted_photo_notes'] = (string)$ifra['restricted_photo_notes']?: "-"; + $r['restricted_notes'] = (string)$ifra['restricted_notes']?: "-"; + $r['specified_notes'] = (string)$ifra['specified_notes']?: "-"; + $r['type'] = (string)$ifra['type']?: "-"; + $r['risk'] = (string)$ifra['risk']?: "-"; + $r['contrib_others'] = (string)$ifra['contrib_others']?: "-"; + $r['contrib_others_notes'] = (string)$ifra['contrib_others_notes']?: "-"; + $r['cat1'] = (double)$ifra['cat1']?: 100; + $r['cat2'] = (double)$ifra['cat2']?: 100; + $r['cat3'] = (double)$ifra['cat3']?: 100; + $r['cat4'] = (double)$ifra['cat4']?: 100; + $r['cat5A'] = (double)$ifra['cat5A']?: 100; + $r['cat5B'] = (double)$ifra['cat5B']?: 100; + $r['cat5C'] = (double)$ifra['cat5C']?: 100; + $r['cat5D'] = (double)$ifra['cat5D']?: 100; + $r['cat6'] = (double)$ifra['cat6']?: 100; + $r['cat7A'] = (double)$ifra['cat7A']?: 100; + $r['cat7B'] = (double)$ifra['cat7B']?: 100; + $r['cat8'] = (double)$ifra['cat8']?: 100; + $r['cat9'] = (double)$ifra['cat9']?: 100; + $r['cat10A'] = (double)$ifra['cat10A']?: 100; + $r['cat10B'] = (double)$ifra['cat10B']?: 100; + $r['cat11A'] = (double)$ifra['cat11A']?: 100; + $r['cat11B'] = (double)$ifra['cat11B']?: 100; + $r['cat12'] = (double)$ifra['cat12']?: 100; + + $IFRA_Data++; + $if[] = $r; + } + + $vd['product'] = $product; + $vd['version'] = $ver; + $vd['ifra_entries'] = $IFRA_Data; + $vd['timestamp'] = date('d/m/Y H:i:s'); + + + $result['IFRALibrary'] = $if; + $result['pvMeta'] = $vd; + + header('Content-disposition: attachment; filename=IFRALibrary.json'); + header('Content-type: application/json'); + echo json_encode($result, JSON_PRETTY_PRINT); + return; +} + +if($_GET['action'] == 'exportFormulas'){ + if($_GET['fid']){ + $filter = " WHERE fid ='".$_GET['fid']."'"; + } + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM formulasMetaData")))){ + $msg['error'] = 'No formulas found to export.'; + echo json_encode($msg); + return; + } + $formulas = 0; + $ingredients = 0; + + $qfmd = mysqli_query($conn, "SELECT * FROM formulasMetaData $filter"); + while($meta = mysqli_fetch_assoc($qfmd)){ + + $r['id'] = (int)$meta['id']; + $r['name'] = (string)$meta['name']; + $r['product_name'] = (string)$meta['product_name']; + $r['fid'] = (string)$meta['fid']; + $r['profile'] = (string)$meta['profile']; + $r['category'] = (string)$meta['profile'] ?: 'Default'; + $r['gender'] = (string)$meta['gender']; + $r['notes'] = (string)$meta['notes'] ?: 'None'; + $r['created'] = (string)$meta['created']; + $r['isProtected'] = (int)$meta['isProtected'] ?: 0; + $r['defView'] = (int)$meta['defView']; + $r['catClass'] = (string)$meta['catClass']; + $r['revision'] = (int)$meta['revision'] ?: 0; + $r['finalType'] = (int)$meta['finalType'] ?: 100; + $r['isMade'] = (int)$meta['isMade']; + $r['madeOn'] = (string)$meta['madeOn'] ?: "0000-00-00 00:00:00"; + $r['scheduledOn'] = (string)$meta['scheduledOn']; + $r['customer_id'] = (int)$meta['customer_id']; + $r['status'] = (int)$meta['status']; + $r['toDo'] = (int)$meta['toDo']; + $r['rating'] = (int)$meta['rating'] ?: 0; + + $formulas++; + $fm[] = $r; + } + + $qfm = mysqli_query($conn, "SELECT * FROM formulas $filter"); + while($formula = mysqli_fetch_assoc($qfm)){ + + + $f['id'] = (int)$formula['id']; + $f['fid'] = (string)$formula['fid']; + $f['name'] = (string)$formula['name']; + $f['ingredient'] = (string)$formula['ingredient']; + $f['ingredient_id'] = (int)$formula['ingredient_id'] ?: 0; + $f['concentration'] = (float)$formula['concentration'] ?: 100; + $f['dilutant'] = (string)$formula['dilutant'] ?: 'None'; + $f['quantity'] = (float)$formula['quantity']; + $f['exclude_from_summary'] = (int)$formula['exclude_from_summary']; + $f['exclude_from_calculation'] = (int)$formula['exclude_from_calculation']; + $f['notes'] = (string)$formula['notes'] ?: 'None'; + $f['created'] = (string)$formula['created']; + $f['updated'] = (string)$formula['updated']; + + $ingredients++; + $fd[] = $f; + } + + $vd['product'] = $product; + $vd['version'] = $ver; + $vd['formulas'] = $formulas; + $vd['ingredients'] = $ingredients; + $vd['timestamp'] = date('d/m/Y H:i:s'); + + + $result['formulasMetaData'] = $fm; + $result['formulas'] = $fd; + $result['pvMeta'] = $vd; + + if(!$_GET['fid']){ + $f['name'] = "All_formulas"; + } + + header('Content-disposition: attachment; filename='.$f['name'].'.json'); + header('Content-type: application/json'); + echo json_encode($result, JSON_PRETTY_PRINT); + return; +} + +if($_GET['action'] == 'restoreFormulas'){ + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path.basename($_FILES['backupFile']['name']); + + if(move_uploaded_file($_FILES['backupFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + + if(!$data['formulasMetaData']){ + $result['error'] = "JSON File seems invalid. Please make sure you importing the right file"; + echo json_encode($result); + return; + } + + foreach ($data['formulasMetaData'] as $meta ){ + $name = mysqli_real_escape_string($conn, $meta['name']); + $product_name = mysqli_real_escape_string($conn, $meta['product_name']); + $notes = mysqli_real_escape_string($conn, $meta['notes']); + + $sql = "INSERT IGNORE INTO formulasMetaData(name,product_name,fid,profile,gender,notes,created,isProtected,defView,catClass,revision,finalType,isMade,madeOn,scheduledOn,customer_id,status,toDo,rating) VALUES('".$name."','".$product_name."','".$meta['fid']."','".$meta['profile']."','".$meta['gender']."','".$notes."','".$meta['created']."','".$meta['isProtected']."','".$meta['defView']."','".$meta['catClass']."','".$meta['revision']."','".$meta['finalType']."','".$meta['isMade']."','".$meta['madeOn']."','".$meta['scheduledOn']."','".$meta['customer_id']."','".$meta['status']."','".$meta['toDo']."','".$meta['rating']."')"; + + if(mysqli_query($conn,$sql)){ + mysqli_query($conn,"DELETE FROM formulas WHERE fid = '".$meta['fid']."'"); + }else{ + $result['error'] = "There was an error importing your JSON file ".mysqli_error($conn); + echo json_encode($result); + return; + } + } + + foreach ($data['formulas'] as $formula ){ + + $name = mysqli_real_escape_string($conn, $formula['name']); + $notes = mysqli_real_escape_string($conn, $formula['notes']); + $ingredient = mysqli_real_escape_string($conn, $formula['ingredient']); + $exclude_from_summary = $formula['exclude_from_summary'] ?: 0; + $exclude_from_calculation = $formula['exclude_from_calculation'] ?: 0; + $created = $formula['created'] ?: date('Y-m-d H:i:s'); + $updated = $formula['updated'] ?: date('Y-m-d H:i:s'); + + $sql = "INSERT INTO formulas(fid,name,ingredient,ingredient_id,concentration,dilutant,quantity,exclude_from_summary,exclude_from_calculation,notes,created,updated) VALUES('".$formula['fid']."','".$name."','".$ingredient."','".$formula['ingredient_id']."','".$formula['concentration']."','".$formula['dilutant']."','".$formula['quantity']."','".$exclude_from_summary."','".$exclude_from_calculation."','".$notes."','".$created."','".$updated."')"; + + if(mysqli_query($conn,$sql)){ + $result['success'] = "Import complete"; + unlink($target_path); + }else{ + $result['error'] = "There was an error importing your JSON file ".mysqli_error($conn); + + } + } + + } else { + $result['error'] = "There was an error processing backup file $target_path, please try again!"; + echo json_encode($result); + + } + echo json_encode($result); + return; + +} + +if($_GET['action'] == 'restoreIngredients'){ + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path.basename($_FILES['backupFile']['name']); + + if(move_uploaded_file($_FILES['backupFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + + if(!$data['ingredients']){ + $result['error'] = "JSON File seems invalid. Please make sure you importing the right file"; + echo json_encode($result); + return; + } + /* + foreach ($data['suppliers'] as $sup) { + $id = mysqli_real_escape_string($conn, $sup['id']); + $ingSupplierID = mysqli_real_escape_string($conn, $sup['ingSupplierID']); + $ingID = mysqli_real_escape_string($conn, $sup['ingID']); + $supplierLink = mysqli_real_escape_string($conn, $sup['supplierLink']); + $price = mysqli_real_escape_string($conn, $sup['price']); + $size = mysqli_real_escape_string($conn, $sup['size']); + $manufacturer = mysqli_real_escape_string($conn, $sup['manufacturer']); + $preferred = mysqli_real_escape_string($conn, $sup['preferred']); + $batch = mysqli_real_escape_string($conn, $sup['batch']); + $purchased = mysqli_real_escape_string($conn, $sup['purchased']); + $mUnit = mysqli_real_escape_string($conn, $sup['mUnit']); + $stock = mysqli_real_escape_string($conn, $sup['stock']); + $status = mysqli_real_escape_string($conn, $sup['status']); + $supplier_sku = mysqli_real_escape_string($conn, $sup['supplier_sku']); + $internal_sku = mysqli_real_escape_string($conn, $sup['internal_sku']); + $storage_location = mysqli_real_escape_string($conn, $sup['storage_location']); + + $sql = "INSERT IGNORE INTO `suppliers` (`id`,`ingSupplierID`,`ingID`,`supplierLink`,`price`,`size`,`manufacturer`,`preferred`,`batch`,`purchased`,`mUnit`,`stock`,`status`,`supplier_sku`,`internal_sku`,`storage_location`,`created_at`) + VALUES ('$id','$ingSupplierID','$ingID','$supplierLink','$price','$size','$manufacturer','$preferred','$batch','$purchased','$mUnit','$stock','$status','$supplier_sku','$internal_sku','$storage_location',current_timestamp())"; + + mysqli_query($conn, $sql); + } + + */ + foreach ($data['compositions'] as $cmp) { + $stmt = mysqli_prepare($conn, "INSERT IGNORE INTO `ingredient_compounds` (`ing`, `name`, `cas`, `ec`, `min_percentage`, `max_percentage`, `GHS`, `toDeclare`, `created`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, current_timestamp())"); + + if ($stmt === false) { + $result['error'] = 'Prepare failed: ' . mysqli_error($conn); + echo json_encode($result); + return; + } + + mysqli_stmt_bind_param($stmt, "ssssdsss", $cmp['ing'], $cmp['name'], $cmp['cas'], $cmp['ec'], $cmp['min_percentage'], $cmp['max_percentage'], $cmp['GHS'], $cmp['toDeclare']); + + $execute_result = mysqli_stmt_execute($stmt); + + if ($execute_result === false) { + $result['error'] = 'Execute failed: ' . mysqli_stmt_error($stmt); + echo json_encode($result); + return; + } + + mysqli_stmt_close($stmt); + } + + + foreach ($data['suppliers'] as $sup) { + $id = mysqli_real_escape_string($conn, $sup['id']); + $ingSupplierID = mysqli_real_escape_string($conn, $sup['ingSupplierID']); + $ingID = mysqli_real_escape_string($conn, $sup['ingID']); + $supplierLink = mysqli_real_escape_string($conn, $sup['supplierLink']); + $price = mysqli_real_escape_string($conn, $sup['price']); + $size = mysqli_real_escape_string($conn, $sup['size']); + $manufacturer = mysqli_real_escape_string($conn, $sup['manufacturer']); + $preferred = mysqli_real_escape_string($conn, $sup['preferred']); + $batch = mysqli_real_escape_string($conn, $sup['batch']); + $purchased = mysqli_real_escape_string($conn, $sup['purchased']); + $mUnit = mysqli_real_escape_string($conn, $sup['mUnit']); + $stock = mysqli_real_escape_string($conn, $sup['stock']); + $status = mysqli_real_escape_string($conn, $sup['status']); + $supplier_sku = mysqli_real_escape_string($conn, $sup['supplier_sku']); + $internal_sku = mysqli_real_escape_string($conn, $sup['internal_sku']); + $storage_location = mysqli_real_escape_string($conn, $sup['storage_location']); + + // Validate that price is numeric, non-empty, and non-zero + if (!is_numeric($price) || empty($price) || $price == 0) { + $warn.="Invalid price for supplier ID $id - Ignoring
"; + continue; // Skip to the next entry + } + $sql = "INSERT IGNORE INTO `suppliers` (`id`,`ingSupplierID`,`ingID`,`supplierLink`,`price`,`size`,`manufacturer`,`preferred`,`batch`,`purchased`,`mUnit`,`stock`,`status`,`supplier_sku`,`internal_sku`,`storage_location`,`created_at`) + VALUES ('$id','$ingSupplierID','$ingID','$supplierLink','$price','$size','$manufacturer','$preferred','$batch','$purchased','$mUnit','$stock','$status','$supplier_sku','$internal_sku','$storage_location',current_timestamp())"; + + mysqli_query($conn, $sql); + } + + + foreach ($data['ingSuppliers'] as $is) { + $id = mysqli_real_escape_string($conn, $is['id']); + $name = mysqli_real_escape_string($conn, $is['name']); + $address = mysqli_real_escape_string($conn, $is['address']); + $po = mysqli_real_escape_string($conn, $is['po']); + $country = mysqli_real_escape_string($conn, $is['country']); + $telephone = mysqli_real_escape_string($conn, $is['telephone']); + $url = mysqli_real_escape_string($conn, $is['url']); + $email = mysqli_real_escape_string($conn, $is['email']); + + $sql = "INSERT IGNORE INTO `ingSuppliers` (`id`,`name`,`address`,`po`,`country`,`telephone`,`url`,`email`) + VALUES ('$id','$name','$address','$po','$country','$telephone','$url','$email')"; + + if (!mysqli_query($conn, $sql)) { + $result['error'] = mysqli_error($conn); + echo json_encode($result); + return; + } + } + + + foreach ($data['ingredients'] as $ingredient) { + $id = mysqli_real_escape_string($conn, $ingredient['id']); + $name = mysqli_real_escape_string($conn, $ingredient['name']); + $INCI = mysqli_real_escape_string($conn, $ingredient['INCI']); + $cas = mysqli_real_escape_string($conn, $ingredient['cas']); + $FEMA = mysqli_real_escape_string($conn, $ingredient['FEMA']); + $type = mysqli_real_escape_string($conn, $ingredient['type']); + $strength = mysqli_real_escape_string($conn, $ingredient['strength']); + $category = mysqli_real_escape_string($conn, $ingredient['category']); + $purity = mysqli_real_escape_string($conn, $ingredient['purity']); + $einecs = mysqli_real_escape_string($conn, $ingredient['einecs']); + $reach = mysqli_real_escape_string($conn, $ingredient['reach']); + $tenacity = mysqli_real_escape_string($conn, $ingredient['tenacity']); + $chemical_name = mysqli_real_escape_string($conn, $ingredient['chemical_name']); + $formula = mysqli_real_escape_string($conn, $ingredient['formula']); + $flash_point = mysqli_real_escape_string($conn, $ingredient['flash_point']); + $notes = mysqli_real_escape_string($conn, $ingredient['notes']); + $flavor_use = mysqli_real_escape_string($conn, $ingredient['flavor_use']); + $soluble = mysqli_real_escape_string($conn, $ingredient['soluble']); + $logp = mysqli_real_escape_string($conn, $ingredient['logp']); + $cat1 = mysqli_real_escape_string($conn, $ingredient['cat1']); + $cat2 = mysqli_real_escape_string($conn, $ingredient['cat2']); + $cat3 = mysqli_real_escape_string($conn, $ingredient['cat3']); + $cat4 = mysqli_real_escape_string($conn, $ingredient['cat4']); + $cat5A = mysqli_real_escape_string($conn, $ingredient['cat5A']); + $cat5B = mysqli_real_escape_string($conn, $ingredient['cat5B']); + $cat5C = mysqli_real_escape_string($conn, $ingredient['cat5C']); + $cat6 = mysqli_real_escape_string($conn, $ingredient['cat6']); + $cat7A = mysqli_real_escape_string($conn, $ingredient['cat7A']); + $cat7B = mysqli_real_escape_string($conn, $ingredient['cat7B']); + $cat8 = mysqli_real_escape_string($conn, $ingredient['cat8']); + $cat9 = mysqli_real_escape_string($conn, $ingredient['cat9']); + $cat10A = mysqli_real_escape_string($conn, $ingredient['cat10A']); + $cat10B = mysqli_real_escape_string($conn, $ingredient['cat10B']); + $cat11A = mysqli_real_escape_string($conn, $ingredient['cat11A']); + $cat11B = mysqli_real_escape_string($conn, $ingredient['cat11B']); + $cat12 = mysqli_real_escape_string($conn, $ingredient['cat12']); + $profile = mysqli_real_escape_string($conn, $ingredient['profile']); + $physical_state = mysqli_real_escape_string($conn, $ingredient['physical_state']); + $allergen = mysqli_real_escape_string($conn, $ingredient['allergen']); + $odor = mysqli_real_escape_string($conn, $ingredient['odor']); + $impact_top = mysqli_real_escape_string($conn, $ingredient['impact_top']); + $impact_heart = mysqli_real_escape_string($conn, $ingredient['impact_heart']); + $impact_base = mysqli_real_escape_string($conn, $ingredient['impact_base']); + $created = mysqli_real_escape_string($conn, $ingredient['created']); + $usage_type = mysqli_real_escape_string($conn, $ingredient['usage_type']); + $noUsageLimit = mysqli_real_escape_string($conn, $ingredient['noUsageLimit']); + $byPassIFRA = mysqli_real_escape_string($conn, $ingredient['byPassIFRA']); + $isPrivate = mysqli_real_escape_string($conn, $ingredient['isPrivate']); + $molecularWeight = mysqli_real_escape_string($conn, $ingredient['molecularWeight']); + + $sql = "INSERT IGNORE INTO ingredients(id,name,INCI,cas,FEMA,type,strength,category,purity,einecs,reach,tenacity,chemical_name,formula,flash_point,notes,flavor_use,soluble,logp,cat1,cat2,cat3,cat4,cat5A,cat5B,cat5C,cat6,cat7A,cat7B,cat8,cat9,cat10A,cat10B,cat11A,cat11B,cat12,profile,physical_state,allergen,odor,impact_top,impact_heart,impact_base,created,usage_type,noUsageLimit,byPassIFRA,isPrivate,molecularWeight) + VALUES ('$id','$name','$INCI','$cas','$FEMA','$type','$strength','$category','$purity','$einecs','$reach','$tenacity','$chemical_name','$formula','$flash_point','$notes','$flavor_use','$soluble','$logp','$cat1','$cat2','$cat3','$cat4','$cat5A','$cat5B','$cat5C','$cat6','$cat7A','$cat7B','$cat8','$cat9','$cat10A','$cat10B','$cat11A','$cat11B','$cat12','$profile','$physical_state','$allergen','$odor','$impact_top','$impact_heart','$impact_base','$created','$usage_type','$noUsageLimit','$byPassIFRA','$isPrivate','$molecularWeight')"; + + if (mysqli_query($conn, $sql)) { + $result['success'] = "Import complete"; + + if ($warn) { + $result['warning'] = $warn; // Set warning message if $err is not empty + } + + unlink($target_path); + } else { + $result['error'] = "There was an error importing your JSON file: " . mysqli_error($conn); + echo json_encode($result); + return; + } + + } + + + + + } else { + $result['error'] = "There was an error processing json file $target_path, please try again!"; + echo json_encode($result); + + } + echo json_encode($result); + return; + +} + + +if($_GET['action'] == 'restoreIFRA'){ + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path.basename($_FILES['backupFile']['name']); + + if(move_uploaded_file($_FILES['backupFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + if(!$data['IFRALibrary']){ + $result['error'] = "JSON File seems invalid. Please make sure you importing the right file"; + echo json_encode($result); + return; + } + mysqli_query($conn, "TRUNCATE IFRALibrary"); + + foreach ($data['IFRALibrary'] as $d ){ + $ifra_key = mysqli_real_escape_string($conn, $d['ifra_key']); + $image = mysqli_real_escape_string($conn, $d['image']); + $amendment = mysqli_real_escape_string($conn, $d['amendment']); + $prev_pub = mysqli_real_escape_string($conn, $d['prev_pub']); + $last_pub = mysqli_real_escape_string($conn, $d['last_pub']); + $deadline_existing = mysqli_real_escape_string($conn, $d['deadline_existing']); + $deadline_new = mysqli_real_escape_string($conn, $d['deadline_new']); + $name = mysqli_real_escape_string($conn, $d['name']); + $cas = mysqli_real_escape_string($conn, $d['cas']); + $cas_comment = mysqli_real_escape_string($conn, $d['cas_comment']); + $synonyms = mysqli_real_escape_string($conn, $d['synonyms']); + $formula = mysqli_real_escape_string($conn, $d['formula']); + $flavor_use = mysqli_real_escape_string($conn, $d['flavor_use']); + $prohibited_notes = mysqli_real_escape_string($conn, $d['prohibited_notes']); + $restricted_photo_notes = mysqli_real_escape_string($conn, $d['restricted_photo_notes']); + $restricted_notes = mysqli_real_escape_string($conn, $d['restricted_notes']); + $specified_notes = mysqli_real_escape_string($conn, $d['specified_notes']); + $type = mysqli_real_escape_string($conn, $d['type']); + $risk = mysqli_real_escape_string($conn, $d['risk']); + $contrib_others = mysqli_real_escape_string($conn, $d['contrib_others']); + $contrib_others_notes = mysqli_real_escape_string($conn, $d['contrib_others_notes']); + + $cat1 = isset($d['cat1']) && $d['cat1'] !== '' ? floatval($d['cat1']) : 100; + $cat2 = isset($d['cat2']) && $d['cat2'] !== '' ? floatval($d['cat2']) : 100; + $cat3 = isset($d['cat3']) && $d['cat3'] !== '' ? floatval($d['cat3']) : 100; + $cat4 = isset($d['cat4']) && $d['cat4'] !== '' ? floatval($d['cat4']) : 100; + $cat5A = isset($d['cat5A']) && $d['cat5A'] !== '' ? floatval($d['cat5A']) : 100; + $cat5B = isset($d['cat5B']) && $d['cat5B'] !== '' ? floatval($d['cat5B']) : 100; + $cat5C = isset($d['cat5C']) && $d['cat5C'] !== '' ? floatval($d['cat5C']) : 100; + $cat5D = isset($d['cat5D']) && $d['cat5D'] !== '' ? floatval($d['cat5D']) : 100; + $cat6 = isset($d['cat6']) && $d['cat6'] !== '' ? floatval($d['cat6']) : 100; + $cat7A = isset($d['cat7A']) && $d['cat7A'] !== '' ? floatval($d['cat7A']) : 100; + $cat7B = isset($d['cat7B']) && $d['cat7B'] !== '' ? floatval($d['cat7B']) : 100; + $cat8 = isset($d['cat8']) && $d['cat8'] !== '' ? floatval($d['cat8']) : 100; + $cat9 = isset($d['cat9']) && $d['cat9'] !== '' ? floatval($d['cat9']) : 100; + $cat10A = isset($d['cat10A']) && $d['cat10A'] !== '' ? floatval($d['cat10A']) : 100; + $cat10B = isset($d['cat10B']) && $d['cat10B'] !== '' ? floatval($d['cat10B']) : 100; + $cat11A = isset($d['cat11A']) && $d['cat11A'] !== '' ? floatval($d['cat11A']) : 100; + $cat11B = isset($d['cat11B']) && $d['cat11B'] !== '' ? floatval($d['cat11B']) : 100; + $cat12 = isset($d['cat12']) && $d['cat12'] !== '' ? floatval($d['cat12']) : 100; + + $s = mysqli_query($conn, " + INSERT INTO `IFRALibrary` ( + `ifra_key`, `image`, `amendment`, `prev_pub`, `last_pub`, + `deadline_existing`, `deadline_new`, `name`, `cas`, `cas_comment`, + `synonyms`, `formula`, `flavor_use`, `prohibited_notes`, `restricted_photo_notes`, + `restricted_notes`, `specified_notes`, `type`, `risk`, `contrib_others`, + `contrib_others_notes`, `cat1`, `cat2`, `cat3`, `cat4`, `cat5A`, + `cat5B`, `cat5C`, `cat5D`, `cat6`, `cat7A`, `cat7B`, `cat8`, `cat9`, + `cat10A`, `cat10B`, `cat11A`, `cat11B`, `cat12` + ) VALUES ( + '$ifra_key', '$image', '$amendment', '$prev_pub', '$last_pub', + '$deadline_existing', '$deadline_new', '$name', '$cas', '$cas_comment', + '$synonyms', '$formula', '$flavor_use', '$prohibited_notes', '$restricted_photo_notes', + '$restricted_notes', '$specified_notes', '$type', '$risk', '$contrib_others', + '$contrib_others_notes', $cat1, $cat2, $cat3, $cat4, $cat5A, + $cat5B, $cat5C, $cat5D, $cat6, $cat7A, $cat7B, $cat8, $cat9, + $cat10A, $cat10B, $cat11A, $cat11B, $cat12 + ) + "); + } + + + if($s){ + $result['success'] = "Import complete"; + unlink($target_path); + }else{ + $result['error'] = "There was an error importing your JSON file ".mysqli_error($conn); + echo json_encode($result); + return; + } + + } else { + $result['error'] = "There was an error processing json file $target_path, please try again!"; + echo json_encode($result); + + } + echo json_encode($result); + return; + +} + +//IMPORT SUPPLIERS +if ($_GET['action'] == 'importSuppliers') { + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path . basename($_FILES['jsonFile']['name']); + + if (move_uploaded_file($_FILES['jsonFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + if (!$data['inventory_suppliers']) { + $result['error'] = "JSON File seems invalid. Please make sure you are importing the right file"; + echo json_encode($result); + return; + } + + foreach ($data['inventory_suppliers'] as $d) { + $s = mysqli_query($conn, " + INSERT INTO `ingSuppliers` + (`name`, `address`, `po`, `country`, `telephone`, `url`, `email`, `platform`, `price_tag_start`, `price_tag_end`, `add_costs`, `price_per_size`, `notes`, `min_ml`, `min_gr`) + VALUES + ('" . $d['name'] . "', '" . $d['address'] . "', '" . $d['po'] . "', '" . $d['country'] . "', '" . $d['telephone'] . "', '" . $d['url'] . "', '" . $d['email'] . "', '" . $d['platform'] . "', '" . $d['price_tag_start'] . "', '" . $d['price_tag_end'] . "', '" . $d['add_costs'] . "', '" . $d['price_per_size'] . "', '" . $d['notes'] . "', '" . $d['min_ml'] . "', '" . $d['min_gr'] . "') + ON DUPLICATE KEY UPDATE + `address` = VALUES(`address`), + `po` = VALUES(`po`), + `country` = VALUES(`country`), + `telephone` = VALUES(`telephone`), + `url` = VALUES(`url`), + `email` = VALUES(`email`), + `platform` = VALUES(`platform`), + `price_tag_start` = VALUES(`price_tag_start`), + `price_tag_end` = VALUES(`price_tag_end`), + `add_costs` = VALUES(`add_costs`), + `price_per_size` = VALUES(`price_per_size`), + `notes` = VALUES(`notes`), + `min_ml` = VALUES(`min_ml`), + `min_gr` = VALUES(`min_gr`) + "); + } + + if ($s) { + $result['success'] = "Import complete"; + unlink($target_path); + } else { + $result['error'] = "There was an error importing your JSON file " . mysqli_error($conn); + echo json_encode($result); + return; + } + } else { + $result['error'] = "There was an error processing the JSON file $target_path, please try again!"; + echo json_encode($result); + } + + echo json_encode($result); + return; +} + +//IMPORT CUSTOMERS +if ($_GET['action'] == 'importCustomers') { + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path . basename($_FILES['jsonFile']['name']); + + if (move_uploaded_file($_FILES['jsonFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + if (!$data['inventory_customers']) { + $result['error'] = "JSON File seems invalid. Please make sure you are importing the right file"; + echo json_encode($result); + return; + } + + foreach ($data['inventory_customers'] as $d) { + $s = mysqli_query($conn, " + INSERT INTO `customers` + (`name`, `address`, `email`, `phone`, `web`, `owner_id`) + VALUES + ('" . $d['name'] . "', '" . $d['address'] . "', '" . $d['email'] . "', '" . $d['phone'] . "', '" . $d['web'] . "', '" . $d['owner_id'] . "') + ON DUPLICATE KEY UPDATE + `address` = VALUES(`address`), + `email` = VALUES(`email`), + `phone` = VALUES(`phone`), + `web` = VALUES(`web`), + `owner_id` = VALUES(`owner_id`) + "); + } + + if ($s) { + $result['success'] = "Import complete"; + unlink($target_path); + } else { + $result['error'] = "There was an error importing your JSON file " . mysqli_error($conn); + echo json_encode($result); + return; + } + } else { + $result['error'] = "There was an error processing the JSON file $target_path, please try again!"; + echo json_encode($result); + } + + echo json_encode($result); + return; +} + +//IMPORT BOTTLES +if ($_GET['action'] == 'importBottles') { + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path . basename($_FILES['jsonFile']['name']); + + if (move_uploaded_file($_FILES['jsonFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + if (!$data['inventory_bottles']) { + $result['error'] = "JSON File seems invalid. Please make sure you are importing the right file"; + echo json_encode($result); + return; + } + + foreach ($data['inventory_bottles'] as $d) { + $s = mysqli_query($conn, " + INSERT INTO `bottles` + (`name`, `ml`, `price`, `height`, `width`, `diameter`, `weight`, `supplier`, `supplier_link`, `notes`, `pieces`) + VALUES + ('" . $d['name'] . "', '" . $d['ml'] . "', '" . $d['price'] . "', '" . $d['height'] . "', '" . $d['width'] . "', '" . $d['diameter'] . "', '" . $d['weight'] . "', '" . $d['supplier'] . "', '" . $d['supplier_link'] . "', '" . $d['notes'] . "', '" . $d['pieces'] . "') + ON DUPLICATE KEY UPDATE + `ml` = VALUES(`ml`), + `price` = VALUES(`price`), + `height` = VALUES(`height`), + `width` = VALUES(`width`), + `diameter` = VALUES(`diameter`), + `weight` = VALUES(`weight`), + `supplier` = VALUES(`supplier`), + `supplier_link` = VALUES(`supplier_link`), + `notes` = VALUES(`notes`), + `pieces` = VALUES(`pieces`) + "); + } + + if ($s) { + $result['success'] = "Import complete"; + unlink($target_path); + } else { + $result['error'] = "There was an error importing your JSON file " . mysqli_error($conn); + echo json_encode($result); + return; + } + } else { + $result['error'] = "There was an error processing the JSON file $target_path, please try again!"; + echo json_encode($result); + } + + echo json_encode($result); + return; +} + +//IMPORT ACCESSORIES +if ($_GET['action'] == 'importAccessories') { + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path . basename($_FILES['jsonFile']['name']); + + if (move_uploaded_file($_FILES['jsonFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + if (!$data['inventory_accessories']) { + $result['error'] = "JSON File seems invalid. Please make sure you are importing the right file"; + echo json_encode($result); + return; + } + + foreach ($data['inventory_accessories'] as $d) { + $s = mysqli_query($conn, " + INSERT INTO `inventory_accessories` + (`name`, `accessory`, `price`, `supplier`, `supplier_link`, `pieces`) + VALUES + ('" . $d['name'] . "', '" . $d['accessory'] . "', '" . $d['price'] . "', '" . $d['supplier'] . "', '" . $d['supplier_link'] . "', '" . $d['pieces'] . "') + ON DUPLICATE KEY UPDATE + `accessory` = VALUES(`accessory`), + `price` = VALUES(`price`), + `supplier` = VALUES(`supplier`), + `supplier_link` = VALUES(`supplier_link`), + `pieces` = VALUES(`pieces`) + "); + } + + if ($s) { + $result['success'] = "Import complete"; + unlink($target_path); + } else { + $result['error'] = "There was an error importing your JSON file " . mysqli_error($conn); + echo json_encode($result); + return; + } + } else { + $result['error'] = "There was an error processing the JSON file $target_path, please try again!"; + echo json_encode($result); + } + + echo json_encode($result); + return; +} + + +//IMPORT COMPOUNDS +if ($_GET['action'] == 'importCompounds') { + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path . basename($_FILES['jsonFile']['name']); + + if (move_uploaded_file($_FILES['jsonFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + if (!$data['inventory_compounds']) { + $result['error'] = "JSON File seems invalid. Please make sure you are importing the right file"; + echo json_encode($result); + return; + } + + foreach ($data['inventory_compounds'] as $d) { + $s = mysqli_query($conn, " + INSERT INTO `inventory_compounds` + (`name`, `description`, `batch_id`, `size`, `updated`, `created`, `location`, `label_info`) + VALUES + ('" . $d['name'] . "', '" . $d['description'] . "', '" . $d['batch_id'] . "', '" . $d['size'] . "', '" . $d['updated'] . "', '" . $d['created'] . "', '" . $d['location'] . "', '" . $d['label_info'] . "') + ON DUPLICATE KEY UPDATE + `description` = VALUES(`description`), + `batch_id` = VALUES(`batch_id`), + `size` = VALUES(`size`), + `updated` = VALUES(`updated`), + `created` = VALUES(`created`), + `location` = VALUES(`location`), + `label_info` = VALUES(`label_info`) + "); + } + + if ($s) { + $result['success'] = "Import complete"; + unlink($target_path); + } else { + $result['error'] = "There was an error importing your JSON file " . mysqli_error($conn); + echo json_encode($result); + return; + } + } else { + $result['error'] = "There was an error processing the JSON file $target_path, please try again!"; + echo json_encode($result); + } + + echo json_encode($result); + return; +} + + +// IMPORT CATEGORIES +if ($_GET['action'] == 'importCategories') { + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path . basename($_FILES['jsonFile']['name']); + + if (move_uploaded_file($_FILES['jsonFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + + if (!$data['ingCategory'] && !$data['formulaCategories'] && !$data['ingProfiles']) { + $result['error'] = "JSON File seems invalid. Please make sure you are importing the right file"; + echo json_encode($result); + return; + } + + $conn->autocommit(FALSE); // Turn off auto-commit for transaction + + $success = true; + + if ($data['ingCategory']) { + $stmt = $conn->prepare("INSERT INTO `ingCategory` (`name`, `notes`, `image`, `colorKey`) VALUES (?, ?, ?, ?)"); + foreach ($data['ingCategory'] as $d) { + $stmt->bind_param("ssss", $d['name'], $d['notes'], $d['image'], $d['colorKey']); + if (!$stmt->execute()) { + $success = false; + $result['error'] = "Error inserting into ingCategory: " . $stmt->error; + break; + } + } + $stmt->close(); + } + + if ($data['formulaCategories']) { + $stmt = $conn->prepare("INSERT INTO `formulaCategories` (`name`, `cname`, `type`, `colorKey`) VALUES (?, ?, ?, ?)"); + foreach ($data['formulaCategories'] as $d) { + $stmt->bind_param("ssss", $d['name'], $d['cname'], $d['type'], $d['colorKey']); + if (!$stmt->execute()) { + $success = false; + $result['error'] = "Error inserting into formulaCategories: " . $stmt->error; + break; + } + } + $stmt->close(); + } + + if ($data['ingProfiles']) { + $stmt = $conn->prepare("INSERT INTO `ingProfiles` (`name`, `notes`, `image`) VALUES (?, ?, ?)"); + foreach ($data['ingProfiles'] as $d) { + $stmt->bind_param("sss", $d['name'], $d['notes'], $d['image']); + if (!$stmt->execute()) { + $success = false; + $result['error'] = "Error inserting into ingProfiles: " . $stmt->error; + break; + } + } + $stmt->close(); + } + + if ($success) { + $conn->commit(); // Commit the transaction + $result['success'] = "Import complete"; + unlink($target_path); + } else { + $conn->rollback(); // Rollback the transaction on error + echo json_encode($result); + return; + } + + $conn->autocommit(TRUE); // Turn auto-commit back on + } else { + $result['error'] = "There was an error processing json file $target_path, please try again!"; + } + + echo json_encode($result); + return; +} + + +// IMPORT MAKING +if ($_GET['action'] == 'importMaking') { + if (!file_exists($tmp_path)) { + mkdir($tmp_path, 0777, true); + } + + if (!is_writable($tmp_path)) { + $result['error'] = "Upload directory not writable. Make sure you have write permissions."; + echo json_encode($result); + return; + } + + $target_path = $tmp_path . basename($_FILES['jsonFile']['name']); + + if (move_uploaded_file($_FILES['jsonFile']['tmp_name'], $target_path)) { + $data = json_decode(file_get_contents($target_path), true); + + if (!$data || !isset($data['makeFormula'])) { + $result['error'] = "JSON File seems invalid. Please make sure you are importing the right file"; + echo json_encode($result); + return; + } + + $conn->autocommit(FALSE); // Turn off auto-commit for transaction + + $success = true; + + if (!empty($data['makeFormula'])) { + $stmt = $conn->prepare("INSERT INTO `makeFormula` (`fid`, `name`, `ingredient`, `ingredient_id`, `replacement_id`, `concentration`, `dilutant`, `quantity`, `overdose`, `originalQuantity`, `notes`, `skip`, `toAdd`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + foreach ($data['makeFormula'] as $d) { + $stmt->bind_param("sssssssssssss", $d['fid'], $d['name'], $d['ingredient'], $d['ingredient_id'], $d['replacement_id'], $d['concentration'], $d['dilutant'], $d['quantity'], $d['overdose'], $d['originalQuantity'], $d['notes'], $d['skip'], $d['toAdd']); + if (!$stmt->execute()) { + $success = false; + $result['error'] = "Error inserting into makeFormula: " . $stmt->error; + break; + } + } + $stmt->close(); + } + + if ($success) { + //CREATE A FORMULA ENTRY + $stmtMeta = $conn->prepare("INSERT INTO formulasMetaData (name, fid, todo) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE name=VALUES(name), todo=VALUES(todo)"); + + $todo = 1; + $stmtMeta->bind_param("ssi", $data['makeFormula'][0]['name'], $data['makeFormula'][0]['fid'], $todo); + if (!$stmtMeta->execute()) { + $success = false; + $result['error'] = "Error inserting into formulasMetaData " . $stmtMeta->error; + } + $stmtMeta->close(); + } +/* + if ($success) { + $stmtFormula = $conn->prepare("INSERT IGNORE INTO formulas (name, fid, ingredient, ingredient_id, concentration, dilutant, quantity) VALUES (?, ?, ?, ?, ?, ?, ?)"); + foreach ($data['makeFormula'] as $d) { + $stmtFormula->bind_param("sssssss", $d['name'], $d['fid'], $d['ingredient'], $d['ingredient_id'], $d['concentration'], $d['dilutant'], $d['quantity']); + if (!$stmtFormula->execute()) { + $success = false; + $result['error'] = "Error inserting into formulas: " . $stmtFormula->error; + break; + } + } + $stmtFormula->close(); + } +*/ + if (!empty($data['makeFormula'])) { + $stmt = $conn->prepare("INSERT INTO `makeFormula` (`fid`, `name`, `ingredient`, `ingredient_id`, `replacement_id`, `concentration`, `dilutant`, `quantity`, `overdose`, `originalQuantity`, `notes`, `skip`, `toAdd`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + foreach ($data['makeFormula'] as $d) { + // Fetch ingredient_id + $stmtIngredient = $conn->prepare("SELECT id FROM `ingredients` WHERE name = ?"); + $stmtIngredient->bind_param("s", $d['ingredient_id']); + $stmtIngredient->execute(); + $stmtIngredient->bind_result($ingredient_id); + $stmtIngredient->fetch(); + $stmtIngredient->close(); + + // If ingredient not found, insert it and fetch the new id + if (empty($ingredient_id)) { + $stmtInsertIngredient = $conn->prepare("INSERT INTO `ingredients` (name) VALUES (?)"); + $stmtInsertIngredient->bind_param("s", $d['ingredient']); + if (!$stmtInsertIngredient->execute()) { + $success = false; + $result['error'] = "Error inserting into ingredients: " . $stmtInsertIngredient->error; + break; + } + $ingredient_id = $stmtInsertIngredient->insert_id; + $stmtInsertIngredient->close(); + } + + // Insert into makeFormula + $stmt->bind_param("sssssssssssss", $d['fid'], $d['name'], $d['ingredient'], $ingredient_id, $d['replacement_id'], $d['concentration'], $d['dilutant'], $d['quantity'], $d['overdose'], $d['originalQuantity'], $d['notes'], $d['skip'], $d['toAdd']); + if (!$stmt->execute()) { + $success = false; + $result['error'] = "Error inserting into makeFormula: " . $stmt->error; + break; + } + } + $stmt->close(); + } + if ($success) { + // Insert ignore logic for `formulas` + $stmtFormula = $conn->prepare("INSERT IGNORE INTO formulas (name, fid, ingredient, ingredient_id, concentration, dilutant, quantity) VALUES (?, ?, ?, ?, ?, ?, ?)"); + foreach ($data['makeFormula'] as $d) { + // Fetch ingredient_id again in case it was updated during the loop + $stmtIngredient = $conn->prepare("SELECT id FROM `ingredients` WHERE name = ?"); + $stmtIngredient->bind_param("s", $d['ingredient']); + $stmtIngredient->execute(); + $stmtIngredient->bind_result($ingredient_id); + $stmtIngredient->fetch(); + $stmtIngredient->close(); + + $stmtFormula->bind_param("sssssss", $d['name'], $d['fid'], $d['ingredient'], $ingredient_id, $d['concentration'], $d['dilutant'], $d['quantity']); + if (!$stmtFormula->execute()) { + $success = false; + $result['error'] = "Error inserting into formulas: " . $stmtFormula->error; + break; + } + } + $stmtFormula->close(); + } + + if ($success) { + $conn->commit(); // Commit the transaction + $result['success'] = "Import complete"; + unlink($target_path); + } else { + $conn->rollback(); // Rollback the transaction on error + } + + $conn->autocommit(TRUE); // Turn auto-commit back on + } else { + $result['error'] = "There was an error processing the JSON file $target_path, please try again!"; + } + + echo json_encode($result); + return; +} + + +//EXPORT INGREDIENT CATEGORIES +if($_GET['action'] == 'exportIngCat'){ + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM ingCategory")))){ + $msg['error'] = 'No data found to export.'; + echo json_encode($msg); + return; + } + $data = 0; + $q = mysqli_query($conn, "SELECT * FROM ingCategory"); + while($resData = mysqli_fetch_assoc($q)){ + + $r['id'] = (int)$resData['id']; + $r['name'] = (string)$resData['name']?: "-"; + $r['notes'] = (string)$resData['notes']?: "-"; + $r['image'] = (string)$resData['image'] ?: "-"; + $r['colorKey'] = (string)$resData['colorKey']?: "-"; + + $data++; + $cat[] = $r; + } + + $vd['product'] = $product; + $vd['version'] = $ver; + $vd['ingCategory'] = $data; + $vd['timestamp'] = date('d/m/Y H:i:s'); + + + $result['ingCategory'] = $cat; + $result['pvMeta'] = $vd; + + header('Content-disposition: attachment; filename=IngCategories.json'); + header('Content-type: application/json'); + echo json_encode($result, JSON_PRETTY_PRINT); + return; +} + +//EXPORT FORMULA CATEGORIES +if($_GET['action'] == 'exportFrmCat'){ + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM formulaCategories")))){ + $msg['error'] = 'No data found to export.'; + echo json_encode($msg); + return; + } + $data = 0; + $q = mysqli_query($conn, "SELECT * FROM formulaCategories"); + while($resData = mysqli_fetch_assoc($q)){ + + $r['id'] = (int)$resData['id']; + $r['name'] = (string)$resData['name']?: "-"; + $r['cname'] = (string)$resData['cname']?: "-"; + $r['type'] = (string)$resData['type'] ?: "-"; + $r['colorKey'] = (string)$resData['colorKey']?: "-"; + + $data++; + $cat[] = $r; + } + + $vd['product'] = $product; + $vd['version'] = $ver; + $vd['formulaCategories'] = $data; + $vd['timestamp'] = date('d/m/Y H:i:s'); + + + $result['formulaCategories'] = $cat; + $result['pvMeta'] = $vd; + + header('Content-disposition: attachment; filename=FormulaCategories.json'); + header('Content-type: application/json'); + echo json_encode($result, JSON_PRETTY_PRINT); + return; +} + +//EXPORT PERFUME TYPES +if($_GET['action'] == 'exportPerfTypes'){ + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM perfumeTypes")))){ + $msg['error'] = 'No data found to export.'; + echo json_encode($msg); + return; + } + $data = 0; + $q = mysqli_query($conn, "SELECT * FROM perfumeTypes"); + while($resData = mysqli_fetch_assoc($q)){ + + $r['id'] = (int)$resData['id']; + $r['name'] = (string)$resData['name']?: "-"; + $r['concentration'] = (int)$resData['concentration']?: 100; + $r['description'] = (string)$resData['description'] ?: "-"; + + $data++; + $cat[] = $r; + } + + $vd['product'] = $product; + $vd['version'] = $ver; + $vd['perfumeTypes'] = $data; + $vd['timestamp'] = date('d/m/Y H:i:s'); + + + $result['perfumeTypes'] = $cat; + $result['pvMeta'] = $vd; + + header('Content-disposition: attachment; filename=PerfumeTypes.json'); + header('Content-type: application/json'); + echo json_encode($result, JSON_PRETTY_PRINT); + return; +} + + + +//EXPORT MAKING FORMULA +if($_GET['action'] == 'exportMaking'){ + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM makeFormula")))){ + $msg['error'] = 'No data found to export.'; + echo json_encode($msg); + return; + } + $data = 0; + if($fid = $_GET['fid']){ + + $filter = " WHERE fid = '$fid' "; + } + + $q = mysqli_query($conn, "SELECT * FROM makeFormula $filter"); + while($resData = mysqli_fetch_assoc($q)){ + + $r['id'] = (int)$resData['id']; + $r['fid'] = (string)$resData['fid']; + $r['name'] = (string)$resData['name']; + $r['ingredient'] = (string)$resData['ingredient']; + $r['ingredient_id'] = (int)$resData['ingredient_id']; + $r['replacement_id'] = (int)$resData['replacement_id']; + $r['concentration'] = (double)$resData['concentration']; + $r['dilutant'] = (string)$resData['dilutant']; + $r['quantity'] = (double)$resData['quantity']; + $r['overdose'] = (double)$resData['overdose']; + $r['originalQuantity'] = (double)$resData['originalQuantity']; + $r['notes'] = (string)$resData['notes']; + $r['skip'] = (int)$resData['skip']; + $r['toAdd'] = (int)$resData['toAdd']; + + $data++; + $dat_arr[] = $r; + } + + $vd['product'] = $product; + $vd['version'] = $ver; + $vd['makeFormula'] = $data; + $vd['timestamp'] = date('d/m/Y H:i:s'); + + + $result['makeFormula'] = $dat_arr; + $result['pvMeta'] = $vd; + + header('Content-disposition: attachment; filename=MakeFormula.json'); + header('Content-type: application/json'); + echo json_encode($result, JSON_PRETTY_PRINT); + return; +} + +//EXPORT INGREDIENT PROFILES +if($_GET['action'] == 'exportIngProf'){ + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM ingProfiles")))){ + $msg['error'] = 'No data found to export.'; + echo json_encode($msg); + return; + } + $data = 0; + $q = mysqli_query($conn, "SELECT * FROM ingProfiles"); + while($resData = mysqli_fetch_assoc($q)){ + + $r['id'] = (int)$resData['id']; + $r['name'] = (string)$resData['name']?: "-"; + $r['notes'] = (string)$resData['notes']?: "-"; + $r['image'] = (string)$resData['image'] ?: "-"; + + $data++; + $cat[] = $r; + } + + $vd['product'] = $product; + $vd['version'] = $ver; + $vd['ingCategory'] = $data; + $vd['timestamp'] = date('d/m/Y H:i:s'); + + + $result['ingProfiles'] = $cat; + $result['pvMeta'] = $vd; + + header('Content-disposition: attachment; filename=IngProfiles.json'); + header('Content-type: application/json'); + echo json_encode($result, JSON_PRETTY_PRINT); + return; +} + + +if($_POST['do'] == 'tagadd' && $_POST['fid'] && $_POST['tag']){ + if(mysqli_num_rows(mysqli_query($conn,"SELECT id FROM formulasTags WHERE formula_id='".$_POST['fid']."' AND tag_name = '".$_POST['tag']."'"))){ + $response[] = ''; + echo json_encode($response); + return; + } + mysqli_query($conn,"INSERT INTO formulasTags (formula_id,tag_name) VALUES('".$_POST['fid']."','".$_POST['tag']."')" ); + $response[] = ''; + echo json_encode($response); + return; +} + +if($_POST['do'] == 'tagremove' && $_POST['fid'] && $_POST['tag']){ + mysqli_query($conn,"DELETE FROM formulasTags WHERE formula_id='".$_POST['fid']."' AND tag_name = '".$_POST['tag']."'" ); + $response[] = ''; + echo json_encode($response); + return; +} + +if($_POST['update_rating'] == '1' && $_POST['fid'] && is_numeric($_POST['score'])){ + mysqli_query($conn,"UPDATE formulasMetaData SET rating = '".$_POST['score']."' WHERE id = '".$_POST['fid']."'"); +} + +//EXCLUDE/INCLUDE INGREDIENT +if($_POST['action'] == 'excIng' && $_POST['ingID']){ + $id = mysqli_real_escape_string($conn, $_POST['ingID']); + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $ing = mysqli_real_escape_string($conn, $_POST['ingName']); + + $status = (int)$_POST['status']; + if($status == 1){ + $st = 'excluded from calclulations'; + }else{ + $st = 'included in calculations'; + } + + $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT id,isProtected FROM formulasMetaData WHERE fid = '$fid'")); + if($meta['isProtected'] == FALSE){ + if(mysqli_query($conn, "UPDATE formulas SET exclude_from_calculation = '$status' WHERE id = '$id'")){ + $response['success'] = $ing.' is now '. $st; + }else{ + $response['error'] = $ing.' cannot be '.$st.' from the formula!'; + } + } + + echo json_encode($response); + return; +} + +//IS MADE +if($_POST['isMade'] && $_POST['fid']){ + $fid = mysqli_real_escape_string($conn,$_POST['fid']); + + $quant = mysqli_query($conn, "SELECT ingredient,quantity FROM formulas WHERE fid = '$fid'"); + while($get_quant = mysqli_fetch_array($quant)){ + $ing = mysqli_fetch_array(mysqli_query($conn, "SELECT id FROM ingredients WHERE name = '".$get_quant['ingredient']."'")); + $q = "UPDATE suppliers SET stock = GREATEST(0, stock - '".$get_quant['quantity']."') WHERE ingID = '".$ing['id']."' AND stock = GREATEST(stock, '".$get_quant['quantity']."')"; + $upd = mysqli_query($conn, $q); + + } + if($upd){ + mysqli_query($conn,"UPDATE formulasMetaData SET isMade = '1', madeOn = NOW() WHERE fid = '$fid'"); + $response['success'] = 'Inventory updated'; + }else{ + $response['error'] = mysqli_error($conn); + } + + echo json_encode($response); + return; +} + + +//CREATE ACCORD +if($_POST['accordName'] && $_POST['accordProfile'] && $_POST['fid']){ + require_once(__ROOT__.'/func/genFID.php'); + + $fid = mysqli_real_escape_string($conn,$_POST['fid']); + $accordProfile = mysqli_real_escape_string($conn,$_POST['accordProfile']); + $accordName = mysqli_real_escape_string($conn,$_POST['accordName']); + $nfid = random_str(40, '1234567890abcdefghijklmnopqrstuvwxyz'); + + if(mysqli_num_rows(mysqli_query($conn,"SELECT name FROM formulasMetaData WHERE name = '$accordName'"))){ + $response['error'] = 'A formula with name '.$accordName.' already exists, please choose a different name!'; + echo json_encode($response); + return; + } + + $get_formula = mysqli_query($conn,"SELECT ingredient FROM formulas WHERE fid = '$fid'"); + while($formula = mysqli_fetch_array($get_formula)){ + if($i = mysqli_fetch_array(mysqli_query($conn,"SELECT name,profile FROM ingredients WHERE profile = '$accordProfile' AND name ='".$formula['ingredient']."'"))){ + mysqli_query($conn, "INSERT INTO formulas (fid, name, ingredient, ingredient_id, concentration, dilutant, quantity, notes) SELECT '$nfid', '$accordName', ingredient, ingredient_id, concentration, dilutant, quantity, notes FROM formulas WHERE fid = '$fid' AND ingredient = '".$i['name']."'"); + } + } + if(mysqli_query($conn,"INSERT INTO formulasMetaData (fid,name) VALUES ('$nfid','$accordName')")){ + $response['success'] = 'Accord '.$accordName.' created!'; + } + echo json_encode($response); + return; +} + +//RESTORE REVISION +if($_GET['restore'] == 'rev' && $_GET['revision'] && $_GET['fid']){ + $fid = mysqli_real_escape_string($conn,$_GET['fid']); + $revision = $_GET['revision']; + + mysqli_query($conn, "DELETE FROM formulas WHERE fid = '$fid'"); + if(mysqli_query($conn, "INSERT INTO formulas (fid, name, ingredient, ingredient_id, concentration, dilutant, quantity, notes) SELECT fid, name, ingredient, ingredient_id, concentration, dilutant, quantity, notes FROM formulasRevisions WHERE fid = '$fid' AND revision = '$revision'")){ + mysqli_query($conn, "UPDATE formulasMetaData SET revision = '$revision' WHERE fid = '$fid'"); + $response['success'] = 'Formula revision restored!'; + }else{ + $response['error'] = 'Unable to restore revision! '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//DELETE REVISION +if($_GET['delete'] == 'rev' && $_GET['revision'] && $_GET['fid']){ + $fid = mysqli_real_escape_string($conn,$_GET['fid']); + $revision = $_GET['revision']; + + if(mysqli_query($conn,"DELETE FROM formulasRevisions WHERE fid = '$fid' AND revision = '$revision'")){ + $response['success'] = 'Formula revision deleted!'; + }else{ + $response['error'] = 'Unable to delete revision! '.mysqli_error($conn); + } + echo json_encode($response); + return; +} + +//MANAGE VIEW +if($_GET['manage_view'] == '1'){ + $ing = mysqli_real_escape_string($conn,str_replace('_', ' ',$_GET['ex_ing'])); + + if($_GET['ex_status'] == 'true'){ + $status = '0'; + }elseif($_GET['ex_status'] == 'false'){ + $status = '1'; + } + $fid = $_GET['fid']; + + $q = mysqli_query($conn, "UPDATE formulas SET exclude_from_summary = '$status' WHERE fid = '$fid' AND ingredient = '$ing'"); + if($q){ + $response['success'] = 'View updated!'; + }else{ + $response['error'] = 'Something went wrong'; + } + + echo json_encode($response); + return; +} + +//SCALE FORMULA +if ($_POST['fid'] && $_POST['action'] == 'advancedScale' && $_POST['SG'] && $_POST['amount']) { + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $SG = mysqli_real_escape_string($conn, $_POST['SG']); + $amount = mysqli_real_escape_string($conn, $_POST['amount']); + + $new_amount = $amount * $SG; + $mg = mysqli_fetch_assoc(mysqli_query($conn, "SELECT SUM(quantity) AS total_mg FROM formulas WHERE fid = '$fid'")); + + $q = mysqli_query($conn, "SELECT quantity, ingredient FROM formulas WHERE fid = '$fid'"); + $all_success = true; + + while ($cur = mysqli_fetch_array($q)) { + $nq = $cur['quantity'] / $mg['total_mg'] * $new_amount; + + if (empty($nq)) { + $response['error'] = 'Something went wrong...'; + echo json_encode($response); + return; + } + + $update = mysqli_query($conn, "UPDATE formulas SET quantity = '$nq' WHERE fid = '$fid' AND quantity = '" . $cur['quantity'] . "' AND ingredient = '" . $cur['ingredient'] . "'"); + + if (!$update) { + $all_success = false; + $error_message = mysqli_error($conn); + break; + } + } + + if ($all_success) { + $response['success'] = 'Formula scaled'; + } else { + $response['error'] = 'Something went wrong... ' . $error_message; + } + + echo json_encode($response); + return; +} + + +//DIVIDE - MULTIPLY +if ($_POST['formula'] && $_POST['action'] == 'simpleScale') { + $fid = mysqli_real_escape_string($conn, $_POST['formula']); + $q = mysqli_query($conn, "SELECT quantity, ingredient FROM formulas WHERE fid = '$fid'"); + $all_success = true; + + while ($cur = mysqli_fetch_array($q)) { + // Calculate the new quantity based on the scale action + if ($_POST['scale'] == 'multiply') { + $nq = $cur['quantity'] * 2; + } elseif ($_POST['scale'] == 'divide') { + $nq = $cur['quantity'] / 2; + } else { + $all_success = false; + $error_message = "Invalid scale action."; + break; + } + + $update = mysqli_query($conn, "UPDATE formulas SET quantity = '$nq' WHERE fid = '$fid' AND quantity = '" . $cur['quantity'] . "' AND ingredient = '" . $cur['ingredient'] . "'"); + + if (!$update) { + $all_success = false; + $error_message = mysqli_error($conn); + break; + } + } + + if ($all_success) { + $response['success'] = 'Formula scaled successfully'; + } else { + $response['error'] = 'Error during scaling: ' . $error_message; + } + + echo json_encode($response); + return; +} + + +//DELETE INGREDIENT +if($_POST['action'] == 'deleteIng' && $_POST['ingID'] && $_POST['ing']){ + $id = mysqli_real_escape_string($conn, $_POST['ingID']); + $ing = mysqli_real_escape_string($conn, $_POST['ing']); + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $ingredient_id = mysqli_real_escape_string($conn, $_POST['ingredient_id']); + + if($_POST['reCalc'] == 'true'){ + if(!$_POST['formulaSolventID']){ + $response["error"] = 'Please select solvent'; + echo json_encode($response); + return; + } + $formulaSolventID = $_POST['formulaSolventID']; + + if(mysqli_num_rows(mysqli_query($conn,"SELECT id FROM ingredients WHERE id = '".$ingredient_id."' AND profile='solvent'"))){ + $response["error"] = 'You cannot deduct a solvent from a solvent'; + echo json_encode($response); + return; + } + + $qs = mysqli_fetch_array(mysqli_query($conn,"SELECT quantity FROM formulas WHERE id = '$id' AND fid = '$fid'")); + $v = $qs['quantity']; + mysqli_query($conn,"UPDATE formulas SET quantity = quantity + $v WHERE fid = '$fid' AND ingredient_id = '".$formulaSolventID."'"); + + } + + $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT id,isProtected FROM formulasMetaData WHERE fid = '$fid'")); + + if($meta['isProtected'] == FALSE){ + + if(mysqli_query($conn, "DELETE FROM formulas WHERE id = '$id' AND fid = '$fid'")){ + $response['success'] = $ing.' removed from the formula'; + $lg = "REMOVED: $ing removed"; + mysqli_query($conn, "INSERT INTO formula_history (fid,ing_id,change_made,user) VALUES ('".$meta['id']."','".$ingredient_id."','$lg','".$user['fullName']."')"); + }else{ + $response['error'] = $ing.' cannot be removed from the formula'; + } + } + echo json_encode($response); + return; +} + +//ADD INGREDIENT +if($_POST['action'] == 'addIngToFormula'){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $id = mysqli_real_escape_string($conn, $_POST['id']); + $ingredient_id = mysqli_real_escape_string($conn, $_POST['ingredient']); + $quantity = preg_replace("/[^0-9.]/", "", mysqli_real_escape_string($conn, $_POST['quantity'])); + $concentration = preg_replace("/[^0-9.]/", "", mysqli_real_escape_string($conn, $_POST['concentration'])); + $dilutant = mysqli_real_escape_string($conn, $_POST['dilutant']); + $ingredient = mysqli_fetch_array(mysqli_query($conn, "SELECT name FROM ingredients WHERE id = '$ingredient_id'")); + + $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT id,isProtected,name FROM formulasMetaData WHERE fid = '$fid'")); + if($meta['isProtected'] == TRUE){ + $response["error"] = 'Formula is protected and cannot be modified'; + echo json_encode($response); + return; + } + + if (empty($quantity) || empty($concentration)){ + $response['error'] = 'Missing required fields'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT ingredient_id FROM formulas WHERE ingredient_id = '$ingredient_id' AND fid = '$fid'"))){ + $response['error'] = $ingredient['name'].' already exists in formula'; + echo json_encode($response); + return; + } + + if($_POST['reCalc'] == 'true'){ + if(!$_POST['formulaSolventID']){ + $response["error"] = 'Please select solvent'; + echo json_encode($response); + return; + } + + $formulaSolventID = $_POST['formulaSolventID']; + + if(mysqli_num_rows(mysqli_query($conn,"SELECT id FROM ingredients WHERE id = '".$ingredient_id."' AND profile='solvent'"))){ + $response["error"] = 'You cannot add a solvent to a solvent'; + echo json_encode($response); + return; + } + + $slv = mysqli_fetch_array(mysqli_query($conn,"SELECT quantity FROM formulas WHERE ingredient_id = '".$formulaSolventID."' AND fid = '".$fid."'")); + + if($slv['quantity'] < $quantity){ + $response["error"] = 'Not enough solvent, available: '.number_format($slv['quantity'],$settings['qStep']).$settings['mUnit']; + echo json_encode($response); + return; + } + + mysqli_query($conn,"UPDATE formulas SET quantity = quantity - $quantity WHERE fid = '$fid' AND ingredient_id = '".$formulaSolventID."'"); + + } + + if(mysqli_query($conn,"INSERT INTO formulas(fid,name,ingredient,ingredient_id,concentration,quantity,dilutant) VALUES('$fid','".$meta['name']."','".$ingredient['name']."','".$ingredient_id."','$concentration','$quantity','$dilutant')")){ + + $lg = "ADDED: ".$ingredient['name']." $quantity".$settings['mUnit']." @$concentration% $dilutant"; + mysqli_query($conn, "INSERT INTO formula_history (fid,ing_id,change_made,user) VALUES ('".$id."','$ingredient_id','$lg','".$user['fullName']."')"); + mysqli_query($conn, "UPDATE formulasMetaData SET status = '1' WHERE fid = '".$fid."' AND status = '0' AND isProtected = '0'"); + + $response['success'] = ''.$quantity.$settings['mUnit'].' of '.$ingredient['name'].' added to the formula'; + echo json_encode($response); + return; + } else { + $response['error'] = 'Something went wrong '.mysqli_error($conn); + echo json_encode($response); + } + + if(mysqli_error($conn)){ + $response['error'] = 'Something went wrong '.mysqli_error($conn); + echo json_encode($response); + } + return; +} + +//REPLACE INGREDIENT +if($_POST['action'] == 'repIng' && $_POST['fid']){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + + if(!$_POST['dest']){ + $response['error'] = 'Please select ingredient'; + echo json_encode($response); + return; + } + + $ingredient = mysqli_real_escape_string($conn, $_POST['dest']); + $oldIngredient = mysqli_real_escape_string($conn, $_POST['ingSrcName']); + $ingredient_id = mysqli_fetch_array(mysqli_query($conn, "SELECT id FROM ingredients WHERE name = '$ingredient'")); + + $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT id,isProtected FROM formulasMetaData WHERE fid = '$fid'")); + if($meta['isProtected'] == FALSE){ + if(mysqli_num_rows(mysqli_query($conn, "SELECT ingredient FROM formulas WHERE ingredient = '$ingredient' AND fid = '$fid'"))){ + $response['error'] = $ingredient.' already exists in formula!'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "UPDATE formulas SET ingredient = '$ingredient', ingredient_id = '".$ingredient_id['id']."' WHERE ingredient = '$oldIngredient' AND id = '".$_POST['ingSrcID']."' AND fid = '$fid'")){ + $response['success'] = $oldIngredient.' replaced by '.$ingredient; + $lg = "REPLACED: $oldIngredient WITH $ingredient"; + mysqli_query($conn, "INSERT INTO formula_history (fid,ing_id,change_made,user) VALUES ('".$meta['id']."','".$ingredient_id['id']."','$lg','".$user['fullName']."')"); + }else{ + $response['error'] = 'Error replacing '.$oldIngredient; + } + } + + header('Content-Type: application/json'); + echo json_encode($response); + return; +} + +//Convert to ingredient +if($_POST['action'] == 'conv2ing' && $_POST['ingName'] && $_POST['fid']){ + $name = mysqli_real_escape_string($conn, $_POST['ingName']); + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $fname = mysqli_real_escape_string($conn, $_POST['fname']); + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM ingredients WHERE name = '$name'"))){ + $response['error'] = ''.$name.' already exists'; + echo json_encode($response); + return; + } + + $formula_q = mysqli_query($conn, "SELECT ingredient,quantity,concentration FROM formulas WHERE fid = '$fid'"); + while ($formula = mysqli_fetch_array($formula_q)){ + $ing_data = mysqli_fetch_array(mysqli_query($conn,"SELECT cas FROM ingredients WHERE name = '".$formula['ingredient']."'")); + $conc = number_format($formula['quantity']/100 * 100, $settings['qStep']); + $conc_p = number_format($formula['concentration'] / 100 * $conc, $settings['qStep']); + + mysqli_query($conn, "INSERT INTO ingredient_compounds (ing, name, cas, min_percentage, max_percentage) VALUES ('$name','".$formula['ingredient']."','".$ing_data['cas']."','".$conc_p."','".$conc_p."')"); + } + + if(mysqli_query($conn, "INSERT INTO ingredients (name, type, cas, notes) VALUES ('$name','Base','Mixture','Converted from formula $fname')")){ + $response['success'] = ''.$name.' converted to ingredient'; + echo json_encode($response); + } + return; + +} + +//DUPLICATE FORMULA +if($_POST['action'] == 'clone' && $_POST['fid']){ + require_once(__ROOT__.'/func/genFID.php'); + + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $fname = mysqli_real_escape_string($conn, $_POST['fname']); + + $newName = $fname.' - (Copy)'; + $newFid = random_str(40, '1234567890abcdefghijklmnopqrstuvwxyz'); + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM formulasMetaData WHERE name = '$newName'"))){ + $response['error'] = $newName.' already exists, please remove or rename it first!'; + echo json_encode($response); + return; + } + $sql1 = "INSERT INTO formulasMetaData (fid, name, notes, profile, gender, defView, product_name, catClass) SELECT '$newFid', '$newName', notes, profile, gender, defView, '$newName', catClass FROM formulasMetaData WHERE fid = '$fid'"; + $sql2 = "INSERT INTO formulas (fid, name, ingredient, ingredient_id, concentration, dilutant, quantity, notes) SELECT '$newFid', '$newName', ingredient, ingredient_id, concentration, dilutant, quantity, notes FROM formulas WHERE fid = '$fid'"; + + if(mysqli_query($conn, $sql1) && mysqli_query($conn, $sql2)) { + // Fetch the id of the newly inserted record + $nID = mysqli_fetch_array(mysqli_query($conn, "SELECT id FROM formulasMetaData WHERE fid = '$newFid'")); + if($nID){ + $response['success'] = $fname.' cloned as '.$newName.'!'; + } else { + $response['error'] = "Failed to fetch ID of cloned record!"; + echo json_encode($response); + return; + } + } else { + $response['error'] = "Failed to clone formula!"; + echo json_encode($response); + return; + } + echo json_encode($response); + return; +} + +//ADD NEW FORMULA +if($_POST['action'] == 'addFormula'){ + if(empty($_POST['name'])){ + $response['error'] = 'Formula name is required.'; + echo json_encode($response); + return; + } + + if(strlen($_POST['name']) > '100'){ + $response['error'] = 'Formula name is too big. Max 100 chars allowed.'; + echo json_encode($response); + return; + } + + require_once(__ROOT__.'/func/genFID.php'); + + $name = mysqli_real_escape_string($conn, $_POST['name']); + $notes = mysqli_real_escape_string($conn, $_POST['notes']); + $profile = mysqli_real_escape_string($conn, $_POST['profile']); + $catClass = mysqli_real_escape_string($conn, $_POST['catClass']); + $finalType = mysqli_real_escape_string($conn, $_POST['finalType']); + $customer_id = $_POST['customer']?:0; + $fid = random_str(40, '1234567890abcdefghijklmnopqrstuvwxyz'); + + if(mysqli_num_rows(mysqli_query($conn, "SELECT name FROM formulasMetaData WHERE name = '$name'"))){ + $response['error'] = $name.' already exists!'; + }else{ + if(mysqli_query($conn, "INSERT INTO formulasMetaData (fid, name, notes, profile, catClass, finalType, customer_id) VALUES ('$fid', '$name', '$notes', '$profile', '$catClass', '$finalType', '$customer_id')")){ + $last_id = mysqli_insert_id($conn); + $fullver = $product.' '.$ver; + mysqli_query($conn, "INSERT INTO formulasTags (formula_id, tag_name) VALUES ('$last_id','$fullver')"); + $response = array( + "success" => array( + "id" => (int)$last_id, + "msg" => "$name added!", + ) + ); + }else{ + $response['error'] = 'Something went wrong...'.mysqli_error($conn); + } + } + + echo json_encode($response); + return; +} + +//DELETE FORMULA +if($_POST['action'] == 'deleteFormula' && $_POST['fid']){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $fname = mysqli_real_escape_string($conn, $_POST['fname']); + + if($_POST['archiveFormula'] == "true"){ + require_once(__ROOT__.'/libs/fpdf.php'); + require_once(__ROOT__.'/func/genBatchPDF.php'); + require_once(__ROOT__.'/func/ml2L.php'); + + define('FPDF_FONTPATH',__ROOT__.'/fonts'); + + $defCatClass = $settings['defCatClass']; + $arcID = "Archived-".$fname.$fid; + + $rs = genBatchPDF($fid,$arcID,'100','100','100',$defCatClass,$settings['qStep'],$settings['defPercentage'],'formulas'); + + if($rs !== true){ + $response['error'] = 'Error archiving the formula, '.$rs['error']; + echo json_encode($response); + return; + } + + } + + if(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM formulasMetaData WHERE fid = '$fid' AND isProtected = '1'"))){ + $response['error'] = 'Error deleting formula '.$fname.' is protected.'; + echo json_encode($response); + return; + } + + $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT id FROM formulasMetaData WHERE fid = '$fid'")); + + if(mysqli_query($conn, "DELETE FROM formulas WHERE fid = '$fid'")){ + mysqli_query($conn, "DELETE FROM formulasMetaData WHERE fid = '$fid'"); + mysqli_query($conn, "DELETE FROM formulasRevisions WHERE fid = '$fid'"); + mysqli_query($conn, "DELETE FROM formula_history WHERE fid = '".$meta['id']."'"); + mysqli_query($conn, "DELETE FROM formulasTags WHERE formula_id = '".$meta['id']."'"); + mysqli_query($conn, "DELETE FROM makeFormula WHERE fid = '$fid'"); + $response['success'] = 'Formula '.$fname.' deleted!'; + }else{ + $response['error'] = 'Error deleting '.$fname.' formula!'; + } + echo json_encode($response); + return; +} + +//RESET ING IN MAKE FORMULA +if($_POST['action'] == 'makeFormula' && $_POST['undo'] == '1'){ + $q = trim($_POST['originalQuantity']); + $ingID = mysqli_real_escape_string($conn, $_POST['ingID']); + $repName = $_POST['repName']; + + if(mysqli_query($conn, "UPDATE makeFormula SET replacement_id = '0', toAdd = '1', skip = '0', overdose = '0', quantity = '".$_POST['originalQuantity']."' WHERE id = '".$_POST['ID']."'")){ + if(!empty($repName)) { + $msg = $repName."'s quantity reset"; + }else{ + $msg = $_POST['ing']."'s quantity reset"; + } + $response['success'] = $msg; + + if($_POST['resetStock'] == "true"){ + if(!($_POST['supplier'])){ + $response['error'] = 'Please select a supplier'; + echo json_encode($response); + return; + } + $nIngID = $_POST['repID'] ?: $ingID; + mysqli_query($conn, "UPDATE suppliers SET stock = stock + $q WHERE ingID = '$nIngID' AND ingSupplierID = '".$_POST['supplier']."'"); + $response['success'] .= "
Stock increased by ".$q.$settings['mUnit'].""; + } + echo json_encode($response); + } + return; +} + +//MAKE FORMULA +if($_POST['action'] == 'makeFormula' && $_POST['fid'] && $_POST['qr'] && $_POST['id']){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $id = mysqli_real_escape_string($conn, $_POST['id']); + + + if($_POST['repID']) { + $repID = $_POST['repID']; + $ingID = $_POST['repID']; + } else { + $repID = 0; + $ingID = $_POST['ingId']; + } + + $ingredient = mysqli_real_escape_string($conn, $_POST['repName'] ?: $_POST['ing']); + + $notes = mysqli_real_escape_string($conn, $_POST['notes']) ?: "-"; + + $qr = trim($_POST['qr']); + $q = trim($_POST['q']); + + + if(!is_numeric($_POST['q'])){ + $response['error'] = 'Invalid amount value'; + echo json_encode($response); + return; + } + + + if($_POST['updateStock'] == "true"){ + if(!($_POST['supplier'])){ + $response['error'] = 'Please select a supplier'; + echo json_encode($response); + return; + } + $getStock = mysqli_fetch_array(mysqli_query($conn, "SELECT stock,mUnit FROM suppliers WHERE ingID = '$ingID' AND ingSupplierID = '".$_POST['supplier']."'")); + if($getStock['stock'] < $q){ + $w = "

Amount exceeds quantity available in stock (".$getStock['stock'].$getStock['mUnit']."). The maximum available will be deducted from stock

"; + + $q = $getStock['stock']; + } + mysqli_query($conn, "UPDATE suppliers SET stock = stock - $q WHERE ingID = '$ingID' AND ingSupplierID = '".$_POST['supplier']."'"); + $response['success'] .= "
Stock deducted by ".$q.$settings['mUnit'].""; + } + + $q = trim($_POST['q']); //DIRTY HACK - TODO + + if($qr == $q){ + if(mysqli_query($conn, "UPDATE makeFormula SET replacement_id = '$repID', toAdd = '0', notes = '$notes' WHERE fid = '$fid' AND id = '$id'")){ + $response['success'] = $ingredient.' added in the formula.'.$w; + } else { + $response['error'] = mysqli_error($conn); + } + }else{ + $sub_tot = $qr - $q; + if(mysqli_query($conn, "UPDATE makeFormula SET replacement_id = '$repID', quantity='$sub_tot', notes = '$notes' WHERE fid = '$fid' AND id = '$id'")){ + $response['success'] = 'Formula updated'; + } + } + + + if($qr < $q){ + if(mysqli_query($conn, "UPDATE makeFormula SET overdose = '$q' WHERE fid = '$fid' AND id = '$id'")){ + $response['success'] = $_POST['ing'].' is overdosed, '.$q.' added'; + } + } + + if(!mysqli_num_rows(mysqli_query($conn, "SELECT id FROM makeFormula WHERE fid = '$fid' AND toAdd = '1'"))){ + $response['success'] = 'All materials added. You should mark formula as complete now!'; + } + + + echo json_encode($response); + return; +} + + + +//SKIP MATERIAL FROM MAKE FORMULA +if($_POST['action'] == 'skipMaterial' && $_POST['fid'] && $_POST['id']){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $id = mysqli_real_escape_string($conn, $_POST['id']); + $ingID = mysqli_real_escape_string($conn, $_POST['ingId']); + $notes = mysqli_real_escape_string($conn, $_POST['notes']) ?: "-"; + + if(mysqli_query($conn, "UPDATE makeFormula SET skip = '1', notes = '$notes' WHERE fid = '$fid' AND id = '$id'")){ + $response['success'] = $_POST['ing'].' skipped from the formulation'; + } else { + $response['error'] = 'Error skipping the ingredient'; + } + + echo json_encode($response); + return; +} + + + +//MARK COMPLETE +if($_POST['action'] == 'todo' && $_POST['fid'] && $_POST['markComplete']){ + require_once(__ROOT__.'/libs/fpdf.php'); + require_once(__ROOT__.'/func/genBatchID.php'); + require_once(__ROOT__.'/func/genBatchPDF.php'); + require_once(__ROOT__.'/func/ml2L.php'); + + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $total_quantity = mysqli_real_escape_string($conn, $_POST['totalQuantity']); + + define('FPDF_FONTPATH',__ROOT__.'/fonts'); + $defCatClass = $settings['defCatClass']; + + + if(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM makeFormula WHERE fid = '$fid' AND toAdd = '1' AND skip = '0'"))){ + $response['error'] = 'Formula is pending materials to add, cannot be marked as complete.'; + echo json_encode($response); + return; + } + if(mysqli_query($conn,"UPDATE formulasMetaData SET isMade = '1', toDo = '0', madeOn = NOW(), status = '2' WHERE fid = '$fid'")){ + $batchID = genBatchID(); + genBatchPDF($fid,$batchID,$total_quantity,'100',$total_quantity,$defCatClass,$settings['qStep'],$settings['defPercentage'],'makeFormula'); + + mysqli_query($conn, "DELETE FROM makeFormula WHERE fid = '$fid'"); + + $response['success'] = 'Formula is complete'; + } + + echo json_encode($response); + return; +} + + +//TODO ADD FORMULA +if($_POST['action'] == 'todo' && $_POST['fid'] && $_POST['add']){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $fname = mysqli_real_escape_string($conn, $_POST['fname']); + + if(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM formulasMetaData WHERE fid = '$fid' AND toDo = '1'"))){ + $response['error'] = 'Formula '.$fname.' is already scheduled'; + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO makeFormula (fid, name, ingredient, ingredient_id, concentration, dilutant, quantity, originalQuantity, toAdd) SELECT fid, name, ingredient, ingredient_id, concentration, dilutant, quantity, quantity, '1' FROM formulas WHERE fid = '$fid' AND exclude_from_calculation = '0'")){ + + + mysqli_query($conn, "UPDATE formulasMetaData SET toDo = '1', status = '1', isMade = '0', scheduledOn = NOW() WHERE fid = '$fid'"); + $response['success'] = 'Formula '.$fname.' scheduled to make!'; + }else{ + $response['error'] = 'An error occured '.mysqli_error($conn); + } + + echo json_encode($response); + return; +} + +//TODO REMOVE FORMULA +if($_POST['action'] == 'todo' && $_POST['fid'] && $_POST['remove']){ + $fid = mysqli_real_escape_string($conn, $_POST['fid']); + $name = mysqli_real_escape_string($conn, $_POST['name']); + + if(mysqli_query($conn, "DELETE FROM makeFormula WHERE fid = '$fid'")){ + mysqli_query($conn, "UPDATE formulasMetaData SET toDo = '0', status = '0', isMade = '0' WHERE fid = '$fid'"); + $response['success'] = $name.' removed'; + echo json_encode($response); + } + return; +} + +//CART MANAGE +if($_POST['action'] == 'addToCart' && $_POST['material'] && $_POST['quantity']){ + $material = mysqli_real_escape_string($conn, $_POST['material']); + $quantity = mysqli_real_escape_string($conn, $_POST['quantity']); + $purity = mysqli_real_escape_string($conn, $_POST['purity']); + $ingID = mysqli_real_escape_string($conn, $_POST['ingID']); + + $qS = mysqli_fetch_array(mysqli_query($conn, "SELECT ingSupplierID, supplierLink FROM suppliers WHERE ingID = '$ingID'")); + + if(empty($qS['supplierLink'])){ + $response['error'] = $material.' cannot be added to cart as missing supplier info. Please update material supply details first.'; + echo json_encode($response); + return; + } + + if(mysqli_num_rows(mysqli_query($conn,"SELECT id FROM cart WHERE name = '$material'"))){ + if(mysqli_query($conn, "UPDATE cart SET quantity = quantity + '$quantity' WHERE name = '$material'")){ + $response['success'] = 'Additional '.$quantity.$settings['mUnit'].' of '.$material.' added to the cart.'; + } + echo json_encode($response); + return; + } + + if(mysqli_query($conn, "INSERT INTO cart (ingID,name,quantity,purity) VALUES ('$ingID','$material','$quantity','$purity')")){ + $response['success'] = $material.' added to the cart!'; + echo json_encode($response); + return; + } + + return; +} + +if($_POST['action'] == 'removeFromCart' && $_POST['materialId']){ + $materialId = mysqli_real_escape_string($conn, $_POST['materialId']); + + if(mysqli_query($conn, "DELETE FROM cart WHERE id = '$materialId'")){ + $response['success'] = $_POST['materialName'].' removed from cart!'; + echo json_encode($response); + } +} + + +//VIEW BOX BACK LABEL +if($_GET['action'] == 'viewBoxLabel' && $_GET['fid']){ + $fid = $_GET['fid']; + + $q = mysqli_fetch_array(mysqli_query($conn, "SELECT name,product_name FROM formulasMetaData WHERE fid = '".$fid."'")); + $name = $q['name']; + $qIng = mysqli_query($conn, "SELECT ingredient FROM formulas WHERE fid = '".$fid."'"); + + while($ing = mysqli_fetch_array($qIng)){ + $chName = mysqli_fetch_array(mysqli_query($conn, "SELECT chemical_name,name FROM ingredients WHERE name = '".$ing['ingredient']."' AND allergen = '1'")); + + if($qCMP = mysqli_query($conn, "SELECT name FROM ingredient_compounds WHERE ing = '".$ing['ingredient']."' AND toDeclare = '1'")){ + while($cmp = mysqli_fetch_array($qCMP)){ + $allergen[] = $cmp['name']; + } + } + $allergen[] = $chName['chemical_name']?:$chName['name']; + } + $allergen[] = 'Denatured Ethyl Alcohol '.$_GET['carrier'].'% Vol, Fragrance, DPG, Distilled Water'; + + if($_GET['batchID']){ + $bNo = $_GET['batchID']; + }else{ + $bNO = 'N/A'; + } + if($settings['brandName']){ + $brand = $settings['brandName']; + }else{ + $brand = 'PV Pro'; + } + $allergenFinal = implode(", ",array_filter(array_unique($allergen))); + $info = "FOR EXTERNAL USE ONLY. \nKEEP AWAY FROM HEAT AND FLAME. \nKEEP OUT OF REACH OF CHILDREN. \nAVOID SPRAYING IN EYES. \n \nProduction: ".date("d/m/Y")." \nB. NO: ".$bNo." \n$brand"; + + + echo "
";
+	echo "".$name."\n\n";
+	echo 'INGREDIENTS'."\n\n";
+	echo wordwrap ($allergenFinal, 90)."\n\n";
+	echo wordwrap ($info, 50)."\n\n";
+	echo '
'; + + + return; +} diff --git a/core/finished_formula_data.php b/core/finished_formula_data.php index ea4ebcaa..ff16cabc 100644 --- a/core/finished_formula_data.php +++ b/core/finished_formula_data.php @@ -43,19 +43,19 @@ $bottle_id = $_POST['bottle_id']; $concentration = $_POST['concentration']; $carrier_id = $_POST['carrier_id']; -$lid_id = $_POST['lid_id']; +$accessory_id = $_POST['accessory_id']; $bottle = mysqli_fetch_array(mysqli_query($conn, "SELECT price,ml,name FROM bottles WHERE id = '$bottle_id' AND price != 0 ")); $carrier_cost = mysqli_fetch_array(mysqli_query($conn, "SELECT price,size FROM suppliers WHERE ingID = '$carrier_id'")); -if($_POST['lid_id']){ - $lid = mysqli_fetch_array(mysqli_query($conn, "SELECT price,style FROM lids WHERE id = '$lid_id'")); -}else{ - $lid['price'] = 0; - $lid['style'] = 'none'; +if($_POST['accessory_id']){ + if(!$accessory = mysqli_fetch_array(mysqli_query($conn, "SELECT name, price, accessory FROM inventory_accessories WHERE id = '$accessory_id'"))){ + //}else{ + $accessory['price'] = 0; + $accessory['accessory'] = 'none'; + } } - $new_conc = $bottle['ml'] / 100 * $concentration; $carrier = $bottle['ml'] - $new_conc; @@ -177,8 +177,8 @@ $m['carrier_quantity'] = number_format($carrier, $settings['qStep']); $m['carrier_cost'] = (float)$carrier_sub_cost; $m['bottle_quantity'] = (float)$bottle['ml']; -$m['lid_cost'] = (float)$lid['price']; -$m['lid_style'] = (string)$lid['style']; +$m['accessory_cost'] = (float)$accessory['price']; +$m['accessory'] = (string)$accessory['name'].' ('.$accessory['accessory'].')'; $m['batchNo'] = $batchID; $m['total_quantity'] = (float)number_format( array_sum($new_tot) + $carrier,$settings['qStep']); $m['quantity_unit'] = (string)$settings['mUnit']; @@ -186,7 +186,7 @@ $m['carrier_concentration'] = (float)number_format($carrier ?? 100 * 100 / $bottle['ml'],$settings['qStep']); $m['sub_cost'] = (float)number_format(array_sum($tot),$settings['qStep']); $m['bottle_cost'] = (float)number_format($bottle['price'],$settings['qStep']); -$m['total_cost'] = (float)number_format(array_sum($tot) + $lid['price'] + $carrier_sub_cost + $bottle['price'], $settings['qStep']); +$m['total_cost'] = (float)number_format(array_sum($tot) + $accessory['price'] + $carrier_sub_cost + $bottle['price'], $settings['qStep']); $m['cat_class'] = (string)$defCatClass; diff --git a/core/list_lid_data.php b/core/list_accessory_data.php similarity index 63% rename from core/list_lid_data.php rename to core/list_accessory_data.php index c68cd1ee..299d7c9e 100644 --- a/core/list_lid_data.php +++ b/core/list_accessory_data.php @@ -5,11 +5,11 @@ require_once(__ROOT__.'/inc/opendb.php'); require_once(__ROOT__.'/inc/settings.php'); -$row = $_POST['start']?:0; -$limit = $_POST['length']?:10; +$row = $_POST['start'] ?: 0; +$limit = $_POST['length'] ?: 10; -$order_by = $_POST['order_by']?:'style'; -$order = $_POST['order_as']?:'ASC'; +$order_by = $_POST['order_by'] ?: 'name'; +$order = $_POST['order_as'] ?: 'ASC'; $extra = "ORDER BY ".$order_by." ".$order; $defCatClass = $settings['defCatClass']; @@ -18,30 +18,30 @@ $s = trim($_POST['search']['value']); if($s != ''){ - $f = "WHERE 1 AND (style LIKE '%".$s."%')"; + $f = "WHERE 1 AND (name LIKE '%".$s."%')"; } -$q = mysqli_query($conn, "SELECT * FROM lids $f $extra LIMIT $row, $limit"); +$q = mysqli_query($conn, "SELECT * FROM inventory_accessories $f $extra LIMIT $row, $limit"); while($res = mysqli_fetch_array($q)){ $rs[] = $res; } foreach ($rs as $rq) { $r['id'] = (int)$rq['id']; - $r['style'] = (string)$rq['style']?:'N/A'; - $r['price'] = (double)$rq['price']?:'N/A'; - $r['colour'] = (string)$rq['colour']; - $r['supplier'] = (string)$rq['supplier']?:'N/A'; - $r['supplier_link'] = (string)$rq['supplier_link']?:'N/A'; - $r['pieces'] = (int)$rq['pieces']?:0; + $r['name'] = (string)$rq['name'] ?: 'N/A'; + $r['price'] = (double)$rq['price'] ?: 'N/A'; + $r['accessory'] = (string)$rq['accessory']; + $r['supplier'] = (string)$rq['supplier'] ?: 'N/A'; + $r['supplier_link'] = (string)$rq['supplier_link'] ?: 'N/A'; + $r['pieces'] = (int)$rq['pieces'] ?: 0; $photo = mysqli_fetch_array(mysqli_query($conn,"SELECT docData FROM documents WHERE type = '5' AND ownerID = '".$r['id']."'")); $r['photo'] = (string)$photo['docData']?:'data:image/png;base64,'.$defImage; $rx[]=$r; } -$total = mysqli_fetch_assoc(mysqli_query($conn,"SELECT COUNT(id) AS entries FROM lids")); -$filtered = mysqli_fetch_assoc(mysqli_query($conn,"SELECT COUNT(id) AS entries FROM lids ".$f)); +$total = mysqli_fetch_assoc(mysqli_query($conn,"SELECT COUNT(id) AS entries FROM inventory_accessories")); +$filtered = mysqli_fetch_assoc(mysqli_query($conn,"SELECT COUNT(id) AS entries FROM inventory_accessories ".$f)); $response = array( "draw" => (int)$_POST['draw'], diff --git a/core/list_formula_data.php b/core/list_formula_data.php index 2e718aab..17dc92f0 100644 --- a/core/list_formula_data.php +++ b/core/list_formula_data.php @@ -21,12 +21,12 @@ } */ $filters = []; -if (!empty($_GET['filter']) && (!empty($_GET['profile']) || !empty($_GET['sex']))) { +if (!empty($_GET['filter']) && (!empty($_GET['profile']) || !empty($_GET['gender']))) { if (!empty($_GET['profile'])) { $filters[] = "profile = '" . mysqli_real_escape_string($conn, $_GET['profile']) . "'"; } - if (!empty($_GET['sex'])) { - $filters[] = "sex = '" . mysqli_real_escape_string($conn, $_GET['sex']) . "'"; + if (!empty($_GET['gender'])) { + $filters[] = "gender = '" . mysqli_real_escape_string($conn, $_GET['gender']) . "'"; } } @@ -40,7 +40,7 @@ $Query = " SELECT - id, fid, name, product_name, isProtected, profile, sex, created, + id, fid, name, product_name, isProtected, profile, gender, created, catClass, isMade, madeOn, status, rating, revision, (SELECT updated FROM formulas WHERE fid = formulasMetaData.fid ORDER BY updated DESC LIMIT 1) AS updated, (SELECT COUNT(dilutant) FROM formulas WHERE fid = formulasMetaData.fid) AS ingredients @@ -66,9 +66,9 @@ 'name' => (string)($formula['name'] ?: 'Unnamed'), 'isProtected' => (int)($formula['isProtected'] ?: 0), 'profile' => (string)($formula['profile'] ?: 'N/A'), - 'sex' => (string)($formula['sex'] ?: 'unisex'), + 'gender' => (string)($formula['gender'] ?: 'unisex'), 'created' => (string)$formula['created'], - 'updated' => (string)($formula['updated'] ?: '-'), + 'updated' => (string)($formula['updated'] ?: '0000-00-00 00:00:00'), 'catClass' => (string)($formula['catClass'] ?: 'N/A'), 'ingredients' => (int)($formula['ingredients'] ?: 0), 'isMade' => (int)($formula['isMade'] ?: 0), diff --git a/css/vault.css b/css/vault.css index 7622f129..557a31a0 100755 --- a/css/vault.css +++ b/css/vault.css @@ -1109,7 +1109,7 @@ table#tdDataPending.dataTable thead:hover { } */ .pv-transition td { - background-color: var(--bs-secondary-bg); + background-color: var(--bs-warning-border-subtle); } .schedule_details { diff --git a/db/pvault.sql b/db/pvault.sql index 18982826..592b1d80 100755 --- a/db/pvault.sql +++ b/db/pvault.sql @@ -62,7 +62,7 @@ CREATE TABLE `formulas` ( `quantity` decimal(10,4) DEFAULT NULL, `exclude_from_summary` INT NOT NULL DEFAULT '0', `exclude_from_calculation` INT NOT NULL DEFAULT '0', - `notes` varchar(255) COLLATE utf8_general_ci DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, `created` datetime NOT NULL DEFAULT current_timestamp(), `updated` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; @@ -100,7 +100,7 @@ CREATE TABLE `formulasMetaData` ( `product_name` varchar(255) DEFAULT NULL, `fid` varchar(255) COLLATE utf8_general_ci NOT NULL, `profile` varchar(255) COLLATE utf8_general_ci DEFAULT NULL, - `sex` varchar(255) COLLATE utf8_general_ci DEFAULT 'unisex', + `gender` varchar(255) COLLATE utf8_general_ci DEFAULT 'unisex', `notes` text COLLATE utf8_general_ci DEFAULT NULL, `created` timestamp NOT NULL DEFAULT current_timestamp(), `isProtected` INT NULL DEFAULT '0', @@ -282,13 +282,13 @@ INSERT INTO `ingTypes` (`id`, `name`) VALUES (6, 'Solvent'), (7, 'Base'); -CREATE TABLE `lids` ( +CREATE TABLE `inventory_accessories` ( `id` int(11) NOT NULL, - `style` varchar(255) COLLATE utf8_general_ci NOT NULL, - `colour` varchar(255) COLLATE utf8_general_ci DEFAULT NULL, + `name` varchar(255) NOT NULL, + `accessory` varchar(255) NOT NULL, `price` DOUBLE DEFAULT 0, - `supplier` varchar(255) COLLATE utf8_general_ci DEFAULT NULL, - `supplier_link` varchar(255) COLLATE utf8_general_ci DEFAULT NULL, + `supplier` varchar(255) NOT NULL, + `supplier_link` varchar(255) NOT NULL, `pieces` int(11) NOT NULL DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; @@ -444,8 +444,8 @@ ALTER TABLE `ingSuppliers` ALTER TABLE `ingTypes` ADD PRIMARY KEY (`id`); -ALTER TABLE `lids` - ADD PRIMARY KEY (`id`); +ALTER TABLE `inventory_accessories` ADD PRIMARY KEY (`id`); +ALTER TABLE `inventory_accessories` ADD UNIQUE(`name`); ALTER TABLE `settings` ADD PRIMARY KEY (`id`); @@ -457,11 +457,11 @@ ALTER TABLE `users` ALTER TABLE `ingredient_compounds` ADD PRIMARY KEY (`id`); -ALTER TABLE `bottles` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `bottles` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `bottles` ADD UNIQUE(`name`); -ALTER TABLE `customers` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `customers` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `customers` ADD UNIQUE(`name`); ALTER TABLE `formulas` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; @@ -484,14 +484,13 @@ ALTER TABLE `ingredients` ALTER TABLE `ingStrength` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; -ALTER TABLE `ingSuppliers` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `ingSuppliers` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `ingSuppliers` ADD UNIQUE(`name`); ALTER TABLE `ingTypes` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; -ALTER TABLE `lids` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `inventory_accessories` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; ALTER TABLE `settings` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; @@ -616,7 +615,7 @@ CREATE TABLE `formulasRevisions` ( CREATE TABLE `formula_history` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `fid` varchar(255) NOT NULL, + `fid` int(11) NOT NULL, `ing_id` INT NOT NULL DEFAULT '0', `change_made` text COLLATE utf8_general_ci NOT NULL, `date_time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), @@ -633,7 +632,7 @@ CREATE TABLE `formulaCategories` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; -INSERT INTO `formulaCategories` (`id`, `name`, `cname`, `type`) VALUES (NULL, 'Oriental', 'oriental', 'profile'), (NULL, 'Woody', 'woody', 'profile'), (NULL, 'Floral', 'floral', 'profile'), (NULL, 'Fresh', 'fresh', 'profile'), (NULL, 'Unisex', 'unisex', 'sex'), (NULL, 'Men', 'men', 'sex'), (NULL, 'Women', 'women', 'sex'); +INSERT INTO `formulaCategories` (`id`, `name`, `cname`, `type`) VALUES (NULL, 'Oriental', 'oriental', 'profile'), (NULL, 'Woody', 'woody', 'profile'), (NULL, 'Floral', 'floral', 'profile'), (NULL, 'Fresh', 'fresh', 'profile'), (NULL, 'Unisex', 'unisex', 'gender'), (NULL, 'Men', 'men', 'gender'), (NULL, 'Women', 'women', 'gender'); CREATE TABLE `synonyms` ( `id` INT NOT NULL , `ing` VARCHAR(255) NOT NULL, `cid` INT(10) NULL DEFAULT NULL , `synonym` VARCHAR(255) NOT NULL , `source` VARCHAR(255) NULL DEFAULT NULL, `created_at` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE = InnoDB; @@ -799,6 +798,8 @@ INSERT INTO `backup_provider` (`id`, `credentials`, `provider`, `schedule`, `ena CREATE TABLE `inventory_compounds` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `description` TEXT NOT NULL , `batch_id` VARCHAR(255) NOT NULL DEFAULT '-' , `size` DOUBLE NOT NULL DEFAULT '0' , `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , `owner_id` INT NOT NULL DEFAULT '0' , `location` VARCHAR(255) NOT NULL , `label_info` TEXT NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_general_ci; +ALTER TABLE `inventory_compounds` ADD UNIQUE(`name`); + CREATE TABLE `sds_data` ( `id` INT NOT NULL AUTO_INCREMENT , `product_name` VARCHAR(255) NOT NULL , `product_use` VARCHAR(255) NOT NULL , `country` VARCHAR(255) NOT NULL DEFAULT 'United Kingdom' , `language` VARCHAR(255) NOT NULL DEFAULT 'English' , `product_type` VARCHAR(255) NOT NULL DEFAULT 'Substance' , `state_type` VARCHAR(255) NOT NULL DEFAULT 'Liquid' , `supplier_id` INT NOT NULL , `docID` INT NOT NULL, `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_general_ci; CREATE TABLE `ingredient_safety_data` ( diff --git a/db/schema.ver b/db/schema.ver index 675364cd..d7213f31 100644 --- a/db/schema.ver +++ b/db/schema.ver @@ -1 +1 @@ -11.9 +12.0 diff --git a/db/updates/update_11.9-12.0.sql b/db/updates/update_11.9-12.0.sql new file mode 100644 index 00000000..7bf8b516 --- /dev/null +++ b/db/updates/update_11.9-12.0.sql @@ -0,0 +1,12 @@ +RENAME TABLE `lids` TO `inventory_accessories`; +ALTER TABLE `inventory_accessories` CHANGE `style` `name` VARCHAR(255) NOT NULL; +ALTER TABLE `inventory_accessories` CHANGE `colour` `accessory` VARCHAR(255) NOT NULL; +ALTER TABLE `inventory_accessories` CHANGE `supplier_link` `supplier_link` VARCHAR(255) NOT NULL; +ALTER TABLE `inventory_accessories` CHANGE `supplier` `supplier` VARCHAR(255) NOT NULL; +ALTER TABLE `inventory_accessories` ADD UNIQUE(`name`); +ALTER TABLE `inventory_compounds` ADD UNIQUE(`name`); +ALTER TABLE `bottles` ADD UNIQUE(`name`); +ALTER TABLE `customers` ADD UNIQUE(`name`); +ALTER TABLE `ingSuppliers` ADD UNIQUE(`name`); +ALTER TABLE `formulasMetaData` CHANGE `sex` `gender` VARCHAR(255) NULL DEFAULT 'unisex'; +UPDATE `formulaCategories` SET type = 'gender' WHERE type = 'sex'; \ No newline at end of file diff --git a/func/convertTime.php b/func/convertTime.php new file mode 100644 index 00000000..31bf4f99 --- /dev/null +++ b/func/convertTime.php @@ -0,0 +1,19 @@ + $hours, + 'minutes' => $remainingMinutes, + ]; +} + +?> \ No newline at end of file diff --git a/inc/opendb.php b/inc/opendb.php index 33e4f2d6..0241379a 100755 --- a/inc/opendb.php +++ b/inc/opendb.php @@ -8,7 +8,8 @@ if(strtoupper(getenv('PLATFORM')) === "CLOUD"){ if(!getenv('DB_HOST') || !getenv('DB_USER') || !getenv('DB_PASS') || !getenv('DB_NAME')){ - echo 'Required parameters not found. Please make sure your provided all the required variables as per documentation'; + $error_msg = 'Required parameters not found. Please make sure your provided all the required variables as per documentation'; + require_once(__ROOT__.'/pages/error.php'); exit; } @@ -16,13 +17,13 @@ $dbuser = getenv('DB_USER'); $dbpass = getenv('DB_PASS'); $dbname = getenv('DB_NAME'); - + $tmp_path = getenv('TMP_PATH') ?: "/tmp/"; $allowed_ext = getenv('FILE_EXT') ?: "pdf, doc, docx, xls, csv, xlsx, png, jpg, jpeg, gif"; $max_filesize = getenv('MAX_FILE_SIZE') ?: "4194304"; $bkparams = getenv('DB_BACKUP_PARAMETERS') ?: '--column-statistics=1'; - $sysLogsEnabled = strtoupper(getenv('SYS_LOGS')) === 'ENABLED' || getenv('SYS_LOGS') === '1'; + $session_timeout = getenv('SYS_TIMEOUT') ?: 1800; $conn = dbConnect($dbhost, $dbuser, $dbpass, $dbname); @@ -32,10 +33,18 @@ } -function dbConnect($dbhost, $dbuser, $dbpass, $dbname){ - $conn = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname) or die ('Unable to connect to '.$dbname.' database on '. $dbhost.' host. Please make sure the database exists and user '.$dbuser.' has full permissions on it.'); - mysqli_select_db($conn, $dbname); - mysqli_set_charset($conn, "utf8"); - return $conn; +function dbConnect(string $dbhost, string $dbuser, string $dbpass, string $dbname) { + mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); + try { + $conn = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname); + mysqli_set_charset($conn, "utf8"); + return $conn; + } catch (mysqli_sql_exception $e) { + $error_msg = "Database connection error: " . $e->getMessage(); + require_once(__ROOT__.'/pages/error.php'); + error_log($error_msg); + return false; // Return false on failure + } } + ?> diff --git a/inc/sec.php b/inc/sec.php index 7cbf5deb..a405d099 100755 --- a/inc/sec.php +++ b/inc/sec.php @@ -17,6 +17,27 @@ session_start(); } +if(strtoupper(getenv('PLATFORM')) === "CLOUD"){ + $session_timeout = getenv('SYS_TIMEOUT') ?: 1800; +} else { + require_once(__ROOT__.'/inc/config.php'); +} + +if (isset($_SESSION['parfumvault_time'])) { + if ((time() - $_SESSION['parfumvault_time']) > $session_timeout) { + session_unset(); + session_destroy(); + $response['auth']['error'] = true; + $response['auth']['msg'] = 'You have been automatically logged out due to inactivity of '.$session_timeout.' seconds. Please log in again. '; + echo json_encode($response); + return; + } else { + $_SESSION['parfumvault_time'] = time(); + } +} else { + $_SESSION['parfumvault_time'] = time(); +} + if(!isset($_SESSION['parfumvault'])){ if($_GET['do']){ $redirect = '?do='.$_GET['do']; diff --git a/index.php b/index.php index c6653e70..bd81b310 100755 --- a/index.php +++ b/index.php @@ -6,19 +6,12 @@ if(file_exists(__ROOT__.'/inc/config.php') == FALSE && !getenv('DB_HOST') && !getenv('DB_USER') && !getenv('DB_PASS') && !getenv('DB_NAME')){ session_destroy(); - header('Location: login.php'); + header('Location: /login.php'); } require_once(__ROOT__.'/inc/product.php'); require_once(__ROOT__.'/inc/opendb.php'); - -require_once(__ROOT__.'/func/checkIng.php'); -require_once(__ROOT__.'/func/searchIFRA.php'); -require_once(__ROOT__.'/func/formatBytes.php'); -require_once(__ROOT__.'/func/countElement.php'); - require_once(__ROOT__.'/func/countPending.php'); require_once(__ROOT__.'/func/countCart.php'); -require_once(__ROOT__.'/func/pvOnline.php'); require_once(__ROOT__.'/func/getIngSupplier.php'); require_once(__ROOT__.'/inc/settings.php'); @@ -211,7 +204,7 @@ function chkUpdate() { @@ -279,7 +272,7 @@ function chkUpdate() { } elseif ($_GET['do'] == 'statistics') { require_once(__ROOT__.'/pages/statistics.php'); } elseif ($_GET['do'] == 'IFRA') { - require_once(__ROOT__.'/pages/IFRA.php'); + require_once(__ROOT__.'/pages/views/regulatory/IFRA.php'); } elseif ($_GET['do'] == 'listFormulas') { ?>
@@ -301,13 +294,9 @@ function chkUpdate() { } elseif ($_GET['do'] == 'genFinishedProduct') { require_once(__ROOT__.'/pages/genFinishedProduct.php'); } elseif ($_GET['do'] == 'bottles') { - require_once(__ROOT__.'/pages/bottles.php'); - } elseif ($_GET['do'] == 'addBottle') { - require_once(__ROOT__.'/pages/addBottle.php'); - } elseif ($_GET['do'] == 'lids') { - require_once(__ROOT__.'/pages/lids.php'); - } elseif ($_GET['do'] == 'addLid') { - require_once(__ROOT__.'/pages/addLid.php'); + require_once(__ROOT__.'/pages/views/inventory/bottles.php'); + } elseif ($_GET['do'] == 'accessories') { + require_once(__ROOT__.'/pages/views/inventory/accessories.php'); } elseif ($_GET['do'] == 'batches') { require_once(__ROOT__.'/pages/views/formula/batches.php'); } elseif ($_GET['do'] == 'scheduledFormulas') { @@ -319,11 +308,11 @@ function chkUpdate() { } elseif ($_GET['do'] == 'sellFormula') { require_once(__ROOT__.'/pages/sellFormula.php'); } elseif ($_GET['do'] == 'customers') { - require_once(__ROOT__.'/pages/customers.php'); + require_once(__ROOT__.'/pages/views/inventory/customers.php'); } elseif ($_GET['do'] == 'compareFormulas') { require_once(__ROOT__.'/pages/compareFormulas.php'); } elseif ($_GET['do'] == 'compounds') { - require_once(__ROOT__.'/pages/compounds.php'); + require_once(__ROOT__.'/pages/views/inventory/compounds.php'); } elseif ($_GET['do'] == 'genSDS') { require_once(__ROOT__.'/pages/views/regulatory/listSDS.php'); } else { diff --git a/js/fullformula.view.js b/js/fullformula.view.js index ed8d6c0d..b559af63 100644 --- a/js/fullformula.view.js +++ b/js/fullformula.view.js @@ -6,18 +6,22 @@ * Full formula js helpers */ -//MULTIPLY - DIVIDE +//SCALE FORMULA SIMPLE $('.manageQuantity').click(function() { $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { - do: 'scale', + action: 'simpleScale', scale: $(this).attr('data-action'), formula: myFID, }, + dataType: 'json', success: function (data) { reload_formula_data(); + $('#toast-title').html('' + data.success); + $('.toast-header').removeClass().addClass('toast-header alert-success'); + $('.toast').toast('show'); }, error: function (xhr, status, error) { $('#toast-title').html(' An ' + status + ' occurred, check server logs for more info. '+ error); @@ -27,33 +31,43 @@ $('.manageQuantity').click(function() { }); }); -//AMOUNT TO MAKE +//SCALE FORMULA ADVANCED $('#amount_to_make').on('click', '[id*=amountToMake]', function () { + $('#amountToMakeMsg').html(''); if($("#sg").val().trim() == '' ){ $('#sg').focus(); - $('#amountToMakeMsg').html('
Error: all fields required!
'); + $('#amountToMakeMsg').html('
Specific gravity is required
'); }else if($("#totalAmount").val().trim() == '' ){ $('#totalAmount').focus(); - $('#amountToMakeMsg').html('
Error: all fields required!
'); + $('#amountToMakeMsg').html('
New amount is required
'); }else{ + $('#amountToMakeMsg').html('
Scaling the formula...
'); + $('#amountToMake').prop('disabled', true); $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', cache: false, data: { + action: 'advancedScale', fid: myFID, SG: $("#sg").val(), amount: $("#totalAmount").val(), }, + dataType: 'json', success: function (data) { - $('#amountToMakeMsg').html(data); - $('#amount_to_make').modal('toggle'); - reload_formula_data(); + if( data.success ){ + $('#amountToMakeMsg').html(''); + $('#amount_to_make').modal('toggle'); + $('#amountToMake').prop('disabled', false); + reload_formula_data(); + } else { + $('#amountToMakeMsg').html('
' + data.error + '
'); + $('#amountToMake').prop('disabled', false); + } }, error: function (xhr, status, error) { - $('#toast-title').html(' An ' + status + ' occurred, check server logs for more info. '+ error); - $('.toast-header').removeClass().addClass('toast-header alert-danger'); - $('.toast').toast('show'); + $('#amountToMakeMsg').html('
An ' + status + ' occurred, check server logs for more info. ' + error + '
'); + $('#amountToMake').prop('disabled', false); } }); } @@ -67,7 +81,7 @@ $('#create_accord').on('click', '[id*=createAccord]', function () { $('#accordMsg').html('
Error: Accord name required!
'); }else{ $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', cache: false, data: { @@ -101,7 +115,7 @@ $('#conv_ingredient').on('click', '[id*=conv2ing]', function () { $('#cnvMsg').html('
Error: Ingredient name required!
'); }else{ $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', cache: false, data: { @@ -131,7 +145,7 @@ $('#conv_ingredient').on('click', '[id*=conv2ing]', function () { //Clone $('#cloneMe').click(function() { $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { action: "clone", @@ -161,7 +175,7 @@ $.ajax({ //Add in Schedule $('#schedule_to_make').on('click', '[id*=addTODO]', function () { $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { action: 'todo', @@ -203,7 +217,7 @@ $('#formula').on('click', '[id*=cCAS]', function () { $('#replaceIng').on('click', '[id*=replaceConfirm]', function () { $.ajax({ - url: "/pages/manageFormula.php" , + url: "/core/core.php" , type: 'POST', data: { action: "repIng", @@ -361,7 +375,7 @@ $("#formula").on("click", ".open-replace-dialog", function () { $('#mrgIng').on('click', '[id*=mergeConfirm]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { merge: "true", @@ -448,7 +462,7 @@ $("#formula").on("click", ".open-merge-dialog", function () { $('#manage-quantity').on('click', '[id*=quantityConfirm]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { updateQuantity: "true", @@ -660,4 +674,4 @@ function update_bar(){ }); }; -update_bar(); \ No newline at end of file +update_bar(); diff --git a/js/import.IFRA.js b/js/import.IFRA.js index 54b8e4b3..af507d80 100644 --- a/js/import.IFRA.js +++ b/js/import.IFRA.js @@ -66,7 +66,7 @@ $('#btnRestoreIFRA').click(function() { } $.ajax({ - url: '/pages/operations.php?action=restoreIFRA', + url: '/core/core.php?action=restoreIFRA', type: 'POST', data: fd, contentType: false, diff --git a/js/import.accessories.js b/js/import.accessories.js new file mode 100644 index 00000000..8e54d030 --- /dev/null +++ b/js/import.accessories.js @@ -0,0 +1,121 @@ +/* +IMPORT JSON +*/ + +function uploadProgressHandler(event) { + $("#loaded_n_total").html("Uploaded " + event.loaded + " bytes of " + event.total); + var percent = (event.loaded / event.total) * 100; + var progress = Math.round(percent); + $("#uploadProgressBar").html(progress + " %"); + $("#uploadProgressBar").css("width", progress + "%"); +} + +function loadHandler(event) { + $("#status").html(event.target.responseText); + $(".progress").hide(); + //$("#btnImportAccessories").hide(); + $("#jsonFile").val(''); + $('#btnCloseBK').prop('value', 'Close'); + $("#uploadProgressBar").css("width", "0%"); +} + +function errorHandler(event) { + $("#JSRestMsg").html('
Upload failed
'); +} + +function abortHandler(event) { + $("#JSRestMsg").html('
Upload Aborted
'); +} + +$(".progress").hide(); +$("#btnImportAccessories").prop("disabled", true); +$("#jsonFile").change(function(){ + var allowedTypes = ['application/json']; + var file = this.files[0]; + var fileType = file.type; + var fileSize = file.size; + $("#JSRestMsg").html(''); + var fileSizePHP = $("#raw").data("size"); + if(!allowedTypes.includes(fileType)){ + $("#JSRestMsg").html('
Invalid file selected. Please select a JSON file exported from PV.
'); + $("#jsonFile").val(''); + $("#btnImportAccessories").prop("disabled", true); + return false; + } + + if (fileSize > fileSizePHP){ + $("#JSRestMsg").html('
File size ('+formatBytes(fileSize)+') is exceeding your server file upload limit '+ formatBytes(fileSizePHP)+'
'); + $("#jsonFile").val(''); + $("#btnImportAccessories").prop("disabled", true); + return false; + } + + $("#btnImportAccessories").prop("disabled", false); + $('#btnImportAccessories').prop('value', 'Import'); +}); + + +$('#btnImportAccessories').click(function() { + + event.preventDefault(); + var fd = new FormData(); + var files = $('#jsonFile')[0].files; + + if(files.length > 0 ){ + fd.append('jsonFile',files[0]); + } + + $.ajax({ + url: '/core/core.php?action=importAccessories', + type: 'POST', + data: fd, + contentType: false, + processData: false, + cache: false, + dataType: 'json', + xhr: function () { + var xhr = new window.XMLHttpRequest(); + xhr.upload.addEventListener("progress", uploadProgressHandler, false ); + xhr.addEventListener("load", loadHandler, false); + xhr.addEventListener("error", errorHandler, false); + xhr.addEventListener("abort", abortHandler, false); + $(".progress").show(); + $("#btnImportAccessories").prop("disabled", true); + $('#btnImportAccessories').prop('value', 'Please wait...'); + return xhr; + }, + success: function (data) { + if(data.success){ + var msg = '
'+data.success+'
'; + $("#btnImportAccessories").hide(); + $("#backupArea").css('display', 'none'); + $('#tdDataAccessories').DataTable().ajax.reload(null, true); + + }else if(data.error){ + var msg = '
'+data.error+'
'; + $("#btnImportAccessories").show(); + $("#btnImportAccessories").prop("disabled", false); + $('#btnImportAccessories').prop('value', 'Import'); + } + $('#btnImportAccessories').prop('value', 'Import'); + $("#btnImportAccessories").prop("disabled", false); + $('#JSRestMsg').html(msg); + }, + error: function (xhr, status, error) { + $('#JSRestMsg').html('
An ' + status + ' occurred, check server logs for more info. ' + error + '
'); + $("#btnImportAccessories").show(); + $("#btnImportAccessories").prop("disabled", false); + $('#btnImportAccessories').prop('value', 'Import'); + } + + }); +}); + +function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} diff --git a/js/import.bottles.js b/js/import.bottles.js new file mode 100644 index 00000000..17c42c7a --- /dev/null +++ b/js/import.bottles.js @@ -0,0 +1,121 @@ +/* +IMPORT JSON +*/ + +function uploadProgressHandler(event) { + $("#loaded_n_total").html("Uploaded " + event.loaded + " bytes of " + event.total); + var percent = (event.loaded / event.total) * 100; + var progress = Math.round(percent); + $("#uploadProgressBar").html(progress + " %"); + $("#uploadProgressBar").css("width", progress + "%"); +} + +function loadHandler(event) { + $("#status").html(event.target.responseText); + $(".progress").hide(); + //$("#btnImportBottles").hide(); + $("#jsonFile").val(''); + $('#btnCloseBK').prop('value', 'Close'); + $("#uploadProgressBar").css("width", "0%"); +} + +function errorHandler(event) { + $("#JSRestMsg").html('
Upload failed
'); +} + +function abortHandler(event) { + $("#JSRestMsg").html('
Upload Aborted
'); +} + +$(".progress").hide(); +$("#btnImportBottles").prop("disabled", true); +$("#jsonFile").change(function(){ + var allowedTypes = ['application/json']; + var file = this.files[0]; + var fileType = file.type; + var fileSize = file.size; + $("#JSRestMsg").html(''); + var fileSizePHP = $("#raw").data("size"); + if(!allowedTypes.includes(fileType)){ + $("#JSRestMsg").html('
Invalid file selected. Please select a JSON file exported from PV.
'); + $("#jsonFile").val(''); + $("#btnImportBottles").prop("disabled", true); + return false; + } + + if (fileSize > fileSizePHP){ + $("#JSRestMsg").html('
File size ('+formatBytes(fileSize)+') is exceeding your server file upload limit '+ formatBytes(fileSizePHP)+'
'); + $("#jsonFile").val(''); + $("#btnImportBottles").prop("disabled", true); + return false; + } + + $("#btnImportBottles").prop("disabled", false); + $('#btnImportBottles').prop('value', 'Import'); +}); + + +$('#btnImportBottles').click(function() { + + event.preventDefault(); + var fd = new FormData(); + var files = $('#jsonFile')[0].files; + + if(files.length > 0 ){ + fd.append('jsonFile',files[0]); + } + + $.ajax({ + url: '/core/core.php?action=importBottles', + type: 'POST', + data: fd, + contentType: false, + processData: false, + cache: false, + dataType: 'json', + xhr: function () { + var xhr = new window.XMLHttpRequest(); + xhr.upload.addEventListener("progress", uploadProgressHandler, false ); + xhr.addEventListener("load", loadHandler, false); + xhr.addEventListener("error", errorHandler, false); + xhr.addEventListener("abort", abortHandler, false); + $(".progress").show(); + $("#btnImportBottles").prop("disabled", true); + $('#btnImportBottles').prop('value', 'Please wait...'); + return xhr; + }, + success: function (data) { + if(data.success){ + var msg = '
'+data.success+'
'; + $("#btnImportBottles").hide(); + $("#backupArea").css('display', 'none'); + $('#tdDataBottles').DataTable().ajax.reload(null, true); + + }else if(data.error){ + var msg = '
'+data.error+'
'; + $("#btnImportBottles").show(); + $("#btnImportBottles").prop("disabled", false); + $('#btnImportBottles').prop('value', 'Import'); + } + $('#btnImportBottles').prop('value', 'Import'); + $("#btnImportBottles").prop("disabled", false); + $('#JSRestMsg').html(msg); + }, + error: function (xhr, status, error) { + $('#JSRestMsg').html('
An ' + status + ' occurred, check server logs for more info. ' + error + '
'); + $("#btnImportBottles").show(); + $("#btnImportBottles").prop("disabled", false); + $('#btnImportBottles').prop('value', 'Import'); + } + + }); +}); + +function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} diff --git a/js/import.categories.js b/js/import.categories.js index f75c9ed7..7f668069 100644 --- a/js/import.categories.js +++ b/js/import.categories.js @@ -66,7 +66,7 @@ $('#btnRestoreCategories').click(function() { } $.ajax({ - url: '/pages/operations.php?action=importCategories', + url: '/core/core.php?action=importCategories', type: 'POST', data: fd, contentType: false, diff --git a/js/import.compounds.js b/js/import.compounds.js index e6867257..7af022c5 100644 --- a/js/import.compounds.js +++ b/js/import.compounds.js @@ -1,5 +1,5 @@ /* -IMPORT INGREDIENTS JSON +IMPORT JSON */ function uploadProgressHandler(event) { @@ -54,7 +54,6 @@ $("#jsonFile").change(function(){ $('#btnImportCompounds').prop('value', 'Import'); }); -//RESTORE Ingredients $('#btnImportCompounds').click(function() { event.preventDefault(); @@ -66,7 +65,7 @@ $('#btnImportCompounds').click(function() { } $.ajax({ - url: '/pages/operations.php?action=importCompounds', + url: '/core/core.php?action=importCompounds', type: 'POST', data: fd, contentType: false, @@ -74,28 +73,25 @@ $('#btnImportCompounds').click(function() { cache: false, dataType: 'json', xhr: function () { - var xhr = new window.XMLHttpRequest(); - xhr.upload.addEventListener("progress", - uploadProgressHandler, - false - ); - xhr.addEventListener("load", loadHandler, false); - xhr.addEventListener("error", errorHandler, false); - xhr.addEventListener("abort", abortHandler, false); - $(".progress").show(); - $("#btnImportCompounds").prop("disabled", true); - $('#btnImportCompounds').prop('value', 'Please wait...'); - return xhr; - }, + var xhr = new window.XMLHttpRequest(); + xhr.upload.addEventListener("progress", uploadProgressHandler, false); + xhr.addEventListener("load", loadHandler, false); + xhr.addEventListener("error", errorHandler, false); + xhr.addEventListener("abort", abortHandler, false); + $(".progress").show(); + $("#btnImportCompounds").prop("disabled", true); + $('#btnImportCompounds').prop('value', 'Please wait...'); + return xhr; + }, success: function (data) { if(data.success){ var msg = '
'+data.success+'
'; $("#btnImportCompounds").hide(); $("#backupArea").css('display', 'none'); - + $('#tdDataCompounds').DataTable().ajax.reload(null, true); }else if(data.error){ - var msg = '
'+data.error+'
'; + var msg = '
'+data.error+'
'; $("#btnImportCompounds").show(); $("#btnImportCompounds").prop("disabled", false); $('#btnImportCompounds').prop('value', 'Import'); @@ -103,6 +99,12 @@ $('#btnImportCompounds').click(function() { $('#btnImportCompounds').prop('value', 'Import'); $("#btnImportCompounds").prop("disabled", false); $('#JSRestMsg').html(msg); + }, + error: function (xhr, status, error) { + var msg = '
An ' + status + ' occurred, check server logs for more info. ' + error + '
'; + $("#btnImportCompounds").show(); + $("#btnImportCompounds").prop("disabled", false); + $('#btnImportCompounds').prop('value', 'Import'); } }); diff --git a/js/import.customers.js b/js/import.customers.js new file mode 100644 index 00000000..a21f5b79 --- /dev/null +++ b/js/import.customers.js @@ -0,0 +1,121 @@ +/* +IMPORT JSON +*/ + +function uploadProgressHandler(event) { + $("#loaded_n_total").html("Uploaded " + event.loaded + " bytes of " + event.total); + var percent = (event.loaded / event.total) * 100; + var progress = Math.round(percent); + $("#uploadProgressBar").html(progress + " %"); + $("#uploadProgressBar").css("width", progress + "%"); +} + +function loadHandler(event) { + $("#status").html(event.target.responseText); + $(".progress").hide(); + //$("#btnImportCustomers").hide(); + $("#jsonFile").val(''); + $('#btnCloseBK').prop('value', 'Close'); + $("#uploadProgressBar").css("width", "0%"); +} + +function errorHandler(event) { + $("#JSRestMsg").html('
Upload failed
'); +} + +function abortHandler(event) { + $("#JSRestMsg").html('
Upload Aborted
'); +} + +$(".progress").hide(); +$("#btnImportCustomers").prop("disabled", true); +$("#jsonFile").change(function(){ + var allowedTypes = ['application/json']; + var file = this.files[0]; + var fileType = file.type; + var fileSize = file.size; + $("#JSRestMsg").html(''); + var fileSizePHP = $("#raw").data("size"); + if(!allowedTypes.includes(fileType)){ + $("#JSRestMsg").html('
Invalid file selected. Please select a JSON file exported from PV.
'); + $("#jsonFile").val(''); + $("#btnImportCustomers").prop("disabled", true); + return false; + } + + if (fileSize > fileSizePHP){ + $("#JSRestMsg").html('
File size ('+formatBytes(fileSize)+') is exceeding your server file upload limit '+ formatBytes(fileSizePHP)+'
'); + $("#jsonFile").val(''); + $("#btnImportCustomers").prop("disabled", true); + return false; + } + + $("#btnImportCustomers").prop("disabled", false); + $('#btnImportCustomers').prop('value', 'Import'); +}); + + +$('#btnImportCustomers').click(function() { + + event.preventDefault(); + var fd = new FormData(); + var files = $('#jsonFile')[0].files; + + if(files.length > 0 ){ + fd.append('jsonFile',files[0]); + } + + $.ajax({ + url: '/core/core.php?action=importCustomers', + type: 'POST', + data: fd, + contentType: false, + processData: false, + cache: false, + dataType: 'json', + xhr: function () { + var xhr = new window.XMLHttpRequest(); + xhr.upload.addEventListener("progress", uploadProgressHandler, false ); + xhr.addEventListener("load", loadHandler, false); + xhr.addEventListener("error", errorHandler, false); + xhr.addEventListener("abort", abortHandler, false); + $(".progress").show(); + $("#btnImportCustomers").prop("disabled", true); + $('#btnImportCustomers').prop('value', 'Please wait...'); + return xhr; + }, + success: function (data) { + if(data.success){ + var msg = '
'+data.success+'
'; + $("#btnImportCustomers").hide(); + $("#backupArea").css('display', 'none'); + $('#tdDataCustomers').DataTable().ajax.reload(null, true); + + }else if(data.error){ + var msg = '
'+data.error+'
'; + $("#btnImportCustomers").show(); + $("#btnImportCustomers").prop("disabled", false); + $('#btnImportCustomers').prop('value', 'Import'); + } + $('#btnImportCustomers').prop('value', 'Import'); + $("#btnImportCustomers").prop("disabled", false); + $('#JSRestMsg').html(msg); + }, + error: function (xhr, status, error) { + $('#JSRestMsg').html('
An ' + status + ' occurred, check server logs for more info. ' + error + '
'); + $("#btnImportCustomers").show(); + $("#btnImportCustomers").prop("disabled", false); + $('#btnImportCustomers').prop('value', 'Import'); + } + + }); +}); + +function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} diff --git a/js/import.formulas.js b/js/import.formulas.js index c92fb28c..846d5141 100644 --- a/js/import.formulas.js +++ b/js/import.formulas.js @@ -66,7 +66,7 @@ $('#btnRestoreFormulas').click(function() { } $.ajax({ - url: '/pages/operations.php?action=restoreFormulas', + url: '/core/core.php?action=restoreFormulas', type: 'POST', data: fd, contentType: false, diff --git a/js/import.ingredients.js b/js/import.ingredients.js index abf30a6e..3c0456b8 100644 --- a/js/import.ingredients.js +++ b/js/import.ingredients.js @@ -66,7 +66,7 @@ $('#btnRestoreIngredients').click(function() { } $.ajax({ - url: '/pages/operations.php?action=restoreIngredients', + url: '/core/core.php?action=restoreIngredients', type: 'POST', data: fd, contentType: false, diff --git a/js/import.making.js b/js/import.making.js index 8d566b45..1fea4108 100644 --- a/js/import.making.js +++ b/js/import.making.js @@ -66,7 +66,7 @@ $('#btnRestoreMaking').click(function() { } $.ajax({ - url: '/pages/operations.php?action=importMaking', + url: '/core/core.php?action=importMaking', type: 'POST', data: fd, contentType: false, diff --git a/js/import.suppliers.js b/js/import.suppliers.js new file mode 100644 index 00000000..ff00fb2b --- /dev/null +++ b/js/import.suppliers.js @@ -0,0 +1,121 @@ +/* +IMPORT JSON +*/ + +function uploadProgressHandler(event) { + $("#loaded_n_total").html("Uploaded " + event.loaded + " bytes of " + event.total); + var percent = (event.loaded / event.total) * 100; + var progress = Math.round(percent); + $("#uploadProgressBar").html(progress + " %"); + $("#uploadProgressBar").css("width", progress + "%"); +} + +function loadHandler(event) { + $("#status").html(event.target.responseText); + $(".progress").hide(); + //$("#btnImportSuppliers").hide(); + $("#jsonFile").val(''); + $('#btnCloseBK').prop('value', 'Close'); + $("#uploadProgressBar").css("width", "0%"); +} + +function errorHandler(event) { + $("#JSRestMsg").html('
Upload failed
'); +} + +function abortHandler(event) { + $("#JSRestMsg").html('
Upload Aborted
'); +} + +$(".progress").hide(); +$("#btnImportSuppliers").prop("disabled", true); +$("#jsonFile").change(function(){ + var allowedTypes = ['application/json']; + var file = this.files[0]; + var fileType = file.type; + var fileSize = file.size; + $("#JSRestMsg").html(''); + var fileSizePHP = $("#raw").data("size"); + if(!allowedTypes.includes(fileType)){ + $("#JSRestMsg").html('
Invalid file selected. Please select a JSON file exported from PV.
'); + $("#jsonFile").val(''); + $("#btnImportSuppliers").prop("disabled", true); + return false; + } + + if (fileSize > fileSizePHP){ + $("#JSRestMsg").html('
File size ('+formatBytes(fileSize)+') is exceeding your server file upload limit '+ formatBytes(fileSizePHP)+'
'); + $("#jsonFile").val(''); + $("#btnImportSuppliers").prop("disabled", true); + return false; + } + + $("#btnImportSuppliers").prop("disabled", false); + $('#btnImportSuppliers').prop('value', 'Import'); +}); + + +$('#btnImportSuppliers').click(function() { + + event.preventDefault(); + var fd = new FormData(); + var files = $('#jsonFile')[0].files; + + if(files.length > 0 ){ + fd.append('jsonFile',files[0]); + } + + $.ajax({ + url: '/core/core.php?action=importSuppliers', + type: 'POST', + data: fd, + contentType: false, + processData: false, + cache: false, + dataType: 'json', + xhr: function () { + var xhr = new window.XMLHttpRequest(); + xhr.upload.addEventListener("progress", uploadProgressHandler, false ); + xhr.addEventListener("load", loadHandler, false); + xhr.addEventListener("error", errorHandler, false); + xhr.addEventListener("abort", abortHandler, false); + $(".progress").show(); + $("#btnImportSuppliers").prop("disabled", true); + $('#btnImportSuppliers').prop('value', 'Please wait...'); + return xhr; + }, + success: function (data) { + if(data.success){ + var msg = '
'+data.success+'
'; + $("#btnImportSuppliers").hide(); + $("#backupArea").css('display', 'none'); + $('#tdIngSupData').DataTable().ajax.reload(null, true); + + }else if(data.error){ + var msg = '
'+data.error+'
'; + $("#btnImportSuppliers").show(); + $("#btnImportSuppliers").prop("disabled", false); + $('#btnImportSuppliers').prop('value', 'Import'); + } + $('#btnImportSuppliers').prop('value', 'Import'); + $("#btnImportSuppliers").prop("disabled", false); + $('#JSRestMsg').html(msg); + }, + error: function (xhr, status, error) { + $('#JSRestMsg').html('
An ' + status + ' occurred, check server logs for more info. ' + error + '
'); + $("#btnImportSuppliers").show(); + $("#btnImportSuppliers").prop("disabled", false); + $('#btnImportSuppliers').prop('value', 'Import'); + } + + }); +}); + +function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} diff --git a/js/makeFormula.js b/js/makeFormula.js index 119666ef..e2774db9 100644 --- a/js/makeFormula.js +++ b/js/makeFormula.js @@ -174,7 +174,7 @@ function formatSuppliersSelection (supplierData) { //UPDATE AMOUNT $('#addedToFormula').click(function() { $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { action: "makeFormula", @@ -217,7 +217,7 @@ function formatSuppliersSelection (supplierData) { className : "btn-warning", callback: function (){ $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { action: "todo", @@ -259,7 +259,7 @@ function formatSuppliersSelection (supplierData) { //SKIP ADD $('#skippedFromFormula').click(function() { $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { action: "skipMaterial", @@ -292,7 +292,7 @@ function formatSuppliersSelection (supplierData) { //ADD TO CART $('#tdDataPending').on('click', '[id*=addToCart]', function () { $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { action: "addToCart", @@ -386,4 +386,4 @@ function formatSuppliersSelection (supplierData) { }); -}); \ No newline at end of file +}); diff --git a/js/mgmIngredient.js b/js/mgmIngredient.js index 640da273..1f2b8696 100644 --- a/js/mgmIngredient.js +++ b/js/mgmIngredient.js @@ -215,7 +215,7 @@ function fetch_reps(){ //Clone $('#cloneIng').on('click', '[id*=cloneME]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { action: 'clone', @@ -274,7 +274,7 @@ $('#genDOC').on('click', '[id*=generateDOC]', function () { //Rename $('#renameIng').on('click', '[id*=renameME]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { action: 'rename', @@ -357,4 +357,4 @@ function fetch_qrc(){ } }); }; -fetch_qrc(); \ No newline at end of file +fetch_qrc(); diff --git a/js/rating.js b/js/rating.js index 4931b44b..5f6f3110 100644 --- a/js/rating.js +++ b/js/rating.js @@ -15,10 +15,10 @@ function initRating(container){ if(cur == '1' && score == '1'){ score = 0; } - $.post('/pages/manageFormula.php', + $.post('/core/core.php', { update_rating: 1, fid: fid, score: score } ); //reload_formulas_data(); } }); -} \ No newline at end of file +} diff --git a/js/settings.backup.js b/js/settings.backup.js index daf021d5..9eb59bfa 100644 --- a/js/settings.backup.js +++ b/js/settings.backup.js @@ -66,7 +66,7 @@ $('#btnRestore').click(function() { } $.ajax({ - url: '/pages/operations.php?restore=db_bk', + url: '/core/core.php?restore=db_bk', type: 'POST', data: fd, contentType: false, diff --git a/js/sys-upgrade.js b/js/sys-upgrade.js index 2fe933c3..369cbd61 100644 --- a/js/sys-upgrade.js +++ b/js/sys-upgrade.js @@ -5,7 +5,7 @@ $('#dbUpBtn').click(function() { $('#dbBkBtn').hide(); $('#dbUpOk').hide(); $.ajax({ - url: '/pages/operations.php', + url: '/core/core.php', type: 'GET', data: { 'do': "db_update" @@ -29,4 +29,4 @@ $('#dbUpBtn').click(function() { }, }); -}); \ No newline at end of file +}); diff --git a/js/validate-session.js b/js/validate-session.js index 22dffa51..ac644180 100644 --- a/js/validate-session.js +++ b/js/validate-session.js @@ -1,9 +1,11 @@ function session_checking() { $.post("/core/ajax-session.php", function(data) { - if(data == "-1"){ - //alert("Your session has been expired!"); + const response = JSON.parse(data); + + if (response.session_status === false) { location.reload(); } + }); } -var validateSession = setInterval(session_checking, 5000); \ No newline at end of file +var validateSession = setInterval(session_checking, 5000); diff --git a/logout.php b/logout.php index bd664bd6..3cf034b4 100644 --- a/logout.php +++ b/logout.php @@ -1,7 +1,18 @@ diff --git a/openshift/README.md b/openshift/README.md new file mode 100644 index 00000000..2ef29b62 --- /dev/null +++ b/openshift/README.md @@ -0,0 +1,20 @@ +## Deploy Perfumers Vault with MariaDB and phpMyAdmin + + +Project structure: +``` +. +├── pvault-ocp.yaml +└── README.md +``` + + +The manifest will create pods for the pv app using the latest image tag, mariadb and phpmyadmin + + +## Deploy in openshift via cli + +``` +$ oc apply -f pvault-ocp.yaml +``` + diff --git a/openshift/pvault-ocp.yaml b/openshift/pvault-ocp.yaml new file mode 100644 index 00000000..b3ed669e --- /dev/null +++ b/openshift/pvault-ocp.yaml @@ -0,0 +1,221 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: pvault +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + com.jbparfum.service: db-data + name: db-data + namespace: pvault +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + com.jbparfum.service: phpmyadmin + name: phpmyadmin + namespace: pvault +spec: + replicas: 1 + selector: + matchLabels: + com.jbparfum.service: phpmyadmin + template: + metadata: + labels: + com.jbparfum.service: phpmyadmin + spec: + containers: + - env: + - name: DB_HOST + value: pvdb + image: globaldyne/phpmyadmin:cloud + name: phpmyadmin + ports: + - containerPort: 8000 + protocol: TCP + restartPolicy: Always +--- +apiVersion: v1 +kind: Service +metadata: + labels: + com.jbparfum.service: phpmyadmin + name: phpmyadmin + namespace: pvault +spec: + ports: + - name: "9000" + port: 9000 + targetPort: 8000 + selector: + com.jbparfum.service: phpmyadmin +--- +apiVersion: v1 +kind: Service +metadata: + + labels: + com.jbparfum.service: pvault + name: pvault + namespace: pvault +spec: + ports: + - name: "8000" + port: 8000 + targetPort: 8000 + selector: + com.jbparfum.service: pvault +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + com.jbparfum.service: pvault + name: pvault + namespace: pvault +spec: + replicas: 1 + selector: + matchLabels: + com.jbparfum.service: pvault + template: + metadata: + labels: + com.jbparfum.service: pvault + spec: + containers: + - env: + - name: DB_BACKUP_PARAMETERS + value: --column-statistics=1 + - name: DB_HOST + value: pvdb + - name: DB_NAME + value: pvault + - name: DB_PASS + value: pvault + - name: DB_USER + value: pvault + - name: FILE_EXT + value: pdf, doc, docx, xls, csv, xlsx, png, jpg, jpeg, gif + - name: MAX_FILE_SIZE + value: "4194304" + - name: PLATFORM + value: CLOUD + - name: SYS_LOGS + value: ENABLED + - name: TMP_PATH + value: /tmp/ + image: globaldyne/perfumersvault:latest + name: pvault + ports: + - containerPort: 8000 + protocol: TCP + restartPolicy: Always +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + com.jbparfum.service: pvdb + name: pvdb + namespace: pvault +spec: + replicas: 1 + selector: + matchLabels: + com.jbparfum.service: pvdb + strategy: + type: Recreate + template: + metadata: + labels: + com.jbparfum.service: pvdb + spec: + containers: + - args: + - --default-authentication-plugin=mysql_native_password + - --innodb-flush-method=fsync + env: + - name: MYSQL_DATABASE + value: pvault + - name: MYSQL_PASSWORD + value: pvault + - name: MYSQL_ROOT_PASSWORD + value: pvault + - name: MYSQL_USER + value: pvault + image: mariadb:10.5 + name: pvdb + ports: + - containerPort: 3306 + protocol: TCP + volumeMounts: + - mountPath: /var/lib/mysql + name: db-data + restartPolicy: Always + volumes: + - name: db-data + persistentVolumeClaim: + claimName: db-data +--- +apiVersion: v1 +kind: Service +metadata: + labels: + com.jbparfum.service: pvdb + name: pvdb + namespace: pvault +spec: + ports: + - name: "3306" + port: 3306 + targetPort: 3306 + selector: + com.jbparfum.service: pvdb +--- +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: pvault + namespace: pvault + labels: + com.jbparfum.service: pvault +spec: + to: + kind: Service + name: pvault + tls: + insecureEdgeTerminationPolicy: Redirect + port: + targetPort: '8000' + alternateBackends: +--- +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: phpmyadmin + namespace: pvault + labels: + com.jbparfum.service: phpmyadmin +spec: + to: + kind: Service + name: phpmyadmin + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect + destinationCACertificate: '' + path: / + port: + targetPort: '9000' + alternateBackends: [] diff --git a/pages/cart.php b/pages/cart.php index 92668538..98bb6514 100644 --- a/pages/cart.php +++ b/pages/cart.php @@ -136,7 +136,7 @@ function reload_cart_data() { className : "btn-danger", callback: function (){ $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'POST', data: { action: "removeFromCart", @@ -176,4 +176,4 @@ className : "btn-secondary", }); }); //END DOC - \ No newline at end of file + diff --git a/pages/dashboard.php b/pages/dashboard.php index e1b8e2b7..42825990 100755 --- a/pages/dashboard.php +++ b/pages/dashboard.php @@ -215,9 +215,9 @@
diff --git a/pages/editLid.php b/pages/editLid.php deleted file mode 100644 index 77823fdb..00000000 --- a/pages/editLid.php +++ /dev/null @@ -1,134 +0,0 @@ - - - -
-
-
-
-
-
-
-

- Style - -

-

- Colour - -

-

- Price - -

-

- Pieces in stock - -

-

- Supplier - -

-

- Supplier URL - -

-

- Image - -

-
- - - \ No newline at end of file diff --git a/pages/editUser.php b/pages/editUser.php index a3c81190..92e78162 100755 --- a/pages/editUser.php +++ b/pages/editUser.php @@ -21,7 +21,7 @@
- +
@@ -79,7 +79,7 @@ $('#save-profile').click(function() { $.ajax({ - url: '/pages/update_settings.php', + url: '/core/core.php', type: 'POST', data: { update_user_profile: 1, @@ -90,14 +90,14 @@ dataType: 'json', success: function (data) { if(data.success){ - var msg = '
'+data.success+'
'; + var msg = '
'+data.success+'
'; }else if( data.error){ - var msg = '
'+data.error+'
'; + var msg = '
'+data.error+'
'; } $('#msgU').html(msg); }, error: function (xhr, status, error) { - $('#msgU').html('
An ' + status + ' occurred, check server logs for more info. '+ error + '
'); + $('#msgU').html('
An ' + status + ' occurred, check server logs for more info. '+ error + '
'); } }); }); @@ -110,7 +110,7 @@ fd.append('avatar',files[0]); } $.ajax({ - url: '/pages/update_settings.php?update_user_avatar=1', + url: '/core/core.php?update_user_avatar=1', type: 'POST', data: fd, contentType: false, @@ -119,18 +119,18 @@ dataType: 'json', success: function (data) { if(data.success){ - var msg = '
'+data.success.msg+'
'; + var msg = '
'+data.success.msg+'
'; $('#profile_pic').html(''); }else if( data.error){ - var msg = '
'+data.error+'
'; + var msg = '
'+data.error+'
'; } $('#msgU').html(msg); }, error: function (xhr, status, error) { - $('#msgU').html('
An ' + status + ' occurred, check server logs for more info. '+ error + '
'); + $('#msgU').html('
An ' + status + ' occurred, check server logs for more info. '+ error + '
'); } }); }); }); - \ No newline at end of file + diff --git a/pages/error.php b/pages/error.php new file mode 100644 index 00000000..5fbfd5cd --- /dev/null +++ b/pages/error.php @@ -0,0 +1,32 @@ + + + + + + + + Error + + + + + + + + + + +
+
+
+
Error...
+
+

It looks like you found a glitch in the matrix...

+ Back to Dashboard +
+
+
+ + \ No newline at end of file diff --git a/pages/export.php b/pages/export.php index 630ef9fb..837cfa2e 100644 --- a/pages/export.php +++ b/pages/export.php @@ -6,22 +6,22 @@ require_once(__ROOT__.'/inc/settings.php'); require_once(__ROOT__.'/inc/product.php'); -//EXPORT LIDS JSON -if($_GET['format'] == 'json' && $_GET['kind'] == 'lids'){ +//EXPORT ACCESSORIES JSON +if($_GET['format'] == 'json' && $_GET['kind'] == 'accessories'){ - if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM lids")))){ - $msg['error'] = 'No lids found to export.'; + if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM inventory_accessories")))){ + $msg['error'] = 'No accessories found to export'; echo json_encode($msg); return; } $count = 0; - $q = mysqli_query($conn, "SELECT * FROM lids"); + $q = mysqli_query($conn, "SELECT * FROM inventory_accessories"); while($res = mysqli_fetch_assoc($q)){ $r['id'] = (int)$res['id']; - $r['style'] = (string)$res['style']; - $r['colour'] = (string)$res['colour']; + $r['name'] = (string)$res['name']; + $r['accessory'] = (string)$res['accessory']; $r['price'] = (double)$res['price']; $r['currency'] = (string)$settings['currency']; $r['supplier'] = (string)$res['supplier']; @@ -35,13 +35,13 @@ $vd['product'] = $product; $vd['version'] = $ver; - $vd['lids'] = $count; + $vd['inventory_accessories'] = $count; $vd['timestamp'] = date('d/m/Y H:i:s'); - $result['lids'] = $ic; + $result['inventory_accessories'] = $ic; $result['pvMeta'] = $vd; - header('Content-disposition: attachment; filename=lids.json'); + header('Content-disposition: attachment; filename=accessories_inventory.json'); header('Content-type: application/json'); echo json_encode($result, JSON_PRETTY_PRINT); return; @@ -49,14 +49,11 @@ } - - - //EXPORT BOTTLES JSON if($_GET['format'] == 'json' && $_GET['kind'] == 'bottles'){ if(empty(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM bottles")))){ - $msg['error'] = 'No bottles found to export.'; + $msg['error'] = 'No bottles found to export'; echo json_encode($msg); return; } @@ -72,6 +69,7 @@ $r['currency'] = (string)$settings['currency']; $r['height'] = (double)$res['height']; $r['width'] = (double)$res['width']; + $r['weight'] = (double)$res['weight']; $r['diameter'] = (double)$res['diameter']; $r['diameter'] = (double)$res['diameter']; $r['supplier'] = (string)$res['supplier']; @@ -88,13 +86,13 @@ $vd['product'] = $product; $vd['version'] = $ver; - $vd['bottles'] = $count; + $vd['inventory_bottles'] = $count; $vd['timestamp'] = date('d/m/Y H:i:s'); - $result['bottles'] = $ic; + $result['inventory_bottles'] = $ic; $result['pvMeta'] = $vd; - header('Content-disposition: attachment; filename=bottles.json'); + header('Content-disposition: attachment; filename=bottles_inventory.json'); header('Content-type: application/json'); echo json_encode($result, JSON_PRETTY_PRINT); return; @@ -131,13 +129,13 @@ $vd['product'] = $product; $vd['version'] = $ver; - $vd['customers'] = $count; + $vd['inventory_customers'] = $count; $vd['timestamp'] = date('d/m/Y H:i:s'); - $result['customers'] = $ic; + $result['inventory_customers'] = $ic; $result['pvMeta'] = $vd; - header('Content-disposition: attachment; filename=customers.json'); + header('Content-disposition: attachment; filename=customers_inventory.json'); header('Content-type: application/json'); echo json_encode($result, JSON_PRETTY_PRINT); return; @@ -189,7 +187,6 @@ } - //EXPORT INGREDIENTS CSV if($_GET['format'] == 'csv' && $_GET['kind'] == 'ingredients'){ $defCatClass = $settings['defCatClass']; @@ -203,7 +200,7 @@ } header('Content-Type: text/csv; charset=utf-8'); - header('Content-Disposition: attachment; filename='.$_GET['kind'].'.csv'); + header('Content-Disposition: attachment; filename=inventory_'.$_GET['kind'].'.csv'); $output = fopen('php://output', 'w'); fputcsv($output, array('Name', 'INCI', 'CAS', 'FEMA', 'Type', 'Strength', 'Profile', 'Physical State', 'Allergen', 'Odor Description', 'Top Note Impact', 'Heart Note Impact', 'Base Note Impact')); @@ -216,35 +213,6 @@ return; } -//EXPORT SUPPLIERS CSV -if($_GET['format'] == 'csv' && $_GET['kind'] == 'suppliers'){ - $r = mysqli_query($conn, "SELECT id,name,address,po,country,telephone,url,email,platform,price_tag_start,price_tag_end,add_costs,price_per_size,notes,min_ml,min_gr FROM ingSuppliers"); - - $res = array(); - if (mysqli_num_rows($r) > 0) { - while ($row = mysqli_fetch_assoc($r)) { - $mt = mysqli_fetch_array(mysqli_query($conn, "SELECT COUNT(id) AS mt FROM suppliers WHERE ingSupplierID = '".$row['id']."'")); - - unset($row['id']); - $row['materials'] = $mt['mt']; - $res[] = $row; - - } - } - - header('Content-Type: text/csv; charset=utf-8'); - header('Content-Disposition: attachment; filename='.$_GET['kind'].'.csv'); - $output = fopen('php://output', 'w'); - fputcsv($output, array('Name', 'Address', 'PO', 'Country', 'Telephone', 'URL', 'Email', 'Platform', 'Price Tag Start', 'Price Tag End', 'Added Costs', 'Price Per Size', 'Notes', 'Min ml', 'Min gr', 'Materials')); - - if (count($res) > 0) { - foreach ($res as $row) { - fputcsv($output, $row); - } - } - - return; -} //EXPORT INGREDIENTS JSON if($_GET['format'] == 'json' && $_GET['kind'] == 'ingredients'){ @@ -593,13 +561,13 @@ $vd['product'] = $product; $vd['version'] = $ver; - $vd['suppliers'] = $suppliers_count; + $vd['inventory_suppliers'] = $suppliers_count; $vd['timestamp'] = date('d/m/Y H:i:s'); - $result['suppliers'] = $sup; + $result['inventory_suppliers'] = $sup; $result['pvMeta'] = $vd; - header('Content-disposition: attachment; filename=suppliers.json'); + header('Content-disposition: attachment; filename=suppliers_inventory.json'); header('Content-type: application/json'); echo json_encode($result, JSON_PRETTY_PRINT); return; diff --git a/pages/formula.php b/pages/formula.php index 15249bae..c30c5d28 100755 --- a/pages/formula.php +++ b/pages/formula.php @@ -1,36 +1,37 @@ @@ -46,8 +47,15 @@ }
- -
+ +
@@ -83,9 +91,7 @@
-
- Formula Image -
+
Loading
@@ -282,7 +288,7 @@ diff --git a/pages/views/formula/attachments.php b/pages/views/formula/attachments.php index 440818bd..2dfa2567 100644 --- a/pages/views/formula/attachments.php +++ b/pages/views/formula/attachments.php @@ -47,7 +47,8 @@ language: { loadingRecords: ' ', processing: 'Loading...', - emptyTable: 'No attachments found.', + zeroRecords: '
Nothing found
', + emptyTable: '
No attachments found
', search: '', searchPlaceholder: 'Search by name...', }, @@ -103,22 +104,27 @@ function actions(data, type, row){ }; $('#tdAttachments').editable({ - container: 'body', - selector: 'a.name', - type: 'POST', - url: "/pages/update_data.php?ingDoc=update&ingID=", - title: 'Attachment name', + container: 'body', + selector: 'a.name', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + url: "/core/core.php?action=updateDocument&ingID=", + title: 'Attachment name', }); $('#tdAttachments').editable({ - container: 'body', - selector: 'a.notes', - type: 'POST', - url: "/pages/update_data.php?ingDoc=update&ingID=", - title: 'Notes', + container: 'body', + selector: 'a.notes', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + url: "/core/core.php?action=updateDocument&ingID=", + title: 'Notes', }); - $('#tdAttachments').on('click', '[id*=dDel]', function () { var d = {}; d.ID = $(this).attr('data-id'); @@ -132,18 +138,21 @@ function actions(data, type, row){ label : "Remove", className : "btn-danger", callback: function (){ - - $.ajax({ - url: '/pages/update_data.php', + $.ajax({ + url: '/core/core.php', type: 'GET', data: { - doc: 'delete', + action: 'deleteDocument', id: d.ID, ownerID: '' }, - dataType: 'html', + dataType: 'json', success: function (data) { - reload_doc_data(); + if( data.success){ + reload_doc_data(); + } else { + $('#doc_inf').html('
x' + response.error + '
'); + } }, error: function (xhr, status, error) { $('#toast-title').html(' An ' + status + ' occurred, check server logs for more info. '+ error); @@ -223,7 +232,17 @@ className : "btn-secondary", function reload_doc_data() { $('#tdAttachments').DataTable().ajax.reload(null, true); }; - + + function extrasShow() { + $('[rel=tip]').tooltip({ + html: true, + boundary: "window", + overflow: "auto", + container: "body", + delay: {"show": 100, "hide": 0}, + }); + } + }); diff --git a/pages/views/formula/batches.php b/pages/views/formula/batches.php index 3420f333..1ce207e8 100644 --- a/pages/views/formula/batches.php +++ b/pages/views/formula/batches.php @@ -139,7 +139,7 @@ function reload_data() { className : "btn-danger", callback: function (){ $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { action: 'batch', @@ -182,4 +182,4 @@ className : "btn-secondary", }); //END DOC - \ No newline at end of file + diff --git a/pages/views/formula/finishedProduct.php b/pages/views/formula/finishedProduct.php index c032df1f..39168728 100644 --- a/pages/views/formula/finishedProduct.php +++ b/pages/views/formula/finishedProduct.php @@ -61,10 +61,10 @@ - Lid - + Accessory + - - + @@ -177,7 +177,7 @@ var id = ""; var bottle_id = ""; var carrier_id = ""; -var lid_id = ""; +var accessory_id = ""; var concentration = ""; var defCatClass = ""; var supplier_id = ""; @@ -253,7 +253,7 @@ id: id, bottle_id: $("#bottle_id").val(), carrier_id: $("#carrier_id").val(), - lid_id: $("#lid_id").val(), + accessory_id: $("#accessory_id").val(), concentration: $("#concentration").val(), defCatClass: $("#defCatClass").val(), supplier_id: $("#supplier_id").val(), @@ -280,8 +280,8 @@ $('#sub-total-quantity').text(response.meta['sub_total_quantity'] + response.meta['quantity_unit']); $('#carrier-quantity').text(response.meta['carrier_quantity'] + response.meta['quantity_unit']); $('#bottle-quantity').text(response.meta['bottle_quantity'] + response.meta['quantity_unit']); - $('#lid-cost').html(response.meta['currency'] + response.meta['lid_cost']); - $('#lid-style').text(response.meta['lid_style']); + $('#accessory-cost').html(response.meta['currency'] + response.meta['accessory_cost']); + $('#accessory').text(response.meta['accessory']); if(response.meta['batchNo']){ $('#batch-no').html('' + response.meta['batchNo'] + ''); @@ -388,7 +388,7 @@ function createAlertBox(response) { const action = "viewBoxLabel"; - const url = "/pages/manageFormula.php?action="+ action + "&batchID=" + batchNo +"&fid=" + fid + "&carrier=" + carrier_concentration +"&download=text"; + const url = "/core/core.php?action="+ action + "&batchID=" + batchNo +"&fid=" + fid + "&carrier=" + carrier_concentration +"&download=text"; $.get(url) .then(data => { diff --git a/pages/views/formula/getFormMeta.php b/pages/views/formula/getFormMeta.php index 1fc55017..c61b5d6c 100644 --- a/pages/views/formula/getFormMeta.php +++ b/pages/views/formula/getFormMeta.php @@ -55,20 +55,18 @@ -
-
Some of the changes require the page to be reloaded to appear properly. Please remember to refresh your browser if your changes not automatically appear.
-
+
- +
- +
@@ -156,8 +154,8 @@
@@ -193,46 +191,64 @@ $('[rel=tip]').tooltip({placement: 'right'}); $('#formula_metadata').editable({ - container: 'body', - selector: 'a.name', - url: "/pages/update_data.php?action=rename&fid=", - title: 'Name', - mode: 'inline', - ajaxOptions: { - dataType: 'json' - }, - validate: function(value){ - if($.trim(value) == ''){ - return 'This field is required'; - } - }, - success: function(response) { - if(response.success){ - $("#getFormMetaLabel").html(response.msg); - }else{ - msg = '
x' + response.error + '
'; - } - $('#set_msg').html(msg); + container: 'body', + selector: 'a.name', + url: "/core/core.php?action=rename&fid=", + title: 'Name', + mode: 'inline', + ajaxOptions: { + dataType: 'json' + }, + validate: function(value){ + if($.trim(value) == ''){ + return 'This field is required'; + } + }, + success: function(response) { + if(response.success){ + $("#getFormMetaLabel").html(response.msg); + $("#formula_name").html(response.msg); + $('#set_msg').html(''); + }else{ + $('#set_msg').html('
x' + response.error + '
'); + } }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); - } - - }); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); + } + }); $('#formula_metadata').editable({ container: 'body', selector: 'a.notes', emptytext: 'None', - url: "/pages/update_data.php?formulaMeta=", + url: "/core/core.php?formulaMeta=", title: 'Notes', - mode: 'inline' + mode: 'inline', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + $('#formula_desc').html( $('#notes').text() ); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#formula_metadata').editable({ container: 'body', selector: 'a.product_name', - url: "/pages/update_data.php?formulaMeta=", + url: "/core/core.php?formulaMeta=", title: 'Product Name', mode: 'inline', emptytext: 'None', @@ -245,7 +261,7 @@ } }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); @@ -253,7 +269,7 @@ $("#isProtected").change(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'GET', data: { protect: '', @@ -268,14 +284,14 @@ } }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); $("#defView").change(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { formulaSettings: true, @@ -293,14 +309,14 @@ $('#set_msg').html(msg); }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); $("#profile").change(function() { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: 'POST', data: { formulaSettings: true, @@ -318,7 +334,7 @@ $('#set_msg').html(msg); }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); @@ -326,12 +342,12 @@ $("#gender").change(function() { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: 'POST', data: { formulaSettings: true, fid: '', - set: 'sex', + set: 'gender', val: $("#gender").find(":selected").val(), }, dataType: 'json', @@ -344,7 +360,7 @@ $('#set_msg').html(msg); }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); @@ -352,7 +368,7 @@ $("#catClass").change(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { formulaSettings: true, @@ -370,14 +386,14 @@ $('#set_msg').html(msg); }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); $("#finalType").change(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { formulaSettings: true, @@ -395,14 +411,14 @@ $('#set_msg').html(msg); }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); $("#status").change(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { formulaSettings: true, @@ -415,12 +431,12 @@ if(response.success){ msg = '
x' + response.success + '
'; }else{ - msg = '
x' + response.error + '
'; + msg = '
x' + response.error + '
'; } $('#set_msg').html(msg); }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); @@ -428,7 +444,7 @@ $("#customer").change(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { formulaSettings: true, @@ -441,12 +457,12 @@ if(response.success){ msg = '
x' + response.success + '
'; }else{ - msg = '
x' + response.error + '
'; + msg = '
x' + response.error + '
'; } $('#set_msg').html(msg); }, error: function (xhr, status, error) { - $('#set_msg').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); + $('#set_msg').html('
An error occurred, check server logs for more info. '+ error +'
'); } }); }); @@ -454,7 +470,7 @@ $("#pic_upload").click(function(){ - $("#upload_resp").html(' \ No newline at end of file +
diff --git a/pages/views/formula/viewSummary.php b/pages/views/formula/viewSummary.php index 0c7b8cd8..fd495033 100644 --- a/pages/views/formula/viewSummary.php +++ b/pages/views/formula/viewSummary.php @@ -250,7 +250,7 @@ function update_view(){ $('.ex_ing').each(function(){ $.ajax({ - url: '/pages/manageFormula.php', + url: '/core/core.php', type: 'GET', data: { fid: '', @@ -276,4 +276,4 @@ function update_view(){ } - \ No newline at end of file + diff --git a/pages/views/ingredients/compos.php b/pages/views/ingredients/compos.php index ae4cea2e..10089002 100644 --- a/pages/views/ingredients/compos.php +++ b/pages/views/ingredients/compos.php @@ -68,6 +68,7 @@ loadingRecords: ' ', processing: 'Loading...', emptyTable: '
No compositions added yet
', + zeroRecords: '
Nothing found
', search: '', searchPlaceholder: 'Search by name...', }, @@ -124,7 +125,6 @@ $('#allgCAS').val(''); $('#allgEC').val(''); $('#addToIng').prop('disabled', false); - } }, error: function(xhr, status, error) { @@ -175,7 +175,7 @@ function cmpActions(data, type, row){ data = ''; return data; }; @@ -183,55 +183,151 @@ function cmpActions(data, type, row){ $('#tdCompositions').editable({ container: 'body', selector: 'i.name', - type: 'POST', - url: "/pages/update_data.php?composition=update&ing=", - title: 'Name' + url: "/core/core.php?composition=update&ing=", + title: 'Name', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_cmp_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }); $('#tdCompositions').editable({ container: 'body', selector: 'i.cas', - type: 'POST', - url: "/pages/update_data.php?composition=update&ing=", - title: 'CAS' + url: "/core/core.php?composition=update&ing=", + title: 'CAS', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_cmp_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }); $('#tdCompositions').editable({ container: 'body', selector: 'i.ec', - type: 'POST', - url: "/pages/update_data.php?composition=update&ing=", + url: "/core/core.php?composition=update&ing=", title: 'EINECS', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_cmp_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }); $('#tdCompositions').editable({ container: 'body', selector: 'i.min_percentage', - type: 'POST', - url: "/pages/update_data.php?composition=update&ing=", + url: "/core/core.php?composition=update&ing=", title: 'Min percentage', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { + if ( data.success ) { reload_cmp_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); $('#tdCompositions').editable({ container: 'body', selector: 'i.max_percentage', - type: 'POST', - url: "/pages/update_data.php?composition=update&ing=", + url: "/core/core.php?composition=update&ing=", title: 'Max percentage', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { + if ( data.success ) { reload_cmp_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); $('#tdCompositions').editable({ container: 'body', selector: 'i.GHS', - type: 'POST', - url: "/pages/update_data.php?composition=update&ing=", - title: 'GHS' + url: "/core/core.php?composition=update&ing=", + title: 'GHS', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_cmp_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }); $('#tdCompositions').editable({ @@ -241,15 +337,29 @@ function cmpActions(data, type, row){ emptyclass: "", container: 'body', selector: 'i.toDeclare', - type: 'POST', - url: "/pages/update_data.php?composition=update&ing=", + url: "/core/core.php?composition=update&ing=", title: 'To be declared', source: [ {value: '0', text: 'No'}, {value: '1', text: 'Yes'}, ], + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { + if ( data.success ) { reload_cmp_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); @@ -260,15 +370,14 @@ function cmpActions(data, type, row){ bootbox.dialog({ title: "Confirm removal", - message : 'Remove '+ cmp.Name +' from the list?', + message : 'Delete '+ cmp.Name +' from the list?', buttons :{ main: { - label : "Remove", + label : "Delete", className : "btn-danger", callback: function (){ - $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { composition: 'delete', @@ -280,12 +389,11 @@ className : "btn-danger", reload_cmp_data(); }, error: function (xhr, status, error) { - $('#toast-title').html(' An ' + status + ' occurred, check server logs for more info. '+ error); + $('#toast-title').html('An ' + status + ' occurred, check server logs for more info. '+ error); $('.toast-header').removeClass().addClass('toast-header alert-danger'); $('.toast').toast('show'); } - }); - + }); return true; } }, @@ -303,7 +411,7 @@ className : "btn-secondary", $('#addComposition').on('click', '[id*=cmpAdd]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { composition: 'add', @@ -320,7 +428,7 @@ className : "btn-secondary", dataType: 'json', success: function (data) { if (data.success) { - var msg = '
x' + data.success + '
'; + var msg = '
x' + data.success + '
'; $("#allgName").val(''); $("#allgCAS").val(''); $("#allgEC").val(''); @@ -329,11 +437,12 @@ className : "btn-secondary", $("#GHS").val(''); reload_cmp_data(); }else{ - var msg = '
x' + data.error + '
'; - } - + var msg = '
x' + data.error + '
'; + } $('#inf').html(msg); - + }, + error: function (xhr, status, error) { + $('#inf').html('
An ' + status + ' occurred, check server logs for more info. '+ error + '
'); } }); }); @@ -353,7 +462,7 @@ className : "btn-secondary", data: fd, contentType: false, processData: false, - cache: false, + cache: false, success: function(response){ if(response != 0){ $("#CSVImportMsg").html(response); @@ -469,4 +578,3 @@ function reload_cmp_data() {
- diff --git a/pages/views/ingredients/impactData.php b/pages/views/ingredients/impactData.php index cf0124a9..46d43582 100644 --- a/pages/views/ingredients/impactData.php +++ b/pages/views/ingredients/impactData.php @@ -1,7 +1,8 @@ \ No newline at end of file + diff --git a/pages/views/ingredients/ingDocuments.php b/pages/views/ingredients/ingDocuments.php index 0d9146cc..55cc3845 100644 --- a/pages/views/ingredients/ingDocuments.php +++ b/pages/views/ingredients/ingDocuments.php @@ -53,11 +53,11 @@ }, ajax: { url: '/core/list_ing_doc_data.php?id=' }, columns: [ - { data : 'name', title: 'Document', render: dName }, - { data : 'docData', title: 'File', render: docData}, - { data : 'notes', title: 'Notes', render: dNotes}, - { data : 'docSize', title: 'Size'}, - { data : null, title: '', render: dActions}, + { data : 'name', title: 'Document', render: dName }, + { data : 'docData', title: 'File', render: docData}, + { data : 'notes', title: 'Notes', render: dNotes}, + { data : 'docSize', title: 'Size'}, + { data : null, title: '', render: dActions}, ], order: [[ 1, 'asc' ]], lengthMenu: [[20, 50, 100, -1], [20, 50, 100, "All"]], @@ -83,7 +83,7 @@ function dActions(data, type, row){ data = ''; return data; }; @@ -91,17 +91,51 @@ function dActions(data, type, row){ $('#tdIngDocs').editable({ container: 'body', selector: 'i.name', - type: 'POST', - url: "/pages/update_data.php?ingDoc=update&ingID=", - title: 'Document name', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_doc_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, + url: "/core/core.php?action=updateDocument&ingID=", + title: 'Document name' }); $('#tdIngDocs').editable({ - container: 'body', - selector: 'i.notes', - type: 'POST', - url: "/pages/update_data.php?ingDoc=update&ingID=", - title: 'Notes', + container: 'body', + selector: 'i.notes', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_doc_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, + url: "/core/core.php?action=updateDocument&ingID=", + title: 'Notes' }); @@ -111,29 +145,32 @@ function dActions(data, type, row){ d.Name = $(this).attr('data-name'); bootbox.dialog({ - title: "Confirm document removal", - message : 'Remove '+ d.Name +' from the list?', + title: "Confirm document deletion", + message : 'Delete '+ d.Name +' from the list?', buttons :{ main: { - label : "Remove", + label : "Delete", className : "btn-danger", callback: function (){ - - $.ajax({ - url: '/pages/update_data.php', + $.ajax({ + url: '/core/core.php', type: 'GET', data: { - doc: 'delete', + action: 'deleteDocument', id: d.ID, ownerID: '' }, - dataType: 'html', + dataType: 'json', success: function (data) { - $('#msg_doc').html(data); + if( data.success){ + reload_doc_data(); + } else { + $('#doc_inf').html('
x' + response.error + '
'); + } reload_doc_data(); }, error: function (xhr, status, error) { - $('#toast-title').html(' An ' + status + ' occurred, check server logs for more info. '+ error); + $('#toast-title').html('An ' + status + ' occurred, check server logs for more info. '+ error); $('.toast-header').removeClass().addClass('toast-header alert-danger'); $('.toast').toast('show'); } @@ -155,7 +192,7 @@ className : "btn-secondary", $('#addDoc').on('click', '[id*=doc_upload]', function () { - $("#doc_inf").html('
Please wait, file upload in progress....
'); + $("#doc_inf").html('
Please wait, file upload in progress...
'); $("#doc_upload").prop("disabled", true); $("#doc_upload").prop('value', 'Please wait...'); @@ -174,15 +211,15 @@ className : "btn-secondary", dataType: 'json', contentType: false, processData: false, - cache: false, + cache: false, success: function(response){ if(response.success){ - var msg = '
x' + response.success + '
'; + var msg = '
x' + response.success + '
'; $("#doc_upload").prop("disabled", false); $("#doc_upload").prop('value', 'Upload'); reload_doc_data(); }else{ - $("#doc_inf").html('
x' + response.error + '
'); + $("#doc_inf").html('
x' + response.error + '
'); $("#doc_upload").prop("disabled", false); $("#doc_upload").prop('value', 'Upload'); } @@ -190,7 +227,7 @@ className : "btn-secondary", }, }); }else{ - $("#doc_inf").html('
xError: Please select a file to upload!
'); + $("#doc_inf").html('
xPlease select a file to upload
'); $("#doc_upload").prop("disabled", false); $("#doc_upload").prop('value', 'Upload'); } diff --git a/pages/views/ingredients/ingOverview.php b/pages/views/ingredients/ingOverview.php index d99a2bb6..1304f3e9 100644 --- a/pages/views/ingredients/ingOverview.php +++ b/pages/views/ingredients/ingOverview.php @@ -11,6 +11,8 @@ if(empty($_GET["id"])){ + $response["error"] = 'Invalid ID'; + echo json_encode($response); return; } $ingID = mysqli_real_escape_string($conn, $_GET["id"]); @@ -69,5 +71,3 @@
- - diff --git a/pages/views/ingredients/ingSuppliers.php b/pages/views/ingredients/ingSuppliers.php index a27e473f..9d857f68 100644 --- a/pages/views/ingredients/ingSuppliers.php +++ b/pages/views/ingredients/ingSuppliers.php @@ -156,7 +156,7 @@ $('#addSupplier').on('click', '[id*=sAdd]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { ingSupplier: 'add', @@ -194,7 +194,10 @@ var msg ='
x' + data.error + '
'; } $('#supplier_inf').html(msg); - } + }, + error: function (xhr, status, error) { + $('#supplier_inf').html('
An error occurred, check server logs for more info. '+ error+'
'); + }, }); }); @@ -295,20 +298,34 @@ function sActions(data, type, row){ title: "Supplier's Name", container: 'body', selector: 'i.ingSupplierID', - type: 'POST', emptytext: "", emptyclass: "", - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", source: [ - + ], + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); @@ -319,26 +336,57 @@ function sActions(data, type, row){ title: "Availability status", container: 'body', selector: 'i.status', - type: 'POST', emptytext: "", emptyclass: "", - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", source: [ - {value: '1', text: 'Available'}, - {value: '2', text: 'Limited availability'}, - {value: '3', text: 'Discontinued / Cannot sourced'}, + {value: '1', text: 'Available'}, + {value: '2', text: 'Limited availability'}, + {value: '3', text: 'Discontinued / Cannot sourced'}, ], + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); $('#tdIngSup').editable({ container: 'body', selector: 'i.supplierLink', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Store link', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, validate: function(value){ if($.trim(value) == ''){ return 'This field is required'; @@ -349,9 +397,26 @@ function sActions(data, type, row){ $('#tdIngSup').editable({ container: 'body', selector: 'i.price', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Price', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, validate: function(value){ if($.trim(value) == ''){ return 'This field is required'; @@ -368,12 +433,26 @@ function sActions(data, type, row){ $('#tdIngSup').editable({ container: 'body', selector: 'i.size', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Size', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ @@ -383,96 +462,208 @@ function sActions(data, type, row){ emptyclass: "", container: 'body', selector: 'i.mUnit', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Measurement Unit', source: [ - {value: 'ml', text: 'Milliliter'}, - {value: 'g', text: 'Grams'}, - {value: 'L', text: 'Liter'}, - {value: 'fl. oz.', text: 'Fluid ounce (fl. oz.)'} + {value: 'ml', text: 'Milliliter'}, + {value: 'g', text: 'Grams'}, + {value: 'L', text: 'Liter'}, + {value: 'fl. oz.', text: 'Fluid ounce (fl. oz.)'} ], + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ container: 'body', selector: 'i.manufacturer', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Manufacturer', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ container: 'body', selector: 'i.batch', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Batch', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ container: 'body', selector: 'i.purchased', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Purchase date', type: 'date', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ container: 'body', selector: 'i.stock', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'In Stock', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ container: 'body', selector: 'i.internal_sku', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Internal SKU', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ container: 'body', selector: 'i.supplier_sku', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Supplier SKU', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); $('#tdIngSup').editable({ container: 'body', selector: 'i.storage_location', - type: 'POST', - url: "/pages/update_data.php?ingSupplier=update&ingID=", + url: "/core/core.php?ingSupplier=update&ingID=", title: 'Storage location', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { - reload_sup_data(); - } + if ( data.success ) { + reload_sup_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); @@ -482,18 +673,23 @@ function sActions(data, type, row){ s.Status = $(this).attr('data-status'); $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'GET', data: { ingSupplier: 'preferred', sID: s.ID, status: s.Status, ingID: '' - }, - dataType: 'html', + }, + dataType: 'json', success: function (data) { reload_sup_data(); - } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); }); @@ -508,7 +704,7 @@ function sActions(data, type, row){ $('#supMsg').html('
Please wait, trying to fetch supplier data...
'); $('#' + s.ID).html(''); $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { ingSupplier: 'getPrice', @@ -526,7 +722,12 @@ function sActions(data, type, row){ } $('#supMsg').html(msg); reload_sup_data(); - } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); }); @@ -544,9 +745,8 @@ function sActions(data, type, row){ label : "Remove", className : "btn-danger", callback: function (){ - $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'GET', data: { ingSupplier: 'delete', diff --git a/pages/views/ingredients/mgmGeneral.php b/pages/views/ingredients/mgmGeneral.php index edff7c5a..a8da2e5d 100644 --- a/pages/views/ingredients/mgmGeneral.php +++ b/pages/views/ingredients/mgmGeneral.php @@ -153,7 +153,7 @@ } $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { manage: 'ingredient', @@ -222,4 +222,4 @@ $('.selectpicker').selectpicker('refresh'); }); });//end doc - \ No newline at end of file + diff --git a/pages/views/ingredients/privacyData.php b/pages/views/ingredients/privacyData.php index 47c8fa96..08a8fc31 100644 --- a/pages/views/ingredients/privacyData.php +++ b/pages/views/ingredients/privacyData.php @@ -29,7 +29,7 @@ $('#privacy').on('click', '[id*=savePrivacy]', function () { $.ajax({ - url: 'update_data.php', + url: '/core/core.php', type: 'POST', data: { manage: 'ingredient', @@ -50,4 +50,4 @@ } }); }); - \ No newline at end of file + diff --git a/pages/views/ingredients/pubChem.php b/pages/views/ingredients/pubChem.php index ef20a252..f4c11def 100644 --- a/pages/views/ingredients/pubChem.php +++ b/pages/views/ingredients/pubChem.php @@ -1,9 +1,11 @@ $(document).ready(function(){ -$('#btnUpdatePub').on('click', function () { - $.ajax({ - url: '/pages/update_data.php', - type: 'POST', - data: { - pubChemData: 'update', - molecularWeight: "", - logP: "", - molecularFormula: "", - InChI: "", - CanonicalSMILES: "", - ExactMass: "", - cas: "", - }, - dataType: 'JSON', - success: function (data) { - $('#toast-title').html('' + data.success); - $('.toast-header').removeClass().addClass('toast-header alert-success'); - $("#INCI").val(""); - reload_overview(); - $('.toast').toast('show'); - }, - error: function (xhr, status, error) { - $('#toast-title').html(' An ' + status + ' occurred, check server logs for more info. '+ error); - $('.toast-header').removeClass().addClass('toast-header alert-danger'); - $('.toast').toast('show'); - } - }); -}); + $('#btnUpdatePub').on('click', function () { + $.ajax({ + url: '/core/core.php', + type: 'POST', + data: { + pubChemData: 'update', + molecularWeight: "", + logP: "", + molecularFormula: "", + InChI: "", + CanonicalSMILES: "", + ExactMass: "", + cas: "", + }, + dataType: 'JSON', + success: function (data) { + $('#toast-title').html('' + data.success); + $('.toast-header').removeClass().addClass('toast-header alert-success'); + $("#INCI").val(""); + reload_overview(); + $('.toast').toast('show'); + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An ' + status + ' occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }); + }); }); @@ -117,6 +119,3 @@
- - - diff --git a/pages/views/ingredients/repData.php b/pages/views/ingredients/repData.php index cafcc096..1a6fb12e 100644 --- a/pages/views/ingredients/repData.php +++ b/pages/views/ingredients/repData.php @@ -60,79 +60,27 @@ url: '/core/list_ing_rep_data.php', type: 'POST', data: { - ing_name: '', - ing_cas: '', - view: 'ingredients', - }, + ing_name: '', + ing_cas: '', + view: 'ingredients', + }, }, columns: [ - { data : null, title: 'Name', render: repName }, - { data : 'ing_rep_cas', title: 'CAS' }, - { data : 'notes', title: 'Notes', render: repNotes }, - { data : null, title: '', render: repActions }, + { data : null, title: 'Name', render: repName }, + { data : 'ing_rep_cas', title: 'CAS' }, + { data : 'notes', title: 'Notes', render: repNotes }, + { data : null, title: '', render: repActions }, ], order: [[ 1, 'asc' ]], lengthMenu: [[20, 50, 100, -1], [20, 50, 100, "All"]], pageLength: 20, - displayLength: 20, + displayLength: 20 }); function repName(data, type, row){ - - $('#tdReplacements').editable({ - select2: { - width: '100%', - placeholder: 'Search for ingredient (name, cas)', - allowClear: true, - dropdownAutoWidth: true, - minimumInputLength: 2, - dropdownParent: '.popover:last', - ajax: { - url: '/core/list_ingredients_simple.php', - dataType: 'json', - type: 'POST', - delay: 100, - quietMillis: 250, - data: function (params) { - return { - search: params.term - }; - }, - processResults: function(data) { - return { - results: $.map(data.data, function(obj) { - return { - id: obj.name, //TODO: TO BE CHANGED TO ID WHEN THE BACKEND IS READY - repID: obj.id, - text: obj.name || 'No ingredient found...', - } - }) - }; - }, - cache: true, - - } - }, - tpl:'', - selector: 'i.replaceIngredient', - pvnoresp: false, - highlight: false, - emptytext: null, - emptyclass: null, - url: "update_data.php?replacement=update&ing=", - dataType: 'json', - success: function (data) { - reload_rep_data(); - }, - validate: function(value){ - if($.trim(value) == ''){ - return 'Ingredient is required'; - } - } - }); - return ''+ row.ing_rep_name +''; - } + return row.ing_rep_name; + }; function repNotes(data, type, row){ return ''+row.notes+''; @@ -143,7 +91,7 @@ function repActions(data, type, row){ data = ''; return data; } @@ -152,9 +100,26 @@ function repActions(data, type, row){ $('#tdReplacements').editable({ container: 'body', selector: 'i.repNotes', - type: 'POST', - url: "update_data.php?replacement=update&ing=", - title: 'Notes' + url: "/core/core.php?replacement=update&ing=", + title: 'Notes', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_rep_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }); $('#tdReplacements').on('click', '[id*=repDel]', function () { @@ -163,16 +128,16 @@ function repActions(data, type, row){ rep.Name = $(this).attr('data-name'); bootbox.dialog({ - title: "Confirm removal", - message : 'Remove '+ rep.Name +' from the list?', + title: "Confirm deletion", + message : 'Delete '+ rep.Name +'?', buttons :{ main: { - label : "Remove", + label : "Delete", className : "btn-danger", callback: function (){ $.ajax({ - url: 'update_data.php', + url: '/core/core.php', type: 'POST', data: { replacement: 'delete', @@ -258,7 +223,7 @@ className : "btn-secondary", $('#addReplacement').on('click', '[id*=repAdd]', function () { $.ajax({ - url: 'update_data.php', + url: '/core/core.php', type: 'POST', data: { replacement: 'add', @@ -282,6 +247,9 @@ className : "btn-secondary", var msg ='
' + data.error + '
'; } $('#infRep').html(msg); + }, + error: function (xhr, status, error) { + $('#infRep').html('
An ' + status + ' occurred, check server logs for more info. '+ error + '
'); } }); }); @@ -320,4 +288,3 @@ function reload_rep_data() { - diff --git a/pages/views/ingredients/safetyData.php b/pages/views/ingredients/safetyData.php index 4d618b11..caeb3fd5 100644 --- a/pages/views/ingredients/safetyData.php +++ b/pages/views/ingredients/safetyData.php @@ -883,7 +883,7 @@ $('#save_addinf').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -914,7 +914,7 @@ $('#save_leg').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -941,7 +941,7 @@ $('#save_trans').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -971,7 +971,7 @@ $('#save_dis').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -996,7 +996,7 @@ $('#save_ec').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1028,7 +1028,7 @@ $('#save_tx').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1067,7 +1067,7 @@ $('#save_sr').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1095,7 +1095,7 @@ $('#safety_info').on('changed.bs.select', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1121,7 +1121,7 @@ var imageId = $(this).data('id'); $.ajax({ type: "POST", - url: "/pages/update_data.php", + url: "/core/core.php", data: { manage: "ingredient", tab: "safety_info", @@ -1144,7 +1144,7 @@ $('#save_faid').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1176,7 +1176,7 @@ $('#save_fire').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1204,7 +1204,7 @@ $('#save_acc_rel').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1233,7 +1233,7 @@ $('#save_HS').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1261,7 +1261,7 @@ $('#save_exposure').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1295,7 +1295,7 @@ $('#save_pcp').on('click', function () { $.ajax({ - url: "/pages/update_data.php", + url: "/core/core.php", type: "POST", data: { manage: "ingredient", @@ -1344,4 +1344,4 @@ }); - \ No newline at end of file + diff --git a/pages/views/ingredients/synonyms.php b/pages/views/ingredients/synonyms.php index 6cdb139b..a803d7ff 100644 --- a/pages/views/ingredients/synonyms.php +++ b/pages/views/ingredients/synonyms.php @@ -41,7 +41,6 @@ + diff --git a/pages/bottles.php b/pages/views/inventory/bottles.php similarity index 80% rename from pages/bottles.php rename to pages/views/inventory/bottles.php index 8bff6aa9..33b0b18f 100644 --- a/pages/bottles.php +++ b/pages/views/inventory/bottles.php @@ -1,12 +1,14 @@
- -
- +

Bottles

@@ -15,10 +17,11 @@
@@ -118,10 +121,51 @@
+ + - + + '; + var msg = '
'+data.success+'
'; }else if( data.error){ - var msg = '
'+data.error+'
'; + var msg = '
'+data.error+'
'; } $('#bottle-inf').html(msg); + },error: function (xhr, status, error) { + $('#bottle-inf').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); } - }); + }); var fd = new FormData(); var files = $('#bottle_pic_file')[0].files; if(files.length > 0 ){ fd.append('bottle_pic',files[0]); - } - $.ajax({ - url: '/pages/update_data.php?update_bottle_pic=1&bottle_id=', - type: 'POST', - data: fd, - contentType: false, - processData: false, - cache: false, - dataType: 'json', - success: function (data) { - if(data.success){ - $('#bottle_pic').html(''); - }else if( data.error){ - $('#bottle-inf').html('
'+data.error+'
'); + $.ajax({ + url: '/core/core.php?update_bottle_pic=1&bottle_id=', + type: 'POST', + data: fd, + contentType: false, + processData: false, + cache: false, + dataType: 'json', + success: function (data) { + if(data.success){ + $('#bottle_pic').html(''); + }else if( data.error){ + $('#bottle-inf').html('
'+data.error+'
'); + } + },error: function (xhr, status, error) { + $('#bottle-inf').html('
An ' + status + ' occurred, check server logs for more info. '+ error +'
'); } - } - }); + }); + } }); - \ No newline at end of file + diff --git a/pages/views/inventory/editCompound.php b/pages/views/inventory/editCompound.php index 83c0fd88..6d7f9e44 100644 --- a/pages/views/inventory/editCompound.php +++ b/pages/views/inventory/editCompound.php @@ -66,7 +66,7 @@ $('#cmp_edit_save').click(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { update_inv_compound_data: 1, @@ -93,4 +93,4 @@ }); - \ No newline at end of file + diff --git a/pages/editCustomer.php b/pages/views/inventory/editCustomer.php similarity index 95% rename from pages/editCustomer.php rename to pages/views/inventory/editCustomer.php index 34f2438d..357623ad 100644 --- a/pages/editCustomer.php +++ b/pages/views/inventory/editCustomer.php @@ -1,5 +1,5 @@ \ No newline at end of file + diff --git a/pages/views/inventory/suppliers.php b/pages/views/inventory/suppliers.php index f92d3c5c..83c5e57f 100644 --- a/pages/views/inventory/suppliers.php +++ b/pages/views/inventory/suppliers.php @@ -1,29 +1,25 @@
- +
-
-
- - - -
-
-
@@ -41,6 +37,11 @@
+
+
+
+
+ @@ -478,7 +496,47 @@ function reload_data() {
- + +
+ diff --git a/pages/views/pvOnline/marketPlace.php b/pages/views/pvOnline/marketPlace.php index 264ac2e8..3a5942ce 100644 --- a/pages/views/pvOnline/marketPlace.php +++ b/pages/views/pvOnline/marketPlace.php @@ -47,15 +47,15 @@

Please note, your full name and your email address will be shared with the author(s) of the formula so they can get in touch to discuss further. Also, a copy of your message will be shared with the admins to ensure there is no service abuse.

- +
- +
- +
@@ -89,15 +89,15 @@

Please don't use this form if you have queries or suggestions regarding the formula, use the Contact Author option instead.

- +
- +
- +
@@ -299,7 +299,7 @@ function actions(data, type, row, meta){ className : "btn-warning", callback: function (){ $.ajax({ - url: '/pages/pvonline.php', + url: '/core/core.php', type: 'POST', data: { action: "import", @@ -355,8 +355,9 @@ className : "btn-secondary", $('#contact-formula-author').on('click', '[id*=confirm-contact-author]', function () { $("#cntMsg").html('
Please wait...
'); + $('#contact-formula-author, #confirm-contact-author').prop('disabled', true); $.ajax({ - url: '/pages/pvonline.php', + url: '/core/core.php', type: 'POST', data: { action: "contactAuthor", @@ -371,14 +372,17 @@ className : "btn-secondary", success: function (data) { if (data.success) { var msg = '
' + data.success + '
'; - $('#contact-formula-author .modal-body-main').hide(); + $('#contact-formula-author .modal-body-main, #contact-formula-author #confirm-contact-author').hide(); + $('#contact-formula-author, #confirm-contact-author').prop('disabled', true); }else{ var msg = '
' + data.error + '
'; + $('#contact-formula-author, #confirm-contact-author').prop('disabled', false); } $('#cntMsg').html(msg); }, error: function (request, status, error) { $('#cntMsg').html('
Unable to handle request, server returned an error: '+request.status+'
'); + $('#contact-formula-author, #confirm-contact-author').prop('disabled', false); }, }); }); @@ -400,8 +404,10 @@ className : "btn-secondary", $('#report-market-formula').on('click', '[id*=confirm-formula-report]', function () { $("#reportMsg").html('
Please wait...
'); + $('#report-market-formula, #confirm-formula-report').prop('disabled', true); + $.ajax({ - url: '/pages/pvonline.php', + url: '/core/core.php', type: 'POST', data: { action: 'report', @@ -416,14 +422,18 @@ className : "btn-secondary", success: function (data) { if (data.success) { var msg = '
' + data.success + '
'; - $('#report-market-formula .modal-body-main').hide(); + $('#report-market-formula .modal-body-main, #report-market-formula #confirm-formula-report').hide(); + }else{ var msg = '
' + data.error + '
'; + $('#report-market-formula, #confirm-formula-report').prop('disabled', false); } $('#reportMsg').html(msg); }, error: function (request, status, error) { $('#reportMsg').html('
Unable to handle request, server returned an error: '+request.status+'
'); + $('#report-market-formula, #confirm-formula-report').prop('disabled', false); + }, }); }); diff --git a/pages/IFRA.php b/pages/views/regulatory/IFRA.php old mode 100755 new mode 100644 similarity index 96% rename from pages/IFRA.php rename to pages/views/regulatory/IFRA.php index 01e03b27..0e79747b --- a/pages/IFRA.php +++ b/pages/views/regulatory/IFRA.php @@ -23,7 +23,7 @@
  • Import images
  • -
  • Export as JSON
  • +
  • Export as JSON
  • Export as CSV
  • @@ -120,7 +120,7 @@
    - +
    @@ -220,7 +220,8 @@ language: { loadingRecords: ' ', processing: '
    Please Wait...', - zeroRecords: '
    Nothing found, have you imported the IFRA library?
    ', + zeroRecords: '
    Nothing found
    ', + emptyTable: '
    Nothing found, have you imported the IFRA library?
    ', search: '', searchPlaceholder: 'Search by name, CAS, synonyms...', }, @@ -417,7 +418,7 @@ function actions(data, type, row) { $("#ImportpbC").hide(); $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'GET', data: { IFRA_PB: "import", @@ -469,7 +470,7 @@ className : "btn-danger", callback: function (){ $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { IFRA: 'delete', @@ -512,7 +513,7 @@ className : "btn-secondary", $('#tdDataIFRA').editable({ container: 'body', selector: 'a.cas', - url: "/pages/update_data.php?IFRA=edit&type=cas", + url: "/core/core.php?IFRA=edit&type=cas", title: 'CAS#', ajaxOptions: { dataType: 'json' @@ -535,7 +536,7 @@ className : "btn-secondary", container: 'body', selector: 'a.cat1, a.cat2, a.cat3, a.cat4, a.cat5A, a.cat5B, a.cat5C, a.cat5D, a.cat6, a.cat7A, a.cat7B, a.cat8, a.cat9, a.cat10A, a.cat11A, a.cat11B, a.cat12', type: 'POST', - url: "/pages/update_data.php", + url: "/core/core.php", params: function(params) { var category = String($(params).attr('name').split(' ')[0]).toUpperCase(); diff --git a/pages/views/regulatory/listSDS.php b/pages/views/regulatory/listSDS.php index 35e250ff..5512b3eb 100644 --- a/pages/views/regulatory/listSDS.php +++ b/pages/views/regulatory/listSDS.php @@ -175,7 +175,7 @@ className : "btn-danger", callback: function (){ $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { action: "delete", diff --git a/pages/views/settings/api.php b/pages/views/settings/api.php index fda0fd0e..66a275f1 100644 --- a/pages/views/settings/api.php +++ b/pages/views/settings/api.php @@ -46,7 +46,7 @@ }); $('#save-api').click(function() { $.ajax({ - url: '/pages/update_settings.php', + url: '/core/core.php', type: 'POST', data: { manage: 'api', @@ -73,4 +73,4 @@ }); }); - \ No newline at end of file + diff --git a/pages/views/settings/branding.php b/pages/views/settings/branding.php index 2d19cffa..3ba07696 100644 --- a/pages/views/settings/branding.php +++ b/pages/views/settings/branding.php @@ -66,7 +66,7 @@ $('#save-brand').click(function() { $.ajax({ - url: '/pages/update_settings.php', + url: '/core/core.php', type: 'POST', data: { manage: 'brand', @@ -134,4 +134,4 @@ }); - \ No newline at end of file + diff --git a/pages/editHtmlTmpl.php b/pages/views/settings/editHtmlTmpl.php similarity index 86% rename from pages/editHtmlTmpl.php rename to pages/views/settings/editHtmlTmpl.php index ecee718d..b4520c3f 100644 --- a/pages/editHtmlTmpl.php +++ b/pages/views/settings/editHtmlTmpl.php @@ -1,5 +1,5 @@ - diff --git a/pages/views/settings/general.php b/pages/views/settings/general.php index 960399eb..2ab1cf38 100644 --- a/pages/views/settings/general.php +++ b/pages/views/settings/general.php @@ -4,6 +4,10 @@ require_once(__ROOT__.'/inc/sec.php'); require_once(__ROOT__.'/inc/opendb.php'); require_once(__ROOT__.'/inc/settings.php'); +require_once(__ROOT__.'/func/convertTime.php'); + +$session_validity_calc = convertTime($session_timeout); + $cats_q = mysqli_query($conn, "SELECT id,name,description,type FROM IFRACategories ORDER BY id ASC"); while($cats_res = mysqli_fetch_array($cats_q)){ @@ -166,9 +170,15 @@ +
    +
    + User session validity: + + +
    - +
    @@ -184,7 +194,7 @@ var selectedCurrency = $("#currency").val(); var currencyData = selectedCurrency.split('|'); $.ajax({ - url: '/pages/update_settings.php', + url: '/core/core.php', type: 'POST', data: { manage: 'general', @@ -248,4 +258,4 @@ }); - \ No newline at end of file + diff --git a/pages/views/settings/listCat.php b/pages/views/settings/listCat.php index ffe8b9d8..d4176785 100644 --- a/pages/views/settings/listCat.php +++ b/pages/views/settings/listCat.php @@ -16,7 +16,7 @@
  • Add ingredient category
  • Import from JSON
  • -
  • Export as JSON
  • +
  • Export as JSON
  • @@ -49,6 +49,7 @@ loadingRecords: ' ', processing: '', emptyTable: '
    No categories added yet
    ', + zeroRecords: '
    Nothing found
    ', search: '', searchPlaceholder: 'Search by name...', }, @@ -124,7 +125,7 @@ function ciActions(data, type, row){ $('#add-category').click(function() { $.ajax({ - url: '/pages/update_settings.php', + url: '/core/core.php', type: 'POST', data: { manage: 'category', @@ -153,10 +154,26 @@ function ciActions(data, type, row){ $('#tdDataCat').editable({ container: 'body', selector: 'a.name', - url: "/pages/update_data.php?settings=cat", + url: "/core/core.php?action=ingredientCategories", title: 'Category', - type: "POST", - dataType: 'json', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if (data.success) { + reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, validate: function(value){ if($.trim(value) == ''){ return 'This field is required'; @@ -167,10 +184,26 @@ function ciActions(data, type, row){ $('#tdDataCat').editable({ container: 'body', selector: 'a.notes', - url: "/pages/update_data.php?settings=cat", + url: "/core/core.php?action=ingredientCategories", title: 'Description', - type: "POST", - dataType: 'json', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if (data.success) { + reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); //Change colorKey @@ -178,22 +211,35 @@ function ciActions(data, type, row){ pvnoresp: false, highlight: false, selector: 'a.colorKey', - type: "POST", emptytext: "", emptyclass: "", - url: "pages/update_data.php?settings=cat", + url: "/core/core.php?action=ingredientCategories", source: [ - + ], - dataType: 'html', - success: function () { - reload_data(); - } + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if (data.success) { + reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); @@ -211,25 +257,30 @@ function ciActions(data, type, row){ className : "btn-danger", callback: function (){ - $.ajax({ - url: '/pages/update_settings.php', - type: 'POST', - data: { - action: "delete", - catId: cat.ID, - }, - dataType: 'json', - success: function (data) { - if ( data.success ) { - $('#toast-title').html('' + data.success); - $('.toast-header').removeClass().addClass('toast-header alert-success'); - reload_data(); - } else { - $('#toast-title').html('' + data.error); + $.ajax({ + url: '/core/core.php', + type: 'POST', + data: { + action: "delete", + catId: cat.ID, + }, + dataType: 'json', + success: function (data) { + if ( data.success ) { + $('#toast-title').html('' + data.success); + $('.toast-header').removeClass().addClass('toast-header alert-success'); + reload_data(); + } else { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + } + $('.toast').toast('show'); + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); $('.toast-header').removeClass().addClass('toast-header alert-danger'); - } - $('.toast').toast('show'); - } + $('.toast').toast('show'); + }, }); return true; } diff --git a/pages/views/settings/listFrmCat.php b/pages/views/settings/listFrmCat.php index b8a3d9f1..da772063 100644 --- a/pages/views/settings/listFrmCat.php +++ b/pages/views/settings/listFrmCat.php @@ -14,7 +14,7 @@ @@ -46,6 +46,7 @@ loadingRecords: ' ', processing: '', emptyTable: '
    No categories added yet
    ', + zeroRecords: '
    Nothing found
    ', search: '', searchPlaceholder: 'Search by name...', }, @@ -105,8 +106,8 @@ function fKey(data, type, row){ }; $('#add-fcat').click(function() { - $.ajax({ - url: '/pages/update_settings.php', + $.ajax({ + url: '/core/core.php', type: 'POST', data: { manage: 'add_frmcategory', @@ -116,34 +117,50 @@ function fKey(data, type, row){ dataType: 'json', success: function (data) { if ( data.success ) { - $('#toast-title').html('' + data.success); + $('#toast-title').html('' + data.success); $('.toast-header').removeClass().addClass('toast-header alert-success'); reload_data(); $('#add_formula_cat').modal('toggle'); $('.toast').toast('show'); } else { - var msg = '
    '+data.error+'
    '; - $('#fcatMsgIn').html(msg); + $('#fcatMsgIn').html('
    '+data.error+'
    '); } - + }, + error: function (xhr, status, error) { + $('#fcatMsgIn').html('
    An ' + status + ' occurred, check server logs for more info. '+ error + '
    '); } }); }); - $('#frmDataCat').editable({ - container: 'body', - selector: 'a.name', - url: "/pages/update_data.php?settings=fcat", - title: 'Category name', - type: "POST", - dataType: 'json', - validate: function(value){ - if($.trim(value) == ''){ - return 'This field is required'; - } - } + container: 'body', + selector: 'a.name', + url: "/core/core.php?settings=fcat&action=updateFormulaCategory", + title: 'Category name', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, + validate: function(value){ + if($.trim(value) == ''){ + return 'This field is required'; + } + } }); @@ -153,21 +170,30 @@ function fKey(data, type, row){ highlight: false, title: 'Category type', selector: 'a.type', - type: "POST", emptytext: "", emptyclass: "", - url: "/pages/update_data.php?settings=fcat", + url: "/core/core.php?settings=fcat&action=updateFormulaCategory", source: [ - - {value: "", text: ""}, - - ], - dataType: 'html', - success: function () { - reload_data(); + {value: 'gender', text: 'Gender'}, + {value: 'profile', text: 'Profile'}, + ], + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if (data.success) { + reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); @@ -176,21 +202,34 @@ function fKey(data, type, row){ pvnoresp: false, highlight: false, selector: 'a.colorKey', - type: "POST", emptytext: "", emptyclass: "", - url: "/pages/update_data.php?settings=fcat", + url: "/core/core.php?settings=fcat&action=updateFormulaCategory", source: [ - - ], - dataType: 'html', - success: function () { - reload_data(); + + ], + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if (data.success) { + reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html('An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); @@ -207,9 +246,8 @@ function fKey(data, type, row){ label : "Delete", className : "btn-danger", callback: function (){ - $.ajax({ - url: '/pages/update_settings.php', + url: '/core/core.php', type: 'POST', data: { action: "del_frmcategory", @@ -218,14 +256,19 @@ className : "btn-danger", dataType: 'json', success: function (data) { if ( data.success ) { - $('#toast-title').html('' + data.success); + $('#toast-title').html('' + data.success); $('.toast-header').removeClass().addClass('toast-header alert-success'); reload_data(); } else { - $('#toast-title').html('' + data.error); + $('#toast-title').html('' + data.error); $('.toast-header').removeClass().addClass('toast-header alert-danger'); } $('.toast').toast('show'); + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); return true; @@ -248,8 +291,8 @@ function reload_data() { }); - + @@ -280,6 +323,3 @@ function reload_data() { - - - diff --git a/pages/views/settings/maintenance.php b/pages/views/settings/maintenance.php index 94d9c7b7..5626e2c5 100644 --- a/pages/views/settings/maintenance.php +++ b/pages/views/settings/maintenance.php @@ -118,7 +118,7 @@ $("#btnClear").prop("disabled", true); $.ajax({ - url: '/pages/operations.php', + url: '/core/core.php', data: { do: 'userPerfClear', }, @@ -153,7 +153,7 @@ $("#btnCloseBK").prop("disabled", true); $('#btnBackup').prepend(''); $.ajax({ - url: '/pages/operations.php', + url: '/core/core.php', data: { do: 'backupDB', column_statistics: $('#column-statistics').prop("checked") diff --git a/pages/views/settings/perfume_types.php b/pages/views/settings/perfume_types.php index 54b1e2c1..99dd46d1 100644 --- a/pages/views/settings/perfume_types.php +++ b/pages/views/settings/perfume_types.php @@ -12,7 +12,7 @@ @@ -42,6 +42,7 @@ loadingRecords: ' ', processing: 'Loading...', emptyTable: '
    No perfume types added yet
    ', + zeroRecords: '
    Nothing found
    ', search: '', searchPlaceholder: 'Search by name...', }, @@ -101,32 +102,58 @@ function actions(data, type, row){ $('#tdperfTypes').editable({ - container: 'body', - selector: 'a.name', - type: 'POST', - url: "/pages/update_data.php?perfType=update", - title: 'Perfume type name', - success: function (data) { + container: 'body', + selector: 'a.name', + url: "/core/core.php?perfType=update", + title: 'Perfume type name', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if (data.success) { reload_data(); - }, - - validate: function(value){ + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, + validate: function(value){ if($.trim(value) == ''){ return 'This field is required'; } - } + } }); $('#tdperfTypes').editable({ - container: 'body', - selector: 'a.concentration', - type: 'POST', - url: "/pages/update_data.php?perfType=update", - title: 'Concentration in %', - success: function (data) { + container: 'body', + selector: 'a.concentration', + url: "/core/core.php?perfType=update", + title: 'Concentration in %', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if (data.success) { reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); }, - validate: function(value){ if($.trim(value) == ''){ return 'This field is required'; @@ -140,12 +167,26 @@ function actions(data, type, row){ $('#tdperfTypes').editable({ container: 'body', selector: 'a.description', - type: 'POST', - url: "/pages/update_data.php?perfType=update", + url: "/core/core.php?perfType=update", title: 'Short description', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, success: function (data) { + if (data.success) { reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }); @@ -165,17 +206,29 @@ className : "btn-danger", callback: function (){ $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { perfType: 'delete', pID: pType.ID, pName: pType.Name - }, + }, dataType: 'json', success: function (data) { - reload_data(); + if (data.success) { + reload_data(); + } else if (data.error) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } + }); return true; @@ -194,7 +247,7 @@ className : "btn-secondary", $('#addpType').on('click', '[id*=sAdd]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { perfType: 'add', @@ -211,6 +264,11 @@ className : "btn-secondary", } $('#ptype_inf').html(msg); reload_data(); + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); }); @@ -255,6 +313,3 @@ function reload_data() { - - - diff --git a/pages/views/settings/sds.php b/pages/views/settings/sds.php index 29663ce4..e744fb5d 100644 --- a/pages/views/settings/sds.php +++ b/pages/views/settings/sds.php @@ -24,10 +24,10 @@ $('#sds_set_update').click(function() { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { - settings: 'sds', + action: 'sdsDisclaimerContent', sds_disc_content: $("#sds_disc_content").val(), }, dataType: 'json', @@ -40,10 +40,15 @@ $('.toast-header').removeClass().addClass('toast-header alert-danger'); } $('.toast').toast('show'); + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); } }); }); }); - \ No newline at end of file + diff --git a/pages/views/settings/templates.php b/pages/views/settings/templates.php index e53283df..78dd41e7 100644 --- a/pages/views/settings/templates.php +++ b/pages/views/settings/templates.php @@ -42,6 +42,7 @@ loadingRecords: ' ', processing: 'Loading...', emptyTable: '
    No templates added yet
    ', + zeroRecords: '
    Nothing found
    ', search: '', searchPlaceholder: 'Search by name...', }, @@ -112,31 +113,59 @@ function actions(data, type, row){ $('#tdTempls').editable({ - container: 'body', - selector: 'a.name', - type: 'POST', - url: "/pages/update_data.php?tmpl=update", - title: 'Template name', - success: function (data) { - reload_data(); - }, - validate: function(value){ + container: 'body', + selector: 'a.name', + url: "/core/core.php?action=htmlTmplUpdate", + title: 'Template name', + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + success: function (data) { + if ( data.success ) { + reload_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, + validate: function(value){ if($.trim(value) == ''){ return 'This field is required'; } - } + } }); $('#tdTempls').editable({ container: 'body', selector: 'a.description', - type: 'POST', - url: "/pages/update_data.php?tmpl=update", + ajaxOptions: { + type: "POST", + dataType: 'json' + }, + url: "/core/core.php?action=htmlTmplUpdate", title: 'Short description', success: function (data) { - reload_data(); + if ( data.success ) { + reload_data(); + } else if ( data.error ) { + $('#toast-title').html('' + data.error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + } }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, validate: function(value){ if($.trim(value) == ''){ return 'This field is required'; @@ -151,26 +180,30 @@ function actions(data, type, row){ tmpl.Name = $(this).attr('data-name'); bootbox.dialog({ - title: "Confirm template removal", + title: "Confirm template deletion", message : 'Delete '+ tmpl.Name +'?', buttons :{ main: { - label : "Remove", + label : "Delete", className : "btn-danger", callback: function (){ - $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { - tmpl: 'delete', + action: 'htmlTmplDelete', tmplID: tmpl.ID, tmplName: tmpl.Name }, dataType: 'json', success: function (data) { reload_data(); - } + }, + error: function (xhr, status, error) { + $('#toast-title').html(' An error occurred, check server logs for more info. '+ error); + $('.toast-header').removeClass().addClass('toast-header alert-danger'); + $('.toast').toast('show'); + }, }); return true; @@ -189,10 +222,10 @@ className : "btn-secondary", $('#addTmpl').on('click', '[id*=sAdd]', function () { $.ajax({ - url: '/pages/update_data.php', + url: '/core/core.php', type: 'POST', data: { - tmpl: 'add', + action: 'htmlTmplAdd', tmpl_name: $("#tmpl_name").val(), tmpl_content: $("#tmpl_content").val(), tmpl_desc: $("#tmpl_desc").val(), @@ -200,12 +233,15 @@ className : "btn-secondary", dataType: 'json', success: function (data) { if(data.success){ - var msg = '
    x' + data.success + '
    '; + var msg = '
    x' + data.success + '
    '; + reload_data(); }else{ var msg ='
    x' + data.error + '
    '; } $('#tmpl_inf').html(msg); - reload_data(); + }, + error: function (xhr, status, error) { + $('#tmpl_inf').html('
    An error occurred, check server logs for more info. '+ error +'
    '); } }); }); @@ -228,7 +264,7 @@ function extrasShow() { const id = e.relatedTarget.dataset.id; const name = e.relatedTarget.dataset.name; - $.get("/pages/editHtmlTmpl.php?id=" + id) + $.get("/pages/views/settings/editHtmlTmpl.php?id=" + id) .then(data => { $("#editTmplLabel", this).html(name); $(".modal-body", this).html(data); @@ -270,7 +306,6 @@ function extrasShow() { - - diff --git a/releasenotes.md b/releasenotes.md index 87435a42..3cefedeb 100755 --- a/releasenotes.md +++ b/releasenotes.md @@ -1,9 +1,23 @@ -Whats New in v11.9 +Whats New in v12.0 -------------------------- -- Added system logs access via the UI for docker/cloud installations - this comes disabled by default and requires to be enabled in order to access it -- You can now hide properties column in formulas -- Fix a bug preventing formula categories to be shown properly -- Prevent deletion of the last left supplier in an ingredient -- Prevent adding an ingredient with incomplete supplier data to a formula -- New dashboard update, including better and cleaner view +- Lids inventory dropped to accessories +- Import json functions update +- Added import for accessories +- Added import for bottles +- Added import for suppliers +- Added import for customers +- Fixed pagination for suppliers +- Formula scaling improvements +- Fix invalid formula update date on empty formulas +- Update empty table message +- Rename sex to gender +- Error handling improvements +- Date Format update +- Auto update image for formulas when uploaded +- Auto update text title and description after a succesfull update for a formula +- Removed user alert to reload formula settings pages when making a changes +- Added openshift yaml manifests +- Added a dedicated page to display in case of fatal error +- Added a session timeout to automatically logoff the user after 30 minutes of inactivity - Please refer to the KB online if you want to change the default value +- Change selected material color to yellow in formula making for better descrimination - This release may include more changes, for full details please refer to the CHANGELOG