From ade5472d9ea853735f9b8e74e06e0a5f5298d274 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 3 May 2021 21:23:39 +1000 Subject: [PATCH 01/16] Code of Conduct --- CODE_OF_CONDUCT.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000000..8aab1edc58db --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,4 @@ +# Invoice Ninja Code of Conduct + +The development team has invested a tremendous amount of time and energy into this project. While we appreciate that bugs can be frustrating we ask that our community refrain from insults and snide remarks. We're happy to provide support to both our hosted and selfhosted communities but ask that feedback is always polite. + From 5510993d133b9caa5fd383df1fef76b328afab6f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 3 May 2021 21:51:00 +1000 Subject: [PATCH 02/16] Fixes for gateway fees --- app/Http/Controllers/BaseController.php | 3 ++- app/Http/Controllers/ClientPortal/InvoiceController.php | 2 ++ app/Http/Controllers/ClientPortal/PaymentController.php | 4 ++++ app/Services/Invoice/InvoiceService.php | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index aec442c9c184..9b03936b5722 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -395,7 +395,8 @@ class BaseController extends Controller 'company' => function ($query) use ($created_at, $user) { $query->whereNotNull('created_at')->with('documents'); }, - 'company.clients' => function ($query) use ($user) { + 'company.clients' => function ($query) use ($created_at, $user) { + $query->where('clients.created_at', '>=', $created_at)->with('contacts.company', 'gateway_tokens', 'documents'); if(!$user->hasPermission('view_client')) $query->where('clients.user_id', $user->id)->orWhere('clients.assigned_user_id', $user->id); diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index 2300600714c0..9746863da046 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -50,6 +50,8 @@ class InvoiceController extends Controller { set_time_limit(0); + $invoice->service()->removeUnpaidGatewayFees()->save(); + $data = [ 'invoice' => $invoice, ]; diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 6d17c3daff54..8531c36fefb1 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -97,6 +97,10 @@ class PaymentController extends Controller $payable_invoices = collect($request->payable_invoices); $invoices = Invoice::whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->get(); + $invoices->each(function($invoice){ + $invoice->service()->removeUnpaidGatewayFees()->save(); + }); + /* pop non payable invoice from the $payable_invoices array */ $payable_invoices = $payable_invoices->filter(function ($payable_invoice) use ($invoices) { diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 4ae0787809df..3531e0d266f5 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -110,6 +110,7 @@ class InvoiceService public function addGatewayFee(CompanyGateway $company_gateway, $gateway_type_id, float $amount) { + $this->invoice = (new AddGatewayFee($company_gateway, $gateway_type_id, $this->invoice, $amount))->run(); return $this; From a9aeb906c3af51001bf78e0589d607cf740206b5 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 3 May 2021 22:25:45 +1000 Subject: [PATCH 03/16] Fixes for migration --- app/Jobs/Util/StartMigration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Jobs/Util/StartMigration.php b/app/Jobs/Util/StartMigration.php index 8b5f09fcfbc6..e26c7462ed74 100644 --- a/app/Jobs/Util/StartMigration.php +++ b/app/Jobs/Util/StartMigration.php @@ -109,7 +109,7 @@ class StartMigration implements ShouldQueue throw new NonExistingMigrationFile('Migration file does not exist, or it is corrupted.'); } - Import::dispatchNow($file, $this->company, $this->user)->onQueue('migration'); + Import::dispatchNow($file, $this->company, $this->user); Storage::deleteDirectory(public_path("storage/migrations/{$filename}")); From f7257e4335d4e631ebcbb83e67d79812e3f7007d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 12:40:28 +1000 Subject: [PATCH 04/16] Migration emails --- app/Http/Controllers/MigrationController.php | 50 ++++++++++++++---- app/Mail/ExistingMigration.php | 17 +++++-- app/Mail/Migration/MaxCompanies.php | 51 +++++++++++++++++++ resources/lang/en/texts.php | 5 ++ .../views/email/migration/existing.blade.php | 37 +++++--------- .../email/migration/max_companies.blade.php | 18 +++++++ 6 files changed, 140 insertions(+), 38 deletions(-) create mode 100644 app/Mail/Migration/MaxCompanies.php create mode 100644 resources/views/email/migration/max_companies.blade.php diff --git a/app/Http/Controllers/MigrationController.php b/app/Http/Controllers/MigrationController.php index afe76b9c1c80..c554a657e821 100644 --- a/app/Http/Controllers/MigrationController.php +++ b/app/Http/Controllers/MigrationController.php @@ -18,6 +18,7 @@ use App\Jobs\Mail\NinjaMailerJob; use App\Jobs\Mail\NinjaMailerObject; use App\Jobs\Util\StartMigration; use App\Mail\ExistingMigration; +use App\Mail\Migration\MaxCompanies; use App\Models\Company; use App\Models\CompanyToken; use Illuminate\Foundation\Bus\DispatchesJobs; @@ -231,19 +232,51 @@ class MigrationController extends BaseController nlog($request->all()); } + try { + return response()->json([ + '_id' => Str::uuid(), + 'method' => config('queue.default'), + 'started_at' => now(), + ], 200); + + } finally { + // Controller logic here + foreach ($companies as $company) { $is_valid = $request->file($company->company_index)->isValid(); if (!$is_valid) { - // We might want to send user something's wrong with migration or nope? continue; } $user = auth()->user(); + $company_count = $user->account->companies()->count(); + // Look for possible existing company (based on company keys). $existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company->company_key])->first(); + if(!$existing_company && $company_count >=10) { + + $nmo = new NinjaMailerObject; + $nmo->mailable = new MaxCompanies($user->account->companies()->first()); + $nmo->company = $user->account->companies()->first(); + $nmo->settings = $user->account->companies()->first()->settings; + $nmo->to_user = $user; + NinjaMailerJob::dispatch($nmo); + return; + } + elseif($existing_company && $company_count > 10 ){ + + $nmo = new NinjaMailerObject; + $nmo->mailable = new MaxCompanies($user->account->companies()->first()); + $nmo->company = $user->account->companies()->first(); + $nmo->settings = $user->account->companies()->first()->settings; + $nmo->to_user = $user; + NinjaMailerJob::dispatch($nmo); + return; + } + $checks = [ 'existing_company' => $existing_company ? (bool)1 : false, 'force' => property_exists($company, 'force') ? (bool) $company->force : false, @@ -254,11 +287,11 @@ class MigrationController extends BaseController nlog('Migrating: Existing company without force. (CASE_01)'); $nmo = new NinjaMailerObject; - $nmo->mailable = new ExistingMigration(); - $nmo->company = $existing_company; - $nmo->settings = $existing_company->settings; + $nmo->mailable = new ExistingMigration($existing_company); + $nmo->company = $user->account->companies()->first(); + $nmo->settings = $user->account->companies()->first(); $nmo->to_user = $user; - + NinjaMailerJob::dispatch($nmo); return response()->json([ @@ -355,10 +388,7 @@ class MigrationController extends BaseController // } } - return response()->json([ - '_id' => Str::uuid(), - 'method' => config('queue.default'), - 'started_at' => now(), - ], 200); + } + } } diff --git a/app/Mail/ExistingMigration.php b/app/Mail/ExistingMigration.php index 60f7abdf95d4..366a4c146af5 100644 --- a/app/Mail/ExistingMigration.php +++ b/app/Mail/ExistingMigration.php @@ -10,14 +10,22 @@ class ExistingMigration extends Mailable { // use Queueable, SerializesModels; + public $company; + + public $settings; + + public $logo; + + public $company_name; + /** * Create a new message instance. * * @return void */ - public function __construct() + public function __construct($company) { - // + $this->company = $company; } /** @@ -27,8 +35,11 @@ class ExistingMigration extends Mailable */ public function build() { - return $this->from(config('mail.from.address'), config('mail.from.name')) + $this->settings = $this->company->settings; + $this->logo = $this->company->present()->logo(); + $this->company_name = $this->company->present()->name(); + return $this->from(config('mail.from.address'), config('mail.from.name')) ->view('email.migration.existing'); } } diff --git a/app/Mail/Migration/MaxCompanies.php b/app/Mail/Migration/MaxCompanies.php new file mode 100644 index 000000000000..af65f766b95e --- /dev/null +++ b/app/Mail/Migration/MaxCompanies.php @@ -0,0 +1,51 @@ +company = $company; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + $this->settings = $this->company->settings; + $this->logo = $this->company->present()->logo(); + $this->title = ctrans('texts.max_companies'); + $this->message = ctrans('texts.max_companies_desc'); + $this->whitelabel = $this->company->account->isPaid(); + + return $this->from(config('mail.from.address'), config('mail.from.name')) + ->view('email.migration.max_companies'); + } +} diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 2619e20330fc..1bebb2cc44cf 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4235,6 +4235,11 @@ $LANG = array( 'notification_quote_created_subject' => 'Quote :invoice was created for :client', 'notification_credit_created_subject' => 'Credit :invoice was created to :client', 'notification_credit_created_subject' => 'Credit :invoice was created for :client', + 'max_companies' => 'Maximum companies migrated', + 'max_companies_desc' => 'You have reached your maximum number of companies. Delete existing companies to migrate new ones.', + 'migration_already_completed' => 'Company already migrated', + 'migration_already_completed_desc' => 'Looks like you already migrated :company_name to the V5 version of the Invoice Ninja. In case you want to start over, you can force migrate to wipe existing data.', + ); return $LANG; diff --git a/resources/views/email/migration/existing.blade.php b/resources/views/email/migration/existing.blade.php index 1491488b17d6..3a4c1dbd6ca1 100644 --- a/resources/views/email/migration/existing.blade.php +++ b/resources/views/email/migration/existing.blade.php @@ -1,31 +1,18 @@ @component('email.template.master', ['design' => 'light', 'settings' => $settings]) -@slot('header') - @component('email.components.header') - Migration already completed - @endcomponent -@endslot + @slot('header') + @include('email.components.header', ['logo' => $logo]) + @endslot -@slot('greeting') - Hello, -@endslot +

