jgravois

jgravois

Technical Manager at Universal Asset Management

Member Since 5 Years Ago

Memphis

Experience Points
134,685
Total
Experience

315 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
1363
Lessons
Completed
Best Reply Awards
2
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

Level 27
134,685 XP
May
27
4 days ago
Activity icon

Replied to Can't Livewire Child Components Have Their Own Methods?

@snapey Mark, I sent you an email ... I HOPE you don't mind

Activity icon

Replied to Can't Livewire Child Components Have Their Own Methods?

<span tooltip="ITAR">
                @if($deniedPartyChecked)
                    @if($deniedPartyCleared)
                        @svg('solid/exclamation-triangle', 'mr-2 text-nephritis-500')
                    @else
                        @svg('solid/exclamation-triangle', 'mr-2 text-orange-500')
                    @endif
                @else
                    <span class="cursor-pointer" wire:click="checkDenied({{$cmpID}})">
                        @svg('solid/exclamation-triangle', 'mr-2 text-silver-500')
                    </span>
                @endif
            </span>
Activity icon

Started a new Conversation Can't Livewire Child Components Have Their Own Methods?

if I have a @forelse of

@forelse($agreements as $ag)
    @livewire('customers.caf-row', ['id' => $ag->id], key($ag->id))
@empty ...

and if am triggering a method on the CafRow component, WHY am I getting

Livewire\Exceptions\MethodNotFoundException
Unable to call component method. Public method [checkDenied] not found on component: [customers.customer-portal]

I want to call the method on the child so it is self-contained and then $emit only if necessary.

so WHY is it looking at the parent for the public function?

May
26
5 days ago
Activity icon

Replied to I Am Coded Into A Corner And Need Help

@snapey even though I thought I had the winner, 2 hours later I am still fighting this and hope you would help me win this battle.

The filter bar works great with your suggested reply but the tabs are not used.

According to my research since the tabs actually filter the results by the relationship, I need to be put something like this

$authors = Author::with(['books' => function($query) {
  $query->whereYear('created_at', date('Y'));
}])->get();

into our

$query = Company::has('caf')
            ->with( 'caf:id,company_id,status_id,reporter,reporter_email', 'contacts:id,company_id,accounting_name,accounting_email' )
            ->select('id', 'company_code', 'legal_name', 'city', 'state', 'phone', 'country', 'denied_party_checked', 'denied_party_cleared', 'last_denied_party_check');

        if($this->search) {
            $term = "%{$this->search}%";

            $query->where('legal_name','like', $term)
                ->orwhere('company_code','like', $term);
        } else {
            //TODO DO THE TABS HERE
        } // end if

        $this->agreements = $query->get();

I have tried many permutations but they haven't been pretty

Activity icon

Replied to I Am Coded Into A Corner And Need Help

@snapey THANKS AGAIN!!!

This sucker loads like lightning!

Activity icon

Replied to I Am Coded Into A Corner And Need Help

@snapey I think I solved it by flip-flopping it

$cmps = Company::has('caf')
  ->with( 'caf:id,company_id,status_id,reporter,reporter_email', 'contacts:id,company_id,accounting_name,accounting_email' )
  ->select('id', 'company_code', 'legal_name', 'city', 'state', 'country', 'denied_party_checked', 'denied_party_cleared', 'last_denied_party_check')->get();

now I should be able to search for LIKE %legal_name% OR LIKE%company_code%

thanks again for your help and patience ... I have always just reverted to RAW SQL whenever the Eloquent got complicated but this has been a learning experience.

Activity icon

Replied to I Am Coded Into A Corner And Need Help

Further research got me this far using Tinkerwell.

$agreements = DB::select( DB::raw("SELECT caf.id, cmp.company_code, cmp.legal_name, cmp.city, cmp.state, cmp.country, cmp.denied_party_checked, cmp.denied_party_cleared, cmp.last_denied_party_check, cmp.phone, caf.status_id, caf.reporter, caf.reporter_email, con.accounting_name, con.accounting_email FROM company_customer_agreements caf LEFT JOIN companies cmp ON caf.company_id = cmp.id LEFT JOIN company_contacts con ON cmp.id = con.company_id WHERE cmp.company_code IS NOT NULL ORDER BY cmp.legal_name"));

$cafs = CompanyCustomerAgreement::select('id', 'status_id', 'reporter', 'reporter_email')->get();

however if I try to add the company relationship

$cafs = CompanyCustomerAgreement::with('company')->select('id', 'status_id', 'reporter', 'reporter_email')->get();

I get

