I'm using Laravel Excel by https://laravel-excel.com/. I have a CSV file that has data like:
I want to import some CSV and validate the existed data and not inserting it into database.
But, I want to insert data that not existed in database and I don't know how to validate it.
I just want to insert the new data together and denying the old one for the purpose of preventing some duplicate data after importing CSV into a database and reducing human error.
I have example code like this:
<?php
namespace App\Imports\Points;
use App\Models\PointRegular;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\Importable;
class PointsRegularImport implements ToCollection, WithHeadingRow
{
use Importable;
public function collection(Collection $rows)
{
foreach($rows as $row) {
// Check existing data in database
$pointRegulars = PointRegular::orderBy('created_at', 'desc')
->where('product_id', $row['product_id'])
->where('channel_id', $row['channel_id'])
->where('transaction_type_id', $row['transaction_type_id'])
->where('payment_method_id', $row['payment_method_id'])
->get();
foreach($pointRegulars as $pointRegular) {
// Check for update data with id
if($row->has('id')) {
if($pointRegular->id == $row['id']) {
$point = PointRegular::findOrFail($row['id']);
$point->product_id = $row['product_id'];
$point->channel_id = $row['channel_id'];
$point->transaction_type_id = $row['transaction_type_id'];
$point->payment_method_id = $row['payment_method_id'];
}
} else {
// Create new data
// Check for data existed in database
// If exist, deny existed data and insert new data
if($pointRegular) {
return "Existed and not insert";
} else {
return "You Inserting new data without creating the old one";
}
}
}
}
}
}
Using updateOrCreate with Eloquent reference here
function updateOrCreate(array $attributes, array $values = []){}
Related
While trying to update database using Excel:
public function collection(Collection $rows)
{
foreach ($rows as $row)
{
$this->gradelevel = $row['grade_level_code'];
$employeegrade = HrEmployee::where('company_id',auth()->user()->company_id)->where('employee_code', $row['staff_id'])->where('email', $row['official_email']) ->first();
$employeegrade->grade_level_id = $this->getGradeLevel();
$employeegrade->save();
}
}
public function getGradeLevel(){
if(!empty($this->gradelevel) || !$this->gradelevel){
return HrGradeLevel::where('grade_level_code',$this->gradelevel)->where('company_id',Auth::user()->company_id)->pluck('id')->first();
} else {
return 0;
}
}
I got this error:
production.ERROR: Creating default object from empty value
and it points to this line:
$employeegrade->grade_level_id = $this->getGradeLevel();
How do I get this resolved?
most probably this will return null
$employeegrade = HrEmployee::where('company_id',auth()->user()->company_id)->where('employee_code', $row['staff_id'])->where('email', $row['official_email']) ->first();
You can also use firstOrNew() if not exist then will create new object of HrEmployee
$employeegrade = HrEmployee::firstOrNew(array("column"=>value, "column2"=>value));
if you want update the existing record only use as
$employeegrade = HrEmployee::where('company_id',auth()->user()->company_id)->where('employee_code', $row['staff_id'])->where('email', $row['official_email']) ->first()
if(!$employeegrade){
//log error employee nit found
}else
{
//update record
}
I want to insert new data in database using API, but first, i want to check the database using $po_transaction, it exist or not, if $po_transaction exist, do updated. But when i am input same data, it changed all data with one value
This is my database, when first insert:
and this is my database, when i am input same data (This the issue):
This is my controller:
public function post_data(Request $request){
$po_transaction = $request->input('po_transaction');
$data = $request->input('data');
$decode_data = json_decode($data);
if(!$decode_data){
return response()->json(['message'=>'No Data','success'=>0]);
}
$po_id = Produk::where('po_transaction','=', $po_transaction)->first();
// if po_id exist, update the data
if ($po_id) {
foreach ($decode_data as $item => $value) {
DB::table('produk')
->where('po_transaction', $po_transaction)
->update(['po_transaction'=>$po_transaction, 'nama_produk'=>$value->produk, 'harga_jual'=>$value->price]);
}
return response()->json(['message'=>'success, data saved','success'=>1]);
}else{
// if po_id not exist, create new
foreach($decode_data as $item => $value)
{
$saveTransaction = new Produk();
$saveTransaction->po_transaction = $po_transaction;
$saveTransaction->nama_produk = $value->produk;
$saveTransaction->harga_jual = $value->price;
$saveTransaction->save();
}
if($saveTransaction->save()){
return response()->json(['message'=>'success, data saved','success'=>1]);
}else{
return response()->json(['message'=>'no data saved','success'=>0]);
}
}
}
and for data, i am using json data like this:
[
{"produk":"shampoo","price":"12000"},
{"produk":"noodle","price":"110200"},
{"produk":"cup","price":"1000"}
]
This is decode_data:
How to fix this issue, when i input same data, it not only change all data with one value?
You need to specify which record you actually want to update by proving the id in the where clause like this:
DB::table('produk')
->where([
'po_transaction' => $po_transaction,
'id_produk'=> $value->id,
])
->update([
'po_transaction'=>$po_transaction,
'nama_produk'=>$value->produk,
'harga_jual'=>$value->price,
]);
You can use this method <model_name>::updateOrCreate() to Create/Update in single method.
Produk::updateOrCreate(['po_transaction'=>$po_transaction,'nama_produk'=>$value->produk],['harga_jual'=>$value->price]);
for more info look at this https://laravel.com/docs/5.7/eloquent
I'm using $casts to save data in array to database. I have an issue with that.
How can i push data to an existing array in the database?
For example i have already an array of data in my db column like: ["some_data", "another_el"] and so on and in the Controller i want to push in this array in db some other data from input.
$brand = Brand::find($request->input('brand'));
$brand->model = $request->input('model');
$brand->update();
Pushing data like this.
You cannot do this with Eloquent's Mass Assignment functions (update, create, etc). You must pull down your field, change it, then save the model.
$collection = collect($brand->field);
$collection->push($myNewData);
$brand->field = $collection->toJson();
$brand->save();
Way 1
$brand = Brand::find($request->input('brand'));
$brand->model = array_merge($brand->model, [$request->input('model')]);
$brand->update();
Way 2 (my favorite because it encapsulates the logic)
$brand = Brand::find($request->input('brand'));
$brand->addModel($request->input('model'));
$brand->update();
And on Entity:
public function addModel($value)
{
$this->model = array_merge($this->model, [$value]);
}
Optional
And on Entity (instead $casts):
public function setModelAttribute($value)
{
$this->attributes['model'] = json_encode($value);
}
public function getModelAttribute($value)
{
return json_decode($value, true);
}
Hi I have problem when i tried to save attribute of model to database. I write in OctoberCMS and i have this function:
public function findActualNewsletter()
{
$actualNewsletter = Newsletter::where('status_id', '=', NewsletterStatus::getSentNowStatus())->first();
if (!$actualNewsletter) {
$actualNewsletter = Newsletter::where('send_at', '<=', date('Y-m-d'))->where('status_id', NewsletterStatus::getUnsentStatus())->first();
$actualNewsletter->status_id = NewsletterStatus::getSentNowStatus();
dd($actualNewsletter);
}
return $actualNewsletter;
}
getSentNowStatus()=2;
getUnsentStatus()=1;
dd($actualNewsletter) in my if statement show that status_id = 2 But in database i still have 1. I used this function in afterSave() so i dont need:
$actualNewsletter->status_id = NewsletterStatus::getSentNowStatus();
$actualNewsletter->save();
becosue i have error then i use save in save.
Of course i filled table $fillable =['status_id']. And now i dont know why its not save in database when it go to my if. Maybe someone see my mistake?
If you are trying to modify the model based on some custom logic and then save it, the best place to put it is in the beforeSave() method of the model. To access the current model being saved, just use $this. Below is an example of the beforeSave() method being used to modify the attributes of a model before it gets saved to the database:
public function beforeSave() {
$user = BackendAuth::getUser();
$this->backend_user_id = $user->id;
// Handle archiving
if ($this->is_archived && !$this->archived_at) {
$this->archived_at = Carbon\Carbon::now()->toDateTimeString();
}
// Handle publishing
if ($this->is_published && !$this->published_at) {
$this->published_at = Carbon\Carbon::now()->toDateTimeString();
}
// Handle unarchiving
if ($this->archived_at && !$this->is_archived) {
$this->archived_at = null;
}
// Handle unpublishing, only allowed when no responses have been recorded against the form
if ($this->published_at && !$this->is_published) {
if (is_null($this->responses) || $this->responses->isEmpty()) {
$this->published_at = null;
}
}
}
You don't have to run $this->save() or anything like that. Simply modifying the model's attributes in the beforeSave() method will accomplish what you desire.
I have the following class:
<?php
class photos_profile {
// Display UnApproved Profile Photos
public $unapprovedProfilePhotosArray = array();
public function displayUnapprovedProfilePhotos() {
$users = new database('users');
$sql='SELECT userid,profile_domainname,photo_name FROM login WHERE photo_verified=0 AND photo_name IS NOT NULL LIMIT 100;';
$pds=$users->pdo->prepare($sql); $pds->execute(array()); $rows=$pds->fetchAll();
$unapprovedProfilePhotosArray = $rows;
echo 'inside the class now....';
foreach($rows as $row) {
echo $row['userid'];
}
}
}
I can display the data successfully from the foreach loop.
This is a class that is called as follows and want to be able to use the array in the display/view code. This why I added the "$unapprovedProfilePhotosArray = $rows;" but it doesn't work.
$photos_profile = new photos_profile;
$photos_profile->displayUnapprovedProfilePhotos();
<?php
foreach($photos_profile->unapprovedProfilePhotosArray as $row) {
//print_r($photos_profile->unapprovedProfilePhotosArray);
echo $row['userid'];
}
?>
What is the best way for me to take the PHP PDO return array and use it in a view (return from class object). I could loop through all the values and populate a new array but this seems excessive.
Let me know if I should explain this better.
thx
I think you're missing the $this-> part. So basically you're creating a local variable inside the method named unapprovedProfilePhotosArray which disappears when the method finishes. If you want that array to stay in the property, then you should use $this->, which is the proper way to access that property.
...
$pds=$users->pdo->prepare($sql); $pds->execute(array()); $rows=$pds->fetchAll();
$this->unapprovedProfilePhotosArray = $rows;
...