Preventing multiple value in 3 column in laravel 5.5 - php

I have get problem on this case, I don't know how to prevent multiple value in 3 column, I mean if the 3 column have multiple value it will not insert to database,for example I have Krs table where has data like this :
| id | nim | nip | kode_mk
| 1 | 134 | 154 | 543
and laravel will ignore this data when someone insert data like this :
nim=134,nip=154,kode_mk=543 laravel will not insert and give an
atttention
but laravel will accept if data like this :
nim=1132,nip=154,kode_mk=543 laravel will accept and save to database
nim=134,nip=1984,kode_mk=543 laravel will accept and save to database
nim=1345,nip=154,kode_mk=543 laravel will accept and save to database
I have a table like this where I want prevent the data in the black circle:
this my Krs.php :
protected $fillable = ['nim','nip','kode_mk','absen','uts','uas'];
protected $table = 'krs';
public function mahasiswas(){
return $this->belongsToMany('App\Mahasiswa','id');
}
public function dosens(){
return $this->belongsToMany('App\Dosen','id');
}
public function makuls(){
return $this->belongsToMany('App\Matakuliah','id');
}
this my KrsController.php :
public function store(KrsRequest $request)
{
$krs = new Krs([
'nim' => $request->get('nim'),
'nip' => $request->get('nip'),
'kode_mk' => $request->get('kode_mk'),
'absen' => $request->get('absen'),
'uts' => $request->get('uts'),
'uas' => $request->get('uas')
]);
if ($krs->save()) {
session()->flash('status','done_all');
session()->flash('pesan','Data berhasil disimpan');
}else{
session()->flash('status','clear');
session()->flash('pesan','Data gagal disimpan');
}
return redirect('Akademik/Krs/create');
}
I don't know how to explain it in english , sorry for my bad grammar
EDIT 1 Table Structure

In your Krs migration, set the field to require the value to be unique. For example:
$table->string('kode_mk')->unique();

Related

How to add custom increment value to database with laravel excel import

i'm using maatwebsite laravel excel to import some data from excel to database. But i want to add some custom ID with incremental value for each row of data.
For now, i'm able to import data with some input value form together.
DataImport file
class DataImport implements ToModel, WithStartRow{
public function model(array $row)
{
return new Tempdat([
'employee_id' => ??? (combination of client_code +1)
'name' => $row[1],
'gender' => $row[2],
'bod' => $this->transformDate($row[3]),
'engagement_code' => request('engagement_code'), //from input form
'client_code' => request('client_code'), //from input form
]);
}
public function transformDate($value, $format = 'Y-m-d')
{
try {
return \Carbon\Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value));
} catch (\ErrorException $e) {
return \Carbon\Carbon::createFromFormat($format, $value);
}
}
public function startRow(): int
{
return 2;
} }
DataController file
public function ImportExcel(Request $request)
{
$this->validate($request,[
'file' => 'required|mimes:xls,xlsx',
'engagement_code' => 'required',
]);
$file = $request->file('file');
$clientCode = request('client_code');
$engagementCode = request('engagement_code');
$todayDate = date('dFY');
$file_name = $engagementCode.'_'.$todayDate.$file->getClientOriginalName();
$file->move('tempdat',$file_name);
Excel::import(new DataImport, public_path('/tempdat/'.$file_name));
return redirect()->route('dashboard.tempdat.index');
}
What i'd like to do is to add "employee code" which is combination of "client_code" + 1 for every row. for example if client_code is ABCD and there is 3 rows of data imported then the employee_code will be :
ABCD0001
ABCD0002
ABCD0003
...
i'm already searching for count rows but nothing found yet.
Counting rows will bring you problems whenever you remove a single record from the table: You won't be able to insert new rows if your primary employee_id field has UNIQUE key, or you will start inserting duplicated IDs.
Generating the ID in PHP isn't my recomendation either since you could face integrity problems if two records are trying to be stored simultaneously.
I would use the default model's model_id field with autoincrement to make sure that I won't have problems with id assignation, and inmediatly after saving the record I would update the id for the employee_id field which can be also keyed as "primary" in order to be indexed and accessed efficiently.
For example:
class MyModel extends Model {
public function save() {
if(parent::save()) {
$this->update['employee_id' => "ABCD".$this->id];
}
}
}
I haven't still realized how the Excel library you're using handles the model, but I supposed it can be specified somewhere along the process.
I am able to generate incremental id in laravel excel using this:
https://github.com/haruncpi/laravel-id-generator
$config = [
'table' => 'table_name',
'length' => 7,
'field' => 'employee_id',
'prefix' => request('client_code'),
'reset_on_prefix_change' => true,
];
$employee_id = IdGenerator::generate($config);
so, everytime import executed, employee_id will generated on its own following with client_code prefix (ex: ABCD001, ... )