Illuminate\Database\Eloquent\Collection {#1696
     all: [
       App\Models\CompanyCustomerAgreement {#1705
         id: 1,
         status_id: 3,
         reporter: "Jon Gravois",
         reporter_email: "[email protected]",
         company: App\Models\Company {#1708},
       },

and with

$cafs = CompanyCustomerAgreement::with('company:id, legal_name')->select('id', 'status_id', 'reporter', 'reporter_email')->get();

I get

Aliasing 'CompanyCustomerAgreement' to 'App\Models\CompanyCustomerAgreement' for this Tinker session.
Illuminate/Database/QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column ' legal_name' in 'field list' (SQL: select `id`, ` legal_name` from `companies` where 0 = 1)'
Activity icon

Replied to I Am Coded Into A Corner And Need Help

The companies table has 92 columns, the company_customer_agreements table has 72 columns, the company_contacts table has 47 columns.

With over 1100 companies in the database, that dataset takes several seconds to load but I only use 15 datapoints.

Activity icon

Replied to I Am Coded Into A Corner And Need Help

but then if I use regular relationships I am back to dealing with the 210+ datapoints AND I still have no way to "find" a record by legal_name which is in the companies table and not in the company_customer_agreements table.

Isn't that backtracking?

Activity icon

Replied to I Am Coded Into A Corner And Need Help

LOL, I have never used Eloquent for a join before so I think I need to explore that. I agree that once this is an eloquent query then filtering it would be easier.

Thanks again for your insight.

Activity icon

Replied to I Am Coded Into A Corner And Need Help

OK @snapey I am making some progress and thank you for your time!

https://share.getcloudapp.com/JrubryKz

The question is definitely (at least now) how to filter ...

Unfortunately this has become one of those god object things that grew and morphed into a beast. Every customer has to complete this every year and as different admins have assumed control, additional requirements have just stacked on.

a) Done c) Done

d) I originally had a query builder then moved to an API Resource and finally settled on Raw ... The dataset size using the 210+ datapoints and the potential size of the overall number of records was causing the page load to either approach 4 seconds OR in some case, time-out. -- The API RESOURCE doesn't seem to work well with LARAVEL-LIVEWIRE as I was just alternating between has to be an array and public error and you can't use a class as an array.

So as you can see from the screen shot, now I get all of the records but that is just it, I get all of the records regardless if I have any value in $this->search OR have a tab selected. The question now is how to filter this.

public function render()
    {
        $agreements = DB::select( DB::raw("SELECT caf.id, cmp.company_code, cmp.legal_name, cmp.city, cmp.state, cmp.country, cmp.denied_party_checked, cmp.denied_party_cleared, cmp.last_denied_party_check, cmp.phone, caf.status_id, caf.reporter, caf.reporter_email, con.accounting_name, con.accounting_email FROM company_customer_agreements caf LEFT JOIN companies cmp ON caf.company_id = cmp.id LEFT JOIN company_contacts con ON cmp.id = con.company_id WHERE cmp.company_code IS NOT NULL ORDER BY cmp.legal_name"));

        $this->invited = collect($agreements)->filter(function($i) {
            return $i->status_id === 1;
        })->all();
        $this->initiated = collect($agreements)->filter(function($i) {
            return $i->status_id === 2;
        })->all();
        $this->submitted = collect($agreements)->filter(function($i) {
            return $i->status_id === 3;
        })->all();
        $this->verified = collect($agreements)->filter(function($i) {
            return $i->status_id === 4;
        })->all();
        $this->approved = collect($agreements)->filter(function($i) {
            return $i->status_id === 5;
        })->all();
        $this->processed = collect($agreements)->filter(function($i) {
            return $i->status_id === 6;
        })->all();
        $this->completed = collect($agreements)->filter(function($i) {
            return $i->status_id === 7;
        })->all();

        $this->agreements = $agreements;

        return view('livewire.customers.customer-portal');
    }
May
25
6 days ago
Activity icon

Started a new Conversation I Am Coded Into A Corner And Need Help

I have apparently turned 3rd grade math into Calculus and now I can't see the way home and need a bit of help --

This is a screenshot of where I am --

https://share.getcloudapp.com/nOu80oB8

I am trying to avoid 210+ datapoints where I only need 15 in a combination of 3 tables so I have a raw query and I need to be able to filter these into a table in this way:

  1. no matter what tab is selected - if $this-search is not empty, the list is filtered by company_code and/or legal_name.
  2. if $this->search is empty, the array is filtered by status_id based on the selected tab
