Currently I have working foreach array where it collects all tasks and it contains weight for each task.
Here's my working code
foreach ($arr4 as $row4) {
$taskCode = strtoupper(str_random(12));
$insert_data5[] = array(
'projCode' => $projCode,
'taskCode' => $taskCode,
'taskWeight' => $row4['weight'],
'plan_days' => $row4['planned_days'],
'actual_days' => $row4['actual_days'],
'deleted' => 0,
'by_id' => auth()->user()->id,
'updated_by' => auth()->user()->name,
'created_at' => now(),
'updated_at' => now(),
);
}
dd($insert_data5);
OUTPUT
What I'm trying to do is to validate if the sum up of taskWeight of 5 Tasks doesn't reached 100% this will show an error message.
As of now my idea is to use validator but I have no idea how can I calculate the array fields of taskWeight
$validator = Validator::make(
$insert_data5,
[
......
]
);
if($validator->fails()){
return redirect()
->back()
->with(['errors'=>$validator->errors()->all()])
->with('modal',$modal);
}
Fixed my problem
I declare $ttlTaskWeight = 0; outside of foreach
Then as suggested do the sum up inside of the foreach
like this
$ttlTaskWeight += $row4['weight'];
and I did this to validate if it exceeds 100% or not
if($ttlTaskWeight != 100){
return redirect()
->back()
->with(['errors'=> [0=> 'Total Task Weight must be exact 100%']])
->with('modal',$modal);
}
and the output is this
Related
Solution
foreach($request->all() as $record){
EventViews::query()->updateOrCreate(['id'=>$record['id']], $record);
}
Question
How do I update a whole table by passing a request array? It should update existing rows and create new ones if id doesn't exist. If possible without having to loop over the whole table.
Attempts that don't work:
EventViews::query()->updateOrCreate($request->all());
.
DB::transaction(function ($request) {
foreach ($request->all() as $record) {
EventViews::updateOrCreate($record);
}
});
.
$model = new EventViews($request->all());
$model->fill($request->all())->save();
assuming your request payload looks something like
records[]=[id=1,name=foo,description=foo,c=1]&
records[]=[id=2,name=bar,description=bar,c=1]&
...
you could loop over it like:
$input = $request->input('records');
foreach($input as $record){
EventViews::query()->updateOrCreate(['id'=>$record['id']],$record);
}
if your request looks like:
1=[name=foo,description=foo,c=1]&
2=[name=bar,description=bar,c=1]&
...
where the parameter name is the id, then you could use:
$input = $request->input();
foreach($input as $key => $record){
EventViews::query()->updateOrCreate(['id'=>$key],$record);
}
updateOrCreate receives 2 parameters, the first is the constrains and the second is the data.
I don't know your request structure, but it's good practice verify it before throwing it into your database.
Example:
Model::query()->updateOrCreate(
['my_column' => $request->input('my_column')],
[*array of column/values of what should be updated*]
)]
If exists a Model with given my_column value, it will update it's value with the associative array passed on the second argument, otherwise it will create a new entry.
you can use this method :
$flight = Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
or
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
for get more information see this link:
https://laravel.com/docs/9.x/eloquent#upserts
I have a Laravel Request where I need to validate the keys from an array.
The keys are the productId and I am checking if the product belongs to the user.
Here is an example of products at the POST request:
[
8 => [
'quantity' => 10,
'discount' => 10
],
9 => [
'quantity' => 10,
'discount' => 10
]
]
And bellow is the Request rules. Is it possible to check on the keys?
public function rules()
{
return [
'product.*' => 'required|exists:recipes,id,user_id,' . $this->user()->id,
'product.*.quantity' => 'required|numeric|min:0',
'product.*.discount' => 'required|numeric|min:0'
];
}
I made a temporary solution...I kept the id validation at the request.
'products.*.id' => 'required|exists:recipes,id,user_id,' . $this->user()->id,
'products.*.quantity' => 'required|numeric|min:0',
'products.*.discount' => 'required|numeric|min:0',
But at the controller the data is modified to fit the sync() method where the id is removed from the object that will be modified and setted as a key.
$products = [];
for ($i = 0; $i < count($data['products']); $i++) {
$recipes[$data['products'][$i]['id']] = $data['products'][$i];
unset($products[$data['products'][$i]['id']]['id']);
}
$budget->products()->sync($products);
$budget->products = $data['products'];
I didn't mentioned that this is a manytomany polymorphic relationships.
I have an issue where I'm trying to get all descendants of an object and keep only those with a specific property.
I have these relations:
public function getChildren()
{
return $this->hasMany(self::class, 'parent_id', 'id');
}
public function allChildren()
{
return $this->getChildren()->with('allChildren');
}
And I get this type of array for example:
$array = [
0 => ['name' => 'aaa', 'type' => 0, 'parent' => null, 'children' => [
1 => ['name' => 'bbb', 'type' => 1, 'parent' => null, 'children' => []],
2 => ['name' => 'ccc', 'type' => 0, 'parent' => null, 'children' => [
3 => ['name' => 'ddd', 'type' => 1, 'parent' => 2, 'children' => []]
]]
]],
4 => ['name' => 'eee', 'type' => 0, 'parent' => null, 'children' => []]
];
For this example, I would like to remove all objects that are of type 1 and get a clean array without those only.
I don't really understand why it is possible to get all descendats of an object but not be able to pass conditions.
Thanks in advance.
A collection only solution would be something like this (place the custom macro in a Service Provider of your application):
Collection::macro('whereDeep', function ($column, $operator, $value, $nested) {
return $this->where($column, $operator, $value)->map(function ($x) use ($column, $operator, $value, $nested) {
return $x->put($nested, $x->get($nested)->whereDeep($column, $operator, $value, $nested));
});
});
Then where needed call:
$yourArray->whereDeep('type', '!=', 1, 'children');
On your example, the macro works like this:
Filter all the elements where: type != 1
(the outer array will beuntouched as both items has type => 0)
For each element of the current array:
Retrive the children property and apply the same filtering to this subarray starting with the first point of this instructions.
Replace the children property with the new children property just filtered.
Anyways, you should try to deep dive into why the relation filtering doesn't work. That solution would be more efficient if optimized correctly.
I found a great solution where there is no need of all this recursion or any of these relationship calls so I share it:
Using: "gazsp/baum"
// get your object with roots method
$contents = Content::roots()->get();
// and simply run through the object and get whatever you need
// thanks to getDescendantsAndSelf method
$myArray = [];
foreach($contents as $content) {
$myArray[] = $content->getDescendantsAndSelf()->where('type', '!=', 1)->toHierarchy();
}
return $myArray;
This works for me the same way as the other method above.
I have an array in my request:
['progress_group'] = [0, 0];
['fields'] = [];
If all values in progress_group have the value '0', then the field: fields, should be required. How do I implement this?
I've tried:
$rules = [
'progress_group.*' => 'required',
//'fields' => 'present',
'fields.*' => 'required_if:progress_group.*,0'
];
So:
['progress_group'] = [0, 0];
means fields is required, but
['progress_group'] = [0, 1];
means it is not required to fill in..
required_if compares each element from one array with the one you are comparing with, so it will be progress_group[0] == fields[0] and so on for each item.
What you need is I guess a sum of all the values to be either 0 than it is required, and if the sum is bigger than 0 then it is not required.
So you can make a custom rule, or update your validation as such:
$total = array_sum(request()->input('progress_group'));
if($total == 0) {
$rules['fields.*'] = 'required';
}
I think you had the right idea to use requiredIf, but I think youmay have got the use and syntax wrong, I think this is correct, or will help you on the way to solving your problem:
Validator::make($request->all(), [
'progress_group.*' => 'required',
'fields' => 'present',
'fields.*' => Rule:requiredIf:(progress_group.*, 0),
]);
I have a store function that saves array items into my items table and together with that I am trying to check if the product_is is already in my Warehouse1StockSummaries. if still not, I will grab the product_id and its qty, If its there already then I want to ADD the value from the 'stock_in_qty' which is inside the array to the 'qty_in' in my Warehouse1StockSummaries. I hope my explanation make sense to you :)
here's my code.
public function store(Request $request)
{
$input = $request->all();
$items = [];
for($i=0; $i<= count($input['stock_in_qty']); $i++) {
if(empty($input['stock_in_qty'][$i]) || !is_numeric($input['stock_in_qty'][$i])) continue;
$acceptItem = [
'order_id' => $input['order_id'][$i],
'product_id' => $input['product_id'][$i],
'order_item_id' => $input['order_item_id'][$i],
'delivery_date' => $input['delivery_date'][$i],
'company_id' => $input['company_id'][$i],
'stock_in_qty' => intval($input['stock_in_qty'][$i]),
'stock_out_qty' => $input['stock_out_qty'][$i],
'transfer_to' => $input['transfer_to'][$i],
'delivery_note' => $input['delivery_note'][$i],
'user_id' => $input['user_id'][$i]
];
$product_id = $input['product_id'][$i];
$qty_in = intval($input['stock_in_qty'][$i]);
// dd($qty_in);
// ADD stock_in_qty TO QTY_IN ????
$stockSummary = Warehouse1StockSummaries::updateOrCreate(
['product_id' => $product_id ],
['qty_in' => $qty_in,
'qty_out' => null
]);
// dd($stockSummary);
array_push($items, Warehouse1stocks::create($acceptItem));
}
return redirect()->route('orders.index');
}
I check and everything is ok the only missing is the part where I need to grab the value from 'stock_in_qty' and add to 'qty_in' if the product id is already found in Warehouse1StockSummaries. Thank you so much in advance!
You could use the wasRecentlyCreated property on the model to determine if the model has just been created or not. If it hasn't then it won't have used $qty_in value, this means you could then use the increment() to add to the existing value in the database:
$stockSummary = Warehouse1StockSummaries::firstOrCreate(
['product_id' => $product_id ],
['qty_in' => $qty_in, 'qty_out' => null]
);
if (!$stockSummary->wasRecentlyCreated) {
$stockSummary->increment('qty_in', $qty_in);
}