1

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

cycles table

I user wants to put a number of mortality to cycle id 1 , so he/she go to mortality modal.

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();
    }

1 Answers1

0

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;
}
Remul
  • 7,874
  • 1
  • 13
  • 30
  • sir what this code do ? `'cycle_id' => optional($cycle)->id ?? 0,` –  Nov 30 '18 at 09:27
  • 1
    It either uses the `cycle_id` or `0`. The optional helper is there so it does not throw an exception if the cycle is null. [docs](https://laravel.com/docs/5.7/helpers#method-optional) – Remul Nov 30 '18 at 09:31
  • 1
    @Peejong see [here](https://stackoverflow.com/questions/34571330/php-ternary-operator-vs-null-coalescing-operator) for more information – DarkBee Nov 30 '18 at 09:32
  • @Remul could you edit the answer? the `$start = Carbon::parse($value->date_start_raise);` should be `$start = Carbon::parse($cycle->date_start_raise);` –  Nov 30 '18 at 11:44
  • i have a question. I wonder there was a code for the scenario. If the user misinput the `number_of_mortality` and he wants to edit it. what will be the code for that? –  Nov 30 '18 at 11:49
  • 1
    @Peejong I updated my code, it should work for you now. – Remul Nov 30 '18 at 12:57
  • @Remul how about it i delete i retrieve the population ? i edit my question –  Dec 03 '18 at 03:17
  • @Peejong Delete seems simple, just save the `number_of_mortality` in a variable, then `delete` the model and `increment` the population by the `number_of_mortality` – Remul Dec 03 '18 at 08:51