{{ctrans('texts.migration_already_completed')}}

-Looks like you already migrated your data to V2 version of the Invoice Ninja. In case you want to start over, you can 'force' migrate to wipe existing data. - -@component('email.components.button', ['url' => url('/')]) - Visit portal -@endcomponent - - -@slot('signature') -Thank you,
-Invoice Ninja -@endslot - -@slot('footer') - @component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja']) - For any info, please visit InvoiceNinja. - @endcomponent -@endslot +

{{ctrans('texts.migration_already_completed_desc', ['company_name' => $company_name])}}

+ @if(isset($whitelabel) && !$whitelabel) + @slot('footer') + @component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja']) + For any info, please visit InvoiceNinja. + @endcomponent + @endslot + @endif @endcomponent diff --git a/resources/views/email/migration/max_companies.blade.php b/resources/views/email/migration/max_companies.blade.php new file mode 100644 index 000000000000..4d76f055b962 --- /dev/null +++ b/resources/views/email/migration/max_companies.blade.php @@ -0,0 +1,18 @@ +@component('email.template.master', ['design' => 'light', 'settings' => $settings]) + + @slot('header') + @include('email.components.header', ['logo' => $logo]) + @endslot + +

{{ctrans('texts.max_companies')}}

+ +

{{ctrans('texts.max_companies_desc')}}

