As you can see from the table below the user with the id of 1 has 10 points altogether
What I'm trying to do is have one number submitted from a form $edit_points to loop through and subtract from user 1
This number could be anything eg:
$edit_points = 6
would subtract 4 from the first record
then move to the next and only subtract the remainder 2
then break out of loop
UserID | TotalPoints
-------------------
1 | 4
1 | 4
1 | 2
4 | 3
3 | 3
5 | 4
This is what I've got so far
$pointLeft = $edit_points;//sent from form
while($point = mysqli_fetch_array($output)){
if($pointLeft > $point["TotalPoints"]){//if pointsLeft more than this record
$remainder = $pointLeft-$point["TotalPoints"];//get remainder
$query2 = "UPDATE pointstable SET TotalPoints=0 WHERE UserID=".$UserID;
$output2 = $mysqli->query($query2);
}elseif($pointLeft < $point["TotalPoints"]){
$remainder = $point["TotalPoints"] - $pointLeft;
$query2 = "UPDATE pointstable SET TotalPoints=".$remainder." WHERE UserID=".$UserID;
$output2 = $mysqli->query($query2);
}
$pointLeft = $remainder;
}
It works to a point and seems to populate all the records with the same last value that remainder holds
I've tried break and putting an if ($pointLeft<=0) above the first if
but none works.
any help? or a better way of doing it preferably using php
Thanks to Marty
Revised code below
There's a unique id PointID that I now use
$poinstLeft = $edit_points; //sent from form
while($point = mysqli_fetch_array($output)){
//if pointsLeft more than this record
if($poinstLeft >= $point["TotalPoints"]){
//get remainder
echo $poinstLeft." ";
$remainder = $poinstLeft-$point["TotalPoints"];
$query2 = "UPDATE pointstable SET TotalPoints=0 WHERE UserID=".$UserID." AND PointID=".$point["PointID"];
$output2 = $mysqli->query($query2);
// Calculate new pointsleft
$poinstLeft = $remainder;
} elseif ($poinstLeft < $point["TotalPoints"]){
$remainder = $point["TotalPoints"] - $poinstLeft;
echo $poinstLeft." ";
$query2 = "UPDATE pointstable SET TotalPoints=".$remainder." WHERE UserID=".$UserID." AND PointID=".$point["PointID"] ;
$output2 = $mysqli->query($query2);
// Here, your remainder is different from the upper half of your if-function!
// So, you don't have to recalculate pointsleft... It's just:
$poinstLeft = 0;
// Break the while loop:
break 2;
}
}
Related
I'm new to CodeIgniter. I'm trying to update the quantity of the table based on FIFO. I'm making a stock take page, if we count the physical item less than what the table has, we will reconcile and this will update the inventory table and the discard table. Updating inventory table is easy and I've done but I want to update the discard table's quantity based on FIFO. What I want is for example the quantity of item A in inventory table is 50 but when we count it physically it's 35, so when we reconcile, it should minus 15 from the discard table quantity.
Items
Qty
Date
Item A
5
2022-8-22
Item A
4
2022-8-22
Item A
9
2022-8-22
After update it should be like:
| Items | Qty | Date |
|:--------|:------:| --------:|
| Item A | 0 | 2022-8-22|
| Item A | 0 | 2022-8-22|
| Item A | 3 | 2022-8-22|
Please help me. If you need further clarification, do let me know. Thanks in advance
public function update_complete(){
$stock_diff = $this->input->post('stock_diff');
$counted_stock_value = $this->input->post('counted_stock_value');
$cost_diff = $this->input->post('cost_diff');
$reconcile = $this->input->post('reconcile');
$barcode = $this->input->post('barcode');
$stk_id = $this->input->post('stk_id');
for ($i = 0; $i < count($barcode); $i++)
{
$data = array(
'stocktake_value' => $counted_stock_value[$i],
'stock_diff' => $stock_diff[$i],
'cost_diff' => $cost_diff[$i],
'status' => $reconcile[$i]
);
// Commented for testing
$this->db->where('stk_id', $stk_id);
$this->db->where('barcode', $barcode[$i]);
$this->db->update('stocktake_trans', $data);
$itemResult = $this->item_model->getStockdiscardTransByBarcodeNew($barcode[$i]);
foreach($itemResult as $item)
{
$rest = $stock_diff[$i];
if($rest > 0)
{
if($item['quantity'] >= $rest)
{
$rest = $item['quantity']-=$rest;
//$rest = 0;
echo $rest;
}
else
{
$item['quantity'] = 0;
$rest = $rest - $item['quantity'];
}
$this->db->where('barcode', $barcode[$i]);
$this->db->update('stockdiscard_trans', array('quantity' => $rest));
}
}
}
// Update Stock Take
$data1 = array(
'reconciled_by' => $this->session->userdata('name'),
'reconciled_at' => date('Y-m-d')
);
$this->db->where('id', $stk_id);
$this->db->update('stocktake', $data1);
// Set message
$this->session->set_flashdata('stocktake_reconciled', 'Stock Take has been Reconciled!');
//redirect('stocktake/complete');
}
I understand you want to store the difference between the old stock and the new stock.
You can store the original quantity in a variable, update the product with the new value, and then do the difference between the original quantity and the new quantity. Finally, you store the difference in the discard table.
Is what I understood correct?
Edit 1:
Something like this?
$itemsModel = model('App\Models\itemsModel');
$totalDB = $itemsModel->where('Items', 'Item A')->select('sum(Qty)')->first(); // let say 50
$totalMag = 35;
$rest = $totalDB - $totalMag; // rest 50-35 = 15
$itemResult = $itemsModel->where('Items', 'Item A')->findAll();
foreach($itemResult as $item)
{
if($rest > 0)
{
if($item->Qty >= $rest)
{
$item->Qty -= $rest;
$rest = 0;
}
else
{
$item->Qty = 0;
$rest = $rest - $item->Qty;
}
$item->save();
}
}
Backtesting:
-remaining qty 15
5 >= 15? - FALSE
Qty = 0
Rest = 10
4 >= 10 FALSE
Qty = 0
Rest = 6
9 >= 6 TRUE
Qty = 9-6 = 3
Rest = 0
But you need to manage, for what will happen if the remaining stock of products will be more than 0 and the quantity of products A will be 0.
Lets say we have remaining qty to 19
5 >= 19? False
Qty = 0
Rest = 14
4 >= 14? False
Qty = 0
Rest = 10
9 >= 10? False
Qty = 0
Rest = 1
What will happen for the rest = 1 when all item in our table have 0 Qty?
I have two queries, one which will get a list of IDs from the main table, and another which will get all records in another table that relate to that ID.
I'd like to split it into pages of results, but my google searches are only coming up with people who want to have a certain number of results per column value, not who want to limit the overall count by it.
The main table has a column that contains the number of records, so actually reading the other table isn't needed. The limit would be used as a minimum value, so if there are still records left in the current group after the limit, it'll continue displaying them. That'd be somehow calculated as part of the offset so it can start in the correct place.
Here's an example of what I mean:
Table 1:
ID | Records
1 | 2
2 | 3
3 | 28
4 | 7
...
Table 2 (contents don't need to be known for this question):
ID | GroupID | Value
1 | 1 | x
2 | 1 | x
3 | 2 | x
4 | 2 | x
5 | 2 | x
6 | 3 | x
...
If the limit was given as 3 for example, both 1 and 2 should display on the first page, since just 1 by itself is under the limit. The next page will then start on 3, and that'll take up the entire page.
I could just manually count up using PHP until I reach the limit, though it might end up going slow if there were a lot of pages (I've no idea if mysql would be any better in that regard though). Here's a quick example of how that'd work to get the offset:
$page = 2;
$limit = 40;
$count = 0;
$current_page = 1;
$query = 'SELECT ID, Records FROM table1';
$stmt = $conn->prepare($query);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$count += $row['Records'];
if($count > $limit){
$current_page ++;
$count = 0;
if($current_page == $page){
$start_id = $row['ID'];
break;
}
}
}
Updated:
A "custom" Pagination is what you're looking for. So if you're planning to hop from page to page, you can't use hardcoded $page and $current_page values. Those values should be generated dynamically once you're on a particular page. In fact, you should have the ID column value in the query part of the URL so that the pagination links could satisfy your business logic.
Assuming the fact that your ID column value starts from 1, your code should be like this:
$id = isset($_GET['id']) && is_numeric($_GET['id']) ? $_GET['id'] : 1;
$limit = 40;
// Display query results based on particular ID number
$query = 'SELECT ID, Records FROM table1 WHERE ID >= ' . $id;
$stmt = $conn->prepare($query);
$stmt->execute();
$rowCount = $stmt->rowCount();
if($rowCount){
$total = 0;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
if($total <= $limit){
$total += $row['Records'];
// Display $row details here
}else{
// Get the next $id value
$id = $row['ID'];
break;
}
}
}
// Display relevant ID links
$query = 'SELECT * FROM table1';
$stmt = $conn->prepare($query);
$stmt->execute();
$idArr = array();
$total = 0;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
if($total == 0){
$idArr[] = $row['ID'];
}
if($total <= $limit){
$total += $row['Records'];
}else{
$total = 0;
}
}
foreach($idArr as $idValue){
if($idValue == $id){
echo '<a>'.$idValue.'</a> ';
}else{
echo ''.$idValue.' ';
}
}
Sidenote: If the ID column value of your table doesn't start from 1, then use a separate query to get the first ID value and update the following statement,
$id = isset($_GET['id']) && is_numeric($_GET['id']) ? $_GET['id'] : <FIRST_ID_VALUE>;
If you only need to create the "Next" button, you could try this way:
select t1.ID, t1.Records
from table1 t1
left join table1 t2
on t2.ID < t1.ID
and t2.ID > :last_selected_id_1
where t1.ID > :last_selected_id_2
group by t1.ID, t1.Records
having coalesce(sum(t2.Records), 0) < :limit
order by t1.ID
:last_selected_id_x is the last ID from the current page or 0 for the first page.
http://rextester.com/FJRUV28068
You can use MySQL session variables to create page links:
select page, min(ID) as min_id, max(ID) as max_id
from (
select ID
, #page := case when #sum = 0 then #page + 1 else #page end as page
, #sum := case when (#sum + Records) >= :limit
then 0
else #sum + Records
end as sum
from table1
cross join (select #sum := 0, #page := 0) initvars
order by ID
) sub
group by page
The result would look like:
page | min_id | max_id
1 | 1 | 2
2 | 3 | 3
3 | 4 | 4
http://rextester.com/LQVJWP18655
Note that it is officially (as of documentation) not recomended to use the session variables like that (read and write in one statement). Feature versions may break your code.
Here's the result I ended up with, I ended up basing it off Rajdeeps answer but tweaked so that it'll allow sorting.
$query = 'SELECT ID, Records FROM table1 ORDER BY something';
$stmt = $conn->prepare($query);
$stmt->execute();
$id_array = array(); // For storing each ID
$current_ids = array(); // For storing the current ID pages
$initial_ids = array(); // For storing the first page, in case the page is too high
$count = 0;
$current_page = 1;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$already_reset = false;
// Move the session to the next page if it's more over the limit than under
// For example, if a limit of 10 has 6 records already, and the next ID is 9 records, then start a new page
if($id_array and $count + $row['Records'] / 2 > $max_links){
array_push($id_array, $last_id);
$current_page ++;
$count = 0;
$already_reset = true; // Set a marker so that if this ID is larger than the limit then don't start a 2nd new page
}
// Backup the first results in case page is too high and needs to be reset to 1
if($current_page == 1){
array_push($initial_ids, $row['ID']);
}
$count += $row['Records'];
// The values that appear here are the results for the selected page
// They may not be in sequence so store the individual IDs
if($_GET['page'] == $current_page){
array_push($current_ids, $row['ID']);
}
// Start a new page if over the limit
if($count > $max_links and !$already_reset){
$current_page ++;
$count = 0;
array_push($id_array, $row['ID']);
}
$last_id = $row['ID'];
}
array_push($id_array, $last_id);
$total_pages = count($id_array);
// If page is invalid revert to default
if(!$current_ids){
$current_ids = $initial_ids;
$_GET['page'] = 1;
}
$_GET['page'] = max(1, min($total_pages, intval($_GET['page'])));
$current_ids is an array of the IDs for the current page, and $total_pages is pretty self explanatory.
I can't figure-it out how to count all these dancers columns and echo with total of all dancers
id | dancer1 | dancer2 | dancer3 | dancer4, and so on..
---------------------------------------
1 alex michael dalm name
2 clare rose test
I have this for the start but is not working:
$counter = mysql_query("SELECT COUNT(*) AS id FROM table");
$num = mysql_fetch_array($counter);
$dancers = $num["id"];
echo "Total dancers: $dancers";
Any help is appreciated. Thanks!
Try this:
$counter = mysql_query("SELECT * FROM table");
$dancers = 0;
while($rows = mysql_fetch_array($counter)){
for($i = 1; $i <= 24; $i++){
$dan_id = 'dancer'.$i;
if($rows[$dan_id] != "" || $rows[$dan_id] != null )
$dancers++;
}
}
echo "Total dancers:". $dancers;
Note: Never design your database table like this.
I would actually save your dancers in a different (easier) way... For examle:
ID NAME SURNAME PHONE ....
1 Anna Brickstone 0975 ...
2 Jef Damen 0754 ...
That way you could use the following code to count tables:
$dancersCount="0";
$sql = "SELECT * FROM dancers";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$dancersCount++;
}
} else {
echo "No dancers..";
}
echo"$dancersCount";
The counter will count +1 each time it finds a row (dancer)
If you really want to do it that way...
Then I don't really think there's an easy way to fix this... You will probably need to check how many columns you have in your database but that's not something i can help you with...
You need to change your table structure:
id | dancerNumber | name
1 1 alex
2 1 clare
3 2 michael
4 2 rose
5 3 dalm
6 3 test
7 4 name
8 4 dana
SELECT COUNT(*) AS id FROM table will return 8 dancers. If this is what you were looking for?
if you want to keep your structure then you need to do the following sql query
SELECT dancer1,
dancer2,
dancer3,
(CASE WHEN (dancer1 <> "" AND dancer1 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer2 <> "" AND dancer2 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer3 <> "" AND dancer3 IS NOT NULL) THEN 1 ELSE 0 END) AS COUNTER
FROM table
This will count all the non empty and non null columns and add a counter at the end of the table. this counter will then contain the number of dancers with your structure.
Full answer with your php code
$query = 'SELECT (CASE WHEN (dancer1 <> "" AND dancer1 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer2 <> "" AND dancer2 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer3 <> "" AND dancer3 IS NOT NULL) THEN 1 ELSE 0 END) AS COUNTER
FROM table'
$counter = mysql_query($query);
$num = mysql_fetch_array($counter);
$dancers = $num["COUNTER"];
echo "Total dancers: $dancers";
I have two data tables stock_incomes, stock_outcomes and stock_outcomes_fifo (the one I insert pre-calculated data):
stock_incomes (stores leftovers data)
id| Levtv
-----------
7 | 100
8 | 250
9 | 350
stock_outcomes (here is the point)
id| Quantity
--------------
1 | 150*
I have no problem when stock_outcomes.Quantity is less than 100 (min(Id) from stock_incomes, please see my code below) but I have no idea what code to write I could get calculations if outcome is >100. In my example I used 150 and I would like to get data in next table as:
stock_outcomes_fifo (the one I wish to insert pre-calculated data from the previous two tables)
id| IncomeId| OutcomeId| OutcomePart| Leftv
---------------------------------------------
1 | 7 | 1 | 100 | 0
2 | 8 | 1 | 50 | 200
Here is my code with question inside (see last part of the code):
<?php
include_once("config.inc.php");
include_once("db.class.php");
// stock_outcomes
$db = new db($host, $database, $user, $passwd);
$sql = "SELECT * FROM stock_outcomes WHERE Id = '1'";
$mas = $db->get_array($sql);
if($mas) {
foreach ($mas as $k => $v) {
$OutcomeId = $mas[$k]['Id'];
$OutcomeQuantity = $mas[$k]['Quantity'];
}
}
// stock_incomes
$sql = "select * from stock_incomes where Id = (select min(Id) from stock_incomes where Leftv > 0)";
$mas = $db->get_array($sql);
if($mas) {
foreach ($mas as $k => $v) {
$IncomeId = $mas[$k]['Id'];
$IncomeLeftv = $mas[$k]['Leftv'];
}
}
// insert into stock_outcomes_fifo
if ($OutcomeQuantity <= $IncomeLeftv) {
$OutcomePart = $OutcomeQuantity;
$FifoLeftv = $IncomeLeftv - $OutcomeQuantity;
mysql_query("INSERT INTO `stock_outcomes_fifo` (IncomeId,OutcomeId,OutcomePart,Leftv) VALUES ($IncomeId, $OutcomeId, $OutcomePart, $FifoLeftv)");
}
if ($OutcomeQuantity > $IncomeLeftv) {
// I have no idea what php function to use in this case... please give me direction, thank you...
}
?>
The question has been solved, here is the final working code in case someone might need it:
<?php
include_once("config.inc.php");
include_once("db.class.php");
// stock_outcomes
$db = new db($host, $database, $user, $passwd);
$sql = "SELECT * FROM stock_outcomes WHERE Id = '1'";
$mas = $db->get_array($sql);
if($mas){
foreach ($mas as $k=>$v) {
$OutcomeId=$mas[$k]['Id'];
$OutcomeBarCode=$mas[$k]['BarCode'];
$OutcomeQuantity=$mas[$k]['Quantity'];
}
}
/* - Start code */
if ($OutcomeQuantity > 0) {
$sql = "select * from stock_incomes where Leftv > 0 order by id asc";
$mas = $db->get_array($sql);
if ($mas) {
//filing stock_outcomes_fifo
foreach ($mas as $k=>$v) {
$IncomeId = $mas[$k]['Id'];
$IncomeQuantity = $mas[$k]['Quantity'];
$IncomeUnitPrice = $mas[$k]['UnitPrice'];
$IncomeLeftv = $mas[$k]['Leftv'];
$OutcomePart = min($OutcomeQuantity, $IncomeLeftv);
$FifoLeftv = $IncomeLeftv - $OutcomePart;
$FifoCost = $IncomeUnitPrice * $OutcomePart;
mysql_query("INSERT INTO `stock_outcomes_fifo` (BarCode,IncomeId,OutcomeId,OutcomePart,UnitPrice,Leftv,Cost) VALUES ($OutcomeBarCode, $IncomeId, $OutcomeId, $OutcomePart, $IncomeUnitPrice, $FifoLeftv, $FifoCost)");
mysql_query("UPDATE `stock_incomes` SET Leftv = ".$FifoLeftv." WHERE Id = ".$IncomeId);
$OutcomeQuantity -= $OutcomePart;
if ($OutcomeQuantity <= 0) break;
}
$OutcomeCostQuery = "select sum(Cost) as summ from stock_outcomes_fifo where OutcomeId = ".$OutcomeId."";
$OutcomeCost = mysql_query($OutcomeCostQuery);
$OutcomeCostResult = mysql_fetch_array($OutcomeCost);
mysql_query("UPDATE `stock_outcomes` SET Cost = ".$OutcomeCostResult["summ"]." WHERE Id = ".$OutcomeId."");
}
} /* - Finish code */
?>
Please help me let me explain with this.....
purchase table
id purchase_id product_id qty net_unit_cost created_at
-------------------------------------------------------------------------
1 1 1 10 10 2022-10-10
--------------------------------------------------------------------------
2 2 1 20 12 2022-10-10
Sale table
sale_id product_id qty net_unit_price created_at
1 1 11 15 2022-10-10
in this, if i sold '11' units then how can i subtract from the rows to get remaining units? i've to subtract '10' units from first row and '1' unit from second row...
I have tried this around a couple of ways and different manners but no luck. (also searched for different solutions) I am sure I'm just missing something.
I have the following code:
$variable = returned array eg. 7, 8, 9;
foreach($variable as $entry_id){
$query = mysql_query("SELECT * FROM table WHERE entry_id=$entry_id") or die (mysql_error());
while($row = mysql_fethc_array($query)){
$qty = $row['quantity'];
$combination = array_combine($qty);
}
}
Everything works and the correct quantities are returned (on testing) but the combinations are not correct. Currently the combinations - of each entry_id - is combined with the next one.
Instead of receiveing eg.
$entry_id(7) = 15;
$entry_id(8) = 26;
$entry_id(9) = 58;
I am getting:
$entry_id(7) = 15;
$entry_id(8) = 41;
$entry_id(9) = 99;
The table structure would look something like this:
entry_id | quantity
7 | 5
7 | 5
9 | 29
8 | 26
7 | 5
9 | 29