How to increment MAXIMUM value in laravel - php

I need to increment the revision no. (known as quot_rev, not a primary key as there is already record id) which is based on quot_id, so I need to get the maximum (highest) quot_rev value and then increment it when the user goes to the edit page, in which the user can save it as a new record.
public function edit($quot_id)
{$quotation = Quotation::where('quot_id', $quot_id)->orderBy('quot_rev', 'desc')->latest()->first();
if ($quotation->quot_rev > 0){
$quotation->max('quot_rev')+1;
}
return view('quotation.quotation_edit', compact('quotation', 'quot_rev'));
For the above code, laravel only show the max quot_rev no. but it didn't add 1 for me.
I have tried several ways like $quotation->increment(max('quot_rev')); and $quotation->max('quot_rev')++; but it all didn't work. Either it says error or it did not add 1.
Can anyone be able to help? I'm still a beginner at laravel. TIA.

you don't need to send quotation and quote_rev seperatly. you can get it from quotation objct
public function edit($quot_id)
{
$quotation = Quotation::where('quot_id', $quot_id)->orderBy('quot_rev', 'desc')->first(); // your query is duplicated, you can remove the latest(),
if ($quotation->quot_rev > 0){
$quotation->quot_rev = $quotation->quot_rev+1;
}else{
$quotation->quot_rev = 1;
}
//if you want to save it in database as welll
$quotation->save();
return view('quotation.quotation_edit', compact('quotation'));
}

You can try this
public function edit($quot_id)
{
$quotation = Quotation::where('quot_id', $quot_id)->orderBy('quot_rev', 'desc')->first(); // your query is duplicated, you can remove the latest(),
$maximum = 0;
if ($quotation->quot_rev > 0){
$maximum = $quotation->quot_rev+1;
}
return view('quotation.quotation_edit', compact('maximum'));
If you just need the next quot_rev, you can just pass the $maximum variable
Hope this helps.

Related

php import excel file error function str_replace

I have the code below, the purpose is to automatically add the product code.
For example, if the product code field is left blank, the default first product will be SP00001.
The next product will be SP00002...
The code still works fine with manually adding products. However, when I use the excel file to import data, I get the above code error.
The place where the product code runs is quite chaotic, only the first product is the code SP00001, then the full SP00002. The next time the code is entered, the codes are repeated a lot without knowing what's wrong. Thanks for your help.
public function cms_save_product($data){
$store_id = $this->auth['store_id'];
$data['user_init'] = $this->auth['id'];
if ($data['prd_code'] == '') {
$code = $this->db
->select('prd_code')
->from('products')
->like('prd_code', 'SP')
->order_by('created desc')
->get()
->row_array();
if(empty($code)){
$data['prd_code'] = 'SP00001';
}else{
$max_code = (int)(str_replace('SP', '', $code['prd_code'])) + 1;
if ($max_code < 10)
$data['prd_code'] = 'SP0000' . ($max_code);
else if ($max_code < 100)
$data['prd_code'] = 'SP000' . ($max_code);
else if ($max_code < 1000)
$data['prd_code'] = 'SP00' . ($max_code);
else if ($max_code < 10000)
$data['prd_code'] = 'SP0' . ($max_code);
else if ($max_code < 100000)
$data['prd_code'] = 'SP' . ($max_code);
}
}
$this->db->insert('products', $data);
}
It looks like you are using the record create date for ordering when looking for the greatest product code. If you are inserting many records in a loop while importing from a spreadsheet, and using something like datetime for your time format, this will cause your routine to generate the same code repeatedly until the next second ticks by. You should use something like:
SELECT MAX(prd_code) FROM products WHERE prd_code LIKE 'SP%'
for your query. This will ensure that you are always incrementing the highest product code.
You also have a problem where there is a maximum of 99999 product codes, which may be too low.
For the product code formatting, your logic can be greatly simplified by using str_pad.
This will completely replace empty codes with SP00001, and handle formatting the code with the correct number of zeroes in order to match the desired length.
$defaultCode = 'SP';
if (empty($code))
{
$data['prd_code'] = $defaultCode;
}
else
{
// Remove the SP prefix from the product code and cast to an int
$numCode = (int)(str_replace('SP', '', $code['prd_code']));
// Increment code
$numCode++;
/*
* Set the pad length to either the size of the default code, or the
* length of the stored product code plus 2 (for "SP" prefix), whichever is larger.
* This ensures that the codes always begin with SP even if they are longer than expected.
*/
$padLength = max(strlen($defaultCode), strlen($numCode) + 2);
// Format the product code using the default code as a left pad
$data['prd_code'] = str_pad($numCode, $padLength, $defaultCode, STR_PAD_LEFT);
}

How can I add records on an empty table

I have an empty table in my database in MySQL, and I trying to add multiple records
(I do this in this way because I'm following and order; If I delete a record then the auto increment field (id) skips 1 value. For example. I delete the id = 340 and then the following record start with an id with a value = 341)
I have an If Else statement in a function in my controller where I use to compare the id itself of my table Hours.
public function showHours($id){
$complex = ComplexNew::find($id);
$fields = CourtsComplex::all();
$hours = HoursNew::all();
$last_hours = collect($hours)->last();
if ($last_hours->id == $last_hours->id){
$last_hours->id = $last_hours->id + 1;
}else{
return Redirect()->back();
}
return view('hours.FormNewHours')->with('complex', $complex)->with('fields', $fields)->with('last_hours', $last_hours);
}
And this line is the line where I have the error.
if ($last_hours->id == $last_hours->id){
//DO SOMETHING
// ...
}
The error is: 'Trying to get property 'id' of non-object'.
Also I was trying to add another if else statement something like this:
if(is_null($last_hours->id)){
$last_hours->id = 1;
}else if($last_hours->id == $last_hours->id){
//ADD +1 TO ID.
}
Because I want that if the table is empty the id of the first record must be started with value = 1 but if the table is not empty add 1 to the last id, like a for statement because this condition add always +1 to last id.
Change
$last_hours = collect($hours)->last();
to
$last_hours = $hours->last();
Plus dd($last_hours) if it returns object then try accessing id like $last_hours->id

CodeIgniter Wildcard Query

I am trying to perform a wildcard search query using CI.
I am checking for loggedin sessions. If a user is logged into more than one device, a popup is displayed. To check if the user is logged in from any other device, I perform a wildcard query to check the existence of its user id in the user_data column and return the number of rows. The problem I am facing is, even if I am logging in for the first time, it goes to the else clause and not to if or if-else clause.
In my controller, I am checking if it reaches the else clause, display a popup. However, it is going to the else clause even if someone is logging in for the first time.
Model:
public function update_bool($id) {
$this->db->select('user_data');
$this->db->from('ci_sess');
$this->db->like('user_data', $id, 'both');
$counter = $this->db->get()->row();
if (empty($counter)) $counter = 0;
else if($counter === 1) $counter = 1;
else $counter = 3;
return $counter;
}
Controller:
$counter = $this->ion_auth_model->loggedin_status_update_bool($userId);
if($this->ion_auth_model->loggedin_status_update_bool($userId) === 3) {
warning('multiple_session_title', 'multiple_session_text');
}
You need to count number of rows return by the query. And based on no of records, your condition will work. Currently its returning one row of type array. And $counter as array to match else if condition will always fail.
I hope this will help you.
....
$query = $this->db->get();
$counter = $query->num_rows();
if (empty($counter)) {
$counter = 0;
}else if($counter === 1) {
$counter = 1;
} else {
$counter = 3;
}
return $counter;
I think your shorthand might be off a little and if I understand what you mean then there would be multiple sessions for the same user in the table meaning you couldn't get it using ->row().
Try like this:
public function update_bool($id) {
$this->db->select('user_data');
$this->db->from('ci_sess');
$this->db->like('user_data', $id, 'both');
$query = $this->db->get();
return $query->num_rows(); // This will give you now many times this user exists in the database, eg 0, 1, 2, 3
}
Then clean up your controller so you're not calling the database twice:
$counter = $this->ion_auth_model->loggedin_status_update_bool($userId);
if($counter == 3) {
warning('multiple_session_title', 'multiple_session_text');
}

How to generate voucher code, check the DB if it's unique, generate new one if not

I'm having a loop issue in my script. I've spent a lot of time trying to fix it but I still don't know how to fix the problem. I need your help and suggestions regarding this.
My goal is to create a voucher code generator script where the user enters the number of voucher codes to be generated.
Then, the script will generate the required number of vouchers in the database table, and each voucher code will be checked if it is unique - if not, a new voucher code will be generated and the script will proceed until all vouchers are saved.
The problem is that if voucher already exists in the DB, a new one needs to be generated. This newly generated voucher code needs to be checked again if it's already in the DB, if it's unique it will be saved to the DB and if not, the process will go on again. This is where the loop problem lies. I hope you get what i mean.
By the way, the voucher code is in this format: XXXX-XXXX-XXXX (uppercase letters only)
Here's the current codes that I have:
include 'conn.php';
function WriteCSV($flname,$values) {
$Filename = "./vouchers/$flname.csv";
$fh = fopen($Filename, 'a') or die("can't open file");
$filecontent = $values;
$filecontent .= PHP_EOL;
fwrite($fh,$filecontent);
fclose($fh);
}
function generateCode(){
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$res = "";
for ($i = 0; $i < 4; $i++) {
$res .= $chars[mt_rand(0, strlen($chars)-1)];
}
return $res;
}
function generateVCode(){
$c1 = generateCode();
$c2 = generateCode();
$c3 = generateCode();
$voucher = "$c1-$c2-$c3";
return $voucher;
}
function searchDB($con, $voucher){
$rs = mysqli_query($con,"SELECT count(*) AS cnt FROM vouchers WHERE vouchercode = '$voucher'");
$row = mysqli_fetch_assoc($rs);
$cnt = $row['cnt'];
if($cnt > 0){
return '1';
} else {
return '0';
}
}
function checkVoucher($con, $voucher, $vsource, $expiry, $today, $vnum, $vprice){
$dbres = searchDB($con, $voucher);
if($dbres == '1'){ //voucher found in db
$val = '0';
$voucher = generateVCode(); //generate a new voucher
checkVoucher($con, $voucher, $vsource, $expiry, $today, $vnum, $vprice); //repeat the process
} else { // voucher is unique
mysqli_query($con, "INSERT INTO vouchers (vouchercode, source, price, expires, generated) VALUES ('$voucher', '$vsource', '$vprice', '$expiry', '$today')");
$flname = "$vsource - ".date('d M Y')." ($vnum vouchers)";
WriteCSV($flname,$voucher);
$val = '1';
}
return $val;
}
$vnum = $_POST['vouchernum'];
$vsource = $_POST['source'];
$vprice = $_POST['amt'];
$expdate = $_POST['expdate'];
$expiry = $_POST['voucherexpiry'];
$today = date('Y-m-d');
$expconv = date('Y-m-d',strtotime("$expiry"));
$expfive = date('Y-m-d',strtotime("$expiry +5 years"));
for ($x = 1; $x <= $vnum; $x++) {
$vouchercode = generateVCode();
if($expdate == "no"){
$expiry = $expfive;
} else {
$expiry = $expconv;
}
do {
$result = checkVoucher($con, $vouchercode, $vsource, $expiry, $today, $vnum, $vprice);
} while ($result != '1');
header("location: index.php?s=1");
}
By the way, if you have suggestions on how to generate the voucher codes easier, please feel free to share.
I'm thinking the issue/problem here is on either the do-while statement or the checkVoucher() function.
I'd really appreciate you help and suggestions. Thanks.
I would go completely easier. Set the voucher column in your table to unique. Generate a code PHP side, do your insert, in the error callback function call to generate a new code.
Basically, this will self loop until inserted. Then in your success callback add it to your display. All of this is wrapped in a while loop. Once you get your 5, break the loop.
As far as generating a random string with minimal chance of a repeat, check this thread: PHP random string generator
I would generate the full length string and then just add your hyphens.
Using this approach to generate random unique data, the amount of processing required increases proportionally as more and more codes are generated.
What I would do instead is:
Generate a whole bunch of values (lets say a few thousand) values sequentially and store them in a redis/SQL database
Use a random number to index that record in the database, and remove the record from the table once it has been used
This reduces the processing required greatly, and also gives you a pre determined pool of voucher codes which could be useful for other purposes in your application
Mysql unique constraint may be the solution you are looking for.it ensures a value is always unique. It is like primary key. but unlike primary key a table can have multiple unique values.
Here is the link to w3school explaining this
www.w3schools.com/sql/sql_unique.asp
The best part is it will genrerate a Duplicate Entry error when adding a duplicate entry. so you can use it to add data to csv . add it only when you have no error.
But make sure the unique value is not null.

Codeigniter post view count function -

Hello i'm trying to make a post count function based on the codeigniter framework and what i done so far works great looking by my side. The function is complete and everything works fine.
But i have a question here from some experts to tell me that this is the correct ussage of the function and non of the above will harm my page loading. The function is accesed by jQuery get function on every click on the post.
First i'm checking if there is an ip address and if the ip address date inserted is more then 24 hours if its more i'm deleting the current row and then checking again becuase of the previous select its still remembering the last ip address and inserting again with new datime.
And other question should i make cleanjob every week or similar for all ip addreses ?
Here is my code:
function show_count($post_id){
$ip = $this->input->ip_address();
$this->db->select('ip_address,data');
$this->db->from('post_views');
$this->db->where('ip_address',$ip);
$query = $this->db->get();
foreach ($query->result() as $row){
$ip_address = $row->ip_address;
$data = $row->data;
}
if(isset($ip_address) && time() >= strtotime($data) + 8640){
$this->db->where('ip_address',$ip);
$this->db->delete('post_views');
}
$this->db->select('ip_address');
$this->db->from('post_views');
$this->db->where('ip_address',$ip);
$query = $this->db->get();
foreach ($query->result() as $row){
$ip_address_new = $row->ip_address;
}
if(!isset($ip_address_new) && $ip_address_new == false){
$date = new DateTime('now', new DateTimeZone('Europe/Skopje'));
$this->db->set('views', 'views+ 1', false);
$this->db->where('post_id',$post_id);
$this->db->update('posts');
$data = array(
'ip_address'=>$ip,
'data'=>$date->format("Y-m-d H:i:s")
);
$this->db->insert('post_views',$data);
}
}
Thanks, any suggestions will be appreciate.
Instead of doing lots of queries to increment unique views on your posts, you should use and set cookies and have a fallback method if cookies are not enabled.
$post_id = "???"
if(isset($_COOKIE['read_articles'])) {
//grab the JSON encoded data from the cookie and decode into PHP Array
$read_articles = json_decode($_COOKIE['read_articles'], true);
if(isset($read_articles[$post_id]) AND $read_articles[$post_id] == 1) {
//this post has already been read
} else {
//increment the post view count by 1 using update queries
$read_articles[$post_id] = 1;
//set the cookie again with the new article ID set to 1
setcookie("read_articles",json_encode($read_articles),time()+60*60*24);
}
} else {
//hasn't read an article in 24 hours?
//increment the post view count
$read_articles = Array();
$read_articles[$post_id] = 1;
setcookie("read_articles",json_encode($read_articles),time()+60*60*24);
}

Categories