diff --git a/.env.ci b/.env.ci index 87976de27699..d4b797cd2ea3 100644 --- a/.env.ci +++ b/.env.ci @@ -19,3 +19,4 @@ DB_HOST=127.0.0.1 NINJA_ENVIRONMENT=hosted COMPOSER_AUTH='{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' TRAVIS=true +API_SECRET=superdoopersecrethere diff --git a/.env.example b/.env.example index b92cf8fae044..54e388c4fee7 100644 --- a/.env.example +++ b/.env.example @@ -55,10 +55,5 @@ NINJA_ENVIRONMENT=selfhost PHANTOMJS_KEY='a-demo-key-with-low-quota-per-ip-address' PHANTOMJS_SECRET= -SELF_UPDATER_REPO_VENDOR = invoiceninja -SELF_UPDATER_REPO_NAME = invoiceninja -SELF_UPDATER_USE_BRANCH = v2 -SELF_UPDATER_MAILTO_ADDRESS = user@example.com -SELF_UPDATER_MAILTO_NAME = "John Doe" COMPOSER_AUTH='{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' SENTRY_LARAVEL_DSN=https://cc7e8e2c678041689e53e409b7dba236@sentry.invoicing.co/5 \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bcbb19f476f2..b4748d96356a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,8 +41,7 @@ jobs: - name: Cleanup Builds run: | sudo rm -rf bootstrap/cache/* - sudo rm public/index.html - + - name: Build project # This would actually build your project, using zip for an example artifact run: | zip -r ./invoiceninja.zip ./ diff --git a/VERSION.txt b/VERSION.txt index dbf3366489b1..c9c84322d739 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.0.22 +5.0.23 diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index f4a84a3c7000..7499b41d2d19 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -322,7 +322,7 @@ class CheckData extends Command $total_invoice_payments = 0; foreach ($client->invoices as $invoice) { - $total_amount = $invoice->payments->sum('pivot.amount'); + $total_amount = $invoice->payments->sum('pivot.amount'); $total_refund = $invoice->payments->sum('pivot.refunded'); $total_invoice_payments += ($total_amount - $total_refund); @@ -330,7 +330,7 @@ class CheckData extends Command foreach($client->payments as $payment) { - $credit_total_applied += $payment->paymentables->where('paymentable_type', App\Models\Credit::class)->sum(\DB::raw('amount')); + $credit_total_applied += $payment->paymentables->where('paymentable_type', App\Models\Credit::class)->sum(DB::raw('amount')); } if($credit_total_applied < 0) @@ -484,9 +484,9 @@ class CheckData extends Command } else { $company_id = 'company_id'; } - $records = \DB::table($table) + $records = DB::table($table) ->join($tableName, "{$tableName}.id", '=', "{$table}.{$field}_id") - ->where("{$table}.{$company_id}", '!=', \DB::raw("{$tableName}.company_id")) + ->where("{$table}.{$company_id}", '!=', DB::raw("{$tableName}.company_id")) ->get(["{$table}.id"]); if ($records->count()) { diff --git a/app/Console/Commands/CreateSingleAccount.php b/app/Console/Commands/CreateSingleAccount.php index c650fe2ad382..ecdcc40ea558 100644 --- a/app/Console/Commands/CreateSingleAccount.php +++ b/app/Console/Commands/CreateSingleAccount.php @@ -11,8 +11,6 @@ namespace App\Console\Commands; -use App\Console\Commands\TestData\CreateTestCreditJob; -use App\Console\Commands\TestData\CreateTestQuoteJob; use App\DataMapper\CompanySettings; use App\DataMapper\DefaultSettings; use App\Events\Invoice\InvoiceWasCreated; @@ -73,10 +71,11 @@ class CreateSingleAccount extends Command protected $count; protected $gateway; + /** * Create a new command instance. * - * @return void + * @param InvoiceRepository $invoice_repo */ public function __construct(InvoiceRepository $invoice_repo) { @@ -112,7 +111,6 @@ class CreateSingleAccount extends Command $company = Company::factory()->create([ 'account_id' => $account->id, 'slack_webhook_url' => config('ninja.notification.slack'), - 'use_credits_payment' => 'always', ]); $account->default_company_id = $company->id; @@ -242,6 +240,8 @@ class CreateSingleAccount extends Command $settings = $client->settings; $settings->currency_id = "1"; + $settings->use_credits_payment = "always"; + $client->settings = $settings; $country = Country::all()->random(); @@ -300,7 +300,7 @@ class CreateSingleAccount extends Command private function createInvoice($client) { - $faker = \Faker\Factory::create(); + $faker = Factory::create(); $invoice = InvoiceFactory::create($client->company->id, $client->user->id); //stub the company and user_id $invoice->client_id = $client->id; @@ -349,7 +349,7 @@ class CreateSingleAccount extends Command private function createCredit($client) { - $faker = \Faker\Factory::create(); + $faker = Factory::create(); $credit = Credit::factory()->create(['user_id' => $client->user->id, 'company_id' => $client->company->id, 'client_id' => $client->id]); @@ -374,7 +374,7 @@ class CreateSingleAccount extends Command private function createQuote($client) { - $faker = \Faker\Factory::create(); + $faker = Factory::create(); $quote = Quote::factory()->create(['user_id' => $client->user->id, 'company_id' => $client->company->id, 'client_id' => $client->id]); $quote->date = $faker->date(); @@ -433,7 +433,7 @@ class CreateSingleAccount extends Command $item->custom_value4 = $product->custom_value4; $line_items[] = $item; - + return $line_items; } diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php index da72449fb55e..2dab5b2dd4cd 100644 --- a/app/Console/Commands/CreateTestData.php +++ b/app/Console/Commands/CreateTestData.php @@ -11,8 +11,6 @@ namespace App\Console\Commands; -use App\Console\Commands\TestData\CreateTestCreditJob; -use App\Console\Commands\TestData\CreateTestQuoteJob; use App\DataMapper\CompanySettings; use App\DataMapper\DefaultSettings; use App\Events\Invoice\InvoiceWasCreated; @@ -72,7 +70,7 @@ class CreateTestData extends Command /** * Create a new command instance. * - * @return void + * @param InvoiceRepository $invoice_repo */ public function __construct(InvoiceRepository $invoice_repo) { @@ -474,7 +472,7 @@ class CreateTestData extends Command private function createInvoice($client) { - $faker = \Faker\Factory::create(); + $faker = Factory::create(); $invoice = InvoiceFactory::create($client->company->id, $client->user->id); //stub the company and user_id $invoice->client_id = $client->id; @@ -524,12 +522,8 @@ class CreateTestData extends Command private function createCredit($client) { - // for($x=0; $x<$this->count; $x++){ - // dispatch(new CreateTestCreditJob($client)); - - // } - $faker = \Faker\Factory::create(); + $faker = Factory::create(); $credit = Credit::factory()->create(['user_id' => $client->user->id, 'company_id' => $client->company->id, 'client_id' => $client->id]); @@ -568,11 +562,8 @@ class CreateTestData extends Command private function createQuote($client) { - // for($x=0; $x<$this->count; $x++){ - // dispatch(new CreateTestQuoteJob($client)); - // } - $faker = \Faker\Factory::create(); + $faker = Factory::create(); //$quote = QuoteFactory::create($client->company->id, $client->user->id);//stub the company and user_id $quote = Quote::factory()->create(['user_id' => $client->user->id, 'company_id' => $client->company->id, 'client_id' => $client->id]); diff --git a/app/Console/Commands/DemoMode.php b/app/Console/Commands/DemoMode.php index 8a5070a1f9bb..8e5c3881d420 100644 --- a/app/Console/Commands/DemoMode.php +++ b/app/Console/Commands/DemoMode.php @@ -57,8 +57,6 @@ class DemoMode extends Command { use MakesHash, GeneratesCounter; - private $count; - protected $name = 'ninja:demo-mode'; /** * The name and signature of the console command. @@ -266,7 +264,7 @@ class DemoMode extends Command // } $client = $company->clients->random(); - $this->createExpense($client, $u2->id); + $this->createExpense($client); //$this->info("creating expense for client #".$client->id); @@ -439,11 +437,7 @@ class DemoMode extends Command private function createCredit($client, $assigned_user_id = null) { - // for($x=0; $x<$this->count; $x++){ - // dispatch(new CreateTestCreditJob($client)); - - // } $faker = \Faker\Factory::create(); $credit = Credit::factory()->create(['user_id' => $client->user->id, 'company_id' => $client->company->id, 'client_id' => $client->id]); diff --git a/app/Console/Commands/DesignUpdate.php b/app/Console/Commands/DesignUpdate.php index e73a3eca65fc..dd234e57e4c9 100644 --- a/app/Console/Commands/DesignUpdate.php +++ b/app/Console/Commands/DesignUpdate.php @@ -13,6 +13,7 @@ namespace App\Console\Commands; use App\Models\Design; use Illuminate\Console\Command; +use stdClass; class DesignUpdate extends Command { @@ -52,7 +53,7 @@ class DesignUpdate extends Command $invoice_design = new $class(); $invoice_design->document(); - $design_object = new \stdClass; + $design_object = new stdClass; $design_object->includes = $invoice_design->getSectionHTML('style'); $design_object->header = $invoice_design->getSectionHTML('header'); $design_object->body = $invoice_design->getSectionHTML('body'); diff --git a/app/Console/Commands/ImportMigrations.php b/app/Console/Commands/ImportMigrations.php index 54d1adfa9fd0..af490e426bb8 100644 --- a/app/Console/Commands/ImportMigrations.php +++ b/app/Console/Commands/ImportMigrations.php @@ -18,7 +18,11 @@ use App\Models\Company; use App\Models\CompanyToken; use App\Models\User; use App\Utils\Traits\MakesHash; +use DirectoryIterator; +use Faker\Factory; +use Faker\Generator; use Illuminate\Console\Command; +use Illuminate\Support\Str; class ImportMigrations extends Command { @@ -38,7 +42,7 @@ class ImportMigrations extends Command protected $description = 'Massively import the migrations.'; /** - * @var \Faker\Generator + * @var Generator */ private $faker; @@ -49,7 +53,7 @@ class ImportMigrations extends Command */ public function __construct() { - $this->faker = \Faker\Factory::create(); + $this->faker = Factory::create(); parent::__construct(); } @@ -63,7 +67,7 @@ class ImportMigrations extends Command { $path = $this->option('path') ?? storage_path('migrations/import'); - $directory = new \DirectoryIterator($path); + $directory = new DirectoryIterator($path); foreach ($directory as $file) { if ($file->getExtension() === 'zip') { @@ -89,7 +93,7 @@ class ImportMigrations extends Command 'company_id' => $company->id, 'account_id' => $account->id, 'name' => 'test token', - 'token' => \Illuminate\Support\Str::random(64), + 'token' => Str::random(64), ]); $user->companies()->attach($company->id, [ diff --git a/app/Console/Commands/PostUpdate.php b/app/Console/Commands/PostUpdate.php index 37f349908dfd..a10654a3fc88 100644 --- a/app/Console/Commands/PostUpdate.php +++ b/app/Console/Commands/PostUpdate.php @@ -18,6 +18,7 @@ use Composer\Installer; use Composer\IO\NullIO; use Illuminate\Console\Command; use Illuminate\Support\Facades\Artisan; +use Log; use Symfony\Component\Console\Input\ArrayInput; class PostUpdate extends Command @@ -41,10 +42,11 @@ class PostUpdate extends Command * Execute the console command. * * @return mixed + * @throws \Exception */ public function handle() { - + set_time_limit(0); info('running post update'); @@ -52,13 +54,13 @@ class PostUpdate extends Command try { Artisan::call('migrate', ['--force' => true]); } catch (Exception $e) { - \Log::error("I wasn't able to migrate the data."); + Log::error("I wasn't able to migrate the data."); } try { Artisan::call('optimize'); } catch (Exception $e) { - \Log::error("I wasn't able to optimize."); + Log::error("I wasn't able to optimize."); } /* For the following to work, the web user (www-data) must own all the directories */ @@ -67,7 +69,7 @@ class PostUpdate extends Command $input = new ArrayInput(array('command' => 'install', '--no-dev' => 'true')); $application = new Application(); - $application->setAutoExit(false); + $application->setAutoExit(false); $application->run($input); echo "Done."; diff --git a/app/Console/Commands/SendTestEmails.php b/app/Console/Commands/SendTestEmails.php index 5890da2d04d6..0a6a2511f6c2 100644 --- a/app/Console/Commands/SendTestEmails.php +++ b/app/Console/Commands/SendTestEmails.php @@ -18,7 +18,7 @@ use App\Factory\CompanyUserFactory; use App\Factory\InvoiceFactory; use App\Factory\InvoiceInvitationFactory; use App\Helpers\Email\InvoiceEmail; -use App\Jobs\Invoice\CreateInvoicePdf; +use App\Jobs\Invoice\CreateEntityPdf; use App\Mail\TemplateEmail; use App\Models\Account; use App\Models\Client; @@ -26,6 +26,7 @@ use App\Models\ClientContact; use App\Models\Company; use App\Models\Invoice; use App\Models\User; +use Faker\Factory; use Illuminate\Console\Command; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Mail; @@ -70,7 +71,7 @@ class SendTestEmails extends Command private function sendTemplateEmails($template) { - $faker = \Faker\Factory::create(); + $faker = Factory::create(); $message = [ 'title' => 'Invoice XJ-3838', @@ -82,7 +83,7 @@ class SendTestEmails extends Command $user = User::whereEmail('user@example.com')->first(); if (! $user) { - + $account = Account::factory()->create(); $user = User::factory()->create([ @@ -149,7 +150,7 @@ class SendTestEmails extends Command $invoice->setRelation('invitations', $ii); $invoice->service()->markSent()->save(); - CreateInvoicePdf::dispatch($invoice->invitations()->first()); + CreateEntityPdf::dispatch($invoice->invitations()->first()); $cc_emails = [config('ninja.testvars.test_email')]; $bcc_emails = [config('ninja.testvars.test_email')]; diff --git a/app/Console/Commands/TestData/CreateTestCreditJob.php b/app/Console/Commands/TestData/CreateTestCreditJob.php deleted file mode 100644 index 225fc5e6f819..000000000000 --- a/app/Console/Commands/TestData/CreateTestCreditJob.php +++ /dev/null @@ -1,136 +0,0 @@ -client = $client; - } - - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - $faker = \Faker\Factory::create(); - - $credit = Credit::factory()->create(['user_id' => $this->client->user->id, 'company_id' => $this->client->company->id, 'client_id' => $this->client->id]); - - //$invoice = InvoiceFactory::create($this->client->company->id, $this->client->user->id);//stub the company and user_id - //$invoice->client_id = $this->client->id; -// $invoice->date = $faker->date(); - $dateable = Carbon::now()->subDays(rand(0, 90)); - $credit->date = $dateable; - - $credit->line_items = $this->buildLineItems(rand(1, 10)); - $credit->uses_inclusive_taxes = false; - - if (rand(0, 1)) { - $credit->tax_name1 = 'GST'; - $credit->tax_rate1 = 10.00; - } - - if (rand(0, 1)) { - $credit->tax_name2 = 'VAT'; - $credit->tax_rate2 = 17.50; - } - - if (rand(0, 1)) { - $credit->tax_name3 = 'CA Sales Tax'; - $credit->tax_rate3 = 5; - } - - $credit->save(); - - $invoice_calc = new InvoiceSum($credit); - $invoice_calc->build(); - - $credit = $invoice_calc->getCredit(); - - $credit->save(); - - event(new CreateCreditInvitation($credit, $credit->company, Ninja::eventVars())); - } - - private function buildLineItems($count = 1) - { - $line_items = []; - - for ($x = 0; $x < $count; $x++) { - $item = InvoiceItemFactory::create(); - $item->quantity = 1; - //$item->cost = 10; - - if (rand(0, 1)) { - $item->tax_name1 = 'GST'; - $item->tax_rate1 = 10.00; - } - - if (rand(0, 1)) { - $item->tax_name1 = 'VAT'; - $item->tax_rate1 = 17.50; - } - - if (rand(0, 1)) { - $item->tax_name1 = 'Sales Tax'; - $item->tax_rate1 = 5; - } - - $product = Product::all()->random(); - - $item->cost = (float) $product->cost; - $item->product_key = $product->product_key; - $item->notes = $product->notes; - $item->custom_value1 = $product->custom_value1; - $item->custom_value2 = $product->custom_value2; - $item->custom_value3 = $product->custom_value3; - $item->custom_value4 = $product->custom_value4; - - $line_items[] = $item; - } - - return $line_items; - } -} diff --git a/app/Console/Commands/TestData/CreateTestQuoteJob.php b/app/Console/Commands/TestData/CreateTestQuoteJob.php deleted file mode 100644 index 24e91e5acf92..000000000000 --- a/app/Console/Commands/TestData/CreateTestQuoteJob.php +++ /dev/null @@ -1,129 +0,0 @@ -client = $client; - } - - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - $faker = \Faker\Factory::create(); - - $quote = Quote::factory()->create(['user_id' => $this->client->user->id, 'company_id' => $this->client->company->id, 'client_id' => $this->client->id]); - $quote->date = $faker->date(); - - $quote->line_items = $this->buildLineItems(rand(1, 10)); - $quote->uses_inclusive_taxes = false; - - if (rand(0, 1)) { - $quote->tax_name1 = 'GST'; - $quote->tax_rate1 = 10.00; - } - - if (rand(0, 1)) { - $quote->tax_name2 = 'VAT'; - $quote->tax_rate2 = 17.50; - } - - if (rand(0, 1)) { - $quote->tax_name3 = 'CA Sales Tax'; - $quote->tax_rate3 = 5; - } - - $quote->save(); - - $quote_calc = new InvoiceSum($quote); - $quote_calc->build(); - - $quote = $quote_calc->getQuote(); - $quote->service()->markSent()->save(); - - CreateQuoteInvitations::dispatch($quote, $quote->company); - } - - private function buildLineItems($count = 1) - { - $line_items = []; - - for ($x = 0; $x < $count; $x++) { - $item = InvoiceItemFactory::create(); - $item->quantity = 1; - //$item->cost = 10; - - if (rand(0, 1)) { - $item->tax_name1 = 'GST'; - $item->tax_rate1 = 10.00; - } - - if (rand(0, 1)) { - $item->tax_name1 = 'VAT'; - $item->tax_rate1 = 17.50; - } - - if (rand(0, 1)) { - $item->tax_name1 = 'Sales Tax'; - $item->tax_rate1 = 5; - } - - $product = Product::all()->random(); - - $item->cost = (float) $product->cost; - $item->product_key = $product->product_key; - $item->notes = $product->notes; - $item->custom_value1 = $product->custom_value1; - $item->custom_value2 = $product->custom_value2; - $item->custom_value3 = $product->custom_value3; - $item->custom_value4 = $product->custom_value4; - - $line_items[] = $item; - } - - return $line_items; - } -} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 7e4cc49f59e3..1dd37df3471d 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -38,7 +38,7 @@ class Kernel extends ConsoleKernel /** * Define the application's command schedule. * - * @param \Illuminate\Console\Scheduling\Schedule $schedule + * @param Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) diff --git a/app/DataMapper/ClientSettings.php b/app/DataMapper/ClientSettings.php index 6423ef07d140..7234afe8379c 100644 --- a/app/DataMapper/ClientSettings.php +++ b/app/DataMapper/ClientSettings.php @@ -15,6 +15,7 @@ use App\DataMapper\ClientSettings; use App\DataMapper\CompanySettings; use App\Models\Client; use App\Utils\TranslationHelper; +use stdClass; /** * ClientSettings. @@ -44,7 +45,7 @@ class ClientSettings extends BaseSettings * prevents missing properties from not being returned * and always ensure an up to date class is returned. * - * @return \stdClass + * @param $obj */ public function __construct($obj) { @@ -54,9 +55,9 @@ class ClientSettings extends BaseSettings /** * Default Client Settings scaffold. * - * @return \stdClass + * @return stdClass */ - public static function defaults() : \stdClass + public static function defaults() : stdClass { $data = (object) [ 'entity' => (string) Client::class, @@ -70,9 +71,9 @@ class ClientSettings extends BaseSettings /** * Merges settings from Company to Client. * - * @param \stdClass $company_settings - * @param \stdClass $client_settings - * @return \stdClass of merged settings + * @param stdClass $company_settings + * @param stdClass $client_settings + * @return stdClass of merged settings */ public static function buildClientSettings($company_settings, $client_settings) { diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index e8fc16fe69c5..24d668064b6c 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -13,6 +13,7 @@ namespace App\DataMapper; use App\DataMapper\CompanySettings; use App\Utils\Traits\MakesHash; +use stdClass; /** * CompanySettings. @@ -189,6 +190,7 @@ class CompanySettings extends BaseSettings public $enable_reminder1 = false; public $enable_reminder2 = false; public $enable_reminder3 = false; + public $enable_reminder_endless = false; public $num_days_reminder1 = 0; public $num_days_reminder2 = 0; @@ -253,7 +255,11 @@ class CompanySettings extends BaseSettings public $client_portal_under_payment_minimum = 0; public $client_portal_allow_over_payment = false; + public $use_credits_payment = 'off'; //always, option, off + public static $casts = [ + 'enable_reminder_endless' => 'bool', + 'use_credits_payment' => 'string', 'recurring_invoice_number_pattern' => 'string', 'recurring_invoice_number_counter' => 'int', 'client_portal_under_payment_minimum'=> 'float', @@ -492,7 +498,7 @@ class CompanySettings extends BaseSettings * prevents missing properties from not being returned * and always ensure an up to date class is returned. * - * @return \stdClass + * @param $obj */ public function __construct($obj) { @@ -501,9 +507,9 @@ class CompanySettings extends BaseSettings /** * Provides class defaults on init. - * @return object + * @return stdClass */ - public static function defaults():\stdClass + public static function defaults(): stdClass { $config = json_decode(config('ninja.settings')); @@ -532,9 +538,10 @@ class CompanySettings extends BaseSettings * need to provide a fallback catch on old settings objects which will * set new properties to the object prior to being returned. * - * @param object $data The settings object to be checked + * @param $settings + * @return stdClass */ - public static function setProperties($settings):\stdClass + public static function setProperties($settings): stdClass { $company_settings = (object) get_class_vars(self::class); @@ -549,7 +556,7 @@ class CompanySettings extends BaseSettings public static function notificationDefaults() { - $notification = new \stdClass; + $notification = new stdClass; $notification->email = ['all_notifications']; return $notification; diff --git a/app/DataMapper/DefaultSettings.php b/app/DataMapper/DefaultSettings.php index 00a0d8a10290..bfdcf155f28f 100644 --- a/app/DataMapper/DefaultSettings.php +++ b/app/DataMapper/DefaultSettings.php @@ -13,6 +13,7 @@ namespace App\DataMapper; use App\Models\Client; use App\Models\User; +use stdClass; /** * Class DefaultSettings. @@ -25,11 +26,11 @@ class DefaultSettings extends BaseSettings public static $per_page = 25; /** - * @return \stdClass + * @return stdClass * * //todo user specific settings / preferences. */ - public static function userSettings() : \stdClass + public static function userSettings() : stdClass { return (object) [ // class_basename(User::class) => self::userSettingsObject(), @@ -37,9 +38,9 @@ class DefaultSettings extends BaseSettings } /** - * @return \stdClass + * @return stdClass */ - private static function userSettingsObject() : \stdClass + private static function userSettingsObject() : stdClass { return (object) [ // 'per_page' => self::$per_page, diff --git a/app/DataMapper/EmailTemplateDefaults.php b/app/DataMapper/EmailTemplateDefaults.php index 8d502c64f39a..5fc3288a95db 100644 --- a/app/DataMapper/EmailTemplateDefaults.php +++ b/app/DataMapper/EmailTemplateDefaults.php @@ -124,11 +124,6 @@ class EmailTemplateDefaults public static function emailInvoiceTemplate() { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', - 'allow_unsafe_links' => false, - ]); - $invoice_message = '
'.self::transformText('invoice_message').'
$view_link
'; return $invoice_message; @@ -141,12 +136,9 @@ class EmailTemplateDefaults public static function emailQuoteTemplate() { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', - 'allow_unsafe_links' => false, - ]); + $quote_message = ''.self::transformText('quote_message').'
$view_link
'; - return $converter->convertToHtml(self::transformText('quote_message')); + return $quote_message; } public static function emailPaymentSubject() @@ -156,34 +148,27 @@ class EmailTemplateDefaults public static function emailPaymentTemplate() { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', - 'allow_unsafe_links' => false, - ]); - return $converter->convertToHtml(self::transformText('payment_message')); + $payment_message = ''.self::transformText('payment_message').'
$view_link
'; + + return $payment_message; } public static function emailCreditTemplate() { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', - 'allow_unsafe_links' => false, - ]); - - return $converter->convertToHtml(self::transformText('credit_message')); + $credit_message = ''.self::transformText('credit_message').'
$view_link
'; + return $credit_message; } public static function emailPaymentPartialTemplate() { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', - 'allow_unsafe_links' => false, - ]); - return $converter->convertToHtml(self::transformText('payment_message')); + $payment_message = ''.self::transformText('payment_message').'
$view_link
'; + + return $payment_message; + } public static function emailPaymentPartialSubject() diff --git a/app/DataMapper/FreeCompanySettings.php b/app/DataMapper/FreeCompanySettings.php index 8147face3e31..0e38bf5d9cf3 100644 --- a/app/DataMapper/FreeCompanySettings.php +++ b/app/DataMapper/FreeCompanySettings.php @@ -13,6 +13,7 @@ namespace App\DataMapper; use App\DataMapper\CompanySettings; use App\Utils\Traits\MakesHash; +use stdClass; /** * FreeCompanySettings. @@ -140,7 +141,7 @@ class FreeCompanySettings extends BaseSettings * prevents missing properties from not being returned * and always ensure an up to date class is returned. * - * @return \stdClass + * @param $obj */ public function __construct($obj) { @@ -148,9 +149,9 @@ class FreeCompanySettings extends BaseSettings /** * Provides class defaults on init. - * @return object + * @return stdClass */ - public static function defaults():\stdClass + public static function defaults(): stdClass { $config = json_decode(config('ninja.settings')); diff --git a/app/DataMapper/PaymentMethodMeta.php b/app/DataMapper/PaymentMethodMeta.php index 607f1c339d53..b97eca6bb860 100644 --- a/app/DataMapper/PaymentMethodMeta.php +++ b/app/DataMapper/PaymentMethodMeta.php @@ -13,13 +13,18 @@ namespace App\DataMapper; class PaymentMethodMeta { + /** @var string */ public $exp_month; + /** @var string */ public $exp_year; + /** @var string */ public $brand; + /** @var string */ public $last4; + /** @var int */ public $type; } diff --git a/app/Designs/AbstractDesign.php b/app/Designs/AbstractDesign.php deleted file mode 100644 index 1f56ae33437e..000000000000 --- a/app/Designs/AbstractDesign.php +++ /dev/null @@ -1,27 +0,0 @@ -$number - - - - -'; - } - - public function header() - { - return '$terms_label
- $terms -$entity.public_notes
-$terms_label
-$terms
-$balance_due_label
-$balance_due
-$terms_label
- $terms -#$entity_number
-$entity.public_notes
-$terms_label
-N21
-$balance_due_label
-$balance
-$client.name
', - '$client.id_number' => '$client.id_number
', - '$client.vat_number' => '$client.vat_number
', - '$client.address1' => '$client.address1
', - '$client.address2' => '$client.address2
', - '$client.city_state_postal' => '$client.city_state_postal
', - '$client.postal_city_state' => '$client.postal_city_state
', - '$client.country' => '$client.country
', - '$contact.email' => '$client.email
', - '$client.custom1' => '$client.custom1
', - '$client.custom2' => '$client.custom2
', - '$client.custom3' => '$client.custom3
', - '$client.custom4' => '$client.custom4
', - '$contact.contact1' => '$contact.custom1
', - '$contact.contact2' => '$contact.custom2
', - '$contact.contact3' => '$contact.custom3
', - '$contact.contact4' => '$contact.custom4
', - ]; - - return $this->processCustomFields($company, $data); - } - - private function companyDetails(Company $company) - { - $data = [ - '$company.name' => '$company.name', - '$company.id_number' => '$company.id_number', - '$company.vat_number' => '$company.vat_number', - '$company.website' => '$company.website', - '$company.email' => '$company.email', - '$company.phone' => '$company.phone', - '$company.company1' => '$company1', - '$company.company2' => '$company2', - '$company.company3' => '$company3', - '$company.company4' => '$company4', - ]; - - return $this->processCustomFields($company, $data); - } - - private function companyAddress(Company $company) - { - $data = [ - '$company.address1' => '$company.address1', - '$company.address2' => '$company.address2', - '$company.city_state_postal' => '$company.city_state_postal', - '$company.postal_city_state' => '$company.postal_city_state', - '$company.country' => '$company.country', - '$company.company1' => '$company1', - '$company.company2' => '$company2', - '$company.company3' => '$company3', - '$company.company4' => '$company4', - ]; - - return $this->processCustomFields($company, $data); - } - - private function invoiceDetails(Company $company) - { - $data = [ - '$invoice.number' => '$invoice.number_label: $invoice.number', - '$invoice.po_number' => '$invoice.po_number_label: $invoice.po_number', - '$invoice.date' => '$invoice.date_label: $invoice.date', - '$invoice.due_date' => '$invoice.due_date_label: $invoice.due_date', - '$invoice.balance_due' => '$invoice.balance_due_label: $invoice.balance_due', - '$invoice.total' => '$invoice.total_label: $invoice.total', - '$invoice.partial_due' => '$invoice.partial_due_label: $invoice.partial_due', - '$invoice.custom1' => '$invoice1_label: $invoice.custom1', - '$invoice.custom2' => '$invoice2_label: $invoice.custom2', - '$invoice.custom3' => '$invoice3_label: $invoice.custom3', - '$invoice.custom4' => '$invoice4_label: $invoice.custom4', - '$surcharge1' => '$surcharge1_label: $surcharge1', - '$surcharge2' => '$surcharge2_label: $surcharge2', - '$surcharge3' => '$surcharge3_label: $surcharge3', - '$surcharge4' => '$surcharge4_label: $surcharge4', - - ]; - - return $this->processCustomFields($company, $data); - } - - private function quoteDetails(Company $company) - { - $data = [ - '$quote.quote_number' => '$quote.number_label: $quote.number', - '$quote.po_number' => '$quote.po_number_label: $quote.po_number', - '$quote.quote_date' => '$quote.date_label: $quote.date', - '$quote.valid_until' => '$quote.valid_until_label: $quote.valid_until', - '$quote.balance_due' => '$quote.balance_due_label: $quote.balance_due', - '$quote.quote_total' => '$quote.total_label: $quote.total', - '$quote.partial_due' => '$quote.partial_due_label: $quote.partial_due', - '$quote.custom1' => '$quote.custom1_label: $quote.custom1', - '$quote.custom2' => '$quote.custom2_label: $quote.custom2', - '$quote.custom3' => '$quote.custom3_label: $quote.custom3', - '$quote.custom4' => '$quote.custom4_label: $quote.custom4', - '$quote.surcharge1' => '$surcharge1_label: $surcharge1', - '$quote.surcharge2' => '$surcharge2_label: $surcharge2', - '$quote.surcharge3' => '$surcharge3_label: $surcharge3', - '$quote.surcharge4' => '$surcharge4_label: $surcharge4', - - ]; - - return $this->processCustomFields($company, $data); - } - - private function creditDetails(Company $company) - { - $data = [ - '$credit.number' => '$credit.number_label$credit.number', - '$credit.po_number' => '$credit.po_number_label$credit.po_number', - '$credit.date' => '$credit.date_label$credit.date', - '$credit.balance' => '$credit.balance_label$credit.balance', - '$credit.total' => '$credit.total_label$credit.total', - '$credit.partial_due' => '$credit.partial_due_label$credit.partial_due', - '$credit.custom1' => '$credit.custom1_label$credit.custom1', - '$credit.custom2' => '$credit.custom2_label$credit.custom2', - '$credit.custom3' => '$credit.custom3_label$credit.custom3', - '$credit.custom4' => '$credit.custom4_label$credit.custom4', - '$credit.surcharge1' => '$surcharge1_label$surcharge1_label: $surcharge1', - '$credit.surcharge2' => '$surcharge2_label$surcharge2_label: $surcharge2', - '$credit.surcharge3' => '$surcharge3_label$surcharge3_label: $surcharge3', - '$credit.surcharge4' => '$surcharge4_label$surcharge4_label: $surcharge4', - - ]; - - return $this->processCustomFields($company, $data); - } - - private function processCustomFields(Company $company, $data) - { - $custom_fields = $company->custom_fields; - - if (! $custom_fields) { - return $data; - } - - foreach (self::$custom_fields as $cf) { - if (! property_exists($custom_fields, $cf) || (strlen($custom_fields->{$cf}) == 0)) { - unset($data[$cf]); - } - } - - return $data; - } - - // private function processInputVariables($company, $variables) - // { - // if(is_object($variables)) - // $variables = json_decode(json_encode($variables),true); - - // $custom_fields = $company->custom_fields; - - // $matches = array_intersect(self::$custom_fields, $variables); - - // foreach ($matches as $match) { - - // if (!property_exists($custom_fields, $match) || (strlen($custom_fields->{$match}) == 0)) { - // foreach ($variables as $key => $value) { - // if ($value == $match) { - // unset($variables[$key]); - // } - // } - // } - - // } - - // return $variables; - - // } -} diff --git a/app/Designs/Elegant.php b/app/Designs/Elegant.php deleted file mode 100644 index d2b3e18a7889..000000000000 --- a/app/Designs/Elegant.php +++ /dev/null @@ -1,144 +0,0 @@ -$number - - - - -'; - } - - public function header() - { - return '$entity.public_notes
-$terms_label
-$terms
-$balance_due_label
-$balance
-From:
-To:
- $client_details -$entity.public_notes
-$terms_label
-$terms
-$balance_due_label
-$balance_due
-
-
-
-
-
- $company_logo
-
-
- $client_details
-
-
-
-
-
-
- $entity.public_notes
-
-
-
-
- $discount_label
- $total_tax_labels
- $line_tax_labels
-
-
- $discount
- $total_tax_values
- $line_tax_values
-
-
-
-
-
-
-
-
- $terms_label - $terms -
-
-
-
-
-
-
- $balance_due_label -$balance_due - |
$to_label:
-$from_label:
-$entity.public_notes
-$terms_label
-$terms
-$balance_due_label
-$balance_due
-$entity.public_notes
-$terms_label
-$terms
-$to_label:
-$from_label:
-$terms_label
-$terms
-$balance_due_label
-$balance_due
-"+e.messages.message[0].code+": "+e.messages.message[0].text+"
"),document.getElementById("card_button").disabled=!1,document.querySelector("#card_button > svg").classList.add("hidden"),document.querySelector("#card_button > span").classList.remove("hidden")}else"Ok"===e.messages.resultCode&&(document.getElementById("dataDescriptor").value=e.opaqueData.dataDescriptor,document.getElementById("dataValue").value=e.opaqueData.dataValue,document.getElementById("store_card").value=document.getElementById("store_card_checkbox").checked,document.getElementById("server_response").submit());return!1})),a(this,"handle",(function(){if(o.cardButton&&o.cardButton.addEventListener("click",(function(){o.cardButton.disabled=!0,o.handleAuthorization()})),o.payNowButton){var e,t=n(o.payNowButton);try{var r=function(){var t=e.value;t.addEventListener("click",(function(){t.disabled=!0,o.handlePayNowAction(t.dataset.id)}))};for(t.s();!(e=t.n()).done;)r()}catch(e){t.e(e)}finally{t.f()}}return o})),this.publicKey=t,this.loginId=r,this.cardHolderName=document.getElementById("cardholder_name"),this.cardButton=document.getElementById("card_button"),this.payNowButton=document.getElementsByClassName("pay_now_button")}var t,r,u;return t=e,(r=[{key:"handlePayNowAction",value:function(e){document.getElementById("token").value=e,document.getElementById("server_response").submit()}}])&&o(t.prototype,r),u&&o(t,u),e}())(document.querySelector('meta[name="authorize-public-key"]').content,document.querySelector('meta[name="authorize-login-id"]').content).handle()}}); \ No newline at end of file +!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=2)}({2:function(e,t,n){e.exports=n("hK5p")},hK5p:function(e,t){function n(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0,a=function(){};return{s:a,n:function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var u,c=!0,i=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return c=e.done,e},e:function(e){i=!0,u=e},f:function(){try{c||null==n.return||n.return()}finally{if(i)throw u}}}}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n"+e.messages.message[0].code+": "+e.messages.message[0].text+"
"),document.getElementById("card_button").disabled=!1,document.querySelector("#card_button > svg").classList.add("hidden"),document.querySelector("#card_button > span").classList.remove("hidden")}else"Ok"===e.messages.resultCode&&(document.getElementById("dataDescriptor").value=e.opaqueData.dataDescriptor,document.getElementById("dataValue").value=e.opaqueData.dataValue,document.getElementById("store_card").value=document.getElementById("store_card_checkbox").checked,document.getElementById("server_response").submit());return!1})),a(this,"handle",(function(){if(o.cardButton&&o.cardButton.addEventListener("click",(function(){o.cardButton.disabled=!0,o.handleAuthorization()})),o.payNowButton){var e,t=n(o.payNowButton);try{var r=function(){var t=e.value;t.addEventListener("click",(function(){t.disabled=!0,o.handlePayNowAction(t.dataset.id)}))};for(t.s();!(e=t.n()).done;)r()}catch(e){t.e(e)}finally{t.f()}}return o})),this.publicKey=t,this.loginId=r,this.cardHolderName=document.getElementById("cardholder_name"),this.cardButton=document.getElementById("card_button"),this.payNowButton=document.getElementsByClassName("pay_now_button")}var t,r,u;return t=e,(r=[{key:"handlePayNowAction",value:function(e){document.getElementById("token").value=e,document.getElementById("server_response").submit()}}])&&o(t.prototype,r),u&&o(t,u),e}())(document.querySelector('meta[name="authorize-public-key"]').content,document.querySelector('meta[name="authorize-login-id"]').content).handle()}}); \ No newline at end of file diff --git a/public/js/clients/payments/card-js.min.js b/public/js/clients/payments/card-js.min.js index db1bdcb163c2..ea31d577eb1e 100644 --- a/public/js/clients/payments/card-js.min.js +++ b/public/js/clients/payments/card-js.min.js @@ -1 +1 @@ -!function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)r.d(n,i,function(e){return t[e]}.bind(null,i));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="/",r(r.s=14)}({14:function(t,e,r){t.exports=r("tci0")},tci0:function(t,e){function r(t){this.elem=jQuery(t),this.captureName=!!this.elem.data("capture-name")&&this.elem.data("capture-name"),this.iconColour=!!this.elem.data("icon-colour")&&this.elem.data("icon-colour"),this.stripe=!!this.elem.data("stripe")&&this.elem.data("stripe"),this.stripe&&(this.captureName=!1),this.initCardNumberInput(),this.initNameInput(),this.initExpiryMonthInput(),this.initExpiryYearInput(),this.initCvcInput(),this.elem.empty(),this.setupCardNumberInput(),this.setupNameInput(),this.setupExpiryInput(),this.setupCvcInput(),this.iconColour&&this.setIconColour(this.iconColour),this.refreshCreditCardTypeIcon()}!function(t){var e={init:function(){return this.data("cardjs",new r(this)),this},cardNumber:function(){return this.data("cardjs").getCardNumber()},cardType:function(){return this.data("cardjs").getCardType()},name:function(){return this.data("cardjs").getName()},expiryMonth:function(){return this.data("cardjs").getExpiryMonth()},expiryYear:function(){return this.data("cardjs").getExpiryYear()},cvc:function(){return this.data("cardjs").getCvc()}};t.fn.CardJs=function(r){return e[r]?e[r].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof r&&r?void t.error("Method "+r+" does not exist on jQuery.CardJs"):e.init.apply(this,arguments)}}(jQuery),$((function(){$(".card-js").each((function(t,e){$(e).CardJs()}))})),r.prototype.constructor=r,r.KEYS={0:48,9:57,NUMPAD_0:96,NUMPAD_9:105,DELETE:46,BACKSPACE:8,ARROW_LEFT:37,ARROW_RIGHT:39,ARROW_UP:38,ARROW_DOWN:40,HOME:36,END:35,TAB:9,A:65,X:88,C:67,V:86},r.CREDIT_CARD_NUMBER_DEFAULT_MASK="XXXX XXXX XXXX XXXX",r.CREDIT_CARD_NUMBER_VISA_MASK="XXXX XXXX XXXX XXXX",r.CREDIT_CARD_NUMBER_MASTERCARD_MASK="XXXX XXXX XXXX XXXX",r.CREDIT_CARD_NUMBER_DISCOVER_MASK="XXXX XXXX XXXX XXXX",r.CREDIT_CARD_NUMBER_JCB_MASK="XXXX XXXX XXXX XXXX",r.CREDIT_CARD_NUMBER_AMEX_MASK="XXXX XXXXXX XXXXX",r.CREDIT_CARD_NUMBER_DINERS_MASK="XXXX XXXX XXXX XX",r.prototype.creditCardNumberMask=r.CREDIT_CARD_NUMBER_DEFAULT_MASK,r.CREDIT_CARD_NUMBER_PLACEHOLDER="Card number",r.NAME_PLACEHOLDER="Name on card",r.EXPIRY_MASK="XX / XX",r.EXPIRY_PLACEHOLDER="MM / YY",r.EXPIRY_USE_DROPDOWNS=!1,r.EXPIRY_NUMBER_OF_YEARS=10,r.CVC_MASK_3="XXX",r.CVC_MASK_4="XXXX",r.CVC_PLACEHOLDER="CVC",r.CREDIT_CARD_SVG='',r.LOCK_SVG='',r.CALENDAR_SVG='',r.USER_SVG='',r.MAIL_SVG='',r.INFORMATION_SVG='',r.keyCodeFromEvent=function(t){return t.which||t.keyCode},r.keyIsCommandFromEvent=function(t){return t.ctrlKey||t.metaKey},r.keyIsNumber=function(t){return r.keyIsTopNumber(t)||r.keyIsKeypadNumber(t)},r.keyIsTopNumber=function(t){var e=r.keyCodeFromEvent(t);return e>=r.KEYS[0]&&e<=r.KEYS[9]},r.keyIsKeypadNumber=function(t){var e=r.keyCodeFromEvent(t);return e>=r.KEYS.NUMPAD_0&&e<=r.KEYS.NUMPAD_9},r.keyIsDelete=function(t){return r.keyCodeFromEvent(t)==r.KEYS.DELETE},r.keyIsBackspace=function(t){return r.keyCodeFromEvent(t)==r.KEYS.BACKSPACE},r.keyIsDeletion=function(t){return r.keyIsDelete(t)||r.keyIsBackspace(t)},r.keyIsArrow=function(t){var e=r.keyCodeFromEvent(t);return e>=r.KEYS.ARROW_LEFT&&e<=r.KEYS.ARROW_DOWN},r.keyIsNavigation=function(t){var e=r.keyCodeFromEvent(t);return e==r.KEYS.HOME||e==r.KEYS.END},r.keyIsKeyboardCommand=function(t){var e=r.keyCodeFromEvent(t);return r.keyIsCommandFromEvent(t)&&(e==r.KEYS.A||e==r.KEYS.X||e==r.KEYS.C||e==r.KEYS.V)},r.keyIsTab=function(t){return r.keyCodeFromEvent(t)==r.KEYS.TAB},r.copyAllElementAttributes=function(t,e){$.each(t[0].attributes,(function(t,r){e.attr(r.nodeName,r.nodeValue)}))},r.numbersOnlyString=function(t){for(var e="",r=0;r