1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00

Add filters for documents

This commit is contained in:
David Bomba 2024-02-28 21:15:43 +11:00
parent 2858ff8946
commit 3ad5de1d2c
6 changed files with 193 additions and 5 deletions

View File

@ -29,11 +29,13 @@ class DocumentFilters extends QueryFilters
*/
public function filter(string $filter = ''): Builder
{
if (strlen($filter) == 0) {
return $this->builder;
}
return $this->builder;
return $this->builder->where('name', 'like', '%'.$filter.'%');
}
/**
@ -47,9 +49,42 @@ class DocumentFilters extends QueryFilters
*/
public function client_id(string $client_id = ''): Builder
{
return $this->builder;
return $this->builder->where(function ($query) use ($client_id) {
$query->whereHasMorph('documentable', [
\App\Models\Invoice::class,
\App\Models\Quote::class,
\App\Models\Credit::class,
\App\Models\Expense::class,
\App\Models\Payment::class,
\App\Models\Task::class], function ($q2) use ($client_id) {
$q2->where('client_id', $this->decodePrimaryKey($client_id));
})->orWhereHasMorph('documentable', [\App\Models\Client::class], function ($q3) use ($client_id) {
$q3->where('id', $this->decodePrimaryKey($client_id));
});
});
}
public function type(string $types = '')
{
$types = explode(',', $types);
foreach ($types as $type)
{
match($type) {
'private' => $this->builder->where('is_public', 0),
'public' => $this->builder->where('is_public', 1),
'pdf' => $this->builder->where('type', 'pdf'),
'image' => $this->builder->whereIn('type', ['png','jpeg','jpg','gif','svg']),
'other' => $this->builder->whereNotIn('type', ['pdf','png','jpeg','jpg','gif','svg']),
default => $this->builder,
};
}
return $this->builder;
}
/**
* Sorts the list based on $sort.
*

View File

@ -208,6 +208,26 @@ class Document extends BaseModel
return ctrans('texts.document');
}
public function link()
{
$entity_id = $this->encodePrimaryKey($this->documentable_id);
match($this->documentable_type) {
'App\Models\Vendor' => $link = "vendors/{$entity_id}",
'App\Models\Project' => $link = "projects/{$entity_id}",
'invoices' => $link = "invoices/{$entity_id}/edit",
'App\Models\Quote' => $link = "quotes/{$entity_id}/edit",
'App\Models\Credit' => $link = "credits/{$entity_id}/edit",
'App\Models\Expense' => $link = "expenses/{$entity_id}/edit",
'App\Models\Payment' => $link = "payments/{$entity_id}/edit",
'App\Models\Task' => $link = "tasks/{$entity_id}/edit",
'App\Models\Client' => $link = "clients/{$entity_id}",
default => $link = ''
};
return $link;
}
public function compress(): mixed
{

View File

@ -52,6 +52,7 @@ class DocumentTransformer extends EntityTransformer
'created_at' => (int) $document->created_at,
'is_deleted' => (bool) false,
'is_public' => (bool) $document->is_public,
'link' => (string) $document->link(),
];
}
}

View File

@ -84,6 +84,7 @@ class SystemHealth
'trailing_slash' => (bool) self::checkUrlState(),
'file_permissions' => (string) self::checkFileSystem(),
'exchange_rate_api_not_configured' => (bool)self::checkCurrencySanity(),
'api_version' => (string) config('ninja.app_version'),
];
}

View File

@ -5240,6 +5240,7 @@ $lang = array(
'use_available_payments' => 'Use Available Payments',
'test_email_sent' => 'Successfully sent email',
'gateway_type' => 'Gateway Type',
'save_template_body' => 'Would you like to save this import mapping as a template for future use?',
);
return $lang;

View File

@ -11,13 +11,14 @@
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Task;
use App\Models\Document;
use Tests\MockAccountData;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Session;
use Tests\MockAccountData;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;
/**
* @test
@ -44,6 +45,135 @@ class DocumentsApiTest extends TestCase
Model::reguard();
}
public function testDocumentFilters()
{
Document::query()->withTrashed()->cursor()->each(function ($d){
$d->forceDelete();
});
$d = Document::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'name' => 'searchable.jpg',
'type' => 'jpg',
]);
$this->client->documents()->save($d);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/documents/{$d->hashed_id}?client_id={$this->client->hashed_id}");
$response->assertStatus(200);
$this->assertCount(1, $response->json());
}
public function testDocumentFilters2()
{
Document::query()->withTrashed()->cursor()->each(function ($d){
$d->forceDelete();
});
$d = Document::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'name' => 'searchable.jpg',
'type' => 'jpg',
]);
$this->task->documents()->save($d);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/documents/{$d->hashed_id}?client_id={$this->client->hashed_id}");
$response->assertStatus(200);
$this->assertCount(1, $response->json());
}
public function testDocumentFilters3()
{
Document::query()->withTrashed()->cursor()->each(function ($d){
$d->forceDelete();
});
$d = Document::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'name' => 'searchable.jpg',
'type' => 'jpg',
]);
$t = Task::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'client_id' => $this->client->id,
]);
$t->documents()->save($d);
$dd = Document::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'name' => 'searchable2.jpg',
'type' => 'jpg',
]);
$this->client->documents()->save($dd);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/documents?client_id={$this->client->hashed_id}");
$response->assertStatus(200);
$this->assertCount(2, $response->json()['data']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/documents?client_id={$this->client->hashed_id}&filter=craycray");
$response->assertStatus(200);
$this->assertCount(0, $response->json()['data']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/documents?client_id={$this->client->hashed_id}&filter=s");
$response->assertStatus(200);
$this->assertCount(2, $response->json()['data']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/documents?client_id={$this->client->hashed_id}&filter=searchable");
$response->assertStatus(200);
$this->assertCount(2, $response->json()['data']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/documents?client_id={$this->client->hashed_id}&filter=searchable2");
$response->assertStatus(200);
$this->assertCount(1, $response->json()['data']);
}
public function testIsPublicTypesForDocumentRequest()
{
$d = Document::factory()->create([