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?
Related
So I have this MySQL table where an item has a field called isCoupon. The default is set to 0 if the seller does not make the item available for coupon use. Each item is ordered by ID and in the shop, there can be more than one coupon where the item is also available for discount. But how do I make it that those coupons display when the item is included? How do I make it that the buyer gets to pick which coupon to use? And how do I calculate the new price if I put "50% off" on the record instead of 0.5?
Table Coupon
couponCode | items | discount
------------------------------
SAMPLE123 | 1 | 50% off
SAMPLE234 | 2,3 | 40% off
SAMPLE345 | 1,5 | 25% off
Table Item
itemID | isCoupon
-----------------
1 | 1
2 | 1
3 | 1
4 | 0
5 | 1
Thanks!
Try the below. As for the buyer picking to choose which coupon, you should let the buyer select the item first and then go to the checkout page by selecting the coupon.
$num_items = 5;
// the below array is used to store the coupons you can use for the item so you can
// proceed with it to the checkout page, there you can make a select dropdown to let
// the buyer select which coupon to use
$coupon_use = array();
for($i = 0; $i < $num_items; $i++) {
// check for current item
$SQL = "SELECT * FROM item WHERE itemID = '$i'";
$result = mysqli_query($connect, $SQL);
$field = mysqli_fetch_assoc($result);
// check if there is a coupon for the current item
if($field['isCoupon'] == 1) {
$SQL2 = "SELECT * FROM coupon";
$result2 = mysqli_query($connect, $SQL2);
// while method to go through every single coupon
while($field2 = mysqli_fetch_assoc($result2)) {
// if you put commas, you can use the explode method
// to store all the items for that coupon and use it to
// check for that current item
$coupons = explode(',', $field2['items']);
if(in_array($i, $coupons)) {
// do your items have a price?
// salePrice is the new price
// thePrice is the old price you need to get with $field (not $field2)
if($field2['discount'] == '50% off') { $salePrice = $thePrice * 0.5; }
else if($field2['discount'] == '40% off') { $salePrice = $thePrice * 0.6; }
else if($field2['discount'] == '25% off') { $salePrice = $thePrice * 0.75; }
// add the coupon code to the array of coupons available for use
array_push($coupon_use, $field2['couponCode']);
// display the prices
echo 'ITEM #'.$i.'<br><s>$'.$thePrice.'</s><br>$'.$salePrice.'<br><br>';
}
}
}
else { echo 'ITEM #'.$i.'$'.$thePrice; }
}
Now you can store the values of the coupon_use array to the checkout page.
I'm stuck with this problem because my loop stops at only the first row of the table. Every customer has a set budget for purchasing products which resets every week to purchase items if ever the qty is not equal to 0. The admin is the one who can process the order for the customer. Customers have a budget = 1000 from customers table. Then customer_product table has the qty of products to be purchased by the customer. For example product_id = 1 has a price of 20 and has the qty of 10 so 20 x 10 = 200. Budget would be deducted by 200, remaining budget would be 800 after looping through the first row. Now i want to continue looping through the 2nd row with the remaining 800 budget instead of the 1000. It continues to loop as long as he still has a budget.
Database tables
customer
id | name | budget
customer_product
product_id | cus_id | qty | status
products
id | name | price
Controller
public function processOrder($id)
{
$customers = Customer::find($id);
foreach ($customers->products as $product)
{
$status = $product->pivot->status;
$budget = $product-budget;
$price = $product->price;
$qty = $product->pivot->qty;
if ($status == 1) {
$i = $qty;
for ($i; $i > 0; $i--) {
if ($budget < 1) {
break;
} else {
$budget-=$price;
}
}
};
echo "Status 0";
}
}
Routes
Route::get('processOrder/{id}', ['as' => 'processOrder',
'uses' => 'AdminController#processOrder']);
I can process the first row of the table and when it reaches 0 qty with my for loop, it stops there and doesn't continue to process the next row even though his budget is still enough to purchase products from the next row. Can someone please help me with this problem?
You should save the customer's budget before going into the loop, then update it while you iterate through the products.
public function processOrder($id)
{
$customer = Customer::find($id);
$remainingBudget = $customer->budget;
foreach ($customer->products as $product) {
// Calculate the total price to get the desired qty of product
$cost = $product->price * $product->pivot->qty;
// If we have enough remaining budget go ahead with the purchase
if ($product->pivot->status == 1 && $remainingBudget >= $cost) {
// Decrease the remaining budget
$remainingBudget -= $cost;
}
}
}
You are forcing the loop to break at the very first index
echo "Status 0"; break;
So remove break; at the end.
update:
foreach($customers->products as $product){
$status = $product->pivot->status;
$budget = $product-budget;
$price = $product->price;
$qty = $product->pivot->qty;
if($status == 1){
do {
if($budget < 1) break;
$budget -=$price;
} while ($qty != 0);
}
}
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 need to implement an algorythm that can keep track of profits for a list of individual item transactions and update the 'profit' table. The idea is to fetch items bought and cross-reference them with items sold, purely by order (i.e no individual instancing of individual items exists, there are only IDs for item types). So, say we have a table with this data:
items:
item id item type
1 red box
2 blue box
3 white box
transactions:
item id -- quantity -- transaction_type -- price_unit($) -- time
1 3 buy 20 2015-10-10
3 1 buy 10 2015-10-11
1 1 sell 25 2015-10-12
1 1 sell 20 2015-11-14
3 1 sell 15 2015-11-13
For this example my profit table should look like:
item_id -- quantity -- profit -- timestamp_bought ---timestamp_sold
1 1 (25-20)=5 2015-10-10 2015-10-12
1 1 (20-20)=0 2015-10-10 2015-11-14
3 1 (15-10)=5 2015-10-11 2015-11-13
This is what I have so far. It works until several different buy/sell quantities come into play...
$buy_list = mysqli_query($con, "SELECT * FROM transaction WHERE
transaction_type = 'Buy' ORDER BY time DESC");
$sell_list = mysqli_query($con, "SELECT * FROM transaction WHERE
transaction_type = 'Sell' ORDER BY time DESC");
while($row = mysqli_fetch_array($buy_list))
{
array_push($buy_stack, array(
$row['idtrans'],
$row['iditem'],
$row['quantity'],
$row['time'],
$row['price_unit']));
}
while($row = mysqli_fetch_array($sell_list))
{
array_push($sell_stack, array(
$row['idtrans'],
$row['iditem'],
$row['quantity'],
$row['time'],
$row['price_unit']));
}
$size_buy = sizeof($buy_stack);
$size_sell = sizeof($sell_stack);
for($i=0; $i<=$size_buy-1; $i++) //iterate BUY orders
{
$idtrans_b = $buy_stack[$i][0];
$itemid_b = $buy_stack[$i][1];
$quantity_b = $buy_stack[$i][2];
$time_b = $buy_stack[$i][3];
$price_unit_b = $buy_stack[$i][4];
$quantity_b_calc = $buy_stack[$i][2];
for($k=0; $k<=$size_sell-1; $k++)
{
$idtrans_s = $sell_stack[$k][0];
$itemid_s = $sell_stack[$k][1];
$quantity_s = $sell_stack[$k][2];
$time_s = $sell_stack[$k][3];
$price_unit_s = $sell_stack[$k][4];
if($itemid_s == $itemid_b &&
$time_s > $time_b &&
$quantity_b > 0
&& $quantity_s >= $quantity_b) //match
{
$sell_stack[$k][1] = "done_sell";
$buy_stack[$i][1] = "done_buy";
$profit_unit = $price_unit_s - $price_unit_b;
$profit_ quantity = min($quantity_s, $quantity_b);
$quantity_b = $quantity_b - $profit_quantity;
$time_bought = $buy_stack[$i][3];
$time_sold = $sell_stack[$k][3];
$add_profit = mysqli_query
($con, "INSERT INTO profit (id, transaction_buy, transaction_sell, profit_unit, quantity, timestamp_buy, timestamp_sell)
VALUES ( 'null', '$idtrans_b', '$idtrans_s', '$profit_unit', '$profit_quantity', $time_bought, $time_sold));
}
}
}
I'm stuck to get this working properly. Should I scrap this and do it with stacks instead?
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;
}
}