Importer function issue using Maat, Excel and Laravel - php

I know this may seem like a long shot, but I have no idea why my importer is missing some columns and taking in others.
I have required the latest Maat version and even did a test using their example to a table of mine and it worked like a charm with the exact table I am using now.
However, there were a few things I need to happen on the create, so I ended up changing it to what was suggested here: https://laracasts.com/discuss/channels/laravel/how-to-include-created-at-and-updated-at-with-imported-file (about 5th answer down)
So now I have a controller function that looks like this:
public function importCustomers (Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
$data = Excel::load($path, function($reader) {
})->get();
if(!empty($data) && $data->count()){
foreach ($data as $key => $value) {
$user = Auth::user()->id;
Customer::create([
'company_name' => $value->company_name,
'first_name' => $value->first_name,
'last_name' => $value->last_name,
'account_type' => $value->account_type,
'shipping_address_1' => $value->shipping_address_1,
'shipping_address_2' => $value->shipping_address_2,
'shipping_city' => $value->shipping_city,
'shipping_state' => $value->shipping_state,
'shipping_zipcode' => $value->shipping_zipcode,
'billing_address_1' => $value->billing_address_1,
'billing_address_2' => $value->billing_address_2,
'billing_city' => $value->billing_city,
'billing_state' => $value->billing_state,
'billing_zipcode' => $value->billing_zipcode,
'primary_phone' => $value->primary_phone,
'mobile_phone' => $value->mobile_phone,
'primary_fax' => $value->primary_fax,
'old_account_number' => $value->old_account_number,
'website' => $value->website,
'customer_name' => $value->customer_name,
'origin' => $value->origin,
'primary_email' => $value->primary_email,
'created_by' => $user,
'carrier' => $value->carrier,
'notes' => $value->notes
]);
}
}
}
Session::flash('flash_message','Database successfully imported!');
return back();
}
and this is the top of my controller up until the end of $fillable:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Customer;
use App\Shipment;
use App\Equipment;
use Validator;
use Response;
use App\User;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Auth;
use DB;
use Storage;
use Illuminate\Http\File;
use Excel;
class CustomerController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
protected $rules =
[
// 'originName' => 'required|min:2|max:32|regex:/^[a-z ,.\'-]+$/i',
'account_type' => 'required'
];
protected $fillable =
[
'company_name',
'first_name',
'last_name',
'account_type',
'shipping_address_1',
'shipping_address_2',
'shipping_city',
'shipping_state',
'shipping_zipcode',
'billing_address_1',
'billing_address_2',
'billing_city',
'billing_state',
'billing_zipcode',
'primary_phone',
'mobile_phone',
'primary_fax',
'old_account_number',
'website',
'customer_name',
'origin',
'primary_email',
'created_by',
'carrier',
'notes'
];
I get the following error if I try to post the import:
SQLSTATE[HY000]: General error: 1364 Field 'created_by' doesn't have a default value (SQL: insert into `customers` (`company_name`, `first_name`, `last_name`, `account_type`, `shipping_city`, `shipping_state`, `billing_city`, `billing_state`, `primary_phone`, `primary_fax`, `customer_name`, `origin`, `primary_email`, `updated_at`, `created_at`) values (BULLET LINE, , , 1, OAK CREEK, WI, OAK CREEK, WI, , , BULLET LINE, 0, , 2017-12-20 19:15:47, 2017-12-20 19:15:47))
As you see, "created_by" is in fact a field in my MySQL table, by it's not even a field that is being passed or anything like that. Even though you can see it's not from my csv, rather the value comes from $auth::user()->id but there are missing fields that I know for a fact are in my excel sheet (and didn't have a problem being imported when I tried out using the document of just importing everything), and you can see them in my function, and they are fillable so I'm not sure what's going on.
The current missing fields are:
shipping_address_1
shipping_address_2
shipping_zipcode
billing_address_1
billing_address_2
billing_zipcode
mobile_phone
old_account_number
website
carrier
notes
Does anyone have any suggestions?

You have to move $fillable variable to Customer Model. It is in the wrong file, it is not going to work in the Controller file. This is the reason why it is missing fields. Probably $fillable variable in Model file is missing these fiels.
Ref: https://laravel.com/docs/5.5/eloquent#mass-assignment

Related

Why my updateOrInsert doesn't work in laravel 9x

I use updateOrInsert to avoid duplicate data, why doesn't the Update function work and always insert data?
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Models\Wip;
use App\Models\db2;
class WipController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$tgl_skrg = date('Y-m-d 00:00:00');
$tgl_skrg2 = date('Y-m-d 23:00:00');
$nilai = '00017';
$db2s = DB::connection('mysql2')->table("wip_tracking_1")->get();
$data = json_decode($db2s, true);
foreach ($data as $db2 ){
DB::table('wip_tracking')
->updateOrInsert(
[
"TP" =>$db2 ['TP'],
"TP_code"=>$db2 ['TP_code'],
"VIN"=>$db2 ['VIN'] ,
"Flag"=>$db2 ['Flag'] ,
"Suffix"=>$db2 ['Suffix'] ,
"Color_Code"=>$db2 ['Color_Code'] ,
"Scan_date"=>$db2 ['Scan_date'] ,
"Production_date"=>$db2 ['Production_date'] ,
"Production_shift"=>$db2 ['Production_shift'] ,
"Model_code"=>$db2 ['Model_code'] ,
"Brand"=>$db2 ['Brand'] ,
"Destination_code"=>$db2 ['Destination_code'] ,
"WIP_code"=>$db2 ['WIP_code'] ,
"ADM_Production_ID"=>$db2 ['ADM_Production_ID'] ,
"Plan_delivery_date"=>$db2 ['Plan_delivery_date'] ,
"created_at" => date('Y-m-d H:i:s'),
],
[
"ADM_Production_ID"=> $db2['ADM_Production_ID']
],
[
"VIN"=> $db2['VIN']
],
);
}
}
updateOrInsert should receive two parameter arrays. The first one is a conditional array, which will check for the records and second array of columns and values to be updated or inserted.
e.g.
DB::table('users')
->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
first array ['email' => 'john#example.com', 'name' => 'John'] will look for matching column => value pairs.
second array ['votes' => '2'] will update or insert data based on findings.
https://laravel.com/docs/9.x/queries#update-or-insert
In your case, it seems that you're trying to match a lot of values in your first array, which might be the reason why exact match is never found and it's always producing a new entry, try to limit and keep your conditional array more spcific.

