Invoice Generator using checkboxes - Undefined Offset [2] PHP Codeigniter - php

I am trying to generate multiple invoices in a school management system.
Here is the issue:
For example I have 10 students in the DB
I am able to generate the invoices if the students are selected in consecutive order.
Student 1, Student 2, Student 3, Student 4
But once I miss a student from the consecutive order and try to generate in a random order it gives me an undefined offset error:
Student 1, Student 4, Student 5, Student 7
Here is the code:
for($x = 1; $x <= count($this->input->post('studentId')); $x++) {
$insert_data = array(
'class_id' => $this->input->post('className'),
'section_id' => $this->input->post('sectionName'),
'student_id' => $this->input->post('studentId')[$x],
'payment_name_id' => $payment_name_id
);
$status = $this->db->insert('payment', $insert_data);
}
return ($status === true ? true : false);
The same also applies to editing the invoices once it has been generated.
I even tried changing the for loop to a while loop for that one, which does not give me any error but it just doesn't save if the students selected are in a random order:
$x = 1;
$form_fields = count($this->input->post('editStudentId'));
while($x <= $form_fields) {
if(!empty($this->input->post('editStudentId')[$x])) {
$update_payment_data = array(
'class_id' => $this->input->post('editClassName'),
'section_id' => $this->input->post('editSectionName'),
'student_id' => $this->input->post('editStudentId')[$x],
'payment_name_id' => $id
);
$status = $this->db->insert('payment', $update_payment_data);
}
$x++;
}
return ($status === true ? true : false);
IMAGE - SELECTING STUDENTS:
IMAGE- POST SAVE WITH JUST 2 out of the 4 I SELECTED:

Replace for with foreach:
foreach ($this->input->post('studentId') as $studentId) {
$insert_data = array(
'class_id' => $this->input->post('className'),
'section_id' => $this->input->post('sectionName'),
'student_id' => $studentId,
'payment_name_id' => $payment_name_id
);
$status = $this->db->insert('payment', $insert_data);
}

Related

laravel condition add amount nested

Code: I have a condition on this, but it's not clear for me
$check_account1 = false;
$check_account2 = false;
$user1_amount = 100;
$user2_amount = 100;
if ($account->type == "A") {
$check_account1 = true;
$amount = 100;
if ($check_account1) {
$amount = $user1_amount;
} else {
$amount += $user1_amount;
}
} elseif ($account->type == "B") {
$amount = $user2_amount;
}
$insert = new Amount;
$insert->user_id = $account->id;
$insert->amount = $amount;
$insert->save();
EDIT: I have a users which has a rank of Basic, Junior, Premium, Advanced, Senior, which is every user has it's corresponding amount based on their rank.
If someone is not present or not available, the amount based on his rank will go to the rank next to him, if the user is present he will receive the amount based on his rank. So if Basic, Junior, Premium and Advanced is not present, the sum of their corresponding amount will go to Senior
Present meaning it's in the database table, if the loop doesn't get a user with that rank, I call it absent.
This is how it goes:
Basic - 10
Junior - 20
Premium - 30
Advanced - 40
Senior - 50
$amount_to_transfer = 0;
$amount_to_receive = 0;
foreach($users as $user){
if($user->rank == 'Basic'){
// basic is present, add 10 to himself, if not 10 will go to the next rank which is Junior
$amount->amount = 10;
$amount->save();
}
else{
//
}
}
Because you want to loop through your users, and transfer amount from those that are not present to the first next user that is present, here is the code that should accomplish that task:
$amount_to_transfer = 0;
$amount_to_receive = 100;
foreach($users as $user){
if($user->present){
$user->amount += $amount_to_receive + $amount_to_transfer;
$amount_to_transfer = 0;
// If you want to save the user here
// $user->save();
}
else{
$amount_to_transfer += $amount_to_receive;
}
}
I assumed that your user model has present property which tells if the user is present or not (boolean value) and that the amount is stored in amount field. You can adapt this condition based on your properties in your User model.
All in all, you just need to define a transfer amount, which starts off as zero and add it alongside with receiving amount every time the user is present. If user is not present, just increment the amount to transfer so it can be added to first next present user.
Adapted
Here is the adapted code, I used dummy collections and ranks. Please adapt this to your settings. In this example there is no Advanced rank, so senior will get 50 + 40 amount.
$ranks = collect([
(object) ['name' => 'Basic', 'amount' => 10],
(object) ['name' => 'Junior', 'amount' => 20],
(object) ['name' => 'Premium', 'amount' => 30],
(object) ['name' => 'Advanced', 'amount' => 40],
(object) ['name' => 'Senior', 'amount' => 50],
]);
$users = collect([
(object) ['rank' => 'Basic', 'amount' => 0],
(object) ['rank' => 'Junior', 'amount' => 0],
(object) ['rank' => 'Premium', 'amount' => 0],
(object) ['rank' => 'Senior', 'amount' => 0],
(object) ['rank' => 'Basic', 'amount' => 0],
]);
$amount_to_transfer = 0;
$available_ranks = $users->pluck('rank');
foreach($ranks as $rank){
if(!in_array($rank->name, $available_ranks->toArray()))
{
$amount_to_transfer += $rank->amount;
}
else{
$usersOfThisRank = $users->filter(function($usr, $key) use($rank){
return $usr->rank == $rank->name;
});
$usersOfThisRank->map(function($usr, $key) use($rank, $amount_to_transfer){
$usr->amount += $rank->amount + $amount_to_transfer;
// $usr->save();
});
$amount_to_transfer = 0;
}
}

