diff --git a/CHANGELOG.md b/CHANGELOG.md index 822359bb..d1ac7651 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,21 @@ # CHANGELOG +### Version 9.9 +- Record replaced ingredients when finalising a formula in the generated PDF +- Increase toast duration for formula making to 10 seconds +- Make sure the correct ingredient's quantity is reset when reseting an ingredient in Formula make which is replaced +- Update bottle add modal +- Prevent illegal characters from a bottle name +- Fix json import for ingredients if values contains illegal chars +- Implement signaling for formula reload when its updated via the API +- Prevent negative value when updating Make Formula data via the API +- Add odor to the data sent to PV Scale +- Increase update interval check from PV Scale to 5s +- Added separate notes field for Formula Make +- When a formula is marked as completed it generates a document in formula attachments +- Added API key to the data sent to PV Scale +- Add material skip when making a formula +- Add advanced material replacement when making a formula + ### Version 9.8 - Added phpMyAdmin definition in the docker compose - Update general settings to use toast messages diff --git a/VERSION.md b/VERSION.md index 021debdf..a61a79be 100755 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -9.8 +9.9 diff --git a/api.php b/api.php index e3a70ff8..0448c604 100644 --- a/api.php +++ b/api.php @@ -32,7 +32,7 @@ if(apiCheckAuth($key, $conn) == true){ $response['status'] = "Success"; }else{ - $response['status'] = "Failed"; + $response['status'] = "Auth failed"; } header('Content-Type: application/json; charset=utf-8'); echo json_encode($response); @@ -44,7 +44,7 @@ $_REQUEST['do'] = strtolower(mysqli_real_escape_string($conn, $_REQUEST['do'])); if(apiCheckAuth($key, $conn) == false){ - $response['status'] = "Failed"; + $response['status'] = "Auth failed"; header('Content-Type: application/json; charset=utf-8'); echo json_encode($response); return; @@ -291,6 +291,26 @@ //CALLBACKS if($_REQUEST['do'] == 'callback'){ + //SKIP MATERIAL FROM MAKE FORMULA + if($_REQUEST['action'] == 'skipMaterial'){ + $fid = mysqli_real_escape_string($conn, $_REQUEST['fid']); + $id = mysqli_real_escape_string($conn, $_REQUEST['id']); + $ingID = mysqli_real_escape_string($conn, $_REQUEST['ingId']); + $notes = mysqli_real_escape_string($conn, $_REQUEST['notes']) ?: "-"; + + if(mysqli_query($conn, "UPDATE makeFormula SET skip = '1', notes = '$notes' WHERE fid = '$fid' AND id = '$id'")){ + $response['success'] = true; + $response['message'] = $_REQUEST['ing'].' skipped from the formulation'; + file_put_contents($tmp_path.'reload_signal.txt', 'reload'); + } else { + $response['success'] = false; + $response['message'] = 'Error skipping the ingredient'; + } + header('Content-Type: application/json;'); + echo json_encode($response); + return; + } + if( $_REQUEST['action'] == 'makeFormula'){ $fid = mysqli_real_escape_string($conn, $_REQUEST['fid']); @@ -299,17 +319,26 @@ $qr = trim($_REQUEST['qr']); if (empty($fid) || empty($id) || empty($ingID) || empty($qr)) { - $response['error'] = 'Missing required params'; + $response['success'] = false; + $response['message'] = 'Missing required params'; echo json_encode($response); return; } if(!is_numeric($_REQUEST['q'])){ - $response['error'] = 'Invalid quantity value'; + $response['success'] = false; + $response['message'] = 'Invalid quantity value'; echo json_encode($response); return; } - + + if((double)$_REQUEST['q'] == 0.00){ + $response['success'] = false; + $response['message'] = 'Please add quantity'; + echo json_encode($response); + return; + } + $q = trim($_REQUEST['q']); $notes = mysqli_real_escape_string($conn, $_REQUEST['notes']); @@ -322,18 +351,22 @@ $q = $getStock['stock']; } mysqli_query($conn, "UPDATE suppliers SET stock = stock - $q WHERE ingID = '$ingID' AND preferred = '1'"); - $response['success'] .= "Stock deducted by ".$q.$settings['mUnit']; + $response['success'] = true; + $response['message'] = "Stock deducted by ".$q.$settings['mUnit']; } $q = trim($_REQUEST['q']); if($qr == $q){ if(mysqli_query($conn, "UPDATE makeFormula SET toAdd = '0' WHERE fid = '$fid' AND id = '$id'")){ - $response['success'] = $_REQUEST['ing'].' added'; + $response = array("success" => true, "message" => "Ingredient added"); } }else{ $sub_tot = $qr - $q; + //if ($sub_tot < 0) { + // $sub_tot += abs($sub_tot); + //} if(mysqli_query($conn, "UPDATE makeFormula SET quantity='$sub_tot' WHERE fid = '$fid' AND id = '$id'")){ - $response['success'] = 'Formula updated'; + $response = array("success" => true, "message" => "Quantity updated ($q)"); } } @@ -344,16 +377,19 @@ if($qr < $q){ if(mysqli_query($conn, "UPDATE makeFormula SET overdose = '$q' WHERE fid = '$fid' AND id = '$id'")){ - $response['success'] = $_REQUEST['ing'].' is overdosed, '.$q.' added'; + $response['success'] = true; + $response['message'] = $_REQUEST['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'; + $response['success'] = true; + $response['message'] = 'All materials added. You should mark formula as complete now'; } - - echo json_encode($response); + file_put_contents($tmp_path.'reload_signal.txt', 'reload'); + header('Content-Type: application/json;'); + echo json_encode($response); return; } diff --git a/core/pending_formulas_data.php b/core/pending_formulas_data.php index 6c6bb6b0..74987f22 100644 --- a/core/pending_formulas_data.php +++ b/core/pending_formulas_data.php @@ -44,9 +44,12 @@ foreach ($rs as $rq) { $gING = mysqli_fetch_array(mysqli_query($conn, "SELECT cas,odor FROM ingredients WHERE name = '".$rq['ingredient']."'")); $inventory = mysqli_fetch_array(mysqli_query($conn, "SELECT stock,mUnit FROM suppliers WHERE ingID = '".$rq['ingredient_id']."' AND preferred = '1'")); + $repq = mysqli_fetch_array(mysqli_query($conn, "SELECT name FROM ingredients WHERE id = '".$rq['replacement_id']."'")); $r['id'] = (int)$rq['id']; $r['fid'] = (string)$rq['fid']; + $r['repID'] = (string)$rq['replacement_id']; + $r['repName'] = (string)$repq['name']; $r['name'] = (string)$rq['name']; $r['ingredient'] = (string)$rq['ingredient']; $r['ingID'] = (int)$rq['ingredient_id']; @@ -63,7 +66,8 @@ $r['inventory']['mUnit'] = (string)$inventory['mUnit'] ?: $settings['mUnit']; $r['toAdd'] = (int)$rq['toAdd']; - + $r['toSkip'] = (int)$rq['skip']; + $rx[]=$r; diff --git a/css/vault.css b/css/vault.css index a13b39ac..5c855629 100755 --- a/css/vault.css +++ b/css/vault.css @@ -218,6 +218,11 @@ tr.strikeout td:before { text-decoration: line-through solid red 3px; } +.skipped { + font-style: italic; + text-decoration: line-through solid yellow 3px; +} + #formula td, table.table th { white-space: nowrap; diff --git a/db/pvault.sql b/db/pvault.sql index f454e295..46a1e640 100755 --- a/db/pvault.sql +++ b/db/pvault.sql @@ -65,11 +65,14 @@ CREATE TABLE `makeFormula` ( `name` varchar(255) COLLATE utf8_general_ci NOT NULL, `ingredient` varchar(255) COLLATE utf8_general_ci DEFAULT NULL, `ingredient_id` INT NOT NULL, + `replacement_id` INT NOT NULL DEFAULT '0', `concentration` decimal(5,2) DEFAULT 100.00, `dilutant` varchar(255) COLLATE utf8_general_ci DEFAULT NULL, `quantity` decimal(8,4) DEFAULT NULL, `overdose` double(8,4) NOT NULL DEFAULT 0.0000, `originalQuantity` double(8,4) DEFAULT NULL, + `notes` MEDIUMTEXT NULL, + `skip` INT NOT NULL DEFAULT '0', `toAdd` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; diff --git a/db/schema.ver b/db/schema.ver index 021debdf..a61a79be 100644 --- a/db/schema.ver +++ b/db/schema.ver @@ -1 +1 @@ -9.8 +9.9 diff --git a/db/updates/update_9.8-9.9.sql b/db/updates/update_9.8-9.9.sql new file mode 100644 index 00000000..b017a824 --- /dev/null +++ b/db/updates/update_9.8-9.9.sql @@ -0,0 +1,3 @@ +ALTER TABLE `makeFormula` ADD `notes` MEDIUMTEXT NULL AFTER `originalQuantity`; +ALTER TABLE `makeFormula` ADD `skip` INT NOT NULL DEFAULT '0' AFTER `notes`; +ALTER TABLE `makeFormula` ADD `replacement_id` INT NOT NULL DEFAULT '0' AFTER `ingredient_id`; \ No newline at end of file diff --git a/func/genBatchPDF.php b/func/genBatchPDF.php index 211b9a50..253148fb 100644 --- a/func/genBatchPDF.php +++ b/func/genBatchPDF.php @@ -117,9 +117,11 @@ function Code39($xpos, $ypos, $code, $baseline=0.5, $height=5){ $display_heading = array('name'=> 'Product', 'ingredient'=> 'Ingredient','concentration'=> 'Concentration',); $formula_q = mysqli_query($conn, "SELECT * FROM formulas WHERE fid = '$fid' ORDER BY ingredient ASC"); - + $header = array('Ingredient', 'CAS#', 'Purity %', 'Dilutant', 'Quantity', 'Concentration %'); $hd_blends = array('Ingredient', 'Contains','CAS#', 'Concentration %'); + $hd_extras = array('Ingredient', 'Notes'); + $hd_replacements = array('Ingredient', 'Replacement'); $meta = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM formulasMetaData WHERE fid = '$fid'")); @@ -202,11 +204,17 @@ function Code39($xpos, $ypos, $code, $baseline=0.5, $height=5){ $pdf->SetFont('Arial','BU',10); $pdf->MultiCell(250,10,"Also contains \n"); + + foreach($hd_blends as $heading) { $pdf->Cell(68,12,$heading,1,0,'C'); } + if($formulaTable == "makeFormula"){ + $qAllIng = mysqli_query($conn, "SELECT ingredient,quantity,concentration,notes,replacement_id FROM makeFormula WHERE fid = '$fid'"); + } else { + $qAllIng = mysqli_query($conn, "SELECT ingredient,quantity,concentration FROM $formulaTable WHERE fid = '$fid'"); - $qAllIng = mysqli_query($conn, "SELECT ingredient,quantity,concentration FROM $formulaTable WHERE fid = '$fid'"); + } while ($res_all_ing = mysqli_fetch_array($qAllIng)) { $bldQ = mysqli_query($conn, "SELECT ing,name,cas,percentage FROM allergens WHERE ing = '".$res_all_ing['ingredient']."'"); @@ -222,10 +230,66 @@ function Code39($xpos, $ypos, $code, $baseline=0.5, $height=5){ } } + //Extras table + $pdf->AddPage(); + $pdf->AliasNbPages(); + $pdf->SetFont('Arial','BU',10); + $pdf->MultiCell(250,10,"Additional information \n"); + + //ADD INFO + foreach($hd_extras as $heading) { + $pdf->Cell(140,12,$heading,1,0,'C'); + } + if($formulaTable == "makeFormula"){ + $qExtras = mysqli_query($conn, "SELECT DISTINCT A.ingredient, B.notes FROM formulas A JOIN makeFormula B ON A.ingredient = B.ingredient WHERE A.fid = '$fid' ORDER BY ingredient ASC"); + } else { + $qExtras = mysqli_query($conn, "SELECT ingredient,notes FROM formulas WHERE fid = '$fid'"); + + } + while ($res_extras = mysqli_fetch_array($qExtras)) { + $pdf->Ln(); + $pdf->SetFont('Arial','',8); + $pdf->Cell(140,8,$res_extras['ingredient'],1,0,'C'); + $pdf->Cell(140,8,$res_extras['notes'] ?: "-",1,0,'C'); + } + if($formulaTable == "makeFormula"){ + //Replacements table + $pdf->AddPage(); + $pdf->AliasNbPages(); + $pdf->SetFont('Arial','BU',10); + $pdf->MultiCell(250,10,"Replacements \n"); + + + foreach($hd_replacements as $heading) { + $pdf->Cell(140,12,$heading,1,0,'C'); + } + + $qRepl = mysqli_query($conn, "SELECT DISTINCT A.ingredient, B.replacement_id FROM formulas A JOIN makeFormula B ON A.ingredient = B.ingredient WHERE A.fid = '$fid' ORDER BY ingredient ASC"); + + while ($res_repl = mysqli_fetch_array($qRepl)) { + $repInfo = mysqli_fetch_array(mysqli_query($conn, "SELECT name FROM ingredients WHERE id = '".$res_repl['replacement_id']."'")); + + $pdf->Ln(); + $pdf->SetFont('Arial','',8); + $pdf->Cell(140,8,$res_repl['ingredient'],1,0,'C'); + $pdf->Cell(140,8,$repInfo['name'] ?: "-",1,0,'C'); + } + } + + + + + //GEN PDF $pdf = base64_encode($pdf->Output('S')); $docData = 'data:application/pdf;base64,' .$pdf; - - mysqli_query($conn, "INSERT INTO batchIDHistory (id,fid,pdf,product_name) VALUES ('$batchID','$fid','$pdf','".$meta['product_name']."')"); + if($formulaTable == "makeFormula"){ + + mysqli_query($conn, "INSERT INTO documents (ownerID,type,name,notes,docData) VALUES (".$meta['id'].",'5','$batchID','Auto generated by Formula Make','$docData')"); + + + }else{ + mysqli_query($conn, "INSERT INTO batchIDHistory (id,fid,pdf,product_name) VALUES ('$batchID','$fid','$pdf','".$meta['product_name']."')"); + } } diff --git a/pages/bottles.php b/pages/bottles.php index e22f8c35..f911b8cf 100644 --- a/pages/bottles.php +++ b/pages/bottles.php @@ -49,7 +49,7 @@