Skip to content

Commit

Permalink
Merge pull request #13 from Morning-Train/feature/customer-contacts
Browse files Browse the repository at this point in the history
Customer Contacts
  • Loading branch information
mschadegg authored Feb 22, 2024
2 parents b99bb9f + 3f394f7 commit 685d90c
Show file tree
Hide file tree
Showing 22 changed files with 324 additions and 32 deletions.
7 changes: 6 additions & 1 deletion src/Abstracts/Endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

abstract class Endpoint
{
public function __construct(protected string $endpoint, protected ?string $slug = null)
public function __construct(protected string $endpoint, protected ?array $references = null)
{
}

Expand Down Expand Up @@ -42,6 +42,11 @@ public function getEndpoint(...$references): string
return $endpoint;
}

public function getEndpointReferences(): array
{
return $this->references;
}

/**
* Check if endpoint is the same as the given slug
*/
Expand Down
3 changes: 3 additions & 0 deletions src/Attributes/Resources/GetCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@

#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)] class GetCollection extends Endpoint
{
public function __construct(protected string $endpoint)
{
}
}
3 changes: 3 additions & 0 deletions src/Attributes/Resources/GetSingle.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@

#[Attribute(Attribute::TARGET_CLASS)] class GetSingle extends Endpoint
{
public function __construct(protected string $endpoint)
{
}
}
2 changes: 1 addition & 1 deletion src/Classes/EconomicRelatedResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function where(int|string $propertyName, string $operatorOrValue, mixed $

}

