Hasnayeen / invobook

Self-hosted app for Time Tracking, Invoice Generation, Project & Client Management, built with Laravel & Filament.
MIT License
2.13k stars 610 forks source link

app  /  Actions  /  GenerateInvoicePdf .php   : 45 #1503

Closed rabol closed 4 months ago

rabol commented 4 months ago

Hi

Just saw this project and wanted to give it a try.

I created a new client, then went to the invoices and pressed 'Generate invoice' and got this error:

LaravelDaily\Invoices\Services\PricingService::applyTax(): Argument #1 ($target) must be of type float, null given, called in /Users/rabol/code/web/invobook/vendor/laraveldaily/laravel-invoices/src/Traits/InvoiceHelpers.php on line 292

Maybe I need to do some base setup or something else ?

Hasnayeen commented 4 months ago

can you share the full stack trace please

rabol commented 4 months ago

Here you go

[2024-07-09 14:40:58] local.ERROR: App\Actions\GenerateInvoicePdf::getBuyer(): Argument #1 ($clientId) must be of type string, null given, called in /Users/rabol/code/web/invobook/app/Actions/GenerateInvoicePdf.php on line 30 {"userId":"01j2b40q57f4nq961c8jmdbbhv","exception":"[object] (TypeError(code: 0): App\\Actions\\GenerateInvoicePdf::getBuyer(): Argument #1 ($clientId) must be of type string, null given, called in /Users/rabol/code/web/invobook/app/Actions/GenerateInvoicePdf.php on line 30 at /Users/rabol/code/web/invobook/app/Actions/GenerateInvoicePdf.php:95)
[stacktrace]
#0 /Users/rabol/code/web/invobook/app/Actions/GenerateInvoicePdf.php(30): App\\Actions\\GenerateInvoicePdf->getBuyer(NULL)
#1 /Users/rabol/code/web/invobook/app/Filament/App/Resources/InvoiceResource/Pages/GenerateInvoice.php(138): App\\Actions\\GenerateInvoicePdf->__invoke(Array, Array, Array)
#2 /Users/rabol/code/web/invobook/vendor/filament/support/src/Concerns/EvaluatesClosures.php(35): App\\Filament\\App\\Resources\\InvoiceResource\\Pages\\GenerateInvoice::App\\Filament\\App\\Resources\\InvoiceResource\\Pages\\{closure}(Object(Filament\\Tables\\Table), Array, Object(App\\Actions\\GenerateInvoicePdf))
#3 /Users/rabol/code/web/invobook/vendor/filament/actions/src/MountableAction.php(41): Filament\\Support\\Components\\Component->evaluate(Object(Closure), Array)
#4 /Users/rabol/code/web/invobook/vendor/filament/tables/src/Actions/Action.php(168): Filament\\Actions\\MountableAction->call(Array)
#5 /Users/rabol/code/web/invobook/vendor/filament/tables/src/Concerns/HasActions.php(113): Filament\\Tables\\Actions\\Action->call(Array)
#6 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): App\\Filament\\App\\Resources\\InvoiceResource\\Pages\\GenerateInvoice->callMountedTableAction(Array)
#7 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#8 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#9 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#10 /Users/rabol/code/web/invobook/vendor/livewire/livewire/src/Wrapped.php(23): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array)
#11 /Users/rabol/code/web/invobook/vendor/livewire/livewire/src/Mechanisms/HandleComponents/HandleComponents.php(474): Livewire\\Wrapped->__call('callMountedTabl...', Array)
#12 /Users/rabol/code/web/invobook/vendor/livewire/livewire/src/Mechanisms/HandleComponents/HandleComponents.php(101): Livewire\\Mechanisms\\HandleComponents\\HandleComponents->callMethods(Object(App\\Filament\\App\\Resources\\InvoiceResource\\Pages\\GenerateInvoice), Array, Object(Livewire\\Mechanisms\\HandleComponents\\ComponentContext))
#13 /Users/rabol/code/web/invobook/vendor/livewire/livewire/src/LivewireManager.php(97): Livewire\\Mechanisms\\HandleComponents\\HandleComponents->update(Array, Array, Array)
#14 /Users/rabol/code/web/invobook/vendor/livewire/livewire/src/Mechanisms/HandleRequests/HandleRequests.php(94): Livewire\\LivewireManager->update(Array, Array, Array)
#15 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(46): Livewire\\Mechanisms\\HandleRequests\\HandleRequests->handleUpdate()
#16 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Livewire\\Mechanisms\\HandleRequests\\HandleRequests), 'handleUpdate')
#17 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Route.php(206): Illuminate\\Routing\\Route->runController()
#18 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Router.php(806): Illuminate\\Routing\\Route->run()
#19 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#20 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#21 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#22 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#23 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#24 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#25 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#26 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#27 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest(Object(Illuminate\\Http\\Request), Object(Illuminate\\Session\\Store), Object(Closure))
#28 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#29 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#30 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#31 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#32 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#33 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#34 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Router.php(805): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#35 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Router.php(784): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#36 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Router.php(748): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#37 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Routing/Router.php(737): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#38 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#39 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#40 /Users/rabol/code/web/invobook/vendor/livewire/livewire/src/Features/SupportDisablingBackButtonCache/DisableBackButtonCacheMiddleware.php(19): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#41 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Livewire\\Features\\SupportDisablingBackButtonCache\\DisableBackButtonCacheMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#42 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#43 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#44 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#45 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#46 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#47 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#48 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#49 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#50 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#51 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#52 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#53 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#54 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#55 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#56 /Users/rabol/code/web/invobook/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#57 /Users/rabol/code/web/invobook/public/index.php(51): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#58 /Users/rabol/.composer/vendor/laravel/valet/server.php(110): require('/Users/rabol/co...')
#59 {main}
"} 
Hasnayeen commented 4 months ago