how to return always 5 index rows in php array?

I am having a problem with returning specific rows of the array in PHP.
I need to always return 5 rows of data in my array so that I don't need to create logic on my view, and with this, I can just display it by using an index.
In my view, I need to display the top 5 users:
1. bob
2. alice
3. MARIA
4. dell
5. cheka
The 3rd row will always be the user which is log in. If there is no row 4 and row 5 the output should be:
1. bob
2. alice
3. MARIA
4. N/A
5. N/A
The same if there is no users above him, and if he is the only one user:
1. N/A
2. N/A
3. MARIA
4. N/A
5. N/A
this is the PHP code that I have currently:
public function GetUserRank(){
$results = $this->Transfer_model->select_all_ranking();
for ($i=0; $i < count($results); $i++) {
if ($this->session->userdata('id') == $results[$i]->id) {
if ($results[$i]< 3) { // there aren't two people ahead of you
// return rows 0 to 4
}elseif ($results[$i] > -3) {
// code...
}else{
// code...
}
}
}
}
Here is the sample response:
Array ( [0] => stdClass Object ( [id] => 1 [name] => MARIA [lob_id] => 3 [current_rank] => 5 ) [1] => stdClass Object ( [id] => 2 [name] => bob [lob_id] => 3 [current_rank] => 2 ) )
The response is already fixed in the query, so that is the actual order of the list of users and the response will likely to have 100 rows or more or it can be less, I just first need to select on my loop the ID of the login users then I will get the two above and the two below of the login user.
Can I do this on array? By doing this I can save time without doing any logic in my view part.
Any help would be really appreciated.
You need to select elements before and after your user. Later just pad those arrays and lastly merge them.
Something like this:
function findUserPosition($inputs, $userId)
{
foreach($inputs as $key => $input){
if ($userId == $input['user_id']){
return $key;
}
}
}
function getResults($inputs, $userId)
{
$userPosition = findUserPosition($inputs, $userId);
$positionsBefore = 2;
$positionsAfter = 2;
$sliceAfter = $positionsBefore;
$sliceBefore = $userPosition-$positionsBefore;
if ($sliceBefore < 0){
$sliceAfter = $sliceAfter - abs($sliceBefore);
$sliceBefore = 0;
}
$elementsBefore = array_slice($inputs, $sliceBefore, $sliceAfter , false);
$elementsAfter = array_slice($inputs, $userPosition+1, $positionsAfter, false);
$paddedElementsBefore = array_pad($elementsBefore, $positionsBefore*-1, ['user_id'=>'N/A', 'score'=>'N/A']);
$paddedElementsAfter = array_pad($elementsAfter, $positionsAfter, ['user_id'=>'N/A', 'score'=>'N/A']);
$results = array_merge($paddedElementsBefore, [$inputs[$userPosition]], $paddedElementsAfter);
return $results;
}
//---===EXAMPLE===---
$exampleInput = [
['user_id' => 100, 'score' => 5000],
['user_id' => 25, 'score' => 4535],
['user_id' => 236, 'score' => 3823],
['user_id' => 263, 'score' => 3612],
['user_id' => 134, 'score' => 3123],
['user_id' => 11, 'score' => 2412],
['user_id' => 84, 'score' => 2113],
['user_id' => 345, 'score' => 1635],
['user_id' => 133, 'score' => 1254],
['user_id' => 156, 'score' => 244]
];
function displayExample($results, $userId)
{
echo '<table>';
foreach($results as $result){
if ($result){
if ($result['user_id'] == $userId){
echo '<tr><td><b>'.$result['user_id'].'</b></td><td><b>'.$result['score'].'</b></td></tr>';
}else{
echo '<tr><td>'.$result['user_id'].'</td><td>'.$result['score'].'</td></tr>';
}
}else{
echo '<tr><td>NULL</td><td>NULL</td></tr>';
}
}
echo '</table>';
}
//DEMO 1
$currentUserId = 134;
$results = getResults($exampleInput, $currentUserId);
displayExample($results, $currentUserId);
echo '-------------';
//DEMO 2
$currentUserId = 25;
$results = getResults($exampleInput, $currentUserId);
displayExample($results, $currentUserId);
echo '-------------';
//DEMO 3
$currentUserId = 156;
$results = getResults($exampleInput, $currentUserId);
displayExample($results, $currentUserId);
echo '-------------';

