From 73861f814cc9e2f210169d4b844ac7eeb1e164c7 Mon Sep 17 00:00:00 2001 From: Peter Papp Date: Thu, 22 Apr 2021 09:33:52 +0200 Subject: [PATCH] Searching backend --- .../Controllers/Oasis/ClientController.php | 20 +++++++- .../Controllers/Oasis/InvoiceController.php | 18 ++++++++ app/Models/Oasis/Client.php | 27 ++++++++++- app/Models/Oasis/Invoice.php | 26 ++++++++++- database/factories/Oasis/ClientFactory.php | 22 ++++----- routes/oasis.php | 2 + tests/Feature/Oasis/OasisClientTest.php | 32 ++++++++++++- tests/Feature/Oasis/OasisInvoiceTest.php | 46 +++++++++++++++---- 8 files changed, 166 insertions(+), 27 deletions(-) diff --git a/app/Http/Controllers/Oasis/ClientController.php b/app/Http/Controllers/Oasis/ClientController.php index 5edc45fc..be49afc2 100644 --- a/app/Http/Controllers/Oasis/ClientController.php +++ b/app/Http/Controllers/Oasis/ClientController.php @@ -2,10 +2,10 @@ namespace App\Http\Controllers\Oasis; -use App\Http\Controllers\Controller; use App\Http\Resources\Oasis\OasisClientCollection; +use App\Http\Controllers\Controller; +use App\Models\Oasis\Client; use Auth; -use Illuminate\Http\Request; class ClientController extends Controller { @@ -18,4 +18,20 @@ class ClientController extends Controller new OasisClientCollection(Auth::user()->clients), 200 ); } + + /** + * @return mixed + */ + public function search() + { + $query = remove_accents(request()->input('query')); + + $results = Client::search($query) + ->where('user_id', request()->user()->id) + ->get(); + + return response( + new OasisClientCollection($results), 200 + ); + } } diff --git a/app/Http/Controllers/Oasis/InvoiceController.php b/app/Http/Controllers/Oasis/InvoiceController.php index fef9fa04..22f54be5 100644 --- a/app/Http/Controllers/Oasis/InvoiceController.php +++ b/app/Http/Controllers/Oasis/InvoiceController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Oasis; use App\Http\Controllers\Controller; use App\Http\Resources\Oasis\OasisInvoiceCollection; +use App\Models\Oasis\Invoice; use Auth; use Illuminate\Http\Request; @@ -28,4 +29,21 @@ class InvoiceController extends Controller new OasisInvoiceCollection(Auth::user()->advanceInvoices), 200 ); } + + /** + * @return mixed + */ + public function search() + { + $query = remove_accents(request()->input('query')); + + $results = Invoice::search($query) + ->where('user_id', request()->user()->id) + ->where('invoice_type', request()->input('type')) + ->get(); + + return response( + new OasisInvoiceCollection($results), 200 + ); + } } diff --git a/app/Models/Oasis/Client.php b/app/Models/Oasis/Client.php index 36bd2232..45aeaa54 100644 --- a/app/Models/Oasis/Client.php +++ b/app/Models/Oasis/Client.php @@ -6,10 +6,12 @@ use App\Models\User; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; +use Laravel\Scout\Searchable; +use TeamTNT\TNTSearch\Indexer\TNTIndexer; class Client extends Model { - use HasFactory; + use HasFactory, Searchable; public $guarded = ['id']; @@ -27,12 +29,33 @@ class Client extends Model return $this->hasMany(Invoice::class, 'client_id', 'id'); } + /** + * Index file + * + * @return array + */ + public function toSearchableArray() + { + $array = $this->toArray(); + + $client_name = Str::slug($array['name'], ' '); + $client_email = Str::slug($array['email'], ' '); + + return [ + 'id' => $this->id, + 'clientName' => $array['name'], + 'clientNameNgrams' => utf8_encode((new TNTIndexer)->buildTrigrams(implode(', ', [$client_name]))), + 'clientEmail' => $array['email'], + 'clientEmailNgrams' => utf8_encode((new TNTIndexer)->buildTrigrams(implode(', ', [$client_email]))), + ]; + } + protected static function boot() { parent::boot(); static::creating(function ($order) { - $order->id = Str::uuid(); + $order->id = (string) Str::uuid(); }); } } diff --git a/app/Models/Oasis/Invoice.php b/app/Models/Oasis/Invoice.php index 523ef667..3205efa4 100644 --- a/app/Models/Oasis/Invoice.php +++ b/app/Models/Oasis/Invoice.php @@ -7,10 +7,12 @@ use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; +use Laravel\Scout\Searchable; +use TeamTNT\TNTSearch\Indexer\TNTIndexer; class Invoice extends Model { - use HasFactory; + use HasFactory, Searchable; protected $casts = [ 'items' => 'array', @@ -34,12 +36,32 @@ class Invoice extends Model return $this->hasOne(Client::class, 'id', 'user_id'); } + /** + * Index file + * + * @return array + */ + public function toSearchableArray() + { + $array = $this->toArray(); + + $client_name = Str::slug($array['client']['name'], ' '); + + return [ + 'id' => $this->id, + 'clientName' => $array['client']['name'], + 'clientNameNgrams' => utf8_encode((new TNTIndexer)->buildTrigrams(implode(', ', [$client_name]))), + 'invoiceNumber' => $array['invoice_number'], + 'invoiceNumberNgrams' => utf8_encode((new TNTIndexer)->buildTrigrams(implode(', ', [$array['invoice_number']]))), + ]; + } + protected static function boot() { parent::boot(); static::creating(function ($invoice) { - $invoice->id = Str::uuid(); + $invoice->id = (string)Str::uuid(); $invoice->delivery_at = $invoice->created_at; $invoice->due_at = Carbon::parse($invoice->created_at)->addWeeks(2); diff --git a/database/factories/Oasis/ClientFactory.php b/database/factories/Oasis/ClientFactory.php index 6a1205a1..8c950ec5 100644 --- a/database/factories/Oasis/ClientFactory.php +++ b/database/factories/Oasis/ClientFactory.php @@ -22,21 +22,21 @@ class ClientFactory extends Factory public function definition() { return [ - 'id' => $this->faker->uuid, - 'user_id' => $this->faker->uuid, - 'name' => $this->faker->company, + 'id' => $this->faker->uuid, + 'user_id' => $this->faker->uuid, + 'name' => $this->faker->company, 'email' => $this->faker->email, 'phone_number' => $this->faker->phoneNumber, - 'address' => $this->faker->address, - 'city' => $this->faker->city, - 'postal_code' => $this->faker->postcode, - 'country' => $this->faker->randomElement( + 'address' => $this->faker->address, + 'city' => $this->faker->city, + 'postal_code' => $this->faker->postcode, + 'country' => $this->faker->randomElement( ['SK', 'CZ', 'DE', 'FR'] ), - 'ico' => $this->faker->numberBetween(11111111, 99999999), - 'dic' => $this->faker->numberBetween(11111111, 99999999), - 'ic_dph' => 'CZ' . $this->faker->numberBetween(1111111111, 9999999999), - 'created_at' => $this->faker->dateTimeBetween( + 'ico' => $this->faker->numberBetween(11111111, 99999999), + 'dic' => $this->faker->numberBetween(11111111, 99999999), + 'ic_dph' => 'CZ' . $this->faker->numberBetween(1111111111, 9999999999), + 'created_at' => $this->faker->dateTimeBetween( $startDate = '-6 months', $endDate = 'now', $timezone = null ), ]; diff --git a/routes/oasis.php b/routes/oasis.php index e4fc9f1a..e0b579cf 100644 --- a/routes/oasis.php +++ b/routes/oasis.php @@ -25,11 +25,13 @@ Route::group(['middleware' => 'api', 'prefix' => '/api/oasis'], function () { Route::group(['prefix' => 'invoices'], function () { Route::get('/regular', [InvoiceController::class, 'get_all_regular_invoices']); Route::get('/advance', [InvoiceController::class, 'get_all_advance_invoices']); + Route::get('/search', [InvoiceController::class, 'search']); }); // Clients Route::group(['prefix' => 'clients'], function () { Route::get('/', [ClientController::class, 'index']); + Route::get('/search', [ClientController::class, 'search']); }); }); diff --git a/tests/Feature/Oasis/OasisClientTest.php b/tests/Feature/Oasis/OasisClientTest.php index 06933ee2..ec834f05 100644 --- a/tests/Feature/Oasis/OasisClientTest.php +++ b/tests/Feature/Oasis/OasisClientTest.php @@ -2,10 +2,10 @@ namespace Tests\Feature\Oasis; -use App\Models\Oasis\Client; -use App\Models\User; use Illuminate\Foundation\Testing\DatabaseMigrations; +use App\Models\Oasis\Client; use Laravel\Sanctum\Sanctum; +use App\Models\User; use Tests\TestCase; class OasisClientTest extends TestCase @@ -45,4 +45,32 @@ class OasisClientTest extends TestCase 'id' => $client->id, ])->assertStatus(200); } + + /** + * @test + */ + public function it_search_user_client() + { + $user = User::factory(User::class) + ->create(['role' => 'user']); + + Sanctum::actingAs($user); + + $client = Client::factory(Client::class) + ->create([ + 'user_id' => $user->id, + 'name' => 'VueFileManager Inc.', + 'email' => 'info@company.com', + ]); + + $this->getJson('/api/oasis/clients/search?query=vue') + ->assertJsonFragment([ + 'id' => $client->id, + ])->assertStatus(200); + + $this->getJson('/api/oasis/clients/search?query=info') + ->assertJsonFragment([ + 'id' => $client->id, + ])->assertStatus(200); + } } diff --git a/tests/Feature/Oasis/OasisInvoiceTest.php b/tests/Feature/Oasis/OasisInvoiceTest.php index d7c5987b..a4280805 100644 --- a/tests/Feature/Oasis/OasisInvoiceTest.php +++ b/tests/Feature/Oasis/OasisInvoiceTest.php @@ -2,15 +2,16 @@ namespace Tests\Feature\Oasis; -use App\Models\Oasis\Invoice; -use App\Models\User; use Illuminate\Foundation\Testing\DatabaseMigrations; +use App\Models\Oasis\Invoice; +use Illuminate\Bus\Queueable; use Laravel\Sanctum\Sanctum; +use App\Models\User; use Tests\TestCase; class OasisInvoiceTest extends TestCase { - use DatabaseMigrations; + use DatabaseMigrations, Queueable; /** * @test @@ -143,12 +144,10 @@ class OasisInvoiceTest extends TestCase 'invoice_type' => 'regular_invoice' ]); - $response = $this->getJson('/api/oasis/invoices/regular') + $this->getJson('/api/oasis/invoices/regular') ->assertJsonFragment([ - 'id' => $invoice->id, + 'id' => $invoice->id, ])->assertStatus(200); - - dd(json_decode($response->content(), true)); } /** @@ -169,7 +168,38 @@ class OasisInvoiceTest extends TestCase $this->getJson('/api/oasis/invoices/advance') ->assertJsonFragment([ - 'id' => $invoice->id, + 'id' => $invoice->id, + ])->assertStatus(200); + } + + /** + * @test + */ + public function it_search_user_regular_invoice() + { + $user = User::factory(User::class) + ->create(['role' => 'user']); + + Sanctum::actingAs($user); + + Invoice::factory(Invoice::class) + ->create([ + 'user_id' => $user->id, + 'invoice_type' => 'regular_invoice', + 'invoice_number' => 2001212, + 'client' => [ + 'name' => 'VueFileManager Inc.', + ] + ]); + + $this->getJson('/api/oasis/invoices/search?type=regular_invoice&query=2001212') + ->assertJsonFragment([ + 'invoiceNumber' => '2001212', + ])->assertStatus(200); + + $this->getJson('/api/oasis/invoices/search?type=regular_invoice&query=Vue') + ->assertJsonFragment([ + 'invoiceNumber' => '2001212', ])->assertStatus(200); } }