have you selected a client when generating invoice? image

rabol commented 4 months ago

No :)

but then one should get an error that client is needed.

Also if different projects is involved, that it might not be for the same client etc.

so, some kind of validation is needed

Now, if I select a clinet I just get another error:

The command "PATH=$PATH:/usr/local/bin:/opt/homebrew/bin NODE_PATH=`/opt/homebrew/bin/node /opt/homebrew/bin/npm root -g` /opt/homebrew/bin/node '/Users/rabol/code/web/invobook/vendor/spatie/browsershot/src/../bin/browser.cjs' '{"url":"http:\/\/invobook.test\/01j2b40wqc2519vw1n9mkfch2t\/invoices\/default\/preview?invoice=01j2bbj7nsqncsa9my38eat6qb","action":"pdf","options":{"path":"\/Users\/rabol\/code\/web\/invobook\/storage\/app\/public\/invoices\/Invoice_example_2024-07-09 15:00.pdf","args":[],"viewport":{"width":800,"height":600},"format":"A4","newHeadless":true,"printBackground":true}}'" failed. Exit Code: 1(General error) Working directory: /Users/rabol/code/web/invobook/public Output: ================ Error Output: ================ Error: ENOENT: no such file or directory, open '/Users/rabol/code/web/invobook/storage/app/public/invoices/Invoice_example_2024-07-09 15:00.pdf' at async Object.open (node:internal/fs/promises:641:25) at async getReadableAsBuffer (/opt/homebrew/lib/node_modules/puppeteer/node_modules/puppeteer-core/lib/cjs/puppeteer/common/util.js:333:28) at async CDPPage.pdf (/opt/homebrew/lib/node_modules/puppeteer/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Page.js:773:24) at async getOutput (/Users/rabol/code/web/invobook/vendor/spatie/browsershot/bin/browser.cjs:49:28) at async callChrome (/Users/rabol/code/web/invobook/vendor/spatie/browsershot/bin/browser.cjs:386:21) { errno: -2, code: 'ENOENT', syscall: 'open', path: '/Users/rabol/code/web/invobook/storage/app/public/invoices/Invoice_example_2024-07-09 15:00.pdf' }
Hasnayeen commented 4 months ago

No :)

but then one should get an error that client is needed.

Also if different projects is involved, that it might not be for the same client etc.

so, some kind of validation is needed

Now, if I select a clinet I just get another error:

The command "PATH=$PATH:/usr/local/bin:/opt/homebrew/bin NODE_PATH=`/opt/homebrew/bin/node /opt/homebrew/bin/npm root -g` /opt/homebrew/bin/node '/Users/rabol/code/web/invobook/vendor/spatie/browsershot/src/../bin/browser.cjs' '{"url":"http:\/\/invobook.test\/01j2b40wqc2519vw1n9mkfch2t\/invoices\/default\/preview?invoice=01j2bbj7nsqncsa9my38eat6qb","action":"pdf","options":{"path":"\/Users\/rabol\/code\/web\/invobook\/storage\/app\/public\/invoices\/Invoice_example_2024-07-09 15:00.pdf","args":[],"viewport":{"width":800,"height":600},"format":"A4","newHeadless":true,"printBackground":true}}'" failed. Exit Code: 1(General error) Working directory: /Users/rabol/code/web/invobook/public Output: ================ Error Output: ================ Error: ENOENT: no such file or directory, open '/Users/rabol/code/web/invobook/storage/app/public/invoices/Invoice_example_2024-07-09 15:00.pdf' at async Object.open (node:internal/fs/promises:641:25) at async getReadableAsBuffer (/opt/homebrew/lib/node_modules/puppeteer/node_modules/puppeteer-core/lib/cjs/puppeteer/common/util.js:333:28) at async CDPPage.pdf (/opt/homebrew/lib/node_modules/puppeteer/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Page.js:773:24) at async getOutput (/Users/rabol/code/web/invobook/vendor/spatie/browsershot/bin/browser.cjs:49:28) at async callChrome (/Users/rabol/code/web/invobook/vendor/spatie/browsershot/bin/browser.cjs:386:21) { errno: -2, code: 'ENOENT', syscall: 'open', path: '/Users/rabol/code/web/invobook/storage/app/public/invoices/Invoice_example_2024-07-09 15:00.pdf' }

yeah validation is missing but a client is necessary, invoice without a client/receiving party doesn't make sense.

As for the error, try running php artisan storage:link

rabol commented 4 months ago

I did the storage link, but it did not work.

I then manually created the folder storage/app/invoices and then a pedf was generated... but please have a Invoice_example_2024-07-09 15:19.pdf look at the attached :)