mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-11 05:32:39 +01:00
commit
87752782ec
@ -28,6 +28,10 @@ class CloneQuoteToInvoiceFactory
|
|||||||
unset($quote_array['invoice_id']);
|
unset($quote_array['invoice_id']);
|
||||||
unset($quote_array['id']);
|
unset($quote_array['id']);
|
||||||
unset($quote_array['invitations']);
|
unset($quote_array['invitations']);
|
||||||
|
unset($quote_array['terms']);
|
||||||
|
unset($quote_array['public_notes']);
|
||||||
|
unset($quote_array['footer']);
|
||||||
|
unset($quote_array['design_id']);
|
||||||
|
|
||||||
foreach ($quote_array as $key => $value) {
|
foreach ($quote_array as $key => $value) {
|
||||||
$invoice->{$key} = $value;
|
$invoice->{$key} = $value;
|
||||||
|
@ -163,6 +163,6 @@ class ActivityController extends BaseController
|
|||||||
|
|
||||||
return response()->streamDownload(function () use ($pdf) {
|
return response()->streamDownload(function () use ($pdf) {
|
||||||
echo $pdf;
|
echo $pdf;
|
||||||
}, $filename);
|
}, $filename, ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ class InvoiceController extends Controller
|
|||||||
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);;
|
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);;
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable output of HTTP headers
|
// enable output of HTTP headers
|
||||||
|
@ -96,7 +96,7 @@ class QuoteController extends Controller
|
|||||||
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable output of HTTP headers
|
// enable output of HTTP headers
|
||||||
|
@ -544,7 +544,7 @@ class CreditController extends BaseController
|
|||||||
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
break;
|
break;
|
||||||
case 'archive':
|
case 'archive':
|
||||||
$this->credit_repository->archive($credit);
|
$this->credit_repository->archive($credit);
|
||||||
@ -596,8 +596,8 @@ class CreditController extends BaseController
|
|||||||
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
// return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -672,16 +672,11 @@ class InvoiceController extends BaseController
|
|||||||
break;
|
break;
|
||||||
case 'download':
|
case 'download':
|
||||||
|
|
||||||
// $file = $invoice->pdf_file_path();
|
|
||||||
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
|
||||||
|
|
||||||
$file = $invoice->service()->getInvoicePdf();
|
$file = $invoice->service()->getInvoicePdf();
|
||||||
|
|
||||||
// return response()->download(Storage::get($file), basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
|
||||||
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -805,11 +800,9 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
$file = $invoice->service()->getInvoicePdf($contact);
|
$file = $invoice->service()->getInvoicePdf($contact);
|
||||||
|
|
||||||
// return response()->download(Storage::get($file), basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
|
||||||
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -861,10 +854,9 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
$file = $invoice->service()->getInvoiceDeliveryNote($invoice, $invoice->invitations->first()->contact);
|
$file = $invoice->service()->getInvoiceDeliveryNote($invoice, $invoice->invitations->first()->contact);
|
||||||
|
|
||||||
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,16 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Factory\InvoiceFactory;
|
||||||
|
use App\Http\Requests\Invoice\StoreInvoiceRequest;
|
||||||
|
use App\Http\Requests\Preview\PreviewInvoiceRequest;
|
||||||
use App\Jobs\Util\PreviewPdf;
|
use App\Jobs\Util\PreviewPdf;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\InvoiceInvitation;
|
use App\Models\InvoiceInvitation;
|
||||||
|
use App\Repositories\InvoiceRepository;
|
||||||
|
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
||||||
use App\Services\PdfMaker\Design;
|
use App\Services\PdfMaker\Design;
|
||||||
use App\Services\PdfMaker\PdfMaker;
|
use App\Services\PdfMaker\PdfMaker;
|
||||||
use App\Utils\HostedPDF\NinjaPdf;
|
use App\Utils\HostedPDF\NinjaPdf;
|
||||||
@ -149,6 +154,103 @@ class PreviewController extends BaseController
|
|||||||
return $this->blankEntity();
|
return $this->blankEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function live(PreviewInvoiceRequest $request)
|
||||||
|
{
|
||||||
|
if(request()->input('entity') == 'invoice'){
|
||||||
|
$repo = new InvoiceRepository();
|
||||||
|
$factory = InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::connection(config('database.default'))->beginTransaction();
|
||||||
|
|
||||||
|
$entity = ucfirst(request()->input('entity'));
|
||||||
|
|
||||||
|
// $class = "App\Models\\$entity";
|
||||||
|
|
||||||
|
// $entity_obj = $class::whereId($this->decodePrimaryKey(request()->input('entity_id')))->company()->first();
|
||||||
|
|
||||||
|
// if (! $entity_obj) {
|
||||||
|
|
||||||
|
$entity_obj = $repo->save(request()->all(), $factory);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
$entity_obj->load('client');
|
||||||
|
|
||||||
|
App::forgetInstance('translator');
|
||||||
|
$t = app('translator');
|
||||||
|
App::setLocale($entity_obj->client->primary_contact()->first()->preferredLocale());
|
||||||
|
$t->replace(Ninja::transformTranslations($entity_obj->client->getMergedSettings()));
|
||||||
|
|
||||||
|
$html = new HtmlEngine($entity_obj->invitations()->first());
|
||||||
|
|
||||||
|
$design = \App\Models\Design::find($entity_obj->design_id);
|
||||||
|
|
||||||
|
/* Catch all in case migration doesn't pass back a valid design */
|
||||||
|
if(!$design)
|
||||||
|
$design = Design::find(2);
|
||||||
|
|
||||||
|
if ($design->is_custom) {
|
||||||
|
$options = [
|
||||||
|
'custom_partials' => json_decode(json_encode($design->design), true)
|
||||||
|
];
|
||||||
|
$template = new PdfMakerDesign(PdfDesignModel::CUSTOM, $options);
|
||||||
|
} else {
|
||||||
|
$template = new PdfMakerDesign(strtolower($design->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
$variables = $html->generateLabelsAndValues();
|
||||||
|
|
||||||
|
$state = [
|
||||||
|
'template' => $template->elements([
|
||||||
|
'client' => $entity_obj->client,
|
||||||
|
'entity' => $entity_obj,
|
||||||
|
'pdf_variables' => (array) $entity_obj->company->settings->pdf_variables,
|
||||||
|
'$product' => $design->design->product,
|
||||||
|
'variables' => $variables,
|
||||||
|
]),
|
||||||
|
'variables' => $variables,
|
||||||
|
'options' => [
|
||||||
|
'all_pages_header' => $entity_obj->client->getSetting('all_pages_header'),
|
||||||
|
'all_pages_footer' => $entity_obj->client->getSetting('all_pages_footer'),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$maker = new PdfMaker($state);
|
||||||
|
|
||||||
|
$maker
|
||||||
|
->design($template)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
if (request()->query('html') == 'true') {
|
||||||
|
return $maker->getCompiledHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::connection(config('database.default'))->rollBack();
|
||||||
|
|
||||||
|
//if phantom js...... inject here..
|
||||||
|
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||||
|
return (new Phantom)->convertHtmlToPdf($maker->getCompiledHTML(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja'){
|
||||||
|
return (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
//else
|
||||||
|
$file_path = PreviewPdf::dispatchNow($maker->getCompiledHTML(true), auth()->user()->company());
|
||||||
|
|
||||||
|
//return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||||
|
|
||||||
|
$response = Response::make($file_path, 200);
|
||||||
|
$response->header('Content-Type', 'application/pdf');
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private function blankEntity()
|
private function blankEntity()
|
||||||
{
|
{
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
|
@ -682,7 +682,7 @@ class QuoteController extends BaseController
|
|||||||
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
|
|
||||||
//return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
//return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||||
|
|
||||||
@ -736,11 +736,10 @@ class QuoteController extends BaseController
|
|||||||
$quote = $invitation->quote;
|
$quote = $invitation->quote;
|
||||||
|
|
||||||
$file = $quote->service()->getQuotePdf($contact);
|
$file = $quote->service()->getQuotePdf($contact);
|
||||||
nlog($file);
|
|
||||||
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
|
|
||||||
// return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
// return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||||
}
|
}
|
||||||
|
@ -505,7 +505,7 @@ class RecurringInvoiceController extends BaseController
|
|||||||
|
|
||||||
return response()->streamDownload(function () use($file) {
|
return response()->streamDownload(function () use($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file));
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ class SubdomainController extends BaseController
|
|||||||
'docs',
|
'docs',
|
||||||
'client_domain',
|
'client_domain',
|
||||||
'custom_domain',
|
'custom_domain',
|
||||||
|
'preview',
|
||||||
|
'invoiceninja',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
|
59
app/Http/Requests/Preview/PreviewInvoiceRequest.php
Normal file
59
app/Http/Requests/Preview/PreviewInvoiceRequest.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Preview;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Http\ValidationRules\Project\ValidProjectForClient;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Utils\Traits\CleanLineItems;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class PreviewInvoiceRequest extends Request
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
use CleanLineItems;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('create', Invoice::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
$rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||||
|
|
||||||
|
$rules['number'] = ['nullable'];
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepareForValidation()
|
||||||
|
{
|
||||||
|
$input = $this->all();
|
||||||
|
|
||||||
|
$input = $this->decodePrimaryKeys($input);
|
||||||
|
|
||||||
|
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||||
|
$input['amount'] = 0;
|
||||||
|
$input['balance'] = 0;
|
||||||
|
|
||||||
|
$this->replace($input);
|
||||||
|
}
|
||||||
|
}
|
@ -238,6 +238,10 @@ class Import implements ShouldQueue
|
|||||||
/*After a migration first some basic jobs to ensure the system is up to date*/
|
/*After a migration first some basic jobs to ensure the system is up to date*/
|
||||||
VersionCheck::dispatch();
|
VersionCheck::dispatch();
|
||||||
|
|
||||||
|
$account = $this->company->account;
|
||||||
|
$account->default_company_id = $this->company->id;
|
||||||
|
$account->save();
|
||||||
|
|
||||||
//company size check
|
//company size check
|
||||||
if ($this->company->invoices()->count() > 1000 || $this->company->products()->count() > 1000 || $this->company->clients()->count() > 1000) {
|
if ($this->company->invoices()->count() > 1000 || $this->company->products()->count() > 1000 || $this->company->clients()->count() > 1000) {
|
||||||
$this->company->is_large = true;
|
$this->company->is_large = true;
|
||||||
|
@ -27,7 +27,6 @@ class CompanyPresenter extends EntityPresenter
|
|||||||
|
|
||||||
return $this->settings->name ?: ctrans('texts.untitled_account');
|
return $this->settings->name ?: ctrans('texts.untitled_account');
|
||||||
|
|
||||||
//return $this->entity->name ?: ctrans('texts.untitled_account');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ class CompanyPresenter extends EntityPresenter
|
|||||||
/**
|
/**
|
||||||
* Test for using base64 encoding
|
* Test for using base64 encoding
|
||||||
*/
|
*/
|
||||||
public function logo2($settings = null)
|
public function logo_base64($settings = null)
|
||||||
{
|
{
|
||||||
if (! $settings) {
|
if (! $settings) {
|
||||||
$settings = $this->entity->settings;
|
$settings = $this->entity->settings;
|
||||||
|
@ -300,7 +300,7 @@ class BaseRepository
|
|||||||
$model->partial = min($model->amount, $model->balance);
|
$model->partial = min($model->amount, $model->balance);
|
||||||
|
|
||||||
/* Update product details if necessary */
|
/* Update product details if necessary */
|
||||||
if ($model->company->update_products)
|
if ($model->company->update_products && $model->id)
|
||||||
UpdateOrCreateProduct::dispatch($model->line_items, $model, $model->company);
|
UpdateOrCreateProduct::dispatch($model->line_items, $model, $model->company);
|
||||||
|
|
||||||
/* Perform model specific tasks */
|
/* Perform model specific tasks */
|
||||||
|
@ -40,6 +40,7 @@ class ConvertQuote
|
|||||||
$invoice->fresh();
|
$invoice->fresh();
|
||||||
|
|
||||||
$invoice->service()
|
$invoice->service()
|
||||||
|
->fillDefaults()
|
||||||
// ->markSent()
|
// ->markSent()
|
||||||
// ->createInvitations()
|
// ->createInvitations()
|
||||||
->save();
|
->save();
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
@keydown.window.escape="sidebarOpen = false"
|
@keydown.window.escape="sidebarOpen = false"
|
||||||
id="main-sidebar">
|
id="main-sidebar">
|
||||||
|
|
||||||
|
@if($settings->enable_client_portal)
|
||||||
<!-- Off-canvas menu for mobile -->
|
<!-- Off-canvas menu for mobile -->
|
||||||
@include('portal.ninja2020.components.general.sidebar.mobile')
|
@include('portal.ninja2020.components.general.sidebar.mobile')
|
||||||
|
|
||||||
@ -12,6 +13,8 @@
|
|||||||
@include('portal.ninja2020.components.general.sidebar.desktop')
|
@include('portal.ninja2020.components.general.sidebar.desktop')
|
||||||
@endunless
|
@endunless
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="flex flex-col w-0 flex-1 overflow-hidden">
|
<div class="flex flex-col w-0 flex-1 overflow-hidden">
|
||||||
@include('portal.ninja2020.components.general.sidebar.header')
|
@include('portal.ninja2020.components.general.sidebar.header')
|
||||||
<main
|
<main
|
||||||
|
@ -114,6 +114,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
|
|||||||
Route::post('payment_terms/bulk', 'PaymentTermController@bulk')->name('payment_terms.bulk');
|
Route::post('payment_terms/bulk', 'PaymentTermController@bulk')->name('payment_terms.bulk');
|
||||||
|
|
||||||
Route::post('preview', 'PreviewController@show')->name('preview.show');
|
Route::post('preview', 'PreviewController@show')->name('preview.show');
|
||||||
|
Route::post('live_preview', 'PreviewController@live')->name('preview.live');
|
||||||
|
|
||||||
Route::resource('products', 'ProductController'); // name = (products. index / create / show / update / destroy / edit
|
Route::resource('products', 'ProductController'); // name = (products. index / create / show / update / destroy / edit
|
||||||
Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk');
|
Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk');
|
||||||
|
Loading…
Reference in New Issue
Block a user