How to update mysql table with array of data - Laravel - laravel

I am trying to update multiple rows using this code:
$data = [];
foreach ($projectFieldOptions as $mapping) {
$data[] = [
'import_field_slug' => $mapping['value'],
'internal_field_slug' => $mapping['text'],
'custom_field' => $mapping['custom'],
'import' => 1,
'date_upd' => $now,
];
}
$update_feed_mappings = DB::table($db_name . '.feed_mappings')
->where('id_project', $token)
->where('id_feed', $id_feed)
->update($data);
But I got this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: update `shibbir_DB1`.`feed_mappings` set `0` = {\"import_field_slug\":\"date\",..........
Would you tell me how can I fix it?

update only works for a single row and each key must correspond to a column in your sql table. You can't use if with a multi-dimensional array.
You should move your update inside your loop to fix the issue.
foreach ($projectFieldOptions as $mapping) {
$data = [
'import_field_slug' => $mapping['value'],
'internal_field_slug' => $mapping['text'],
'custom_field' => $mapping['custom'],
'import' => 1,
'date_upd' => $now,
];
DB::table($db_name . '.feed_mappings')
->where('id_project', $token)
->where('id_feed', $id_feed)
->update($data);
}

Consider the code below please
$data = [];
$projectFieldOptions =
$data[] = [
'import_field_slug' => 1,
'internal_field_slug' => 1,
'custom_field' => 1,
'import' => 1,
'date_upd' => 1,
];
$data[] = [
'import_field_slug' => 2,
'internal_field_slug' => 2,
'custom_field' => 2,
'import' => 2,
'date_upd' => 2,
];
var_dump($data);
The output will be
array(2) {
[0]=>
array(5) {
["import_field_slug"]=>
int(1)
["internal_field_slug"]=>
int(1)
["custom_field"]=>
int(1)
["import"]=>
int(1)
["date_upd"]=>
int(1)
}
[1]=>
array(5) {
["import_field_slug"]=>
int(2)
["internal_field_slug"]=>
int(2)
["custom_field"]=>
int(2)
["import"]=>
int(2)
["date_upd"]=>
int(2)
}
}
So your update translates into something like that
update(['0' => array(...))
But update method needs something like that
update(['import_field_slug' => 1,...])
Conclusion: please update each record one by one inside your loop
Further reading

Related

How to apply subtraction in the query in laravel?

I have one array which contains all the records. I am passing all those records to a loop and there I am getting the sum of the clear column which has null upto.
This part is working fine, now my requirement is I want to add one more check which is based on the one more column refund.
If any column contains refund=1 that amount should be subtracted from the total, can you please help me to achieve the scenario
foreach ($row_data as $key => $value) {
$data_arr[$key]['total'] = ['Price'=> $value->whereIn('clear', null)->sum('amount')];
}
Data
data = [
{'amount' => 55, 'clear' => 'null', 'refund' => '0'},
{'amount' => 5, 'clear' => 'null', 'refund' => '1'},
{'amount' => 10, 'clear' => 'null', 'refund' => '0'},
];
Expected result is :-60
ACtual Result is :- 70
reduce should help.
$data = [
['amount' => 55, 'clear' => null, 'refund' => '0'],
['amount' => 5, 'clear' => null, 'refund' => '1'],
['amount' => 10, 'clear' => null, 'refund' => '0'],
];
You can be very explicit
// sum if refund is 0, substract if refund is 1
$sum = collect($data)
->where('clear', null)
->reduce(function ($carry, $item) {
if ($item['refund'] == '0') {
return $carry + $item['amount'];
} elseif ($item['refund'] == '1') {
return $carry - $item['amount'];
}
}, 0);
Or write it a bit shorter
// sum if refund is 0, substract otherwise
$sum = collect($data)
->where('clear', null)
->reduce(fn($carry, $item) => ($item['refund'] == '0')
? $carry + $item['amount']
: $carry - $item['amount']);
You can even do it without collections using php's array_reduce and array_filter functions. Works pretty much in the same way.
$sum = array_reduce(
array_filter($data, function ($item) {
return $item['clear'] == null;
}),
function($carry, $item) {
return $item['refund'] == '0'
? $carry + $item['amount']
: $carry - $item['amount'];
});
$sum = array_reduce(
array_filter($data, fn($item) => $item['clear'] == null)
fn($carry, $item) => $item['refund'] == '0'
? $carry + $item['amount']
: $carry - $item['amount']
);
I don't have all your code with variable declaration so I created logic snippet with your use case.
EDIT: You can simply get your total amount and substract you total refund as you can see in code below
/** #var Collection $data */
$data = collect([
['amount' => 55, 'clear' => null, 'refund' => false],
['amount' => 5, 'clear' => null, 'refund' => true],
['amount' => 10, 'clear' => null, 'refund' => false],
]);
$totalAmount = $data->whereNull('clear')->sum('amount');
$totalRefund = $data->whereNull('clear')
->where('refund', true)
->sum('amount'); // = 5
$subValue = $totalAmount - $totalRefund

Undefinde offset:1 when importing laravel excel

this my code cause the trouble,
$cust = Customer::where('name', '=', $data[$i][0]['customer_name'])
->pluck('customer_id')[0];
this one for get customer id when i do store to sales order
$sales = array(
'customer_id' => Customer::where('name', '=', $data[$i][0]['customer_name'])->pluck('customer_id')[0],
'logistics_id' => Logistic::where('logistics_name', '=', $data[$i][0]['logistics'])->pluck('logistics_id')[0],
'subtotal' => $data[$i][0]['subtotal_rp'],
'shipping_cost' => $data[$i][0]['shipping_cost_rp'],
'discount_code' => 0,
'date_of_sales' => $data[$i][0]['date'],
'grand_total' => $data[$i][0]['grand_total_rp'],
'tax' => $data[$i][0]['tax_rp'],
'status' => $data[$i][0]['status'],
'discount_amount' => $data[$i][0]['discount_amount_rp']
);
$store_so = SalesOrder::create($sales);
but, when i do dd(), i get the right data
First of all, you need to check if the $data variable returns the data as you expect.
dd($data);
Next, you need to check that the $data array has the number of elements according to $total_data.
dd(count($data) == $total_data));
So basically, you just need to give condition or try-catch (recommended) :
if (isset($data[$i][0])) {
$customer = Customer::where('name', $data[$i][0]['customer_name'])->first();
$logistic = Logistic::where('logistics_name', $data[$i][0]['logistics'])->first();
if(!$customer){
dd('No customer found!');
}
if(!$logistic){
dd('No logistic found!');
}
$sales = [
'customer_id' => $customer->customer_id,
'logistics_id' => $logistic->logistics_id,
'subtotal' => $data[$i][0]['subtotal_rp'],
'shipping_cost' => $data[$i][0]['shipping_cost_rp'],
'discount_code' => 0,
'date_of_sales' => $data[$i][0]['date'],
'grand_total' => $data[$i][0]['grand_total_rp'],
'tax' => $data[$i][0]['tax_rp'],
'status' => $data[$i][0]['status'],
'discount_amount' => $data[$i][0]['discount_amount_rp'],
];
$store_so = SalesOrder::create($sales);
}
else{
dd('No $data[$i][0] found!');
}
PS : I recommend using the first() method instead of pluck('customer_id')[0].
It seems you need to get a customer_id from a customer_name.
Try to make everything simple:
$sales = array(
'customer_id' => Customer::where('name', $data[$i][0]['customer_name'])->first()->id,
...
);

Laravel backpack select2_from_ajax setting my value as null after the correct value has been saved

Im having a weird problem.
Im using laravel backpack for an admin panel. There i use select2_from_ajax to list a values according to another field in create operation. It is showing up correctly as expected & i can select one too.
But after selection when i click save & back it gives me an error
That means my column doesn't allow to update to null right.
So when i go back & check the column it has saved the correct value.
But when default value of my column was null this error will not showup & db value would be changed to null.
This is my select2_from_ajax part.
$this->crud->addField([ // Select
'label' => "Link Type",
'type' => 'select_from_array',
'name' => 'link_type', // the db column for the foreign key
'options' => [1 => 'Product',0 => 'Collection'],
'allows_null' => false,
]);
$this->crud->addField([ // Select
'label' => "Link To", // Table column heading
'type' => "select2_from_ajax",
'name' => "link_to",
'entity' => 'link',
'attribute' => "name",
'data_source' => url('admin/itemtype'),
'placeholder' => "Select a item",
'minimum_input_length' => 0,
'include_all_form_fields' => true,
'dependencies' => ['link_type'],
]);
So why is it trying to set null value after the correct value?
Any help would be appreciated. Thanks.
My admin/itemtype function:
$search_term = $request->input('q');
$form = collect($request->input('form'))->pluck('value', 'name');
if ($search_term) {
if ($form['link_type'] == 0) {
$items = Collection::where('name', 'LIKE', '%' . $search_term . '%')->paginate(10);
} else {
$items = Product::where('title', 'LIKE', '%' . $search_term . '%')->paginate(10);
}
} else {
if ($form['link_type'] == 0) {
$items = Collection::paginate(10);
} else {
$items = Product::paginate(10);
}
}
return $items;

because it shows Undefined offset: 0, seeder laravel?

I have the following for in which I create the records
foreach ($v as $k => $f){
if($v[$k] != false && $f['zip_code'] !=''){
$state = State::whereCode($f['code'])->get();
var_dump($state[0]->id);
\App\Models\ZipCodes::create([
'uuid' => Uuid::generate(4)->string,
'zip_code' => $f['zip_code'],
'city' => $f['city'],
'county' => $f['county'],
'state_id' => $state[0]->id,
]);
}
}
I have noticed that the error appears in the field 'state_id' => $ state [0] -> id
since if I comment and delete it from the table it doesn't give me the error.
In fact if I just leave
foreach ($v as $k => $f){
if($v[$k] != false && $f['zip_code'] !=''){
$state = State::whereCode($f['code'])->get();
var_dump($state[0]->id);
}
}
The same generates the error.

Map array values to collection of items

How would one do the following elegantly with laravel collections ?
Map the values of the $baseMap as keys to the collection.
The baseMap :
$baseMap = [
'name' => 'new_name',
'year' => 'new_year',
];
The collection :
$items = collect([
[
'name' => 'name1',
'year' => '1000',
'not_in_basemap' => 'foo'
],
[
'name' => 'name2',
'year' => '2000',
'not_in_basemap' => 'foo'
],
//...
]);
The end result :
$result =[
[
'new_name' => 'name1',
'new_year' => '1000',
],
[
'new_name'=> 'name2',
'new_year' => '2000',
],
];
I know how to do it in plain php , just wondering what a nice collection version would be. Thanks!
I tried to find collection methods, or php functions, but without success. Some dirty code that works with different keys from both sides (items and basemap).
$result = $items->map(function($item) use ($baseMap) {
$array = [];
foreach($baseMap as $oldKey => $newKey){
if(isset($item[$oldKey])){
$array[$newKey] = $item[$oldKey];
}
}
return $array;
});
$result = $result->toArray();
Thanks to #vivek_23 and #IndianCoding for giving me idea's I ended up with the following :
I made a small edit to make sure the mapping and the items keys lined up.
so you don't have to worry of misalignment and all in laravel collection !
$baseMap = collect($baseMap)->sortKeys();
$result = $items->map(function ($item) use ($baseMap) {
return $baseMap->values()
->combine(
collect($item)->sortKeys()->intersectByKeys($baseMap)
)
->all();
});
Use intersectByKeys to filter your baseMap keys with $items values.
$result = $items->map(function($item,$key) use ($baseMap){
return array_combine(array_values($baseMap),collect($item)->intersectByKeys($baseMap)->all());
});
dd($result);
Update:
In a pure collection way,
$baseMapCollect = collect($baseMap);
$result = $items->map(function($item,$key) use ($baseMapCollect){
return $baseMapCollect->values()->combine(collect($item)->intersectByKeys($baseMapCollect->all())->values())->all();
});
dd($result);
Here are my two cents, using map. Don't know how dynamic your collection should be, but knowing the keys I would do the following:
$baseMap = [
'name' => 'new_name',
'year' => 'new_year',
];
$items = collect([
[
'name' => 'name1',
'year' => '1000',
'not_in_basemap' => 'foo'
],
[
'name' => 'name2',
'year' => '2000',
'not_in_basemap' => 'foo'
],
])->map(function($item, $key) use ($baseMap) {
return [
$baseMap['name'] => $item['name'],
$baseMap['year'] => $item['year']
];
});

Resources