public function render()
    {
        $agreements = DB::select( DB::raw("SELECT caf.id, cmp.company_code, cmp.legal_name, cmp.city, cmp.state, cmp.country, cmp.denied_party_checked, cmp.denied_party_cleared, cmp.last_denied_party_check, cmp.phone, caf.status_id, caf.reporter, caf.reporter_email, con.accounting_name, con.accounting_email FROM company_customer_agreements caf LEFT JOIN companies cmp ON caf.company_id = cmp.id LEFT JOIN company_contacts con ON cmp.id = con.company_id"));

        $this->invited = collect($agreements)->filter(function($i) {
            return $i->status_id === 1;
        })->all();
        $this->cntInvited = collect($this->invited)->count();
        $this->initiated = collect($agreements)->filter(function($i) {
            return $i->status_id === 2;
        })->all();
        $this->cntInitiated = collect($this->initiated)->count();
        $this->submitted = collect($agreements)->filter(function($i) {
            return $i->status_id === 3;
        })->all();
        $this->cntSubmitted = collect($this->submitted)->count();
        $this->verified = collect($agreements)->filter(function($i) {
            return $i->status_id === 4;
        })->all();
        $this->cntVerified = collect($this->verified)->count();
        $this->approved = collect($agreements)->filter(function($i) {
            return $i->status_id === 5;
        })->all();
        $this->cntApproved = collect($this->approved)->count();
        $this->processed = collect($agreements)->filter(function($i) {
            return $i->status_id === 6;
        })->all();
        $this->cntProcessed = collect($this->processed)->count();
        $this->completed = collect($agreements)->filter(function($i) {
            return $i->status_id === 7;
        })->all();
        $this->cntCompleted = collect($this->completed)->count();

        $this->agreements = $agreements;

        return view('livewire.customers.customer-portal');
    }
Activity icon

Replied to I Seem Unable To Grasp Testing And I Am Frustrated

since I am faking the notification, I hope the fact that the [email protected] is a fake email doesn't prevent the test from failing.

Activity icon

Replied to I Seem Unable To Grasp Testing And I Am Frustrated

I "simplified" the test as you suggested and still get the same results

Activity icon

Started a new Conversation I Seem Unable To Grasp Testing And I Am Frustrated

While I understand the importance and value of TDD, I cannot seem to develop a workflow that is conducive to efficacy because I spend hours googling assertions and still cannot get the damn test to pass. I have tweaked almost every line of these 20 - 50 times. PLEASE HELP!

BTW: The data is updated in the local database and the notification DOES appear in MailTrap so i have the manual confidence the process works.

This is a laravel-livewire component method where I validate the data, update the database, send a notification and toast to the user:

public function inviteCustomer()
    {
        $formData = $this->validate([
            'companyID' => 'sometimes',
            'seeker' => 'required',
            'company_name' => 'required',
            'reporter' => 'required',
            'email' => 'required',
        ]);

        $caf = CompanyCustomerAgreement::updateOrCreate([
            'company_id' => $formData['companyID']
        ], [
            'company_id' => $formData['companyID'],
            'requester_id' => auth()->user()->id,
            'status_id' => $this->statusId,
            'reporter' => $formData['reporter'],
            'reporter_email' => $formData['email']
        ]);

        $caf->notify(new InvitedCustomerAgreement(Company::find($formData['companyID'])));

        $this->dispatchBrowserEvent('toast', [
            'type' => 'success',
            'msg' => 'Invitation sent to customer'
        ]);

        $this->mode = 'success';
    } // end function

Here's the test I am trying to write for the Notification part of the above method:

/** @test */
    public function invitation_can_be_sent_and_resent () {
        $CC = 'SUB007';
        Notification::fake();

        $caf = CompanyCustomerAgreement::create([
            'company_id' => factory(Company::class)->create([
                'company_code' => $CC
            ])->id,
            'company_code' => $CC,
            'reporter_email' => '[email protected]',
            'status_id' => 3
        ]);

        Livewire::actingAs(factory(User::class)->create())
            ->test(CustomerSeeker::class)
            ->set('seeker', $CC)
            ->set('companyID', $caf->company_id)
            ->set('company_name', 'Not Null')
            ->set('email', $caf->reporter_email)
            ->set('reporter', $caf->reporter)
            ->call('inviteCustomer');

        Notification::assertSentTo($caf, InvitedCustomerAgreement::class);
    } // end test

Test Results:

The expected [App\Notifications\InvitedCustomerAgreement] notification was not sent.
Failed asserting that false is true.
 /Users/jongravois/code/teamsite7/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:62
 /Users/jongravois/code/teamsite7/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:261
 /Users/jongravois/code/teamsite7/tests/Specifications/CustomerSeekerTest.php:108

May
21
1 week ago
Activity icon

Awarded Best Reply on Is There A Way To Search On A Field In A HasOne Relationship

Duh!

Actually the ternary needs to check if $term is empty or not not $query.

This works:

public static function search($term)
    {
        return empty($term) ? static::query()
            : static::whereHas('company', function($query) use ($term) {
                $query->where('legal_name', 'like', '%'.$term.'%');
            })
                ->orWhere('company_code', 'like', '%'.$term.'%');
    } // end function

Thanks!!!

Activity icon

Replied to Is There A Way To Search On A Field In A HasOne Relationship

