ycs77 / laravel-wizard

A web Setup Wizard for Laravel application.
MIT License
122 stars 18 forks source link

Eloquently Save Multiple, Related Models #45

Closed mcatieno closed 1 year ago

mcatieno commented 1 year ago

Setting relationship this way is not very clear: public function model(Request $request) { return $request->user()->posts(); }

i have this scenario and i would want to save the data in the third step. Basically for me i have 3 steps Claim option, personal details and payment steps.

$claim = new Claim(); $claim->id = $request->claim_id; $claim->name = $request->name; $claim->sponsor_letter = $letter; $claim->exitdate = $request->exitdate;

$nextkin = new NextKin(); $nextkin->kin = $request->kin; $nextkin->kin_id = $request->kin_id; $nextkin->kin_email = $request->kin_email;

$payment = new Payment(); $payment->bank = $request->bank; $payment->branch = $request->branch; $payment->accountname = $request->accountname;

$claim->save(); $claim->nextkin()->save($nextkin); $claim->payment()->save($payment);

So i have three steps in which i collect data for the 3 models Claim, NextKin and Payment. The claim_id references the other two tables. How do we save this data. How do to go to the previous step without saving. I believe the last step is to display result.

ycs77 commented 1 year ago

Hi @mcatieno, you can reference Save data on another step part to save your all models data.

This provide a example for last step to saving:

<?php

class LastStep extends Step
{
    public function model(Request $request)
    {
        //
    }

    public function saveData(Request $request, $data = null, $model = null)
    {
        $data = $this->getStepsData();
        dd($data); // check current your all form data
        // save data into models
    }
}
mcatieno commented 1 year ago

Thanks Lucas. What is the best way to get previous form data and save in the last step. Am trying to use Session, with no success. step repository is not seems not to work on my end.

On Tue, Oct 3, 2023 at 10:00 PM Lucas Yang @.***> wrote:

Hi @mcatieno https://github.com/mcatieno, you can reference Save data on another step https://github.com/ycs77/laravel-wizard#save-data-on-another-step part to save your all models data.

This provide a example for last step to saving:

