├── .gitignore ├── src ├── Exceptions │ ├── ModelValidationException.php │ └── ApiException.php ├── Endpoints │ ├── Quotes.php │ ├── Tasks.php │ ├── Users.php │ ├── Clients.php │ ├── Credits.php │ ├── Vendors.php │ ├── Expenses.php │ ├── Invoices.php │ ├── Payments.php │ ├── Products.php │ ├── Projects.php │ ├── TaxRates.php │ ├── Webhooks.php │ ├── GroupSettings.php │ ├── PurchaseOrders.php │ ├── Subscriptions.php │ ├── BankIntegrations.php │ ├── BankTransactions.php │ ├── ExpenseCategories.php │ ├── RecurringInvoices.php │ ├── Companies.php │ ├── Statics.php │ └── BaseEntity.php ├── Models │ ├── ClientContact.php │ ├── ClientSettings.php │ ├── InvoiceItem.php │ ├── BaseModel.php │ ├── Webhook.php │ ├── Client.php │ └── Invoice.php └── InvoiceNinja.php ├── tests ├── BootTest.php ├── StaticsTest.php ├── BulkActionsTest.php ├── Invoice │ └── CreateInvoiceTest.php ├── ProductsTest.php ├── GroupSettingsTest.php ├── TaxRatesTest.php ├── QuotesTest.php ├── TasksTest.php ├── ExpensesTest.php ├── CompaniesTest.php ├── ProjectsTest.php ├── VendorsTest.php ├── CreditsTest.php ├── SubscriptionsTest.php ├── RecurringInvoicesTest.php ├── BankIntegrationsTest.php ├── ExpenseCategoriesTest.php ├── BankTransactionsTest.php ├── WebhooksTest.php ├── PaymentsTest.php ├── InvoicesTest.php ├── PurchaseOrdersTest.php └── ClientsTest.php ├── phpunit.xml ├── composer.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /src/Exceptions/ModelValidationException.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(InvoiceNinja::class, $ninja); 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /src/Endpoints/Quotes.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Tasks.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Users.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Clients.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Credits.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Vendors.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Expenses.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Invoices.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Payments.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Products.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Projects.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/TaxRates.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Webhooks.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/GroupSettings.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/PurchaseOrders.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/Subscriptions.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/BankIntegrations.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/BankTransactions.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/ExpenseCategories.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/Endpoints/RecurringInvoices.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /tests/StaticsTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 25 | 26 | $currencies = $ninja->statics->currencies(); 27 | 28 | $this->assertTrue(is_array($currencies)); 29 | 30 | } 31 | 32 | 33 | } -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | src/ 6 | 7 | 8 | 9 | 10 | tests 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "invoiceninja/sdk-php", 3 | "description": "The Invoice Ninja v5 PHP SDK", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "David Bomba", 9 | "email": "turbo124@gmail.com" 10 | } 11 | ], 12 | "autoload": { 13 | "psr-4": {"InvoiceNinja\\Sdk\\": "src/"} 14 | }, 15 | "require": { 16 | "php": "^8", 17 | "guzzlehttp/guzzle": "^7", 18 | "nesbot/carbon": "^2|^3" 19 | }, 20 | "require-dev": { 21 | "fakerphp/faker": "^1.16", 22 | "phpunit/phpunit": "^9.5" 23 | }, 24 | "autoload-dev": { 25 | "psr-4": { 26 | "InvoiceNinja\\Sdk\\Tests\\": "tests" 27 | } 28 | }, 29 | "scripts": { 30 | "test": "vendor/bin/phpunit", 31 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 32 | 33 | }, 34 | "config": { 35 | "sort-packages": true 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Models/ClientContact.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $client = $ninja->clients->create(['name' => 'A name']); 26 | 27 | $this->assertTrue(is_array($client)); 28 | 29 | $this->assertEquals(0, $client['data']['archived_at']); 30 | 31 | $a[] = $client['data']['id']; 32 | 33 | $archived_client = $ninja->clients->bulk("archive", $a); 34 | 35 | $this->assertGreaterThan(0, $archived_client['data'][0]['archived_at']); 36 | 37 | $archived_client = $ninja->clients->bulk("restore", $a); 38 | 39 | $this->assertEquals(0, $client['data']['archived_at']); 40 | 41 | $archived_client = $ninja->clients->bulk("delete", $a); 42 | 43 | $this->assertGreaterThan(0, $archived_client['data'][0]['archived_at']); 44 | $this->assertEquals(1, $archived_client['data'][0]['is_deleted']); 45 | 46 | } 47 | 48 | 49 | 50 | 51 | } -------------------------------------------------------------------------------- /src/Endpoints/Companies.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 27 | } 28 | 29 | public function all(array $search = []) 30 | { 31 | $query = ['query' => $search]; 32 | 33 | return $this->ninja->send("GET", "{$this->uri}", $query); 34 | } 35 | 36 | public function get(string $entity_id, array $search = []) 37 | { 38 | $query = ['query' => $search]; 39 | 40 | return $this->ninja->send("GET", "{$this->uri}/{$entity_id}", $query); 41 | } 42 | 43 | public function update(string $entity_id, array $entity) 44 | { 45 | $query = ['form_params' => $entity]; 46 | 47 | return $this->ninja->send("PUT", "{$this->uri}/{$entity_id}", $query); 48 | } 49 | 50 | public function create(array $entity, array $includes = []) 51 | { 52 | $query = ['form_params' => $entity, 'query' => $includes]; 53 | 54 | return $this->ninja->send("POST", "{$this->uri}", $query); 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/Exceptions/ApiException.php: -------------------------------------------------------------------------------- 1 | getStatusCode(), 26 | $field 27 | ); 28 | } 29 | 30 | protected static function parseResponseBody($response) 31 | { 32 | $body = (string) $response->getBody(); 33 | $error = ""; 34 | $object = @json_decode($body); 35 | $error_array = []; 36 | 37 | if(property_exists($object, "message")) 38 | $error = $object->message; 39 | 40 | if(property_exists($object, "errors")) 41 | { 42 | $properties = array_keys(get_object_vars($object->errors)); 43 | 44 | if(is_array($properties) && count($properties) >=1) 45 | $error_array = $object->errors->{$properties[0]}; 46 | 47 | if(is_array($error_array) && count($error_array) >=1) 48 | $error = $error_array[0]; 49 | 50 | } 51 | 52 | if (json_last_error() !== JSON_ERROR_NONE) { 53 | throw new self("Unable to decode response: '{$body}'."); 54 | } 55 | 56 | return $error; 57 | } 58 | } -------------------------------------------------------------------------------- /src/Models/ClientSettings.php: -------------------------------------------------------------------------------- 1 | faker = \Faker\Factory::create(); 26 | } 27 | 28 | // $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 29 | // $ninja->setUrl($_ENV['INVOICENINJA_URL']); 30 | 31 | public function testInitInvoice() 32 | { 33 | $invoice = new Invoice(); 34 | $this->assertInstanceOf(Invoice::class, $invoice); 35 | } 36 | 37 | public function testInitItem() 38 | { 39 | $item = new InvoiceItem(); 40 | $this->assertInstanceOf(InvoiceItem::class, $item); 41 | } 42 | 43 | public function testBaseName() 44 | { 45 | $client = new Client; 46 | 47 | $this->assertEquals("InvoiceNinja\Sdk\Models\Client", get_class($client)); 48 | } 49 | 50 | public function testClientValidation() 51 | { 52 | $client = new Client; 53 | $client->name = 'Jim'; 54 | 55 | $client->save(); 56 | 57 | $this->assertInstanceOf(Client::class, $client); 58 | } 59 | 60 | // public function testBuildInvoice() 61 | // { 62 | // $client = new Client; 63 | // $client->name = 'Jim'; 64 | // $client->save(); 65 | 66 | // $invoice = new Invoice; 67 | // $invoice->setClient($client); 68 | // } 69 | } -------------------------------------------------------------------------------- /src/Models/InvoiceItem.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $products = $ninja->products->all(); 26 | 27 | $this->assertTrue(is_array($products)); 28 | 29 | } 30 | 31 | public function testInvoiceGet() 32 | { 33 | 34 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 35 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 36 | 37 | $product = $ninja->products->create(['product_key' => 'that']); 38 | 39 | $products = $ninja->products->get($product['data']['id']); 40 | 41 | $this->assertTrue(is_array($products)); 42 | 43 | } 44 | 45 | 46 | public function testInvoicePut() 47 | { 48 | 49 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 50 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 51 | 52 | $product = $ninja->products->create(['product_key' => 'thatx']); 53 | 54 | $products = $ninja->products->update($product['data']['id'], ['product_key' => 'this']); 55 | 56 | $this->assertTrue(is_array($products)); 57 | 58 | } 59 | 60 | 61 | public function testInvoicePost() 62 | { 63 | 64 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 65 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 66 | 67 | $products = $ninja->products->create(['product_key' => 'that']); 68 | 69 | $this->assertTrue(is_array($products)); 70 | 71 | } 72 | } -------------------------------------------------------------------------------- /src/Endpoints/Statics.php: -------------------------------------------------------------------------------- 1 | ninja = $ninja; 38 | } 39 | 40 | private function get(array $search = []) 41 | { 42 | return $this->ninja->send("GET", "/api/v1/statics", $search); 43 | } 44 | 45 | public function currencies() 46 | { 47 | return $this->getStaticByKey('currencies'); 48 | } 49 | 50 | public function industries() 51 | { 52 | return $this->getStaticByKey('industries'); 53 | } 54 | 55 | public function languages() 56 | { 57 | return $this->getStaticByKey('languages'); 58 | } 59 | 60 | public function countries() 61 | { 62 | return $this->getStaticByKey('countries'); 63 | } 64 | 65 | public function banks() 66 | { 67 | return $this->getStaticByKey('banks'); 68 | } 69 | 70 | public function payment_types() 71 | { 72 | return $this->getStaticByKey('payment_types'); 73 | } 74 | 75 | public function templates() 76 | { 77 | return $this->getStaticByKey('templates'); 78 | } 79 | 80 | private function getStaticByKey($key) 81 | { 82 | $data = $this->get(); 83 | 84 | if(array_key_exists($key, $data)) 85 | return $data[$key]; 86 | 87 | throw new ApiException("Static data not found"); 88 | } 89 | 90 | } 91 | 92 | -------------------------------------------------------------------------------- /tests/GroupSettingsTest.php: -------------------------------------------------------------------------------- 1 | faker = \Faker\Factory::create(); 23 | 24 | } 25 | 26 | public function testAddGroupSetting() 27 | { 28 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 29 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 30 | 31 | $settings = new \stdClass; 32 | $settings->currency_id = '1'; 33 | 34 | $group_setting = $ninja->group_settings->create(['name' => $this->faker->firstName, 'settings' => $settings]); 35 | 36 | $this->assertTrue(is_array($group_setting)); 37 | 38 | $group_settings = $ninja->group_settings->all(); 39 | 40 | $this->assertTrue(is_array($group_settings)); 41 | 42 | } 43 | 44 | 45 | public function testUpdateGroupSetting() 46 | { 47 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 48 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 49 | 50 | $settings = new \stdClass; 51 | $settings->currency_id = '1'; 52 | 53 | $new_name = $this->faker->firstName; 54 | $group_setting = $ninja->group_settings->create(['name' => $new_name, 'settings' => $settings]); 55 | $this->assertTrue(is_array($group_setting)); 56 | 57 | $newer_name = $this->faker->firstName; 58 | $settings = new \stdClass; 59 | $settings->currency_id = '2'; 60 | 61 | $updated_group_setting = $ninja->group_settings->update($group_setting['data']['id'], ['name' => $newer_name, 'settings' => $settings]); 62 | 63 | $this->assertEquals($newer_name, $updated_group_setting['data']['name']); 64 | $this->assertEquals('2', $updated_group_setting['data']['settings']['currency_id']); 65 | 66 | } 67 | 68 | 69 | } -------------------------------------------------------------------------------- /tests/TaxRatesTest.php: -------------------------------------------------------------------------------- 1 | faker = \Faker\Factory::create(); 24 | } 25 | 26 | public function testProducts() 27 | { 28 | 29 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 30 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 31 | 32 | $tax_rates = $ninja->tax_rates->all(); 33 | 34 | $this->assertTrue(is_array($tax_rates)); 35 | 36 | } 37 | 38 | public function testTaxRateGet() 39 | { 40 | 41 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 42 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 43 | 44 | $tax_rate = $ninja->tax_rates->create(['rate' => 10, 'name' => $this->faker->word()]); 45 | 46 | $tax_rates = $ninja->tax_rates->get($tax_rate['data']['id']); 47 | 48 | $this->assertTrue(is_array($tax_rates)); 49 | 50 | } 51 | 52 | 53 | public function testTaxRatePut() 54 | { 55 | 56 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 57 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 58 | 59 | $tax_rate = $ninja->tax_rates->create(['rate' => 10, 'name' => 'GSTa']); 60 | 61 | $tax_rates = $ninja->tax_rates->update($tax_rate['data']['id'], ['rate' => 10, 'name' => $this->faker->word()]); 62 | 63 | $this->assertTrue(is_array($tax_rates)); 64 | 65 | } 66 | 67 | 68 | public function testTaxRatePost() 69 | { 70 | 71 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 72 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 73 | 74 | $tax_rates = $ninja->tax_rates->create(['rate' => 10, 'name' => $this->faker->word()]); 75 | 76 | $this->assertTrue(is_array($tax_rates)); 77 | 78 | } 79 | } -------------------------------------------------------------------------------- /tests/QuotesTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 27 | 28 | $quotes = $ninja->quotes->all(); 29 | 30 | $this->assertTrue(is_array($quotes)); 31 | 32 | } 33 | 34 | public function testQuoteGet() 35 | { 36 | 37 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 38 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 39 | 40 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 41 | $quote = $ninja->quotes->create(['client_id' => $client['data']['id']]); 42 | 43 | $quotes = $ninja->quotes->get($quote['data']['id']); 44 | 45 | $this->assertTrue(is_array($quotes)); 46 | 47 | } 48 | 49 | 50 | public function testQuotePut() 51 | { 52 | 53 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 54 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 55 | 56 | 57 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 58 | $quote = $ninja->quotes->create(['client_id' => $client['data']['id']]); 59 | 60 | $quotes = $ninja->quotes->update($quote['data']['id'], ['discount' => '10']); 61 | 62 | $this->assertTrue(is_array($quotes)); 63 | 64 | } 65 | 66 | 67 | public function testQuotePost() 68 | { 69 | 70 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 71 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 72 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 73 | 74 | $quotes = $ninja->quotes->create(['client_id' => $client['data']['id']]); 75 | 76 | $this->assertTrue(is_array($quotes)); 77 | 78 | } 79 | } -------------------------------------------------------------------------------- /tests/TasksTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 25 | 26 | $taks = $ninja->tasks->all(); 27 | 28 | $this->assertTrue(is_array($taks)); 29 | 30 | } 31 | 32 | public function testTaskGet() 33 | { 34 | 35 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 36 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 37 | 38 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 39 | $task = $ninja->tasks->create(['name' => 'Project', 'client_id' => $client['data']['id']]); 40 | 41 | $taks = $ninja->tasks->get($task['data']['id']); 42 | 43 | $this->assertTrue(is_array($taks)); 44 | 45 | } 46 | 47 | 48 | public function testTaskPut() 49 | { 50 | 51 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 52 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 53 | 54 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 55 | $task = $ninja->tasks->create(['name' => 'Project', 'client_id' => $client['data']['id']]); 56 | 57 | $taks = $ninja->tasks->update($task['data']['id'], ['name' => 'Project 2']); 58 | 59 | $this->assertTrue(is_array($taks)); 60 | 61 | } 62 | 63 | 64 | public function testTaskPost() 65 | { 66 | 67 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 68 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 69 | 70 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 71 | $taks = $ninja->tasks->create(['name' => 'Project', 'client_id' => $client['data']['id']]); 72 | $this->assertTrue(is_array($taks)); 73 | 74 | } 75 | } -------------------------------------------------------------------------------- /src/Endpoints/BaseEntity.php: -------------------------------------------------------------------------------- 1 | $action, "ids" => $ids]; 23 | 24 | return $this->ninja->send("POST", "{$this->uri}/bulk", $query); 25 | } 26 | 27 | public function archive(array $entity_array) 28 | { 29 | return $this->bulk("archive", $entity_array); 30 | } 31 | 32 | public function delete(array $entity_array) 33 | { 34 | return $this->bulk("delete", $entity_array); 35 | } 36 | 37 | public function restore(array $entity_array) 38 | { 39 | return $this->bulk("restore", $entity_array); 40 | } 41 | 42 | public function all(array $search = []) 43 | { 44 | $query = ['query' => $search]; 45 | 46 | return $this->ninja->send("GET", "{$this->uri}", $query); 47 | } 48 | 49 | public function get(string $entity_id, array $search = []) 50 | { 51 | $query = ['query' => $search]; 52 | 53 | return $this->ninja->send("GET", "{$this->uri}/{$entity_id}", $query); 54 | } 55 | 56 | public function update(string $entity_id, array $entity) 57 | { 58 | $query = ['form_params' => $entity]; 59 | 60 | return $this->ninja->send("PUT", "{$this->uri}/{$entity_id}", $query); 61 | } 62 | 63 | public function create(array $entity, array $includes = []) 64 | { 65 | $query = ['form_params' => $entity, 'query' => $includes]; 66 | 67 | return $this->ninja->send("POST", "{$this->uri}", $query); 68 | } 69 | 70 | public function download(array $entity, array $includes = []) 71 | { 72 | $data = ['ids' => $entity, 'action' => 'download', 'stream' => false]; 73 | 74 | $query = ['form_params' => $data, 'query' => $includes]; 75 | 76 | return $this->ninja->stream("POST", "{$this->uri}/bulk", $query); 77 | 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /tests/ExpensesTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $expenses = $ninja->expenses->all(); 26 | 27 | $this->assertTrue(is_array($expenses)); 28 | 29 | } 30 | 31 | public function testExpenseGet() 32 | { 33 | 34 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 35 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 36 | 37 | $client = $ninja->clients->create(['name' => 'Brand spanking new clients']); 38 | $expense = $ninja->expenses->create(['client_id' => $client['data']['id']]); 39 | 40 | $expenses = $ninja->expenses->get($expense['data']['id']); 41 | 42 | $this->assertTrue(is_array($expenses)); 43 | 44 | } 45 | 46 | 47 | public function testExpensePut() 48 | { 49 | 50 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 51 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 52 | 53 | 54 | $clients = $ninja->clients->create(['name' => 'Brand spanking new client']); 55 | $expense = $ninja->expenses->create(['client_id' => $clients['data']['id']]); 56 | 57 | $expenses = $ninja->expenses->update($expense['data']['id'], ['amount' => '10']); 58 | 59 | $this->assertTrue(is_array($expenses)); 60 | 61 | } 62 | 63 | 64 | public function testExpensePost() 65 | { 66 | 67 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 68 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 69 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 70 | 71 | $expenses = $ninja->expenses->create(['client_id' => $client['data']['id']]); 72 | 73 | $this->assertTrue(is_array($expenses)); 74 | 75 | } 76 | } -------------------------------------------------------------------------------- /tests/CompaniesTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $companies = $ninja->companies->all(); 26 | 27 | $this->assertTrue(is_array($companies)); 28 | 29 | } 30 | 31 | public function testCompanyGet() 32 | { 33 | 34 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 35 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 36 | 37 | $company = $ninja->companies->create([], ['include' => 'company,company.tokens']); 38 | $token = $company['data'][0]['company']['tokens'][0]['token']; 39 | $ninja->setToken($token); 40 | 41 | $companies = $ninja->companies->get($company['data'][0]['company']['id']); 42 | 43 | $this->assertTrue(is_array($companies)); 44 | 45 | } 46 | 47 | 48 | public function testCompanyPut() 49 | { 50 | 51 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 52 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 53 | 54 | $company = $ninja->companies->create([], ['include' => 'company,company.tokens']); 55 | $token = $company['data'][0]['company']['tokens'][0]['token']; 56 | $ninja->setToken($token); 57 | 58 | $companies = $ninja->companies->update($company['data'][0]['company']['id'], ['industry_id' => '1']); 59 | 60 | $this->assertTrue(is_array($companies)); 61 | 62 | } 63 | 64 | 65 | public function testCompanyPost() 66 | { 67 | 68 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 69 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 70 | 71 | $companies = $ninja->companies->create([], ['include' => 'company']); 72 | 73 | $this->assertTrue(is_array($companies)); 74 | 75 | } 76 | } -------------------------------------------------------------------------------- /tests/ProjectsTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $projects = $ninja->projects->all(); 26 | 27 | $this->assertTrue(is_array($projects)); 28 | 29 | } 30 | 31 | public function testProjectGet() 32 | { 33 | 34 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 35 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 36 | 37 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 38 | $product = $ninja->projects->create(['name' => 'Project', 'client_id' => $client['data']['id']]); 39 | 40 | $projects = $ninja->projects->get($product['data']['id']); 41 | 42 | $this->assertTrue(is_array($projects)); 43 | 44 | } 45 | 46 | 47 | public function testProjectPut() 48 | { 49 | 50 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 51 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 52 | 53 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 54 | $product = $ninja->projects->create(['name' => 'Project', 'client_id' => $client['data']['id']]); 55 | 56 | $projects = $ninja->projects->update($product['data']['id'], ['name' => 'Project 2']); 57 | 58 | $this->assertTrue(is_array($projects)); 59 | 60 | } 61 | 62 | 63 | public function testProjectPost() 64 | { 65 | 66 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 67 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 68 | 69 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 70 | $projects = $ninja->projects->create(['name' => 'Project', 'client_id' => $client['data']['id']]); 71 | $this->assertTrue(is_array($projects)); 72 | 73 | } 74 | } -------------------------------------------------------------------------------- /tests/VendorsTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 23 | 24 | $vendors = $ninja->vendors->create(['name' => 'Brand spanking new vendor']); 25 | 26 | $this->assertTrue(is_array($vendors)); 27 | 28 | $vendors = $ninja->vendors->all(['balance' => '0:gt']); 29 | 30 | $this->assertTrue(is_array($vendors)); 31 | 32 | } 33 | 34 | public function testVendorGet() 35 | { 36 | 37 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 38 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 39 | 40 | $vendor = $ninja->vendors->create(['name' => 'Brand spanking new vendor']); 41 | 42 | $this->assertTrue(is_array($vendor)); 43 | 44 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 45 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 46 | 47 | $vendors = $ninja->vendors->get($vendor['data']['id']); 48 | 49 | $this->assertTrue(is_array($vendors)); 50 | 51 | } 52 | 53 | 54 | public function testVendorPut() 55 | { 56 | 57 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 58 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 59 | 60 | $vendor = $ninja->vendors->create(['name' => 'Brand spanking new vendor']); 61 | 62 | $vendors = $ninja->vendors->update($vendor['data']['id'], ['name' => 'A new vendor name updated']); 63 | 64 | $this->assertTrue(is_array($vendors)); 65 | 66 | } 67 | 68 | 69 | public function testVendorPost() 70 | { 71 | 72 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 73 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 74 | 75 | $vendors = $ninja->vendors->create(['name' => 'Brand spanking new vendor']); 76 | 77 | $this->assertTrue(is_array($vendors)); 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /src/Models/BaseModel.php: -------------------------------------------------------------------------------- 1 | resetValidationErrors(); 23 | 24 | foreach($this->rules as $key => $rule) 25 | { 26 | 27 | switch($rule) 28 | { 29 | case 'required': 30 | isset($this->{$key}) ?: $this->setValidationErrors(["error" => "{$this->model} - `{$key}` must be set", "code" => 422]); 31 | break; 32 | case 'date': 33 | isset($this->{$key}) ? $this->checkDate($key) : true; 34 | break; 35 | default: 36 | $this->setValidationErrors(["error" => "{$this->model} - Unknown validation rule `{$rule}` for property `{$key}`", "code" => 500]); 37 | 38 | } 39 | 40 | } 41 | 42 | if(count($this->getValidationErrors()) == 0) 43 | return true; 44 | 45 | throw new ModelValidationException($this->getValidationErrors()[0]["error"] ,$this->getValidationErrors()[0]["code"]); 46 | } 47 | 48 | private function resetValidationErrors() 49 | { 50 | $this->validation_errors = []; 51 | 52 | return $this; 53 | } 54 | 55 | private function setValidationErrors($error): self 56 | { 57 | $this->validation_errors[] = $error; 58 | 59 | return $this; 60 | } 61 | 62 | public function getValidationErrors(): array 63 | { 64 | return $this->validation_errors; 65 | } 66 | 67 | public function checkDate(string $date_field): bool 68 | { 69 | 70 | try { 71 | 72 | $parsed_date = \Carbon\Carbon::parse($this->{$date_field}); 73 | $this->{$date_field} = $parsed_date->format('Y-m-d'); 74 | 75 | return true; 76 | } 77 | catch(\Exception $e) { 78 | $this->setValidationErrors([$date_field => "Invalid date format for field {$date_field} - '{$this->{$date_field}}'"]); 79 | return false; 80 | } 81 | } 82 | 83 | 84 | 85 | 86 | 87 | } -------------------------------------------------------------------------------- /tests/CreditsTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 26 | 27 | $credit = $ninja->credits->create(['client_id' => $client['data']['id']]); 28 | 29 | $credits = $ninja->credits->all(); 30 | 31 | $this->assertTrue(is_array($credits)); 32 | 33 | } 34 | 35 | public function testCreditGet() 36 | { 37 | 38 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 39 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 40 | 41 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 42 | 43 | $credit = $ninja->credits->create(['client_id' => $client['data']['id']]); 44 | 45 | $credits = $ninja->credits->get($credit['data']['id']); 46 | 47 | $this->assertTrue(is_array($credits)); 48 | 49 | } 50 | 51 | 52 | public function testCreditPut() 53 | { 54 | 55 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 56 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 57 | 58 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 59 | 60 | $credit = $ninja->credits->create(['client_id' => $client['data']['id']]); 61 | 62 | $credits = $ninja->credits->update($credit['data']['id'], ['discount' => '10']); 63 | 64 | $this->assertTrue(is_array($credits)); 65 | 66 | } 67 | 68 | 69 | public function testCreditPost() 70 | { 71 | 72 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 73 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 74 | 75 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 76 | 77 | $credits = $ninja->credits->create(['client_id' => $client['data']['id']]); 78 | 79 | $this->assertTrue(is_array($credits)); 80 | 81 | } 82 | } -------------------------------------------------------------------------------- /tests/SubscriptionsTest.php: -------------------------------------------------------------------------------- 1 | faker = \Faker\Factory::create(); 25 | } 26 | 27 | public function testSubscriptions() 28 | { 29 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 30 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 31 | 32 | $subscriptions = $ninja->subscriptions->create(['name' => $this->faker->firstName]); 33 | 34 | $this->assertTrue(is_array($subscriptions)); 35 | 36 | } 37 | 38 | public function testSubscriptionGet() 39 | { 40 | 41 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 42 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 43 | 44 | $subscription = $ninja->subscriptions->create(['name' => $this->faker->firstName]); 45 | 46 | $this->assertTrue(is_array($subscription)); 47 | 48 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 49 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 50 | 51 | $subscriptions = $ninja->subscriptions->get($subscription['data']['id']); 52 | 53 | $this->assertTrue(is_array($subscriptions)); 54 | 55 | } 56 | 57 | 58 | public function testSubscriptionPut() 59 | { 60 | 61 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 62 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 63 | 64 | $subscription = $ninja->subscriptions->create(['name' => $this->faker->firstName]); 65 | 66 | $subscriptions = $ninja->subscriptions->update($subscription['data']['id'], ['name' => $this->faker->firstName]); 67 | 68 | $this->assertTrue(is_array($subscriptions)); 69 | 70 | } 71 | 72 | 73 | public function testSubscriptionPost() 74 | { 75 | 76 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 77 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 78 | 79 | $subscriptions = $ninja->subscriptions->create(['name' => $this->faker->firstName]); 80 | 81 | $this->assertTrue(is_array($subscriptions)); 82 | 83 | } 84 | } -------------------------------------------------------------------------------- /tests/RecurringInvoicesTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 26 | 27 | $invoice = $ninja->recurring_invoices->create(['frequency_id'=>1,'client_id' => $client['data']['id']]); 28 | 29 | $invoices = $ninja->recurring_invoices->all(); 30 | 31 | $this->assertTrue(is_array($invoices)); 32 | 33 | } 34 | 35 | public function testInvoiceGet() 36 | { 37 | 38 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 39 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 40 | 41 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 42 | 43 | $invoice = $ninja->recurring_invoices->create(['frequency_id'=>1,'client_id' => $client['data']['id']]); 44 | 45 | $invoices = $ninja->recurring_invoices->get($invoice['data']['id']); 46 | 47 | $this->assertTrue(is_array($invoices)); 48 | 49 | } 50 | 51 | 52 | public function testInvoicePut() 53 | { 54 | 55 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 56 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 57 | 58 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 59 | 60 | $invoice = $ninja->recurring_invoices->create(['frequency_id'=>1,'client_id' => $client['data']['id']]); 61 | 62 | $invoices = $ninja->recurring_invoices->update($invoice['data']['id'], ['discount' => '10']); 63 | 64 | $this->assertTrue(is_array($invoices)); 65 | 66 | } 67 | 68 | 69 | public function testInvoicePost() 70 | { 71 | 72 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 73 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 74 | 75 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 76 | $invoices = $ninja->recurring_invoices->create(['frequency_id'=>1,'client_id' => $client['data']['id']]); 77 | 78 | $this->assertTrue(is_array($invoices)); 79 | 80 | } 81 | } -------------------------------------------------------------------------------- /tests/BankIntegrationsTest.php: -------------------------------------------------------------------------------- 1 | faker = \Faker\Factory::create(); 25 | } 26 | 27 | public function testBankIntegrations() 28 | { 29 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 30 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 31 | 32 | $bank_integrations = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 33 | 34 | $this->assertTrue(is_array($bank_integrations)); 35 | 36 | } 37 | 38 | public function testBankIntegrationGet() 39 | { 40 | 41 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 42 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 43 | 44 | $integration = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 45 | 46 | $this->assertTrue(is_array($integration)); 47 | 48 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 49 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 50 | 51 | $bank_integrations = $ninja->bank_integrations->get($integration['data']['id']); 52 | 53 | $this->assertTrue(is_array($bank_integrations)); 54 | 55 | } 56 | 57 | 58 | public function testBankIntegrationPut() 59 | { 60 | 61 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 62 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 63 | 64 | $integration = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 65 | 66 | $bank_integrations = $ninja->bank_integrations->update($integration['data']['id'], ['bank_account_name' => $this->faker->firstName]); 67 | 68 | $this->assertTrue(is_array($bank_integrations)); 69 | 70 | } 71 | 72 | 73 | public function testBankIntegrationPost() 74 | { 75 | 76 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 77 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 78 | 79 | $bank_integrations = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 80 | 81 | $this->assertTrue(is_array($bank_integrations)); 82 | 83 | } 84 | } -------------------------------------------------------------------------------- /tests/ExpenseCategoriesTest.php: -------------------------------------------------------------------------------- 1 | faker = \Faker\Factory::create(); 24 | 25 | } 26 | 27 | public function testExpenseCategoriesPost() 28 | { 29 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 30 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 31 | 32 | $expense_categories = $ninja->expense_categories->create(['name' => $this->faker->text(10)]); 33 | 34 | $this->assertTrue(is_array($expense_categories)); 35 | 36 | $expense_categories = $ninja->expense_categories->all(); 37 | 38 | $this->assertTrue(is_array($expense_categories)); 39 | 40 | } 41 | 42 | public function testExpenseCategoryGet() 43 | { 44 | 45 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 46 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 47 | 48 | $expense_categories = $ninja->expense_categories->create(['name' => $this->faker->text(10)]); 49 | 50 | $this->assertTrue(is_array($expense_categories)); 51 | 52 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 53 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 54 | 55 | $expense_categories = $ninja->expense_categories->get($expense_categories['data']['id']); 56 | 57 | $this->assertTrue(is_array($expense_categories)); 58 | 59 | } 60 | 61 | 62 | public function testExpenseCategoryPut() 63 | { 64 | 65 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 66 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 67 | 68 | $expense_category = $this->faker->text(10); 69 | 70 | $expense_categories = $ninja->expense_categories->create(['name' => $expense_category]); 71 | 72 | $expense_categories = $ninja->expense_categories->update($expense_categories['data']['id'], ['name' => $this->faker->text(10)]); 73 | 74 | $this->assertTrue(is_array($expense_categories)); 75 | 76 | } 77 | 78 | 79 | public function testExpenseCategoryPost() 80 | { 81 | 82 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 83 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 84 | 85 | $expense_categories = $ninja->expense_categories->create(['name' => $this->faker->firstName]); 86 | 87 | $this->assertTrue(is_array($expense_categories)); 88 | 89 | } 90 | } -------------------------------------------------------------------------------- /tests/BankTransactionsTest.php: -------------------------------------------------------------------------------- 1 | faker = \Faker\Factory::create(); 25 | } 26 | 27 | public function testBankTransactions() 28 | { 29 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 30 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 31 | 32 | $bank_integrations = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 33 | 34 | $transactions = $ninja->bank_transactions->create(['bank_integration_id' => $bank_integrations['data']['id'], 'name' => $this->faker->firstName]); 35 | 36 | $this->assertTrue(is_array($transactions)); 37 | 38 | } 39 | 40 | public function testTransactionGet() 41 | { 42 | 43 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 44 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 45 | 46 | $bank_integrations = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 47 | 48 | $transaction = $ninja->bank_transactions->create(['bank_integration_id' => $bank_integrations['data']['id'],'name' => $this->faker->firstName]); 49 | 50 | $this->assertTrue(is_array($transaction)); 51 | 52 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 53 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 54 | 55 | $transactions = $ninja->bank_transactions->get($transaction['data']['id']); 56 | 57 | $this->assertTrue(is_array($transactions)); 58 | 59 | } 60 | 61 | 62 | public function testTransactionPut() 63 | { 64 | 65 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 66 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 67 | 68 | $bank_integrations = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 69 | 70 | $transaction = $ninja->bank_transactions->create(['bank_integration_id' => $bank_integrations['data']['id'], 'name' => $this->faker->firstName]); 71 | 72 | $transactions = $ninja->bank_transactions->update($transaction['data']['id'], ['bank_integration_id' => $bank_integrations['data']['id'], 'name' => $this->faker->firstName, 'date' => '2022-10-10', 'amount' => 100]); 73 | 74 | $this->assertTrue(is_array($transactions)); 75 | 76 | } 77 | 78 | 79 | public function testTransactionPost() 80 | { 81 | 82 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 83 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 84 | 85 | $bank_integrations = $ninja->bank_integrations->create(['bank_account_name' => $this->faker->firstName]); 86 | 87 | $transactions = $ninja->bank_transactions->create(['bank_integration_id' => $bank_integrations['data']['id'], 'name' => $this->faker->firstName]); 88 | 89 | $this->assertTrue(is_array($transactions)); 90 | 91 | } 92 | } -------------------------------------------------------------------------------- /tests/WebhooksTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 30 | 31 | $webhooks = $ninja->webhooks->all(); 32 | 33 | $this->assertIsArray($webhooks); 34 | 35 | } 36 | 37 | public function testWebhookPost() 38 | { 39 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 40 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 41 | 42 | $model = new Webhook(); 43 | $model->event_id = Webhook::EVENT_CREATE_CLIENT; 44 | $model->target_url = $this->test_base_url; 45 | 46 | $this->assertTrue($model->validate()); 47 | 48 | $webhooks = $ninja->webhooks->create((array) $model); 49 | 50 | $this->assertIsArray($webhooks); 51 | 52 | } 53 | 54 | public function testWebhookPut() 55 | { 56 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 57 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 58 | 59 | $webhook = $ninja->webhooks->create([ 60 | 'event_id' => Webhook::EVENT_UPDATE_CLIENT, 61 | 'target_url' => $this->test_base_url 62 | ]); 63 | 64 | $attributes = ['target_url' => $this->test_base_url.'-updated-url']; 65 | $webhook_updated = array_merge($webhook['data'], $attributes); 66 | 67 | $webhooks = $ninja->webhooks->update($webhook['data']['id'], $webhook_updated); 68 | 69 | $this->assertIsArray($webhooks); 70 | 71 | $this->assertContains($webhook_updated, $webhooks); 72 | 73 | } 74 | 75 | public function testWebhookGet() 76 | { 77 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 78 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 79 | 80 | $webhook_created = $ninja->webhooks->create([ 81 | 'event_id' => Webhook::EVENT_CREATE_CLIENT, 82 | 'target_url' => $this->test_base_url, 83 | ]); 84 | 85 | $this->assertIsArray($webhook_created); 86 | 87 | $webhook = $ninja->webhooks->get($webhook_created['data']['id']); 88 | 89 | $this->assertEquals($webhook_created['data']['id'], $webhook['data']['id']); 90 | 91 | } 92 | 93 | public function testWebhookDelete() 94 | { 95 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 96 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 97 | 98 | $ninja->webhooks->create([ 99 | 'event_id' => Webhook::EVENT_CREATE_CLIENT, 100 | 'target_url' => $this->test_base_url 101 | ]); 102 | $webhooks = $ninja->webhooks->all(['target_url' => $this->test_base_url, 'status' => 'active']); 103 | 104 | $this->assertNotEmpty($webhooks['data']); 105 | 106 | $webhooks = $ninja->webhooks->delete(array_column($webhooks['data'], 'id')); 107 | 108 | $this->assertIsArray($webhooks); 109 | 110 | $webhooks = $ninja->webhooks->all(['target_url' => $this->test_base_url, 'status' => 'active']); 111 | 112 | $this->assertEmpty($webhooks['data']); 113 | } 114 | } -------------------------------------------------------------------------------- /src/Models/Webhook.php: -------------------------------------------------------------------------------- 1 | 'required', 117 | 'target_url' => 'required', 118 | ]; 119 | 120 | /** 121 | * @throws ModelValidationException 122 | */ 123 | public function save() 124 | { 125 | $this->validate(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /tests/PaymentsTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $payments = $ninja->payments->all(); 26 | 27 | $this->assertTrue(is_array($payments)); 28 | 29 | } 30 | 31 | public function testInvoiceGet() 32 | { 33 | 34 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 35 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 36 | 37 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 38 | $payment = $ninja->payments->create(['client_id' => $client['data']['id'], 'amount' => 10]); 39 | 40 | $payments = $ninja->payments->get($payment['data']['id']); 41 | 42 | $this->assertTrue(is_array($payments)); 43 | 44 | } 45 | 46 | 47 | public function testInvoicePut() 48 | { 49 | 50 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 51 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 52 | 53 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 54 | $payment = $ninja->payments->create(['client_id' => $client['data']['id'], 'amount' => 10]); 55 | 56 | $payments = $ninja->payments->update($payment['data']['id'], ['transaction_reference' => 'ref']); 57 | 58 | $this->assertTrue(is_array($payments)); 59 | 60 | } 61 | 62 | 63 | public function testInvoicePost() 64 | { 65 | 66 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 67 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 68 | 69 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 70 | 71 | $payments = $ninja->payments->create(['client_id' => $client['data']['id'], 'amount' => 10]); 72 | 73 | $this->assertTrue(is_array($payments)); 74 | 75 | } 76 | 77 | public function testInvoicePostPaymentWithInvoicePayment() 78 | { 79 | 80 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 81 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 82 | 83 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 84 | 85 | $invoice = [ 86 | 'client_id' => $client['data']['id'], 87 | 'line_items' => [ 88 | [ 89 | 'product_key' => 'test', 90 | 'notes' => 'description', 91 | 'quantity' => 1, 92 | 'cost' => 10 93 | ] 94 | ], 95 | ]; 96 | 97 | $invoice = $ninja->invoices->create($invoice, ['mark_sent' => true]); 98 | 99 | $payments = $ninja->payments->create([ 100 | 'client_id' => $client['data']['id'], 101 | 'amount' => 10, 102 | 'invoices' => [ 103 | [ 104 | 'invoice_id' => $invoice['data']['id'], 105 | 'amount' => 10 106 | ], 107 | ], 108 | ]); 109 | 110 | $this->assertTrue(is_array($payments)); 111 | 112 | } 113 | 114 | public function testInvoicePostPaymentWithInvoicePaymentAndTransactionReference() 115 | { 116 | 117 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 118 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 119 | 120 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 121 | 122 | $invoice = [ 123 | 'client_id' => $client['data']['id'], 124 | 'line_items' => [ 125 | [ 126 | 'product_key' => 'test', 127 | 'notes' => 'description', 128 | 'quantity' => 1, 129 | 'cost' => 10 130 | ] 131 | ], 132 | ]; 133 | 134 | $invoice = $ninja->invoices->create($invoice, ['mark_sent' => true]); 135 | 136 | $payments = $ninja->payments->create([ 137 | 'client_id' => $client['data']['id'], 138 | 'amount' => 10, 139 | 'invoices' => [ 140 | [ 141 | 'invoice_id' => $invoice['data']['id'], 142 | 'amount' => 10 143 | ], 144 | ], 145 | 'transaction_reference' => 'IAMAWESOME' 146 | ]); 147 | 148 | $this->assertTrue(is_array($payments)); 149 | 150 | $this->assertEquals('IAMAWESOME', $payments['data']['transaction_reference']); 151 | 152 | 153 | } 154 | 155 | } -------------------------------------------------------------------------------- /src/Models/Client.php: -------------------------------------------------------------------------------- 1 | 'required', 256 | ]; 257 | 258 | public function __construct() 259 | { 260 | 261 | } 262 | 263 | public function setContact(ClientContact $contact): self 264 | { 265 | $this->contacts = array_merge($this->contacts, $contact); 266 | 267 | return $this; 268 | } 269 | 270 | public function getContacts(): array 271 | { 272 | return $this->contacts; 273 | } 274 | 275 | public function save() 276 | { 277 | $this->validate(); 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /src/Models/Invoice.php: -------------------------------------------------------------------------------- 1 | 'required', 226 | 'date' => 'date', 227 | 'due_date' => 'date', 228 | 'partial_due_date' => 'date', 229 | ]; 230 | 231 | private array $validation_errors = []; 232 | 233 | public function __construct() 234 | { 235 | 236 | } 237 | 238 | public function setClient(Client $client): self 239 | { 240 | $this->client_id = $client->id; 241 | 242 | return $this; 243 | } 244 | 245 | public function setClientId(string $client_id): self 246 | { 247 | $this->client_id = $client_id; 248 | 249 | return $this; 250 | } 251 | 252 | public function addLine(InvoiceItem $item) 253 | { 254 | $this->line_items = array_merge($this->line_items, $item); 255 | 256 | return $this; 257 | } 258 | 259 | 260 | //////////////////////////////////////// helpers - for abstraction/////////////////////////////////////////// 261 | 262 | 263 | 264 | 265 | } -------------------------------------------------------------------------------- /tests/InvoicesTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 26 | 27 | $invoice = $ninja->invoices->create(['client_id' => $client['data']['id']]); 28 | 29 | $invoices = $ninja->invoices->all(); 30 | 31 | $this->assertTrue(is_array($invoices)); 32 | 33 | } 34 | 35 | public function testInvoiceGet() 36 | { 37 | 38 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 39 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 40 | 41 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 42 | 43 | $invoice = $ninja->invoices->create(['client_id' => $client['data']['id']]); 44 | 45 | $invoices = $ninja->invoices->get($invoice['data']['id']); 46 | 47 | $this->assertTrue(is_array($invoices)); 48 | 49 | } 50 | 51 | 52 | public function testInvoicePut() 53 | { 54 | 55 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 56 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 57 | 58 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 59 | 60 | $invoice = $ninja->invoices->create(['client_id' => $client['data']['id']]); 61 | 62 | $invoices = $ninja->invoices->update($invoice['data']['id'], ['discount' => '10']); 63 | 64 | $this->assertTrue(is_array($invoices)); 65 | 66 | } 67 | 68 | 69 | public function testInvoicePost() 70 | { 71 | 72 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 73 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 74 | 75 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 76 | 77 | $invoices = $ninja->invoices->create(['client_id' => $client['data']['id']]); 78 | 79 | $this->assertTrue(is_array($invoices)); 80 | 81 | } 82 | 83 | 84 | public function testInvoicePostWithItems() 85 | { 86 | 87 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 88 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 89 | 90 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 91 | 92 | $invoice = [ 93 | 'client_id' => $client['data']['id'], 94 | 'line_items' => [ 95 | [ 96 | 'product_key' => 'test', 97 | 'notes' => 'description', 98 | 'quantity' => 1, 99 | 'cost' => 10 100 | ] 101 | ], 102 | ]; 103 | 104 | $invoice = $ninja->invoices->create($invoice); 105 | 106 | $this->assertTrue(is_array($invoice)); 107 | $this->assertEquals(10, $invoice['data']['amount']); 108 | 109 | 110 | } 111 | 112 | public function testInvoicePostWithMultiItems() 113 | { 114 | 115 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 116 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 117 | 118 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 119 | 120 | $invoice = [ 121 | 'client_id' => $client['data']['id'], 122 | 'line_items' => [ 123 | [ 124 | 'product_key' => 'test', 125 | 'notes' => 'description', 126 | 'quantity' => 1, 127 | 'cost' => 10 128 | ], 129 | [ 130 | 'product_key' => 'test', 131 | 'notes' => 'description', 132 | 'quantity' => 1, 133 | 'cost' => 10 134 | ], 135 | ], 136 | ]; 137 | 138 | $invoice = $ninja->invoices->create($invoice); 139 | 140 | $this->assertTrue(is_array($invoice)); 141 | $this->assertEquals(20, $invoice['data']['amount']); 142 | 143 | 144 | } 145 | 146 | public function testInvoicePostWithMultiItemsMarkSent() 147 | { 148 | 149 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 150 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 151 | 152 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 153 | 154 | $invoice = [ 155 | 'client_id' => $client['data']['id'], 156 | 'line_items' => [ 157 | [ 158 | 'product_key' => 'test', 159 | 'notes' => 'description', 160 | 'quantity' => 1, 161 | 'cost' => 10 162 | ], 163 | [ 164 | 'product_key' => 'test', 165 | 'notes' => 'description', 166 | 'quantity' => 1, 167 | 'cost' => 10 168 | ], 169 | ], 170 | ]; 171 | 172 | $invoice = $ninja->invoices->create($invoice, ['mark_sent' => "true"]); 173 | 174 | $this->assertTrue(is_array($invoice)); 175 | $this->assertEquals(20, $invoice['data']['amount']); 176 | 177 | $this->assertEquals(20, $invoice['data']['balance']); 178 | 179 | } 180 | 181 | public function testDownloadInvoice() 182 | { 183 | 184 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 185 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 186 | 187 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 188 | 189 | $invoice = [ 190 | 'client_id' => $client['data']['id'], 191 | 'line_items' => [ 192 | [ 193 | 'product_key' => 'test', 194 | 'notes' => 'description', 195 | 'quantity' => 1, 196 | 'cost' => 10 197 | ], 198 | [ 199 | 'product_key' => 'test', 200 | 'notes' => 'description', 201 | 'quantity' => 1, 202 | 'cost' => 10 203 | ], 204 | ], 205 | ]; 206 | 207 | $invoice = $ninja->invoices->create($invoice, ['mark_sent' => "true"]); 208 | 209 | $download = $ninja->invoices->download([$invoice['data']['id']]); 210 | 211 | $this->assertNotNull($download); 212 | 213 | } 214 | 215 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Invoice Ninja SDK v5! 2 | 3 | ### Installation 4 | 5 | Add the Invoice Ninja SDK 6 | 7 | composer require invoiceninja/sdk-php 8 | 9 | ### Setup 10 | ```php 11 | 12 | use InvoiceNinja\Sdk\InvoiceNinja; 13 | 14 | $ninja = new InvoiceNinja("your_token"); 15 | $invoices = $ninja->invoices->all(); 16 | 17 | ``` 18 | - To connect to a self hosted version use `->setUrl()` on the $ninja object. 19 | 20 | ### Supports 21 | 22 | - Clients 23 | - Invoices 24 | - Quotes 25 | - Products 26 | - Payments 27 | - TaxRates 28 | - Statics 29 | - Expenses 30 | - Expense Categories 31 | - Recurring Invoices 32 | - Credits 33 | - Projects 34 | - Tasks 35 | - Vendors 36 | - Companies 37 | - Subscriptions 38 | - Purchase Orders 39 | - Bank Integrations 40 | - Bank Transactions 41 | 42 | ### Retrieving Models 43 | 44 | Retrieve all clients 45 | ```php 46 | $clients = $ninja->clients->all(); 47 | ``` 48 | 49 | You can perform complex filtering on the ->all() method. 50 | 51 | Query parameters can be chained together to form complex queries. The current supported values are: 52 | 53 | **per_page**: The number of clients per page you want returned 54 | **page**: The page number 55 | **include**: A comma separated list of relations to include ie. contacts,documents,gateway_tokens 56 | **balance**: A query to return clients with a balance using an operator and value 57 | - ie ?balance=lt:10 Returns clients with a balance less than 10 58 | - available operators lt, lte, gt, gte, eq 59 | 60 | **between_balance**: Returns clients with a balance between two values 61 | - ie ?between_balance=10:20 - Returns clients with a balance between 10 and 20 62 | 63 | **email**: Returns clients with a contacts.email field equal to an email 64 | **id_number**: Search by id_number 65 | **number**: Search by number 66 | **filter**: Search across multiple columns (name, id_number, first_name, last_name, email, custom_value1, custom_value2, custom_value3, custom_value4) 67 | **created_at**: Search by created at (Unix timestamp) 68 | **is_deleted**: Search using is_deleted boolean flag 69 | 70 | For example, 71 | 72 | ```php 73 | $clients = $ninja->clients->all([ 74 | 'balance' => 'lt:10', // get all clients with a balance less than 10 75 | 'per_page' => 10, // return 10 results per page 76 | 'page' => 2, // paginate to page 2 77 | 'include' => 'documents', // include the documents relationship 78 | ]); 79 | 80 | ``` 81 | 82 | Retrieve a client by its primary key. 83 | ```php 84 | $client = $ninja->clients->get("CLIENT_HASHED_ID"); 85 | ``` 86 | 87 | Retrieving an invoice by it's number: 88 | ```php 89 | $client = $ninja->invoices->all(['number' => '0001']); 90 | ``` 91 | 92 | ### Inserting & Updating Models 93 | 94 | Create a new client 95 | ```php 96 | $client = $ninja->clients->create(['name' => 'A new client']); 97 | 98 | ``` 99 | 100 | Create a new Client with a contact 101 | ```php 102 | $clients = $ninja->clients->create([ 103 | 'name' => 'Brand spanking new client', 104 | 'contacts' => [ 105 | [ 106 | 'first_name' => 'first', 107 | 'last_name' => 'last', 108 | 'send_email' => true, 109 | 'email' => 'gi-joe@example.com', 110 | ], 111 | 112 | ] 113 | ]); 114 | 115 | ``` 116 | 117 | Update an existing client 118 | ```php 119 | $client = $ninja->clients->update("CLIENT_HASHED_ID",['name' => 'A client with a updated name']); 120 | 121 | ``` 122 | 123 | ***Please Note*** 124 | 125 | When updating a client, you must always include the current contacts (array), if no contacts are included, the system will wipe the contacts from the client record. 126 | 127 | 128 | Create an invoice 129 | ```php 130 | $invoice = $ninja->invoices->create([ 131 | 'client_id' => $client_hashed_id, 132 | 'date' => '2022-10-31', 133 | 'due_date' => '2022-12-01', 134 | 'terms' => 'These are your invoice terms.', 135 | 'footer' => 'Invoice footer text', 136 | 'line_items' => [ 137 | [ 138 | 'product_key' => 'some_product_key', 139 | 'notes' => 'description', 140 | 'quantity' => 1, 141 | 'cost' => 10 142 | ], 143 | [ 144 | 'product_key' => 'another_product_key', 145 | 'notes' => 'description', 146 | 'quantity' => 1, 147 | 'cost' => 10 148 | ], 149 | ], 150 | ]); 151 | ``` 152 | 153 | When creating an invoice, you can perform actions on the invoice in a single call, for example, say you wish to create an invoice and also apply a payment to the invoice: 154 | 155 | ```php 156 | $invoice = $ninja->invoices->create([ 157 | 'client_id' => $client_hashed_id, 158 | 'date' => '2022-10-31', 159 | 'due_date' => '2022-12-01', 160 | 'terms' => 'These are your invoice terms.', 161 | 'footer' => 'Invoice footer text', 162 | 'line_items' => [ 163 | [ 164 | 'product_key' => 'some_product_key', 165 | 'notes' => 'description', 166 | 'quantity' => 1, 167 | 'cost' => 10 168 | ], 169 | [ 170 | 'product_key' => 'another_product_key', 171 | 'notes' => 'description', 172 | 'quantity' => 1, 173 | 'cost' => 10 174 | ], 175 | ], 176 | ], 177 | ['paid' => true] //the second parameter in this method is an array of actions ie paid,mark_sent_send_email,auto_bill 178 | ); 179 | ``` 180 | Or if you wish to apply a partial payment 181 | 182 | ```php 183 | $invoice = $ninja->invoices->create(['client_id'=> 'CLIENT_HASHED_ID'], ['amount_paid' => 10]); 184 | ``` 185 | 186 | Or you may want to automatically send and charge the invoice **note requires a payment method on file** 187 | ```php 188 | $invoice = $ninja->invoices->create(['client_id'=> 'CLIENT_HASHED_ID'], ['auto_bill' => true, 'send_email' => true]); 189 | ``` 190 | 191 | 192 | ### Bulk actions 193 | 194 | You can perform bulk actions against one or many entities. For example if you wish to batch archive a range of invoice you would do 195 | 196 | ```php 197 | $bulk = $ninja->invoices->archive(["hash_1","hash_2"]); 198 | ``` 199 | 200 | You can access the raw bulk method using the following: 201 | 202 | ```php 203 | $bulk = $ninja->invoices->bulk("archive", ["hash_1","hash_2"]); 204 | ``` 205 | 206 | If you wanted to download a invoice PDF 207 | ```php 208 | $pdf = $ninja->invoices->bulk("download", ["hash_1"]); 209 | ``` 210 | 211 | The following are a list of available bulk actions for invoices: 212 | 213 | + mark_sent 214 | + download 215 | + restore 216 | + archive 217 | + delete 218 | + paid 219 | + clone_to_quote 220 | + clone_to_invoice 221 | + cancel 222 | + reverse 223 | + email 224 | 225 | For more examples of what can be achieved with the SDK, please inspect the tests folder in this repository. If you need clarity or more explicit examples of how to use the SDK, please create a issue. -------------------------------------------------------------------------------- /tests/PurchaseOrdersTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 26 | 27 | $purchase_order = $ninja->purchase_orders->create(['vendor_id' => $client['data']['id']]); 28 | 29 | $purchase_orders = $ninja->purchase_orders->all(); 30 | 31 | $this->assertTrue(is_array($purchase_orders)); 32 | 33 | } 34 | 35 | public function testPurchaseOrderGet() 36 | { 37 | 38 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 39 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 40 | 41 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 42 | 43 | $purchase_order = $ninja->purchase_orders->create(['vendor_id' => $client['data']['id']]); 44 | 45 | $purchase_orders = $ninja->purchase_orders->get($purchase_order['data']['id']); 46 | 47 | $this->assertTrue(is_array($purchase_orders)); 48 | 49 | } 50 | 51 | 52 | public function testPurchaseOrderPut() 53 | { 54 | 55 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 56 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 57 | 58 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 59 | 60 | $purchase_order = $ninja->purchase_orders->create(['vendor_id' => $client['data']['id']]); 61 | 62 | $purchase_orders = $ninja->purchase_orders->update($purchase_order['data']['id'], ['discount' => '10']); 63 | 64 | $this->assertTrue(is_array($purchase_orders)); 65 | 66 | } 67 | 68 | 69 | public function testPurchaseOrderPost() 70 | { 71 | 72 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 73 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 74 | 75 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 76 | 77 | $purchase_orders = $ninja->purchase_orders->create(['vendor_id' => $client['data']['id']]); 78 | 79 | $this->assertTrue(is_array($purchase_orders)); 80 | 81 | } 82 | 83 | 84 | public function testPurchaseOrderPostWithItems() 85 | { 86 | 87 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 88 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 89 | 90 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 91 | 92 | $purchase_order = [ 93 | 'vendor_id' => $client['data']['id'], 94 | 'line_items' => [ 95 | [ 96 | 'product_key' => 'test', 97 | 'notes' => 'description', 98 | 'quantity' => 1, 99 | 'cost' => 10 100 | ] 101 | ], 102 | ]; 103 | 104 | $purchase_order = $ninja->purchase_orders->create($purchase_order); 105 | 106 | $this->assertTrue(is_array($purchase_order)); 107 | $this->assertEquals(10, $purchase_order['data']['amount']); 108 | 109 | 110 | } 111 | 112 | public function testPurchaseOrderPostWithMultiItems() 113 | { 114 | 115 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 116 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 117 | 118 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 119 | 120 | $purchase_order = [ 121 | 'vendor_id' => $client['data']['id'], 122 | 'line_items' => [ 123 | [ 124 | 'product_key' => 'test', 125 | 'notes' => 'description', 126 | 'quantity' => 1, 127 | 'cost' => 10 128 | ], 129 | [ 130 | 'product_key' => 'test', 131 | 'notes' => 'description', 132 | 'quantity' => 1, 133 | 'cost' => 10 134 | ], 135 | ], 136 | ]; 137 | 138 | $purchase_order = $ninja->purchase_orders->create($purchase_order); 139 | 140 | $this->assertTrue(is_array($purchase_order)); 141 | $this->assertEquals(20, $purchase_order['data']['amount']); 142 | 143 | 144 | } 145 | 146 | public function testPurchaseOrderPostWithMultiItemsMarkSent() 147 | { 148 | 149 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 150 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 151 | 152 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 153 | 154 | $purchase_order = [ 155 | 'vendor_id' => $client['data']['id'], 156 | 'line_items' => [ 157 | [ 158 | 'product_key' => 'test', 159 | 'notes' => 'description', 160 | 'quantity' => 1, 161 | 'cost' => 10 162 | ], 163 | [ 164 | 'product_key' => 'test', 165 | 'notes' => 'description', 166 | 'quantity' => 1, 167 | 'cost' => 10 168 | ], 169 | ], 170 | ]; 171 | 172 | $purchase_order = $ninja->purchase_orders->create($purchase_order, ['mark_sent' => "true"]); 173 | 174 | $this->assertTrue(is_array($purchase_order)); 175 | 176 | $this->assertEquals(20, $purchase_order['data']['amount']); 177 | $this->assertEquals(20, $purchase_order['data']['balance']); 178 | 179 | } 180 | 181 | public function testDownloadPurchaseOrder() 182 | { 183 | 184 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 185 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 186 | 187 | $client = $ninja->vendors->create(['name' => 'Brand spanking new client']); 188 | 189 | $purchase_order = [ 190 | 'vendor_id' => $client['data']['id'], 191 | 'line_items' => [ 192 | [ 193 | 'product_key' => 'test', 194 | 'notes' => 'description', 195 | 'quantity' => 1, 196 | 'cost' => 10 197 | ], 198 | [ 199 | 'product_key' => 'test', 200 | 'notes' => 'description', 201 | 'quantity' => 1, 202 | 'cost' => 10 203 | ], 204 | ], 205 | ]; 206 | 207 | $purchase_order = $ninja->purchase_orders->create($purchase_order, ['mark_sent' => "true"]); 208 | 209 | $download = $ninja->purchase_orders->download([$purchase_order['data']['id']]); 210 | 211 | $this->assertNotNull($download); 212 | 213 | } 214 | 215 | } -------------------------------------------------------------------------------- /src/InvoiceNinja.php: -------------------------------------------------------------------------------- 1 | token = $token; 105 | 106 | $this->initialize(); 107 | } 108 | 109 | /** 110 | * @return $this 111 | */ 112 | private function initialize() 113 | { 114 | $this->clients = new Clients($this); 115 | $this->invoices = new Invoices($this); 116 | $this->products = new Products($this); 117 | $this->quotes = new Quotes($this); 118 | $this->payments = new Payments($this); 119 | $this->tax_rates = new TaxRates($this); 120 | $this->statics = new Statics($this); 121 | $this->expenses = new Expenses($this); 122 | $this->recurring_invoices = new RecurringInvoices($this); 123 | $this->credits = new Credits($this); 124 | $this->projects = new Projects($this); 125 | $this->tasks = new Tasks($this); 126 | $this->vendors = new Vendors($this); 127 | $this->users = new Users($this); 128 | $this->companies = new Companies($this); 129 | $this->expense_categories = new ExpenseCategories($this); 130 | $this->group_settings = new GroupSettings($this); 131 | $this->subscriptions = new Subscriptions($this); 132 | $this->purchase_orders = new PurchaseOrders($this); 133 | $this->bank_transactions = new BankTransactions($this); 134 | $this->bank_integrations = new BankIntegrations($this); 135 | $this->webhooks = new Webhooks($this); 136 | 137 | return $this; 138 | } 139 | 140 | /** 141 | * @param string $url 142 | * @return $this 143 | */ 144 | public function setUrl(string $url) 145 | { 146 | $this->endpoint_url = $url; 147 | 148 | return $this; 149 | } 150 | 151 | /** 152 | * @param string $url 153 | * @return $this 154 | */ 155 | public function setToken($token) 156 | { 157 | $this->token = $token; 158 | 159 | return $this; 160 | } 161 | 162 | /** 163 | * @param array $options 164 | * @return $this 165 | */ 166 | public function setOptions(array $options) 167 | { 168 | $this->options = array_merge($this->options, $options); 169 | 170 | return $this; 171 | } 172 | 173 | /** 174 | * @return array 175 | */ 176 | 177 | private function getOptions() 178 | { 179 | return $this->options; 180 | } 181 | 182 | /** 183 | * @return string 184 | */ 185 | public function getToken() 186 | { 187 | return $this->token; 188 | } 189 | 190 | /** 191 | * @return string 192 | */ 193 | private function getUrl() :string 194 | { 195 | return rtrim($this->endpoint_url, '/'); 196 | } 197 | /** 198 | * @param array $headers 199 | * @return $this 200 | */ 201 | private function setHeaders(array $headers) 202 | { 203 | $this->headers = $headers; 204 | 205 | return $this; 206 | } 207 | 208 | /** 209 | * @return array 210 | */ 211 | private function getHeaders() 212 | { 213 | return $this->headers; 214 | } 215 | 216 | /** 217 | * @param array $headers 218 | * @return $this 219 | */ 220 | public function addHeader(array $headers) 221 | { 222 | $this->setHeaders(array_merge($this->getHeaders(), $headers)); 223 | 224 | return $this; 225 | } 226 | 227 | /** 228 | * @return array 229 | */ 230 | private function buildHeaders() :array 231 | { 232 | $headers = [ 233 | 'X-API-TOKEN' => $this->getToken(), 234 | 'X-Requested-With' => 'XMLHttpRequest', 235 | ]; 236 | 237 | return array_merge($headers, $this->getHeaders()); 238 | } 239 | 240 | /** 241 | * @return InvoiceNinja 242 | */ 243 | private function httpClient() 244 | { 245 | $this->httpClient = new \GuzzleHttp\Client( 246 | array_merge($this->options,[ 247 | // 'verify' => false, 248 | 'headers' => $this->buildHeaders() 249 | ]) 250 | ); 251 | 252 | return $this; 253 | } 254 | 255 | /** 256 | * @param string $method 257 | * @param string $uri 258 | * @param array $payload 259 | * @return mixed 260 | * @throws GuzzleException 261 | */ 262 | public function send(string $method, string $uri, array $payload) 263 | { 264 | $this->httpClient(); 265 | 266 | $url = $this->getUrl() . $uri; 267 | 268 | try{ 269 | 270 | $response = $this->httpClient->request($method, $url, $payload); 271 | 272 | return json_decode($response->getBody()->getContents(),true); 273 | 274 | } 275 | catch(GuzzleException $e) { 276 | 277 | if (method_exists($e, 'hasResponse') && method_exists($e, 'getResponse') && $e->hasResponse()) 278 | throw ApiException::createFromResponse($e->getResponse()); 279 | 280 | throw new ApiException($e->getMessage(), $e->getCode()); 281 | 282 | } 283 | } 284 | 285 | public function stream(string $method, string $uri, array $payload) 286 | { 287 | 288 | $this->httpClient(); 289 | 290 | $url = $this->getUrl() . $uri; 291 | 292 | try{ 293 | 294 | $response = $this->httpClient->request($method, $url, $payload); 295 | 296 | $body = $response->getBody(); 297 | 298 | return (string)$body; 299 | 300 | } 301 | catch(GuzzleException $e) { 302 | 303 | if (method_exists($e, 'hasResponse') && method_exists($e, 'getResponse') && $e->hasResponse()) 304 | throw ApiException::createFromResponse($e->getResponse()); 305 | 306 | throw new ApiException($e->getMessage(), $e->getCode()); 307 | 308 | } 309 | 310 | } 311 | 312 | } 313 | 314 | 315 | -------------------------------------------------------------------------------- /tests/ClientsTest.php: -------------------------------------------------------------------------------- 1 | setUrl($_ENV['INVOICENINJA_URL']); 24 | 25 | $clients = $ninja->clients->create(['name' => 'Brand spanking new client']); 26 | 27 | $this->assertTrue(is_array($clients)); 28 | 29 | $clients = $ninja->clients->all(['balance' => '0:gt']); 30 | 31 | $this->assertTrue(is_array($clients)); 32 | 33 | } 34 | 35 | public function testClientGet() 36 | { 37 | 38 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 39 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 40 | 41 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 42 | 43 | $this->assertTrue(is_array($client)); 44 | 45 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 46 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 47 | 48 | $clients = $ninja->clients->get($client['data']['id']); 49 | 50 | $this->assertTrue(is_array($clients)); 51 | 52 | } 53 | 54 | 55 | public function testClientPut() 56 | { 57 | 58 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 59 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 60 | 61 | $client = $ninja->clients->create(['name' => 'Brand spanking new client']); 62 | 63 | $clients = $ninja->clients->update($client['data']['id'], ['name' => 'A new client name updated']); 64 | 65 | $this->assertTrue(is_array($clients)); 66 | 67 | } 68 | 69 | public function testClientUpdate() 70 | { 71 | 72 | 73 | $create = [ 74 | "id" => "Vyb8E85dvA", 75 | "user_id" => "Vyb82qgevA", 76 | "assigned_user_id" => "", 77 | "name" => "Bosco-Keeling", 78 | "website" => "https =>\/\/www.fahey.com\/aut-et-quasi-animi-quia-recusandae-aut", 79 | "private_notes" => "Consequatur ut voluptate et rerum natus excepturi qui. Aut consequatur ut aut. Sint iure magni possimus vel omnis non.", 80 | "balance" => 1537.73, 81 | "group_settings_id" => "", 82 | "paid_to_date" => 0, 83 | "credit_balance" => 0, 84 | "last_login" => 0, 85 | "size_id" => "", 86 | "public_notes" => "", 87 | "client_hash" => "qKaZ2Y0xgGnhXsHKyV8mKxXv6tF9tHx2h4AlmAul", 88 | "address1" => "52506", 89 | "address2" => "94067 Maverick Ranch Suite 080", 90 | "phone" => "", 91 | "city" => "Port Danaside", 92 | "state" => "Georgia", 93 | "postal_code" => "51342-6348", 94 | "country_id" => "686", 95 | "industry_id" => "", 96 | "custom_value1" => "", 97 | "custom_value2" => "", 98 | "custom_value3" => "", 99 | "custom_value4" => "", 100 | "shipping_address1" => "4149", 101 | "shipping_address2" => "71001 Pagac Lock", 102 | "shipping_city" => "Blickberg", 103 | "shipping_state" => "Vermont", 104 | "shipping_postal_code" => "83727-6609", 105 | "shipping_country_id" => "4", 106 | "settings" => [ 107 | "entity" => "App\\Models\\Client", 108 | "industry_id" => "", 109 | "size_id" => "", 110 | "currency_id" => "1" 111 | ], 112 | "is_deleted" => false, 113 | "vat_number" => "441202649", 114 | "id_number" => "", 115 | "updated_at" => 1666836715, 116 | "archived_at" => 0, 117 | "created_at" => 1666836715, 118 | "display_name" => "Bosco-Keeling", 119 | "contacts" => [ 120 | [ 121 | "id" => "xkazvJVyaJ", 122 | "first_name" => "Julius", 123 | "last_name" => "Bosco", 124 | "email" => "user@example.com", 125 | "created_at" => 1666836715, 126 | "updated_at" => 1666836715, 127 | "archived_at" => 0, 128 | "is_primary" => true, 129 | "is_locked" => false, 130 | "phone" => "+1-567-788-1383", 131 | "custom_value1" => "", 132 | "custom_value2" => "", 133 | "custom_value3" => "", 134 | "custom_value4" => "", 135 | "contact_key" => "wTu6GS0QPLY7liX0wWqQKl75OUrmtTpfZ9aHrURu", 136 | "send_email" => true, 137 | "last_login" => 0, 138 | "password" => "**********", 139 | "link" => "http =>\/\/ninja.test =>8000\/client\/key_login\/wTu6GS0QPLY7liX0wWqQKl75OUrmtTpfZ9aHrURu" 140 | ], 141 | [ 142 | "id" => "w9aANGjlbv", 143 | "first_name" => "Carson", 144 | "last_name" => "Frami", 145 | "email" => "jean15@example.org", 146 | "created_at" => 1666836715, 147 | "updated_at" => 1666836715, 148 | "archived_at" => 0, 149 | "is_primary" => false, 150 | "is_locked" => false, 151 | "phone" => "+1-785-926-8599", 152 | "custom_value1" => "", 153 | "custom_value2" => "", 154 | "custom_value3" => "", 155 | "custom_value4" => "", 156 | "contact_key" => "qk80shH9KmuWVwOo6Ca918gENLnEwlt7nbORzCRg", 157 | "send_email" => true, 158 | "last_login" => 0, 159 | "password" => "**********", 160 | "link" => "http =>\/\/ninja.test =>8000\/client\/key_login\/qk80shH9KmuWVwOo6Ca918gENLnEwlt7nbORzCRg" 161 | ], 162 | [ 163 | "id" => "46dBNJlYd7", 164 | "first_name" => "Tavares", 165 | "last_name" => "Ebert", 166 | "email" => "stokes.eden@example.org", 167 | "created_at" => 1666836715, 168 | "updated_at" => 1666836715, 169 | "archived_at" => 0, 170 | "is_primary" => false, 171 | "is_locked" => false, 172 | "phone" => "+1-870-840-9344", 173 | "custom_value1" => "", 174 | "custom_value2" => "", 175 | "custom_value3" => "", 176 | "custom_value4" => "", 177 | "contact_key" => "j7r0rh5L3WgeqHJGm7wa0GHnIqXKSfr1N6eHEchR", 178 | "send_email" => true, 179 | "last_login" => 0, 180 | "password" => "**********", 181 | "link" => "http =>\/\/ninja.test =>8000\/client\/key_login\/j7r0rh5L3WgeqHJGm7wa0GHnIqXKSfr1N6eHEchR" 182 | ] 183 | ] 184 | ]; 185 | 186 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 187 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 188 | 189 | $client = $ninja->clients->create($create); 190 | 191 | $this->assertTrue(is_array($client)); 192 | 193 | $clients = $ninja->clients->update($client['data']['id'], ['name' => 'A new client name updated']); 194 | 195 | $this->assertTrue(is_array($client)); 196 | 197 | } 198 | 199 | 200 | 201 | 202 | 203 | public function testClientPost() 204 | { 205 | 206 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 207 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 208 | 209 | $clients = $ninja->clients->create(['name' => 'Brand spanking new client']); 210 | 211 | $this->assertTrue(is_array($clients)); 212 | 213 | } 214 | 215 | 216 | public function testClientWithContactPost() 217 | { 218 | 219 | $ninja = new InvoiceNinja($_ENV['INVOICENINJA_TOKEN']); 220 | $ninja->setUrl($_ENV['INVOICENINJA_URL']); 221 | 222 | $clients = $ninja->clients->create([ 223 | 'name' => 'Brand spanking new client', 224 | 'contacts' => [ 225 | [ 226 | 'first_name' => 'first', 227 | 'last_name' => 'last', 228 | 'send_email' => true, 229 | 'email' => 'joe@gmail.com', 230 | ], 231 | 232 | ] 233 | ]); 234 | 235 | $this->assertTrue(is_array($clients)); 236 | 237 | } 238 | } --------------------------------------------------------------------------------