How to Insert checked checkboxes and delete unchecked checkboxes using php and mysql?

I have a 3 tables:
product, category and product_category.
I am creating a form who edit(insert/delete) categories for a product.
I am trying to insert an array of checkboxes in a relation table.
<input name="category[]" type="checkbox" value="<?php echo $cat->slug; ?>">
I know how to insert the checked values, but I don't know how to delete the unchecked ones.
$category = $_POST['category'];
for ($i = 0; $i < count($category); $i++) {
if (!empty($category)) {
$verifycategory = BD::conn()->prepare("SELECT * FROM `product_category` WHERE id_product = ? AND id_category = ?");
$verifycategory->execute(array($id_prod, $category[$i]));
if ($verifycategory->rowCount() == 0) {
$anm = BD::conn()->prepare("INSERT INTO product_category(id_product, id_category) VALUES(?,?)");
$anm->execute(array($id_prod, $category[$i]));
}
}
}
When you created the form/output you must have had an array of the possible checkboxes.
Just compare the values in this list to the ones posted.
$aCheckboxes = array(
'0' => array('ID' => 1, 'Name' => 'box1'),
'1' => array('ID' => 2, 'Name' => 'box2'),
'2' => array('ID' => 3, 'Name' => 'box3')
);
$aToDelete = array();
foreach($aCheckboxes as $iPos => $a){
if(!in_array($a['ID'], $_POST['category']){
$aToDelete[] = (int)$_POST['category'];
}
}
var_dump($aToDelete);

use of for loop counter in if condition php

Below if my code for column search of datatables as well as complete search,
$columns = array(0 => 'ship_id' ,
1 => 'sr',
2 => 'ce',
3 => 'sto',
4 => 'supply' ,
5 => 'part',
6 => 'description',
7 => 'quantity',
8 => 'date',
9 => 'shipn',
10 => 'ship',
11 => 'transport',
12 => 'docket',
13 => 'delivery');
if(isset($searchValue) && $searchValue != '')
{
$searchingAll = array();
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = $this->db->or_like($columns[$i], $searchValue);
$searchingColumns = NULL;
}
}
else if($this->input->post('columns[1][search][value]', TRUE) != '')
{
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = NULL;
$searchingColumns = $this->db->or_like($columns[1], $this->input->post('columns[1][search][value]', TRUE));
}
}
else
{
$searchingAll = NULL;
$searchingColumns = NULL;
}
First IF condition will search complete datatable, then else-if will search individual column,
I have 12 columns in my datatables, so i need to loop 12 times else-if condition,
In above code currently i shown only column 1, but i need to check all 12 columns that something is entered in any of column search then it will go to for loop of else-if condition,
How can i check all 12 columns in else-if condition?
Thanks,
You were not using the $i you defined in the else if.
Use this instead:
$columns = array(0 => 'ship_id' ,
1 => 'sr',
2 => 'ce',
3 => 'sto',
4 => 'supply' ,
5 => 'part',
6 => 'description',
7 => 'quantity',
8 => 'date',
9 => 'shipn',
10 => 'ship',
11 => 'transport',
12 => 'docket',
13 => 'delivery');
if(isset($searchValue) && $searchValue != '')
{
$searchingAll = array();
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = $this->db->or_like($columns[$i], $searchValue);
$searchingColumns = NULL;
}
}
else if($this->input->post('columns[1][search][value]', TRUE) != '')
{
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = NULL;
$searchingColumns = $this->db->or_like($columns[$i], $this->input->post('columns['.$i.'][search][value]', TRUE));
}
}
else
{
$searchingAll = NULL;
$searchingColumns = NULL;
}

