I want to decrement the _remain_overall_quantity from inventory table by using the feed_consumed in consumption table
In condition
if $chickenAge <= 8 The decrement will occur in CBC
if $chickenAge > 8 && $chickenAge <= 20 The decrement will occur in BSC
if $chickenAge > 20 The decrement will occur in BFP
This is my ConsumptionController.php
public function store(Request $request)
{
$this->validate($request, array(
'date_input' => 'required|date',
'feed_consumed' => 'required|numeric',
) );
//declaring values
$chickenAge = 0;
$input= Carbon::parse($request->get('date_input'));
$cycle = Cycle::where('date_of_loading','<=',$input)
->where('date_of_harvest','>=',$input)
->first();
if ($cycle) {
$start = Carbon::parse($cycle->date_of_loading);
$chickenAge = $start->diffInDays($input) ;
}
$inventory = Inventory::where('cycle_id','=',$cycle->id ?? 0)
->first();
$consumption = Consumption::create([
'date_input' => request('date_input'),
'chicken_age' => $chickenAge,
'feed_consumed' => request('feed_consumed'),
'cycle_id' => $cycle->id ?? 0,
'user_id' => Auth::id()
]);
return $consumption;
}
I don't know where can i put the decrement and i don't know what will be the if condition statement. Can you help me?
try adding this code just before you return statement:
if ($chickenAge <= 8)
{
DB::table('inventory')->where('id', 1)->decrement('remain_overall_quantity ', 1); // CBC
}
elseif ($chickenAge <= 20)
{
DB::table('inventory')->where('id', 2)->decrement('remain_overall_quantity ', 1); // BSC
}
else
{
DB::table('inventory')->where('id', 3)->decrement('remain_overall_quantity ', 1); // BFP
}
if you need to decrement by more than 1 then change the "1" in 'remain_overall_quantity ', 1 part
some insight to increment/decrement in Laravel:
https://laravel.com/docs/5.7/queries#increment-and-decrement
Related
how can insert 1000000 row from textarea into database in laravel 8 ???????
i write this code and just can insert 30000 row and then browser give me HTTP ERROR 500
i set max_execution_time to 300 in php.ini
this is my code
please help me . thanks
public function mobile_store(Request $request)
{
$data = $request->validate([
'mobile' => ['required', 'string', 'unique:mobiles,mobile'],
]);
$textAr = collect(explode("\r\n", $data['mobile']));
$ALL = $textAr->unique();
$Filter = $ALL->filter()->all();
$counter_unique = count($Filter);
$counter = count($textAr);
$insert_data = collect();
foreach ($Filter as $line) {
if (strlen($line) >= 10) {
$final = '+98' . substr($line, -10);
}
$insert_data->push([
'mobile' => $final,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
}
foreach ($insert_data->chunk(5000) as $chunk) {
Mobile::insert($chunk->toArray());
}
return redirect()->back()->with('success', "There were $counter_unique rows in the list and $counter non-duplicate rows were entered");
}
Don't store all of the data first, just use 1 foreach and every 5000 records store the data and then reset the array and do the next batch of records.
$insert_data = collect();
$totalRecords = 0;
$batchCount = 0;
foreach ($Filter as $line) {
if (strlen($line) >= 10) {
$final = '+98' . substr($line, -10);
}
$insert_data->push([
'mobile' => $final,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
if ( $batchCount++ == 5000 ) {
// Insert data
Mobile::insert($insert_data->toArray());
// Reset batch collection
$insert_data = collect();
// Reset counter of current batch
$batchCount = 0;
}
// Count of all records
$totalRecords++;
}
// Insert remaining records
if( $insert_data->count() > 0 )
Mobile::insert($insert_data->toArray());
}
I have a already defined array, containing values just like the one below:
$arr = ['a','b','c'];
How could one add the following using PHP?
$arr = [
'a' => 10,
'b' => 5,
'c' => 21
]
I have tried:
$arr['a'] = 10 but it throws the error: Undefined index: a
I am surely that I do a stupid mistake.. could someone open my eyes?
Full code below:
$finishes = []; //define array to hold finish types
foreach ($projectstages as $stage) {
if ($stage->finish_type) {
if(!in_array($stage->finish_type, $finishes)){
array_push($finishes, $stage->finish_type);
}
}
}
foreach ($projectunits as $unit) {
$data[$i] = [
'id' => $unit->id,
'project_name' => $unit->project_name,
'block_title' => $unit->block_title,
'unit' => $unit->unit,
'core' => $unit->core,
'floor' => $unit->floor,
'unit_type' => $unit->unit_type,
'tenure_type' => $unit->tenure_type,
'floors' => $unit->unit_floors,
'weelchair' => $unit->weelchair,
'dual_aspect' => $unit->dual_aspect
];
$st = array();
$bs = '';
foreach ($projectstages as $stage) {
$projectmeasure = ProjectMeasure::select('measure')
->where('project_id',$this->projectId)
->where('build_stage_id', $stage->id)
->where('unit_id', $unit->id)
->where('block_id', $unit->block_id)
->where('build_stage_type_id', $stage->build_stage_type_id)
->first();
$st += [
'BST-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure : '0')
];
if (($stage->is_square_meter == 0) && ($stage->is_draft == 0)) {
$height = ($stage->height_override == 0 ? $unit->gross_floor_height : $stage->height_override); //08.14.20: override default height if build stage type has it's own custom height
$st += [
'BST-sqm-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure * $height: '0')
];
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure * $height: '0') * ($stage->both_side ? 2 : 1); //error is thrown at this line
}
} else {
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure : '0');
}
}
}
$data[$i] = array_merge($data[$i], $st);
$data[$i] = array_merge($data[$i], $finishes[$stage->finish_type]);
$i++;
}
The above code is used as is and the array $finishes is the one from the first example, called $arr
You're using += in your real code instead of =. That tries to do maths to add to an existing value, whereas = can just assign a new index with that value if it doesn't exist.
+= can't do maths to add a number to nothing. You need to check first if the index exists yet. If it doesn't exist, then assign it with an initial value. If it already exists with a value, then you can add the new value to the existing value.
If you want to convert the array of strings to a collection of keys (elements) and values (integers), you can try the following:
$arr = ['a','b','c'];
$newVals = [10, 5, 21];
function convertArr($arr, $newVals){
if(count($arr) == count($newVals)){
$len = count($arr);
for($i = 0; $i < $len; $i++){
$temp = $arr[$i];
$arr[$temp] = $newVals[$i];
unset($arr[$i]);
}
}
return $arr;
}
print_r(convertArr($arr, $newVals));
Output:
Array ( [a] => 10 [b] => 5 [c] => 21 )
I'm trying to mark exam "is_complete" if the "result" reaches 2. I would like to do this when the form is submitted by the user after completing the test and calculating the results. Both variables are in the same table. Is this possible through PHP or do I need to use Java script.
Here is how I've tried to work out the code.
On the model
public function answers()
{
return $this->hasMany('App\ExamResultsAnswers');
}
public function passed()
{
$instance = new ExamResult;
$instance->result < 2;
$var = ExamResult::where('result', '>=', 2)->get();
$var_is_greater_than_two = ($var >= 2 ? true : false);
$condition = new ExamResult;
$condition->is_complete ='1';
if ($this->compare($instance, $condition)) {
return $instance->$column == 1;
}
}
On the controller
public function exam($course_id, Request $request)
{
$course = Course::where('id', $course_id)->firstOrFail();
$answers = [];
$exam_score = 0;
foreach ($request->get('question') as $question_id => $answer_id) {
$question = ExamQuestion::find($question_id);
$correct_answer = ExamOption::where('exam_question_id', $question_id)
->where('id', $answer_id)
->where('is_correct', 1)->count() > 0;
$answers[] = [
'exam_question_id' => $question_id,
'exam_option_id' => $answer_id,
'corect' => $correct_answer
];
if ($correct_answer) {
$exam_score += $question->score;
}
}
$exam_result = ExamResult::create([
'exam_id' => $course->exam->id,
'employee_id' => \Auth::id(),
'result' => $exam_score,
]);
$exam_result->answers()->createMany($answers);
$exam_result->passed();
return redirect()->route('learn.show', [$course, $request])->with('message', 'Test score: ' . $exam_score);
}
The controller is supposed to do the following
Find all the course and the exam that are associated with the course- this works
Then find all the questions and the options for the questions - this works
Then if the user selects the correct answer
then count all correct answers - this works
Then I want to save the
results and mark it complete if the answers are above a 2 correct
answers. - Here the code saves the exam_id, employee_id and result,
but it doesn't make it complete if the result is equal to 2. That is
why I was trying to do this on the model.
Use the following code to mark the Exam as completed:
$exam_result = ExamResult::create([
'exam_id' => $course->exam->id,
'employee_id' => \Auth::id(),
'result' => $exam_score,
]);
$exam_result->answers()->createMany($answers);
if($exam_result->result > 2) {
$exam_result->is_complete = 1;
$exam_result->save();
}
Let me know if i misunderstood the requirement.
Another optimised solution
$exam_result = ExamResult::create([
'exam_id' => $course->exam->id,
'employee_id' => \Auth::id(),
'result' => $exam_score,
'is_complete' => $exam_score > 2
]);
$exam_result->answers()->createMany($answers);
How can I decrement the value of population in cycles table by using the value of number_of_mortality in mortalities table to subtract the population?
For example
The have 2 data in cycles table
Id 1 - (Date range from September 3 to September 28) Population = 3000
Id 2 - (Date range from October 1 to November 5) Population = 9000
I user wants to put a number of mortality to cycle id 1 , so he/she go to mortality modal.
The user inputs the date and it belongs to the cycle id 1 date range. The value of number_of_mortality is 25. After the user inputs the data, he/she click the add to submit to database.
After the submit, The value of population of cycle id 1 will be decrease and it should be 8975 ( 9000 - 25 = 8975).
This is my controller
MortalityController.php (store)
public function store(Request $request)
{
$this->validate($request, array(
'date_input' => 'required|date',
'number_of_mortality' => 'required|numeric',
));
$cycle = Cycle::select('id', 'date_start_raise')
->where('date_start_raise','<=',$request->get('date_input'))
->where('date_end_raise','>=',$request->get('date_input'))
->get();
$id = 0;
$chickenAge = 0;
$input= Carbon::parse($request->get('date_input'));
foreach($cycle as $value){
$id = $value->id;
}
if ($id) {
$start = Carbon::parse($value->date_start_raise);
$chickenAge = $start->diffInDays($input) ;
}
return Mortality::create([
'date_input' => request('date_input'),
'number_of_mortality' => request('number_of_mortality'),
'chicken_age' => $chickenAge,
'cause_of_death' => request('cause_of_death'),
'cycle_id' => $id,
'user_id' => Auth::id()
]);
}
I figured how to connect the mortalities table to cycles table by using dates but I don’t know how and where can I put the code in decrementing by using the number_of_mortality to subtract the population. Can you help me? Thanks
MortalityController.php (update)
public function update(Request $request, $id)
{
$mortality = Mortality::findOrFail($id);
//validate
$this->validate($request, array(
'date_input' => 'required|date',
'number_of_mortality' => 'required|numeric',
) );
$mortality->update($request->all());
}
MortalityController.php (Destroy)
public function destroy($id)
{
$mortality = Mortality::findOrFail($id);
$mortality->delete();
}
You can use the decrement() method.
After successfully creating the mortality you can decrement the population in the cycle:
Store:
public function store(Request $request)
{
$this->validate($request, array(
'date_input' => 'required|date',
'number_of_mortality' => 'required|numeric',
));
// Make sure you only get the correct cycle here
$cycle = Cycle::where('date_start_raise', '<=', $request->get('date_input'))
->where('date_end_raise', '>=', $request->get('date_input'))
->first();
$chickenAge = 0;
$input= Carbon::parse($request->get('date_input'));
if ($cycle) {
$start = Carbon::parse($cycle->date_start_raise);
$chickenAge = $start->diffInDays($input) ;
}
$mortality = Mortality::create([
'date_input' => request('date_input'),
'number_of_mortality' => request('number_of_mortality'),
'chicken_age' => $chickenAge,
'cause_of_death' => request('cause_of_death'),
'cycle_id' => $cycle->id ?? 0,
'user_id' => Auth::id()
]);
// decrement population after successfully creating the mortality
if ($cycle) {
$cycle->decrement('population', $mortality->number_of_mortality);
}
return mortality;
}
Update:
public function update(Request $request, $id)
{
$this->validate($request, array(
'date_input' => 'required|date',
'number_of_mortality' => 'required|numeric',
));
$mortality = Mortality::findOrFail($id);
$oldNumberOfMortality = $mortality->number_of_mortality;
// fill the model with the new attributes
$mortality->fill($request->all());
// check if number_of_mortality was changed
if ($mortality->isDirty('number_of_mortality')) {
$cycle = $mortality->cycle;
$difference = $oldNumberOfMortality - $mortality->number_of_mortality;
// check if the difference is positive or negative and increment or decrement
if ($difference < 0) {
$cycle->decrement('population', abs($difference));
} elseif ($difference > 0) {
$cycle->increment('population', $difference);
}
}
$mortality->save();
return mortality;
}
I have a series of columns (Jan, Feb, Mar, etc) and I want to average the values of each column for each row however many there may be.
I have:
protected function generateAverage($staff, $type)
{
$months = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
$staff = array_map(function ($row) use ($type) {
if ($row['row_type'] == $type) {
return $row;
}
}, $staff);
foreach ($staff as $key => $employee) {
$months[0] += $employee['amounts'][0];
$months[1] += $employee['amounts'][1];
$months[2] += $employee['amounts'][2];
$months[3] += $employee['amounts'][3];
$months[4] += $employee['amounts'][4];
$months[5] += $employee['amounts'][5];
$months[6] += $employee['amounts'][6];
$months[7] += $employee['amounts'][7];
$months[8] += $employee['amounts'][8];
$months[9] += $employee['amounts'][9];
$months[10] += $employee['amounts'][10];
$months[11] += $employee['amounts'][11];
}
$months = array_map(function ($value) use ($staff) {
return $value / (count($staff) / 2);
}, $months);
$months[] = array_sum($months);
return $months;
}
Here is a sample of the data that goes into the above function:
array:6 [
0 => array:4 [
"amounts" => array:13 [
0 => "30000.00"
1 => "30000.00"
2 => "30000.00"
3 => "30000.00"
4 => "30000.00"
5 => "30000.00"
6 => "30000.00"
7 => "30000.00"
8 => "30000.00"
9 => "30000.00"
10 => "30000.00"
11 => "30000.00"
12 => 360000.0
]
"image" => "test.jpg"
"row_name" => "Target"
"row_type" => "target"
]
...
Usage:
$data['aggregates']['Target average'] = $this->generateAverage(array_values($data['staff']), 'target');
I feel the way the average is calculated is messy, is there a better way to do this?
A couple of small footprint reductions
protected function generateAverage($staff, $type)
{
// create 12 months with 0 value
$months = array_fill(0, 12, 0);
// use array_filter instead of map
$staff = array_filter(function ($row) use ($type) {
return $row['row_type'] === $type;
}, $staff);
// do count outside loop
$staffCount = count($staff);
// loop employees and add up each month, dividing early
foreach ($staff as $employee) {
for ($i = 0; $i < 12; $i++) {
$months[$i] += $employee['amounts'][$i] / $staffCount;
}
}
return $months;
}
I dont know why you are dividing the staff count by 2 or why you are summing in the end, my function just gives an average per month.
Since you're using Laravel, most of the data you work with is collections. So, before converting a collection into an array, you could use avg() helper:
$collection->avg($key);
I think you can consider using array_colum,
1) array_column makes an array of all the values in a particular index position in a row
$column1 = array_column($employee, 0 );
$column2 = array_column($employee, 1 );
$column3 = array_column($employee, 2 );
.
.
.
2)Get the column count by count($columnX), where X is the index of the column
3) Using (1) and (2) calculate the average as needed