Fixes for static analysis

This commit is contained in:
David Bomba 2023-04-27 10:19:55 +10:00
parent 7417a8f1e1
commit cc100de1bd
26 changed files with 332 additions and 101 deletions

View File

@ -52,8 +52,9 @@ class AccountCreated
// *
// * @return Channel|array
// */
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
// return new PrivateChannel('channel-name');
}
}

View File

@ -54,8 +54,8 @@ class ClientWasArchived
// *
// * @return Channel|array
// */
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -42,8 +42,8 @@ class CompanyDocumentsDeleted
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -53,8 +53,8 @@ class ContactLoggedIn
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -35,8 +35,8 @@ class DesignWasArchived
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -32,8 +32,8 @@ class DesignWasCreated
*
* @return PrivateChannel
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -32,8 +32,8 @@ class DesignWasDeleted
*
* @return PrivateChannel
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -32,8 +32,8 @@ class DesignWasRestored
*
* @return PrivateChannel
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -32,8 +32,8 @@ class DesignWasUpdated
*
* @return PrivateChannel
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -56,6 +56,6 @@ class DocumentWasArchived
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
return [];
}
}

View File

@ -54,10 +54,10 @@ class InvoiceWasCreated implements ShouldBroadcast
*
* @return PrivateChannel|array
*/
// public function broadcastOn()
// {
// return ['simple-channel'];
// }
public function broadcastOn()
{
return [];
}
// /**

View File

@ -51,8 +51,8 @@ class MethodDeleted
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -45,8 +45,8 @@ class SubscriptionWasCreated
*
* @return \Illuminate\Broadcasting\Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -35,8 +35,8 @@ class UserLoggedIn
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -35,8 +35,8 @@ class UserWasArchived
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -35,8 +35,8 @@ class UserWasCreated
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -57,8 +57,8 @@ class UserWasDeleted
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -57,8 +57,8 @@ class UserWasRestored
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -57,8 +57,8 @@ class UserWasUpdated
*
* @return Channel|array
*/
// public function broadcastOn()
// {
// return new PrivateChannel('channel-name');
// }
public function broadcastOn()
{
return [];
}
}

View File

@ -54,7 +54,6 @@ class LockedInvoiceRule implements Rule
switch ($lock_invoices) {
case 'off':
return true;
break;
case 'when_sent':
if ($this->invoice->status_id == Invoice::STATUS_SENT) {
return false;
@ -62,17 +61,14 @@ class LockedInvoiceRule implements Rule
return true;
break;
case 'when_paid':
if ($this->invoice->status_id == Invoice::STATUS_PAID) {
return false;
}
return true;
break;
default:
return true;
break;
}
}
}

View File