<?php class LastStep extends Step { public function model(Request $request) { // }

public function saveData(Request $request, $data = null, $model = null)
{
    $data = $this->getStepsData();
    dd($data); // check current your all form data
    // save data
}

}

— Reply to this email directly, view it on GitHub https://github.com/ycs77/laravel-wizard/issues/45#issuecomment-1745551087, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALYODAXSH4OO74Y6SI2GI6LX5RODTAVCNFSM6AAAAAA5QTYLOWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONBVGU2TCMBYG4 . You are receiving this because you were mentioned.Message ID: @.***>

--

Isaiah 40:31

"But they that wait upon the LORD shall renew their strength; they shall mount up with wings as EAGLES they shall run, and not be weary; and they shall walk, and not faint"

ycs77 commented 1 year ago

This is an example with your provide code:

<?php

class ClaimStep extends Step
{
    public function model(Request $request)
    {
        // don't write any code
    }

    public function saveData(Request $request, $data = null, $model = null)
    {
        // don't write any code
    }
}
<?php

class NextKinStep extends Step
{
    public function model(Request $request)
    {
        // don't write any code
    }

    public function saveData(Request $request, $data = null, $model = null)
    {
        // don't write any code
    }
}
<?php

class PaymentStep extends Step
{
    public function model(Request $request)
    {
        // don't write any code
    }

    public function saveData(Request $request, $data = null, $model = null)
    {
        $data = $this->getStepsData();

        $claim = new Claim();
        $claim->id = $data['claim_id'];
        $claim->name = $data['name'];
        $claim->sponsor_letter = $letter;
        $claim->exitdate = $data['exitdate'];

        $nextkin = new NextKin();
        $nextkin->kin = $data['kin'];
        $nextkin->kin_id = $data['kin_id'];
        $nextkin->kin_email = $data['kin_email'];

        $payment = new Payment();
        $payment->bank = $data['bank'];
        $payment->branch = $data['branch'];
        $payment->accountname = $data['accountname'];

        $claim->save();
        $claim->nextkin()->save($nextkin);
        $claim->payment()->save($payment);
    }
}
ycs77 commented 1 year ago

is not seems not to work on my end.

Please provide more information.

mcatieno commented 1 year ago

Hello Lucas,

Thank you. This is works so well. Allow me to bother you one more time with file uploads. Normally this will do: if ($request->hasFile('sponsor_letter')) { $file = $request->file('sponsorletter'); $letter = time() . '' . $file->getClientOriginalName(); $file->storeAs('documents', $letter, 'public'); $claim->sponsor_letter = $letter; }

i tried this but it wasnt working.

$data['sponsor_letter'] = $data['sponsor_letter']->store('sponsor_letter', ['disk' => 'public']); It appends some characters after the file name.

Please guide.

On Fri, Oct 6, 2023 at 5:03 PM Lucas Yang @.***> wrote:

<?php class ClaimStep extends Step { public function model(Request $request) { // don't write any code }

public function saveData(Request $request, $data = null, $model = null)
{
    // don't write any code
}

} class NextKinStep extends Step { public function model(Request $request) { // don't write any code }

public function saveData(Request $request, $data = null, $model = null)
{
    // don't write any code
}

} class PaymentStep extends Step { public function model(Request $request) { // don't write any code }

public function saveData(Request $request, $data = null, $model = null)
{
    $data = $this->getStepsData();

    $claim = new Claim();
    $claim->id = $data['claim_id'];
    $claim->name = $data['name'];
    $claim->sponsor_letter = $letter;
    $claim->exitdate = $data['exitdate'];

    $nextkin = new NextKin();
    $nextkin->kin = $data['kin'];
    $nextkin->kin_id = $data['kin_id'];
    $nextkin->kin_email = $data['kin_email'];

    $payment = new Payment();
    $payment->bank = $data['bank'];
    $payment->branch = $data['branch'];
    $payment->accountname = $data['accountname'];

    $claim->save();
    $claim->nextkin()->save($nextkin);
    $claim->payment()->save($payment);
}

}

— Reply to this email directly, view it on GitHub https://github.com/ycs77/laravel-wizard/issues/45#issuecomment-1750736097, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALYODARYGOH63TJZ5KQMQRTX6AFU3AVCNFSM6AAAAAA5QTYLOWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONJQG4ZTMMBZG4 . You are receiving this because you were mentioned.Message ID: @.***>

--

Isaiah 40:31

"But they that wait upon the LORD shall renew their strength; they shall mount up with wings as EAGLES they shall run, and not be weary; and they shall walk, and not faint"

ycs77 commented 1 year ago

If you want to save uploaded file you could try this:

<?php

class PaymentStep extends Step
{
    public function saveData(Request $request, $data = null, $model = null)
    {
        $data = $this->getStepsData();

        $claim = new Claim();

        $sponsor_letter_filename = time().'_'.$data['sponsor_letter']->getClientOriginalName();

        $claim->sponsor_letter = $data['sponsor_letter']->storeAs('documents', $sponsor_letter_filename, [
            'disk' => 'public',
        ]);
        ...
    }
}

Because the file is not uploaded on this request (this example is upload to ClaimStep), you can't use $request->file('...') to get the file, instead of $data['sponsor_letter'].

The $this->getStepsData() will get the cached user input/uploaded data and clean when the wizard ended.

mcatieno commented 1 year ago

Hello,

Thanks. I have been trying the file upload with some errors. so the blade file looks like this:

then i tried this: $data = $this->getStepsData(); dd($data);

The filename is not being captured correctly: [image: image.png]

Is there something am missing in the configurations. Please let me know.

On Fri, Oct 13, 2023 at 8:32 PM Lucas Yang @.***> wrote:

If you want to save uploaded file you could try this:

<?php class PaymentStep extends Step { public function saveData(Request $request, $data = null, $model = null) { $data = $this->getStepsData();

    $claim = new Claim();

    $sponsor_letter_filename = time().'_'.$data['sponsor_letter']->getClientOriginalName();

    $claim->sponsor_letter = $data['sponsor_letter']->storeAs('documents', $sponsor_letter_filename, [
        'disk' => 'public',
    ]);
    ...
}

}

Because the file is not uploaded on this request (this example is on ClaimStep), you can't use $request->file('...') to get the file, instead of $data['sponsor_letter'].

The $this->getStepsData() will get the cached user input/uploaded data and clean when the wizard ended.

— Reply to this email directly, view it on GitHub https://github.com/ycs77/laravel-wizard/issues/45#issuecomment-1761901254, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALYODAWH6YLIYUDIPNN7MWDX7F3KFANCNFSM6AAAAAA5QTYLOU . You are receiving this because you were mentioned.Message ID: @.***>

--

Isaiah 40:31

"But they that wait upon the LORD shall renew their strength; they shall mount up with wings as EAGLES they shall run, and not be weary; and they shall walk, and not faint"

ycs77 commented 1 year ago

Please for me the screenshot of the error.

mcatieno commented 1 year ago

hello. So this is the error: [image: image.png]

and the full code: public function saveData(Request $request, $data = null, $model = null) {

$data = $this->getStepsData();

$mybank =$data['bank']; $accname =$data['accountname']; $branch =$data['branch']; $accnumber =$data['account']; $kin =$data['kin']; $address =$data['address']; $mobile =$data['mobileno']; $description =$data['description'];

$kin_mobile = $data['kin_mobile']; $relationship = $data['relationship']; $kin_id = $data['kin_id']; $kin_email = $data['kin_email'];

$sponsor_letterfilename = time().''.$data['sponsor_letter']->getClientOriginalName();

$data = [ 'idno' => $this->find('person')->data('idno'), ];

$data['idno'] = $data['idno']->store('idno', ['disk' => 'public']);

$data = [ 'pin' => $this->find('person')->data('pin'), ];

$data['pin'] = $data['pin']->store('pin', ['disk' => 'public']);

$staffno = Auth::user()->member_no; $code = Auth::user()->schemecode; $schemeid =Scheme::where('schemecode',$code)->pluck('id')->first();

$claim = new Claim(); $myid = $request->claim_id; $claim->id = $myid; $claim->name = Auth::user()->name; $claim->memberno =$staffno; $claim->sponsor_letter = $data['sponsor_letter']->storeAs('documents', $sponsor_letter_filename, [ 'disk' => 'public', ]);

$claim->pin = $data['pin']; $claim->dob = '2000-12-01 23:00:00'; $claim->schemedate = '2000-12-01 23:00:00'; $claim->exitdate = '2000-12-01 23:00:00'; $claim->address = $address; $claim->mobileno = $mobile; $claim->email = Auth::user()->email; //$claim->status = $status; $claim->schemecode = $code; $claim->scheme_id=$schemeid; $claim->retirement_type = 'retirement'; $claim->idno = 'idno';

$claim->save(); // dd($claim->id);

// Create a new Payment instance and set its attributes $payment = new Payment(); $payment->claim_id = $myid; // Make sure $claim->id has a valid value $payment->bank = $mybank; $payment->branch = $branch; $payment->accountname = $accname; $payment->memberno = $staffno; $payment->account = $accnumber; $payment->withdrawal_option = $claim->retirement_type;

// Create a new NextKin instance and set its attributes $nextkin = new NextKin(); $nextkin->claim_id = $myid; // Make sure $claim->id has a valid value $nextkin->kin = $kin; $nextkin->kin_mobile = $kin_mobile; $nextkin->relationship = $relationship; $nextkin->kin_id =$kin_id; $nextkin->kin_email =$kin_email;

$comments = new Comment(); $comments->comment_text = $description; $comments->claim_id = $myid; // Make sure $claim->id has a valid value $comments->user_id = Auth::user()->id;

try { $claim->nextkin()->save($nextkin); $claim->payment()->save($payment); $claim->comments()->save($comments);

} catch (\Exception $e) { // Log the exception for debugging \Log::error('Error saving Payment or NextKin: ' . $e->getMessage()); return redirect()->back()->with('error', 'An error occurred while saving Payment or NextKin.'); } }

On Tue, Oct 17, 2023 at 9:10 PM Lucas Yang @.***> wrote:

Please for me the screenshot of the error.

— Reply to this email directly, view it on GitHub https://github.com/ycs77/laravel-wizard/issues/45#issuecomment-1766918245, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALYODAQKXVL5DS34FNDYDTTX73CX5AVCNFSM6AAAAAA5QTYLOWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRWHEYTQMRUGU . You are receiving this because you were mentioned.Message ID: @.***>

--

Isaiah 40:31

"But they that wait upon the LORD shall renew their strength; they shall mount up with wings as EAGLES they shall run, and not be weary; and they shall walk, and not faint"

mcatieno commented 1 year ago

Hello Lucas,

Also when I test to get the file name as below, what i get is not he same name as the file I am trying to upload.

public function saveData(Request $request, $data = null, $model = null) {

$data = $this->getStepsData();

$sponsor_letterfilename = time().''.$data['sponsor_letter']->getClientOriginalName();

dd($sponsor_letter_filename); } returns the below screenshot which is not the name of the form: [image: image.png]

On Tue, Oct 17, 2023 at 9:10 PM Lucas Yang @.***> wrote:

Please for me the screenshot of the error.

— Reply to this email directly, view it on GitHub https://github.com/ycs77/laravel-wizard/issues/45#issuecomment-1766918245, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALYODAQKXVL5DS34FNDYDTTX73CX5AVCNFSM6AAAAAA5QTYLOWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRWHEYTQMRUGU . You are receiving this because you were mentioned.Message ID: @.***>

--

Isaiah 40:31

"But they that wait upon the LORD shall renew their strength; they shall mount up with wings as EAGLES they shall run, and not be weary; and they shall walk, and not faint"

ycs77 commented 1 year ago

If you want to save the original name of the uploaded image filename, you can change it to this:

First, into your WizardController add a wizardStepSaved(), it will be triggered on step saved or cached, at this time you can save the original filename of the uploaded image into the session:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Ycs77\LaravelWizard\Step;
use Ycs77\LaravelWizard\Wizardable;

class UserWizardController extends Controller
{
    use Wizardable;

    ...

    protected function wizardStepSaved(Request $request, Step $step)
    {
        if ($step instanceof ClaimStep && $request->hasFile('sponsor_letter')) {
            $originalFilename = $request->file('sponsor_letter')->getClientOriginalName();
            Session::put('sponsor_letter_original_filename', $originalFilename);
        }
    }
}

Then pull the filename into the session on the last step:

<?php

use Illuminate\Support\Facades\Session;

class PaymentStep extends Step
{
    public function saveData(Request $request, $data = null, $model = null)
    {
        $data = $this->getStepsData();

        $originalFilename = Session::pull('sponsor_letter_original_filename');
        $data['sponsor_letter'] = $data['sponsor_letter']->storeAs('documents', time().'_'.$originalFilename, [
            'disk' => 'public',
        ]);

        dd($data);
    }
}
mcatieno commented 1 year ago

Thanks alot Lucas. This has worked. Really appreciated.👏 👏

On Wed, Oct 18, 2023 at 4:42 PM Lucas Yang @.***> wrote:

If you want to save the original name of the uploaded image filename, you can change it to this:

First, into your WizardController add a wizardStepSaved(), it will be triggered on step saved or cached, at this time you can save the original filename of the uploaded image into the session:

<?php use Illuminate\Http\Request;use Illuminate\Support\Facades\Session;use Ycs77\LaravelWizard\Step;use Ycs77\LaravelWizard\Wizardable; class UserWizardController extends Controller { use Wizardable;

...

protected function wizardStepSaved(Request $request, Step $step)
{
    if ($step instanceof ClaimStep && $request->hasFile('sponsor_letter')) {
        $originalFilename = $request->file('sponsor_letter')->getClientOriginalName();
        Session::put('sponsor_letter_original_filename', $originalFilename);
    }
}

}

Then pull the filename into the session on the last step:

<?php use Illuminate\Support\Facades\Session; class PaymentStep extends Step { public function saveData(Request $request, $data = null, $model = null) { $data = $this->getStepsData();

    $originalFilename = Session::pull('sponsor_letter_original_filename');
    $data['sponsor_letter'] = $data['sponsor_letter']->storeAs('documents', time().'_'.$originalFilename, [
        'disk' => 'public',
    ]);

    dd($data);
}

}

— Reply to this email directly, view it on GitHub https://github.com/ycs77/laravel-wizard/issues/45#issuecomment-1768488677, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALYODAQ4S3EAJPKL2OU36ZLX77MERAVCNFSM6AAAAAA5QTYLOWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRYGQ4DQNRXG4 . You are receiving this because you were mentioned.Message ID: @.***>

--

Isaiah 40:31

"But they that wait upon the LORD shall renew their strength; they shall mount up with wings as EAGLES they shall run, and not be weary; and they shall walk, and not faint"