Duh!

Actually the ternary needs to check if $term is empty or not not $query.

This works:

public static function search($term)
    {
        return empty($term) ? static::query()
            : static::whereHas('company', function($query) use ($term) {
                $query->where('legal_name', 'like', '%'.$term.'%');
            })
                ->orWhere('company_code', 'like', '%'.$term.'%');
    } // end function

Thanks!!!

Activity icon

Started a new Conversation Is There A Way To Search On A Field In A HasOne Relationship

is there a way to pull something like this off? I am trying to do a search on a field from a hasOne relationship and company.legal_name doesn't work

return empty($query) ? static::query()
            : static::where('company_code', 'like', '%'.$query.'%')
                ->orWhere('company.legal_name', 'like', '%'.$query.'%');
    } // end function

This doesn't work either

public static function search($term)
    {
        return empty($query) ? static::query()
            : static::whereHas('company', function($query) use ($term) {
                $query->where('legal_name', 'like', '%'.$term.'%');
            })
                ->orWhere('company_code', 'like', '%'.$term.'%');
    } // end function
    	
May
16
2 weeks ago
Activity icon

Started a new Conversation Mock Notification Gives Get_class() Expects Parameter 1 To Be Object, String Given

Notification::assertSentTo($email, InvitedCustomerAgreement::class); and Notification::assertSentTo([$email], InvitedCustomerAgreement::class); returns ErrorException : get_class() expects parameter 1 to be object, string given and FAILS.

Full Test

/** @test */
    public function caf_record_created_if_it_does_not_exists () {
        Notification::fake();
        $CC = 'UAMI2';
        $email = '[email protected]';

        $this->actingAs(factory(User::class)->create());

        Livewire::test(CustomerSeeker::class)
            ->set('seeker', $CC)
            ->set('company_name', 'Test Company')
            ->set('email', $email)
            ->call('inviteCustomer')
            ->assertSee('SUCCESS!');

        $comp = Company::whereCompanyCode($CC)->first();

        $this->assertTrue($comp->exists);
        $this->assertTrue(CompanyCustomerAgreement::whereCompanyId($comp->id)->exists());

        Notification::assertSentTo($email, InvitedCustomerAgreement::class);
    } // end test
May
11
2 weeks ago
Activity icon

Awarded Best Reply on 400 Bad Request On Laravel Forge

it's back. thanks

Activity icon

Replied to 400 Bad Request On Laravel Forge

it's back. thanks

Activity icon

Started a new Conversation 400 Bad Request On Laravel Forge

I am getting a 400 Bad Request on all of my forge URLs and on https://forge.laravel.com/.

I checked and my account is paid and up-to-date.

Activity icon

Replied to Unable To Clone Repo

how do you do that on Forge? It's just a button to click that runs composer?

Activity icon

Started a new Conversation Unable To Clone Repo

I am trying to upgrade our production site to a new version and when I try to clone repo I get this

Cloning into 'www.my-uam.com'...
Loading composer repositories with package information
                                                      Updating dependencies (including require-dev)
PHP Fatal error:  Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223
Apr
28
1 month ago
Activity icon

Started a new Conversation Eager Loading Authenticated User Relationships

Is there any way to make something like this work

return auth()->user()->with('tags');

rather than having to do

return User::with('tags')->whereId(auth()->id())->first()
Apr
27
1 month ago
Activity icon

Started a new Conversation WhereBetween() Woes (i.e., Lost In Space)

I have a consignments table with the key field of current_net and a hasMany() relationship. I have a consignment_bands table that has the consignment_id (foreign key) and a low field and a high field where the consignment's current_net fits in between. The corresponding current_rate in the consignment_bands table is then applicable for that sale.

I think works. The tests are green but there is no confidence.

