I'm trying to loop through a a string and get array of records where the service status is equals to complete or cancelled. I'm having an issue of get all the records instead it response with the last record from the list.
My Controller:
$id = $request->user_id;
$history = bookings::select('*')->whereIn('service_status', ['complete', 'cancelled'])->where(['specialist_id'=>$id])->orderBy('time', 'DESC')->get();
if($history->isempty()){
return response()->json(['statusCode'=>'5', 'statusMessage' => 'Empty Record', 'data' =>[]]);
}else{
for($i = 0; $i < count($history); $i++){
$b_id = $history[$i]->id;
$service = $history[$i]->service;
$time = $history[$i]->time;
$date = $history[$i]->date;
$location = $history[$i]->location;
$payment = $history[$i]->payment_type;
$price = $history[$i]->amount;
$special_request = $history[$i]->special_request;
$s_id = $history[$i]->costumer_id;
}
$user = User::with('profile')->find($s_id);
$data = array(['id'=>$b_id, 'date'=>$date, 'name'=>$user->name." ".$user->profile->lastname, 'speccial_request'=>$special_request, 'item'=>$service, 'time'=>$time." - 1 hour", 'location'=>$location, 'total'=>"$price"]);
return response()->json(['statusCode'=>'0', 'statusMessage' => 'Successful','data' => $data], 200);
}
My response is as follows:
{
"statusCode": "0",
"statusMessage": "Successful",
"data": [
{
"id": 5,
"date": "2020-07-08",
"name": "User1",
"speccial_request": null,
"item": "Service",
"time": "10:00 - 1 hour",
"location": "street, city",
"total": "300"
}
]
}
I want to get all the items from the DB not just one.
You need to create an empty array ($data) and push to that array in each iteration.
Try below code:
$id = $request->user_id;
$history = bookings::select('*')->whereIn('service_status', ['complete', 'cancelled'])->where(['specialist_id'=>$id])->orderBy('time', 'DESC')->get();
if($history->isempty()){
return response()->json(['statusCode'=>'5', 'statusMessage' => 'Empty Record', 'data' =>[]]);
}else{
$data=[];
for($i = 0; $i < count($history); $i++){
$b_id = $history[$i]->id;
$service = $history[$i]->service;
$time = $history[$i]->time;
$date = $history[$i]->date;
$location = $history[$i]->location;
$payment = $history[$i]->payment_type;
$price = $history[$i]->amount;
$special_request = $history[$i]->special_request;
$s_id = $history[$i]->costumer_id;
$user = User::with('profile')->find($s_id);
array_push($data,['id'=>$b_id, 'date'=>$date, 'name'=>$user->name." ".$user->profile->lastname, 'speccial_request'=>$special_request, 'item'=>$service, 'time'=>$time." - 1 hour", 'location'=>$location, 'total'=>"$price"]);
}
return response()->json(['statusCode'=>'0', 'statusMessage' => 'Successful','data' => $data], 200);
}
Related
I have very complex functions in laravel APIs ( called from Mobile App).
The sample function is given below.
If someone can help to improve the code structure.
I wish to know the best practices in handling multiple transactions in a single API. Because if I move each table's entry to separate function - how do I handle errors of each one? Ex: when the quantity is not set in $request model
SUMMARY:
Can someone please break it into smaller functions?
.... Because I don't know how/where to break it into smaller ones.
public function placeOrder(Request $request)
{
$this->validate($request, [
'addressId' => 'required'
]);
$userId = Auth::user()->id;
$itemList = array();
$deliveryCharge = Store::first()->delivery_charge;
// $deliveryCharge = Store::findOrFail($request->header('StoreId'))->delivery_charge;
$total = $deliveryCharge;
$cod = $request->cod;
$useBalanceFirst = $request->useBalanceFirst;
$addressId = $request->addressId;
$list = $request->list;
$cost = 0;
// fetch all items using id in request
foreach ($list as $orderItemFromRequest) {
if (!isset($orderItemFromRequest['id']))
return $this->error("Invalid item selected");
$itemFromDB = Item::find($orderItemFromRequest['id']);
if (!isset($orderItemFromRequest['quantity']))
return $this->error("Please enter quantity for {$itemFromDB->name}");
$qty = $orderItemFromRequest['quantity'];
if ($qty > 0.0) {
if ($itemFromDB == null || $itemFromDB->available == false)
return $this->error("Invalid item selected");
$itemFromDB->quantity = $qty;
$total += ($itemFromDB->sell_rate * $itemFromDB->quantity) / $itemFromDB->rate_unit_multiple;
$cost += ($qty * $itemFromDB->purchase_rate) / $itemFromDB->rate_unit_multiple;
array_push($itemList, $itemFromDB);
}
}
if (count($itemList) == 0) {
return $this->error("At least 1 item is needed to place the order");
}
// check user balance
$user = User::findOrFail($userId);
// if balance < total -> throw error
if ($cod != true && $user->balance < $total) return $this->error("Insufficient Balance. Please recharge your wallet or use C.O.D.", 403);
$order = new Order();
$order->user_id = $user->id;
$order->total = $total;
$order->delivery_charge = $deliveryCharge;
$order->purchase_rate = $cost;
// because in-case user changes his/her name in future - the order should have the historical name & number
$order->customer_name = $user->name;
$order->customer_contact = $user->contact_no;
$order->address_id = $addressId;
if ($cod == true) {
if ($useBalanceFirst == true) {
if ($user->balance < $order->total)
$order->amount_due = $order->total - $user->balance;
else
$order->amount_due = 0;
} else {
$order->amount_due = $order->total;
}
} else
$order->amount_due = 0;
$ordertransaction = new OrderTimeLine();
$ordertransaction->created_by = Auth::user()->id;
DB::transaction(function () use ($order, $itemList, $user, $ordertransaction) {
// insert 1 entry into orders
$order->save();
$order->refresh();
$newOrderItemList = array();
// insert N entries for Items
foreach ($itemList as $requestItem) {
$item = new OrderItem();
$item->order_id = $order->id;
$item->item_id = $requestItem->id;
$item->item_name = $requestItem->name;
$item->sell_rate = $requestItem->sell_rate;
$item->purchase_rate = $requestItem->purchase_rate;
$item->quantity = $requestItem->quantity;
$item->quantity_unit = $requestItem->unit;
$item->rate_unit_multiple = $requestItem->rate_unit_multiple;
if ($requestItem->remaining_stocks <= 0) {
$item->purchase_rate_qty = 0;
} else if ($requestItem->remaining_stocks < $requestItem->quantity) {
$item->purchase_rate_qty = $requestItem->remaining_stocks;
} else
$item->purchase_rate_qty = $requestItem->quantity;
$item->save();
$item->refresh();
$requestItem->remaining_stocks = $requestItem->remaining_stocks - $requestItem->quantity;
// update remaining QTY and cost price
unset($requestItem->quantity);
if ($requestItem->remaining_stocks <= $requestItem->alert_stocks) {
// send notification
NotificationController::notifyAdminAboutStocks($requestItem);
}
$requestItem->save();
array_push($newOrderItemList, $item);
}
$order->items = $newOrderItemList;
// deduct balance from user table
$user->balance = $user->balance - $order->total + $order->amount_due;
$user->save();
$balanceAffected = 0 - $order->total + $order->amount_due;
// enter transaction in wallet_transaction table
if ($balanceAffected != 0) {
$transaction = new WalletTransaction();
$transaction->user_id = $user->id;
$transaction->amount = $balanceAffected;
$transaction->type = WALLET_ORDER_PLACED;
$transaction->order_id = $order->id;
$transaction->save();
}
$ordertransaction->status = $order->status;
$ordertransaction->order_id = $order->id;
$ordertransaction->save();
});
NotificationController::notifyAdminAboutOrder($user, $order);
return $this->success(["balance" => $user->balance, "order" => $order]);
}
You are handling too many work in the controller function.
First of all I suggest to make full use of Laravel Validation functionality. then use Laravel Collection to make your code more readable and compact. I have refactored your function as how I usually handle.
public function placeOrder(Request $request)
{
$data = $request->validate([
'addressId' => 'required',
'cod' => 'required|boolean',
'useBalanceFirst' => 'required|boolean',
'list' => 'required|array',
'list.*.quantity' => 'required|numeric',
'list.*.id' => ['required', 'numeric', Rule::exists('items')->where(function ($query) {
$query->where('available', true);
})],
]);
$user = Auth::user();
$orderItems = collect($data['list'])->map(function($listItem){
$item = Item::find($listItem['id']);
$orderItem = new OrderItem([
'item_id' => $item->id,
'item_name' => $item->name,
'sell_rate' => $item->sell_rate,
'purchase_rate' => $item->purchase_rate,
'quantity' => $listItem['quantity'],
'quantity_unit' => $item->quantity_unit,
'rate_unit_multiple' => $item->rate_unit_multiple,
]);
if ($item->remaining_stocks <= 0) {
$orderItem->purchase_rate_qty = 0;
} else if ($item->remaining_stocks < $orderItem->quantity) {
$orderItem->purchase_rate_qty = $item->remaining_stocks;
} else
$orderItem->purchase_rate_qty = $orderItem->quantity;
return $orderItem;
});
$total = $orderItems->sum(function($item){
return ($item->sell_rate * $item->quantity) / $item->rate_unit_multiple;
});
$cost = $orderItems->sum(function($item){
return ($item->quantity * $item->purchase_rate) / $item->rate_unit_multiple;
});
$deliveryCharge = Store::first()->delivery_charge;
$total += $deliveryCharge;
// if balance < total -> throw error
if (!$data['cod'] && $user->balance < $total)
{
return $this->error("Insufficient Balance. Please recharge your wallet or use C.O.D.", 403);
}
$order = new Order([
'user_id' => $user->id,
'total' => $total,
'delivery_charge' => $deliveryCharge,
'purchase_rate' => $cost,
// because in-case user changes his/her name in future - the order should have the historical name & number
'customer_name' => $user->name,
'customer_contact' => $user->contact_no,
'address_id' => $data['addressId'],
]);
if ($data['cod']) {
if ($data['useBalanceFirst']) {
if ($user->balance < $order->total)
$order->amount_due = $order->total - $user->balance;
else
$order->amount_due = 0;
} else {
$order->amount_due = $order->total;
}
} else
{
$order->amount_due = 0;
}
DB::transaction(function () use ($order, $orderItems, $user) {
// insert 1 entry into orders
$order->save();
$order->items->saveMany($orderItems);
// deduct balance from user table
$user->balance = $user->balance - $order->total + $order->amount_due;
$user->save();
$ordertransaction = OrderTimeLine::create([
'created_by' => $user->id,
'status' => $order->status,
'order_id' => $order->id,
]);
});
return $this->success(["balance" => $user->balance, "order" => $order]);
}
As you have noticed I have removed notification and user wallet transaction code as these should be updated asynchronously with no impact on your user experience. I suggest you take a look at Laravel Events.
I am using paypal integration in my web application everything is working fine . Checkout is working properly but when i apply the coupon then the paypal throws the exception of 400 error. Below is my code
I am using the daryldecode/cart for the checkout. The only problem is when I apply the coupon and move forward towards the paypal
public function paywithPaypal(Request $request)
{
// dd($request->all());
if(Auth::guest()){
if(Session::has('user_id')){
$sessionUserId = Session::get('user_id');
echo $sessionUserId;
}
$checkEmail= User::where('email',$request->billing_email )->first();
if(empty($checkEmail)) {
$user = User::create( [
'first_name' => $request->billing_first_name,
'last_name' => $request->billing_last_name,
'email' => $request->billing_email,
'username' => $request->billing_first_name,
'password' => bcrypt( 123456 ),
'province' => $request->billing_state,
'city' => $request->billing_town,
'address' => $request->billing_address_1,
'role' => 'Member',
] );
$userId = $user->id;
}else{
$userId = $checkEmail->id;
}
}else{
//user login
$sessionUserId = $userId = Auth::user()->id;
}
$items = [];
\Cart::session($sessionUserId)->getContent()->each(function($item) use (&$items)
{
$items[] = $item;
});
$subtotal = \Cart::session($sessionUserId)->getSubTotal();
// dd($subtotal);
$line1 = $request->billing_address_1;
$line2 = $request->billing_address_2;
$fullname = $request->billing_first_name ." ". $request->billing_last_name;
$state = $request->billing_state;
$zip = $request->billing_zip;
$phone = $request->billing_phone;
$email = $request->billing_email;
$city = $request->billing_town;
//invoke new order
$order = new Orders ;
$order->id = $order->generateID('INV');
$saved_order_id = $order->id;
$shippingAddress= Paypalpayment::shippingAddress();
$shippingAddress->setLine1($line1)
->setLine2($line2)
->setCity($city)
->setState($state)
->setPostalCode($zip)
->setCountryCode("US")
->setPhone($phone)
->setRecipientName($fullname);
// ### Payer
// A resource representing a Payer that funds a payment
// Use the List of `FundingInstrument` and the Payment Method
// as 'credit_card'
$payer = Paypalpayment::payer();
$payer->setPaymentMethod("paypal");
$listitem = array();
$fees=HandlingFee::find(1);
$fee = $fees->fee;
$shipping = $request->shipping_fee;
foreach($items as $key=>$item){
$listitem[$key] = Paypalpayment::item();
$listitem[$key]->setName($item->name)
->setCurrency('USD')
->setQuantity($item->quantity)
->setPrice($item->price);
$item_detail = new Order_Item_Details;
$item_detail->order_id = $saved_order_id;
$item_detail->item_id = $item->id;
$item_detail->qty = $item->quantity;
$item_detail->save();
}
$itemList = Paypalpayment::itemList();
$itemList->setItems($listitem)
->setShippingAddress($shippingAddress);
$details = Paypalpayment::details();
$details->setShipping($shipping)
->setHandlingFee($fee)
//total of items prices
->setSubtotal($subtotal);
$grandTotal = $subtotal + $fee + $shipping;
//dd($grandTotal);
//Payment Amount
$amount = Paypalpayment::amount();
$amount->setCurrency("USD")
// the total is $17.8 = (16 + 0.6) * 1 ( of quantity) + 1.2 ( of Shipping).
->setTotal($grandTotal)
->setDetails($details);
//dd($amount);
// ### Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it. Transaction is created with
// a `Payee` and `Amount` types
$transaction = Paypalpayment::transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setInvoiceNumber($saved_order_id)
->setCustom($request->shipping_service);
// dd($transaction);
// ### Payment
// A Payment Resource; create one using
// the above types and intent as 'sale'
$redirectUrls = Paypalpayment::redirectUrls();
$redirectUrls->setReturnUrl(url("/payments/success"))
->setCancelUrl(url("/payments/fails"));
$payment = Paypalpayment::payment();
$payment->setIntent("sale")
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions([$transaction]);
$order->status = 1;
$order->user_id = $userId;
$order->total = $grandTotal;
$order->subtotal = $subtotal;
$order->shipping = $shipping;
if($request->coupon_code == ""){
$order->isCoupon = 0;
}
else{
$order->isCoupon = 1;
}
$order->isBillingDetail = 1;
if($request->shipping_first_name <> ""){
$order->isShippingDetail = 1;
}
if($request->has('order_notes')){
$order->notes = $request->order_notes;
}
$order->save();
$order_billing = new Order_Billing_Details;
$order_billing->order_id = $order->id;
$order_billing->first_name = $request->billing_first_name ;
$order_billing->last_name = $request->billing_last_name ;
$order_billing->company = $request->billing_company_name ;
$order_billing->address_line_1 = $line1;
$order_billing->address_line_2 = $line2;
$order_billing->state = $state;
$order_billing->city = $city;
$order_billing->postal_code = $zip;
$order_billing->email = $email;
$order_billing->phone = $phone;
$order_billing->save();
if($request->shipping_first_name <> ""){
$order_shipping = new Order_Shipping_Details;
$order_shipping->order_id = $order->id;
$order_shipping->first_name = $request->shipping_first_name ;
$order_shipping->last_name = $request->shipping_last_name ;
$order_shipping->company = $request->shipping_company_name ;
$order_shipping->address_line_1 = $request->shipping_address_1 ;
$order_shipping->address_line_2 = $request->shipping_address_2 ;
$order_shipping->state = $request->shipping_state ;
$order_shipping->city = $request->shipping_town ;
$order_shipping->postal_code = $request->shipping_zip ;
$order_shipping->email = $email ;
$order_shipping->phone = $request->shipping_phone ;
$order_shipping->save();
}
else{
$order_shipping = new Order_Shipping_Details;
$order_shipping->order_id = $order->id;
$order_shipping->first_name = $request->billing_first_name ;
$order_shipping->last_name = $request->billing_last_name ;
$order_shipping->company = $request->billing_company_name ;
$order_shipping->address_line_1 = $line1;
$order_shipping->address_line_2 = $line2;
$order_shipping->state = $state;
$order_shipping->city = $city;
$order_shipping->postal_code = $zip;
$order_shipping->email = $email;
$order_shipping->phone = $phone;
$order_shipping->save();
}
try {
// ### Create Payment
// Create a payment by posting to the APIService
// using a valid ApiContext
// The return object contains the status;
//dd(Paypalpayment::apiContext());
$payment->create(Paypalpayment::apiContext());
// dd($payment);
$arrpayment = $payment->toArray();
$order = Orders::find($saved_order_id);
$order->paypal_invoice = $arrpayment['id'];
$order->save();
} catch (\PPConnectionException $ex) {
echo $ex->getCode(); // Prints the Error Code
echo $ex->getData();
dd($ex);
return response()->json(["error" => $ex->getMessage()], 400);
}
catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode(); // Prints the Error Code
echo $ex->getData(); // Prints the detailed error message
}
$email=$request->billing_email;
$fees=HandlingFee::find(1);
$fee = $fees->fee;
$data=array(
'order' => $order,
'name' => $request->billing_first_name.' '.$request->billing_last_name,
'email'=>$email,
'fee'=>$fee,
'payPalLink' => $payment->getApprovalLink(),
);
Mail::send('email.placed', $data, function($message) use ($email) {
$message->subject('New Order Received');
$message->from('no-reply#blurack.com', 'BluRack');
$message->to($email);
});
$admins=DB::table('users')
->select('updates_email')
->where('receiving_updates',1)
->where(function($q) {
$q->where('role','Administrator')
->orWhere('role','Retailer');
})->get()->toArray();
// ->where('role','Administrator')
// ->orWhere('role','Retailer')
// dd($admins);
foreach($admins as $admin){
$admin_mail=$admin->updates_email;
//dd($admin_mail);
Mail::send('email.orderplaced',$data, function($message) use ($admin_mail) {
$message->subject('New Order Received');
$message->from('no-reply#blurack.com', 'BluRack');
$message->to($admin_mail);
});
}
return redirect($payment->getApprovalLink());
// return response()->json([$payment->toArray(), 'approval_url' => $payment->getApprovalLink()],
200);
}
I think the issue is with try catch problem?
I want to receive an array for data, something like this:
"data": [
"6": {
"title": "..",
"photo": ..
}
]
But I am receving an object :
"data": {
"6": {
"title": "..",
"photo": ".."
}
}
And another intresting fact is that for first page I am receiving how it is needed:
"data": [
"1": {
"title": "..",
"photo": ..
},
.
.
.
"6": {
"title": "..",
"photo": ..
}
]
This is my function in controller:
$lists = [];
$cooks = cook::all();
foreach ($cooks as $cook) {
$list = [
'title' => $cook->title,
'photo' => $cook->photos->path,
'recipe' => $cook->recipe->description
];
$lists[] = $list;
}
$collection = $this->paginate($lists, $perPage = 6, $page = null, $options = []);
return new mainCollection($collection);
I have the following function for pagination:
public function paginate($items, $perPage = 15, $page = null, $options = [])
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
}
and the following is my resourceColection(mainColection) :
public function toArray($request)
{
return [
'data' => $this->collection,
'meta' => ['pagination' => $this->pagination]
];
}
You can use laravel map since you're working with collections.
$array = $this->collection->map(function ($item, $key) {
return [
'title': "tort",
...
]
});
and encode it as json
public function toArray($request)
{
return [
'data' => json_encode($array),
'meta' => ['pagination' => $this->pagination]
];
}
also you read the documentation here: https://laravel.com/docs/5.8/collections
array:2 [▼
0 => "iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AABNq0lEQVR42u3dCZwcVZ3A8Uq6uqu6uqYnx2RykBBCEmIgQCAJSTiUQ1cQEBDUFVRcQVhALg9UUIH1xAVcXHQBBUUEFhREBXHF9eKW3RUQBQVclMso ▶"
1 => "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAACxKgAAsSoBYacs7wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z13 ▶"
]
code:
$multi_image = $request->file('multi_image');
if ($multi_image == '')
{
$data[] = 'null';
}
else
{
$file = $request->file('multi_image');
for($i = 0 ; $i< count($file); $i++)
{
$data[]= base64_encode(file_get_contents($file[$i]));
}
}
$sort = $request->input('category_id');
$order = Category::where('id','=',$sort)->first();
$item = new Item();
$item->admin_id = Auth::user()->id;
$item->category_id = $request->input('category_id');
$item->category_sort_order = $order->sort_order;
$item->name = $request->input('name');
$item->description = $request->input('description');
$item->image = $image;
$item->multi_image = json_encode($data);
// $item->currency = '₹';
$item->price = $request->input('price');
I am using xapian as a search engine for my website.
Recently I found out it does not search words containg polish specific characters like ś, ą, ć, ę.
Anytime I am trying to search word containg one of those language-specific chars it returns no results. Are there any encoding settings in xapian?
Those are my indexing and searching functions ($document has content, id and route field).
protected function _indexDocument($document, $indexer, $database)
{
$doc = new XapianDocument();
$content = Zend_Json::encode($document);
$doc->set_data($content);
$indexer->set_document($doc);
$indexer->index_text($content);
$term = (string) md5($document['id']);
$doc->add_boolean_term($term);
$database->replace_document($term, $doc);
return true;
}
public function searchDocuments($phrase, $page = 0, $limit = 10)
{
$page = (int) $page;
$limit = (int) $limit;
$database = new XapianDatabase($this->getDatabasePath());
$enquire = new XapianEnquire($database);
$qp = new XapianQueryParser();
$stemmer = new XapianStem("english");
$qp->set_stemmer($stemmer);
$qp->set_database($database);
$qp->set_stemming_strategy(XapianQueryParser::STEM_SOME);
$query = $qp->parse_query($phrase);
$enquire->set_query($query);
$matches = $enquire->get_mset(($page-1) * $limit, $limit);
$documentCount = $matches->get_matches_estimated();
$i = $matches->begin();
$documents = array();
$rawDocuments = array();
while (!$i->equals($matches->end())) {
$n = $i->get_rank() + 1;
$data = $i->get_document()->get_data();
$documents[] = $this->_prepareDocument( Zend_Json::decode($data), $phrase );
$rawDocuments[]= Zend_Json::decode($data);
$i->next();
}
$pageCount = ceil($documentCount / $limit);
if ($page > 0) {
$prevPage = ($page - 1) * $limit;
} else {
$prevPage = 0;
}
if ($page < $pageCount) {
$nextPage = ($page + 1) * $limit;
} else {
$nextPage = $pageCount;
}
$result = array('results' => $documents, 'results-raw' => $rawDocuments, 'paginator' => array(
'page' => $page, 'limit' => $limit, 'pageCount' => $pageCount,
'prevPage' => $prevPage, 'nextPage' => $nextPage,
'documentCount' => $documentCount));
return $result;
}