I have a table which has a field of customer_number, some numbers repeat many times but I want to get only that number which is unique in filed.
public function set_unique()
{
$e = $_POST['e'];
if($e == 1)
{
$one = $this->db->get('calls_details');
foreach($one->result() as $data) {
$two = $this->db->where('Customer_Number', $data->Customer_Number)
->get('calls_details');
if($two->num_rows() == 1) {
foreach($two->result() as $data2) {
$three = $this->db->where('Customer_Number', $data2->Customer_Number)
->update('calls_details', ['unique_id'=>1]);
}
}
}
}
}
}
// defining array in which we get form values
$dataDB = ['first_name' => $this->input->post('first_name'),
'second_name' => $this->input->post('second_name'),
'email' => $this->input->post('email'),
];
// load model
$this->load->model('Customer');
//set record id, which we need to be updated
$this->Customer->id = $uniqueCustomerIDNumber;
//save record
$this->Customer->save();
Related
Basically I want to sort them based on the highest - lowest avg rating but I can't do it since I've already fetched the data (paginate(12)).
Adding sortBy in the if else section is not possible since I do not have yet the avg_rating data. I tried it after foreach but keeps throwing error.
Any workarounds here so I can dynamically sort it out?
public function render()
{
$recipe_default = Recipe::where('is_approved', 1);
if(is_null($this->name_atoz))
{
$recipe_default = $recipe_default->orderBy('id', 'asc')->paginate(12);
}
elseif($this->name_atoz == true)
{
$recipe_default = $recipe_default->orderBy('recipe_name')->paginate(12);
}
elseif($this->name_atoz == false)
{
$recipe_default = $recipe_default->orderBy('recipe_name', 'desc')->paginate(12);
}
foreach($recipe_default as $key => $value)
{
$recipe_default[$key]->avg_rating = Feedback::where('recipe_id', $value->id)->avg('rating');
$recipe_default[$key]->feedback_count = Feedback::where('recipe_id', $value->id)->count();
$recipe_default[$key]->tag_name = Taggable::where('taggable_id', $value->id)->where('taggable_type', 'recipe')->value('tag_name');
}
return view('livewire.content-management', [
'recipes' => $recipe_default
]);
}
In controller
Login information is added inside an array and passed to model. Why it is not inserted in table.
$loginInfo = [
'agent' => $this->getUserAgentInfo(),
'ip' => $this->request->getIPAddress(),
'logintime' => date('Y-m-d h:i:s'),
];
$data=$model->saveLoginInfo($loginInfo);
...
...
public function getUserAgentInfo()
{
$agent = $this->request->getUserAgent();
if ($agent->isBrowser())
{
$currentAgent = $agent->getBrowser();
}
elseif ($agent->isRobot())
{
$currentAgent = $this->agent->robot();
}
elseif ($agent->isMobile())
{
$currentAgent = $agent->getMobile();
}
else{
$currentAgent = 'Undefined User Agent';
}
return $currentAgent;
}
In Model
public function saveLoginInfo($data){
$this->db->table('login_activity')->set($data)->insert();
}
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 have a model with the relation called "reviews":
class ReportStructure extends \yii\db\ActiveRecord
{
const REVIEW_LIST_NAME = 'reviews';
public function getReviewList()
{
return $this->hasOne(FileIndexList::className(), ['id_owner' => 'id_report'])
->where('list_name = :list_name', [':list_name' => self::REVIEW_LIST_NAME]);
}
public function getReviews()
{
return $this->hasMany(FileIndex::className(), ['id_file_index' => 'id_file_index'])->via('reviewList');
}
}
In View, the reviews are displayed by GridView widget. The user can add or delete reviews by the other View. The user should specify at least one review. I added the validation rule to the model:
public function rules()
{
return [
['reviews', 'checkReviews'],
];
}
public function checkReviews($attribute)
{
if (count($this->reviews) === 0) {
$this->addError($attribute, 'You should add at least one review');
}
}
But it seems that rule even not fired.
public function actionIndex($idSupply, $restoreTab = false) {
$this->initData($idSupply, $report, $reestrData, $structure, $elements);
$ok = $report->load(Yii::$app->request->post()) &&
$reestrData->load(Yii::$app->request->post()) &&
Model::loadMultiple($elements, Yii::$app->request->post());
if($ok) {
$ok = $report->validate() &&
$reestrData->validate() &&
Model::validateMultiple($elements) &&
$structure->validate();
if($ok) {
$report->id_status = Status::STATUS_VERIFIED;
$this->saveData($report, $reestrData, $structure, $elements);
return $this->redirect(['supplies/update', 'id' => $idSupply]);
}
}
return $this->render('index', [
'structure' => $structure,
'report' => $report,
'reestrData' => $reestrData,
'elements' => $elements,
'restoreTab' => $restoreTab
]);
}
That's how the data is initialized. $elements are the objects of one class, I use tabular input for them.
private function initData($idSupply, &$report, &$reestrData, &$structure, &$elements) {
$report = \app\models\Reports::findOne($idSupply);
$reestrData = \app\models\ReestrData::findOne($report->id_reestr_data);
$structure = \app\models\report\ReportStructure::findOne($report->id_supply);
$elements = [
'titleIndex' => FileIndex::getInstance($structure->id_title_index, $structure->getAttributeLabel('id_title_index')),
'abstractIndex' => FileIndex::getInstance($structure->id_abstract_index, $structure->getAttributeLabel('id_abstract_index')),
'technicalSpecificationIndex' => FileIndex::getInstance($structure->id_technical_specification_index, $structure->getAttributeLabel('id_technical_specification_index')),
'contentsIndex' => FileIndex::getInstance($structure->id_contents_index, $structure->getAttributeLabel('id_contents_index')),
'imageListIndex' => FileIndex::getInstance($structure->id_image_list_index, $structure->getAttributeLabel('id_image_list_index'), false),
'tableListIndex' => FileIndex::getInstance($structure->id_table_list_index, $structure->getAttributeLabel('id_table_list_index'), false),
'textAnnexListIndex' => FileIndex::getInstance($structure->id_text_annex_list_index, $structure->getAttributeLabel('id_text_annex_list_index'), false),
'graphAnnexListIndex' => FileIndex::getInstance($structure->id_graph_annex_list_index, $structure->getAttributeLabel('id_graph_annex_list_index'), false),
'glossaryIndex' => FileIndex::getInstance($structure->id_glossary_index, $structure->getAttributeLabel('id_glossary_index'), false),
'reportIntroductionIndex' => FileIndex::getInstance($structure->id_report_introduction_index, $structure->getAttributeLabel('id_report_introduction_index')),
'reportMainPartIndex' => FileIndex::getInstance($structure->id_report_main_part_index, $structure->getAttributeLabel('id_report_main_part_index')),
'reportConclusionIndex' => FileIndex::getInstance($structure->id_report_conclusion_index, $structure->getAttributeLabel('id_report_conclusion_index')),
'bibliographyIndex' => FileIndex::getInstance($structure->id_bibliography_index, $structure->getAttributeLabel('id_bibliography_index')),
'metrologicalExpertiseIndex' => FileIndex::getInstance($structure->id_metrologicalexpertise_index, $structure->getAttributeLabel('id_metrologicalexpertise_index')),
'patentResearchIndex' => FileIndex::getInstance($structure->id_patent_research_index, $structure->getAttributeLabel('id_patent_research_index')),
'costStatementIndex' => FileIndex::getInstance($structure->id_cost_statement_index, $structure->getAttributeLabel('id_cost_statement_index')),
];
}
And tht's how the data is saved:
private function saveData($report, $reestrData, $structure, $elements) {
$reestrData->save(false);
$report->save(false);
foreach ($elements as $element) {
$element->save(false);
}
$structure->id_title_index = $elements['titleIndex']->id_file_index;
$structure->id_abstract_index = $elements['abstractIndex']->id_file_index;
$structure->id_technical_specification_index = $elements['technicalSpecificationIndex']->id_file_index;
$structure->id_contents_index = $elements['contentsIndex']->id_file_index;
$structure->id_image_list_index = $elements['imageListIndex']->id_file_index;
$structure->id_table_list_index = $elements['tableListIndex']->id_file_index;
$structure->id_text_annex_list_index = $elements['textAnnexListIndex']->id_file_index;
$structure->id_graph_annex_list_index = $elements['graphAnnexListIndex']->id_file_index;
$structure->id_glossary_index = $elements['glossaryIndex']->id_file_index;
$structure->id_report_introduction_index = $elements['reportIntroductionIndex']->id_file_index;
$structure->id_report_main_part_index = $elements['reportMainPartIndex']->id_file_index;
$structure->id_report_conclusion_index = $elements['reportConclusionIndex']->id_file_index;
$structure->id_bibliography_index = $elements['bibliographyIndex']->id_file_index;
$structure->id_metrologicalexpertise_index = $elements['metrologicalExpertiseIndex']->id_file_index;
$structure->id_patent_research_index = $elements['patentResearchIndex']->id_file_index;
$structure->id_cost_statement_index = $elements['costStatementIndex']->id_file_index;
$structure->save(false);
}
I eventually decided not to use validation for the relation at all and simply check reviews count in the controller:
if (count($structure->reviews) === 0) {
$ok = false;
Yii::$app->session->setFlash('danger', 'You should add at least one review!');
}
I think it's better to check it in beforeDelete method.
you can add this method to your model, and check, if it's the only review, then returns false.
public function beforeDelete()
{
if (!parent::beforeDelete()) {
return false;
}
if(self::find()->count() >1)
return true;
else
return false;
}
I want to insert multiple records in my database using Laravel, however when i insert it, it only gives me one record in the database
Here's my Controller
public function postCreateAttendance()
{
$validate = Validator::make(Input::all(), array(
'status' => 'required'
));
if ($validate->fails())
{
return Redirect::route('viewStudent')->withErrors($validate)->withInput();
}
else
{
foreach(User::all() as $user):
foreach(User::whereRaw('isTeacher = "0" and isAdmin = "0"')->get() as $student)
foreach(User::whereRaw('isTeacher = "1" and isAdmin = "0"')->get() as $teacher)
//$users[$user->id]=$user->firstname;
$attendance = new Attendance();
$attendance->status = Input::get('status');
$attendance->comment = Input::get('comment');
$attendance->student_id = $student->id=$student->id;
$attendance->student_firstname = $student->id=$student->firstname;
$attendance->student_lastname = $student->id=$student->lastname;
$attendance->teacher_id = $teacher->id=$teacher->id;
$attendance->teacher_firstname = $teacher->id=$teacher->firstname;
$attendance->teacher_lastname = $teacher->id=$teacher->lastname;
if($attendance->save())
{
return Redirect::route('viewStudent')->with('success', 'ATTENDANCE HAS BEEN RECORDED!');
}
else
{
return Redirect::route('viewStudent')->with('fail', 'An error occured while creating the attendance.');
}
endforeach;
}
}
How can i save multiple records? Please help Thank You ^_^
The issue is that you are returning during the foreach loop - so only one record is processed. You need to process all the records, then return the route.
Here is some refactoring of your code
public function postCreateAttendance()
{
$validate = Validator::make(Input::all(), array(
'status' => 'required'
));
if ($validate->fails()) {
return Redirect::route('viewStudent')->withErrors($validate)->withInput();
}
foreach(User::where('isTeacher', '0')->where('isAdmin', '0')->get() as $student) {
foreach(User::where('isTeacher', '1')->where('isAdmin', '0')->get() as $teacher) {
$attendance = new Attendance();
$attendance->status = Input::get('status');
$attendance->comment = Input::get('comment');
$attendance->student_id = $student->id;
$attendance->student_firstname = $student->firstname;
$attendance->student_lastname = $student->lastname;
$attendance->teacher_id = $teacher->id;
$attendance->teacher_firstname = $teacher->firstname;
$attendance->teacher_lastname = $teacher->lastname;
$attendance->save();
}
}
return Redirect::route('viewStudent')->with('success', 'ATTENDANCE HAS BEEN RECORDED!');
}
Edit: I've removed the first foreach(User::all() as $user): - because at the moment, in your code, it does nothing...?