Skip to content

Commit

Permalink
feat: add invoices.
Browse files Browse the repository at this point in the history
  • Loading branch information
loduis committed Jan 11, 2025
1 parent f28cbec commit 76ca582
Show file tree
Hide file tree
Showing 13 changed files with 1,000 additions and 1 deletion.
19 changes: 19 additions & 0 deletions src/Currency.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types = 1);

namespace TeamWorkPm;

use TeamWorkPm\Rest\Resource;
use TeamWorkPm\Rest\Resource\GetAllTrait;

class Currency extends Resource
{
use GetAllTrait;

protected ?string $parent = 'currency-codes';

protected ?string $action = 'currencycodes';

protected string|array $fields = [];
}
3 changes: 3 additions & 0 deletions src/Expense.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use TeamWorkPm\Rest\Resource\Model;
use TeamWorkPm\Rest\Resource\Project\GetByTrait;

/**
* @see https://apidocs.teamwork.com/docs/teamwork/v1/expenses/get-expenses-json
*/
class Expense extends Model
{
use GetByTrait;
Expand Down
35 changes: 35 additions & 0 deletions src/Invoice.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types = 1);

namespace TeamWorkPm;

use TeamWorkPm\Rest\Resource\Model;
use TeamWorkPm\Rest\Resource\Project\ActionTrait as ProjectTrait;
use TeamWorkPm\Rest\Resource\CompleteTrait;

/**
* @see https://apidocs.teamwork.com/docs/teamwork/v1/invoices/get-invoices-json
*/
class Invoice extends Model
{
use ProjectTrait, CompleteTrait;

protected ?string $parent = 'invoice';

protected ?string $action = 'invoices';

protected string|array $fields = 'invoices';

public function addTime(int $id, string $time): bool
{
return $this->notUseFields()
->put("$this->action/$id/lineitems", [
'lineitems' => [
'add' => [
'timelogs' => "$time"
]
]
]);
}
}
26 changes: 26 additions & 0 deletions src/Rest/Resource/schemas/invoices.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"description": {
"type": "string"
},
"fixed_cost": {
"type": "string",
"transform": "dash"
},
"number": {
"type": "string",
"required": true
},
"po_number": {
"type": "string",
"transform": "dash"
},
"display_date": {
"type": "string",
"transform": "dash",
"required": true
},
"currency_code": {
"type": "string",
"transform": "dash"
}
}
6 changes: 6 additions & 0 deletions src/Rest/Response/JSON.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ public function parse(string $data, array $headers): static | int | bool | strin
] = $headers;

if (!in_array($status, [200, 201, 204])) {
if ($status === 500 && isset($source['content'])) {
$source = $source['content'];
if (isset($source['errors']) && is_array($source['errors'])) {
$source['error'] = implode(PHP_EOL, $source['errors']);
}
}
$errors = $source['MESSAGE'] ?? $source['error'] ?? $errors ?? "Unknown error ($status) status";
}
if ($errors !== null) {
Expand Down
13 changes: 13 additions & 0 deletions tests/CurrencyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace TeamWorkPm\Tests;

final class CurrencyTest extends TestCase
{
public function testAll(): void
{
$this->assertGreaterThan(0, count($this->factory('currency', [
'GET /currencycodes' => true
])->all()));
}
}
96 changes: 96 additions & 0 deletions tests/InvoiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

namespace TeamWorkPm\Tests;

final class InvoiceTest extends TestCase
{
/**
* @dataProvider provider
*/
public function testCreate(array $data): void
{
$this->assertEquals(TPM_TEST_ID, $this->factory('invoice', [
'POST /projects/' . TPM_PROJECT_ID_1 . '/invoices' => fn($data) => $this->assertMatchesJsonSnapshot($data)
])->create($data));
}

public function testAll(): void
{
$this->assertGreaterThan(0, count($this->factory('invoice', [
'GET /invoices' => true
])->all()));
}

public function testGetByProject(): void
{
$this->assertGreaterThan(0, count($this->factory('invoice', [
'GET /projects/' . TPM_PROJECT_ID_1 . '/invoices' => true
])->getByProject(TPM_PROJECT_ID_1)));
}

public function testGet(): void
{
$this->assertEquals('USD', $this->factory('invoice', [
'GET /invoices/' . TPM_INVOICE_ID => true
])->get(TPM_INVOICE_ID)->currencyCode);
}

/**
* @dataProvider provider
*/
public function testUpdate(array $data): void
{
$data['id'] = TPM_INVOICE_ID;
$data['description'] = 'Updated Invoice Description';
$this->assertTrue($this->factory('invoice', [
'PUT /invoices/' . TPM_INVOICE_ID => true
])->update($data));
}

public function testComplete(): void
{
$this->assertTrue($this->factory('invoice', [
'PUT /invoices/' . TPM_INVOICE_ID . '/complete' => true
])->complete(TPM_INVOICE_ID));
}

public function testUnComplete(): void
{
$this->assertTrue($this->factory('invoice', [
'PUT /invoices/' . TPM_INVOICE_ID . '/uncomplete' => true
])->unComplete(TPM_INVOICE_ID));
}

/**
* @todo This test fail on real api
*
* @return void
*/
public function testAddTime(): void
{
$this->assertTrue($this->factory('invoice', [
'PUT /invoices/' . TPM_INVOICE_ID . '/lineitems' => true
])->addTime(TPM_INVOICE_ID, '10 hours'));
}

public function testDelete(): void
{
$this->assertTrue($this->factory('invoice', [
'DELETE /invoices/' . TPM_INVOICE_ID => true
])->delete(TPM_INVOICE_ID));
}

public function provider()
{
return [
[
[
'description' => 'Bla, Bla, Bla',
'number' => 100,
'project_id' => TPM_PROJECT_ID_1,
'display_date' => '20250101'
],
],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"invoice": {
"description": "Bla, Bla, Bla",
"number": "100",
"display-date": "20250101"
}
}
4 changes: 3 additions & 1 deletion tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@

const TPM_PORTFOLIO_CARD_ID = 121235;

const TPM_EXPENSE_ID = 2757;
const TPM_EXPENSE_ID = 2757;

const TPM_INVOICE_ID = 128550;
Loading

0 comments on commit 76ca582

Please sign in to comment.