public function first(): static
public function first(): Resource
{
return (new EconomicQueryBuilder($this->resourceClass))->setEndpoint($this->endpointCollection->getEndpoint($this->references))->first();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#[GetCollection('customers')]
#[GetSingle('customers/:customerNumber')]
#[Create('customers')]
#[Update('customers/:customerNumber')]
#[Update('customers/:customerNumber', [':customerNumber' => 'customerNumber'])]
class Customer extends Resource
{
/**
Expand Down
54 changes: 39 additions & 15 deletions src/Resources/Customer/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,47 @@
use Morningtrain\Economic\Attributes\Resources\Delete;
use Morningtrain\Economic\Attributes\Resources\GetCollection;
use Morningtrain\Economic\Attributes\Resources\GetSingle;
use Morningtrain\Economic\Attributes\Resources\Properties\PrimaryKey;
use Morningtrain\Economic\Attributes\Resources\Update;
use Morningtrain\Economic\Classes\EconomicRelatedResource;
use Morningtrain\Economic\Resources\Customer;
use Morningtrain\Economic\Services\EconomicApiService;
use Morningtrain\Economic\Traits\Resources\Creatable;
use Morningtrain\Economic\Traits\Resources\Deletable;
use Morningtrain\Economic\Traits\Resources\EndpointResolvable;
use Morningtrain\Economic\Traits\Resources\GetCollectionable;
use Morningtrain\Economic\Traits\Resources\GetSingleable;
use Morningtrain\Economic\Traits\Resources\Updatable;

#[GetCollection('customers/:customerNumber/contacts')]
#[GetSingle('customers/:customerNumber/contacts/:contactNumber')]
#[Create('customers/:customerNumber/contacts')]
#[Update('customers/:customerNumber/contacts/:contactNumber')]
#[Delete('customers/:customerNumber/contacts/:contactNumber')]
#[Update('customers/:customerNumber/contacts/:contactNumber', [':customerNumber' => 'customer->customerNumber', ':contactNumber' => 'customerContactNumber'])]
#[Delete('customers/:customerNumber/contacts/:contactNumber', [':customerNumber' => 'customer->customerNumber', ':contactNumber' => 'customerContactNumber'])]
class Contact extends Resource
{
use Creatable, EndpointResolvable;
use Creatable, Deletable, EndpointResolvable, GetCollectionable, GetSingleable, Updatable;

public Customer $customer;

public float $customerContactNumber;
#[PrimaryKey]
public int $customerContactNumber;

public bool $deleted;
public ?bool $deleted = null;

public string $eInvoiceId;
public ?string $eInvoiceId = null;

public string $email;
public ?string $email = null;

public array $emailNotifications;
public array $emailNotifications = [];

public string $name;
public ?string $name = null;

public string $notes;
public ?string $notes = null;

public string $phone;
public ?string $phone = null;

public int $sortKey;
public ?int $sortKey = null;

public static function fromCustomer(Customer|int $customer)
{
Expand All @@ -53,22 +60,39 @@ public static function fromCustomer(Customer|int $customer)
}

public static function create(
Customer $customer,
Customer|int $customer,
string $name,
?string $email = null,
?string $phone = null,
?string $notes = null,
?string $eInvoiceId = null,
?array $emailNotifications = null
) {
return static::createRequest(array_filter(compact(
if (! is_a($customer, Customer::class)) {
$customer = new Customer($customer);
}

return static::createRequest(compact(
'customer',
'name',
'email',
'phone',
'notes',
'eInvoiceId',
'emailNotifications'
)), [$customer->customerNumber]);
), [$customer->customerNumber]);
}

public static function deleteByPrimaryKey(int|string $customerNumber, int|string $customerContactNumber): bool
{
$response = EconomicApiService::delete(static::getEndpoint(Delete::class, $customerNumber, $customerContactNumber));

if ($response->getStatusCode() !== 204) {
// TODO: Log error and throw exception

return false;
}

return true;
}
}
4 changes: 2 additions & 2 deletions src/Resources/CustomerGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#[GetCollection('customer-groups')]
#[GetSingle('customer-groups/:customerGroupNumber')]
#[Create('customer-groups')]
#[Update('customer-groups/:customerGroupNumber')]
#[Delete('customer-groups/:customerGroupNumber')]
#[Update('customer-groups/:customerGroupNumber', [':customerGroupNumber' => 'customerGroupNumber'])]
#[Delete('customer-groups/:customerGroupNumber', [':customerGroupNumber' => 'customerGroupNumber'])]
class CustomerGroup extends Resource
{
use Creatable, Deletable, GetCollectionable, GetSingleable, Updatable;
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/Invoice/BookedInvoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Morningtrain\Economic\Attributes\Resources\GetSingle;

#[GetCollection('invoices/booked')]
#[GetSingle('invoices/booked/:bookedInvoiceNumber', ':bookedInvoiceNumber')]
#[GetSingle('invoices/booked/:bookedInvoiceNumber')]
#[Create('invoices/booked')]
class BookedInvoice extends Invoice
{
Expand Down
4 changes: 2 additions & 2 deletions src/Resources/Invoice/DraftInvoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
use Morningtrain\Economic\Traits\Resources\Updatable;

#[GetCollection('invoices/drafts')]
#[GetSingle('invoices/drafts/:draftInvoiceNumber', ':draftInvoiceNumber')]
#[GetSingle('invoices/drafts/:draftInvoiceNumber')]
#[Create('invoices/drafts')]
#[Update('invoices/drafts/:draftInvoiceNumber', ':draftInvoiceNumber')]
#[Update('invoices/drafts/:draftInvoiceNumber', [':draftInvoiceNumber' => 'draftInvoiceNumber'])]
class DraftInvoice extends Invoice
{
use Updatable {
Expand Down
4 changes: 2 additions & 2 deletions src/Resources/PaymentTerm.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
#[GetCollection('payment-terms')]
#[GetSingle('payment-terms/:paymentTermsNumber')]
#[Create('payment-terms')]
#[Update('payment-terms/:paymentTermsNumber')]
#[Delete('payment-terms/:paymentTermsNumber')]
#[Update('payment-terms/:paymentTermsNumber', [':paymentTermsNumber' => 'paymentTermsNumber'])]
#[Delete('payment-terms/:paymentTermsNumber', [':paymentTermsNumber' => 'paymentTermsNumber'])]
class PaymentTerm extends Resource
{
use Creatable, Deletable, GetCollectionable, GetSingleable, Updatable;
Expand Down
4 changes: 2 additions & 2 deletions src/Resources/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
#[GetCollection('products')] // https://restdocs.e-conomic.com/#get-products
#[GetSingle('products/:productNumber', ':productNumber')]
#[Create('products')]
#[Update('products/:productNumber', ':productNumber')]
#[Delete('products/:productNumber', ':productNumber')]
#[Update('products/:productNumber', [':productNumber' => 'productNumber'])]
#[Delete('products/:productNumber', [':productNumber' => 'productNumber'])]
class Product extends Resource
{
/**
Expand Down
5 changes: 2 additions & 3 deletions src/Resources/Unit.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
#[GetCollection('units')]
#[GetSingle('units/:unitNumber')]
#[Create('units')]
#[Update('units/:unitNumber')]
#[Delete('units/:unitNumber')]
#[GetCollection('units/:unitNumber/products', 'products')]
#[Update('units/:unitNumber', [':unitNumber' => 'unitNumber'])]
#[Delete('units/:unitNumber', [':unitNumber' => 'unitNumber'])]
class Unit extends Resource
{
use Creatable, Deletable, GetCollectionable, GetSingleable, Updatable;
Expand Down
2 changes: 1 addition & 1 deletion src/Traits/Resources/Deletable.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait Deletable

public function delete(): bool
{
$response = EconomicApiService::delete(static::getEndpoint(Delete::class, $this->getPrimaryKey()));
$response = EconomicApiService::delete(static::getEndpoint(Delete::class, $this));

if ($response->getStatusCode() !== 204) {
// TODO: Log error and throw exception
Expand Down
27 changes: 27 additions & 0 deletions src/Traits/Resources/EndpointResolvable.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use Morningtrain\Economic\Abstracts\Endpoint;
use Morningtrain\Economic\Abstracts\Resource;
use ReflectionClass;

trait EndpointResolvable
Expand All @@ -22,9 +23,35 @@ public static function getEndpoint(string $endpointAttributeClass, ...$reference
throw new Exception('Endpoint attribute does not implement Endpoint');
}

if (isset($references[0]) && is_a($references[0], Resource::class)) {
$references = static::getEndpointReferences($instance, $references[0]);
}

return $instance->getEndpoint(...$references);
}

private static function getEndpointReferences(Endpoint $endpoint, Resource $resource): array
{
$references = [];

foreach ($endpoint->getEndpointReferences() as $name => $variable) {
$var = $resource;

foreach (explode('->', $variable) as $key) {
if (isset($var->$key)) {
$var = $var->$key;
} else {
$var = null;
break;
}
}

$references[$name] = $var;
}

return $references;
}

/**
* @param string $slug - The attribute slug to resolve
* @param ...$references - The references to pass to the endpoint. Can be strings, integers or a single array with references
Expand Down
2 changes: 1 addition & 1 deletion src/Traits/Resources/Updatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function save(): static
{
// TODO: add validation method to check if required properties are set and primary key is set - throw exception if not

$response = EconomicApiService::put(static::getEndpoint(Update::class, $this->getPrimaryKey()), $this->toArray());
$response = EconomicApiService::put(static::getEndpoint(Update::class, $this), $this->toArray());

if ($response->getStatusCode() !== 200) {
EconomicLoggerService::error('Economic API Service returned a non 200 status code when updating a resource', [
Expand Down
9 changes: 9 additions & 0 deletions tests/Fixtures/Customers/Contacts/create-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"customer": {
"customerNumber": 1
},
"name": "John Doe",
"email": "[email protected]",
"phone": "12345678",
"notes": "Test"
}
13 changes: 13 additions & 0 deletions tests/Fixtures/Customers/Contacts/create-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"customerContactNumber": 140,
"email": "[email protected]",
"name": "John Doe",
"phone": "12345678",
"notes": "Test",
"customer": {
"customerNumber": 1,
"self": "https://restapi.e-conomic.com/customers/1"
},
"sortKey": 7,
"self": "https://restapi.e-conomic.com/customers/1/contacts/142"
}
64 changes: 64 additions & 0 deletions tests/Fixtures/Customers/Contacts/get-collection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"collection": [
{
"customerContactNumber": 136,
"name": "Test 1",
"customer": {
"customerNumber": 1,
"self": "https://restapi.e-conomic.com/customers/1"
},
"sortKey": 1,
"self": "https://restapi.e-conomic.com/customers/1/contacts/136"
},
{
"customerContactNumber": 137,
"name": "Test 2",
"customer": {
"customerNumber": 1,
"self": "https://restapi.e-conomic.com/customers/1"
},
"sortKey": 2,
"self": "https://restapi.e-conomic.com/customers/1/contacts/137"
},
{
"customerContactNumber": 138,
"name": "Test 3",
"customer": {
"customerNumber": 1,
"self": "https://restapi.e-conomic.com/customers/1"
},
"sortKey": 3,
"self": "https://restapi.e-conomic.com/customers/1/contacts/138"
},
{
"customerContactNumber": 139,
"name": "Test 4",
"customer": {
"customerNumber": 1,
"self": "https://restapi.e-conomic.com/customers/1"
},
"sortKey": 4,
"self": "https://restapi.e-conomic.com/customers/1/contacts/139"
},
{
"customerContactNumber": 140,
"name": "Test 5",
"customer": {
"customerNumber": 1,
"self": "https://restapi.e-conomic.com/customers/1"
},
"sortKey": 5,
"self": "https://restapi.e-conomic.com/customers/1/contacts/140"
}
],
"pagination": {
"skipPages": 0,
"pageSize": 20,
"maxPageSizeAllowed": 1000,
"results": 5,
"resultsWithoutFilter": 5,
"firstPage": "https://restapi.e-conomic.com/customers/1/contacts?skipPages=0&pageSize=20",
"lastPage": "https://restapi.e-conomic.com/customers/1/contacts?skipPages=0&pageSize=20"
},
"self": "https://restapi.e-conomic.com/customers/1/contacts?skipPages=0&pageSize=20"
}
10 changes: 10 additions & 0 deletions tests/Fixtures/Customers/Contacts/get-single.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"customerContactNumber": 140,
"name": "Test 5",
"customer": {
"customerNumber": 1,
"self": "https://restapi.e-conomic.com/customers/1"
},
"sortKey": 5,
"self": "https://restapi.e-conomic.com/customers/1/contacts/140"
}
11 changes: 11 additions & 0 deletions tests/Fixtures/Customers/Contacts/update-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"customer": {
"customerNumber": 1,
"self": "https:\/\/restapi.e-conomic.com\/customers\/1"
},
"customerContactNumber": 140,
"emailNotifications": [],
"name": "Martin",
"sortKey": 5,
"self": "https:\/\/restapi.e-conomic.com\/customers\/1\/contacts\/140"
}
Loading

0 comments on commit 685d90c

Please sign in to comment.