+ + @if(isset($whitelabel) && !$whitelabel) + @slot('footer') + @component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja']) + For any info, please visit InvoiceNinja. + @endcomponent + @endslot + @endif +@endcomponent From e8d6d29f17946093a8ee1795b8ab31788ef55cee Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 12:49:32 +1000 Subject: [PATCH 05/16] Track bounced and spam mail --- app/DataMapper/Analytics/Mail/EmailBounce.php | 77 +++++++++++++++++++ app/DataMapper/Analytics/Mail/EmailSpam.php | 77 +++++++++++++++++++ app/Http/Controllers/PostMarkController.php | 13 +++- 3 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 app/DataMapper/Analytics/Mail/EmailBounce.php create mode 100644 app/DataMapper/Analytics/Mail/EmailSpam.php diff --git a/app/DataMapper/Analytics/Mail/EmailBounce.php b/app/DataMapper/Analytics/Mail/EmailBounce.php new file mode 100644 index 000000000000..bf86139a9dad --- /dev/null +++ b/app/DataMapper/Analytics/Mail/EmailBounce.php @@ -0,0 +1,77 @@ +string_metric5 = $string_metric5; + $this->string_metric6 = $string_metric6; + $this->string_metric7 = $string_metric7; + } +} diff --git a/app/DataMapper/Analytics/Mail/EmailSpam.php b/app/DataMapper/Analytics/Mail/EmailSpam.php new file mode 100644 index 000000000000..75b9dc26b53b --- /dev/null +++ b/app/DataMapper/Analytics/Mail/EmailSpam.php @@ -0,0 +1,77 @@ +string_metric5 = $string_metric5; + $this->string_metric6 = $string_metric6; + $this->string_metric7 = $string_metric7; + } +} diff --git a/app/Http/Controllers/PostMarkController.php b/app/Http/Controllers/PostMarkController.php index e4f6a855d0af..2e45fa1c2ce2 100644 --- a/app/Http/Controllers/PostMarkController.php +++ b/app/Http/Controllers/PostMarkController.php @@ -11,6 +11,7 @@ namespace App\Http\Controllers; +use App\DataMapper\Analytics\EmailBounce; use App\Jobs\Util\SystemLogger; use App\Libraries\MultiDB; use App\Models\CreditInvitation; @@ -19,6 +20,7 @@ use App\Models\QuoteInvitation; use App\Models\RecurringInvoiceInvitation; use App\Models\SystemLog; use Illuminate\Http\Request; +use Turbo124\Beacon\Facades\LightLogs; /** * Class PostMarkController. @@ -71,8 +73,7 @@ class PostMarkController extends BaseController if($request->header('X-API-SECURITY') && $request->header('X-API-SECURITY') == config('postmark.secret')) { - - nlog($request->all()); + // nlog($request->all()); MultiDB::findAndSetDbByCompanyKey($request->input('Tag')); @@ -157,6 +158,14 @@ class PostMarkController extends BaseController $this->invitation->email_status = 'bounced'; $this->invitation->save(); + $bounce = new EmailBounce( + $request->input('Tag'), + $request->input('From'), + $request->input('MessageID') + ); + + LightLogs::create($bounce)->batch(); + SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client); } From b2439bced8a3b511a533bb707fe8f8bade8f736e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 13:46:45 +1000 Subject: [PATCH 06/16] Email Analytics --- app/Http/Controllers/PostMarkController.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/PostMarkController.php b/app/Http/Controllers/PostMarkController.php index 2e45fa1c2ce2..7a98a59f1adc 100644 --- a/app/Http/Controllers/PostMarkController.php +++ b/app/Http/Controllers/PostMarkController.php @@ -12,6 +12,7 @@ namespace App\Http\Controllers; use App\DataMapper\Analytics\EmailBounce; +use App\DataMapper\Analytics\EmailSpam; use App\Jobs\Util\SystemLogger; use App\Libraries\MultiDB; use App\Models\CreditInvitation; @@ -165,7 +166,7 @@ class PostMarkController extends BaseController ); LightLogs::create($bounce)->batch(); - + SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client); } @@ -200,6 +201,14 @@ class PostMarkController extends BaseController $this->invitation->email_status = 'spam'; $this->invitation->save(); + $spam = new EmailSpam( + $request->input('Tag'), + $request->input('From'), + $request->input('MessageID') + ); + + LightLogs::create($bounce)->batch(); + SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client); } From 382dd88e02610ce9c3109ee716a1e1f69660a2bc Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 13:54:28 +1000 Subject: [PATCH 07/16] Do not update/create products from migration --- .../Migration/InvoiceMigrationRepository.php | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/app/Repositories/Migration/InvoiceMigrationRepository.php b/app/Repositories/Migration/InvoiceMigrationRepository.php index 14d56965d29f..ee142650f2ba 100644 --- a/app/Repositories/Migration/InvoiceMigrationRepository.php +++ b/app/Repositories/Migration/InvoiceMigrationRepository.php @@ -107,35 +107,7 @@ class InvoiceMigrationRepository extends BaseRepository InvoiceInvitation::reguard(); RecurringInvoiceInvitation::reguard(); - /* - if (isset($data['invitations'])) { - $invitations = collect($data['invitations']); - $model->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) use ($resource) { - $this->getInvitation($invitation, $resource)->delete(); - }); - - foreach ($data['invitations'] as $invitation) { - - //if no invitations are present - create one. - if (! $this->getInvitation($invitation, $resource)) { - if (isset($invitation['id'])) { - unset($invitation['id']); - } - - //make sure we are creating an invite for a contact who belongs to the client only! - $contact = ClientContact::find($invitation['client_contact_id']); - - if ($contact && $model->client_id == $contact->client_id) { - $new_invitation = $invitation_factory_class::create($model->company_id, $model->user_id); - $new_invitation->{$lcfirst_resource_id} = $model->id; - $new_invitation->client_contact_id = $contact->id; - $new_invitation->save(); - } - } - } - } - */ $model->load('invitations'); /* If no invitations have been created, this is our fail safe to maintain state*/ @@ -152,8 +124,6 @@ class InvoiceMigrationRepository extends BaseRepository if ($class->name == Invoice::class || $class->name == RecurringInvoice::class) { if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) { - // $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount'])); - // $model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save(); } if (! $model->design_id) { @@ -162,7 +132,7 @@ class InvoiceMigrationRepository extends BaseRepository if ($model->company->update_products) { - UpdateOrCreateProduct::dispatchNow($model->line_items, $model, $model->company); + //UpdateOrCreateProduct::dispatchNow($model->line_items, $model, $model->company); } } From 2f9e9dc81ffcf2735b4d5acb33bca072e0775753 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 14:47:37 +1000 Subject: [PATCH 08/16] Port Mobile Localization --- app/Console/Commands/MobileLocalization.php | 120 ++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 app/Console/Commands/MobileLocalization.php diff --git a/app/Console/Commands/MobileLocalization.php b/app/Console/Commands/MobileLocalization.php new file mode 100644 index 000000000000..7ae72f6cd1bc --- /dev/null +++ b/app/Console/Commands/MobileLocalization.php @@ -0,0 +1,120 @@ +option('type')); + + switch ($type) { + case 'laravel': + $this->laravelResources(); + break; + default: + $this->flutterResources(); + break; + } + } + + private function laravelResources() + { + $resources = $this->getResources(); + + foreach ($resources as $key => $val) { + $transKey = "texts.{$key}"; + if (trans($transKey) == $transKey) { + echo "'$key' => '$val',\n"; + } + } + } + + private function flutterResources() + { + $languages = cache('languages'); + $resources = $this->getResources(); + + foreach ($languages as $language) { + if ($language->locale == 'en') { + continue; + } + + echo "'{$language->locale}': {\n"; + + foreach ($resources as $key => $val) { + $text = trim(addslashes(trans("texts.{$key}", [], $language->locale))); + if (substr($text, 0, 6) == 'texts.') { + $text = $resources->$key; + } + + $text = str_replace(array('', ''), '', $text); + $text = str_replace(array('', ''), '', $text); + $text = str_replace(array('', ''), '', $text); + + echo "'$key': '$text',\n"; + } + + echo "},\n"; + } + } + + private function getResources() + { + $url = 'https://raw.githubusercontent.com/invoiceninja/flutter-client/develop/lib/utils/i18n.dart'; + $data = CurlUtils::get($url); + + $start = strpos($data, 'do not remove comment') + 25; + $end = strpos($data, '},', $start); + $data = substr($data, $start, $end - $start - 5); + + $data = str_replace("\n", "", $data); + $data = str_replace("\"", "\'", $data); + $data = str_replace("'", "\"", $data); + + return json_decode('{' . rtrim($data, ',') . '}'); + } + + protected function getOptions() + { + return [ + ['type', null, InputOption::VALUE_OPTIONAL, 'Type', null], + ]; + } + +} From 34ba510d80c434a84a567c3ef8c0214fa3c598ee Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 17:00:05 +1000 Subject: [PATCH 09/16] Fixes for company gateway edge case --- app/Models/CompanyGateway.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index 6495fae14aaf..063153d36b63 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -225,7 +225,7 @@ class CompanyGateway extends BaseModel { $config = $this->getConfig(); - if ($this->gateway->provider == 'Stripe' && strpos($config->publishableKey, 'test')) { + if ($this->gateway->provider == 'Stripe' && property_exists($config, 'publishableKey') && strpos($config->publishableKey, 'test')) { return true; } From 9a0d8afafc6f5f28fa8e2eb6d48b148facfb73a4 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 18:33:36 +1000 Subject: [PATCH 10/16] Update task statuses on migration --- app/Jobs/Util/Import.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Jobs/Util/Import.php b/app/Jobs/Util/Import.php index d39e2a554680..9fc0a4ec0511 100644 --- a/app/Jobs/Util/Import.php +++ b/app/Jobs/Util/Import.php @@ -31,6 +31,7 @@ use App\Factory\VendorFactory; use App\Http\Requests\Company\UpdateCompanyRequest; use App\Http\ValidationRules\ValidCompanyGatewayFeesAndLimitsRule; use App\Http\ValidationRules\ValidUserForCompany; +use App\Jobs\Company\CreateCompanyTaskStatuses; use App\Jobs\Company\CreateCompanyToken; use App\Jobs\Ninja\CheckCompanyData; use App\Jobs\Ninja\CompanySizeCheck; @@ -82,10 +83,10 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Http\UploadedFile; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str; use Turbo124\Beacon\Facades\LightLogs; -use Illuminate\Support\Facades\Mail; class Import implements ShouldQueue { @@ -230,6 +231,9 @@ class Import implements ShouldQueue $this->company->save(); } + // CreateCompanyPaymentTerms::dispatchNow($sp035a66, $spaa9f78); + CreateCompanyTaskStatuses::dispatchNow($this->company, $this->user); + info('CompletedπŸš€πŸš€πŸš€πŸš€πŸš€ at '.now()); unlink($this->file_path); From 148f0466ede4f892848ed1ada9bbada75541287c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 18:43:16 +1000 Subject: [PATCH 11/16] FIxes for Entity Created messageS" --- app/Mail/Admin/EntityCreatedObject.php | 8 ++++---- resources/lang/en/texts.php | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Mail/Admin/EntityCreatedObject.php b/app/Mail/Admin/EntityCreatedObject.php index f33c7cd540ce..ba773ac3c5f9 100644 --- a/app/Mail/Admin/EntityCreatedObject.php +++ b/app/Mail/Admin/EntityCreatedObject.php @@ -62,20 +62,20 @@ class EntityCreatedObject switch ($this->entity_type) { case 'invoice': $this->template_subject = "texts.notification_invoice_created_subject"; - $this->template_body = "texts.notification_invoice_sent"; + $this->template_body = "texts.notification_invoice_created_body"; break; case 'quote': $this->template_subject = "texts.notification_quote_created_subject"; - $this->template_body = "texts.notification_quote_sent"; + $this->template_body = "texts.notification_quote_created_body"; break; case 'credit': $this->template_subject = "texts.notification_credit_created_subject"; - $this->template_body = "texts.notification_credit_sent"; + $this->template_body = "texts.notification_credit_created_body"; break; default: $this->template_subject = "texts.notification_invoice_created_subject"; - $this->template_body = "texts.notification_invoice_sent"; + $this->template_body = "texts.notification_invoice_created_body"; break; } } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 1bebb2cc44cf..4adf5fa1d78d 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4229,11 +4229,11 @@ $LANG = array( 'amount_greater_than_balance_v5' => 'The amount is greater than the invoice balance. You cannot overpay an invoice.', 'click_to_continue' => 'Click to continue', - 'notification_invoice_created_subject' => 'Invoice :invoice was created to :client', + 'notification_invoice_created_body' => 'The following invoice :invoice was created for client :client for :amount.', 'notification_invoice_created_subject' => 'Invoice :invoice was created for :client', - 'notification_quote_created_subject' => 'Quote :invoice was created to :client', + 'notification_quote_created_body' => 'The following quote :invoice was created for client :client for :amount.', 'notification_quote_created_subject' => 'Quote :invoice was created for :client', - 'notification_credit_created_subject' => 'Credit :invoice was created to :client', + 'notification_credit_created_body' => 'The following credit :invoice was created for client :client for :amount.', 'notification_credit_created_subject' => 'Credit :invoice was created for :client', 'max_companies' => 'Maximum companies migrated', 'max_companies_desc' => 'You have reached your maximum number of companies. Delete existing companies to migrate new ones.', From 349d6daa07944032a078a29f40814425c15eee92 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 18:56:01 +1000 Subject: [PATCH 12/16] Fixes for company gateway contsts --- app/Models/CompanyGateway.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index 063153d36b63..9ca4e81b42ea 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -65,6 +65,7 @@ class CompanyGateway extends BaseModel '3758e7f7c6f4cecf0f4f348b9a00f456' => 304, '3b6621f970ab18887c4f6dca78d3f8bb' => 305, '54faab2ab6e3223dbe848b1686490baa' => 306, + 'd14dd26a47cecc30fdd65700bfb67b34' => 301, ]; protected $touches = []; From bd22dc33145436e221a86add02b13f5b6cd94bbf Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 19:56:15 +1000 Subject: [PATCH 13/16] Fixes for Historical PDF generation --- app/Http/Controllers/ActivityController.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php index f6e97b7e01f6..4f854498784e 100644 --- a/app/Http/Controllers/ActivityController.php +++ b/app/Http/Controllers/ActivityController.php @@ -14,12 +14,14 @@ namespace App\Http\Controllers; use App\Http\Requests\Activity\DownloadHistoricalEntityRequest; use App\Models\Activity; use App\Transformers\ActivityTransformer; +use App\Utils\HostedPDF\NinjaPdf; +use App\Utils\PhantomJS\Phantom; use App\Utils\Traits\Pdf\PdfMaker; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; -use stdClass; use Symfony\Component\HttpFoundation\StreamedResponse; +use stdClass; class ActivityController extends BaseController { @@ -139,7 +141,15 @@ class ActivityController extends BaseController return response()->json(['message'=> ctrans('texts.no_backup_exists'), 'errors' => new stdClass], 404); } - $pdf = $this->makePdf(null, null, $backup->html_backup); + if (config('ninja.phantomjs_pdf_generation')) { + $pdf = (new Phantom)->convertHtmlToPdf($backup->html_backup); + } + elseif(config('ninja.invoiceninja_hosted_pdf_generation')){ + $pdf = (new NinjaPdf())->build($backup->html_backup); + } + else { + $pdf = $this->makePdf(null, null, $backup->html_backup); + } if (isset($activity->invoice_id)) { $filename = $activity->invoice->numberFormatter().'.pdf'; From 4703496c7c861322bf0f73a74d5e7f7142ba7dcd Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 22:04:07 +1000 Subject: [PATCH 14/16] Fixes for PSR loading --- app/DataMapper/Analytics/Mail/EmailBounce.php | 2 +- app/DataMapper/Analytics/Mail/EmailSpam.php | 2 +- app/Models/Client.php | 5 +++-- app/Models/Gateway.php | 1 + .../migrations/2021_04_12_095424_stripe_connect_gateway.php | 4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/DataMapper/Analytics/Mail/EmailBounce.php b/app/DataMapper/Analytics/Mail/EmailBounce.php index bf86139a9dad..5a8aaf10af3d 100644 --- a/app/DataMapper/Analytics/Mail/EmailBounce.php +++ b/app/DataMapper/Analytics/Mail/EmailBounce.php @@ -9,7 +9,7 @@ * @license https://opensource.org/licenses/AAL */ -namespace App\DataMapper\Analytics; +namespace App\DataMapper\Analytics\Mail; class EmailBounce { diff --git a/app/DataMapper/Analytics/Mail/EmailSpam.php b/app/DataMapper/Analytics/Mail/EmailSpam.php index 75b9dc26b53b..c420327ddc78 100644 --- a/app/DataMapper/Analytics/Mail/EmailSpam.php +++ b/app/DataMapper/Analytics/Mail/EmailSpam.php @@ -9,7 +9,7 @@ * @license https://opensource.org/licenses/AAL */ -namespace App\DataMapper\Analytics; +namespace App\DataMapper\Analytics\Mail; class EmailSpam { diff --git a/app/Models/Client.php b/app/Models/Client.php index dbb2b12ba8af..1e1ef2232d42 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -79,8 +79,9 @@ class Client extends BaseModel implements HasLocalePreference protected $with = [ 'gateway_tokens', - 'documents' - //'currency', + 'documents', + 'contacts.company', + // 'currency', // 'primary_contact', // 'country', // 'contacts', diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 5d470680aab5..c182f4e1d7ad 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -85,6 +85,7 @@ class Gateway extends StaticModel return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal break; case 20: + case 56: return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable']], GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false], diff --git a/database/migrations/2021_04_12_095424_stripe_connect_gateway.php b/database/migrations/2021_04_12_095424_stripe_connect_gateway.php index 0f2a72242151..2d9fe819f7d3 100644 --- a/database/migrations/2021_04_12_095424_stripe_connect_gateway.php +++ b/database/migrations/2021_04_12_095424_stripe_connect_gateway.php @@ -30,8 +30,8 @@ class StripeConnectGateway extends Migration Gateway::create($gateway); if (Ninja::isNinja()) { - Gateway::where('id', 20)->update(['visible' => 0]); - Gateway::where('id', 56)->update(['visible' => 1]); + Gateway::whereIn('id', [20])->update(['visible' => 0]); + Gateway::whereIn('id', [56])->update(['visible' => 1]); } } From ff7799b0bf856c8d384ce10f52de97721111b548 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 22:20:55 +1000 Subject: [PATCH 15/16] Fixes for eager loading --- app/Models/Presenters/ClientPresenter.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Models/Presenters/ClientPresenter.php b/app/Models/Presenters/ClientPresenter.php index 4e4aacf67626..dfdc11c26423 100644 --- a/app/Models/Presenters/ClientPresenter.php +++ b/app/Models/Presenters/ClientPresenter.php @@ -27,7 +27,8 @@ class ClientPresenter extends EntityPresenter return $this->entity->name; } - $contact = $this->entity->primary_contact->first(); + //$contact = $this->entity->primary_contact->first(); + $contact = $this->entity->contacts->first(); $contact_name = 'No Contact Set'; From 71b407e6809e95a44cc0f03b5e718a80095d8908 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 4 May 2021 22:50:26 +1000 Subject: [PATCH 16/16] v5.1.60 --- VERSION.txt | 2 +- config/ninja.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 30aaaeaa47a6..8f7bfe6fb860 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.1.59 \ No newline at end of file +5.1.60 \ No newline at end of file diff --git a/config/ninja.php b/config/ninja.php index 34e346da0a9d..4481e81ae629 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -14,8 +14,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => '5.1.59', - 'app_tag' => '5.1.59-release', + 'app_version' => '5.1.60', + 'app_tag' => '5.1.60-release', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false),