Storing/updating multiple rows in from same method in Laravel

I have a table like this
month | rate | admin_id
0 | 1000 | 1
I am storing data with following method:
public function store(Request $request)
{
foreach ($request->admin_id as $key => $val){
$adminbillings = AdminBilling::create([
'month' => 0,
'rate' => $request->rate[$key],
'admin_id' => $val,
]);
}
return redirect('/');
}
When I add a new row in the table using this method, I also want to replace the month of previous row (which is 0) with the timestamp of the new line. So the table will become
month | rate | admin_id
29-08-2017 | 1000 | 1
0 | 2000 | 1
I can add multiple lines from single method, but here one is store and one is update, and by default update requires two arguments. But may be I am mistaken somewhere. Can you please guide me how to achieve my target?
I can access the previous row inside the method using this line:
$ended_at = AdminBilling::where('admin_id', $val)->where('month', 0)->get();
This is not best solution but you will achieve your target.
To update previous record after insertion , you can do like this -
$res = AdminBilling::select('id')->orderBy('id','desc')->skip(1)->take(1)->first(); //to get prev. row
AdminBilling::where('id',$res->id)->update(['month',date()]); // to update month
put these lines in your store function as -
public function store(Request $request)
{
foreach ($request->admin_id as $key => $val){
$adminbillings = AdminBilling::create([
'month' => 0,
'rate' => $request->rate[$key],
'admin_id' => $val,
]);
$res = AdminBilling::select('id')->orderBy('id','desc')->skip(1)->take(1)->first();
AdminBilling::where('id',$res->id)->update(['month',date()]);
}
return redirect('/');
}
Hope this will helpful for you.
When you use create method it returns the instance of your inserted row. So you can use $adminbillings->id if you need the access to previously insterted row.

Laravel validation: exists two column same row

Is there a way of referencing another field when specifying the exists validation rule in Laravel?
My request :
public function rules()
{
return [
'numero_de_somme' => 'unique:personnels,numero_de_somme|exists:fonctionnaire,num_somme',
'cin' => 'unique:personnels,cin|exists:fonctionnaire,cin',
];
}
in my validation rules I want to be able to make sure that:
num_somme exists within the fonctionnaire table
cin exists within the fonctionnaire table and cin input must be
on the same row of the num_somme
num_somme : 12345 cin : s89745
num_somme : 78945 cin : U10125
Explaining : for example
1st scenario if the input num_somme = 12345 and cin = U10125 the validation must fail
2nd scenario if the input num_somme = 12345 and cin = s89745 the validation must success
I hope this makes sense.
Thank you
You can simply use this:
'request_input' => exists:table,col,alternative_col_1,alternative_val_1,alternative_col_2,alternative_val_2, ...'
The SQL query is like below:
select count(*) as aggregate from `table` where `id` = [request_input] and `alternative_col1` = "alternative_val1" and `alternative_col2` = "alternative_val2"
I came across the same need today and I think I have a solution using the validation Rule class: Rule example.
Here is my scenario: I have an email verifications table and I want to ensure that a passed machine code and activation code exist on the same row.
Be sure to include use Illuminate\Validation\Rule;
$activationCode = $request->activation_code;
$rules = [
'mc' => [
'required',
Rule::exists('email_verifications', 'machineCode')
->where(function ($query) use ($activationCode) {
$query->where('activationCode', $activationCode);
}),
],
'activation_code' => 'required|integer|min:5',
'operating_system' => 'required|alpha_num|max:45'
];
The first argument in the exists method is the table and the second is the custom column name I'm using for the 'mc' field. I pass the second column I want to check using the 'use' keyword and then use that field in a a where clause.
You can achieve validating multipe columns by using Rule.
Include :
use Illuminate\Validation\Rule;
use Validator;
$AdminId = $request->AdminId;
$Validate = Validator::make($request->all(),[
'TaxId' => [ 'required', Rule::exists('tax','id')
->where(function ($query) use ($AdminId) {
$query->where('u_id', $AdminId);
})],
]);
if($Validate->fails())
{`Your ERROR HERE`}
else
{`SUCCESS`}
Here in my example I'm checking u_id and Id which is in same row and 2 columns.
Explaining : for example
My DB HAS 2 ROWS IN tax TABLE
id = 1 , u_id = 1, tax = "GST" , value -> 8
id = 2 , u_id = 2, tax = "GST" , value -> 5
1st scenario if the input id = 2 and u_id = 1 the validation must fail because this row belongs to u_id = 2.
2nd scenario if the input id = 2 and u_id = 2 the validation must success
i managed to solve it using the most simple method
for numero_de_somme
'numero_de_somme' => 'unique:personnels,numero_de_somme|exists:fonctionnaire,num_somme,cin,'.Request::get('cin'),
for cin
'cin' => 'unique:personnels,cin|exists:fonctionnaire,cin',
PS . don't forget to call use Illuminate\Http\Request;
if (is_numeric($request->get('emailOrphone'))){
$request->validate([
'emailOrphone'=>'exists:users,phone',
],
[
'emailOrphone.exists'=>'phone is invalid.'
]);
}else{
$request->validate([
'emailOrphone'=>'exists:users,email',
],
[
'emailOrphone.exists'=>'email is invalid.''
]);
}

