I have Receipt API that generate Receipt. While generating receipt several SQL operation is being done. Now if I generate receipt by mistake how can Undo all last operation.
What I need to do is I want all data as it is before this API call. I have some Idea about Rollback but I don't know how can I use this in this. If you help please do so.
My receipt look like this.
<?php
include 'connection.php';
extract($_REQUEST);
$data = array();
$resArr = array();
$payment_type = $_POST['payment_type'];
$cheque_date = $_POST['cheque_date'];
$cheque_no = $_POST['cheque_no'];
$paid_amount = $_POST['paid_amount'];
$query = customSelectQuery(
"SELECT c.emi_amount as customer_emi_amount, ltc.no_of_month as ltc_no_of_month,
ltc.emi_date as ltc_emi_date, ltc.loan_amount as ltc_loan_amount
from loan_to_customer ltc
LEFT JOIN customer c ON c.customer_id = ltc.customer_id
WHERE ltc.customer_id = $customer_id");
// print_r($query);
if (isset($query)) {
$ltc_data = array();
foreach ($query as $row) {
$ltc_data = array(
'ltc_emi_date' => explode(',', $row['ltc_emi_date']),
'ltc_no_of_month' => $row['ltc_no_of_month'],
'ltc_loan_amount' => $row['ltc_loan_amount'],
'customer_emi_amount' => $row['customer_emi_amount']
);
}
}
$ltc_loan_amount = $ltc_data['ltc_loan_amount'];
$remaining_loan_amount = $ltc_loan_amount - $paid_amount;
$receipt_number = 'CMF/EMI/RECEIPT/126';
$receipt_data = array(
'customer_id' => $customer_id,
'payment_type' => $payment_type,
'cheque_date' => $cheque_date,
'cheque_no' => $cheque_no,
'paid_amount' => $paid_amount,
'remain_amount' => $remaining_loan_amount,
'receipt_no' => $receipt_number
);
$insert_in_reciept = insert("receipt", $receipt_data);
$removed_emi_date = array_shift($ltc_data['ltc_emi_date']);
$number_of_month_remaining = count($ltc_data['ltc_emi_date']);
$string_number_of_month_remaining = implode(',', $ltc_data['ltc_emi_date']);
$loan_to_customer_data = array(
'customer_id' => $customer_id,
'loan_amount' => $remaining_loan_amount,
'no_of_month' => $number_of_month_remaining,
'emi_date' => $string_number_of_month_remaining
);
$update_ltc = update("loan_to_customer", $loan_to_customer_data, 'customer_id = ' . $customer_id);
$query1 = customSelectQuery("select r.*, ltc.emi_date as ltc_emi_date, ltc.*, c.first_name,
c.middle_name, c.last_name, c.gender, c.cust_address, c.cust_city,
c.cust_dist, c.cust_state, c.cust_pincode FROM receipt r
LEFT JOIN customer c ON c.customer_id = r.customer_id
LEFT JOIN loan_to_customer ltc ON r.customer_id = ltc.customer_id
WHERE r.customer_id = $customer_id");
if (isset($query1)) {
$d = array();
foreach ($query1 as $row) {
$d = array(
'first_name' => $row['first_name'],
'middle_name' => $row['middle_name'],
'last_name' => $row['last_name'],
'gender' => $row['gender'],
'cust_address' => $row['cust_address'],
'cust_city' => $row['cust_city'],
'cust_state' => $row['cust_state'],
'cust_pincode' => $row['cust_pincode'],
'ltc_emi_date' => explode(',', $row['ltc_emi_date']),
'payment_type' => $row['payment_type'],
'cheque_date' => $row['cheque_date'],
'cheque_no' => $row['cheque_no'],
'paid_amount' => $row['paid_amount'],
'remain_amount' => $row['remain_amount'],
'penalty_amount' => $row['penalty_amount'],
'receipt_no' => $row['receipt_no'],
'emi_date' => $row['emi_date'],
'pending_penalty' => $row['pending_penalty'],
'paid_penalty' => $row['paid_penalty'],
'user' => $row['user'],
'user_branch' => $row['user_branch'],
'verify' => $row['verify'],
);
}
}
$resArr = array("success" => 1, "data" => $d, "message" => "");
header('Content-Type: application/json');
echo str_replace("\/", "/", json_encode($resArr, JSON_UNESCAPED_UNICODE));
?>
Of course, it is not possible to use transactions for a scenario like this.
And there is no reliable way to undo the previous operation with a database structure like this either.
To make it possible you must normalize your database. In other words any addition must be done by means of INSERT queries only but not a single UPDATE should to be used.
Given that, to undo the operation you need to collect all the insert ids from insert queries and store them in a session. After hitting the undo button simply delete the records based on the stored ids
First, start a transaction by using the START TRANSACTION statement.
Perform whatever you want.
Finally, commit the transaction using the COMMIT statement to save data.
If you don't want to change roll back the current transaction and cancel its changes, you use the ROLLBACK statement.
Refer below link for more information.
https://dev.mysql.com/doc/refman/8.0/en/innodb-autocommit-commit-rollback.html
You can do something like this:
mysqli_begin_transaction($connection, MYSQLI_TRANS_START_READ_ONLY);
try {
mysqli_query($connection, $yourSelectQuery1);
mysqli_query($connection, $yourSelectQuery2);
mysqli_query($connection, $yourSelectQuery3);
mysqli_commit($connection);
} catch($e) {
mysqli_rollback($connection);
}
mysqli_close($connection);
Related
All I want here is to be able to save all the ID's of services into the pivot table associated with the given keywords/tags but at the moment all it does is that it takes the last ID of the created object and saves into the pivot table with different keywords. let's say for example I enter [id1 => service1, id2 => service2] and [id1 = > keyword1, id2 => keyword2, id3 => keyword3] instead of it saving only id2 of service2 and all the keywords I want it to save all the Ids of all of the services and the keywords. I hope it makes sense
foreach($params['service'] as $key => $value){
$service = Service::firstOrNew(['service' => $value, 'price' => $params['price'][$key], 'business_id' => $params['business_id']]);
$service->service = $value;
$service->price = $params['price'][$key];
$service->business_id = $params['business_id'];
$service->save();
}
foreach($params['keywords'] as $keyword){
$cleaned_keyword = self::cleanKeywords($keyword);
$newKeyword = Keyword::firstOrNew(['keyword' => $cleaned_keyword]);
$newKeyword->keyword = $cleaned_keyword;
$newKeyword->save();
$service->keywords()->syncWithoutDetaching([$newKeyword->id => ['business_id' => $params['business_id']]]);
}
This is something I would expect but it is tricky because a single or 2 services for example can have multiple keywords. NOTE: I had manually changed these values in the database
These are the results from a dd($params)
Based on the dd($params).attached is the result,only
"service" => array:2[
1 => "Mobile development"
]
was saved in the pivot table and got assigned all the keywords
Please correct me if this is a good approach, I managed to solve this by having an inner loop.
foreach($params['service'] as $key => $value) {
$service = Service::firstOrNew(['service' => $value, 'price' => $params['price'][$key], 'business_id' => $params['business_id']]);
$service->service = $value;
$service->price = $params['price'][$key];
$service->business_id = $params['business_id'];
$service->save();
foreach($params['keywords'] as $keyword) {
$cleaned_keyword = self::cleanKeywords($keyword);
$newKeyword = Keyword::firstOrNew(['keyword' => $cleaned_keyword]);
$newKeyword->keyword = $cleaned_keyword;
$newKeyword->save();
$service->keywords()->syncWithoutDetaching([$newKeyword->id => ['business_id' => $params['business_id']]]);
}
}
I have 1 row having 5 form fields. User can add/remove rows. Its repeatable row.
Now i want to store these fields into database with PDO php.
For normal values i am using this code but i am confused for repeater field.
$data = array(
'bill_no' => trim($_REQUEST['bill_no']),
'from_name' => trim($_REQUEST['from_name']),
'to_name' => trim($_REQUEST['to_name']),
'date' => trim($_REQUEST['date_bill']),
'mr_or_ms' => trim($_REQUEST['mr_or_ms']),
);
if($crud->InsertData("bill",$data)) {
header("Location: add-bill.php");
}
Insert Function:
public function InsertData($table,$fields) {
$field = array_keys($fields);
$single_field = implode(",", $field);
$val = implode("','", $fields);
try {
$query = $this->db->prepare("INSERT INTO ".$table."(".$single_field.") VALUES('".$val."')");
$query->execute();
return true;
} catch(PDOException $e) {
echo "unable to insert data";
}
}
Please help me to insert fields. Thanks
Change the names of your form fields, add [] to the end to get PHP arrays. For example change bill_no to bill_no[]. Something like this:
foreach($_REQUEST['bill_no'] as $row_number => $row_content){
$data = array(
'bill_no' => trim($_REQUEST['bill_no'][$row_number]),
'from_name' => trim($_REQUEST['from_name'][$row_number]),
'to_name' => trim($_REQUEST['to_name'][$row_number]),
'date' => trim($_REQUEST['date_bill'][$row_number]),
'mr_or_ms' => trim($_REQUEST['mr_or_ms'][$row_number]),
);
$crud->InsertData("bill",$data);
}
This assumes the browser is not mixing up the order of the fields, so maybe it's better to add unique names to the form fields when adding rows.
Also, there's no input data validation at all, please ensure you are escaping all data properly.
I did it with this method.
$total=count($_POST['description']);
for($i=0; $i<$total; $i++){
$data1 = array(
'bill_no' => trim($_POST['bill_no']),
'description' => trim($_POST['description'][$i]),
'nos' => trim($_POST['nos'][$i]),
'nos_day' => trim($_POST['nos_day'][$i]),
'pay' => trim($_POST['pay'][$i]),
'weekly_off' => trim($_POST['weekly'][$i]),
'hra' => trim($_POST['hra'][$i]),
'rs' => trim($_POST['rs'][$i]),
'ps' => trim($_POST['ps'][$i]),
);
$crud->InsertData("bill_details",$data1);
}
Using the below, I echo a JSON array of the results. But this requires that I identify the column names which I'd like to return from the SQL query:
$new_sql = "SELECT TOP 200 * FROM STracker ORDER BY [ID] DESC";
$check_statement = sqlsrv_query($conn, $new_sql);
$data = array();
while($row = sqlsrv_fetch_array($check_statement, SQLSRV_FETCH_ASSOC)) {
$data['data'][] = array(
'id' => $row['ID'],
's_reference' => $row['s_reference'],
'reference' => $row['reference'],
'customer_name' => $row['customer_name']
);
}
Is there any way to create that array information, but return all of the columns returned by the query dynamically? So by using SELECT * FROM, all of the column data is returned in the array but without me needing to write out all of these individually? (the below)
'id' => $row['ID'],
's_reference' => $row['s_reference'],
'reference' => $row['reference'],
'customer_name' => $row['customer_name']
Ok I forgot to add that I'd tried this:
$data['data'][] = array($row);
Which is clearly wrong, and after using the following, it works perfectly!
$data['data'][] = $row;
Everything is working, all I want is to decrypt the db column containing the credit card number from the database with the following example:
$decp = $crypt->decrypt($encp);
the row in question is:
'Number' => $row['cardNumber'],
the entire code is:
// get the cards
$jsonresult = $conn->query("SELECT nameOnCard, cardNumber, cardType, cardDate, ccvCode
FROM cy_user_credit_cards
WHERE accountNumber='$accountNumber'");
$creditCard = [];
while ($row = mysqli_fetch_assoc($jsonresult)) {
array_push($creditCard, [
'Name' => $row['nameOnCard'],
'Number' => $row['cardNumber'],
'Type' => $row['cardType'],
'Date' => $row['cardDate'],
'ccv' => $row['ccvCode']
]);
}
// Convert the Array to a JSON String and echo it
$ccJSON = json_encode($creditCard);
echo $ccJSON;
$conn->close();
I think you would want to do something like this:
// get the cards
$jsonresult = $conn->query("SELECT nameOnCard, cardNumber, cardType, cardDate, ccvCode
FROM cy_user_credit_cards
WHERE accountNumber='$accountNumber'");
$creditCard = [];
while ($row = mysqli_fetch_assoc($jsonresult)) {
array_push($creditCard, [
'Name' => $row['nameOnCard'],
'Number' => $crypt->decrypt($row['cardNumber']),
'Type' => $row['cardType'],
'Date' => $row['cardDate'],
'ccv' => $row['ccvCode']
]);
}
// Convert the Array to a JSON String and echo it
$ccJSON = json_encode($creditCard);
echo $ccJSON;
$conn->close();
Keep in mind, You really do not want to store all of these credit card details in your database if it is not absolutely necessary. I would urge you to look elsewhere to handle credit card payments.
You can decrypt the string upon pushing your data into the array like so:
array_push($creditCard, [
'Name' => $row['nameOnCard'],
'Number' => $crypt->decrypt($row['cardNumber']),
'Type' => $row['cardType'],
'Date' => $row['cardDate'],
'ccv' => $row['ccvCode']
]);
Learning php and I am losing my mind trying to solve this for days now. Please help.
This is a code which goes thought a table COUPON, take data with a condition met, and download it afterwards. In this table COUPON I have USER_ID as number but I want to have a user name also, which is kept in another table USER.
How can I go to another table (USER) and take names (REALNAME) by this USER_ID which is the same in both tables?
if ( $_POST ) {
$team_id = abs(intval($_POST['team_id']));
$consume = $_POST['consume'];
if (!$team_id || !$consume) die('-ERR ERR_NO_DATA');
$condition = array(
'team_id' => $team_id,
'consume' => $consume,
);
$coupons = DB::LimitQuery('coupon', array(
'condition' => $condition,
));
if (!$coupons) die('-ERR ERR_NO_DATA');
$team = Table::Fetch('team', $team_id);
$name = 'coupon_'.date('Ymd');
$kn = array(
'id' => 'ID',
'secret' => 'Password',
'date' => 'Valid',
'consume' => 'Status',
);
$consume = array(
'Y' => 'Used',
'N' => 'Unused',
);
$ecoupons = array();
foreach( $coupons AS $one ) {
$one['id'] = "#{$one['id']}";
$one['consume'] = $consume[$one['consume']];
$one['date'] = date('Y-m-d', $one['expire_time']);
$ecoupons[] = $one;
}
down_xls($ecoupons, $kn, $name);
After this, I want to try to do the same thing using only SQL queries.
You would need to JOIN the tables in the SQL query
SELECT something FROM coupons as coupons JOIN user as user ON coupons.id=user.id
You should use join when you want to retrieve details from two tables.
Join table COUPON and table USER based on user_id . This should yield results you want.