Skip to content

Commit 76ca582

Browse files
committed
feat: add invoices.
1 parent f28cbec commit 76ca582

13 files changed

+1000
-1
lines changed

src/Currency.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace TeamWorkPm;
6+
7+
use TeamWorkPm\Rest\Resource;
8+
use TeamWorkPm\Rest\Resource\GetAllTrait;
9+
10+
class Currency extends Resource
11+
{
12+
use GetAllTrait;
13+
14+
protected ?string $parent = 'currency-codes';
15+
16+
protected ?string $action = 'currencycodes';
17+
18+
protected string|array $fields = [];
19+
}

src/Expense.php

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
use TeamWorkPm\Rest\Resource\Model;
88
use TeamWorkPm\Rest\Resource\Project\GetByTrait;
99

10+
/**
11+
* @see https://apidocs.teamwork.com/docs/teamwork/v1/expenses/get-expenses-json
12+
*/
1013
class Expense extends Model
1114
{
1215
use GetByTrait;

src/Invoice.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace TeamWorkPm;
6+
7+
use TeamWorkPm\Rest\Resource\Model;
8+
use TeamWorkPm\Rest\Resource\Project\ActionTrait as ProjectTrait;
9+
use TeamWorkPm\Rest\Resource\CompleteTrait;
10+
11+
/**
12+
* @see https://apidocs.teamwork.com/docs/teamwork/v1/invoices/get-invoices-json
13+
*/
14+
class Invoice extends Model
15+
{
16+
use ProjectTrait, CompleteTrait;
17+
18+
protected ?string $parent = 'invoice';
19+
20+
protected ?string $action = 'invoices';
21+
22+
protected string|array $fields = 'invoices';
23+
24+
public function addTime(int $id, string $time): bool
25+
{
26+
return $this->notUseFields()
27+
->put("$this->action/$id/lineitems", [
28+
'lineitems' => [
29+
'add' => [
30+
'timelogs' => "$time"
31+
]
32+
]
33+
]);
34+
}
35+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"description": {
3+
"type": "string"
4+
},
5+
"fixed_cost": {
6+
"type": "string",
7+
"transform": "dash"
8+
},
9+
"number": {
10+
"type": "string",
11+
"required": true
12+
},
13+
"po_number": {
14+
"type": "string",
15+
"transform": "dash"
16+
},
17+
"display_date": {
18+
"type": "string",
19+
"transform": "dash",
20+
"required": true
21+
},
22+
"currency_code": {
23+
"type": "string",
24+
"transform": "dash"
25+
}
26+
}

src/Rest/Response/JSON.php

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ public function parse(string $data, array $headers): static | int | bool | strin
3131
] = $headers;
3232

3333
if (!in_array($status, [200, 201, 204])) {
34+
if ($status === 500 && isset($source['content'])) {
35+
$source = $source['content'];
36+
if (isset($source['errors']) && is_array($source['errors'])) {
37+
$source['error'] = implode(PHP_EOL, $source['errors']);
38+
}
39+
}
3440
$errors = $source['MESSAGE'] ?? $source['error'] ?? $errors ?? "Unknown error ($status) status";
3541
}
3642
if ($errors !== null) {

tests/CurrencyTest.php

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace TeamWorkPm\Tests;
4+
5+
final class CurrencyTest extends TestCase
6+
{
7+
public function testAll(): void
8+
{
9+
$this->assertGreaterThan(0, count($this->factory('currency', [
10+
'GET /currencycodes' => true
11+
])->all()));
12+
}
13+
}

tests/InvoiceTest.php

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
namespace TeamWorkPm\Tests;
4+
5+
final class InvoiceTest extends TestCase
6+
{
7+
/**
8+
* @dataProvider provider
9+
*/
10+
public function testCreate(array $data): void
11+
{
12+
$this->assertEquals(TPM_TEST_ID, $this->factory('invoice', [
13+
'POST /projects/' . TPM_PROJECT_ID_1 . '/invoices' => fn($data) => $this->assertMatchesJsonSnapshot($data)
14+
])->create($data));
15+
}
16+
17+
public function testAll(): void
18+
{
19+
$this->assertGreaterThan(0, count($this->factory('invoice', [
20+
'GET /invoices' => true
21+
])->all()));
22+
}
23+
24+
public function testGetByProject(): void
25+
{
26+
$this->assertGreaterThan(0, count($this->factory('invoice', [
27+
'GET /projects/' . TPM_PROJECT_ID_1 . '/invoices' => true
28+
])->getByProject(TPM_PROJECT_ID_1)));
29+
}
30+
31+
public function testGet(): void
32+
{
33+
$this->assertEquals('USD', $this->factory('invoice', [
34+
'GET /invoices/' . TPM_INVOICE_ID => true
35+
])->get(TPM_INVOICE_ID)->currencyCode);
36+
}
37+
38+
/**
39+
* @dataProvider provider
40+
*/
41+
public function testUpdate(array $data): void
42+
{
43+
$data['id'] = TPM_INVOICE_ID;
44+
$data['description'] = 'Updated Invoice Description';
45+
$this->assertTrue($this->factory('invoice', [
46+
'PUT /invoices/' . TPM_INVOICE_ID => true
47+
])->update($data));
48+
}
49+
50+
public function testComplete(): void
51+
{
52+
$this->assertTrue($this->factory('invoice', [
53+
'PUT /invoices/' . TPM_INVOICE_ID . '/complete' => true
54+
])->complete(TPM_INVOICE_ID));
55+
}
56+
57+
public function testUnComplete(): void
58+
{
59+
$this->assertTrue($this->factory('invoice', [
60+
'PUT /invoices/' . TPM_INVOICE_ID . '/uncomplete' => true
61+
])->unComplete(TPM_INVOICE_ID));
62+
}
63+
64+
/**
65+
* @todo This test fail on real api
66+
*
67+
* @return void
68+
*/
69+
public function testAddTime(): void
70+
{
71+
$this->assertTrue($this->factory('invoice', [
72+
'PUT /invoices/' . TPM_INVOICE_ID . '/lineitems' => true
73+
])->addTime(TPM_INVOICE_ID, '10 hours'));
74+
}
75+
76+
public function testDelete(): void
77+
{
78+
$this->assertTrue($this->factory('invoice', [
79+
'DELETE /invoices/' . TPM_INVOICE_ID => true
80+
])->delete(TPM_INVOICE_ID));
81+
}
82+
83+
public function provider()
84+
{
85+
return [
86+
[
87+
[
88+
'description' => 'Bla, Bla, Bla',
89+
'number' => 100,
90+
'project_id' => TPM_PROJECT_ID_1,
91+
'display_date' => '20250101'
92+
],
93+
],
94+
];
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"invoice": {
3+
"description": "Bla, Bla, Bla",
4+
"number": "100",
5+
"display-date": "20250101"
6+
}
7+
}

tests/bootstrap.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,6 @@
5858

5959
const TPM_PORTFOLIO_CARD_ID = 121235;
6060

61-
const TPM_EXPENSE_ID = 2757;
61+
const TPM_EXPENSE_ID = 2757;
62+
63+
const TPM_INVOICE_ID = 128550;

0 commit comments

Comments
 (0)