@ -12,6 +12,7 @@
namespace App\Jobs\Util;
use App\DataMapper\InvoiceItem;
use App\Factory\InvoiceFactory;
use App\Jobs\Entity\EmailEntity;
use App\Jobs\Ninja\TransactionLog;
use App\Libraries\MultiDB;
@ -111,6 +112,11 @@ class ReminderJob implements ShouldQueue
private function sendReminderForInvoice($invoice)
{
App::forgetInstance('translator');
$t = app('translator');
$t->replace(Ninja::transformTranslations($invoice->client->getMergedSettings()));
App::setLocale($invoice->client->locale());
if ($invoice->isPayable()) {
//Attempts to prevent duplicates from sending
if ($invoice->reminder_last_sent && Carbon::parse($invoice->reminder_last_sent)->startOfDay()->eq(now()->startOfDay())) {
@ -121,7 +127,14 @@ class ReminderJob implements ShouldQueue
$reminder_template = $invoice->calculateTemplate('invoice');
nlog("reminder template = {$reminder_template}");
$invoice->service()->touchReminder($reminder_template)->save();
$invoice = $this->calcLateFee($invoice, $reminder_template);
$fees = $this->calcLateFee($invoice, $reminder_template);
if(in_array($invoice->client->getSetting('lock_invoices'), ['when_sent','when_paid'])) {
return $this->addFeeToNewInvoice($invoice, $reminder_template, $fees);
}
else
$invoice = $this->setLateFee($invoice, $fees[0], $fees[1]);
//20-04-2022 fixes for endless reminders - generic template naming was wrong
$enabled_reminder = 'enable_'.$reminder_template;
@ -148,14 +161,88 @@ class ReminderJob implements ShouldQueue
}
}
private function addFeeToNewInvoice(Invoice $over_due_invoice, string $reminder_template, array $fees): void
{
$amount = $fees[0];
$percent = $fees[1];
$temp_invoice_balance = $over_due_invoice->balance;
if ($amount <= 0 && $percent <= 0) {
return;
}
$fee = $amount;
if ($over_due_invoice->partial > 0) {
$fee += round($over_due_invoice->partial * $percent / 100, 2);
} else {
$fee += round($over_due_invoice->balance * $percent / 100, 2);
}
$invoice = InvoiceFactory::create($over_due_invoice->company_id, $over_due_invoice->user_id);
$invoice->client_id = $invoice->client_id;
$invoice->date = now()->format('Y-m-d');
$invoice->due_date = now()->format('Y-m-d');
$invoice_item = new InvoiceItem();
$invoice_item->type_id = '5';
$invoice_item->product_key = trans('texts.fee');
$invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->translateDate(now()->startOfDay(), $over_due_invoice->client->date_format(), $over_due_invoice->client->locale())]);
$invoice_item->quantity = 1;
$invoice_item->cost = $fee;
$invoice_items = [];
$invoice_items[] = $invoice_item;
$invoice->line_items = $invoice_items;
/**Refresh Invoice values*/
$invoice = $invoice->calc()->getInvoice();
$invoice->service()
->createInvitations()
->applyNumber()
->markSent()
->save();
nlog('adjusting client balance and invoice balance by #'.$invoice->number.' '.$invoice->balance);
$invoice->client->service()->updateBalance($invoice->balance);
$invoice->ledger()->updateInvoiceBalance($invoice->balance, "Late Fee Adjustment for invoice {$invoice->number}");
$invoice->service()->touchPdf(true);
$enabled_reminder = 'enable_'.$reminder_template;
if ($reminder_template == 'endless_reminder') {
$enabled_reminder = 'enable_reminder_endless';
}
if (in_array($reminder_template, ['reminder1', 'reminder2', 'reminder3', 'reminder_endless', 'endless_reminder']) &&
$invoice->client->getSetting($enabled_reminder) &&
$invoice->client->getSetting('send_reminders') &&
(Ninja::isSelfHost() || $invoice->company->account->isPaidHostedClient())) {
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
if ($invitation->contact && !$invitation->contact->trashed() && $invitation->contact->email) {
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
nlog("Firing reminder email for invoice {$invoice->number} - {$reminder_template}");
$invoice->entityEmailEvent($invitation, $reminder_template);
}
});
}
$invoice->service()->setReminder()->save();
}
/**
* Calculates the late if - if any - and rebuilds the invoice
*
* @param Invoice $invoice
* @param string $template
* @return Invoice
* @return array
*/
private function calcLateFee($invoice, $template): Invoice
private function calcLateFee($invoice, $template): array
{
$late_fee_amount = 0;
$late_fee_percent = 0;
@ -183,7 +270,8 @@ class ReminderJob implements ShouldQueue
break;
}
return $this->setLateFee($invoice, $late_fee_amount, $late_fee_percent);
return [$late_fee_amount, $late_fee_percent];
// return $this->setLateFee($invoice, $late_fee_amount, $late_fee_percent);
}
/**
@ -197,10 +285,6 @@ class ReminderJob implements ShouldQueue
*/
private function setLateFee($invoice, $amount, $percent): Invoice
{
App::forgetInstance('translator');
$t = app('translator');
$t->replace(Ninja::transformTranslations($invoice->client->getMergedSettings()));
App::setLocale($invoice->client->locale());
$temp_invoice_balance = $invoice->balance;
@ -236,16 +320,6 @@ class ReminderJob implements ShouldQueue
$invoice->client->service()->updateBalance($invoice->balance - $temp_invoice_balance);
$invoice->ledger()->updateInvoiceBalance($invoice->balance - $temp_invoice_balance, "Late Fee Adjustment for invoice {$invoice->number}");
// $transaction = [
// 'invoice' => $invoice->transaction_event(),
// 'payment' => [],
// 'client' => $invoice->client->transaction_event(),
// 'credit' => [],
// 'metadata' => ['setLateFee'],
// ];
// TransactionLog::dispatch(TransactionEvent::CLIENT_STATUS, $transaction, $invoice->company->db);
$invoice->service()->touchPdf(true);
return $invoice;

View File

@ -11,7 +11,6 @@
namespace App\Models;
use App\DataMapper\ClientSettings;
use App\Jobs\Util\WebhookHandler;
use App\Models\Traits\Excludable;
use App\Utils\Traits\MakesHash;
@ -39,6 +38,7 @@ use Illuminate\Support\Str;
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude(array $excludeable)
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel scopeExclude()
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel find()
* @method \App\Models\Company company()
* @method int companyId()
* @method Builder|static exclude($columns)

View File

@ -796,7 +796,7 @@ class Client extends BaseModel implements HasLocalePreference
if ($pm['gateway_type_id'] == GatewayType::CREDIT_CARD) {
$cg = CompanyGateway::find($pm['company_gateway_id']);
if ($cg && ! property_exists($cg->fees_and_limits, GatewayType::CREDIT_CARD)) {
if ($cg && ! property_exists($cg->fees_and_limits, strval(GatewayType::CREDIT_CARD))) {
$fees_and_limits = $cg->fees_and_limits;
$fees_and_limits->{GatewayType::CREDIT_CARD} = new FeesAndLimits;
$cg->fees_and_limits = $fees_and_limits;

View File

@ -92,6 +92,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Eloquent\Builder|CompanyGateway whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder|CompanyGateway withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|CompanyGateway withoutTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|CompanyGateway find()
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientGatewayToken> $client_gateway_tokens

View File

@ -27,6 +27,7 @@ namespace App\Models;
* @method static \Illuminate\Database\Eloquent\Builder|Timezone whereLocation($value)
* @method static \Illuminate\Database\Eloquent\Builder|Timezone whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Timezone whereUtcOffset($value)
* @method static \Illuminate\Database\Eloquent\Builder|Timezone find()
* @mixin \Eloquent
*/
class Timezone extends StaticModel

View File

@ -11,11 +11,18 @@
namespace Tests\Unit;
use App\DataMapper\InvoiceItem;
use App\Models\Invoice;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\MockAccountData;
use Tests\TestCase;
use App\Models\User;
use App\Models\Client;
use App\Models\Account;
use App\Models\Company;
use App\Models\Invoice;
use Tests\MockAccountData;
use App\Jobs\Util\ReminderJob;
use App\DataMapper\InvoiceItem;
use App\DataMapper\FeesAndLimits;
use App\DataMapper\CompanySettings;
use Illuminate\Foundation\Testing\DatabaseTransactions;
/**
* @test
@ -25,13 +32,164 @@ class LateFeeTest extends TestCase
use DatabaseTransactions;
use MockAccountData;
public $faker;
protected function setUp() :void
{
parent::setUp();
$this->faker = \Faker\Factory::create();
$this->withoutMiddleware(
ThrottleRequests::class
);
$this->makeTestData();
$this->withoutExceptionHandling();
}
private function buildData($settings)
{
$this->account = Account::factory()->create([
'hosted_client_count' => 1000,
'hosted_company_count' => 1000,
]);
$this->account->num_users = 3;
$this->account->save();
$this->user = User::factory()->create([
'account_id' => $this->account->id,
'confirmation_code' => 'xyz123',
'email' => $this->faker->unique()->safeEmail(),
]);
$this->company = Company::factory()->create([
'account_id' => $this->account->id,
'settings' => $settings,
]);
$this->company->settings = $settings;
$this->company->save();
$settings = new \stdClass;
$settings->currency_id = '1';
$this->client = Client::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'is_deleted' => 0,
'settings' => $settings,
]);
}
public function testLateFeeAdded()
{
$settings = CompanySettings::defaults();
$settings->client_online_payment_notification = false;
$settings->client_manual_payment_notification = false;
$settings->late_fee_amount1 = 10;
$settings->late_fee_percent1 = 0;
$settings->lock_invoices = 'off';
$settings->enable_reminder1 = true;
$settings->num_days_reminder1 = 10;
$settings->schedule_reminder1 = 'after_due_date';
$this->buildData($settings);
$i = Invoice::factory()->create([
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'amount' => 0,
'balance' => 0,
'status_id' => 2,
'total_taxes' => 1,
'date' => now()->format('Y-m-d'),
'due_date' => now()->subDays(10)->format('Y-m-d'),
'terms' => 'nada',
'discount' => 0,
'tax_rate1' => 0,
'tax_rate2' => 0,
'tax_rate3' => 0,
'tax_name1' => '',
'tax_name2' => '',
'tax_name3' => '',
'uses_inclusive_taxes' => false,
'line_items' => $this->buildLineItems(),
]);
$i = $i->calc()->getInvoice();
$i->service()->applyNumber()->createInvitations()->save();
$this->assertEquals(10, $i->amount);
$reflectionMethod = new \ReflectionMethod(ReminderJob::class, 'sendReminderForInvoice');
$reflectionMethod->setAccessible(true);
$reflectionMethod->invokeArgs(new ReminderJob(), [$i]);
$i->fresh();
$this->assertEquals(20, $i->balance);
}
public function testLateFeeAddedToNewInvoiceWithLockedInvoiceConfi()
{
$settings = CompanySettings::defaults();
$settings->client_online_payment_notification = false;
$settings->client_manual_payment_notification = false;
$settings->late_fee_amount1 = 10;
$settings->late_fee_percent1 = 0;
$settings->lock_invoices = 'when_sent';
$settings->enable_reminder1 = true;
$settings->num_days_reminder1 = 10;
$settings->schedule_reminder1 = 'after_due_date';
$this->buildData($settings);
$i = Invoice::factory()->create([
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'amount' => 0,
'balance' => 0,
'status_id' => 2,
'total_taxes' => 1,
'date' => now()->format('Y-m-d'),
'due_date' => now()->subDays(10)->format('Y-m-d'),
'terms' => 'nada',
'discount' => 0,
'tax_rate1' => 0,
'tax_rate2' => 0,
'tax_rate3' => 0,
'tax_name1' => '',
'tax_name2' => '',
'tax_name3' => '',
'uses_inclusive_taxes' => false,
'line_items' => $this->buildLineItems(),
]);
$i = $i->calc()->getInvoice();
$i->service()->applyNumber()->createInvitations()->save();
$this->assertEquals(10, $i->amount);
$reflectionMethod = new \ReflectionMethod(ReminderJob::class, 'sendReminderForInvoice');
$reflectionMethod->setAccessible(true);
$reflectionMethod->invokeArgs(new ReminderJob(), [$i]);
$i->fresh();
$this->assertEquals(10, $i->balance);
}
public function testLateFeeBalances()
{
$this->assertEquals(10, $this->client->balance);