diff --git a/app/Events/RecurringExpense/RecurringExpenseWasArchived.php b/app/Events/RecurringExpense/RecurringExpenseWasArchived.php new file mode 100644 index 000000000000..e446ee406bf3 --- /dev/null +++ b/app/Events/RecurringExpense/RecurringExpenseWasArchived.php @@ -0,0 +1,47 @@ +recurring_expense = $recurring_expense; + $this->company = $company; + $this->event_vars = $event_vars; + } +} diff --git a/app/Events/RecurringExpense/RecurringExpenseWasCreated.php b/app/Events/RecurringExpense/RecurringExpenseWasCreated.php new file mode 100644 index 000000000000..501c593efcfe --- /dev/null +++ b/app/Events/RecurringExpense/RecurringExpenseWasCreated.php @@ -0,0 +1,47 @@ +recurring_expense = $recurring_expense; + $this->company = $company; + $this->event_vars = $event_vars; + } +} diff --git a/app/Events/RecurringExpense/RecurringExpenseWasDeleted.php b/app/Events/RecurringExpense/RecurringExpenseWasDeleted.php new file mode 100644 index 000000000000..730628990a60 --- /dev/null +++ b/app/Events/RecurringExpense/RecurringExpenseWasDeleted.php @@ -0,0 +1,47 @@ +recurring_expense = $recurring_expense; + $this->company = $company; + $this->event_vars = $event_vars; + } +} diff --git a/app/Events/RecurringExpense/RecurringExpenseWasRestored.php b/app/Events/RecurringExpense/RecurringExpenseWasRestored.php new file mode 100644 index 000000000000..03f809cc9925 --- /dev/null +++ b/app/Events/RecurringExpense/RecurringExpenseWasRestored.php @@ -0,0 +1,49 @@ +recurring_expense = $recurring_expense; + $this->fromDeleted = $fromDeleted; + $this->company = $company; + $this->event_vars = $event_vars; + } +} diff --git a/app/Events/RecurringExpense/RecurringExpenseWasUpdated.php b/app/Events/RecurringExpense/RecurringExpenseWasUpdated.php new file mode 100644 index 000000000000..7fd385433937 --- /dev/null +++ b/app/Events/RecurringExpense/RecurringExpenseWasUpdated.php @@ -0,0 +1,47 @@ +recurring_expense = $recurring_expense; + $this->company = $company; + $this->event_vars = $event_vars; + } +} diff --git a/database/factories/RecurringExpenseFactory.php b/database/factories/RecurringExpenseFactory.php new file mode 100644 index 000000000000..b90ed0ebdb31 --- /dev/null +++ b/database/factories/RecurringExpenseFactory.php @@ -0,0 +1,47 @@ + $this->faker->numberBetween(1, 10), + 'custom_value1' => $this->faker->text(10), + 'custom_value2' => $this->faker->text(10), + 'custom_value3' => $this->faker->text(10), + 'custom_value4' => $this->faker->text(10), + 'exchange_rate' => $this->faker->randomFloat(2, 0, 1), + 'date' => $this->faker->date(), + 'is_deleted' => false, + 'public_notes' => $this->faker->text(50), + 'private_notes' => $this->faker->text(50), + 'transaction_reference' => $this->faker->text(5), + 'invoice_id' => null, + ]; + } +} diff --git a/database/migrations/2021_08_23_101529_recurring_expenses_schema.php b/database/migrations/2021_08_23_101529_recurring_expenses_schema.php index ae28e7a5ec0a..cc99d58d543d 100644 --- a/database/migrations/2021_08_23_101529_recurring_expenses_schema.php +++ b/database/migrations/2021_08_23_101529_recurring_expenses_schema.php @@ -26,9 +26,11 @@ class RecurringExpensesSchema extends Migration $table->unsignedInteger('invoice_id')->nullable(); $table->unsignedInteger('client_id')->nullable(); $table->unsignedInteger('bank_id')->nullable(); + $table->unsignedInteger('project_id')->nullable(); $table->unsignedInteger('payment_type_id')->nullable(); $table->unsignedInteger('recurring_expense_id')->nullable(); $table->boolean('is_deleted')->default(false); + $table->boolean('uses_inclusive_taxes')->default(true); $table->string('tax_name1')->nullable(); $table->string('tax_name2')->nullable(); $table->string('tax_name3')->nullable(); @@ -44,6 +46,9 @@ class RecurringExpensesSchema extends Migration $table->unsignedInteger('category_id')->nullable(); $table->boolean('calculate_tax_by_amount')->default(false); + $table->decimal('tax_amount1', 20, 6); + $table->decimal('tax_amount2', 20, 6); + $table->decimal('tax_amount3', 20, 6); $table->decimal('tax_rate1', 20, 6); $table->decimal('tax_rate2', 20, 6); $table->decimal('tax_rate3', 20, 6); @@ -53,7 +58,7 @@ class RecurringExpensesSchema extends Migration $table->unsignedInteger('assigned_user_id')->nullable(); $table->string('number')->nullable(); $table->unsignedInteger('invoice_currency_id')->nullable(); - $table->unsignedInteger('expense_currency_id')->nullable(); + $table->unsignedInteger('currency_id')->nullable(); $table->text('private_notes')->nullable(); $table->text('public_notes')->nullable(); $table->text('transaction_reference')->nullable(); diff --git a/routes/api.php b/routes/api.php index a0e63da14382..3f3c993b9df8 100644 --- a/routes/api.php +++ b/routes/api.php @@ -129,6 +129,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk'); Route::put('quotes/{quote}/upload', 'QuoteController@upload'); + Route::resource('recurring_expenses', 'RecurringExpenseController'); Route::resource('recurring_invoices', 'RecurringInvoiceController'); // name = (recurring_invoices. index / create / show / update / destroy / edit Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk'); Route::put('recurring_invoices/{recurring_invoice}/upload', 'RecurringInvoiceController@upload'); diff --git a/tests/Feature/RecurringExpenseApiTest.php b/tests/Feature/RecurringExpenseApiTest.php new file mode 100644 index 000000000000..78a636d45d50 --- /dev/null +++ b/tests/Feature/RecurringExpenseApiTest.php @@ -0,0 +1,175 @@ +makeTestData(); + + Session::start(); + + $this->faker = \Faker\Factory::create(); + + Model::reguard(); + } + + public function testRecurringExpenseGet() + { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_expenses/'); + + $response->assertStatus(200); + } + + public function testRecurringExpenseGetSingleExpense() + { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/recurring_expenses/'.$this->recurring_expense->hashed_id); + + $response->assertStatus(200); + } + + public function testRecurringExpensePost() + { + $data = [ + 'amount' => 10, + 'client_id' => $this->client->hashed_id, + 'number' => '123321', + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/recurring_expenses', $data); + + $response->assertStatus(200); + } +// $arr = $response->json(); + +// $response = $this->withHeaders([ +// 'X-API-SECRET' => config('ninja.api_secret'), +// 'X-API-TOKEN' => $this->token, +// ])->put('/api/v1/recurring_expenses/'.$arr['data']['id'], $data)->assertStatus(200); + +// try{ +// $response = $this->withHeaders([ +// 'X-API-SECRET' => config('ninja.api_secret'), +// 'X-API-TOKEN' => $this->token, +// ])->post('/api/v1/recurring_expenses', $data); +// } +// catch(ValidationException $e){ +// $response->assertStatus(302); +// } + + + +// } + +// public function testRecurringExpensePut() +// { +// $data = [ +// 'name' => $this->faker->firstName, +// 'public_notes' => 'Coolio', +// ]; + +// $response = $this->withHeaders([ +// 'X-API-SECRET' => config('ninja.api_secret'), +// 'X-API-TOKEN' => $this->token, +// ])->put('/api/v1/recurring_expenses/'.$this->encodePrimaryKey($this->project->id), $data); + +// $response->assertStatus(200); +// } + + +// public function testRecurringExpenseNotArchived() +// { +// $response = $this->withHeaders([ +// 'X-API-SECRET' => config('ninja.api_secret'), +// 'X-API-TOKEN' => $this->token, +// ])->get('/api/v1/recurring_expenses/'.$this->encodePrimaryKey($this->project->id)); + +// $arr = $response->json(); + +// $this->assertEquals(0, $arr['data']['archived_at']); +// } + +// public function testRecurringExpenseArchived() +// { +// $data = [ +// 'ids' => [$this->encodePrimaryKey($this->project->id)], +// ]; + +// $response = $this->withHeaders([ +// 'X-API-SECRET' => config('ninja.api_secret'), +// 'X-API-TOKEN' => $this->token, +// ])->post('/api/v1/recurring_expenses/bulk?action=archive', $data); + +// $arr = $response->json(); + +// $this->assertNotNull($arr['data'][0]['archived_at']); +// } + +// public function testRecurringExpenseRestored() +// { +// $data = [ +// 'ids' => [$this->encodePrimaryKey($this->project->id)], +// ]; + +// $response = $this->withHeaders([ +// 'X-API-SECRET' => config('ninja.api_secret'), +// 'X-API-TOKEN' => $this->token, +// ])->post('/api/v1/recurring_expenses/bulk?action=restore', $data); + +// $arr = $response->json(); + +// $this->assertEquals(0, $arr['data'][0]['archived_at']); +// } + +// public function testRecurringExpenseDeleted() +// { +// $data = [ +// 'ids' => [$this->encodePrimaryKey($this->project->id)], +// ]; + +// $response = $this->withHeaders([ +// 'X-API-SECRET' => config('ninja.api_secret'), +// 'X-API-TOKEN' => $this->token, +// ])->post('/api/v1/recurring_expenses/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 0e566900ad80..194b5a9ee2fa 100644 --- a/tests/MockAccountData.php +++ b/tests/MockAccountData.php @@ -36,6 +36,7 @@ use App\Models\Product; use App\Models\Project; use App\Models\Quote; use App\Models\QuoteInvitation; +use App\Models\RecurringExpense; use App\Models\RecurringInvoice; use App\Models\Task; use App\Models\TaskStatus; @@ -83,6 +84,11 @@ trait MockAccountData */ public $token; + /** + * @var + */ + public $recurring_expense; + /** * @var */ @@ -285,6 +291,13 @@ trait MockAccountData 'company_id' => $this->company->id, ]); + + $this->recurring_expense = RecurringExpense::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $this->company->id, + ]); + + $this->task = Task::factory()->create([ 'user_id' => $user_id, 'company_id' => $this->company->id,