Home > database >  How to get other field value from Laravel FormRequest Validation
How to get other field value from Laravel FormRequest Validation

Time:09-17

I've the input function for outbound materials from warehouse like so :

[
    "movement_date" => "2022-09-08",
    "type" => "1",
    "transaction_number" => "OUTBOUND-001",
    "remarks" => "Moved to another warehouse",
    "items" => [
        0 => [
            "material_id" => "47",
            "uom" => "Kilogram",
            "qty" => "1000",
        ],
        1 => [
        "material_id" => "16",
        "uom" => "Kilogram",
        "qty" => "500",
        ],
    ],
]

In FormRequest i tried to check the remaining stocks for each materials like so :

return [
    'type' => 'required',
    'movement_date' => ['required','date', function ($attribute, $value, $fail) {
        if ($value > Carbon::now()->format('Y-m-d')) $fail('Invalid date '.Carbon::now()->format('Y-m-d'));
    }],
    'items' => 'required|array',
    'items.*.material_id' => 'required',
    'items.*.qty' => ['required', function ($attribute, $value, $fail) {
        $stock = \App\Models\MaterialStock::where('material_id', 'I need material id from material_id field here')->first();

        $stock === null ? $balance = 0 : $balance = $stock->qty;
        
        if ($balance < $value) $fail('Insufficient stock');
    }],
];

The question is, how do i get the "material_id" value when i'm trying to validate the qty field ?

CodePudding user response:

As suggested by @matiaslauriti, i did solve the problem by utilizing Laravel's object validator

First, i need to create the Rules which implements DataAwareRule to interact with other field values :

class HasStock implements Rule, DataAwareRule
{
    protected $data = [];

    public function setData($data)
    {
        $this->data = $data;
 
        return $this;
    }

    public function passes($attribute, $value)
    {
        $index = explode('.',$attribute)[1];
        $materialId = $this->data['items'][$index]['material_id'];

        $stock = \App\Models\MaterialStock::where('material_id', $materialId)->first();

        $stock === null ? $balance = 0 : $balance = $stock->stock;
                
        return $balance > $value;
    }

    public function message()
    {
        return 'Insufficient stock.';
    }
}

Then i can initializing the HasStock Rules instance from the Form Request like so :

public function rules()

    {
        return [
            'type' => 'required',
            'movement_date' => ['required','date', function ($attribute, $value, $fail) {
                if ($value > Carbon::now()->format('Y-m-d')) $fail('Invalid date.');
            }],
            'items' => 'required|array',
            'items.*.material_id' => 'required',
            'items.*.qty' => ['required', new HasStock],
        ];
    }

The result was exaclty i was looking for, it did validate the stocks correctly.

CodePudding user response:

Here is your solution:

$rules = [
    // ...
    'items' => ['required', 'array'],
];

foreach($this->items as $key => $item){
    $rules['items.'.$key.'.material_id'] = ['required'];
    $rules['items.'.$key.'.qty'] = ['required', function($attribute, $value, $fail) use ($key) {
        $stock = \App\Models\MaterialStock::where('material_id', $this->items[$key]['material_id'])->first();

        $balance = $stock === null ? 0 : $stock->qty;
            
        if ($balance < $value) $fail('Insufficient stock');
    }];
}

return $rules;
  • Related