diff --git a/CHANGELOG.md b/CHANGELOG.md
index d03ed4e1..8449698e 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,11 @@
# CHANGELOG
+### Version 11.4
+- Add shelf life for ingredients
+- Add temprature measurement unit
+- Add solubility options instead of a free text for ingredients
+- Cleaner and better view for formula comparison
+- Minor UI updates
+
### Version 11.3
- Minor UI updates
- Fix merge ingredient returning incorrect value when nothing found
diff --git a/VERSION.md b/VERSION.md
index 8bb42223..1c7134df 100755
--- a/VERSION.md
+++ b/VERSION.md
@@ -1 +1 @@
-11.3
+11.4
diff --git a/css/vault.css b/css/vault.css
index 9ba2e069..7ccc6f1e 100755
--- a/css/vault.css
+++ b/css/vault.css
@@ -832,10 +832,25 @@ body {
}
.pv_formula_diff {
- color: #858796;
background-color: #f6c23e75 !important;
}
+.pv_formula_nodiff {
+ background-color: #47aa5d !important;
+}
+
+.pv_formula_match {
+ background-color: #47aa5d !important;
+}
+
+.pv_formula_missing {
+ background-color: #bd8787 !important;
+}
+
+.pv_formula_added {
+ background-color: #a587bd !important;
+}
+
#formula_name {
display: inline;
}
@@ -1335,9 +1350,10 @@ hr.hr-text::before {
.badge-success {
color: #fff;
- background-color: #28a745;
+ background-color: #28a745 !important;
}
+
.badge-success[href]:hover, .badge-success[href]:focus {
color: #fff;
text-decoration: none;
diff --git a/db/pvault.sql b/db/pvault.sql
index 2def9f5b..aaf261fd 100755
--- a/db/pvault.sql
+++ b/db/pvault.sql
@@ -234,7 +234,8 @@ CREATE TABLE `ingredients` (
`isPrivate` INT NULL DEFAULT '0',
`molecularWeight` VARCHAR(255) NULL,
`physical_state` INT NULL DEFAULT '1',
- `cid` INT NULL,
+ `cid` INT NULL,
+ `shelf_life` INT NOT NULL DEFAULT '0'
`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -329,7 +330,8 @@ CREATE TABLE `settings` (
`pv_scale_enabled` INT NOT NULL DEFAULT '0',
`pv_host` VARCHAR(255) NOT NULL DEFAULT 'localhost',
`sds_disclaimer` MEDIUMTEXT NOT NULL DEFAULT 'PLEASE ADD A PROPER DISCLAIMER MESSAGE',
- `bs_theme` VARCHAR(255) NOT NULL DEFAULT 'light'
+ `bs_theme` VARCHAR(255) NOT NULL DEFAULT 'light',
+ `temp_sys` VARCHAR(255) NOT NULL DEFAULT '°C'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `settings` (`id`, `currency`, `top_n`, `heart_n`, `base_n`, `chem_vs_brand`, `grp_formula`, `brandName`, `brandAddress`, `brandEmail`, `brandPhone`, `brandLogo`) VALUES
diff --git a/db/schema.ver b/db/schema.ver
index 8bb42223..1c7134df 100644
--- a/db/schema.ver
+++ b/db/schema.ver
@@ -1 +1 @@
-11.3
+11.4
diff --git a/db/updates/update_11.3-11.4.sql b/db/updates/update_11.3-11.4.sql
new file mode 100644
index 00000000..25fd785d
--- /dev/null
+++ b/db/updates/update_11.3-11.4.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `settings` ADD `temp_sys` VARCHAR(255) NOT NULL DEFAULT '°C' AFTER `bs_theme`;
+ALTER TABLE `ingredients` ADD `shelf_life` INT NOT NULL DEFAULT '0' AFTER `cid`;
\ No newline at end of file
diff --git a/pages/compareFormulas.php b/pages/compareFormulas.php
index ff9b4fcf..9567db3b 100644
--- a/pages/compareFormulas.php
+++ b/pages/compareFormulas.php
@@ -9,12 +9,12 @@
INFO: You need to
create at least one formula first.
';
+ echo 'You need to
create at least one formula first.
';
return;
}
if(mysqli_num_rows(mysqli_query($conn, "SELECT id FROM ingredients WHERE type = 'Carrier' OR type = 'Solvent'"))== 0){
- echo 'INFO: You need to
add at least one solvent or carrier first.
';
+ echo 'You need to
add at least one solvent or carrier first.
';
return;
}
?>
@@ -66,8 +66,10 @@
url: '/pages/views/formula/cmp_formulas_data.php',
type: 'POST',
data: {
- id_a: $("#formula_a").val(),
+ id_a: $("#formula_a").val(),
+ name_a: $("#formula_a option:selected").text(),
id_b: $("#formula_b").val(),
+ name_b: $("#formula_b option:selected").text(),
},
dataType: 'html',
success: function (data) {
diff --git a/pages/update_data.php b/pages/update_data.php
index 8a019f32..f4cf4694 100755
--- a/pages/update_data.php
+++ b/pages/update_data.php
@@ -1665,11 +1665,12 @@ function formatVal($num){
$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' WHERE id='$ingID'";
+ $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!';
+ $response["success"] = 'Technical data has been updated';
}else{
$response["error"] = 'Something went wrong '.mysqli_error($conn);
}
diff --git a/pages/update_settings.php b/pages/update_settings.php
index 43f379f7..31dadb98 100644
--- a/pages/update_settings.php
+++ b/pages/update_settings.php
@@ -111,6 +111,7 @@
$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';
@@ -142,7 +143,7 @@
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'")){
+ 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);
diff --git a/pages/views/formula/cmp_formulas_data.php b/pages/views/formula/cmp_formulas_data.php
index bcf3ae81..56c2db0e 100644
--- a/pages/views/formula/cmp_formulas_data.php
+++ b/pages/views/formula/cmp_formulas_data.php
@@ -14,71 +14,146 @@
$(document).ready(function() {
var formula_a_length;
+ var formula_a_name = '=$_POST['name_a']?>';
+ var formula_b_name = '=$_POST['name_b']?>';
- var formula_a_table = $('#formula_a_table').DataTable( {
- dom: 'lfrtip',
- language: {
- loadingRecords: ' ',
- processing: 'Loading...',
- emptyTable: "Incomplete formula.",
- search: "Search in formula:",
- },
- ajax: {
- url: '/core/full_formula_data.php?id==$id_a?>'
- },
- columns: [
- { data : 'ingredient.name', title: 'Ingredient'},
- { data : 'purity', title: 'Purity %'},
- { data : 'quantity', title: 'Quantity'},
- ],
- lengthMenu: [[50, 100, 200, -1], [50, 100, 200, "All"]],
- pageLength: 100,
- displayLength: 100,
- });
+ var formula_a_table = $('#formula_a_table').DataTable({
+ dom: '<"top"f><"formula-name-a">rt<"bottom"lip><"clear">',
+ processing: true,
+ language: {
+ loadingRecords: ' ',
+ processing: 'Loading...',
+ emptyTable: "Incomplete formula.",
+ search: "",
+ searchPlaceholder: 'Search by name',
+ },
+ ajax: {
+ url: '/core/full_formula_data.php?id==$id_a?>'
+ },
+ columns: [
+ { data: 'ingredient.name', title: 'Ingredient' },
+ { data: 'purity', title: 'Purity %' },
+ { data: 'concentration', title: 'Concentration %' }
+ ],
+ lengthMenu: [[50, 100, 200, -1], [50, 100, 200, "All"]],
+ pageLength: 100,
+ displayLength: 100,
+ });
- formula_a_table.on('draw', function () {
- formula_a_length = formula_a_table.rows().count();
- });
-
-
- var url = '/core/full_formula_data.php?id==$id_b?>';
-
- var url = '/core/full_revision_data.php?fid==$_POST['fid']?>&revID==$_POST['revID']?>';
-
- var formula_b_table = $('#formula_b_table').DataTable({
- dom: 'lfrtip',
- language: {
- loadingRecords: ' ',
- processing: 'Loading...',
- emptyTable: "Incomplete formula.",
- search: "Search in formula:",
- },
- ajax: {
- url: url
- },
- columns: [
- { data : 'ingredient.name', title: 'Ingredient'},
- { data : 'purity', title: 'Purity %'},
- { data : 'quantity', title: 'Quantity'},
- ],
- lengthMenu: [[50, 100, 200, -1], [50, 100, 200, "All"]],
- pageLength: 100,
- displayLength: 100,
- rowCallback: function (formula_b_tableRow, formula_b_tableData) {
- for ( var y=0; y < formula_a_length; y++ ) {
- var formula_a_data = formula_a_table.row(y).data();
- if (formula_a_data.quantity === formula_b_tableData.quantity &&
- formula_a_data.ingredient.name === formula_b_tableData.ingredient.name) {
- $(formula_b_tableRow).removeClass().addClass('badge-success');
- break;
- }else{
- $(formula_b_tableRow).removeClass().addClass('pv_formula_diff');
- }
- }
- }
- });
+ $('').appendTo('.formula-name-a');
+
+ formula_a_table.on('draw', function () {
+ formula_a_length = formula_a_table.rows().count();
+ });
+
+ var url = '/core/full_formula_data.php?id==$id_b?>';
+
+ var url = '/core/full_revision_data.php?fid==$_POST['fid']?>&revID==$_POST['revID']?>';
+
+
+ var formula_b_table = $('#formula_b_table').DataTable({
+ dom: '<"top"f><"formula-name-b">rt<"bottom"lip><"clear">',
+ processing: true,
+ language: {
+ loadingRecords: ' ',
+ processing: 'Loading...',
+ emptyTable: "Incomplete formula.",
+ search: "",
+ searchPlaceholder: 'Search by name'
+ },
+ ajax: {
+ url: url
+ },
+ columns: [
+ { data: 'ingredient.name', title: 'Ingredient' },
+ { data: 'purity', title: 'Purity %' },
+ { data: 'concentration', title: 'Concentration %' }
+ ],
+ lengthMenu: [[50, 100, 200, -1], [50, 100, 200, "All"]],
+ pageLength: 100,
+ displayLength: 100,
+
+ rowCallback: function (formula_b_tableRow, formula_b_tableData) {
+ var isMatching = false;
+ var comparisonIcon = '';
+ var formula_a_data;
+
+ for (var y = 0; y < formula_a_length; y++) {
+ formula_a_data = formula_a_table.row(y).data();
+
+ if (formula_a_data.ingredient.name === formula_b_tableData.ingredient.name) {
+ isMatching = true;
+
+ if (parseFloat(formula_b_tableData.concentration) > parseFloat(formula_a_data.concentration)) {
+ comparisonIcon = '';
+ } else if (parseFloat(formula_b_tableData.concentration) < parseFloat(formula_a_data.concentration)) {
+ comparisonIcon = '';
+ }else {
+ comparisonIcon = '';
+ //$(formula_b_tableRow).removeClass().addClass('pv_formula_nodiff');
+ $(formula_b_tableRow).addClass('pv_formula_nodiff');
+
+ $(formula_a_table.row(y).node()).addClass('pv_formula_nodiff');
+ $('td:eq(2)', formula_a_table.row(y).node()).html(formula_a_data.concentration + ' ');
+ extrasShow();
+ }
+
+ $('td:eq(2)', formula_b_tableRow).html(formula_b_tableData.concentration + ' ' + comparisonIcon);
+ break;
+ }
+ }
+
+ if (!isMatching) {
+ $(formula_b_tableRow).removeClass().addClass('pv_formula_added');
+ var currentHtml = $('td:eq(2)', formula_b_tableRow).text();
+ $('td:eq(2)', formula_b_tableRow).html(currentHtml + ' ');
+
+ } else {
+ if (comparisonIcon !== '' && comparisonIcon.indexOf('fa-check') === -1) {
+ $(formula_b_tableRow).removeClass().addClass('pv_formula_diff');
+ } else {
+ $(formula_b_tableRow).removeClass().addClass('pv_formula_nodiff');
+ }
+ }
+ }
+ });
+
+ $('').appendTo('.formula-name-b');
+
+ formula_b_table.on('draw', function () {
+ formula_b_length = formula_b_table.rows().count();
+
+ formula_a_table.rows().every(function () {
+ var formula_a_data = this.data();
+ var isFoundInB = false;
+
+ for (var x = 0; x < formula_b_length; x++) {
+ var formula_b_data = formula_b_table.row(x).data();
+
+ if (formula_a_data.ingredient.name === formula_b_data.ingredient.name) {
+ isFoundInB = true;
+ break;
+ }
+ }
+
+ if (!isFoundInB) {
+ $(this.node()).addClass('pv_formula_missing');
+ var currentHtml = $('td:eq(2)', this.node()).text();
+ $('td:eq(2)', this.node()).html(currentHtml + ' ');
+ extrasShow();
+
+ }
+ });
+ });
+
+ function extrasShow() {
+ $('[rel=tip]').tooltip({
+ "html": true,
+ "delay": {"show": 100, "hide": 0},
+ });
+ };
-});//doc ready
+});
@@ -89,7 +164,7 @@
Ingredient |
Purity % |
- Quantity |
+ Concentration % |
@@ -100,7 +175,7 @@
Ingredient |
Purity % |
- Quantity |
+ Concentration % |
diff --git a/pages/views/ingredients/compos.php b/pages/views/ingredients/compos.php
index 66003904..f5d0ef71 100644
--- a/pages/views/ingredients/compos.php
+++ b/pages/views/ingredients/compos.php
@@ -92,7 +92,9 @@
order: [[ 1, 'asc' ]],
lengthMenu: [[20, 50, 100, -1], [20, 50, 100, "All"]],
pageLength: 20,
- displayLength: 20,
+ displayLength: 20,
+ scrollCollapse: true,
+ scrollY: '500px'
});
$('#allgName').on('input', function(){
diff --git a/pages/views/ingredients/ingDocuments.php b/pages/views/ingredients/ingDocuments.php
index 57b3c385..4fd3796b 100644
--- a/pages/views/ingredients/ingDocuments.php
+++ b/pages/views/ingredients/ingDocuments.php
@@ -62,7 +62,9 @@
order: [[ 1, 'asc' ]],
lengthMenu: [[20, 50, 100, -1], [20, 50, 100, "All"]],
pageLength: 20,
- displayLength: 20,
+ displayLength: 20,
+ scrollCollapse: true,
+ scrollY: '500px'
});
function dName(data, type, row){
diff --git a/pages/views/ingredients/ingSuppliers.php b/pages/views/ingredients/ingSuppliers.php
index ab735825..97a739cc 100644
--- a/pages/views/ingredients/ingSuppliers.php
+++ b/pages/views/ingredients/ingSuppliers.php
@@ -129,7 +129,8 @@
lengthMenu: [[20, 50, 100, -1], [20, 50, 100, "All"]],
pageLength: 20,
displayLength: 20,
-
+ scrollCollapse: true,
+ scrollY: '500px',
stateSave: true,
stateDuration : -1,
stateLoadCallback: function (settings, callback) {
diff --git a/pages/views/ingredients/synonyms.php b/pages/views/ingredients/synonyms.php
index 010fe7f4..e3238cba 100644
--- a/pages/views/ingredients/synonyms.php
+++ b/pages/views/ingredients/synonyms.php
@@ -65,7 +65,9 @@
order: [[ 1, 'asc' ]],
lengthMenu: [[20, 50, 100, -1], [20, 50, 100, "All"]],
pageLength: 20,
- displayLength: 20,
+ displayLength: 20,
+ scrollCollapse: true,
+ scrollY: '500px'
});
diff --git a/pages/views/ingredients/techData.php b/pages/views/ingredients/techData.php
index 3501867c..d704fbb2 100644
--- a/pages/views/ingredients/techData.php
+++ b/pages/views/ingredients/techData.php
@@ -4,14 +4,18 @@
require_once(__ROOT__.'/inc/sec.php');
require_once(__ROOT__.'/inc/opendb.php');
+require_once(__ROOT__.'/inc/settings.php');
if(!$_GET['ingID']){
echo 'Invalid ID';
return;
}
-$ing = mysqli_fetch_array(mysqli_query($conn, "SELECT id,tenacity,flash_point,chemical_name,formula,logp,soluble,molecularWeight,appearance,rdi FROM ingredients WHERE id = '".$_GET['ingID']."'"));
+$query = "SELECT id, tenacity, flash_point, chemical_name, formula, logp, soluble, molecularWeight, appearance, rdi, shelf_life FROM ingredients WHERE id = '".$_GET['ingID']."'";
+$result = mysqli_query($conn, $query);
+$ing = mysqli_fetch_array($result);
+$ing['soluble'] = explode(',', $ing['soluble']);
?>
Technical Data
@@ -20,22 +24,25 @@
@@ -46,25 +53,51 @@
-
+
@@ -74,11 +107,16 @@
+