Using a loop to perform multiple SQL inserts using Codeigniter/Activerecord

I have an array that looking like this:
Array
(
[currency] => GBP
[shipping] => 3.5
[tax] => 0
[taxRate] => 0
[itemCount] => 3
[item_name_1] => Proletarian Sparrow
[item_quantity_1] => 2
[item_price_1] => 75
[item_name_2] => Guillemot Colony
[item_quantity_2] => 5
[item_price_2] => 20
[item_name_3] => Dandelion Clock
[item_quantity_3] => 2
[item_price_3] => 50
)
I'm trying to use a loop to extract the individual item details and insert a row in a database for each one. I'm using Codeigniter.
My model looks like this:
public function set_order($cust_id, $order_data)
{
// Breaks up order information and creates a new row in the pn_orders tables for each item
// Get the last row in the orders table so we can work out the next order_id
$this->db->order_by('order_id', 'desc');
$this->db->limit(1);
$query = $this->db->get('pn_orders');
$row = $query->row_array();
// If the resulting array is empty, there are no orders so we can set the order_id to 1. If there is already an order_id, just add 1 to it.
if (empty($row)) {
$order_id = 1;
} else {
$order_id = $row['order_id'] + 1;
}
//echo "<pre>";
//print_r($order_data);
//echo "</pre>";
// The delivery message input has a placeholder. if the user's input is different to this, assign it to $delivery_message.
if ($this->input->post('delivery_message') == "e.g. if out, leave in porch") {
$delivery_message = NULL;
} else {
$delivery_message = $this->input->post('delivery_message');
}
// Set today's date for insertion into the DB
$date = date('Y-m-d');
// The order information is clumped together in a single array. We have to split out single items by looping through the array before inserting them into the DB.
for ($i = 1; $i <= $order_data['itemCount']; $i++) {
$item = array(
'order_id' => $order_id,
'cust_id' => $cust_id,
'date_ordered' => $date,
'item_name' => $order_data["item_name_{$i}"],
'item_quantity' => $order_data["item_quantity_{$i}"],
'item_price' => $order_data["item_price_{$i}"],
'payment_method' => $_POST['payment_method'],
'delivery_message' => $delivery_message
);
$this->db->insert('pn_orders', $item);
}
}
Everything seems to be in place, however, only 1 row is ever inserted and I can't work out why. It seems very simple.
Is it something to do with the Activerecord pattern?
Thanks.
First print out the array to see if the array structure is correct or not. If its Okay then just use insert_batch like this:
for ($i = 1; $i <= $order_data['itemCount']; $i++) {
$items[] = array(
'order_id' => $order_id,
'cust_id' => $cust_id,
'date_ordered' => $date,
'item_name' => $order_data["item_name_{$i}"],
'item_quantity' => $order_data["item_quantity_{$i}"],
'item_price' => $order_data["item_price_{$i}"],
'payment_method' => $_POST['payment_method'],
'delivery_message' => $delivery_message
);
}
//echo "<pre>";print_r($item);echo "</pre>";die; uncomment to see the array structure
$this->db->insert_batch('pn_orders', $items);

Categories