diff --git a/app/Filters/RecurringInvoiceFilters.php b/app/Filters/RecurringInvoiceFilters.php index d9655b975b63..82dd6fd1d0f8 100644 --- a/app/Filters/RecurringInvoiceFilters.php +++ b/app/Filters/RecurringInvoiceFilters.php @@ -12,6 +12,7 @@ namespace App\Filters; use App\Models\RecurringInvoice; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; /** @@ -121,4 +122,82 @@ class RecurringInvoiceFilters extends QueryFilters { return $this->builder->company(); } + + /** + * Filter based on line_items product_key + * + * @param string value Product keys + * @return Builder + */ + public function product_key(string $value = ''): Builder + { + if (strlen($value) == 0) { + return $this->builder; + } + + $key_parameters = explode(',', $value); + + if (count($key_parameters)) { + return $this->builder->where(function ($query) use ($key_parameters) { + foreach ($key_parameters as $key) { + $query->orWhereJsonContains('line_items', ['product_key' => $key]); + } + }); + } + + return $this->builder; + } + + /** + * next send date between. + * + * @param string range + * @return Builder + */ + public function next_send_between(string $range = ''): Builder + { + $parts = explode('|', $range); + + if (!isset($parts[0]) || !isset($parts[1])) { + return $this->builder; + } + + if (is_numeric($parts[0])) { + $startDate = Carbon::createFromTimestamp((int)$parts[0]); + } else { + $startDate = Carbon::parse($parts[0]); + } + + if (is_numeric($parts[1])) { + $endDate = Carbon::createFromTimestamp((int)$parts[1]); + } else { + $endDate = Carbon::parse($parts[1]); + } + + if (!$startDate || !$endDate) { + return $this->builder; + } + + return $this->builder->whereBetween( + 'next_send_date', + [$startDate->format('Y-m-d H:i:s'), $endDate->format('Y-m-d H:i:s')] + ); + } + + /** + * Filter by frequency id. + * + * @param integer frequency_id + * @return Builder + */ + public function frequency_id(string $value = ''): Builder + { + if (strlen($value) == 0) { + return $this->builder; + } + + $frequencyIds = explode(',', $value); + + return $this->builder->whereIn('frequency_id', $frequencyIds); + } } diff --git a/tests/Feature/RecurringInvoiceTest.php b/tests/Feature/RecurringInvoiceTest.php index d0a90de7197a..e09632500c44 100644 --- a/tests/Feature/RecurringInvoiceTest.php +++ b/tests/Feature/RecurringInvoiceTest.php @@ -22,6 +22,7 @@ use App\Models\RecurringInvoice; use App\Utils\Helpers; use App\Utils\Traits\MakesHash; use App\Models\Product; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Routing\Middleware\ThrottleRequests; @@ -78,7 +79,7 @@ class RecurringInvoiceTest extends TestCase $recurring_invoice->line_items = $line_items; $recurring_invoice->calc()->getInvoice()->service()->start()->save()->fresh(); - + (new UpdateRecurring([$recurring_invoice->id], $this->company, $this->user, 'increase_prices', 10))->handle(); $recurring_invoice->refresh(); @@ -114,7 +115,7 @@ class RecurringInvoiceTest extends TestCase $recurring_invoice->line_items = $line_items; $recurring_invoice->calc()->getInvoice()->service()->start()->save()->fresh(); - + (new UpdateRecurring([$recurring_invoice->id], $this->company, $this->user, 'update_prices'))->handle(); $recurring_invoice->refresh(); @@ -204,7 +205,7 @@ class RecurringInvoiceTest extends TestCase 'tax_name3' => '', 'tax_rate3' => 0, ]; - + $line_items[] = [ 'product_key' => 'pink', 'notes' => 'test', @@ -570,5 +571,237 @@ class RecurringInvoiceTest extends TestCase $this->assertEquals(null, $invoice->subscription_id); } - + + public function testFilterProductKey() + { + $p1 = Product::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'cost' => 10, + 'price' => 10, + 'product_key' => $this->faker->word, + ]); + + $p2 = Product::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'cost' => 20, + 'price' => 20, + 'product_key' => $this->faker->word, + ]); + + $recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice->client_id = $this->client->id; + $recurring_invoice->line_items = [[ + 'product_key' => $p1->product_key, + 'notes' => 'test', + 'cost' => 20, + 'quantity' => 1, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + ]]; + + $recurring_invoice->calc()->getInvoice()->service()->start()->save()->fresh(); + + $recurring_invoice2 = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice2->client_id = $this->client->id; + $recurring_invoice2->line_items = [[ + 'product_key' => $p2->product_key, + 'notes' => 'test', + 'cost' => 10, + 'quantity' => 1, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + ]]; + + $recurring_invoice2->calc()->getInvoice()->service()->start()->save()->fresh(); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_invoices?product_key=' . $this->faker->word) + ->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals('0', $arr['meta']['pagination']['total']); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_invoices?product_key=' . $p1->product_key) + ->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals('1', $arr['meta']['pagination']['total']); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_invoices?product_key=' . $p1->product_key .',' . $p2->product_key) + ->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals('2', $arr['meta']['pagination']['total']); + } + + public function testFilterFrequency() + { + $p1 = Product::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'cost' => 10, + 'price' => 10, + 'product_key' => $this->faker->word, + ]); + + $p2 = Product::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'cost' => 20, + 'price' => 20, + 'product_key' => $this->faker->word, + ]); + + $recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice->frequency_id = RecurringInvoice::FREQUENCY_TWO_WEEKS; + $recurring_invoice->client_id = $this->client->id; + $recurring_invoice->line_items = [[ + 'product_key' => $p1->product_key, + 'notes' => 'test', + 'cost' => 20, + 'quantity' => 1, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + ]]; + + $recurring_invoice->calc()->getInvoice()->service()->start()->save()->fresh(); + + $recurring_invoice2 = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice2->frequency_id = RecurringInvoice::FREQUENCY_ANNUALLY; + $recurring_invoice2->client_id = $this->client->id; + $recurring_invoice2->line_items = [[ + 'product_key' => $p2->product_key, + 'notes' => 'test', + 'cost' => 10, + 'quantity' => 1, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + ]]; + + $recurring_invoice2->calc()->getInvoice()->service()->start()->save()->fresh(); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_invoices?frequency_id=' . RecurringInvoice::FREQUENCY_SIX_MONTHS) + ->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals('0', $arr['meta']['pagination']['total']); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_invoices?frequency_id=' . RecurringInvoice::FREQUENCY_TWO_WEEKS) + ->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals('1', $arr['meta']['pagination']['total']); + } + + public function testFilterNextDateBetween() + { + $p1 = Product::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'cost' => 10, + 'price' => 10, + 'product_key' => $this->faker->word, + ]); + + $p2 = Product::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'cost' => 20, + 'price' => 20, + 'product_key' => $this->faker->word, + ]); + + $recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice->client_id = $this->client->id; + $recurring_invoice->next_send_date = Carbon::now()->subDays(7)->format('Y-m-d H:i:s'); + $recurring_invoice->line_items = [[ + 'product_key' => $p1->product_key, + 'notes' => 'test', + 'cost' => 20, + 'quantity' => 1, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + ]]; + + $recurring_invoice->calc()->getInvoice()->service()->start()->save()->fresh(); + + $recurring_invoice2 = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice2->next_send_date = Carbon::now()->subDays(2)->format('Y-m-d H:i:s'); + $recurring_invoice2->client_id = $this->client->id; + $recurring_invoice2->line_items = [[ + 'product_key' => $p2->product_key, + 'notes' => 'test', + 'cost' => 10, + 'quantity' => 1, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + ]]; + + $recurring_invoice2->calc()->getInvoice()->service()->start()->save()->fresh(); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_invoices?next_send_between=2020-01-01 00:00:00|2020-01-01 00:00:10') + ->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals('0', $arr['meta']['pagination']['total']); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_invoices?next_send_between=' . $recurring_invoice->next_send_date . '|' . $recurring_invoice->next_send_date) + ->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals('1', $arr['meta']['pagination']['total']); + } }