public function handle()
    {
        $consignments = Consignment::where('fixed', false)->get();

        foreach($consignments as $con) {
            $band = ConsignmentBand::where('consignment_id', $con->id)
                ->where('low', '>=', $con->current_net)
                ->where('high', '<=', $con->current_net)
                ->first();

            if($band) {
                $con->current_rate = $band->percent;
            } else {
                $con->current_rate = 1;
            } // end if

            $con->save();
            $this->line("{$con->consignment_code} updated");
        } // end foreach
Apr
21
1 month ago
Activity icon

Started a new Conversation Test Results In Array (...) Does Not Match Expected Type "string".

I am working on a report that shows a rolling 12-month span.

I started with a test but got hit with Array (...) does not match expected type "string".

/** @test */
    public function can_create_a_12_month_rolling_array () {
        $dt = Carbon::today();
        $reporter[] = [
            'name' => $dt->format('F Y')
        ];

        for($i=1; $i<13; $i++) {
            $reporter[] = [
                'name' => $dt->subMonth()->format('F Y')
            ];
        } // end for

        //dd($reporter);

        $this->assertEquals(Carbon::today()->format('F Y'), collect($reporter)->first->name);

        $this->assertEquals(Carbon::today()->subYear()->format('F Y'), collect($reporter)->last->name);
    } // end test

This is the results of dd($reporter) which is correct.

array:13 [
  0 => array:1 [
    "name" => "April 2020"
  ]
  1 => array:1 [
    "name" => "March 2020"
  ]
  2 => array:1 [
    "name" => "February 2020"
  ]
  3 => array:1 [
    "name" => "January 2020"
  ]
  4 => array:1 [
    "name" => "December 2019"
  ]
  5 => array:1 [
    "name" => "November 2019"
  ]
  6 => array:1 [
    "name" => "October 2019"
  ]
  7 => array:1 [
    "name" => "September 2019"
  ]
  8 => array:1 [
    "name" => "August 2019"
  ]
  9 => array:1 [
    "name" => "July 2019"
  ]
  10 => array:1 [
    "name" => "June 2019"
  ]
  11 => array:1 [
    "name" => "May 2019"
  ]
  12 => array:1 [
    "name" => "April 2019"
  ]
]

Since the dump shows the results are arrays, I tried this

$this->assertEquals(Carbon::today()->format('F Y'), collect($reporter)->first['name']);

$this->assertEquals(Carbon::today()->subYear()->format('F Y'), collect($reporter)->last['name']);

but that gives me Cannot use object of type Illuminate\Support\HigherOrderCollectionProxy as array

Apr
20
1 month ago
Activity icon

Replied to Multiple Conditions On Relationship

thanks ... didn't know you could do the EZ like chain there.

Activity icon

Started a new Conversation Multiple Conditions On Relationship

I need to add a conditional to a model scope ... I have the following but I need to also return records where active_date is less than or equal to today AND where completion_date is null.

public function scopeCurrent($query)
    {
        return $query->whereNotNull('active_date');
    } // end function
Apr
12
1 month ago
Activity icon

Replied to Laravel 7 Component Showing <?php Echo E(session('toastr')['body']); ?>

I removed the comments which I had just added for debugging and the display hasn't changed.

screenshot

Apr
11
1 month ago
Activity icon

Started a new Conversation Laravel 7 Component Showing <?php Echo E(session('toastr')['body']); ?>

I am following the What's New in Laravel 7: Supercharged Blade Components video, I created a Laravel 7 component using php artisan make:component Toastr and created the component (WIP). I am not sure what I am doing wrong.

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Toastr extends Component
{
    public $body;
    public $type;

    public function __construct($type, $body)
    {
        $this->body = $body;
        $this->type = $type;
    }

    public function render()
    {
        return view('components.toastr');
    }
}

The component view looks like this

<div class="absolute right-0 mt-4 mr-4 flex justify-between items-center font-semibold p-4 text-xl text-white bg-blue-500 rounded-lg">
    <span class="mr-4 text-3xl">
        @svg('uam/uam-tail')
    </span>

    {{ $body }}
</div>

In a Laravel-Livewire component, I am calling it

public function clearCache()
    {
        Artisan::call('cache:clear');
        Session::flash('toastr', ['body'=>'Artisan Command completed!','type'=>'info']);
    } // end function

and the Laravel-Livewire component view is

{{--        @if (session()->has('toastr'))--}}
        <x-toastr
            type="{{session('toastr')['type']}}"
            body="{{session('toastr')['body']}}"></x-toastr>
{{--        @endif--}}
Apr
02
1 month ago
Activity icon

Commented on Build The Follow Form

cheater

Apr
01
1 month ago
Activity icon

Commented on Build The Follow Form

Is the issue at the 12:00 mark (the removal of getRouteKeyName()) caused by your using a Laravel 7 feature in a Laravel 6 series???

Mar
26
2 months ago
Activity icon

Commented on Expanding The Timeline

Would it be possible to download the zeplin file for this segment? I am still trying to add Zeplin to our workflow and the designer would like to see an example.

Feb
20
3 months ago
Activity icon

Started a new Conversation Trying To Test If A Relationship Exists

I am trying to test if the relationship on a model exists and is empty but the test fails with

Property [bands] does not exist on this collection instance.
/** @test */
    public function a_consignment_can_be_a_fixed_rate () {
        $this->withoutExceptionHandling();
        $con = Consignment::with('bands')->whereConsignmentCode('FIXED')->get();

        $this->assertTrue($con->bands->isEmpty());
    } // end test

I have tried without the $this->withoutExceptionHandling(); as well.

I have also tried $this->assertNull($con->bands).

Activity icon

Replied to SetUp() Not Compatible

not optional, eh?

Activity icon

Started a new Conversation SetUp() Not Compatible

I am in Laravel 6.14 on PHP 7.2.25

I have a new Unit Test where every test will require an Invoice so I am following one of Jeff's videos and using a setUp() method resulting in

PHP Fatal error:  Declaration of Tests\Unit\InvoiceGpNetMethodTest::setUp() must be compatible with Illuminate\Foundation\Testing\TestCase::setUp(): void in /Users/jongravois/code/teamsite/tests/Unit/InvoiceGpNetMethodTest.php on line 32

This is my test case

<?php

namespace Tests\Unit;

use App\Models\Invoice;
use PHPUnit\Framework\TestCase;
use Tests\UamTestCase;

class InvoiceGpNetMethodTest extends UamTestCase
{
    protected $invoice;

    public function setUp()
    {
        parent::setUp();
        $this->invoice = factory(Invoice::class)->create([
            'gross' => 1000
        ]);
    } // end function

    /** @test */
    public function the_test_suite_works () {
        $this->assertTrue(true);
    } // end test
}

The UamTestCase is just a convenience so I don't forget to refresh the database

<?php

namespace Tests;

use App\User;
use JMac\Testing\Traits\HttpTestAssertions;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class UamTestCase extends TestCase
{
    use WithFaker, HttpTestAssertions, RefreshDatabase;
}
Feb
19
3 months ago
Activity icon

Replied to Find 100 From 100CR, 100CR1, 100CR-1, 100CR2, 100CR-2

great idea ... it's is always an integer until they add the CR flag ... works!!!

Activity icon

Started a new Conversation Find 100 From 100CR, 100CR1, 100CR-1, 100CR2, 100CR-2

I have a large database table of invoices where I need to match Credit Memos to Invoices by a project code. In the past, adding the project_code was not a business requirement (nice, huh).

If an invoice number has a credit memo, the credit memo's invoice number is SUPPOSED to be the invoice number plus 'CR' (i.e., Invoice: 100, Credit: 100CR) but humans being human have littered the table with CR, CR1 or CR-1, CR2 and CR-2 and now I have to rectify.

If I find ALL of the invoices without a project_code and loop through them, how can I find the original invoice (100) if I might have invoice numbers of 100CR, 100CR1 etc. The invoice number is not a constant length so I can't sub-string and I am lost and looking for advice.

Thanks.

Activity icon

Started a new Conversation No Such Table

I use an sqlite database in memory for testing (set in my phpunit.xml file).

I verify that I have a migration for my invoices table.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateInvoicesTable extends Migration
{
    public function up()
    {
        if (Schema::hasTable('invoices')) { return; }
        
        Schema::table('invoices', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('consignment_code')->nullable();
            $table->string('route_code')->nullable();
            $table->string('route_description')->nullable();
            $table->string('part_number')->nullable();
            $table->string('serial_no')->nullable();
            $table->string('description')->nullable();
            $table->string('invc_number')->nullable();
            $table->string('so_number')->nullable();
            $table->string('cond')->nullable();
            $table->string('company')->nullable();
            $table->string('salesperson')->nullable();
            $table->date('invoice_date')->nullable();
            $table->double('price', 10, 2)->nullable();
            $table->double('cost', 10, 2)->nullable();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::table('invoices', function (Blueprint $table) {
            //
        });
    }
}

I have an Invoices factory

<?php

/** @var Factory $factory */

use App\Models\Invoice;
use Carbon\Carbon;
use Faker\Generator as Faker;
use Illuminate\Database\Eloquent\Factory;

$factory->define(Invoice::class, function (Faker $faker) {
    return [
        'consignment_code' => $faker->word,
        'invc_number' => $faker->word,
        'route_code' => $faker->word,
        'route_description' => $faker->word,
        'part_number' => $faker->word,
        'serial_no' => $faker->word,
        'description' => $faker->word,
        'cond' => 'AR',
        'company' => 'ToysRUs',
        'salesperson' => 'JGRAV',
        'invoice_date' => Carbon::yesterday(),
        'ship_date' => Carbon::today(),
        'gross' => 1200,
        'qty' => 1,
        'cost' => 200,
        'net' => 1000,
    ];
});

So I am writing my first "sanity" test

<?php

namespace Tests\Feature;

use App\Models\Invoice;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use Tests\UamTestCase;

class InvoicesControllerTest extends UamTestCase
{
    /** @test */
    public function factory_makes_an_invoice () {
        //$this->withoutExceptionHandling();

        $invc = factory(Invoice::class)->create();

        $this->assertEquals(1000, $invc->net);
    } // end test
}

I run the test and get this error which I have never seen before and am not sure how to fix

Illuminate\Database\QueryException
SQLSTATE[HY000]: General error: 1 no such table: invoices (SQL: alter table "invoices" add column "id" integer not null primary key autoincrement)
Feb
03
3 months ago
Activity icon

Started a new Conversation Call To Undefined Method App\Models\Ticket::via()

I have an Event Listener

<?php

namespace App\Listeners;

use App\Events\TicketClosed;
use App\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class NotifyUserOfClosedTicket
{
    public function __construct()
    {
        //
    }

    public function handle(TicketClosed $event)
    {
        $user = User::find($event->ticket->user_id);
        $user->notify($event->ticket);
    }
}

I am getting Call to undefined method App\Models\Ticket::via()

That method is on the Notification and not the model and I can't see what I am missing to fix.

Jan
21
4 months ago
Activity icon

Commented on Send SMS Notifications In 5 Minutes

Will we cover how to use the little window that pops up in the browser (like when a new mail message comes in)???

Dec
12
5 months ago
Activity icon

Replied to Json Response Removing Path To Image

The images are saved to a Digital Ocean Spaces external disk. The full path is in the .env file.

Activity icon

Started a new Conversation Json Response Removing Path To Image

I have a View Composer serving the currentUser to all views (I have a JSON Resource modifying the authenticated user).

The path to the avatar is broken so I dumped out the $user object and inside I see avatar":"https:\/\/uam.sfo2.digitaloceanspaces.com\/avatars\/JonGravois.png" but when I dump out $user->avatar, i get JonGravois.png?

HOME:

@extends('layouts.app')

@section('content')
    <div class="flex items-center">
        <div class="md:w-1/2 md:mx-auto">

            @if (session('status'))
                <div class="text-sm border border-t-8 rounded text-green-700 border-green-600 bg-green-100 px-3 py-4 mb-4" role="alert">
                    {{ session('status') }}
                </div>
            @endif

            <div class="flex flex-col break-words bg-white border border-2 rounded shadow-md">

                <div class="font-semibold bg-gray-200 text-gray-700 py-3 px-6 mb-0">
                    Dashboard
                </div>

                <div class="w-full p-6">
                    <p class="text-gray-700">
                        You are logged in!
                    </p>
                </div>
            </div>

                {{json_encode($user)}}

                <br><br><br>

                {{$user->avatar}}

        </div>
    </div>
@endsection

RESOURCE:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class StaffResource extends JsonResource
{
    public function toArray($request)
    {
        //return parent::toArray($request);
        $perms = [];
        foreach($this->permissions as $p) {
            $perms[$p->name] = $p->pivot->permission_level;
        } // end foreach

        $avatar = ($this->avatar ? env('SPACES_URI') . 'avatars/' . $this->avatar : env('SPACES_URI') . 'avatars/default.png');

        return [
            'id' => $this->id,
            'anniversary' => (string)$this->anniversary,
            'avatar' => $avatar,
            'badge' => $this->badge,
            'display' => $this->display,
            'can_drive' => (boolean)$this->can_drive,
            'can_manage' => (boolean)$this->can_manage,
            'cellphone' => $this->cellphone,
            'department' => ($this->departments ? implode(', ', collect($this->departments)->pluck('display')->all()) : null),
            'directLine' => $this->directLine,
            'dob' => (string)$this->dob,
            'email' => $this->email,
            'extension' => $this->extension,
            'firstName' => $this->firstName,
            'isDeveloper' => (boolean)$this->is_developer,
            'isLeadership' => (boolean)$this->is_leadership,
            'isManagement' => (boolean)$this->is_management,
            'isOnline' => (boolean)$this->is_online,
            'isOntask' => (boolean)$this->is_ontask,
            'isPaused' => (boolean)$this->is_paused,
            'isStaff' => true,
            'lastName' => $this->lastName,
            'location' => $this->office->location,
            'manager_id' => $this->manager_id,
            'manager' => ($this->manager ? $this->manager->name : null),
            'name' => $this->name,
            'office' => $this->office['display'],
            'office_id' => $this->office_id,
            'salesperson' => $this->salesperson,
            'skype' => $this->skype,
            'status' => $this->status,
            'title' => $this->title,
            'user_id' => $this->id,
            'roles' => ($this->roles ? implode(', ', collect($this->roles)->sortBy('title')->pluck('title')->all()) : null),
            'perms' => $perms,
        ];
    }
}

VIEW COMPOSER

<?php

namespace App\Providers;

use App\Http\Resources\StaffResource;
use App\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ViewComposerServiceProvider extends ServiceProvider
{
    public function register()
    {
        //
    }

    public function boot()
    {
        //Current Authenticated User Resource to all views
        View::composer('*', function ($view) {
            $raw = User::whereId(Auth::id())->first();
            $currentUser = (new StaffResource($raw));

            $view->with('user', $currentUser);
        });
    }
}
Dec
09
5 months ago
Activity icon

Started a new Conversation Lost Trying To Mock A Guzzle Presenter In PhpUnit

I am trying to test this method

public function searchForInvoice($inv)
    {
        $qp = new QuantumPresenter();
        $type = request('searchType');

        try
        {
            if($type == 'invoice') {
                $invoice = $qp->fetchProd('rma/invoice/' . $inv);
            } else {
                $invoice = $qp->fetchProd('rma/po/' . $inv);
            }

            if($invoice->result == 'success') {
                return json_encode($invoice->data);
            } else {
                return response()->json(['msg' => 'Unable to locate invoice.'], 419);
            } // end if
        }
        catch(\Exception $e)
            {
                return response()->json(['msg' => 'Unable to connect to Quantum.'], 419);
            } // End try...catch

    } // end function

The Presenter is pretty straight forward:

<?php

namespace App\Presenters;

use GuzzleHttp\Pool;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Illuminate\Support\Facades\Log;

class QuantumPresenter extends Presenter
{
    protected $client;

    public function __construct()
    {
        $this->client = new Client;
    }

    public function fetch($path)
    {
        try {
            $response = $this->client->request('GET', env('Q2GO') . $path, ['auth' => [env('QUANTUM_NAME'), env('QUANTUM_KEY')]]);

            return json_decode($response->getBody()->getContents());
        } catch (\Exception $e) {
            Log::error('Received error: ' . $e->getMessage());
            return false;
        }
    } // end function

    public function fetchProd($path)
    {
        try {
            $response = $this->client->request('GET', env('Q2GOP') . $path, ['auth' => [env('QUANTUM_NAME'), env('QUANTUM_KEY')]]);

            return json_decode($response->getBody()->getContents());
        } catch (\Exception $e) {
            Log::error('Received error: ' . $e->getMessage());
            return false;
        }
    } // end function

    public function post($path, $payload)
    {
        try{
            $response = $this->client->request('POST', env('Q2GO') . $path, ['auth' => [env('QUANTUM_NAME'), env('QUANTUM_KEY')], 'form_params' => $payload]);

            return json_decode($response->getBody()->getContents());
        } catch (\Exception $e) {
            Log::error('Received error: ' . $e->getMessage());
            return $e;
        }
    } // end function

    public function postProd($path, $payload)
    {
        try{
            $response = $this->client->request('POST', env('Q2GOP') . $path, ['auth' => [env('QUANTUM_NAME'), env('QUANTUM_KEY')], 'form_params' => $payload]);

            return json_decode($response->getBody()->getContents());
        } catch (\Exception $e) {
            Log::error('Received error: ' . $e->getMessage());
            return $e;
        }
    } // end function
}

I am trying to mock that with this class but not sure if I am doing it correctly

<?php

namespace App\Presenters;

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use Illuminate\Support\Facades\Log;

class MockQPresenter
{
    protected $client;

    public function __construct()
    {
        $this->client = new Client;
    }

    public function fetch($path)
    {
        return response()->json(['msg' => 'Fetch'], 200);
    } // end function

    public function fetchProd($path)
    {
        return response()->json(['msg' => 'FetchProd'], 204);
    } // end function

    public function post($path)
    {
        return response()->json(['msg' => 'Post'], 200);
    } // end function

    public function postProd($path)
    {
        return response()->json(['msg' => 'PostProd'], 200);
    } // end function
}

Here's my failing test

/** @test */
    public function user_receives_invoice_from_qp () {
        $user = factory(User::class)->create();
        $mock = $this->mock(MockQPresenter::class);

        $rsp = $this->actingAs($user)
            ->post('/api/returns/search_inv/87259', [
                'searchType' => 'invoice'
            ])
            ->assertStatus(200);

        $mocked = $mock->shouldReceive('fetchProd')
            ->with('search_inv/87259')
            ->once()
            ->andReturn(new Response(
                $status = 204,
                $headers = [],
                File::get(base_path('tests/stubs/invoice.json'))
            ));

        var_dump($mocked);

    } // end test

and failure is

There was 1 error:

1) Tests\Unit\ReturnsLookupTest::user_receives_invoice_from_qp
Mockery\Exception\InvalidCountException: Method fetchProd('search_inv/87259') from Mockery_2_App_Presenters_MockQPresenter should be called
 exactly 1 times but called 0 times.

/Users/jgravois/code/my-uam/vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php:38
/Users/jgravois/code/my-uam/vendor/mockery/mockery/library/Mockery/Expectation.php:310
/Users/jgravois/code/my-uam/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php:119
/Users/jgravois/code/my-uam/vendor/mockery/mockery/library/Mockery/Container.php:309
/Users/jgravois/code/my-uam/vendor/mockery/mockery/library/Mockery/Container.php:294
/Users/jgravois/code/my-uam/vendor/mockery/mockery/library/Mockery.php:205
/Users/jgravois/code/my-uam/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:172