Laravel 5 - update overwriting all data

I have a Document Model which represents a Document (name, description etc). I then have a DocumentData Model which represents the data of a Document. A Document has One to Many DocumentData,
So to create a Document I have a form. Lets say that my form has a text input for Document Owner. Within my DocumentData table, the label documentOwner is set as the key and the inputted data is set as the value. So with multiple form elements, my DocumentData table might look like this
document_data
id | documentId | key | value |
----------------------------------------------
1 | 1 | clientName | Google |
----------------------------------------------
2 | 1 | projectName | Analytics |
----------------------------------------------
3 | 1 | Contact | Mr Sharp |
----------------------------------------------
4 | 1 | startDate | 29/12/2016 |
----------------------------------------------
The Document name and description for the Document table is created using hidden fields within the view of the Document.
So I can create Documents without a problem. I am having a problem with my update function though. So far I have the following
public function update(Request $request, Project $project, $id)
{
$document = $project->document()->where('id', '=', $id)->first();
$docData = $document->documentData()->get();
$input = $request->all();
foreach($docData as $orgData) {
foreach($input as $key => $value) {
if($key !== "filePath" && $key !== "documentType" && $key !== "documentTypeDesc") {
if($key == $orgData->key) {
$orgData->value = $value;
$orgData->update();
}
}
}
}
return View::make($document->name.'Doc.edit', compact('project', 'document'));
}
So firstly I get the Document I am working on and store it in $document. I then get the DocumentData for this Document and store it in $docData. $docData is a collection containing my key-value pairings for a Document.
I then loop both the $docData and the inputted data and where the keys match, I reset its updated value.
However, at the moment, it updates everything to the last inputted data field. I am not sure where else I can perform the update operation, but I only need it to update the row it is referring too, not the whole thing.
How could I go about doing this?
Thanks
I've cleaned up the code a little, and made a few implementation changes. This code should work, so let us know if it doesn't, and if not, what failed.
public function update(Request $request, Project $project, $id)
{
// you can use eager loading and find on the relationship query
$document = $project->document()->with('documentData')->find($id);
// you can just access the relationship attribute, no need for the query
$docData = $document->documentData;
// gets all input, except the keys specified
$input = $request->except(['filePath', 'documentType', 'documentTypeDesc']);
foreach($docData as $orgData) {
// check if the input has a key that matches the docdata key
if (array_key_exists($orgData->key, $input)) {
// update the value
$orgData->value = $input[$orgData->key];
// use save, not update
$orgData->save();
}
}
return View::make($document->name.'Doc.edit', compact('project', 'document'));
}

Issue in updating contract record in Codeigniter

I am trying to update each contract I have for a particular job entry. My condition is for every job I post, more than one applicant can be hired. Right now, this is what my code shows.
Job ID | Job Title | Provider | Contract Status | Provider's Feedback | Note to Self
1 | First job.| Provider1| DONE | |I like his work.
1 | First job.| Provider2| DONE | |I like his work.
This is supposedly correct but just until PROVIDER column. Whenever I click job title entry (I have it linked to another page where I can update the contract), I should be able to write something about the worker - if the job was done, how his performance was (which should be view-able on his equivalent page), and my note to self about him. Problem is, whenever I click one of the contracts and make an update, all the contracts will be affected. How will I make it unique?
Here's my code so far:
public function update_job_contract($post_obj)
{
$id = $post_obj['id'];
$data = array
(
'client_feedback' => $post_obj['client_feedback'],
'client_notetoself' => $post_obj['client_notetoself'],
'contract_status' => $post_obj['contract_status'],
'client_id' => $this->auth_model->get_user_id()
);
$this->db->where('id', $id);
$this->db->update('job', $data);
}
in my controller:
public function update_job_contract()
{
$this->validateRole('client');
$this->load->model('job_model');
$id = $this->uri->segment(3,0);
$data['job'] = $this->job_model->get_job($id);
$this->load->view('client/update_job_contract', $data);
}
public function update_job_contract_submit()
{
$this->validateRole('client');
$this->load->model('job_model');
//if ( '0' == $_POST['id'] ) {
$this->job_model->update_job_contract($_POST);
//}
redirect('client/manage_job_contracts?message=Congratulations!');
}
I am looking forward to getting help! Thanks!

Categories