1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 20:22:42 +01:00

Revert refactor for whereHas

This commit is contained in:
David Bomba 2024-06-30 17:37:44 +10:00
parent 3cd1d7767f
commit ab23592b96
7 changed files with 140 additions and 30 deletions

View File

@ -152,22 +152,22 @@ class InvoiceFilters extends QueryFilters
{ {
return $this->builder->where(function ($query) { return $this->builder->where(function ($query) {
$query->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT]) $query->whereIn('invoices.status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
->where('is_deleted', 0) ->where('invoices.is_deleted', 0)
->where('balance', '>', 0) ->where('invoices.balance', '>', 0)
->where(function ($query) { ->orWhere(function ($query) {
$query->whereNull('due_date') $query->whereNull('invoices.due_date')
->orWhere(function ($q) { ->orWhere(function ($q) {
$q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0); $q->where('invoices.due_date', '>=', now()->startOfDay()->subSecond())->where('invoices.partial', 0);
}) })
->orWhere(function ($q) { ->orWhere(function ($q) {
$q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0); $q->where('invoices.partial_due_date', '>=', now()->startOfDay()->subSecond())->where('invoices.partial', '>', 0);
}); });
}) })
->orderByRaw('ISNULL(due_date), due_date ' . 'desc') ->orderByRaw('ISNULL(invoices.due_date), invoices.due_date ' . 'desc')
->orderByRaw('ISNULL(partial_due_date), partial_due_date ' . 'desc'); ->orderByRaw('ISNULL(invoices.partial_due_date), invoices.partial_due_date ' . 'desc');
}); });
} }
@ -337,10 +337,10 @@ class InvoiceFilters extends QueryFilters
// return $this->builder->orderByRaw('CAST(number AS UNSIGNED), number ' . $dir); // return $this->builder->orderByRaw('CAST(number AS UNSIGNED), number ' . $dir);
// return $this->builder->orderByRaw("number REGEXP '^[A-Za-z]+$',CAST(number as SIGNED INTEGER),CAST(REPLACE(number,'-','')AS SIGNED INTEGER) ,number"); // return $this->builder->orderByRaw("number REGEXP '^[A-Za-z]+$',CAST(number as SIGNED INTEGER),CAST(REPLACE(number,'-','')AS SIGNED INTEGER) ,number");
// return $this->builder->orderByRaw('ABS(number) ' . $dir); // return $this->builder->orderByRaw('ABS(number) ' . $dir);
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir); return $this->builder->orderByRaw("REGEXP_REPLACE(invoices.number,'[^0-9]+','')+0 " . $dir);
} }
return $this->builder->orderBy($sort_col[0], $dir); return $this->builder->orderBy("{$this->builder->getQuery()->from}.".$sort_col[0], $dir);
} }
/** /**

View File

@ -273,20 +273,11 @@ abstract class QueryFilters
public function filter_deleted_clients($value) public function filter_deleted_clients($value)
{ {
// if ($value == 'true') { if ($value == 'true') {
// return $this->builder->whereHas('client', function (Builder $query) { return $this->builder->whereHas('client', function (Builder $query) {
// $query->where('is_deleted', 0); $query->where('is_deleted', 0);
// });
// }
if($value == 'true')
{
return $this->builder->leftJoin('clients', function($join) {
$join->on("{$this->builder->getQuery()->from}.client_id", '=', 'clients.id')
->where('clients.is_deleted', 0);
}); });
}
}
return $this->builder; return $this->builder;
} }
@ -307,7 +298,7 @@ abstract class QueryFilters
{ {
return $this->builder->where(function ($query) { return $this->builder->where(function ($query) {
$query->whereHas('client', function ($sub_query) { $query->whereHas('client', function ($sub_query) {
$sub_query->where('is_deleted', 0); $sub_query->where('is_deleted', 0)->where('deleted_at', null);
})->orWhere('client_id', null); })->orWhere('client_id', null);
}); });
} }

View File

@ -937,7 +937,9 @@ class BaseController extends Controller
} elseif (in_array($this->entity_type, [Design::class, GroupSetting::class, PaymentTerm::class, TaskStatus::class])) { } elseif (in_array($this->entity_type, [Design::class, GroupSetting::class, PaymentTerm::class, TaskStatus::class])) {
// nlog($this->entity_type); // nlog($this->entity_type);
} else { } else {
$query->where('user_id', '=', $user->id)->orWhere('assigned_user_id', $user->id); $query->where(function ($q) use ($user){ //grouping these together improves query performance significantly)
$q->where('user_id', '=', $user->id)->orWhere('assigned_user_id', $user->id);
});
} }
} }

View File

@ -71,7 +71,7 @@ class ReminderJob implements ShouldQueue
->whereHas('company', function ($query) { ->whereHas('company', function ($query) {
$query->where('is_disabled', 0); $query->where('is_disabled', 0);
}) })
->with('invitations')->chunk(50, function ($invoices) { ->with('invitations')->chunk(200, function ($invoices) {
foreach ($invoices as $invoice) { foreach ($invoices as $invoice) {
$this->sendReminderForInvoice($invoice); $this->sendReminderForInvoice($invoice);
} }

View File

@ -129,7 +129,7 @@ class BaseModel extends Model
/** @var \App\Models\User $user */ /** @var \App\Models\User $user */
$user = auth()->user(); $user = auth()->user();
$query->where('company_id', $user->companyId()); $query->where("{$query->getQuery()->from}.company_id", $user->companyId());
return $query; return $query;
} }

