mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-21 00:41:34 +02:00
commit
66f23abea1
@ -1 +1 @@
|
||||
5.0.40
|
||||
5.0.41
|
55
app/Console/Commands/GenerateSetupKey.php
Normal file
55
app/Console/Commands/GenerateSetupKey.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class GenerateSetupKey extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ninja:generate-setup-key';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Generate random APP_KEY value';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$randomString = base64_encode(\Illuminate\Support\Str::random(32));
|
||||
|
||||
$this->info('Success! Copy the following content into your .env or docker-compose.yml:');
|
||||
$this->warn('base64:' . $randomString);
|
||||
}
|
||||
}
|
@ -35,6 +35,8 @@ class UserWasRestored
|
||||
|
||||
public $event_vars;
|
||||
|
||||
public $fromDeleted;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
@ -42,11 +44,12 @@ class UserWasRestored
|
||||
* @param Company $company
|
||||
* @param array $event_vars
|
||||
*/
|
||||
public function __construct(User $user, Company $company, array $event_vars)
|
||||
public function __construct(User $user, bool $fromDeleted, Company $company, array $event_vars)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->company = $company;
|
||||
$this->event_vars = $event_vars;
|
||||
$this->fromDeleted = $fromDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
31
app/Helpers/Generic.php
Normal file
31
app/Helpers/Generic.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
/**
|
||||
* Simple helper function that will log into "invoiceninja.log" file
|
||||
* only when extended logging is enabled.
|
||||
*
|
||||
* @param mixed $output
|
||||
* @param array $context
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function nlog($output, $context = []): void
|
||||
{
|
||||
if (config('ninja.expanded_logging')) {
|
||||
if (gettype($output) == 'object') {
|
||||
$output = print_r($output, 1);
|
||||
}
|
||||
|
||||
\Illuminate\Support\Facades\Log::channel('invoiceninja')->info($output, $context);
|
||||
}
|
||||
}
|
@ -65,8 +65,8 @@ class BaseController extends Controller
|
||||
'company.task_statuses',
|
||||
'company.expense_categories',
|
||||
'company.documents',
|
||||
'company.users',
|
||||
//'company.users.company_user',
|
||||
//'company.users',
|
||||
'company.users.company_user',
|
||||
'company.clients.contacts.company',
|
||||
'company.clients.gateway_tokens',
|
||||
'company.clients.documents',
|
||||
|
@ -125,7 +125,7 @@ class PreviewController extends BaseController
|
||||
->design($design)
|
||||
->build();
|
||||
|
||||
if (request()->query('html') == true) {
|
||||
if (request()->query('html') == 'true') {
|
||||
return $maker->getCompiledHTML;
|
||||
}
|
||||
|
||||
@ -209,6 +209,10 @@ class PreviewController extends BaseController
|
||||
->design($design)
|
||||
->build();
|
||||
|
||||
if (request()->query('html') == 'true') {
|
||||
return $maker->getCompiledHTML();
|
||||
}
|
||||
|
||||
if (config('ninja.phantomjs_pdf_generation')) {
|
||||
return (new Phantom)->convertHtmlToPdf($maker->getCompiledHTML(true));
|
||||
}
|
||||
|
@ -221,15 +221,19 @@ class SetupController extends Controller
|
||||
return $this->testPhantom();
|
||||
}
|
||||
|
||||
$snappdf = new Snappdf();
|
||||
$pdf = new Snappdf();
|
||||
|
||||
$pdf = $snappdf
|
||||
if (config('ninja.snappdf_chromium_path')) {
|
||||
$pdf->setChromiumPath(config('ninja.snappdf_chromium_path'));
|
||||
}
|
||||
|
||||
$pdf = $pdf
|
||||
->setHtml('GENERATING PDFs WORKS! Thank you for using Invoice Ninja!')
|
||||
->generate();
|
||||
|
||||
Storage::put('public/test.pdf', $pdf);
|
||||
|
||||
return response(['url' => asset('storage/test.pdf')], 200);
|
||||
return response(['url' => asset('test.pdf')], 200);
|
||||
} catch (Exception $e) {
|
||||
info($e->getMessage());
|
||||
|
||||
|
@ -98,7 +98,7 @@ class CSVImport implements ShouldQueue
|
||||
//sort the array by key
|
||||
ksort($this->column_map);
|
||||
|
||||
info("import".ucfirst($this->entity_type));
|
||||
nlog("import".ucfirst($this->entity_type));
|
||||
$this->{"import".ucfirst($this->entity_type)}();
|
||||
|
||||
$data = [
|
||||
@ -110,7 +110,7 @@ class CSVImport implements ShouldQueue
|
||||
'settings' => $this->company->settings
|
||||
];
|
||||
|
||||
info(print_r($data, 1));
|
||||
//info(print_r($data, 1));
|
||||
|
||||
MailRouter::dispatch(new ImportCompleted($data), $this->company, auth()->user());
|
||||
}
|
||||
|
@ -110,6 +110,8 @@ class Import implements ShouldQueue
|
||||
'payment_terms',
|
||||
'tax_rates',
|
||||
'clients',
|
||||
'company_gateways',
|
||||
'client_gateway_tokens',
|
||||
'vendors',
|
||||
'projects',
|
||||
'products',
|
||||
@ -118,8 +120,6 @@ class Import implements ShouldQueue
|
||||
'recurring_invoices',
|
||||
'quotes',
|
||||
'payments',
|
||||
'company_gateways',
|
||||
'client_gateway_tokens',
|
||||
'expense_categories',
|
||||
'task_statuses',
|
||||
'expenses',
|
||||
@ -459,6 +459,24 @@ class Import implements ShouldQueue
|
||||
$saveable_contacts['contacts'] = $modified_contacts;
|
||||
|
||||
$contact_repository->save($saveable_contacts, $client);
|
||||
|
||||
//link contact ids
|
||||
$client->fresh();
|
||||
$new_contacts = $client->contacts;
|
||||
|
||||
foreach($resource['contacts'] as $key => $old_contact)
|
||||
{
|
||||
$contact_match = $new_contacts->where('contact_key', $old_contact['contact_key'])->first();
|
||||
|
||||
if($contact_match)
|
||||
{
|
||||
$this->ids['client_contacts']['client_contacts_'.$old_contact['id']] = [
|
||||
'old' => $old_contact['id'],
|
||||
'new' => $contact_match->id,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$key = "clients_{$resource['id']}";
|
||||
@ -611,6 +629,16 @@ class Import implements ShouldQueue
|
||||
|
||||
unset($modified['id']);
|
||||
|
||||
foreach($resource['invitations'] as $key => $invite)
|
||||
{
|
||||
|
||||
$resource['invitations'][$key]['client_contact_id'] = $this->transformId('client_contacts', $invite['client_contact_id']);
|
||||
$resource['invitations'][$key]['user_id'] = $modified['user_id'];
|
||||
$resource['invitations'][$key]['company_id'] = $this->company->id;
|
||||
unset($resource['invitations'][$key]['recurring_invoice_id']);
|
||||
|
||||
}
|
||||
|
||||
$invoice = $invoice_repository->save(
|
||||
$modified,
|
||||
RecurringInvoiceFactory::create($this->company->id, $modified['user_id'])
|
||||
@ -660,6 +688,18 @@ class Import implements ShouldQueue
|
||||
$modified['line_items'] = $this->cleanItems($modified['line_items']);
|
||||
|
||||
unset($modified['id']);
|
||||
|
||||
foreach($resource['invitations'] as $key => $invite)
|
||||
{
|
||||
$resource['invitations'][$key]['client_contact_id'] = $this->transformId('client_contacts', $invite['client_contact_id']);
|
||||
$resource['invitations'][$key]['user_id'] = $modified['user_id'];
|
||||
$resource['invitations'][$key]['company_id'] = $this->company->id;
|
||||
unset($resource['invitations'][$key]['invoice_id']);
|
||||
|
||||
nlog("find a match for " . $invite['client_contact_id'] . " " .$resource['invitations'][$key]['client_contact_id']);
|
||||
}
|
||||
|
||||
$modified['invitations'] = $resource['invitations'];
|
||||
|
||||
$invoice = $invoice_repository->save(
|
||||
$modified,
|
||||
@ -830,6 +870,12 @@ class Import implements ShouldQueue
|
||||
PaymentFactory::create($this->company->id, $modified['user_id'])
|
||||
);
|
||||
|
||||
if($resource['company_gateway_id'] != 'NULL' && $resource['company_gateway_id'] != NULL){
|
||||
$payment->company_gateway_id = $this->transformId('company_gateways', $resource['company_gateway_id']);
|
||||
$payment->save();
|
||||
}
|
||||
|
||||
|
||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||
|
||||
$this->ids['payments'] = [
|
||||
@ -1026,13 +1072,11 @@ class Import implements ShouldQueue
|
||||
|
||||
$company_gateway = CompanyGateway::create($modified);
|
||||
|
||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||
$key = "company_gateways_{$resource['id']}";
|
||||
|
||||
$this->ids['company_gateways'] = [
|
||||
"company_gateways_{$old_user_key}" => [
|
||||
$this->ids['company_gateways'][$key] = [
|
||||
'old' => $resource['id'],
|
||||
'new' => $company_gateway->id,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Mail\Engine;
|
||||
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
use App\Utils\Helpers;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
|
||||
@ -30,6 +31,8 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
public $company;
|
||||
|
||||
public $contact;
|
||||
|
||||
private $helpers;
|
||||
|
||||
public function __construct($payment, $contact, $template_data = null)
|
||||
{
|
||||
@ -39,6 +42,7 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
$this->contact = $contact ?: $this->client->primary_contact()->first();
|
||||
$this->settings = $this->client->getMergedSettings();
|
||||
$this->template_data = $template_data;
|
||||
$this->helpers = new Helpers();
|
||||
}
|
||||
|
||||
public function build()
|
||||
@ -106,16 +110,16 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
$data['$transaction_reference'] = ['value' => $this->payment->transaction_reference, 'label' => ctrans('texts.transaction_reference')];
|
||||
$data['$public_notes'] = ['value' => $this->payment->public_notes, 'label' => ctrans('texts.notes')];
|
||||
|
||||
$data['$payment1'] = ['value' => $this->formatCustomFieldValue('payment1', $this->payment->custom_value1) ?: ' ', 'label' => $this->makeCustomField('payment1')];
|
||||
$data['$payment2'] = ['value' => $this->formatCustomFieldValue('payment2', $this->payment->custom_value2) ?: ' ', 'label' => $this->makeCustomField('payment2')];
|
||||
$data['$payment3'] = ['value' => $this->formatCustomFieldValue('payment3', $this->payment->custom_value3) ?: ' ', 'label' => $this->makeCustomField('payment3')];
|
||||
$data['$payment4'] = ['value' => $this->formatCustomFieldValue('payment4', $this->payment->custom_value4) ?: ' ', 'label' => $this->makeCustomField('payment4')];
|
||||
$data['$payment1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'payment1', $this->payment->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'payment1')];
|
||||
$data['$payment2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'payment2', $this->payment->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'payment2')];
|
||||
$data['$payment3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'payment3', $this->payment->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'payment3')];
|
||||
$data['$payment4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'payment4', $this->payment->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'payment4')];
|
||||
// $data['$type'] = ['value' => $this->payment->type->name ?: '', 'label' => ctrans('texts.payment_type')];
|
||||
|
||||
$data['$client1'] = ['value' => $this->formatCustomFieldValue('client1', $this->client->custom_value1) ?: ' ', 'label' => $this->makeCustomField('client1')];
|
||||
$data['$client2'] = ['value' => $this->formatCustomFieldValue('client2', $this->client->custom_value2) ?: ' ', 'label' => $this->makeCustomField('client2')];
|
||||
$data['$client3'] = ['value' => $this->formatCustomFieldValue('client3', $this->client->custom_value3) ?: ' ', 'label' => $this->makeCustomField('client3')];
|
||||
$data['$client4'] = ['value' => $this->formatCustomFieldValue('client4', $this->client->custom_value4) ?: ' ', 'label' => $this->makeCustomField('client4')];
|
||||
$data['$client1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client1', $this->client->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'client1')];
|
||||
$data['$client2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client2', $this->client->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'client2')];
|
||||
$data['$client3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client3', $this->client->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'client3')];
|
||||
$data['$client4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client4', $this->client->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, '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')];
|
||||
@ -153,10 +157,10 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
$data['$contact.name'] = ['value' => isset($this->contact) ? $this->contact->present()->name() : 'no contact name on record', 'label' => ctrans('texts.contact_name')];
|
||||
$data['$contact.first_name'] = ['value' => isset($this->contact) ? $this->contact->first_name : '', 'label' => ctrans('texts.first_name')];
|
||||
$data['$contact.last_name'] = ['value' => isset($this->contact) ? $this->contact->last_name : '', 'label' => ctrans('texts.last_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['$contact.custom1'] = ['value' => isset($this->contact) ? $this->contact->custom_value1 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact1')];
|
||||
$data['$contact.custom2'] = ['value' => isset($this->contact) ? $this->contact->custom_value2 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact1')];
|
||||
$data['$contact.custom3'] = ['value' => isset($this->contact) ? $this->contact->custom_value3 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact1')];
|
||||
$data['$contact.custom4'] = ['value' => isset($this->contact) ? $this->contact->custom_value4 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, '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')];
|
||||
@ -178,10 +182,10 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
|
||||
$data['$company.logo'] = ['value' => $logo ?: ' ', 'label' => ctrans('texts.logo')];
|
||||
$data['$company_logo'] = &$data['$company.logo'];
|
||||
$data['$company1'] = ['value' => $this->formatCustomFieldValue('company1', $this->settings->custom_value1) ?: ' ', 'label' => $this->makeCustomField('company1')];
|
||||
$data['$company2'] = ['value' => $this->formatCustomFieldValue('company2', $this->settings->custom_value2) ?: ' ', 'label' => $this->makeCustomField('company2')];
|
||||
$data['$company3'] = ['value' => $this->formatCustomFieldValue('company3', $this->settings->custom_value3) ?: ' ', 'label' => $this->makeCustomField('company3')];
|
||||
$data['$company4'] = ['value' => $this->formatCustomFieldValue('company4', $this->settings->custom_value4) ?: ' ', 'label' => $this->makeCustomField('company4')];
|
||||
$data['$company1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company1', $this->settings->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company1')];
|
||||
$data['$company2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company2', $this->settings->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company2')];
|
||||
$data['$company3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company3', $this->settings->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company3')];
|
||||
$data['$company4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company4', $this->settings->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company4')];
|
||||
|
||||
$data['$view_link'] = ['value' => '<a href="'.$this->payment->getLink().'">'.ctrans('texts.view_payment').'</a>', 'label' => ctrans('texts.view_payment')];
|
||||
$data['$view_url'] = ['value' => $this->payment->getLink(), 'label' => ctrans('texts.view_payment')];
|
||||
@ -202,46 +206,6 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
return $invoice_list;
|
||||
}
|
||||
|
||||
private function makeCustomField($field) :string
|
||||
{
|
||||
$custom_fields = $this->company->custom_fields;
|
||||
|
||||
if ($custom_fields && property_exists($custom_fields, $field)) {
|
||||
$custom_field = $custom_fields->{$field};
|
||||
|
||||
$custom_field_parts = explode('|', $custom_field);
|
||||
|
||||
return $custom_field_parts[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function formatCustomFieldValue($field, $value) :string
|
||||
{
|
||||
$custom_fields = $this->company->custom_fields;
|
||||
$custom_field = '';
|
||||
|
||||
if ($custom_fields && property_exists($custom_fields, $field)) {
|
||||
$custom_field = $custom_fields->{$field};
|
||||
$custom_field_parts = explode('|', $custom_field);
|
||||
|
||||
if (count($custom_field_parts) >= 2) {
|
||||
$custom_field = $custom_field_parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
switch ($custom_field) {
|
||||
case 'date':
|
||||
return $this->formatDate($value, $this->client->date_format());
|
||||
break;
|
||||
|
||||
default:
|
||||
return is_null($value) ? '' : $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function makeValues() :array
|
||||
{
|
||||
$data = [];
|
||||
|
@ -191,6 +191,11 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
return $this->hasMany(CompanyUser::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function co_user()
|
||||
{
|
||||
return $this->company_user();
|
||||
}
|
||||
|
||||
public function company_user()
|
||||
{
|
||||
if (! $this->id && auth()->user()) {
|
||||
|
@ -94,6 +94,7 @@ use App\Listeners\Activity\ExpenseArchivedActivity;
|
||||
use App\Listeners\Activity\ExpenseDeletedActivity;
|
||||
use App\Listeners\Activity\ExpenseRestoredActivity;
|
||||
use App\Listeners\Activity\ExpenseUpdatedActivity;
|
||||
use App\Listeners\Activity\PaymentArchivedActivity;
|
||||
use App\Listeners\Activity\PaymentCreatedActivity;
|
||||
use App\Listeners\Activity\PaymentDeletedActivity;
|
||||
use App\Listeners\Activity\PaymentRefundedActivity;
|
||||
@ -122,8 +123,8 @@ use App\Listeners\Invoice\InvoiceArchivedActivity;
|
||||
use App\Listeners\Invoice\InvoiceCancelledActivity;
|
||||
use App\Listeners\Invoice\InvoiceDeletedActivity;
|
||||
use App\Listeners\Invoice\InvoiceEmailActivity;
|
||||
use App\Listeners\Invoice\InvoiceEmailedNotification;
|
||||
use App\Listeners\Invoice\InvoiceEmailFailedActivity;
|
||||
use App\Listeners\Invoice\InvoiceEmailedNotification;
|
||||
use App\Listeners\Invoice\InvoicePaidActivity;
|
||||
use App\Listeners\Invoice\InvoiceReminderEmailActivity;
|
||||
use App\Listeners\Invoice\InvoiceRestoredActivity;
|
||||
@ -131,8 +132,8 @@ use App\Listeners\Invoice\InvoiceReversedActivity;
|
||||
use App\Listeners\Invoice\InvoiceViewedActivity;
|
||||
use App\Listeners\Invoice\UpdateInvoiceActivity;
|
||||
use App\Listeners\Misc\InvitationViewedListener;
|
||||
use App\Listeners\Payment\PaymentEmailedActivity;
|
||||
use App\Listeners\Payment\PaymentEmailFailureActivity;
|
||||
use App\Listeners\Payment\PaymentEmailedActivity;
|
||||
use App\Listeners\Payment\PaymentNotification;
|
||||
use App\Listeners\Payment\PaymentRestoredActivity;
|
||||
use App\Listeners\Quote\QuoteApprovedActivity;
|
||||
|
@ -59,8 +59,8 @@ class ClientRepository extends BaseRepository
|
||||
}
|
||||
|
||||
$client->fill($data);
|
||||
|
||||
if (!isset($client->id_number)) {
|
||||
|
||||
if (!isset($client->id_number) || empty($client->id_number)) {
|
||||
$client->id_number = $this->getNextClientNumber($client);
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,10 @@ use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\Quote;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Repositories\BaseRepository;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\SavesDocuments;
|
||||
@ -86,10 +88,25 @@ class InvoiceMigrationRepository extends BaseRepository
|
||||
}
|
||||
}
|
||||
|
||||
InvoiceInvitation::unguard();
|
||||
RecurringInvoiceInvitation::unguard();
|
||||
|
||||
foreach($data['invitations'] as $invitation)
|
||||
{
|
||||
nlog($invitation);
|
||||
|
||||
$new_invitation = $invitation_factory_class::create($model->company_id, $model->user_id);
|
||||
$new_invitation->{$lcfirst_resource_id} = $model->id;
|
||||
$new_invitation->fill($invitation);
|
||||
$new_invitation->save();
|
||||
}
|
||||
|
||||
InvoiceInvitation::reguard();
|
||||
RecurringInvoiceInvitation::reguard();
|
||||
/*
|
||||
if (isset($data['invitations'])) {
|
||||
$invitations = collect($data['invitations']);
|
||||
|
||||
/* Get array of Keys which have been removed from the invitations array and soft delete each invitation */
|
||||
$model->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) use ($resource) {
|
||||
$this->getInvitation($invitation, $resource)->delete();
|
||||
});
|
||||
@ -114,7 +131,7 @@ class InvoiceMigrationRepository extends BaseRepository
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
$model->load('invitations');
|
||||
|
||||
/* If no invitations have been created, this is our fail safe to maintain state*/
|
||||
|
@ -310,6 +310,10 @@ class Design extends BaseDesign
|
||||
foreach ($this->context['pdf_variables']["{$type}_columns"] as $column) {
|
||||
if (array_key_exists($column, $aliases)) {
|
||||
$elements[] = ['element' => 'th', 'content' => $aliases[$column] . '_label'];
|
||||
} elseif ($column == '$product.discount' && !$this->client->company->enable_product_discount) {
|
||||
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
|
||||
} elseif ($column == '$product.quantity' && !$this->client->company->enable_product_quantity) {
|
||||
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
|
||||
} else {
|
||||
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th']];
|
||||
}
|
||||
@ -384,6 +388,10 @@ class Design extends BaseDesign
|
||||
|
||||
if ($cell == '$task.rate') {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.cost'], 'properties' => ['data-ref' => 'task_table-task.cost-td']];
|
||||
} elseif ($cell == '$product.discount' && !$this->client->company->enable_product_discount) {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.discount'], 'properties' => ['data-ref' => 'product_table-product.discount-td', 'style' => 'display: none;']];
|
||||
} elseif ($cell == '$product.quantity' && !$this->client->company->enable_product_quantity) {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.quantity'], 'properties' => ['data-ref' => 'product_table-product.quantity-td', 'style' => 'display: none;']];
|
||||
} elseif ($cell == '$task.hours') {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.quantity'], 'properties' => ['data-ref' => 'task_table-task.hours-td']];
|
||||
} elseif ($cell == '$task.description') {
|
||||
|
@ -211,7 +211,12 @@ class CompanyTransformer extends EntityTransformer
|
||||
{
|
||||
$transformer = new UserTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($company->users, $transformer, User::class);
|
||||
$users = $company->users->map(function ($user) use ($company){
|
||||
$user->company_id = $company->id;
|
||||
return $user;
|
||||
});
|
||||
|
||||
return $this->includeCollection($users, $transformer, User::class);
|
||||
}
|
||||
|
||||
public function includeCompanyGateways(Company $company)
|
||||
@ -346,4 +351,4 @@ class CompanyTransformer extends EntityTransformer
|
||||
|
||||
return $this->includeCollection($company->system_logs, $transformer, SystemLog::class);
|
||||
}
|
||||
}
|
||||
}
|
@ -40,16 +40,16 @@ class Helpers
|
||||
}
|
||||
|
||||
/**
|
||||
* A centralised way to format the custom fields content.
|
||||
* A centralised method to format the custom fields content.
|
||||
*
|
||||
* @param mixed $custom_fields
|
||||
* @param mixed|null $custom_fields
|
||||
* @param mixed $field
|
||||
* @param mixed $value
|
||||
* @param null|\App\Models\Client $client
|
||||
* @param \App\Models\Client|null $client
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function formatCustomFieldValue($custom_fields, $field, $value, ?Client $client): ?string
|
||||
public function formatCustomFieldValue($custom_fields = null, $field, $value, Client $client = null): ?string
|
||||
{
|
||||
$custom_field = '';
|
||||
|
||||
@ -64,7 +64,7 @@ class Helpers
|
||||
|
||||
switch ($custom_field) {
|
||||
case 'date':
|
||||
return $this->formatDate($value, $client->date_format());
|
||||
return is_null($client) ? $value : $this->formatDate($value, $client->date_format());
|
||||
break;
|
||||
|
||||
case 'switch':
|
||||
@ -76,4 +76,24 @@ class Helpers
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A centralised method to make custom field.
|
||||
* @param mixed|null $custom_fields
|
||||
* @param mixed $field
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function makeCustomField($custom_fields = null, $field): string
|
||||
{
|
||||
if ($custom_fields && property_exists($custom_fields, $field)) {
|
||||
$custom_field = $custom_fields->{$field};
|
||||
|
||||
$custom_field_parts = explode('|', $custom_field);
|
||||
|
||||
return $custom_field_parts[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ class HtmlEngine
|
||||
|
||||
public $entity_string;
|
||||
|
||||
private $helpers;
|
||||
|
||||
public function __construct($invitation)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
@ -58,6 +60,8 @@ class HtmlEngine
|
||||
$this->settings = $this->client->getMergedSettings();
|
||||
|
||||
$this->entity_calc = $this->entity->calc();
|
||||
|
||||
$this->helpers = new Helpers();
|
||||
}
|
||||
|
||||
|
||||
@ -179,10 +183,10 @@ class HtmlEngine
|
||||
$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->formatCustomFieldValue('invoice1', $this->entity->custom_value1) ?: ' ', 'label' => $this->makeCustomField('invoice1')];
|
||||
$data['$invoice.custom2'] = ['value' => $this->formatCustomFieldValue('invoice2', $this->entity->custom_value2) ?: ' ', 'label' => $this->makeCustomField('invoice2')];
|
||||
$data['$invoice.custom3'] = ['value' => $this->formatCustomFieldValue('invoice3', $this->entity->custom_value3) ?: ' ', 'label' => $this->makeCustomField('invoice3')];
|
||||
$data['$invoice.custom4'] = ['value' => $this->formatCustomFieldValue('invoice4', $this->entity->custom_value4) ?: ' ', 'label' => $this->makeCustomField('invoice4')];
|
||||
$data['$invoice.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice1', $this->entity->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice1')];
|
||||
$data['$invoice.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')];
|
||||
$data['$invoice.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice3', $this->entity->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice3')];
|
||||
$data['$invoice.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice4', $this->entity->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice4')];
|
||||
$data['$invoice.public_notes'] = ['value' => nl2br($this->entity->public_notes) ?: ' ', 'label' => ctrans('texts.public_notes')];
|
||||
$data['$entity.public_notes'] = &$data['$invoice.public_notes'];
|
||||
|
||||
@ -214,10 +218,10 @@ class HtmlEngine
|
||||
// $data['$details'] = ;
|
||||
$data['$invoice_no'] = &$data['$number'];
|
||||
$data['$invoice.invoice_no'] = &$data['$number'];
|
||||
$data['$client1'] = ['value' => $this->formatCustomFieldValue('client1', $this->client->custom_value1) ?: ' ', 'label' => $this->makeCustomField('client1')];
|
||||
$data['$client2'] = ['value' => $this->formatCustomFieldValue('client2', $this->client->custom_value2) ?: ' ', 'label' => $this->makeCustomField('client2')];
|
||||
$data['$client3'] = ['value' => $this->formatCustomFieldValue('client3', $this->client->custom_value3) ?: ' ', 'label' => $this->makeCustomField('client3')];
|
||||
$data['$client4'] = ['value' => $this->formatCustomFieldValue('client4', $this->client->custom_value4) ?: ' ', 'label' => $this->makeCustomField('client4')];
|
||||
$data['$client1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client1', $this->client->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'client1')];
|
||||
$data['$client2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client2', $this->client->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'client2')];
|
||||
$data['$client3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client3', $this->client->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'client3')];
|
||||
$data['$client4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'client4', $this->client->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, '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')];
|
||||
@ -259,10 +263,10 @@ class HtmlEngine
|
||||
$data['$contact.last_name'] = ['value' => isset($this->contact) ? $this->contact->last_name : '', 'label' => ctrans('texts.last_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('contact2')];
|
||||
$data['$contact.custom3'] = ['value' => isset($this->contact) ? $this->contact->custom_value3 : ' ', 'label' => $this->makeCustomField('contact3')];
|
||||
$data['$contact.custom4'] = ['value' => isset($this->contact) ? $this->contact->custom_value4 : ' ', 'label' => $this->makeCustomField('contact4')];
|
||||
$data['$contact.custom1'] = ['value' => isset($this->contact) ? $this->contact->custom_value1 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact1')];
|
||||
$data['$contact.custom2'] = ['value' => isset($this->contact) ? $this->contact->custom_value2 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact2')];
|
||||
$data['$contact.custom3'] = ['value' => isset($this->contact) ? $this->contact->custom_value3 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact3')];
|
||||
$data['$contact.custom4'] = ['value' => isset($this->contact) ? $this->contact->custom_value4 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact4')];
|
||||
|
||||
$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')];
|
||||
@ -284,15 +288,15 @@ class HtmlEngine
|
||||
|
||||
$data['$company.logo'] = ['value' => $logo ?: ' ', 'label' => ctrans('texts.logo')];
|
||||
$data['$company_logo'] = &$data['$company.logo'];
|
||||
$data['$company1'] = ['value' => $this->formatCustomFieldValue('company1', $this->settings->custom_value1) ?: ' ', 'label' => $this->makeCustomField('company1')];
|
||||
$data['$company2'] = ['value' => $this->formatCustomFieldValue('company2', $this->settings->custom_value2) ?: ' ', 'label' => $this->makeCustomField('company2')];
|
||||
$data['$company3'] = ['value' => $this->formatCustomFieldValue('company3', $this->settings->custom_value3) ?: ' ', 'label' => $this->makeCustomField('company3')];
|
||||
$data['$company4'] = ['value' => $this->formatCustomFieldValue('company4', $this->settings->custom_value4) ?: ' ', 'label' => $this->makeCustomField('company4')];
|
||||
$data['$company1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company1', $this->settings->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company1')];
|
||||
$data['$company2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company2', $this->settings->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company2')];
|
||||
$data['$company3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company3', $this->settings->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company3')];
|
||||
$data['$company4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company4', $this->settings->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company4')];
|
||||
|
||||
$data['$custom_surcharge1'] = ['value' => $this->entity->custom_surcharge1 ?: ' ', 'label' => $this->makeCustomField('custom_surcharge1')];
|
||||
$data['$custom_surcharge2'] = ['value' => $this->entity->custom_surcharge2 ?: ' ', 'label' => $this->makeCustomField('custom_surcharge2')];
|
||||
$data['$custom_surcharge3'] = ['value' => $this->entity->custom_surcharge3 ?: ' ', 'label' => $this->makeCustomField('custom_surcharge3')];
|
||||
$data['$custom_surcharge4'] = ['value' => $this->entity->custom_surcharge4 ?: ' ', 'label' => $this->makeCustomField('custom_surcharge4')];
|
||||
$data['$custom_surcharge1'] = ['value' => $this->entity->custom_surcharge1 ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'custom_surcharge1')];
|
||||
$data['$custom_surcharge2'] = ['value' => $this->entity->custom_surcharge2 ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'custom_surcharge2')];
|
||||
$data['$custom_surcharge3'] = ['value' => $this->entity->custom_surcharge3 ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'custom_surcharge3')];
|
||||
$data['$custom_surcharge4'] = ['value' => $this->entity->custom_surcharge4 ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'custom_surcharge4')];
|
||||
|
||||
$data['$product.item'] = ['value' => '', 'label' => ctrans('texts.item')];
|
||||
$data['$product.date'] = ['value' => '', 'label' => ctrans('texts.date')];
|
||||
@ -308,10 +312,10 @@ class HtmlEngine
|
||||
$data['$product.line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
|
||||
$data['$product.description'] = ['value' => '', 'label' => ctrans('texts.description')];
|
||||
$data['$product.unit_cost'] = ['value' => '', 'label' => ctrans('texts.unit_cost')];
|
||||
$data['$product.product1'] = ['value' => '', 'label' => $this->makeCustomField('product1')];
|
||||
$data['$product.product2'] = ['value' => '', 'label' => $this->makeCustomField('product2')];
|
||||
$data['$product.product3'] = ['value' => '', 'label' => $this->makeCustomField('product3')];
|
||||
$data['$product.product4'] = ['value' => '', 'label' => $this->makeCustomField('product4')];
|
||||
$data['$product.product1'] = ['value' => '', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'product1')];
|
||||
$data['$product.product2'] = ['value' => '', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'product2')];
|
||||
$data['$product.product3'] = ['value' => '', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'product3')];
|
||||
$data['$product.product4'] = ['value' => '', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'product4')];
|
||||
|
||||
$data['$task.date'] = ['value' => '', 'label' => ctrans('texts.date')];
|
||||
$data['$task.discount'] = ['value' => '', 'label' => ctrans('texts.discount')];
|
||||
@ -517,46 +521,6 @@ class HtmlEngine
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function makeCustomField($field) :string
|
||||
{
|
||||
$custom_fields = $this->company->custom_fields;
|
||||
|
||||
if ($custom_fields && property_exists($custom_fields, $field)) {
|
||||
$custom_field = $custom_fields->{$field};
|
||||
|
||||
$custom_field_parts = explode('|', $custom_field);
|
||||
|
||||
return $custom_field_parts[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function formatCustomFieldValue($field, $value) :string
|
||||
{
|
||||
$custom_fields = $this->company->custom_fields;
|
||||
$custom_field = '';
|
||||
|
||||
if ($custom_fields && property_exists($custom_fields, $field)) {
|
||||
$custom_field = $custom_fields->{$field};
|
||||
$custom_field_parts = explode('|', $custom_field);
|
||||
|
||||
if (count($custom_field_parts) >= 2) {
|
||||
$custom_field = $custom_field_parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
switch ($custom_field) {
|
||||
case 'date':
|
||||
return $this->formatDate($value, $this->client->date_format());
|
||||
break;
|
||||
|
||||
default:
|
||||
return is_null($value) ? '' : $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function makeTotalTaxes() :string
|
||||
{
|
||||
$data = '';
|
||||
|
@ -68,20 +68,6 @@ trait MakesInvoiceValues
|
||||
'company4',
|
||||
];
|
||||
|
||||
public function makeCustomField($field) :string
|
||||
{
|
||||
$custom_fields = $this->company->custom_fields;
|
||||
|
||||
if ($custom_fields && property_exists($custom_fields, $field)) {
|
||||
$custom_field = $custom_fields->{$field};
|
||||
$custom_field_parts = explode('|', $custom_field);
|
||||
|
||||
return $custom_field_parts[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function findCustomType($field)
|
||||
{
|
||||
$custom_fields = $this->company->custom_fields;
|
||||
@ -96,35 +82,6 @@ trait MakesInvoiceValues
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method produces the key /value pairs for
|
||||
* custom fields.
|
||||
*
|
||||
* We need to explode the field name and search for the |
|
||||
* we split on the pipe, the first value is the field name
|
||||
* and the second is the field _type_
|
||||
*
|
||||
* We transform the $value depending the $field type
|
||||
*
|
||||
* @param string $field The full field name
|
||||
* @param string $value The custom value
|
||||
* @return array The key value pair
|
||||
*/
|
||||
private function makeCustomFieldKeyValuePair($field, $value)
|
||||
{
|
||||
if ($this->findCustomType($field) == 'date') {
|
||||
$value = $this->formatDate($value, $this->client->date_format());
|
||||
} elseif ($this->findCustomType($field) == 'switch') {
|
||||
$value = ctrans('texts.'.$value);
|
||||
}
|
||||
|
||||
if (! $value) {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
return ['value' => $value, 'field' => $this->makeCustomField($field)];
|
||||
}
|
||||
|
||||
public function makeLabels($contact = null) :array
|
||||
{
|
||||
$data = [];
|
||||
|
@ -29,6 +29,10 @@ trait PdfMaker
|
||||
{
|
||||
$pdf = new Snappdf();
|
||||
|
||||
if (config('ninja.snappdf_chromium_path')) {
|
||||
$pdf->setChromiumPath(config('ninja.snappdf_chromium_path'));
|
||||
}
|
||||
|
||||
return $pdf
|
||||
->setHtml($html)
|
||||
->generate();
|
||||
|
@ -102,6 +102,12 @@
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": [
|
||||
"vendor/bin/snappdf download"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"vendor/bin/snappdf download"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
|
38
composer.lock
generated
38
composer.lock
generated
@ -116,16 +116,16 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.171.4",
|
||||
"version": "3.171.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "6a6b5b2e48ad18c2bfa48b7035e09d220d0e3984"
|
||||
"reference": "5587d22e63ef82ef74dffca5d47f307b84137b51"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6a6b5b2e48ad18c2bfa48b7035e09d220d0e3984",
|
||||
"reference": "6a6b5b2e48ad18c2bfa48b7035e09d220d0e3984",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5587d22e63ef82ef74dffca5d47f307b84137b51",
|
||||
"reference": "5587d22e63ef82ef74dffca5d47f307b84137b51",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -200,22 +200,22 @@
|
||||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.171.4"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.171.6"
|
||||
},
|
||||
"time": "2020-12-22T19:23:05+00:00"
|
||||
"time": "2020-12-23T19:12:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beganovich/snappdf",
|
||||
"version": "v1.0.0",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/beganovich/snappdf.git",
|
||||
"reference": "96e0e2176f01ae712ab06dad0da6d2d79f7c1832"
|
||||
"reference": "5f5e9bb17ddc9d9f16df7c20b7af35f04ffcddbd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/beganovich/snappdf/zipball/96e0e2176f01ae712ab06dad0da6d2d79f7c1832",
|
||||
"reference": "96e0e2176f01ae712ab06dad0da6d2d79f7c1832",
|
||||
"url": "https://api.github.com/repos/beganovich/snappdf/zipball/5f5e9bb17ddc9d9f16df7c20b7af35f04ffcddbd",
|
||||
"reference": "5f5e9bb17ddc9d9f16df7c20b7af35f04ffcddbd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -252,9 +252,9 @@
|
||||
"description": "Convert webpages or HTML into the PDF file using Chromium or Google Chrome.",
|
||||
"support": {
|
||||
"issues": "https://github.com/beganovich/snappdf/issues",
|
||||
"source": "https://github.com/beganovich/snappdf/tree/v1.0.0"
|
||||
"source": "https://github.com/beganovich/snappdf/tree/v1.2.0"
|
||||
},
|
||||
"time": "2020-12-21T14:55:21+00:00"
|
||||
"time": "2020-12-28T11:57:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -10619,16 +10619,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v2.17.2",
|
||||
"version": "v2.17.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
|
||||
"reference": "aaee4f3d16a996fc0b570be0c69d3b80c909c507"
|
||||
"reference": "bd32f5dd72cdfc7b53f54077f980e144bfa2f595"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/aaee4f3d16a996fc0b570be0c69d3b80c909c507",
|
||||
"reference": "aaee4f3d16a996fc0b570be0c69d3b80c909c507",
|
||||
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/bd32f5dd72cdfc7b53f54077f980e144bfa2f595",
|
||||
"reference": "bd32f5dd72cdfc7b53f54077f980e144bfa2f595",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -10654,7 +10654,7 @@
|
||||
"justinrainbow/json-schema": "^5.0",
|
||||
"keradus/cli-executor": "^1.4",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"php-coveralls/php-coveralls": "^2.4.1",
|
||||
"php-coveralls/php-coveralls": "^2.4.2",
|
||||
"php-cs-fixer/accessible-object": "^1.0",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
|
||||
@ -10711,7 +10711,7 @@
|
||||
"description": "A tool to automatically fix PHP code style",
|
||||
"support": {
|
||||
"issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.17.2"
|
||||
"source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.17.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -10719,7 +10719,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2020-12-17T16:41:55+00:00"
|
||||
"time": "2020-12-24T11:14:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
|
@ -99,6 +99,11 @@ return [
|
||||
'emergency' => [
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
],
|
||||
|
||||
'invoiceninja' => [
|
||||
'driver' => 'single',
|
||||
'path' => storage_path('logs/invoiceninja.log'),
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -12,7 +12,7 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', ''),
|
||||
'app_version' => '5.0.40',
|
||||
'app_version' => '5.0.41',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', false),
|
||||
@ -136,4 +136,6 @@ return [
|
||||
'base_path' => resource_path('views/pdf-designs/'),
|
||||
],
|
||||
'log_pdf_html' => env('LOG_PDF_HTML', false),
|
||||
'expanded_logging' => env('EXPANDED_LOGGING', false),
|
||||
'snappdf_chromium_path' => env('SNAPPDF_CHROMIUM_PATH', false),
|
||||
];
|
||||
|
4
public/flutter_service_worker.js
vendored
4
public/flutter_service_worker.js
vendored
@ -30,8 +30,8 @@ const RESOURCES = {
|
||||
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
|
||||
"assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac",
|
||||
"/": "23224b5e03519aaa87594403d54412cf",
|
||||
"version.json": "2337a2140fc2ea8baeb10b0e5a200f59",
|
||||
"main.dart.js": "cb45263da95ac53b92a95e621c5880a8",
|
||||
"version.json": "304f9dfb96375c4f92a1f5eb00536410",
|
||||
"main.dart.js": "f64e2f489dc693583352428978fbbf8f",
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b"
|
||||
};
|
||||
|
||||
|
2
public/js/clients/payments/stripe-sofort.js
vendored
2
public/js/clients/payments/stripe-sofort.js
vendored
@ -1,2 +1,2 @@
|
||||
/*! For license information please see stripe-sofort.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=6)}({6:function(e,t,n){e.exports=n("RFiP")},RFiP:function(e,t){function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}new function e(t){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),n(this,"setupStripe",(function(){return r.stripe=Stripe(r.key),r})),n(this,"handle",(function(){var e={type:"sofort",amount:document.querySelector('meta[name="amount"]').content,currency:"eur",redirect:{return_url:document.querySelector('meta[name="return-url"]').content},sofort:{country:document.querySelector('meta[name="country"').content}};document.getElementById("pay-now").addEventListener("click",(function(t){document.getElementById("pay-now").disabled=!0,document.querySelector("#pay-now > svg").classList.remove("hidden"),document.querySelector("#pay-now > span").classList.add("hidden"),r.stripe.createSource(e).then((function(e){if(e.hasOwnProperty("source"))return window.location=e.source.redirect.url;document.getElementById("pay-now").disabled=!1,document.querySelector("#pay-now > svg").classList.add("hidden"),document.querySelector("#pay-now > span").classList.remove("hidden"),this.errors.textContent="",this.errors.textContent=e.error.message,this.errors.hidden=!1,document.getElementById("pay-now").disabled=!1}))}))})),this.key=t,this.errors=document.getElementById("errors")}(document.querySelector('meta[name="stripe-publishable-key"]').content).setupStripe().handle()}});
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=6)}({6:function(e,t,n){e.exports=n("RFiP")},RFiP:function(e,t){function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}new function e(t){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),n(this,"setupStripe",(function(){return r.stripe=Stripe(r.key),r})),n(this,"handle",(function(){var e={type:"sofort",amount:document.querySelector('meta[name="amount"]').content,currency:"eur",redirect:{return_url:document.querySelector('meta[name="return-url"]').content},sofort:{country:document.querySelector('meta[name="country"]').content}};document.getElementById("pay-now").addEventListener("click",(function(t){document.getElementById("pay-now").disabled=!0,document.querySelector("#pay-now > svg").classList.remove("hidden"),document.querySelector("#pay-now > span").classList.add("hidden"),r.stripe.createSource(e).then((function(e){if(e.hasOwnProperty("source"))return window.location=e.source.redirect.url;document.getElementById("pay-now").disabled=!1,document.querySelector("#pay-now > svg").classList.add("hidden"),document.querySelector("#pay-now > span").classList.remove("hidden"),this.errors.textContent="",this.errors.textContent=e.error.message,this.errors.hidden=!1,document.getElementById("pay-now").disabled=!1}))}))})),this.key=t,this.errors=document.getElementById("errors")}(document.querySelector('meta[name="stripe-publishable-key"]').content).setupStripe().handle()}});
|
2
public/js/setup/setup.js
vendored
2
public/js/setup/setup.js
vendored
File diff suppressed because one or more lines are too long
113274
public/main.dart.js
vendored
113274
public/main.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -10,11 +10,11 @@
|
||||
"/js/clients/payments/stripe-ach.js": "/js/clients/payments/stripe-ach.js?id=c4012ad90f17d60432ad",
|
||||
"/js/clients/payments/stripe-alipay.js": "/js/clients/payments/stripe-alipay.js?id=6dbe9316b98deea55421",
|
||||
"/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=f4659d26a26d2f408397",
|
||||
"/js/clients/payments/stripe-sofort.js": "/js/clients/payments/stripe-sofort.js?id=bb7c55ca3da2d29e55d2",
|
||||
"/js/clients/payments/stripe-sofort.js": "/js/clients/payments/stripe-sofort.js?id=9b9fd56d655ad238f149",
|
||||
"/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=1b8f9325aa6e8595e7fa",
|
||||
"/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=85bcae0a646882e56b12",
|
||||
"/js/clients/shared/multiple-downloads.js": "/js/clients/shared/multiple-downloads.js?id=5c35d28cf0a3286e7c45",
|
||||
"/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=fa54bb4229aba6b0817c",
|
||||
"/js/setup/setup.js": "/js/setup/setup.js?id=b264d828086fdf87b710",
|
||||
"/js/setup/setup.js": "/js/setup/setup.js?id=29e88ab480038cba57df",
|
||||
"/css/card-js.min.css": "/css/card-js.min.css?id=62afeb675235451543ad"
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.33","build_number":"33"}
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.35","build_number":"35"}
|
32
resources/js/setup/setup.js
vendored
32
resources/js/setup/setup.js
vendored
@ -25,13 +25,18 @@ class Setup {
|
||||
handleDatabaseCheck() {
|
||||
let data = {
|
||||
db_host: document.querySelector('input[name="db_host"]').value,
|
||||
db_database: document.querySelector('input[name="db_database"]').value,
|
||||
db_username: document.querySelector('input[name="db_username"]').value,
|
||||
db_password: document.querySelector('input[name="db_password"]').value,
|
||||
db_database: document.querySelector('input[name="db_database"]')
|
||||
.value,
|
||||
db_username: document.querySelector('input[name="db_username"]')
|
||||
.value,
|
||||
db_password: document.querySelector('input[name="db_password"]')
|
||||
.value,
|
||||
};
|
||||
|
||||
Axios.post('/setup/check_db', data)
|
||||
.then((response) => this.handleSuccess(this.checkDbAlert, 'mail-wrapper'))
|
||||
.then((response) =>
|
||||
this.handleSuccess(this.checkDbAlert, 'mail-wrapper')
|
||||
)
|
||||
.catch((e) =>
|
||||
this.handleFailure(this.checkDbAlert, e.response.data.message)
|
||||
);
|
||||
@ -39,7 +44,8 @@ class Setup {
|
||||
|
||||
handleSmtpCheck() {
|
||||
let data = {
|
||||
mail_driver: document.querySelector('select[name="mail_driver"]').value,
|
||||
mail_driver: document.querySelector('select[name="mail_driver"]')
|
||||
.value,
|
||||
mail_name: document.querySelector('input[name="mail_name"]').value,
|
||||
mail_address: document.querySelector('input[name="mail_address"]')
|
||||
.value,
|
||||
@ -59,7 +65,7 @@ class Setup {
|
||||
this.handleSuccess(this.checkSmtpAlert, 'account-wrapper');
|
||||
this.handleSuccess(this.checkSmtpAlert, 'submit-wrapper');
|
||||
|
||||
return this.checkSmtpButton.disabled = false;
|
||||
return (this.checkSmtpButton.disabled = false);
|
||||
}
|
||||
|
||||
Axios.post('/setup/check_mail', data)
|
||||
@ -74,13 +80,18 @@ class Setup {
|
||||
}
|
||||
|
||||
handleTestPdfCheck() {
|
||||
this.checkPdfButton.disabled = true;
|
||||
|
||||
Axios.post('/setup/check_pdf', {})
|
||||
.then((response) => {
|
||||
try {
|
||||
let win = window.open(response.data.url, '_blank');
|
||||
win.focus();
|
||||
|
||||
return this.handleSuccess(this.checkPdfAlert, 'database-wrapper');
|
||||
return this.handleSuccess(
|
||||
this.checkPdfAlert,
|
||||
'database-wrapper'
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleSuccess(this.checkPdfAlert, 'database-wrapper');
|
||||
this.checkPdfAlert.textContent = `Success! You can preview test PDF here: ${response.data.url}`;
|
||||
@ -89,7 +100,8 @@ class Setup {
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
this.handleFailure(this.checkPdfAlert);
|
||||
});
|
||||
})
|
||||
.finally(() => (this.checkPdfButton.disabled = false));
|
||||
}
|
||||
|
||||
handleSuccess(element, nextStep = null) {
|
||||
@ -99,7 +111,9 @@ class Setup {
|
||||
|
||||
if (nextStep) {
|
||||
document.getElementById(nextStep).classList.remove('hidden');
|
||||
document.getElementById(nextStep).scrollIntoView({behavior: 'smooth', block: 'center'});
|
||||
document
|
||||
.getElementById(nextStep)
|
||||
.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ if(!isset($design)) $design = 'light';
|
||||
<div class="grid grid-cols-6">
|
||||
<div class="col-span-4 col-start-2">
|
||||
<div class="{{ $design == 'light' ? 'bg-white' : 'bg-gray-900' }} shadow border-t-2 {{ $design == 'light' ? 'border-primary' : 'border-gray-800' }}">
|
||||
<div class="px-10">
|
||||
<div class="px-10 break-all">
|
||||
{{ $header }}
|
||||
</div>
|
||||
<div id="text" class="flex flex-col px-10 py-6">
|
||||
|
@ -56,7 +56,7 @@ class ImportCsvTest extends TestCase
|
||||
|
||||
public function testInvoiceCsvImport()
|
||||
{
|
||||
$this->markTestSkipped();
|
||||
$this->markTestSkipped();
|
||||
|
||||
$csv = file_get_contents(base_path().'/tests/Feature/Import/invoice.csv');
|
||||
$hash = Str::random(32);
|
||||
@ -132,7 +132,7 @@ class ImportCsvTest extends TestCase
|
||||
|
||||
public function testProductCsvImport()
|
||||
{
|
||||
$this->markTestSkipped();
|
||||
$this->markTestSkipped();
|
||||
|
||||
|
||||
$csv = file_get_contents(base_path().'/tests/Feature/Import/products.csv');
|
||||
|
86
tests/Feature/PreviewTest.php
Normal file
86
tests/Feature/PreviewTest.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App\Http\Controllers\PreviewController
|
||||
*/
|
||||
class PreviewTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->makeTestData();
|
||||
|
||||
$this->withoutMiddleware(
|
||||
ThrottleRequests::class
|
||||
);
|
||||
}
|
||||
|
||||
public function testPreviewRoute()
|
||||
{
|
||||
$data = $this->getData();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/preview/', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testPreviewHtmlResponse()
|
||||
{
|
||||
$data = $this->getData();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/preview?html=true', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function getData()
|
||||
{
|
||||
$data =
|
||||
[
|
||||
'entity_type' => 'invoice',
|
||||
'entity_id' => '',
|
||||
'design' => [
|
||||
'name' => '',
|
||||
'design' => [
|
||||
'includes' => '</style>',
|
||||
'header' => '<div id="header"></div>',
|
||||
'body' => '<div id="body">',
|
||||
'product' => '',
|
||||
'task' => '',
|
||||
'footer' => '<div id="footer">$entity_footer</div>'
|
||||
],
|
||||
],
|
||||
'is_custom' => 1,
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
@ -8,6 +9,7 @@
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace Tests\Pdf;
|
||||
|
||||
use Beganovich\Snappdf\Snappdf;
|
||||
@ -19,16 +21,20 @@ use Tests\TestCase;
|
||||
*/
|
||||
class PdfGenerationTest extends TestCase
|
||||
{
|
||||
public function setUp() :void
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testPdfGeneration()
|
||||
{
|
||||
$snappdf = new Snappdf();
|
||||
$pdf = new Snappdf();
|
||||
|
||||
$pdf = $snappdf
|
||||
if (config('ninja.snappdf_chromium_path')) {
|
||||
$pdf->setChromiumPath(config('ninja.snappdf_chromium_path'));
|
||||
}
|
||||
|
||||
$pdf = $pdf
|
||||
->setHtml('<h1>Invoice Ninja</h1>')
|
||||
->generate();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user