From 7ed709d1a27d3eecfa35177cf2d675e6c0bf725d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 3 Jan 2022 12:14:24 +1100 Subject: [PATCH] Tax Rate Filters --- app/Filters/TaxRateFilters.php | 115 ++++++++++++ app/Http/Controllers/TaxRateController.php | 5 +- app/Models/TaxRate.php | 4 +- tests/Feature/TaxRateApiTest.php | 197 +++++++++++++++++++++ tests/MockAccountData.php | 13 ++ 5 files changed, 331 insertions(+), 3 deletions(-) create mode 100644 app/Filters/TaxRateFilters.php create mode 100644 tests/Feature/TaxRateApiTest.php diff --git a/app/Filters/TaxRateFilters.php b/app/Filters/TaxRateFilters.php new file mode 100644 index 000000000000..59987a64c646 --- /dev/null +++ b/app/Filters/TaxRateFilters.php @@ -0,0 +1,115 @@ +builder; + } + + return $this->builder->where(function ($query) use ($filter) { + $query->where('tax_rates.name', 'like', '%'.$filter.'%'); + }); + + } + + /** + * Filters the list based on the status + * archived, active, deleted. + * + * @param string filter + * @return Builder + */ + public function status(string $filter = '') : Builder + { + if (strlen($filter) == 0) { + return $this->builder; + } + + $table = 'tax_rates'; + $filters = explode(',', $filter); + + return $this->builder->where(function ($query) use ($filters, $table) { + $query->whereNull($table.'.id'); + + if (in_array(parent::STATUS_ACTIVE, $filters)) { + $query->orWhereNull($table.'.deleted_at'); + } + + if (in_array(parent::STATUS_ARCHIVED, $filters)) { + $query->orWhere(function ($query) use ($table) { + $query->whereNotNull($table.'.deleted_at'); + + if (! in_array($table, ['users'])) { + $query->where($table.'.is_deleted', '=', 0); + } + }); + } + + if (in_array(parent::STATUS_DELETED, $filters)) { + $query->orWhere($table.'.is_deleted', '=', 1); + } + }); + } + + /** + * Sorts the list based on $sort. + * + * @param string sort formatted as column|asc + * @return Builder + */ + public function sort(string $sort) : Builder + { + $sort_col = explode('|', $sort); + + return $this->builder->orderBy($sort_col[0], $sort_col[1]); + } + + /** + * Returns the base query. + * + * @param int company_id + * @param User $user + * @return Builder + * @deprecated + */ + public function baseQuery(int $company_id, User $user) : Builder + { + return $this->builder; + } + + /** + * Filters the query by the users company ID. + * + * @return Illuminate\Database\Query\Builder + */ + public function entityFilter() + { + return $this->builder->company(); + } +} diff --git a/app/Http/Controllers/TaxRateController.php b/app/Http/Controllers/TaxRateController.php index d874aabe89ac..1b4638488bbc 100644 --- a/app/Http/Controllers/TaxRateController.php +++ b/app/Http/Controllers/TaxRateController.php @@ -12,6 +12,7 @@ namespace App\Http\Controllers; use App\Factory\TaxRateFactory; +use App\Filters\TaxRateFilters; use App\Http\Requests\TaxRate\CreateTaxRateRequest; use App\Http\Requests\TaxRate\DestroyTaxRateRequest; use App\Http\Requests\TaxRate\EditTaxRateRequest; @@ -79,9 +80,9 @@ class TaxRateController extends BaseController * * @return Response */ - public function index() + public function index(TaxRateFilters $filters) { - $tax_rates = TaxRate::scope(); + $tax_rates = TaxRate::filter($filters); return $this->listResponse($tax_rates); } diff --git a/app/Models/TaxRate.php b/app/Models/TaxRate.php index b2737c6b6cc1..5f72f75759ec 100644 --- a/app/Models/TaxRate.php +++ b/app/Models/TaxRate.php @@ -11,6 +11,7 @@ namespace App\Models; +use App\Models\Filterable; use App\Utils\Traits\MakesHash; use Illuminate\Database\Eloquent\SoftDeletes; @@ -18,7 +19,8 @@ class TaxRate extends BaseModel { use MakesHash; use SoftDeletes; - + use Filterable; + protected $fillable = [ 'name', 'rate', diff --git a/tests/Feature/TaxRateApiTest.php b/tests/Feature/TaxRateApiTest.php new file mode 100644 index 000000000000..a0acc34f4db7 --- /dev/null +++ b/tests/Feature/TaxRateApiTest.php @@ -0,0 +1,197 @@ +makeTestData(); + + Session::start(); + + $this->faker = \Faker\Factory::create(); + + Model::reguard(); + } + + public function testTaxRatePost() + { + $rate_name = $this->faker->firstName; + + $data = [ + 'name' => $rate_name, + 'rate' => 10 + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tax_rates', $data); + + $arr = $response->json(); + $response->assertStatus(200); + + $this->assertEquals($rate_name, $arr['data']['name']); + + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->put('/api/v1/tax_rates/'.$arr['data']['id'], $data); + + $response->assertStatus(200); + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tax_rates', $data); + + $arr = $response->json(); + }catch(ValidationException $e){ + $response->assertStatus(302); + } + + $this->assertNotEmpty($arr['data']['name']); + } + + public function testTaxRatePostWithActionStart() + { + $data = [ + 'name' => $this->faker->firstName, + 'rate' => rand(1,20), + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tax_rates', $data); + + $arr = $response->json(); + $response->assertStatus(200); + + } + + public function testTaxRatePut() + { + $data = [ + 'name' => $this->faker->firstName, + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->put('/api/v1/tax_rates/'.$this->encodePrimaryKey($this->tax_rate->id), $data); + + $response->assertStatus(200); + } + + + public function testTaxRatesGet() + { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/tax_rates'); + + $response->assertStatus(200); + } + + + public function testTaxRateGet() + { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/tax_rates/'.$this->encodePrimaryKey($this->tax_rate->id)); + + $response->assertStatus(200); + } + + public function testTaxRateNotArchived() + { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/tax_rates/'.$this->encodePrimaryKey($this->tax_rate->id)); + + $arr = $response->json(); + + $this->assertEquals(0, $arr['data']['archived_at']); + } + + public function testTaxRateArchived() + { + $data = [ + 'ids' => [$this->encodePrimaryKey($this->tax_rate->id)], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tax_rates/bulk?action=archive', $data); + + $arr = $response->json(); + + $this->assertNotNull($arr['data'][0]['archived_at']); + } + + public function testTaxRateRestored() + { + $data = [ + 'ids' => [$this->encodePrimaryKey($this->tax_rate->id)], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tax_rates/bulk?action=restore', $data); + + $arr = $response->json(); + + $this->assertEquals(0, $arr['data'][0]['archived_at']); + } + + public function testTaxRateDeleted() + { + $data = [ + 'ids' => [$this->encodePrimaryKey($this->tax_rate->id)], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/tax_rates/bulk?action=delete', $data); + + $arr = $response->json(); + + $this->assertTrue($arr['data'][0]['is_deleted']); + } +} diff --git a/tests/MockAccountData.php b/tests/MockAccountData.php index 4056e6a828a5..7983a9d9d4de 100644 --- a/tests/MockAccountData.php +++ b/tests/MockAccountData.php @@ -42,6 +42,7 @@ use App\Models\RecurringInvoice; use App\Models\RecurringQuote; use App\Models\Task; use App\Models\TaskStatus; +use App\Models\TaxRate; use App\Models\User; use App\Models\Vendor; use App\Models\VendorContact; @@ -136,6 +137,13 @@ trait MockAccountData */ public $cu; + /** + * @var + */ + + public $tax_rate; + + /** * */ @@ -337,6 +345,11 @@ trait MockAccountData 'company_id' => $this->company->id, ]); + $this->tax_rate = TaxRate::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $this->company->id, + ]); + $gs = new GroupSetting; $gs->name = 'Test'; $gs->company_id = $this->client->company_id;