Refactor invitations

This commit is contained in:
David Bomba 2021-10-14 16:25:09 +11:00
parent 1ad881afe6
commit 0cfe5bc39a
21 changed files with 89 additions and 186 deletions

View File

@ -13,6 +13,7 @@ namespace App\Http\Middleware;
use App\Libraries\MultiDB;
use Closure;
use Hashids\Hashids;
use Illuminate\Http\Request;
use stdClass;
@ -45,6 +46,30 @@ class SetInviteDb
if($entity == "pay")
$entity = "invoice";
/* Try and determine the DB from the invitation key STRING*/
if (config('ninja.db.multi_db_enabled')) {
// nlog("/ Try and determine the DB from the invitation key /");
$hashids = new Hashids(config('ninja.hash_salt'), 10);
$segments = explode('-', $request->route('invitation_key'));
$hashed_db = false;
if(is_array($segments)){
$hashed_db = $hashids->decode($segments[0]);
}
if(is_array($hashed_db)){
MultiDB::setDB(MultiDB::DB_PREFIX.str_pad($hashed_db[0], 2, '0', STR_PAD_LEFT));
return $next($request);
}
}
/* Attempt to set DB from invitatation key*/
if ($request->getSchemeAndHttpHost() && config('ninja.db.multi_db_enabled') && ! MultiDB::findAndSetDbByInvitation($entity, $request->route('invitation_key'))) {
if (request()->json) {
return response()->json($error, 403);

View File

@ -101,7 +101,9 @@ class CreateEntityPdf implements ShouldQueue
public function handle()
{
$start = microtime(true);
nlog("Start ". $start);
/* Forget the singleton*/
App::forgetInstance('translator');
@ -113,6 +115,9 @@ class CreateEntityPdf implements ShouldQueue
/* Set customized translations _NOW_ */
$t->replace(Ninja::transformTranslations($this->client->getMergedSettings()));
$translate = microtime(true);
nlog("Translate ". $translate - $start);
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
return (new Phantom)->generate($this->invitation);
}
@ -148,6 +153,9 @@ class CreateEntityPdf implements ShouldQueue
$html = new HtmlEngine($this->invitation);
$design_time = microtime(true);
nlog("Design ". $design_time - $translate);
if ($design->is_custom) {
$options = [
'custom_partials' => json_decode(json_encode($design->design), true)
@ -159,6 +167,9 @@ class CreateEntityPdf implements ShouldQueue
$variables = $html->generateLabelsAndValues();
$labels_time = microtime(true);
nlog("Labels ". $labels_time - $design_time);
$state = [
'template' => $template->elements([
'client' => $this->client,
@ -181,6 +192,10 @@ class CreateEntityPdf implements ShouldQueue
->design($template)
->build();
$template_time = microtime(true);
nlog("Template Build ". $template_time - $labels_time);
$pdf = null;
try {
@ -201,6 +216,9 @@ class CreateEntityPdf implements ShouldQueue
}
$pdf_time = microtime(true);
nlog("PDF time " . $pdf_time - $template_time);
if ($pdf) {
try{

View File

@ -1,68 +0,0 @@
<?php
/**
* Quote Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Quote Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Jobs\Quote;
use App\Factory\QuoteInvitationFactory;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Quote;
use App\Models\QuoteInvitation;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class CreateQuoteInvitations implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $quote;
private $company;
/**
* Create a new job instance.
*
* @param Quote $quote
* @param Company $company
*/
public function __construct(Quote $quote, Company $company)
{
$this->quote = $quote;
$this->company = $company;
}
public function handle()
{
MultiDB::setDB($this->company->db);
$contacts = $this->quote->client->contacts;
$contacts->each(function ($contact) {
$invitation = QuoteInvitation::whereCompanyId($this->quote->company_id)
->whereClientContactId($contact->id)
->whereQuoteId($this->quote->id)
->first();
if (! $invitation && $contact->send) {
$ii = QuoteInvitationFactory::create($this->quote->company_id, $this->quote->user_id);
$ii->quote_id = $this->quote->id;
$ii->client_contact_id = $contact->id;
$ii->save();
} elseif ($invitation && ! $contact->send) {
$invitation->delete();
}
});
}
}

View File

@ -332,7 +332,7 @@ class MultiDB
$current_db = config('database.default');
foreach (self::$dbs as $db) {
if ($invite = $class::on($db)->whereRaw('BINARY `key`= ?', [$invitation_key])->exists()) {
if ($invite = $class::on($db)->where('key', $invitation_key)->exists()) {
self::setDb($db);
return true;
}

View File

@ -1,51 +0,0 @@
<?php
/**
* Invoice Ninja (https://creditninja.com).
*
* @link https://github.com/creditninja/creditninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://creditninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Listeners\Credit;
use App\Factory\CreditInvitationFactory;
use App\Libraries\MultiDB;
use App\Models\CreditInvitation;
use Illuminate\Contracts\Queue\ShouldQueue;
class CreateCreditInvitation implements ShouldQueue
{
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$credit = $event->credit;
$contacts = $credit->client->contacts;
$contacts->each(function ($contact) use ($credit) {
$invitation = CreditInvitation::whereCompanyId($credit->company_id)
->whereClientContactId($contact->id)
->whereCreditId($credit->id)
->first();
if (! $invitation && $contact->send_credit) {
$ii = CreditInvitationFactory::create($credit->company_id, $credit->user_id);
$ii->credit_id = $credit->id;
$ii->client_contact_id = $contact->id;
$ii->save();
} elseif ($invitation && ! $contact->send_credit) {
$invitation->delete();
}
});
}
}

View File

@ -1,51 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Listeners\Invoice;
use App\Factory\InvoiceInvitationFactory;
use App\Libraries\MultiDB;
use App\Models\InvoiceInvitation;
use Illuminate\Contracts\Queue\ShouldQueue;
class CreateInvoiceInvitation implements ShouldQueue
{
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$invoice = $event->invoice;
$contacts = $invoice->client->contacts;
$contacts->each(function ($contact) use ($invoice) {
$invitation = InvoiceInvitation::whereCompanyId($invoice->company_id)
->whereClientContactId($contact->id)
->whereInvoiceId($invoice->id)
->first();
if (! $invitation && $contact->send) {
$ii = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
$ii->invoice_id = $invoice->id;
$ii->client_contact_id = $contact->id;
$ii->save();
} elseif ($invitation && ! $contact->send) {
$invitation->delete();
}
});
}
}

View File

@ -14,10 +14,13 @@ namespace App\Listeners\Quote;
use App\Factory\QuoteInvitationFactory;
use App\Libraries\MultiDB;
use App\Models\QuoteInvitation;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
class CreateQuoteInvitation implements ShouldQueue
{
use MakesHash;
/**
* Handle the event.
*
@ -40,6 +43,7 @@ class CreateQuoteInvitation implements ShouldQueue
if (! $invitation && $contact->send_credit) {
$ii = QuoteInvitationFactory::create($quote->company_id, $quote->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->quote_id = $quote->id;
$ii->client_contact_id = $contact->id;
$ii->save();

View File

@ -239,10 +239,20 @@ class PaymentEmailEngine extends BaseEmailEngine
$data['$invoices'] = ['value' => $this->formatInvoices(), 'label' => ctrans('texts.invoices')];
$data['$invoice_references'] = ['value' => $this->formatInvoiceReferences(), 'label' => ctrans('texts.invoices')];
$data['$invoice'] = ['value' => $this->formatInvoice(), 'label' => ctrans('texts.invoices')];
return $data;
}
private function formatInvoice()
{
$invoice = '';
if($this->payment->invoices()->exists())
$invoice = ctrans('texts.invoice_number_short') . implode(",", $this->payment->invoices->pluck('number')->toArray());
return $invoice;
}
private function formatInvoices()
{
$invoice_list = '<br><br>';

View File

@ -72,7 +72,6 @@ class CompanyPresenter extends EntityPresenter
else
return "data:image/png;base64, ". base64_encode(file_get_contents(asset('images/new_logo.png'), false, stream_context_create($context_options)));
}
public function address($settings = null)

View File

@ -16,10 +16,13 @@ use App\Factory\CreditInvitationFactory;
use App\Models\Credit;
use App\Models\CreditInvitation;
use App\Services\AbstractService;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Str;
class CreateInvitations extends AbstractService
{
use MakesHash;
private $credit;
public function __construct(Credit $credit)
@ -46,6 +49,7 @@ class CreateInvitations extends AbstractService
if (! $invitation) {
$ii = CreditInvitationFactory::create($this->credit->company_id, $this->credit->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->credit_id = $this->credit->id;
$ii->client_contact_id = $contact->id;
$ii->save();

View File

@ -16,10 +16,13 @@ use App\Factory\InvoiceInvitationFactory;
use App\Models\Invoice;
use App\Models\InvoiceInvitation;
use App\Services\AbstractService;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Str;
class CreateInvitations extends AbstractService
{
use MakesHash;
private $invoice;
public function __construct(Invoice $invoice)
@ -48,6 +51,7 @@ class CreateInvitations extends AbstractService
if (! $invitation && $contact->send_email) {
$ii = InvoiceInvitationFactory::create($this->invoice->company_id, $this->invoice->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->invoice_id = $this->invoice->id;
$ii->client_contact_id = $contact->id;
$ii->save();
@ -61,6 +65,7 @@ class CreateInvitations extends AbstractService
$contact = $this->createBlankContact();
$ii = InvoiceInvitationFactory::create($this->invoice->company_id, $this->invoice->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->invoice_id = $this->invoice->id;
$ii->client_contact_id = $contact->id;
$ii->save();

View File

@ -83,7 +83,7 @@ class PdfMaker
/**
* Final method to get compiled HTML.
*
* @param bool $final @deprecated
* @param bool $final @deprecated // is it? i still see it being called elsewhere
* @return mixed
*/
public function getCompiledHTML($final = false)

View File

@ -15,10 +15,13 @@ use App\Factory\ClientContactFactory;
use App\Factory\QuoteInvitationFactory;
use App\Models\Quote;
use App\Models\QuoteInvitation;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Str;
class CreateInvitations
{
use MakesHash;
public $quote;
public function __construct(Quote $quote)
@ -47,6 +50,7 @@ class CreateInvitations
if (! $invitation && $contact->send_email) {
$ii = QuoteInvitationFactory::create($this->quote->company_id, $this->quote->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->quote_id = $this->quote->id;
$ii->client_contact_id = $contact->id;
$ii->save();

View File

@ -12,11 +12,14 @@
namespace App\Services\Recurring;
use App\Services\AbstractService;
use App\Utils\Traits\MakesHash;
use Exception;
use Illuminate\Support\Str;
class CreateRecurringInvitations extends AbstractService
{
use MakesHash;
private $entity;
private $entity_name;
@ -48,6 +51,7 @@ class CreateRecurringInvitations extends AbstractService
if (! $invitation && $contact->send_email) {
$ii = $this->invitation_factory::create($this->entity->company_id, $this->entity->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->{$this->entity_id_name} = $this->entity->id;
$ii->client_contact_id = $contact->id;
$ii->save();

View File

@ -77,9 +77,9 @@ trait MakesReminders
private function checkEndlessReminder($last_sent_date, $endless_reminder_frequency_id) :bool
{
nlog("endless date match = ".$this->addTimeInterval($last_sent_date, $endless_reminder_frequency_id));
nlog("Endless reminder bool = ");
nlog(Carbon::now()->startOfDay()->eq($this->addTimeInterval($last_sent_date, $endless_reminder_frequency_id)));
// nlog("endless date match = ".$this->addTimeInterval($last_sent_date, $endless_reminder_frequency_id));
// nlog("Endless reminder bool = ");
// nlog(Carbon::now()->startOfDay()->eq($this->addTimeInterval($last_sent_date, $endless_reminder_frequency_id)));
if (Carbon::now()->startOfDay()->eq($this->addTimeInterval($last_sent_date, $endless_reminder_frequency_id))) {
return true;

View File

@ -21,7 +21,7 @@ return [
'api_secret' => env('API_SECRET', ''),
'google_maps_api_key' => env('GOOGLE_MAPS_API_KEY'),
'google_analytics_url' => env('GOOGLE_ANALYTICS_URL', 'https://www.google-analytics.com/collect'),
'key_length' => 64,
'key_length' => 32,
'date_format' => 'Y-m-d',
'date_time_format' => 'Y-m-d H:i',
'daily_email_limit' => 300,

View File

@ -15,8 +15,6 @@ use App\DataMapper\CompanySettings;
use App\Events\Payment\PaymentWasCreated;
use App\Helpers\Invoice\InvoiceSum;
use App\Helpers\Invoice\InvoiceSumInclusive;
use App\Listeners\Credit\CreateCreditInvitation;
use App\Listeners\Invoice\CreateInvoiceInvitation;
use App\Models\Account;
use App\Models\Client;
use App\Models\ClientContact;
@ -203,8 +201,6 @@ class RandomDataSeeder extends Seeder
$invoice->save();
//event(new CreateInvoiceInvitation($invoice));
$invoice->service()->createInvitations()->markSent()->save();
$invoice->ledger()->updateInvoiceBalance($invoice->balance);
@ -257,7 +253,6 @@ class RandomDataSeeder extends Seeder
$credit->save();
//event(new CreateCreditInvitation($credit));
$credit->service()->createInvitations()->markSent()->save();
//$invoice->markSent()->save();

View File

@ -113,6 +113,7 @@ class InvitationTest extends TestCase
$this->assertNotNull($invoice->client->primary_contact);
$i = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
$i->key = $this->createDbHash(config('database.default'));
$i->client_contact_id = $client->primary_contact->first()->id;
$i->invoice_id = $invoice->id;
$i->save();

View File

@ -8,7 +8,7 @@
*
* @license https://opensource.org/licenses/AAL
*/
namespace Tests\Feature;
namespace Tests\Feature\Payments;
use App\DataMapper\ClientSettings;
use App\Factory\ClientFactory;

View File

@ -487,6 +487,7 @@ trait MockAccountData
if (! $invitation && $contact->send_email) {
$ii = InvoiceInvitationFactory::create($this->invoice->company_id, $this->invoice->user_id);
$ii->key = $this->createDbHash(config('database.default'));
$ii->invoice_id = $this->invoice->id;
$ii->client_contact_id = $contact->id;
$ii->save();

View File

@ -12,6 +12,7 @@ namespace Tests\Unit;
use App\Factory\InvoiceInvitationFactory;
use App\Models\CompanyToken;
use App\Utils\Traits\MakesHash;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Validation\ValidationException;
@ -22,7 +23,8 @@ class InvitationTest extends TestCase
{
use MockAccountData;
use DatabaseTransactions;
use MakesHash;
public function setUp() :void
{
parent::setUp();
@ -79,6 +81,7 @@ class InvitationTest extends TestCase
$new_invite = InvoiceInvitationFactory::create($this->invoice->company_id, $this->invoice->user_id);
$new_invite->client_contact_id = $contact->hashed_id;
$new_invite->key = $this->createDbHash(config('database.default'));
$invitations = $this->invoice->invitations()->get();