diff --git a/app/Http/Controllers/RecurringInvoiceController.php b/app/Http/Controllers/RecurringInvoiceController.php index 2c1b5ea290c8..96d32cc3a698 100644 --- a/app/Http/Controllers/RecurringInvoiceController.php +++ b/app/Http/Controllers/RecurringInvoiceController.php @@ -431,6 +431,62 @@ class RecurringInvoiceController extends BaseController return response()->json([], 200); } + + /** + * @OA\Get( + * path="/api/v1/recurring_invoice/{invitation_key}/download", + * operationId="downloadInvoice", + * tags={"invoices"}, + * summary="Download a specific invoice by invitation key", + * description="Downloads a specific invoice", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="invitation_key", + * in="path", + * description="The Recurring Invoice Invitation Key", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the recurring invoice pdf", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + * @param $invitation_key + * @return \Symfony\Component\HttpFoundation\BinaryFileResponse + */ + public function downloadPdf($invitation_key) + { + $invitation = $this->recurring_invoice_repo->getInvitationByKey($invitation_key); + $contact = $invitation->contact; + $recurring_invoice = $invitation->recurring_invoice; + + $file_path = $recurring_invoice->service()->getInvoicePdf($contact); + + return response()->download($file_path, basename($file_path)); + } + /** * Perform bulk actions on the list view. * diff --git a/app/Jobs/Entity/CreateEntityPdf.php b/app/Jobs/Entity/CreateEntityPdf.php index 04ca27461698..ce3e37103a20 100644 --- a/app/Jobs/Entity/CreateEntityPdf.php +++ b/app/Jobs/Entity/CreateEntityPdf.php @@ -19,6 +19,7 @@ use App\Models\Invoice; use App\Models\InvoiceInvitation; use App\Models\Quote; use App\Models\QuoteInvitation; +use App\Models\RecurringInvoice; use App\Models\RecurringInvoiceInvitation; use App\Services\PdfMaker\Design as PdfDesignModel; use App\Services\PdfMaker\Design as PdfMakerDesign; @@ -106,6 +107,9 @@ class CreateEntityPdf implements ShouldQueue } elseif ($this->entity instanceof Credit) { $path = $this->entity->client->credit_filepath(); $entity_design_id = 'credit_design_id'; + } elseif ($this->entity instanceof RecurringInvoice) { + $path = $this->entity->client->recurring_invoice_filepath(); + $entity_design_id = 'invoice_design_id'; } $file_path = $path.$this->entity->number.'.pdf'; diff --git a/app/Models/Client.php b/app/Models/Client.php index 8066fa4bd986..6f079cd56860 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -605,6 +605,11 @@ class Client extends BaseModel implements HasLocalePreference return $this->company->company_key.'/'.$this->client_hash.'/credits/'; } + public function recurring_invoice_filepath() + { + return $this->company->company_key.'/'.$this->client_hash.'/recurring_invoices/'; + } + public function company_filepath() { return $this->company->company_key.'/'; diff --git a/app/Models/RecurringInvoice.php b/app/Models/RecurringInvoice.php index 549aa08333ee..956aa558e9e1 100644 --- a/app/Models/RecurringInvoice.php +++ b/app/Models/RecurringInvoice.php @@ -13,12 +13,14 @@ namespace App\Models; use App\Helpers\Invoice\InvoiceSum; use App\Helpers\Invoice\InvoiceSumInclusive; +use App\Models\Presenters\RecurringInvoicePresenter; use App\Services\Recurring\RecurringService; use App\Utils\Traits\MakesDates; use App\Utils\Traits\MakesHash; use App\Utils\Traits\Recurring\HasRecurrence; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Carbon; +use Laracasts\Presenter\PresentableTrait; /** * Class for Recurring Invoices. @@ -30,6 +32,9 @@ class RecurringInvoice extends BaseModel use Filterable; use MakesDates; use HasRecurrence; + use PresentableTrait; + + protected $presenter = RecurringInvoicePresenter::class; /** * Invoice Statuses. diff --git a/app/Repositories/RecurringInvoiceRepository.php b/app/Repositories/RecurringInvoiceRepository.php index aad82a4e6c23..b74560bc1b1e 100644 --- a/app/Repositories/RecurringInvoiceRepository.php +++ b/app/Repositories/RecurringInvoiceRepository.php @@ -13,6 +13,7 @@ namespace App\Repositories; use App\Helpers\Invoice\InvoiceSum; use App\Models\RecurringInvoice; +use App\Models\RecurringInvoiceInvitation; /** * RecurringInvoiceRepository. @@ -38,4 +39,9 @@ class RecurringInvoiceRepository extends BaseRepository return $invoice; } + + public function getInvitationByKey($key) :?RecurringInvoiceInvitation + { + return RecurringInvoiceInvitation::whereRaw('BINARY `key`= ?', [$key])->first(); + } } diff --git a/app/Services/Recurring/RecurringService.php b/app/Services/Recurring/RecurringService.php index 8f6bbe32ac3b..a84c229514f3 100644 --- a/app/Services/Recurring/RecurringService.php +++ b/app/Services/Recurring/RecurringService.php @@ -12,6 +12,7 @@ namespace App\Services\Recurring; use App\Models\RecurringInvoice; +use App\Services\Recurring\GetInvoicePdf; use Illuminate\Support\Carbon; class RecurringService @@ -77,6 +78,11 @@ class RecurringService return $this; } + public function getInvoicePdf($contact = null) + { + return (new GetInvoicePdf($this->recurring_entity, $contact))->run(); + } + public function save() { $this->recurring_entity->save(); diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index ff1020d0b2e8..c9f20182c57b 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -118,7 +118,7 @@ class HtmlEngine $data['$quote.datetime'] = &$data['$entity.datetime']; $data['$credit.datetime'] = &$data['$entity.datetime']; - if ($this->entity_string == 'invoice') { + if ($this->entity_string == 'invoice' || $this->entity_string == 'recurring_invoice') { $data['$entity'] = ['value' => '', 'label' => ctrans('texts.invoice')]; $data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')]; $data['$entity.terms'] = ['value' => $this->entity->terms ?: ' ', 'label' => ctrans('texts.invoice_terms')]; diff --git a/routes/client.php b/routes/client.php index e3cb1285ee26..fb886e9d0b0e 100644 --- a/routes/client.php +++ b/routes/client.php @@ -80,6 +80,7 @@ Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'clie /*Invitation catches*/ Route::get('recurring_invoice/{invitation_key}', 'ClientPortal\InvitationController@recurringRouter'); Route::get('{entity}/{invitation_key}', 'ClientPortal\InvitationController@router'); + Route::get('recurring_invoice/{invitation_key}/download_pdf', 'RecurringInvoiceController@downloadPdf')->name('recurring_invoice.download_invitation_key'); Route::get('invoice/{invitation_key}/download_pdf', 'InvoiceController@downloadPdf')->name('invoice.download_invitation_key'); Route::get('quote/{invitation_key}/download_pdf', 'QuoteController@downloadPdf')->name('quote.download_invitation_key'); Route::get('credit/{invitation_key}/download_pdf', 'CreditController@downloadPdf')->name('credit.download_invitation_key');