diff --git a/.env.dusk.example b/.env.dusk.example
index 1e9637c88a31..5529bb44f721 100644
--- a/.env.dusk.example
+++ b/.env.dusk.example
@@ -5,7 +5,7 @@ APP_URL=http://127.0.0.1:8000
APP_KEY=s7epnjtomsdond5zgfqgaqmwhhcjct02
APP_CIPHER=AES-256-CBC
REQUIRE_HTTPS=false
-NINJA_ENVIRONMENT=hosted
+NINJA_ENVIRONMENT=development
DB_TYPE=mysql
DB_STRICT=false
diff --git a/.env.travis b/.env.travis
index 2ad583a420ab..f672e2a58d55 100644
--- a/.env.travis
+++ b/.env.travis
@@ -21,3 +21,4 @@ TEST_USERNAME=user@example.com
TEST_PERMISSIONS_USERNAME=permissions@example.com
MULTI_DB_ENABLED=true
+NINJA_ENVIRONMENT=development
diff --git a/app/Console/Commands/SendTestEmails.php b/app/Console/Commands/SendTestEmails.php
index a55b1df51c05..7e25dba03f17 100644
--- a/app/Console/Commands/SendTestEmails.php
+++ b/app/Console/Commands/SendTestEmails.php
@@ -143,7 +143,7 @@ class SendTestEmails extends Command
$invoice->setRelation('invitations', $ii);
$invoice->service()->markSent()->save();
- CreateInvoicePdf::dispatch($invoice, $company, $client->primary_contact()->first());
+ CreateInvoicePdf::dispatch($invoice->invitations()->first());
$cc_emails = [config('ninja.testvars.test_email')];
$bcc_emails = [config('ninja.testvars.test_email')];
diff --git a/app/Filters/InvoiceFilters.php b/app/Filters/InvoiceFilters.php
index df727032a55b..47ff97554cf8 100644
--- a/app/Filters/InvoiceFilters.php
+++ b/app/Filters/InvoiceFilters.php
@@ -173,7 +173,7 @@ class InvoiceFilters extends QueryFilters
if (auth('contact')->user()) {
return $this->contactViewFilter();
} else {
- return $this->builder->company();
+ return $this->builder->company()->with(['invitations.company'],['documents.company']);
}
// return $this->builder->whereCompanyId(auth()->user()->company()->id);
diff --git a/app/Helpers/Email/InvoiceEmail.php b/app/Helpers/Email/InvoiceEmail.php
index 6af1550f4091..a946baeeebca 100644
--- a/app/Helpers/Email/InvoiceEmail.php
+++ b/app/Helpers/Email/InvoiceEmail.php
@@ -77,7 +77,7 @@ class InvoiceEmail extends EmailBuilder
->setViewText(ctrans('texts.view_invoice'));
if ($client->getSetting('pdf_email_attachment') !== false) {
- $this->setAttachments($invoice->pdf_file_path());
+ $this->setAttachments($invitation->pdf_file_path());
}
return $this;
}
diff --git a/app/Helpers/Email/QuoteEmail.php b/app/Helpers/Email/QuoteEmail.php
index fc3302228eec..3696eb6ea3dd 100644
--- a/app/Helpers/Email/QuoteEmail.php
+++ b/app/Helpers/Email/QuoteEmail.php
@@ -61,7 +61,7 @@ class QuoteEmail extends EmailBuilder
->setBody($body_template);
if ($client->getSetting('pdf_email_attachment') !== false) {
- $this->attachments = $quote->pdf_file_path();
+ $this->attachments = $invitation->pdf_file_path();
}
return $this;
diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php
index dec3c6ccf433..6bd3bc062493 100644
--- a/app/Http/Controllers/ClientPortal/InvoiceController.php
+++ b/app/Http/Controllers/ClientPortal/InvoiceController.php
@@ -19,6 +19,7 @@ use App\Http\Requests\Request;
use App\Jobs\Entity\ActionEntity;
use App\Models\Invoice;
use App\Utils\Number;
+use App\Utils\TempFile;
use App\Utils\Traits\MakesDates;
use App\Utils\Traits\MakesHash;
use ZipStream\Option\Archive;
@@ -45,8 +46,11 @@ class InvoiceController extends Controller
*/
public function index(InvoiceFilters $filters)
{
- $invoices = auth()->user()->client->company->invoices()->paginate(10);
+ $client_id = auth('contact')->user()->client->id;
+ $invoices = Invoice::where('client_id', $client_id)->paginate(10);
+
+ // $invoices = Invoice::filter($filters);
return $this->render('invoices.index', ['invoices' => $invoices]);
}
@@ -154,10 +158,9 @@ class InvoiceController extends Controller
//if only 1 pdf, output to buffer for download
if ($invoices->count() == 1) {
- return response()->download(public_path($invoices->first()->pdf_file_path()));
+ return response()->download(TempFile::path($invoices->first()->pdf_file_path()), basename($invoices->first()->pdf_file_path()));
}
-
# enable output of HTTP headers
$options = new Archive();
$options->setSendHttpHeaders(true);
@@ -166,7 +169,7 @@ class InvoiceController extends Controller
$zip = new ZipStream(date('Y-m-d') . '_' . str_replace(' ', '_', trans('texts.invoices')).".zip", $options);
foreach ($invoices as $invoice) {
- $zip->addFileFromPath(basename($invoice->pdf_file_path()), public_path($invoice->pdf_file_path()));
+ $zip->addFileFromPath(basename($invoice->pdf_file_path()), TempFile::path($invoice->pdf_file_path()));
}
# finish the zip stream
diff --git a/app/Http/Controllers/ClientPortal/QuoteController.php b/app/Http/Controllers/ClientPortal/QuoteController.php
index c98080caaac3..d2cf33597e40 100644
--- a/app/Http/Controllers/ClientPortal/QuoteController.php
+++ b/app/Http/Controllers/ClientPortal/QuoteController.php
@@ -7,6 +7,7 @@ use App\Http\Requests\ClientPortal\ProcessQuotesInBulkRequest;
use App\Http\Requests\ClientPortal\ShowQuoteRequest;
use App\Models\Company;
use App\Models\Quote;
+use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
@@ -70,7 +71,7 @@ class QuoteController extends Controller
}
if ($quotes->count() == 1) {
- return response()->download(public_path($quotes->first()->pdf_file_path()));
+ return response()->download(TempFile::path($invoices->first()->pdf_file_path()), basename($quotes->first()->pdf_file_path()));
}
# enable output of HTTP headers
@@ -81,7 +82,7 @@ class QuoteController extends Controller
$zip = new ZipStream(date('Y-m-d') . '_' . str_replace(' ', '_', trans('texts.invoices')) . ".zip", $options);
foreach ($quotes as $quote) {
- $zip->addFileFromPath(basename($quote->pdf_file_path()), public_path($quote->pdf_file_path()));
+ $zip->addFileFromPath(basename($quote->pdf_file_path()), TempFile::path($quote->pdf_file_path()));
}
# finish the zip stream
diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php
index 008ecff23321..2341ffca289c 100644
--- a/app/Http/Controllers/CreditController.php
+++ b/app/Http/Controllers/CreditController.php
@@ -22,6 +22,7 @@ use App\Models\Client;
use App\Models\Credit;
use App\Repositories\CreditRepository;
use App\Transformers\CreditTransformer;
+use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
/**
@@ -526,8 +527,8 @@ class CreditController extends BaseController
}
break;
case 'download':
- return response()->download(public_path($credit->pdf_file_path()));
- break;
+ return response()->download(TempFile::path($credit->pdf_file_path()), basename($credit->pdf_file_path()));
+ break;
case 'archive':
$this->credit_repository->archive($credit);
diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index 8c06901e9eab..ed8266fb5758 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -36,6 +36,7 @@ use App\Models\Invoice;
use App\Models\InvoiceInvitation;
use App\Repositories\InvoiceRepository;
use App\Transformers\InvoiceTransformer;
+use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
@@ -659,7 +660,7 @@ class InvoiceController extends BaseController
}
break;
case 'download':
- return response()->download(public_path($invoice->pdf_file_path()));
+ return response()->download(TempFile::path($invoice->pdf_file_path()), basename($invoice->pdf_file_path()));
break;
case 'archive':
$this->invoice_repo->archive($invoice);
diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php
index 5e11973a1119..2cca17684b05 100644
--- a/app/Http/Controllers/QuoteController.php
+++ b/app/Http/Controllers/QuoteController.php
@@ -31,6 +31,7 @@ use App\Models\Quote;
use App\Repositories\QuoteRepository;
use App\Transformers\InvoiceTransformer;
use App\Transformers\QuoteTransformer;
+use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
@@ -657,7 +658,7 @@ class QuoteController extends BaseController
# code...
break;
case 'download':
- return response()->download(public_path($quote->pdf_file_path()));
+ return response()->download(TempFile::path($quote->pdf_file_path()), basename($quote->pdf_file_path()));
break;
case 'archive':
$this->invoice_repo->archive($quote);
diff --git a/app/Http/Middleware/QueryLogging.php b/app/Http/Middleware/QueryLogging.php
index 3ad0a11d19f1..9d86390553b8 100644
--- a/app/Http/Middleware/QueryLogging.php
+++ b/app/Http/Middleware/QueryLogging.php
@@ -47,10 +47,11 @@ class QueryLogging
$count = count($queries);
$timeEnd = microtime(true);
$time = $timeEnd - $timeStart;
- // Log::info($request->method() . ' - ' . $request->url() . ": $count queries - " . $time);
+
+ Log::info($request->method() . ' - ' . $request->url() . ": $count queries - " . $time);
- // if($count > 50)
- // Log::info($queries);
+ if($count > 50)
+ Log::info($queries);
}
}
diff --git a/app/Http/Requests/Account/CreateAccountRequest.php b/app/Http/Requests/Account/CreateAccountRequest.php
index 298e28c3ebbc..3b52a1c069b4 100644
--- a/app/Http/Requests/Account/CreateAccountRequest.php
+++ b/app/Http/Requests/Account/CreateAccountRequest.php
@@ -25,7 +25,6 @@ class CreateAccountRequest extends Request
public function authorize()
{
return true;
- //return ! auth()->user();
}
/**
diff --git a/app/Http/Requests/ClientPortal/ShowInvoiceRequest.php b/app/Http/Requests/ClientPortal/ShowInvoiceRequest.php
index 15013892869b..e3371b40dc9d 100644
--- a/app/Http/Requests/ClientPortal/ShowInvoiceRequest.php
+++ b/app/Http/Requests/ClientPortal/ShowInvoiceRequest.php
@@ -23,7 +23,8 @@ class ShowInvoiceRequest extends Request
*/
public function authorize() : bool
- {
- return auth()->user()->client->id === $this->invoice->client_id;
+ {info(auth('contact')->user()->client->id);
+ info($this->invoice->client_id);
+ return auth('contact')->user()->client->id === $this->invoice->client_id;
}
}
diff --git a/app/Jobs/Credit/CreateCreditPdf.php b/app/Jobs/Credit/CreateCreditPdf.php
index 8a0fef63e84f..496f71715dae 100644
--- a/app/Jobs/Credit/CreateCreditPdf.php
+++ b/app/Jobs/Credit/CreateCreditPdf.php
@@ -19,6 +19,7 @@ use App\Models\ClientContact;
use App\Models\Company;
use App\Models\Design;
use App\Models\Invoice;
+use App\Utils\HtmlEngine;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceHtml;
use App\Utils\Traits\NumberFormatter;
@@ -44,32 +45,30 @@ class CreateCreditPdf implements ShouldQueue
private $disk;
+ public $invitation;
+
/**
* Create a new job instance.
*
* @return void
*/
- public function __construct($credit, Company $company, ClientContact $contact = null)
+ public function __construct($invitation)
{
- $this->credit = $credit;
+ $this->invitation = $invitation;
- $this->company = $company;
+ $this->credit = $invitation->credit;
- $this->contact = $contact;
+ $this->company = $invitation->company;
+
+ $this->contact = $invitation->contact;
$this->disk = $disk ?? config('filesystems.default');
}
public function handle()
{
- MultiDB::setDB($this->company->db);
-
$this->credit->load('client');
- if (!$this->contact) {
- $this->contact = $this->credit->client->primary_contact()->first();
- }
-
App::setLocale($this->contact->preferredLocale());
$path = $this->credit->client->credit_filepath();
@@ -80,11 +79,8 @@ class CreateCreditPdf implements ShouldQueue
$designer = new Designer($this->credit, $design, $this->credit->client->getSetting('pdf_variables'), 'credit');
- //get invoice design
- // $html = $this->generateInvoiceHtml($designer->build()->getHtml(), $this->credit, $this->contact);
- $html = $this->generateEntityHtml($designer, $this->credit, $this->contact);
+ $html = (new HtmlEngine($designer, $invitation, 'credit'))->build();
- //todo - move this to the client creation stage so we don't keep hitting this unnecessarily
Storage::makeDirectory($path, 0755);
$pdf = $this->makePdf(null, null, $html);
diff --git a/app/Jobs/Invoice/CreateInvoicePdf.php b/app/Jobs/Invoice/CreateInvoicePdf.php
index 44f13602802a..155f27a51b5e 100644
--- a/app/Jobs/Invoice/CreateInvoicePdf.php
+++ b/app/Jobs/Invoice/CreateInvoicePdf.php
@@ -19,6 +19,7 @@ use App\Models\ClientContact;
use App\Models\Company;
use App\Models\Design;
use App\Models\Invoice;
+use App\Utils\HtmlEngine;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceHtml;
use App\Utils\Traits\NumberFormatter;
@@ -44,30 +45,28 @@ class CreateInvoicePdf implements ShouldQueue
private $disk;
+ public $invitation;
+
/**
* Create a new job instance.
*
* @return void
*/
- public function __construct($invoice, Company $company, ClientContact $contact = null)
+ public function __construct($invitation)
{
- $this->invoice = $invoice;
+ $this->invitation = $invitation;
- $this->company = $company;
+ $this->invoice = $invitation->invoice;
- $this->contact = $contact;
+ $this->company = $invitation->company;
+
+ $this->contact = $invitation->contact;
$this->disk = $disk ?? config('filesystems.default');
}
public function handle()
- {
- $this->invoice->load('client');
-
- if (!$this->contact) {
- $this->contact = $this->invoice->client->primary_contact()->first();
- }
-
+ {info(print_r($this->invitation->contact,1));
App::setLocale($this->contact->preferredLocale());
$path = $this->invoice->client->invoice_filepath();
@@ -78,8 +77,7 @@ class CreateInvoicePdf implements ShouldQueue
$designer = new Designer($this->invoice, $design, $this->invoice->client->getSetting('pdf_variables'), 'invoice');
- //get invoice design
- $html = $this->generateEntityHtml($designer, $this->invoice, $this->contact);
+ $html = (new HtmlEngine($designer, $this->invitation, 'invoice'))->build();
//todo - move this to the client creation stage so we don't keep hitting this unnecessarily
Storage::makeDirectory($path, 0755);
diff --git a/app/Jobs/Invoice/ZipInvoices.php b/app/Jobs/Invoice/ZipInvoices.php
index 4004ce79cd77..c427ea0adf59 100644
--- a/app/Jobs/Invoice/ZipInvoices.php
+++ b/app/Jobs/Invoice/ZipInvoices.php
@@ -16,6 +16,7 @@ use App\Libraries\MultiDB;
use App\Mail\DownloadInvoices;
use App\Models\Company;
use App\Models\Invoice;
+use App\Utils\TempFile;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -72,7 +73,7 @@ class ZipInvoices implements ShouldQueue
$zip = new ZipStream($file_name, $options);
foreach ($this->invoices as $invoice) {
- $zip->addFileFromPath(basename($invoice->pdf_file_path()), public_path($invoice->pdf_file_path()));
+ $zip->addFileFromPath(basename($invoice->pdf_file_path()), TempFile::path($invoice->pdf_file_path()));
}
$zip->finish();
diff --git a/app/Jobs/Quote/CreateQuotePdf.php b/app/Jobs/Quote/CreateQuotePdf.php
index 87f0f7b9ab53..99f423c053ab 100644
--- a/app/Jobs/Quote/CreateQuotePdf.php
+++ b/app/Jobs/Quote/CreateQuotePdf.php
@@ -19,6 +19,7 @@ use App\Models\ClientContact;
use App\Models\Company;
use App\Models\Design;
use App\Models\Invoice;
+use App\Utils\HtmlEngine;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceHtml;
use App\Utils\Traits\NumberFormatter;
@@ -44,34 +45,30 @@ class CreateQuotePdf implements ShouldQueue
private $disk;
+ public $invitation;
+
/**
* Create a new job instance.
*
* @return void
*/
- public function __construct($quote, Company $company, ClientContact $contact = null)
+ public function __construct($invitation)
{
- $this->quote = $quote;
+ $this->invitation = $invitation;
- $this->company = $company;
+ $this->quote = $invitation->quote;
- $this->contact = $contact;
+ $this->company = $invitation->company;
+
+ $this->contact = $invitation->contact;
$this->disk = $disk ?? config('filesystems.default');
}
public function handle()
{
- MultiDB::setDB($this->company->db);
-
- $settings = $this->quote->client->getMergedSettings();
-
$this->quote->load('client');
- if (!$this->contact) {
- $this->contact = $this->quote->client->primary_contact()->first();
- }
-
App::setLocale($this->contact->preferredLocale());
$path = $this->quote->client->quote_filepath();
@@ -82,20 +79,12 @@ class CreateQuotePdf implements ShouldQueue
//todo - move this to the client creation stage so we don't keep hitting this unnecessarily
Storage::makeDirectory($path, 0755);
-
- $quote_number = $this->quote->number;
- //$start = microtime(true);
-
- $design_body = $designer->build()->getHtml();
-
- $html = $this->generateEntityHtml($designer, $this->quote, $this->contact);
+ $html = (new HtmlEngine($designer, $this->invitation, 'quote'))->build();
$pdf = $this->makePdf(null, null, $html);
- //\Log::error("PDF Build time = ". (microtime(true) - $start));
-
- $file_path = $path . $quote_number . '.pdf';
+ $file_path = $path . $this->quote->number . '.pdf';
$instance = Storage::disk($this->disk)->put($file_path, $pdf);
diff --git a/app/Jobs/Util/UploadFile.php b/app/Jobs/Util/UploadFile.php
index 536dd94cab3a..6fe1fe728ad7 100644
--- a/app/Jobs/Util/UploadFile.php
+++ b/app/Jobs/Util/UploadFile.php
@@ -47,7 +47,7 @@ class UploadFile implements ShouldQueue
public $entity;
- public function __construct($file, $type, $user, $company, $entity, $disk = 'public')
+ public function __construct($file, $type, $user, $company, $entity, $disk = null)
{
$this->file = $file;
$this->type = $type;
diff --git a/app/Listeners/Document/DeleteCompanyDocuments.php b/app/Listeners/Document/DeleteCompanyDocuments.php
index 4dedb47e4c3f..e8c4d701bace 100644
--- a/app/Listeners/Document/DeleteCompanyDocuments.php
+++ b/app/Listeners/Document/DeleteCompanyDocuments.php
@@ -34,8 +34,8 @@ class DeleteCompanyDocuments
// Remove all files & folders, under company's path.
// This will delete directory itself, as well.
// In case we want to remove the content of folder, we should use $fs->cleanDirectory();
- $filesystem = new Filesystem();
- $filesystem->deleteDirectory($path);
+ //$filesystem = new Filesystem();
+ Storage::deleteDirectory($event->company->company_key);
Document::whereCompanyId($event->company->id)->delete();
}
diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php
index 78aee6af8415..1fc6d528af6c 100644
--- a/app/Mail/TemplateEmail.php
+++ b/app/Mail/TemplateEmail.php
@@ -57,6 +57,7 @@ class TemplateEmail extends Mailable
'view_link' => $this->build_email->getViewLink(),
'view_text' => $this->build_email->getViewText(),
'title' => $this->build_email->getSubject(),
+ 'signature' => $settings->email_signature,
'settings' => $settings,
'company' => $company
]);
diff --git a/app/Models/Credit.php b/app/Models/Credit.php
index 9ba26acd7337..609a03b7aa8a 100644
--- a/app/Models/Credit.php
+++ b/app/Models/Credit.php
@@ -11,6 +11,7 @@
namespace App\Models;
+use App\Events\Credit\CreditWasUpdated;
use App\Helpers\Invoice\InvoiceSum;
use App\Helpers\Invoice\InvoiceSumInclusive;
use App\Jobs\Credit\CreateCreditPdf;
@@ -218,15 +219,18 @@ class Credit extends BaseModel
public function pdf_file_path($invitation = null)
{
- $storage_path = 'storage/' . $this->client->credit_filepath() . $this->number . '.pdf';
- if (Storage::exists($storage_path)) {
+ $storage_path = Storage::url($this->client->credit_filepath() . $this->number . '.pdf');
+
+ if (Storage::exists($this->client->credit_filepath() . $this->number . '.pdf')) {
return $storage_path;
}
if (!$invitation) {
+ event(new CreditWasUpdated($this, $this->company));
CreateCreditPdf::dispatchNow($this, $this->company, $this->client->primary_contact()->first());
} else {
+ event(new CreditWasUpdated($this, $this->company));
CreateCreditPdf::dispatchNow($invitation->credit, $invitation->company, $invitation->contact);
}
diff --git a/app/Models/CreditInvitation.php b/app/Models/CreditInvitation.php
index cc76d7e673dd..139a5b9a4000 100644
--- a/app/Models/CreditInvitation.php
+++ b/app/Models/CreditInvitation.php
@@ -11,12 +11,15 @@
namespace App\Models;
+use App\Events\Credit\CreditWasUpdated;
+use App\Jobs\Credit\CreateCreditPdf;
use App\Models\Invoice;
use App\Utils\Traits\Inviteable;
use App\Utils\Traits\MakesDates;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Storage;
class CreditInvitation extends BaseModel
{
@@ -112,4 +115,16 @@ class CreditInvitation extends BaseModel
$this->viewed_date = Carbon::now();
$this->save();
}
+
+ public function pdf_file_path()
+ {
+ $storage_path = Storage::url($this->credit->client->quote_filepath() . $this->credit->number . '.pdf');
+
+ if (!Storage::exists($this->credit->client->credit_filepath() . $this->credit->number . '.pdf')) {
+ event(new CreditWasUpdated($this, $this->company));
+ CreateCreditPdf::dispatchNow($this);
+ }
+
+ return $storage_path;
+ }
}
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index e0df9f8fc964..40a2a200062e 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -195,6 +195,16 @@ class Invoice extends BaseModel
return $this->morphMany(CompanyLedger::class, 'company_ledgerable');
}
+ public function activities()
+ {
+ return $this->hasMany(Activity::class);
+ }
+
+ public function history()
+ {
+ $this->activities->with('backup');
+ }
+
// public function credits()
// {
// return $this->belongsToMany(Credit::class)->using(Paymentable::class)->withPivot(
@@ -356,21 +366,6 @@ class Invoice extends BaseModel
}
}
- /**
- * Returns the template for the invoice
- *
- * @return string Either the template view, OR the template HTML string
- * @todo this needs attention, invoice->settings needs clarification
- */
- public function design(): string
- {
- if ($this->client->getSetting('design')) {
- return File::exists(resource_path($this->client->getSetting('design'))) ? File::get(resource_path($this->client->getSetting('design'))) : File::get(resource_path('views/pdf/design1.blade.php'));
- } else {
- return File::get(resource_path('views/pdf/design1.blade.php'));
- }
- }
-
/**
* Access the invoice calculator object
*
@@ -389,34 +384,16 @@ class Invoice extends BaseModel
return $invoice_calc->build();
}
- /** TODO// DOCUMENT THIS FUNCTIONALITY */
- public function pdf_url()
+ public function pdf_file_path($invitation = null)
{
- // $public_path = 'storage/' . $this->client->invoice_filepath() . $this->number . '.pdf';
+ if(!$invitation)
+ $invitation = $this->invitations->first();
- // $storage_path = 'public/' . $this->client->invoice_filepath() . $this->number . '.pdf';
+ $storage_path = Storage::url($this->client->invoice_filepath() . $this->number . '.pdf');
- $public_path = $this->client->invoice_filepath() . $this->number . '.pdf';
-
- $storage_path = 'storage/' . $this->client->invoice_filepath() . $this->number . '.pdf';
-
- $disk = config('filesystems.default');
-
- if (!Storage::disk($disk)->exists($public_path)) {
+ if (!Storage::exists($this->client->invoice_filepath() . $this->number . '.pdf')) {
event(new InvoiceWasUpdated($this, $this->company));
- CreateInvoicePdf::dispatch($this, $this->company, $this->client->primary_contact()->first());
- }
-
- return $storage_path;
- }
-
- public function pdf_file_path()
- {
- $storage_path = 'storage/' . $this->client->invoice_filepath() . $this->number . '.pdf';
-
-
- if (!Storage::exists($storage_path)) {
- CreateInvoicePdf::dispatchNow($this, $this->company, $this->client->primary_contact()->first());
+ CreateInvoicePdf::dispatchNow($invitation);
}
return $storage_path;
diff --git a/app/Models/InvoiceInvitation.php b/app/Models/InvoiceInvitation.php
index 5906d588c00f..2fc0e1a99283 100644
--- a/app/Models/InvoiceInvitation.php
+++ b/app/Models/InvoiceInvitation.php
@@ -11,12 +11,14 @@
namespace App\Models;
+use App\Events\Invoice\InvoiceWasUpdated;
+use App\Jobs\Invoice\CreateInvoicePdf;
use App\Models\Invoice;
use App\Utils\Traits\Inviteable;
use App\Utils\Traits\MakesDates;
-
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Storage;
class InvoiceInvitation extends BaseModel
{
@@ -122,4 +124,17 @@ class InvoiceInvitation extends BaseModel
$this->viewed_date = Carbon::now();
$this->save();
}
+
+ public function pdf_file_path()
+ {
+ $storage_path = Storage::url($this->invoice->client->invoice_filepath() . $this->invoice->number . '.pdf');
+
+ if (!Storage::exists($this->invoice->client->invoice_filepath() . $this->invoice->number . '.pdf')) {
+ event(new InvoiceWasUpdated($this->invoice, $this->company));
+ CreateInvoicePdf::dispatchNow($this);
+ }
+
+ return $storage_path;
+ }
+
}
diff --git a/app/Models/Quote.php b/app/Models/Quote.php
index 86fb9a6c422a..49d4ae481971 100644
--- a/app/Models/Quote.php
+++ b/app/Models/Quote.php
@@ -11,6 +11,7 @@
namespace App\Models;
+use App\Events\Quote\QuoteWasUpdated;
use App\Helpers\Invoice\InvoiceSum;
use App\Helpers\Invoice\InvoiceSumInclusive;
use App\Jobs\Invoice\CreateInvoicePdf;
@@ -177,17 +178,18 @@ class Quote extends BaseModel
public function pdf_file_path($invitation = null)
{
- $storage_path = 'storage/' . $this->client->quote_filepath() . $this->number . '.pdf';
+ if(!$invitation)
+ $invitation = $this->invitations->where('client_contact_id', $this->client->primary_contact()->first()->id)->first();
- if (Storage::exists($storage_path)) {
+ $storage_path = Storage::url($this->client->quote_filepath() . $this->number . '.pdf');
+
+ if (Storage::exists($this->client->quote_filepath() . $this->number . '.pdf')) {
return $storage_path;
}
- if (!$invitation) {
- CreateQuotePdf::dispatchNow($this, $this->company, $this->client->primary_contact()->first());
- } else {
- CreateQuotePdf::dispatchNow($invitation->quote, $invitation->company, $invitation->contact);
- }
+ event(new QuoteWasUpdated($this, $this->company));
+
+ CreateQuotePdf::dispatchNow($invitation);
return $storage_path;
}
diff --git a/app/Models/QuoteInvitation.php b/app/Models/QuoteInvitation.php
index 5180524a92c9..b456297d7250 100644
--- a/app/Models/QuoteInvitation.php
+++ b/app/Models/QuoteInvitation.php
@@ -11,11 +11,14 @@
namespace App\Models;
+use App\Events\Quote\QuoteWasUpdated;
+use App\Jobs\Quote\CreateQuotePdf;
use App\Models\Quote;
use App\Utils\Traits\Inviteable;
use App\Utils\Traits\MakesDates;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Storage;
class QuoteInvitation extends BaseModel
{
@@ -110,4 +113,16 @@ class QuoteInvitation extends BaseModel
$this->viewed_date = Carbon::now();
$this->save();
}
+
+ public function pdf_file_path()
+ {
+ $storage_path = Storage::url($this->quote->client->quote_filepath() . $this->quote->number . '.pdf');
+
+ if (!Storage::exists($this->quote->client->quote_filepath() . $this->quote->number . '.pdf')) {
+ event(new QuoteWasUpdated($this, $this->company));
+ CreateQuotePdf::dispatchNow($this);
+ }
+
+ return $storage_path;
+ }
}
diff --git a/app/Notifications/BaseNotification.php b/app/Notifications/BaseNotification.php
index a66bb03b05ef..1a7f2f30c624 100644
--- a/app/Notifications/BaseNotification.php
+++ b/app/Notifications/BaseNotification.php
@@ -2,6 +2,7 @@
namespace App\Notifications;
+use App\Utils\TempFile;
use App\Utils\Traits\MakesInvoiceHtml;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -74,11 +75,11 @@ class BaseNotification extends Notification implements ShouldQueue
}
if ($this->settings->pdf_email_attachment) {
- $mail_message->attach(public_path($this->entity->pdf_file_path()));
+ $mail_message->attach(TempFile::path($this->invitation->pdf_file_path()), ['as' => basename($this->invitation->pdf_file_path())]);
}
foreach ($this->entity->documents as $document) {
- $mail_message->attach($document->generateUrl(), ['as' => $document->name]);
+ $mail_message->attach(TempFile::path($document->generateUrl()), ['as' => $document->name]);
}
if ($this->entity instanceof Invoice && $this->settings->ubl_email_attachment) {
@@ -98,7 +99,6 @@ class BaseNotification extends Notification implements ShouldQueue
if ($design_style == 'custom') {
$email_style_custom = $this->settings->email_style_custom;
- //$body = str_replace("$body", $body, $email_style_custom);
$body = strtr($email_style_custom, "$body", $body);
}
@@ -109,11 +109,13 @@ class BaseNotification extends Notification implements ShouldQueue
'title' => '',
'settings' => '',
'company' => '',
+ 'view_link' => $this->invitation->getLink(),
+ 'view_text' => ctrans('texts.view_'.$this->entity_string),
'logo' => $this->entity->company->present()->logo(),
- 'signature' => '',
+ 'signature' => $this->settings->email_signature,
];
return $data;
}
-}
+}
\ No newline at end of file
diff --git a/app/Notifications/SendGenericNotification.php b/app/Notifications/SendGenericNotification.php
index e2e4cc353f1e..0deab68d3199 100644
--- a/app/Notifications/SendGenericNotification.php
+++ b/app/Notifications/SendGenericNotification.php
@@ -50,6 +50,8 @@ class SendGenericNotification extends BaseNotification implements ShouldQueue
$this->settings = $this->entity->client->getMergedSettings();
$this->subject = $subject;
$this->body = $body;
+ $this->invitation = $invitation;
+ $this->entity_string = $entity_string;
}
/**
diff --git a/app/Services/Invoice/GetInvoicePdf.php b/app/Services/Invoice/GetInvoicePdf.php
index 3e8a7a790fe1..c6c4354636aa 100644
--- a/app/Services/Invoice/GetInvoicePdf.php
+++ b/app/Services/Invoice/GetInvoicePdf.php
@@ -32,6 +32,8 @@ class GetInvoicePdf extends AbstractService
$this->contact = $this->invoice->client->primary_contact()->first();
}
+ $invitation = $this->invoice->invitations->where('client_contact_id', $this->contact->id)->first();
+
$path = $this->invoice->client->invoice_filepath();
$file_path = $path . $this->invoice->number . '.pdf';
@@ -41,11 +43,9 @@ class GetInvoicePdf extends AbstractService
$file = Storage::disk($disk)->exists($file_path);
if (!$file) {
- $file_path = CreateInvoicePdf::dispatchNow($this->invoice, $this->invoice->company, $this->contact);
+ $file_path = CreateInvoicePdf::dispatchNow($invitation);
}
- //return $file_path;
-
return Storage::disk($disk)->path($file_path);
}
}
diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php
index e7e49754f990..054a93b317c9 100644
--- a/app/Services/Invoice/InvoiceService.php
+++ b/app/Services/Invoice/InvoiceService.php
@@ -105,9 +105,7 @@ class InvoiceService
public function getInvoicePdf($contact)
{
- $get_invoice_pdf = new GetInvoicePdf($this->invoice, $contact);
-
- return $get_invoice_pdf->run();
+ return (new GetInvoicePdf($this->invoice, $contact))->run();
}
public function sendEmail($contact)
diff --git a/app/Services/Quote/MarkSent.php b/app/Services/Quote/MarkSent.php
index 5010cdd3a988..09976a019cb3 100644
--- a/app/Services/Quote/MarkSent.php
+++ b/app/Services/Quote/MarkSent.php
@@ -22,7 +22,7 @@ class MarkSent
/* Return immediately if status is not draft */
if ($this->quote->status_id != Quote::STATUS_DRAFT) {
- return $quote;
+ return $this->quote;
}
$this->quote->markInvitationsSent();
diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php
new file mode 100644
index 000000000000..7dee190e9e89
--- /dev/null
+++ b/app/Utils/HtmlEngine.php
@@ -0,0 +1,603 @@
+designer = $designer;
+
+ $this->invitation = $invitation;
+
+ $this->entity = $invitation->{$entity_string};
+
+ $this->company = $invitation->company;
+
+ $this->contact = $invitation->contact;
+
+ $this->client = $this->entity->client;
+
+ $this->settings = $this->client->getMergedSettings();
+
+ $this->entity_calc = $this->entity->calc();
+
+ $this->entity_string = $entity_string;
+ }
+
+ public function build() :string
+ {
+
+ App::setLocale($this->client->preferredLocale());
+
+ $values_and_labels = $this->generateLabelsAndValues();
+
+ $this->designer->build();
+
+ $data = [];
+ $data['entity'] = $this->entity;
+ $data['lang'] = $this->client->preferredLocale();
+ $data['includes'] = $this->designer->getIncludes();
+ $data['header'] = $this->designer->getHeader();
+ $data['body'] = $this->designer->getBody();
+ $data['footer'] = $this->designer->getFooter();
+
+ $html = view('pdf.stub', $data)->render();
+
+ $html = $this->parseLabelsAndValues($values_and_labels['labels'], $values_and_labels['values'], $html);
+
+ return $html;
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ private function buildEntityDataArray() :array
+ {
+ if (!$this->client->currency()) {
+ throw new \Exception(debug_backtrace()[1]['function'], 1);
+ exit;
+ }
+
+ $data = [];
+ $data['$tax'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$app_url'] = ['value' => $this->generateAppUrl(), 'label' => ''];
+ $data['$from'] = ['value' => '', 'label' => ctrans('texts.from')];
+ $data['$to'] = ['value' => '', 'label' => ctrans('texts.to')];
+ $data['$total_tax_labels'] = ['value' => $this->totalTaxLabels(), 'label' => ctrans('texts.taxes')];
+ $data['$total_tax_values'] = ['value' => $this->totalTaxValues(), 'label' => ctrans('texts.taxes')];
+ $data['$line_tax_labels'] = ['value' => $this->lineTaxLabels(), 'label' => ctrans('texts.taxes')];
+ $data['$line_tax_values'] = ['value' => $this->lineTaxValues(), 'label' => ctrans('texts.taxes')];
+ $data['$date'] = ['value' => $this->entity->date ?: ' ', 'label' => ctrans('texts.date')];
+ //$data['$invoice_date'] = ['value' => $this->date ?: ' ', 'label' => ctrans('texts.invoice_date')];
+ $data['$invoice.date'] = &$data['$date'];
+ $data['$invoice.due_date'] = ['value' => $this->entity->due_date ?: ' ', 'label' => ctrans('texts.due_date')];
+ $data['$due_date'] = &$data['$invoice.due_date'];
+ $data['$invoice.number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')];
+ $data['$invoice.po_number'] = ['value' => $this->entity->po_number ?: ' ', 'label' => ctrans('texts.po_number')];
+ $data['$line_taxes'] = ['value' => $this->makeLineTaxes() ?: ' ', 'label' => ctrans('texts.taxes')];
+ $data['$invoice.line_taxes'] = &$data['$line_taxes'];
+ $data['$total_taxes'] = ['value' => $this->makeTotalTaxes() ?: ' ', 'label' => ctrans('texts.taxes')];
+ $data['$invoice.total_taxes'] = &$data['$total_taxes'];
+
+ if ($this->entity_string == 'invoice') {
+ $data['$entity_label'] = ['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')];
+ $data['$terms'] = &$data['$entity.terms'];
+ }
+
+ if ($this->entity_string == 'quote') {
+ $data['$entity_label'] = ['value' => '', 'label' => ctrans('texts.quote')];
+ $data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.quote_number')];
+ $data['$entity.terms'] = ['value' => $this->entity->terms ?: ' ', 'label' => ctrans('texts.quote_terms')];
+ $data['$terms'] = &$data['$entity.terms'];
+ }
+
+ if ($this->entity_string == 'credit') {
+ $data['$entity_label'] = ['value' => '', 'label' => ctrans('texts.credit')];
+ $data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.credit_number')];
+ $data['$entity.terms'] = ['value' => $this->entity->terms ?: ' ', 'label' => ctrans('texts.credit_terms')];
+ $data['$terms'] = &$data['$entity.terms'];
+ }
+
+ $data['$entity_number'] = &$data['$number'];
+
+ //$data['$paid_to_date'] = ;
+ $data['$invoice.discount'] = ['value' => Number::formatMoney($this->entity_calc->getTotalDiscount(), $this->client) ?: ' ', 'label' => ctrans('texts.discount')];
+ $data['$discount'] = &$data['$invoice.discount'];
+ $data['$subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getSubTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.subtotal')];
+ $data['$invoice.subtotal'] = &$data['$subtotal'];
+ $data['$invoice.balance_due'] = ['value' => Number::formatMoney($this->entity->balance, $this->client) ?: ' ', 'label' => ctrans('texts.balance_due')];
+ $data['$quote.balance_due'] = &$data['$invoice.balance_due'];
+ $data['$balance_due'] = &$data['$invoice.balance_due'];
+ $data['$invoice.partial_due'] = ['value' => Number::formatMoney($this->entity->partial, $this->client) ?: ' ', 'label' => ctrans('texts.partial_due')];
+ $data['$total'] = ['value' => Number::formatMoney($this->entity_calc->getTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.total')];
+ $data['$amount'] = &$data['$total'];
+ $data['$quote.total'] = &$data['$total'];
+ $data['$invoice.total'] = ['value' => Number::formatMoney($this->entity_calc->getTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.invoice_total')];
+ $data['$invoice.amount'] = &$data['$total'];
+ $data['$quote.amount'] = ['value' => Number::formatMoney($this->entity_calc->getTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.quote_total')];
+ $data['$credit.total'] = ['value' => Number::formatMoney($this->entity_calc->getTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.credit_total')];
+ $data['$credit.number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.credit_number')];
+ $data['$credit.amount'] = &$data['$credit.total'];
+ $data['$credit.po_number'] = &$data['$invoice.po_number'];
+ $data['$credit.date'] = ['value' => $this->entity->date, 'label' => ctrans('texts.credit_date')];
+ $data['$balance'] = ['value' => Number::formatMoney($this->entity_calc->getBalance(), $this->client) ?: ' ', 'label' => ctrans('texts.balance')];
+ $data['$credit.balance'] = &$data['$balance'];
+
+ $data['$invoice.balance'] = &$data['$balance'];
+ $data['$taxes'] = ['value' => Number::formatMoney($this->entity_calc->getItemTotalTaxes(), $this->client) ?: ' ', 'label' => ctrans('texts.taxes')];
+ $data['$invoice.taxes'] = &$data['$taxes'];
+
+ $data['$invoice.custom1'] = ['value' => $this->entity->custom_value1 ?: ' ', 'label' => $this->makeCustomField('invoice1')];
+ $data['$invoice.custom2'] = ['value' => $this->entity->custom_value2 ?: ' ', 'label' => $this->makeCustomField('invoice2')];
+ $data['$invoice.custom3'] = ['value' => $this->entity->custom_value3 ?: ' ', 'label' => $this->makeCustomField('invoice3')];
+ $data['$invoice.custom4'] = ['value' => $this->entity->custom_value4 ?: ' ', 'label' => $this->makeCustomField('invoice4')];
+ $data['$invoice.public_notes'] = ['value' => $this->entity->public_notes ?: ' ', 'label' => ctrans('texts.public_notes')];
+ $data['$entity.public_notes'] = &$data['$invoice.public_notes'];
+
+ // $data['$your_invoice'] = ;
+ // $data['$quote'] = ;
+ // $data['$your_quote'] = ;
+ //
+ $data['$quote.date'] = ['value' => $this->entity->date ?: ' ', 'label' => ctrans('texts.quote_date')];
+ $data['$quote.number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.quote_number')];
+ $data['$quote.po_number'] = &$data['$invoice.po_number'];
+ $data['$quote.quote_number'] = &$data['$quote.number'];
+ $data['$quote_no'] = &$data['$quote.number'];
+ $data['$quote.quote_no'] = &$data['$quote.number'];
+ $data['$quote.valid_until'] = ['value' => $this->entity->due_date, 'label' => ctrans('texts.valid_until')];
+ $data['$credit_amount'] = ['value' => Number::formatMoney($this->entity_calc->getTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.credit_amount')];
+ $data['$credit_balance'] = ['value' => Number::formatMoney($this->entity->balance, $this->client) ?: ' ', 'label' => ctrans('texts.credit_balance')];
+ ;
+ $data['$credit_number'] = &$data['$number'];
+ $data['$credit_no'] = &$data['$number'];
+ $data['$credit.credit_no'] = &$data['$number'];
+
+ // $data['$invoice_issued_to'] = ;
+ // $data['$quote_issued_to'] = ;
+ // $data['$rate'] = ;
+ // $data['$hours'] = ;
+ // $data['$from'] = ;
+ // $data['$to'] = ;
+ // $data['$invoice_to'] = ;
+ // $data['$quote_to'] = ;
+ // $data['$details'] = ;
+ $data['$invoice_no'] = &$data['$number'];
+ $data['$invoice.invoice_no'] = &$data['$number'];
+ $data['$client1'] = ['value' => $this->client->custom_value1 ?: ' ', 'label' => $this->makeCustomField('client1')];
+ $data['$client2'] = ['value' => $this->client->custom_value2 ?: ' ', 'label' => $this->makeCustomField('client2')];
+ $data['$client3'] = ['value' => $this->client->custom_value3 ?: ' ', 'label' => $this->makeCustomField('client3')];
+ $data['$client4'] = ['value' => $this->client->custom_value4 ?: ' ', 'label' => $this->makeCustomField('client4')];
+ $data['$address1'] = ['value' => $this->client->address1 ?: ' ', 'label' => ctrans('texts.address1')];
+ $data['$address2'] = ['value' => $this->client->address2 ?: ' ', 'label' => ctrans('texts.address2')];
+ $data['$id_number'] = ['value' => $this->client->id_number ?: ' ', 'label' => ctrans('texts.id_number')];
+ $data['$vat_number'] = ['value' => $this->client->vat_number ?: ' ', 'label' => ctrans('texts.vat_number')];
+ $data['$website'] = ['value' => $this->client->present()->website() ?: ' ', 'label' => ctrans('texts.website')];
+ $data['$phone'] = ['value' => $this->client->present()->phone() ?: ' ', 'label' => ctrans('texts.phone')];
+ $data['$country'] = ['value' => isset($this->client->country->name) ? $this->client->country->name : 'No Country Set', 'label' => ctrans('texts.country')];
+ $data['$email'] = ['value' => isset($this->contact) ? $this->contact->email : 'no contact email on record', 'label' => ctrans('texts.email')];
+ $data['$client_name'] = ['value' => $this->entity->present()->clientName() ?: ' ', 'label' => ctrans('texts.client_name')];
+ $data['$client.name'] = &$data['$client_name'];
+ $data['$client.address1'] = &$data['$address1'];
+ $data['$client.address2'] = &$data['$address2'];
+ $data['$client_address'] = ['value' => $this->entity->present()->address() ?: ' ', 'label' => ctrans('texts.address')];
+ $data['$client.address'] = &$data['$client_address'];
+ $data['$client.id_number'] = &$data['$id_number'];
+ $data['$client.vat_number'] = &$data['$vat_number'];
+ $data['$client.website'] = &$data['$website'];
+ $data['$client.phone'] = &$data['$phone'];
+ $data['$city_state_postal'] = ['value' => $this->entity->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, false) ?: ' ', 'label' => ctrans('texts.city_state_postal')];
+ $data['$client.city_state_postal'] = &$data['$city_state_postal'];
+ $data['$postal_city_state'] = ['value' => $this->entity->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, true) ?: ' ', 'label' => ctrans('texts.postal_city_state')];
+ $data['$client.postal_city_state'] = &$data['$postal_city_state'];
+ $data['$client.country'] = &$data['$country'];
+ $data['$client.email'] = &$data['$email'];
+
+
+ $data['$contact.full_name'] = ['value' => $this->contact->present()->name(), 'label' => ctrans('texts.name')];
+ $data['$contact.email'] = ['value' => $this->contact->email, 'label' => ctrans('texts.email')];
+ $data['$contact.phone'] = ['value' => $this->contact->phone, 'label' => ctrans('texts.phone')];
+
+ $data['$contact.name'] = ['value' => isset($this->contact) ? $this->contact->present()->name() : 'no contact name on record', 'label' => ctrans('texts.contact_name')];
+ $data['$contact.custom1'] = ['value' => isset($this->contact) ? $this->contact->custom_value1 : ' ', 'label' => $this->makeCustomField('contact1')];
+ $data['$contact.custom2'] = ['value' => isset($this->contact) ? $this->contact->custom_value2 : ' ', 'label' => $this->makeCustomField('contact1')];
+ $data['$contact.custom3'] = ['value' => isset($this->contact) ? $this->contact->custom_value3 : ' ', 'label' => $this->makeCustomField('contact1')];
+ $data['$contact.custom4'] = ['value' => isset($this->contact) ? $this->contact->custom_value4 : ' ', 'label' => $this->makeCustomField('contact1')];
+
+ $data['$company.city_state_postal'] = ['value' => $this->company->present()->cityStateZip($this->settings->city, $this->settings->state, $this->settings->postal_code, false) ?: ' ', 'label' => ctrans('texts.city_state_postal')];
+ $data['$company.postal_city_state'] = ['value' => $this->company->present()->cityStateZip($this->settings->city, $this->settings->state, $this->settings->postal_code, true) ?: ' ', 'label' => ctrans('texts.postal_city_state')];
+ $data['$company.name'] = ['value' => $this->company->present()->name() ?: ' ', 'label' => ctrans('texts.company_name')];
+ $data['$company.address1'] = ['value' => $this->settings->address1 ?: ' ', 'label' => ctrans('texts.address1')];
+ $data['$company.address2'] = ['value' => $this->settings->address2 ?: ' ', 'label' => ctrans('texts.address2')];
+ $data['$company.city'] = ['value' => $this->settings->city ?: ' ', 'label' => ctrans('texts.city')];
+ $data['$company.state'] = ['value' => $this->settings->state ?: ' ', 'label' => ctrans('texts.state')];
+ $data['$company.postal_code'] = ['value' => $this->settings->postal_code ?: ' ', 'label' => ctrans('texts.postal_code')];
+ $data['$company.country'] = ['value' => $this->getCountryName(), 'label' => ctrans('texts.country')];
+ $data['$company.phone'] = ['value' => $this->settings->phone ?: ' ', 'label' => ctrans('texts.phone')];
+ $data['$company.email'] = ['value' => $this->settings->email ?: ' ', 'label' => ctrans('texts.email')];
+ $data['$company.vat_number'] = ['value' => $this->settings->vat_number ?: ' ', 'label' => ctrans('texts.vat_number')];
+ $data['$company.id_number'] = ['value' => $this->settings->id_number ?: ' ', 'label' => ctrans('texts.id_number')];
+ $data['$company.website'] = ['value' => $this->settings->website ?: ' ', 'label' => ctrans('texts.website')];
+ $data['$company.address'] = ['value' => $this->company->present()->address($this->settings) ?: ' ', 'label' => ctrans('texts.address')];
+
+ $logo = $this->company->present()->logo($this->settings);
+
+ $data['$company.logo'] = ['value' => "" ?: ' ', 'label' => ctrans('texts.logo')];
+ $data['$company_logo'] = &$data['$company.logo'];
+ $data['$company1'] = ['value' => $this->settings->custom_value1 ?: ' ', 'label' => $this->makeCustomField('company1')];
+ $data['$company2'] = ['value' => $this->settings->custom_value2 ?: ' ', 'label' => $this->makeCustomField('company2')];
+ $data['$company3'] = ['value' => $this->settings->custom_value3 ?: ' ', 'label' => $this->makeCustomField('company3')];
+ $data['$company4'] = ['value' => $this->settings->custom_value4 ?: ' ', 'label' => $this->makeCustomField('company4')];
+
+ $data['$product.date'] = ['value' => '', 'label' => ctrans('texts.date')];
+ $data['$product.discount'] = ['value' => '', 'label' => ctrans('texts.discount')];
+ $data['$product.product_key'] = ['value' => '', 'label' => ctrans('texts.product_key')];
+ $data['$product.notes'] = ['value' => '', 'label' => ctrans('texts.notes')];
+ $data['$product.cost'] = ['value' => '', 'label' => ctrans('texts.cost')];
+ $data['$product.quantity'] = ['value' => '', 'label' => ctrans('texts.quantity')];
+ $data['$product.tax_name1'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$product.tax'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$product.tax_name2'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$product.tax_name3'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$product.line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
+
+ $data['$task.date'] = ['value' => '', 'label' => ctrans('texts.date')];
+ $data['$task.discount'] = ['value' => '', 'label' => ctrans('texts.discount')];
+ $data['$task.product_key'] = ['value' => '', 'label' => ctrans('texts.product_key')];
+ $data['$task.notes'] = ['value' => '', 'label' => ctrans('texts.notes')];
+ $data['$task.cost'] = ['value' => '', 'label' => ctrans('texts.cost')];
+ $data['$task.quantity'] = ['value' => '', 'label' => ctrans('texts.quantity')];
+ $data['$task.tax'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$task.tax_name1'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$task.tax_name2'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$task.tax_name3'] = ['value' => '', 'label' => ctrans('texts.tax')];
+ $data['$task.line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
+ //$data['$contact.signature']
+
+ // $data['custom_label1'] = ['value' => '', 'label' => ctrans('texts.')];
+ // $data['custom_label2'] = ['value' => '', 'label' => ctrans('texts.')];
+ // $data['custom_label3'] = ['value' => '', 'label' => ctrans('texts.')];
+ // $data['custom_label4'] = ['value' => '', 'label' => ctrans('texts.')];
+ //$data['$blank'] = ;
+ //$data['$surcharge'] = ;
+ /*
+ $data['$tax_invoice'] =
+ $data['$tax_quote'] =
+ $data['$statement'] = ;
+ $data['$statement_date'] = ;
+ $data['$your_statement'] = ;
+ $data['$statement_issued_to'] = ;
+ $data['$statement_to'] = ;
+ $data['$credit_note'] = ;
+ $data['$credit_date'] = ;
+ $data['$credit_issued_to'] = ;
+ $data['$credit_to'] = ;
+ $data['$your_credit'] = ;
+ $data['$phone'] = ;
+
+ $data['$outstanding'] = ;
+ $data['$invoice_due_date'] = ;
+ $data['$quote_due_date'] = ;
+ $data['$service'] = ;
+ $data['$product_key'] = ;
+ $data['$unit_cost'] = ;
+ $data['$custom_value1'] = ;
+ $data['$custom_value2'] = ;
+ $data['$delivery_note'] = ;
+ $data['$date'] = ;
+ $data['$method'] = ;
+ $data['$payment_date'] = ;
+ $data['$reference'] = ;
+ $data['$amount'] = ;
+ $data['$amount_paid'] =;
+ */
+
+ $arrKeysLength = array_map('strlen', array_keys($data));
+ array_multisort($arrKeysLength, SORT_DESC, $data);
+
+ return $data;
+ }
+
+ private function generateLabelsAndValues()
+ {
+ $data = [];
+
+ $values = $this->buildEntityDataArray();
+
+ foreach ($values as $key => $value) {
+ $data['values'][$key] = $value['value'];
+ $data['labels'][$key.'_label'] = $value['label'];
+ }
+
+ return $data;
+ }
+
+
+ private function totalTaxLabels() :string
+ {
+ $data = '';
+
+ if (!$this->entity_calc->getTotalTaxMap()) {
+ return $data;
+ }
+
+ foreach ($this->entity_calc->getTotalTaxMap() as $tax) {
+ $data .= ''. $tax['name'] .'';
+ }
+
+ return $data;
+ }
+
+ private function totalTaxValues() :string
+ {
+ $data = '';
+
+ if (!$this->entity_calc->getTotalTaxMap()) {
+ return $data;
+ }
+
+ foreach ($this->entity_calc->getTotalTaxMap() as $tax) {
+ $data .= ''. Number::formatMoney($tax['total'], $this->client) .'';
+ }
+
+ return $data;
+ }
+
+ private function lineTaxLabels() :string
+ {
+ $tax_map = $this->entity_calc->getTaxMap();
+
+ $data = '';
+
+ foreach ($tax_map as $tax) {
+ $data .= ''. $tax['name'] .'';
+ }
+
+ return $data;
+ }
+
+ private function getCountryName() :string
+ {
+ $country = Country::find($this->settings->country_id)->first();
+
+ if($country)
+ return $country->name;
+
+
+ return ' ';
+ }
+ /**
+ * Due to the way we are compiling the blade template we
+ * have no ability to iterate, so in the case
+ * of line taxes where there are multiple rows,
+ * we use this function to format a section of rows
+ *
+ * @return string a collection of