There is nothing happening when store data for Laravel API

I making laravel API where i can store a new data where the value in body raw json. but when i try to send request using post, i got nothing but the status is 200 OK. when i chek my mysql there is no data inputed.
So, what should i do?
mysql data
Laravel Controller, and API,
// function in controller
use App\Models\ChartAge;
class ChartController extends Controller
{
public function saveChart(Request $request)
{
$data = $request->validate([
'entity' => 'required|string|max:10',
'code' => 'required|string|max:10',
'year' => 'required|int|max:10',
'under_age_15' => 'required|string|max:50',
'age_15_64' => 'required|string|max:50',
'age_65_over' => 'required|string|max:50',
]);
$values = ChartAge::create($request);
return response()->json(
[
'status' => true,
'message' => "the videos has been favorites",
'data' => $values,
],
201
);
}
}
//in api.php
Route::post("charts", [ChartController::class, 'saveChart']);
and here is when i tried to send request using postman.
because there is no error, i don't know what's wrong??
First double check your ChartAge model, does it have $fillable or not?
and Edit your code:
From
$values = ChartAge::create($request);
To:
$values = ChartAge::create($request->all());
Hope this will be useful.
With validation:
$data = \Validator::make($request->all(),[
'entity' => 'required|string|max:10',
'code' => 'required|string|max:10',
'year' => 'required|int|max:10',
'under_age_15' => 'required|string|max:50',
'age_15_64' => 'required|string|max:50',
'age_65_over' => 'required|string|max:50',
]);
if($data-> fails()){
return back()->withErrors($data)->withInput();
}
$values = ChartAge::create($request->all());
Do you set fillable fields in your 'ChartAge' model?
protected $fillable = ['entity','code','year'...];
Do you try to test code with disabling validation?
Please try to put dd($request) in the first row of the controller code.
Method create expects a plain PHP array, not a Request object.

escaping comma for faker on lumen seeder