View File

@ -107,7 +107,6 @@ use Laracasts\Presenter\PresentableTrait;
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $invitations * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $invitations
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
* @mixin \Eloquent * @mixin \Eloquent
* @mixin \Illuminate\Database\Eloquent\Builder * @mixin \Illuminate\Database\Eloquent\Builder
*/ */

View File

@ -11,7 +11,9 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Models\Client;
use App\Models\CompanyGateway; use App\Models\CompanyGateway;
use App\Models\Invoice;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\MockAccountData; use Tests\MockAccountData;
use Tests\TestCase; use Tests\TestCase;
@ -44,6 +46,122 @@ class ClientModelTest extends TestCase
} }
public function testNewWithoutAndDeletedClientFilters()
{
$this->invoice->amount = 10;
$this->invoice->balance = 10;
$this->invoice->status_id=2;
$this->invoice->date = now()->subDays(2);
$this->invoice->due_date = now()->addDays(2);
$this->invoice->save();
$cd = Client::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
]);
$cd2 = Client::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
]);
$invoice_count = Invoice::where('company_id', $this->company->id)->count();
$this->assertGreaterThan(0, $invoice_count);
$i = Invoice::factory()->create([
'client_id' => $cd->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'status_id' => 2,
'amount' => 10,
'balance' => 10,
'date' => now()->subDays(2)->format('Y-m-d'),
'due_date' => now()->addDays(5)->format('Y-m-d'),
]);
$i2 = Invoice::factory()->create([
'client_id' => $cd2->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'status_id' => 2,
'amount' => 10,
'balance' => 10,
'date' => now()->subDays(2)->format('Y-m-d'),
'due_date' => now()->addDays(5)->format('Y-m-d'),
]);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/invoices?status=active');
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals($invoice_count+2, count($arr['data']));
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/invoices?upcoming=true&status=active&include=client');
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals($invoice_count + 2, count($arr['data']));
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/invoices?upcoming=true&status=active&without_deleted_clients=true');
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals($invoice_count + 2, count($arr['data']));
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/invoices?upcoming=true&status=active&filter_deleted_clients=true');
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals($invoice_count + 2, count($arr['data']));
$cd2->is_deleted = true;
$cd2->save();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/invoices?upcoming=true&status=active&without_deleted_clients=true');
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals($invoice_count + 1, count($arr['data']));
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/invoices?upcoming=true&status=active&filter_deleted_clients=true');
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals($invoice_count + 1, count($arr['data']));
}
public function testPaymentMethodsWithCreditsEnforced() public function testPaymentMethodsWithCreditsEnforced()
{ {
@ -51,6 +169,6 @@ class ClientModelTest extends TestCase
$this->assertGreaterThan(0, CompanyGateway::count()); $this->assertGreaterThan(0, CompanyGateway::count());
$this->assertEquals(1, count($payment_methods)); $this->assertEquals(2, count($payment_methods));
} }
} }