diff --git a/database/factories/CloneCreditFactory.php b/app/Factory/CloneCreditFactory.php similarity index 100% rename from database/factories/CloneCreditFactory.php rename to app/Factory/CloneCreditFactory.php diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index 074bf1cd12a5..e39a044da4cd 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -80,7 +80,7 @@ class CreditController extends BaseController if($request->entityIsDeleted($credit)) return $request->disallowUpdate(); - $credit = $this->credit_repo->save($request->all(), $credit); + $credit = $this->credit_repository->save($request->all(), $credit); event(new CreditWasUpdated($credit, $credit->company)); @@ -160,14 +160,14 @@ class CreditController extends BaseController return response()->download(public_path($credit->pdf_file_path())); break; case 'archive': - $this->credit_repo->archive($credit); + $this->credit_repository->archive($credit); if (!$bulk) { return $this->listResponse($credit); } break; case 'delete': - $this->credit_repo->delete($credit); + $this->credit_repository->delete($credit); if (!$bulk) { return $this->listResponse($credit); diff --git a/app/Http/Requests/Credit/StoreCreditRequest.php b/app/Http/Requests/Credit/StoreCreditRequest.php index 3d36d2c712a3..6a3e8fc8b720 100644 --- a/app/Http/Requests/Credit/StoreCreditRequest.php +++ b/app/Http/Requests/Credit/StoreCreditRequest.php @@ -3,10 +3,15 @@ namespace App\Http\Requests\Credit; use App\Models\Credit; +use App\Utils\Traits\CleanLineItems; +use App\Utils\Traits\MakesHash; use Illuminate\Foundation\Http\FormRequest; class StoreCreditRequest extends FormRequest { + use MakesHash; + use CleanLineItems; + /** * Determine if the user is authorized to make this request. * @@ -25,7 +30,19 @@ class StoreCreditRequest extends FormRequest public function rules() { return [ - // + 'client_id' => 'required', + // 'invoice_type_id' => 'integer', + // 'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx', ]; } + + protected function prepareForValidation() + { + $input = $this->all(); + + $input['client_id'] = $this->decodePrimaryKey($input['client_id']); + $input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : []; + //$input['line_items'] = json_encode($input['line_items']); + $this->replace($input); + } } diff --git a/app/Policies/CreditPolicy.php b/app/Policies/CreditPolicy.php new file mode 100644 index 000000000000..74a24483d3c8 --- /dev/null +++ b/app/Policies/CreditPolicy.php @@ -0,0 +1,16 @@ +isAdmin() || $user->hasPermission('create_quote') || $user->hasPermission('create_all'); + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 9f63ee91bb78..f8ce881292f3 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -15,6 +15,7 @@ use App\Models\Activity; use App\Models\Client; use App\Models\Company; use App\Models\CompanyGateway; +use App\Models\Credit; use App\Models\Expense; use App\Models\GroupSetting; use App\Models\Invoice; @@ -30,6 +31,7 @@ use App\Policies\ActivityPolicy; use App\Policies\ClientPolicy; use App\Policies\CompanyGatewayPolicy; use App\Policies\CompanyPolicy; +use App\Policies\CreditPolicy; use App\Policies\ExpensePolicy; use App\Policies\GroupSettingPolicy; use App\Policies\InvoicePolicy; @@ -58,6 +60,7 @@ class AuthServiceProvider extends ServiceProvider Company::class => CompanyPolicy::class, Product::class => ProductPolicy::class, Invoice::class => InvoicePolicy::class, + Credit::class => CreditPolicy::class, Payment::class => PaymentPolicy::class, RecurringInvoice::class => RecurringInvoicePolicy::class, RecurringQuote::class => RecurringQuotePolicy::class, diff --git a/routes/api.php b/routes/api.php index ce5e073f2cf1..8117be9af0e3 100644 --- a/routes/api.php +++ b/routes/api.php @@ -46,7 +46,7 @@ Route::group(['middleware' => ['api_db', 'api_secret_check', 'token_auth', 'loca Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk'); - Route::resource('credits', 'CreditsController'); // name = (credits. index / create / show / update / destroy / edit + Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action'); diff --git a/tests/Feature/CreditTest.php b/tests/Feature/CreditTest.php new file mode 100644 index 000000000000..c317db2714c7 --- /dev/null +++ b/tests/Feature/CreditTest.php @@ -0,0 +1,158 @@ +faker = \Faker\Factory::create(); + + Model::reguard(); + + $this->makeTestData(); + } + + public function testCreditsList() + { + $data = [ + 'first_name' => $this->faker->firstName, + 'last_name' => $this->faker->lastName, + 'name' => $this->faker->company, + 'email' => $this->faker->unique()->safeEmail, + 'password' => 'ALongAndBrilliantPassword123', + '_token' => csrf_token(), + 'privacy_policy' => 1, + 'terms_of_service' => 1 + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + ])->post('/api/v1/signup?include=account', $data); + + $acc = $response->json(); + + $account = Account::find($this->decodePrimaryKey($acc['data'][0]['account']['id'])); + + $company_token = $account->default_company->tokens()->first(); + $token = $company_token->token; + $company = $company_token->company; + + $user = $company_token->user; + + $this->assertNotNull($company_token); + $this->assertNotNull($token); + $this->assertNotNull($user); + $this->assertNotNull($company); + + factory(Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company) { + + factory(\App\Models\ClientContact::class, 1)->create([ + 'user_id' => $user->id, + 'client_id' => $c->id, + 'company_id' => $company->id, + 'is_primary' => 1 + ]); + + factory(\App\Models\ClientContact::class, 1)->create([ + 'user_id' => $user->id, + 'client_id' => $c->id, + 'company_id' => $company->id + ]); + }); + + $client = Client::all()->first(); + + factory(Credit::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]); + + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $token, + ])->get('/api/v1/credits'); + + $response->assertStatus(200); + } + + public function testCreditRESTEndPoints() + { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/credits/' . $this->encodePrimaryKey($this->credit->id)); + + $response->assertStatus(200); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/credits/' . $this->encodePrimaryKey($this->credit->id) . '/edit'); + + $response->assertStatus(200); + + $credit_update = [ + 'tax_name1' => 'dippy', + ]; + + $this->assertNotNull($this->credit); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->put('/api/v1/credits/' . $this->encodePrimaryKey($this->credit->id), $credit_update) + ->assertStatus(200); + } + + public function testPostNewCredit() + { + $credit = [ + 'status_id' => 1, + 'number' => 'dfdfd', + 'discount' => 0, + 'is_amount_discount' => 1, + 'number' => '3434343', + 'public_notes' => 'notes', + 'is_deleted' => 0, + 'custom_value1' => 0, + 'custom_value2' => 0, + 'custom_value3' => 0, + 'custom_value4' => 0, + 'status' => 1, + 'client_id' => $this->encodePrimaryKey($this->client->id), + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/credits/', $credit) + ->assertStatus(200); + } + + public function testDeleteCredit() + { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->delete('/api/v1/credits/'.$this->encodePrimaryKey($this->credit->id)); + + $response->assertStatus(200); + } +} diff --git a/tests/MockAccountData.php b/tests/MockAccountData.php index c511b990b04a..d10bf0e58958 100644 --- a/tests/MockAccountData.php +++ b/tests/MockAccountData.php @@ -16,6 +16,7 @@ use App\DataMapper\CompanySettings; use App\DataMapper\DefaultSettings; use App\Factory\ClientFactory; use App\Factory\CompanyUserFactory; +use App\Factory\CreditFactory; use App\Factory\InvoiceFactory; use App\Factory\InvoiceInvitationFactory; use App\Factory\InvoiceItemFactory; @@ -179,6 +180,14 @@ trait MockAccountData $this->invoice->save(); $this->invoice->markSent(); + + $this->credit = CreditFactory::create($this->company->id,$this->user->id); + $this->credit->client_id = $this->client->id; + + $this->credit->line_items = $this->buildLineItems(); + $this->credit->uses_inclusive_Taxes = false; + + $this->credit->save(); $contacts = $this->invoice->client->contacts;