I'm learning to do some simple migration and seeding on lumen using factory and faker to mysql database, below are my codes :
PostSeeder.php
use Illuminate\Database\Seeder;
class PostSeeder extends Seeder
{
public function run()
{
factory(App\Models\Post::class, 40)->create();
}
}
and on the factory PostFactory.php
$factory->define(Post::class, function (Faker $faker) {
return [
'post_id' => Str::uuid(),
'title' => $faker->sentence(3),
'content' => $faker->realText(200),
'user_id' => Str::uuid(),
'created_at' => $faker->dateTimeBetween('-1 years', 'now')->format('Y-m-d H:i:s'),
'created_by' => Str::uuid(),
'app' => NULL
];
});
when I tried to run the seeder got error like this :
SQLSTATE[22001]: String data, right truncated: 1406 Data too long for
column 'user_id' at row 1 (SQL: insert into 'posts' ('post_id', 'title',
'content', 'user_id', 'created_at', 'created_by', 'app') values
(c1460ae8-e472-4439-aad8-af3aaf090268, Assumenda
ipsa corrupti., King triumphantly, pointing to the shore, and then
treading on her spectacles, and began picking them up again as quickly
as she could. The next thing was snorting like a wild beast,
screamed 'Off.))
I'm not sure, but looks like on faker realText comma is not being escaped on the query, is there anything I need to add on the factory to escape the faker, or need to do something on the database?
I'm using mysql 14.14 on ubuntu 18.04 and lumen 7.x
on posts table the content type is text

How should I use factories in Laravel when I have default values in DB

I have a factory:
$factory->define(\App\MissingData::class, function (Faker $faker) {
$operations = Operation::all()->pluck('id')->toArray();
$operationId = $faker->randomElement($operations);
$operation = Operation::find($operationId);
$meters = $operation->meters->pluck('id')->toArray();
$arrStatus = ['Done', 'Undone'];
return [
'operation_id' => $operationId,
'meter_id' => $faker->randomElement($meters),
'date_ini' => $faker->dateTimeThisYear,
'date_end' => $faker->dateTimeThisYear,
'status' => $faker->randomElement($arrStatus),
];
});
In my migration, I have:
$table->string('status')->default('Undone');
When I want to insert an array in DB, I always prefer to use factory:
factory(MissingData::class)->create($missingData);
with
return [
'operation_id' => $measure->operation_id,
'meter_id' => $measure->meter_id,
'conso_prod' => $measure->conso_prod,
'date_ini' => $missingDataIni,
'date_end' => $missingDataEnd,
];
The wanted behaviour is to insert the status: 'Undone' configured in DB, but my factory will generate a fake status, so I will always have to send Undone status to my factory, which is not the point of using a DB default.
How am I supposed to manage this. Using factory to create and insert model is a good practice.
Using default in DB is also very practical, I believe they can be used both at the same time, but I don't see how should I do that.
Any idea ?
Your best bet is probably to default the status to undone then have a seperate state for done and any other status' that you may add.
$factory->define(\App\MissingData::class, function (Faker $faker) {
$operations = Operation::all()->pluck('id')->toArray();
$operationId = $faker->randomElement($operations);
$operation = Operation::find($operationId);
$meters = $operation->meters->pluck('id')->toArray();
return [
'operation_id' => $operationId,
'meter_id' => $faker->randomElement($meters),
'date_ini' => $faker->dateTimeThisYear,
'date_end' => $faker->dateTimeThisYear,
'status' => 'Undone',
];
});
$factory->state(\App\MissingData::class, 'done', fn() => ['status' => 'Done']);
Then when you want the status to be done you would use the state like this.
factory(\App\MissingData)->state('done')->create();

Mass Assignment Insert in Eloquent

In Laravel 5.1 I'm using mass assignment for inserts. But i want to learn how to bulk insert with Eloquent.
I need to insert sold products in order process.
Here is my data for insert.
foreach($cart['fields'] as $key => $product)
{
$orderDetailData[] = [
'order_id' => $orderData['order_id'],
'product_id' => $product['id'],
'quantity' => $product['total_quantity'],
'price' => floatval($product['wholesale_price']),
'vat' => $product['vat'],
'vat_value' => floatval($product['vat_value']),
'discount_ratio' => $product['discount_ratio'],
'discount' => floatval($product['discount_value']),
'total_amount' => floatval($product['total_amount']),
];
}
Here is my code for insert
(new OrderDetail)->create($orderDetailData);
I think this method doesn't support bulk insert.
In Laravel 5.1 Manuel i see this.
DB::table('table')->insert($orderDetailData);
What should i do for mass assignment for bulk insert ? Should i use previous one (DB facade)
Because i'm getting error (500 internal server error) with this code
(new OrderDetail)->create($orderDetailData);
To insert/creae using mass-assignment you may declare an array in your Eloquent model like this one:
protected $fillable = [
'order_id',
'product_id',
'quantity',
'more fields names here...'
];
Defined field names will be inserted. Check the documentation for more. Also you may use forceCreate method which allows mass-assignment.
Also, the 500 internal server error is not obvious about the specific error so find it out.
this is example you can make array of your data and can insert the same way here going on.
$data = array(
array(
'name'=>'Coder 1', 'rep'=>'4096',
'created_at'=>date('Y-m-d H:i:s'),
'modified_at'=> date('Y-m-d H:i:s')
),
array(
'name'=>'Coder 2', 'rep'=>'2048',
'created_at'=>date('Y-m-d H:i:s'),
'modified_at'=> date('Y-m-d H:i:s')
),
//...
);
YourModelName::create($data);
you can insert that way
$data = array(
array('name'=>'Coder 1', 'rep'=>'4096'),
array('name'=>'Coder 2', 'rep'=>'2048'),
//...
);
OrderDetail::insert($data);
also make fillable those fileds
protected $fillable = [
'name',
'rep_id',
];

Categories