Reputation: 971
Edit: (08/09/2019)
I have a question concerning the payment verification.
For example, the student Leonard
pays a training on 09/09/2019
only.
In my form Training
, I see that I can add several seances (trainings) ????
Can I block this?
For information, in my table Training
, I have 5 foreign keys (fk_former, fk_student, fk_motorbike, fk_typetraining, fk_payment)
.
To join the table training and payment I do this:
Model Training
class Training extends Model
{
//
protected $fillable = ['date_seance', 'hour_start', 'hour_end', 'fk_motorbike', 'fk_former', 'fk_student'];
protected $dates = ['date_seance'];
public function motorbikes(){
return $this->belongsTo('App\Motorbike', 'fk_motorbike');
}
public function formers(){
return $this->belongsTo('App\Former', 'fk_former');
}
public function students(){
return $this->belongsTo('App\Student', 'fk_student');
}
public function payments(){
return $this->hasMany('App\Payment', 'fk_training');
}
}
Model Payment
class Payment extends Model
{
protected $fillable = ['date_payment', 'fk_student', 'method_payment', 'fk_type_seance', 'number_seance', 'total', 'fk_training'];
protected $dates = ['date_payment'];
public function students(){
return $this->belongsTo('App\Student', 'fk_student');
}
public function trainings(){
return $this->belongsTo('App\Training', 'fk_training', 'id');
}
My relationships are ok
I have to do how to limit the trainings? Because it's for now illimited... the number of seances is not taken into account with the payment.
Here is my function store() on my Controller Training Edit
public function store(Request $request)
{
$request->validate([
'date_seance' => 'required',
'hour_start' => 'required',
'hour_end' => 'required',
'fk_motorbike' => 'required',
'fk_former' => 'required',
'fk_student' => 'required'
]);
$date_start = $request->get('date_seance');
$hour_start = $request->get('hour_start');
$hour_end = $request->get('hour_end');
$fk_motorbike = $request->get('fk_motorbike');
$fk_former = $request->get('fk_former');
$fk_student = $request->get('fk_student');
$PaymentHasBeenMadeForThisTraining = Payment::where('fk_student', $fk_student)
->where('fk_training', $request->get('fk_training'))
->first();
$trainings = Training::with('payments')->get();
$johnsTrainings = Training::with(['payments' => function($query) use($fk_student){
$query->where('fk_student', $fk_student);
}])->get();
/*
if(isset($trainings)){
return redirect()->route('trainings.index')
->with('error', 'Duplicate ! ');
}*/
if(isset($johnsTrainings)){
return redirect()->route('trainings.index')
->with('error', 'Limit ! ');
}
else{
Training::create($request->all());
return redirect()->route('trainings.index')
->with('success', 'Add');
}
}
In testing your code I get this:
Upvotes: 0
Views: 83
Reputation: 8178
I think there are several things which need attention. You state:
In my form Training, I see that I can add several seances ????
So I assume you want to link the ability to add trainings based on if a person pays for THAT training. And on your form, you see that someone can add more trainings, even though they haven't paid for them. And this is the problem.
I suggest you may wish to change your architecture on this and simplify your relationships. If you create a payment as a one-to-many relationship between Payment model and Training model, you don't have to worry about checking to see if the payment can apply to many dates.
So on your Training model the relationship is many:
public function payments(){
return $this->hasMany("App\Payment", 'your_foreign_key', 'your_local_key');
}
And on your Payment model it has one Training only:
public function training(){
return $this->belongsTo("App\Training");
}
You'll have to tweak this code and maybe a tiny bit of the database (probably don't need fk_type_seance
, but do need some kind of fk_training
). But now it is very easy to check if you have a conflict for the payment of the training for this person by checking the payment against the specific Training.
$PaymentHasBeenMadeForThisTraining = Payment::where('fk_student', $fk_student)
->where('fk_training', $request->get('fk_training'))
->first();
The if-check is now looking to see if the payment fits the training and the student - if so, it will stop a double payment for the same training by the same person.
For your list of trainings you'll need to come at this from the reverse. Pull the trainings with payments:
$trainings = Training::with('payments')->get();
Then, in your list, if you are listing a specific person you will need to check if the payment has been made by that person in order to list that person's payment for this specific training. You'll have to work on this, but something like this in your controller:
$thisStudentsTrainings = Training::with(['payments' => function($query) use($fk_student){
$query->where('fk_student', $fk_student);
}])->get();
EDIT: From here, check to see if the training from the form is in that collection of paid for trainings from this student (from the form):
$hasPaidForThisTraining = $thisStudentsTrainings ->contains('id', $request->get('fk_training'));
You may also have success by just pulling John's payments and then linking to the Training models within each - you can loop on those as well. MIght be easier. There are several ways to do this, but this is getting a long way from you question - look for simplifying your architecture to make this work :)
Upvotes: 1