diff --git a/Exception.php b/Exception.php deleted file mode 100644 index 623a8e1..0000000 --- a/Exception.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class Exception extends \Exception -{ -} diff --git a/README.md b/README.md index 137dec2..0027340 100755 --- a/README.md +++ b/README.md @@ -10,6 +10,41 @@ PHP DeFactuur is a (wrapper)class to communicate with [De Factuur](https://www.d PHP DeFactuur is [BSD](http://classes.verkoyen.eu/overview/bsd) licensed. +## Initialisation + +Using symfony/httpclient: + + use Nyholm\Psr7\Factory\Psr17Factory; + use Symfony\Component\HttpClient\Psr18Client; + + $deFactuur = new DeFactuur( + new Psr18Client(), + new Psr17Factory(), + new Psr17Factory(), + 'your_api_token' + ); + +Using Guzzle: + + $deFactuur = new \SumoCoders\DeFactuur\DeFactuur( + new \GuzzleHttp\Client(), + new \Nyholm\Psr7\Factory\Psr17Factory(), + new \Nyholm\Psr7\Factory\Psr17Factory(), + 'your_api_token' + ); + +You can replace Psr17Factory with your own implementations of PSR-17's RequestFactoryInterface and StreamFactoryInterface. + +## Using DeFactuur as a Service + +Add the following to your services.yml: + + SumoCoders\DeFactuur\DeFactuur: + arguments: + $apiToken: '%your.api.token%' + +If you use auto-wiring, that's it! + ## Documentation Each method in the class is well documented using PHPDoc. diff --git a/composer.json b/composer.json index 361c608..65e7efa 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,11 @@ "php": ">=7.4.0", "ext-curl": "*", "ext-json": "*", - "symfony/http-client": "^5.3" + "psr/http-client": "^1.0", + "nyholm/psr7": "^1.4" + }, + "suggest": { + "symfony/http-client": "Low-level HTTP-client" }, "autoload": { "psr-4": {"SumoCoders\\DeFactuur\\": "src"} diff --git a/src/Client/Address.php b/src/Client/Address.php index 99c67ad..417e804 100644 --- a/src/Client/Address.php +++ b/src/Client/Address.php @@ -2,14 +2,6 @@ namespace SumoCoders\DeFactuur\Client; -/** - * Address class - * - * @author Tijs Verkoyen - * @version 2.0.0 - * @copyright Copyright (c), Tijs Verkoyen. All rights reserved. - * @license BSD License - */ class Address { protected string $country; diff --git a/src/Client/Client.php b/src/Client/Client.php index 1784306..726e83d 100644 --- a/src/Client/Client.php +++ b/src/Client/Client.php @@ -2,59 +2,84 @@ namespace SumoCoders\DeFactuur\Client; -/** - * Client class - * - * @author Tijs Verkoyen - * @version 2.0.0 - * @copyright Copyright (c), Tijs Verkoyen. All rights reserved. - * @license BSD License - */ class Client { - protected int $id; + // required + protected string $lastName; - protected int $paymentDays; + protected array $email; - protected int $replacedById; + protected Address $billingAddress; - protected string $cid; + protected Address $companyAddress; - protected string $company; + // optional + protected ?int $id; - protected string $vat; + protected ?int $paymentDays; - protected string $firstName; + protected ?int $replacedById; - protected string $lastName; + protected ?string $cid; - protected string $phone; + protected ?string $company; - protected string $fax; + protected ?string $vat; - protected string $cell; + protected ?string $firstName; - protected string $website; + protected ?string $phone; - protected string $remarks; + protected ?string $fax; - protected Address $billingAddress; + protected ?string $cell; - protected Address $companyAddress; + protected ?string $website; - protected array $email; + protected ?string $remarks; - protected bool $invoiceableByEmail; + protected ?bool $invoiceableByEmail; - protected bool $invoiceableBySnailMail; + protected ?bool $invoiceableBySnailMail; - protected bool $invoiceableByFactr; + protected ?bool $invoiceableByFactr; - protected bool $disabled = false; + protected ?bool $disabled; - public function setBillingAddress(Address $billingAddress): void + public function __construct( + string $lastName, + array $email, + Address $billingAddress, + Address $companyAddress + ) { + $this->lastName = $lastName; + $this->email = $email; + $this->billingAddress = $billingAddress; + $this->companyAddress = $companyAddress; + + $this->id = null; + $this->paymentDays = null; + $this->replacedById = null; + $this->cid = null; + $this->company = null; + $this->vat = null; + $this->firstName = null; + $this->phone = null; + $this->fax = null; + $this->cell = null; + $this->website = null; + $this->remarks = null; + $this->invoiceableByEmail = null; + $this->invoiceableBySnailMail = null; + $this->invoiceableByFactr = null; + $this->disabled = null; + } + + public function setBillingAddress(Address $billingAddress): Client { $this->billingAddress = $billingAddress; + + return $this; } public function getBillingAddress(): Address @@ -62,32 +87,38 @@ public function getBillingAddress(): Address return $this->billingAddress; } - public function setCell(string $cell): void + public function setCell(string $cell): Client { $this->cell = $cell; + + return $this; } - public function getCell(): string + public function getCell(): ?string { return $this->cell; } - public function setCid(string $cid): void + public function setCid(string $cid): Client { $this->cid = $cid; + + return $this; } - public function getCid(): string + public function getCid(): ?string { return $this->cid; } - public function setCompany(string $company): void + public function setCompany(string $company): Client { $this->company = $company; + + return $this; } - public function getCompany(): string + public function getCompany(): ?string { return $this->company; } @@ -102,14 +133,18 @@ public function getCompanyAddress(): Address return $this->companyAddress; } - public function addEmail(string $email): void + public function addEmail(string $email): Client { $this->email[] = $email; + + return $this; } - public function setEmail(array $email): void + public function setEmail(array $email): Client { $this->email = $email; + + return $this; } public function getEmail(): array @@ -117,69 +152,83 @@ public function getEmail(): array return $this->email; } - public function setFax(string $fax): void + public function setFax(string $fax): Client { $this->fax = $fax; + + return $this; } - public function getFax(): string + public function getFax(): ?string { return $this->fax; } - public function setFirstName(string $firstName): void + public function setFirstName(string $firstName): Client { $this->firstName = $firstName; + + return $this; } - public function getFirstName(): string + public function getFirstName(): ?string { return $this->firstName; } - private function setId(int $id): void + private function setId(int $id): Client { $this->id = $id; + + return $this; } - public function getId(): int + public function getId(): ?int { return $this->id; } - public function setInvoiceableByEmail(bool $invoiceableByEmail): void + public function setInvoiceableByEmail(bool $invoiceableByEmail): Client { $this->invoiceableByEmail = $invoiceableByEmail; + + return $this; } - public function getInvoiceableByEmail(): bool + public function getInvoiceableByEmail(): ?bool { return $this->invoiceableByEmail; } - public function setInvoiceableByFactr(bool $invoiceableByFactr): void + public function setInvoiceableByFactr(bool $invoiceableByFactr): Client { $this->invoiceableByFactr = $invoiceableByFactr; + + return $this; } - public function getInvoiceableByFactr(): bool + public function getInvoiceableByFactr(): ?bool { return $this->invoiceableByFactr; } - public function setInvoiceableBySnailMail(bool $invoiceableBySnailMail): void + public function setInvoiceableBySnailMail(bool $invoiceableBySnailMail): Client { $this->invoiceableBySnailMail = $invoiceableBySnailMail; + + return $this; } - public function getInvoiceableBySnailMail(): bool + public function getInvoiceableBySnailMail(): ?bool { return $this->invoiceableBySnailMail; } - public function setLastName(string $lastName): void + public function setLastName(string $lastName): Client { $this->lastName = $lastName; + + return $this; } public function getLastName(): string @@ -187,74 +236,88 @@ public function getLastName(): string return $this->lastName; } - public function setPaymentDays(int $paymentDays): void + public function setPaymentDays(int $paymentDays): Client { $this->paymentDays = $paymentDays; + + return $this; } - public function getPaymentDays(): int + public function getPaymentDays(): ?int { return $this->paymentDays; } - public function setPhone(string $phone): void + public function setPhone(string $phone): Client { $this->phone = $phone; + + return $this; } - public function getPhone(): string + public function getPhone(): ?string { return $this->phone; } - public function setRemarks(string $remarks): void + public function setRemarks(string $remarks): Client { $this->remarks = $remarks; + + return $this; } - public function getRemarks(): string + public function getRemarks(): ?string { return $this->remarks; } - public function setVat(string $vat): void + public function setVat(string $vat): Client { $this->vat = $vat; + + return $this; } - public function getVat(): string + public function getVat(): ?string { return $this->vat; } - public function setWebsite(string $website): void + public function setWebsite(string $website): Client { $this->website = $website; + + return $this; } - public function getWebsite(): string + public function getWebsite(): ?string { return $this->website; } - public function getReplacedById(): int + public function getReplacedById(): ?int { return $this->replacedById; } - public function setReplacedById(int $replacedById): void + public function setReplacedById(int $replacedById): Client { $this->replacedById = $replacedById; + + return $this; } - public function isDisabled(): bool + public function isDisabled(): ?bool { return $this->disabled; } - public function setDisabled(bool $disabled = true): void + public function setDisabled(bool $disabled = true): Client { $this->disabled = $disabled; + + return $this; } /** @@ -262,7 +325,12 @@ public function setDisabled(bool $disabled = true): void */ public static function initializeWithRawData(array $data): Client { - $item = new Client(); + $item = new Client( + $data['last_name'] ?? '', + $data['email'] ?? '', + Address::initializeWithRawData($data['billing_address'] ?? []), + Address::initializeWithRawData($data['company_address'] ?? []) + ); if(isset($data['id'])) $item->setId($data['id']); if(isset($data['cid'])) $item->setCid($data['cid']); @@ -300,7 +368,7 @@ public static function initializeWithRawData(array $data): Client */ public function toArray(bool $forApi = false): array { - $data = array(); + $data = []; $data['id'] = $this->getId(); $data['cid'] = $this->getCid(); diff --git a/DeFactuur.php b/src/DeFactuur.php similarity index 77% rename from DeFactuur.php rename to src/DeFactuur.php index 4f60f8f..6247721 100644 --- a/DeFactuur.php +++ b/src/DeFactuur.php @@ -3,7 +3,11 @@ namespace SumoCoders\DeFactuur; use InvalidArgumentException; -use SumoCoders\DeFactuur\Exception as FactuurException; +use Psr\Http\Client\ClientExceptionInterface; +use Psr\Http\Client\ClientInterface; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\StreamFactoryInterface; +use SumoCoders\DeFactuur\Exception as DeFactuurException; use SumoCoders\DeFactuur\Client\Client; use SumoCoders\DeFactuur\Invoice\Invoice; use SumoCoders\DeFactuur\Invoice\Mail; @@ -11,14 +15,6 @@ use SumoCoders\DeFactuur\Product\Product; use Exception; -/** - * DeFactuur class - * - * @author Tijs Verkoyen - * @version 2.0.0 - * @copyright Copyright (c), Tijs Verkoyen. All rights reserved. - * @license BSD License - */ class DeFactuur { // internal constant to enable/disable debugging @@ -41,12 +37,11 @@ class DeFactuur */ private string $apiToken; - /** - * cURL instance - * - * @var resource - */ - private $curl; + private ClientInterface $client; + + private RequestFactoryInterface $requestFactory; + + private StreamFactoryInterface $streamFactory; /** * The timeout @@ -59,13 +54,19 @@ class DeFactuur private string $userAgent; // class methods - /** - * Default destructor - */ - public function __destruct() - { - // close the curl-instance if needed - if($this->curl != null) curl_close($this->curl); + public function __construct( + ClientInterface $httpClient, + RequestFactoryInterface $requestFactory, + StreamFactoryInterface $streamFactory, + ?string $apiToken = null + ) { + $this->client = $httpClient; + $this->requestFactory = $requestFactory; + $this->streamFactory = $streamFactory; + + if ($apiToken !== null && $apiToken !== '') { + $this->apiToken = $apiToken; + } } /** @@ -110,7 +111,7 @@ private function encodeData($data, array $array = [], ?string $prefix = null): a * Make the call * * @return array|bool|string - * @throws FactuurException + * @throws DeFactuurException */ private function doCall( string $url, @@ -118,19 +119,13 @@ private function doCall( string $method = 'GET', bool $returnHeaders = false ) { - // redefine - $options = array(); + $data = null; // add credentials $parameters['api_key'] = $this->getApiToken(); // through GET if ($method == 'GET') { - // remove POST-specific stuff - unset($options[CURLOPT_HTTPHEADER]); - unset($options[CURLOPT_POST]); - unset($options[CURLOPT_POSTFIELDS]); - // build url $url .= '?' . http_build_query($parameters, null); $url = $this->removeIndexFromArrayParameters($url); @@ -141,86 +136,74 @@ private function doCall( $data = http_build_query($data, null); $data = $this->removeIndexFromArrayParameters($data); } - - $options[CURLOPT_POST] = true; - $options[CURLOPT_POSTFIELDS] = $data; } elseif ($method == 'DELETE') { - unset($options[CURLOPT_HTTPHEADER]); - unset($options[CURLOPT_POST]); - unset($options[CURLOPT_POSTFIELDS]); - $options[CURLOPT_CUSTOMREQUEST] = 'DELETE'; - // build url $url .= '?' . http_build_query($parameters, null); } elseif ($method == 'PUT') { $data = $this->encodeData($parameters); $data = http_build_query($data, null); $data = $this->removeIndexFromArrayParameters($data); - - $options[CURLOPT_POSTFIELDS] = $data; - $options[CURLOPT_CUSTOMREQUEST] = 'PUT'; - } else throw new FactuurException('Unsupported method (' . $method . ')'); + } else throw new DeFactuurException('Unsupported method (' . $method . ')'); // prepend $url = self::API_URL . '/' . self::API_VERSION . '/' . $url; + $request = $this->requestFactory->createRequest($method, $url); - // set options - $this->getCurlOptions($url); - - // init - $this->curl = curl_init(); - - // set options - curl_setopt_array($this->curl, $options); - - // execute - $response = curl_exec($this->curl); - $headers = curl_getinfo($this->curl); - - // fetch errors - $errorNumber = curl_errno($this->curl); - $errorMessage = curl_error($this->curl); - - // check status code - if ($headers['http_code'] >= 400) { - // try to read JSON - $json = @json_decode($response, true); + if ($data !== null) { + $request = $request->withBody($this->streamFactory->createStream($data)); + } - // throw - if ($json !== null && $json !== false) { + try { + $response = $this->client->sendRequest($request); + } catch (ClientExceptionInterface $e) { + throw new DeFactuurException($e->getMessage()); + } - // errors? - if (is_array($json) && array_key_exists('errors', $json)) { - $message = ''; - foreach($json['errors'] as $key => $value) $message .= $key . ': ' . implode(', ', $value) . "\n"; + if ($response->getStatusCode() === 422) { + // Unprocessable entity = validation error on data that was passed + throw new DeFactuurException( + 'Validation error - Unprocessable entity. (' . $response->getStatusCode() . ')', + $response->getStatusCode() + ); + } - throw new FactuurException(trim($message)); - } else { - if(is_array($json) && array_key_exists('message', $json)) $response = $json['message']; - throw new FactuurException($response, $headers['http_code']); + if ($response->getStatusCode() >= 400) { + try { + $json = json_decode($response->getBody()->getContents(), true); + + // throw + if ($json !== null && $json !== false) { + // errors? + if (is_array($json) && array_key_exists('errors', $json)) { + $message = ''; + foreach ($json['errors'] as $key => $value) $message .= $key . ': ' . implode(', ', $value) . "\n"; + + throw new DeFactuurException(trim($message)); + } else { + if (is_array($json) && array_key_exists('message', $json)) $response = $json['message']; + throw new DeFactuurException($response, $response->getStatusCode()); + } } + } catch (\Exception $e) { + throw new DeFactuurException($e->getMessage()); } // unknown error - throw new FactuurException('Invalid response (' . $headers['http_code'] . ')', $headers['http_code']); + throw new DeFactuurException('Invalid response (' . $response->getStatusCode() . ')', $response->getStatusCode()); } - // error? - if($errorNumber != '') throw new FactuurException($errorMessage, $errorNumber); - // return the headers if needed - if($returnHeaders) return $headers; + if($returnHeaders) return $response->getHeaders(); if (stristr($url, '.pdf')) { // Return pdf contents immediately without tampering with them - return $response; + return $response->getBody()->getContents(); } - // we expect JSON so decode it - $json = @json_decode($response, true); + $json = json_decode($response->getBody()->getContents(), true); // validate json - if($json === false) throw new FactuurException('Invalid JSON-response'); + if($json === false) throw new DeFactuurException('Invalid JSON-response'); // decode the response array_walk_recursive($json, array(__CLASS__, 'decodeResponse')); @@ -317,64 +300,44 @@ public function setUserAgent(string $userAgent): void /** * Get an API token * - * @throws FactuurException + * @throws DeFactuurException */ public function accountApiToken(string $username, string $password): string { $url = self::API_URL . '/' . self::API_VERSION . '/account/api_token.json'; - // set options - $options = $this->getCurlOptions($url); - $options[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC; - $options[CURLOPT_USERPWD] = $username . ':' . $password; - - // init - $this->curl = curl_init(); + $request = $this->requestFactory->createRequest('GET', $url); + $request = $request->withAddedHeader( + 'Authorization', + 'Basic ' . base64_encode($username . ':' . $password) + ); - // set options - curl_setopt_array($this->curl, $options); + try { + $response = $this->client->sendRequest($request); - // execute - $response = curl_exec($this->curl); - $headers = curl_getinfo($this->curl); + // check status code + if ($response->getStatusCode() != 200) { + throw new DeFactuurException('Could\'t authenticate you'); + } - // check status code - if ($headers['http_code'] != 200) { - throw new FactuurException('Could\'t authenticate you'); + // we expect JSON so decode it + $json = json_decode($response->getBody()->getContents(), true); + } catch (ClientExceptionInterface $e) { + throw new DeFactuurException($e->getMessage()); } - // we expect JSON so decode it - $json = @json_decode($response, true); - // validate json - if($json === false || !isset($json['api_token'])) throw new FactuurException('Invalid JSON-response'); - - // set the token - $this->setApiToken($json['api_token']); + if($json === false || !isset($json['api_token'])) throw new DeFactuurException('Invalid JSON-response'); // return return $json['api_token']; } - private function getCurlOptions(string $url): array - { - $options[CURLOPT_URL] = $url; - $options[CURLOPT_PORT] = self::API_PORT; - $options[CURLOPT_USERAGENT] = $this->getUserAgent(); - $options[CURLOPT_FOLLOWLOCATION] = true; - $options[CURLOPT_SSL_VERIFYPEER] = false; - $options[CURLOPT_SSL_VERIFYHOST] = false; - $options[CURLOPT_RETURNTRANSFER] = true; - $options[CURLOPT_TIMEOUT] = $this->getTimeOut(); - - return $options; - } - // client methods /** * Get a list of all the clients for the authenticating user. * - * @throws FactuurException + * @throws DeFactuurException */ public function clients(): array { @@ -393,7 +356,7 @@ public function clients(): array * Get all of the available information for a single client. You 'll need the id of the client. * * @return Client|bool - * @throws FactuurException + * @throws DeFactuurException */ public function clientsGet(string $id) { @@ -407,7 +370,7 @@ public function clientsGet(string $id) * Get all clients that are linked to an email address * * @return Client[]|bool - * @throws FactuurException + * @throws DeFactuurException */ public function clientsGetByEmail(string $email) { @@ -427,7 +390,7 @@ function (array $clientData) { /** * Create a new client. * - * @throws FactuurException + * @throws DeFactuurException */ public function clientsCreate(Client $client): Client { @@ -440,7 +403,7 @@ public function clientsCreate(Client $client): Client /** * Update an existing client * - * @throws FactuurException + * @throws DeFactuurException */ public function clientsUpdate(string $id, Client $client): bool { @@ -453,7 +416,7 @@ public function clientsUpdate(string $id, Client $client): bool /** * Check if country is European * - * @throws FactuurException + * @throws DeFactuurException */ public function clientsIsEuropean(string $countryCode): bool { @@ -466,7 +429,7 @@ public function clientsIsEuropean(string $countryCode): bool /** * Delete a client * - * @throws FactuurException + * @throws DeFactuurException */ public function clientsDelete(string $id): bool { @@ -478,7 +441,7 @@ public function clientsDelete(string $id): bool /** * Disable client in favour of another client * - * @throws FactuurException + * @throws DeFactuurException */ public function clientsDisable(string $id, string $replacedById): bool { @@ -569,7 +532,7 @@ public function invoicesGet(string $id) * Get the pdf for an invoice * * @return string|bool Raw PDF contents - * @throws FactuurException + * @throws DeFactuurException */ public function invoicesGetAsPdf(string $id) { @@ -630,7 +593,7 @@ public function invoicesCreateCreditNote(string $id, Invoice $creditNote): Invoi /** * Update an existing invoice * - * @throws FactuurException + * @throws DeFactuurException */ public function invoicesUpdate(string $id, Invoice $invoice): bool { @@ -643,7 +606,7 @@ public function invoicesUpdate(string $id, Invoice $invoice): bool /** * Delete an invoice * - * @throws FactuurException + * @throws DeFactuurException */ public function invoicesDelete(int $id): bool { @@ -656,7 +619,7 @@ public function invoicesDelete(int $id): bool * Sending an invoice by mail. * * @return Mail|bool - * @throws FactuurException + * @throws DeFactuurException */ public function invoiceSendByMail( string $id, @@ -681,7 +644,7 @@ public function invoiceSendByMail( /** * Marking invoice as sent by mail. * - * @throws FactuurException + * @throws DeFactuurException */ public function invoiceMarkAsSentByMail(string $id, string $email): void { @@ -709,7 +672,7 @@ public function invoicesAddPayment(string $id, Payment $payment): Payment * * @param string $id The invoice id * - * @throws FactuurException + * @throws DeFactuurException */ public function invoiceSendReminder(string $id): array { @@ -719,7 +682,7 @@ public function invoiceSendReminder(string $id): array /** * Check if vat is required * - * @throws FactuurException + * @throws DeFactuurException */ public function invoicesVatRequired(string $countryCode, bool $isCompany): bool { @@ -733,7 +696,7 @@ public function invoicesVatRequired(string $countryCode, bool $isCompany): bool /** * Check if valid vat number * - * @throws FactuurException + * @throws DeFactuurException */ public function isValidVat(string $vatNumber): bool { @@ -746,7 +709,7 @@ public function isValidVat(string $vatNumber): bool /** * Upload a CODA file and let DeFactuur interpret it * - * @throws FactuurException + * @throws DeFactuurException */ public function uploadCodaFile(string $filePath): array { @@ -759,7 +722,7 @@ public function uploadCodaFile(string $filePath): array } /** - * @throws FactuurException + * @throws DeFactuurException */ public function products(): array { @@ -777,7 +740,7 @@ public function products(): array /** * @return Product|bool - * @throws FactuurException + * @throws DeFactuurException */ public function productsGet(int $id) { @@ -791,7 +754,7 @@ public function productsGet(int $id) } /** - * @throws FactuurException + * @throws DeFactuurException */ public function productsCreate(Product $product): Product { diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 0000000..592db44 --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,7 @@ +client = $client; + $this->clientId = $client === null ? null : $client->getId(); + $this->items = $items; + + $this->id = null; + $this->iid = null; + $this->state = null; + $this->paymentMethod = null; + $this->description = null; + $this->shownRemark = null; + $this->generated = null; + $this->dueDate = null; + $this->fullyPaidAt = null; + $this->payments = null; + $this->history = null; + $this->total = null; + $this->language = null; + $this->discount = null; + $this->discountDescription = null; + $this->vatException = null; + $this->vatDescription = null; + } + + public function setClient(Client $client): Invoice { $this->client = $client; - $this->setClientId($client->getId()); + $this->clientId = $client->getId(); + + return $this; } public function getClient(): Client @@ -71,9 +101,11 @@ public function getClient(): Client return $this->client; } - public function setClientId(int $clientId): void + public function setClientId(int $clientId): Invoice { $this->clientId = $clientId; + + return $this; } public function getClientId(): int @@ -81,12 +113,14 @@ public function getClientId(): int return $this->clientId; } - public function setDescription(string $description): void + public function setDescription(string $description): Invoice { $this->description = $description; + + return $this; } - public function getDescription(): string + public function getDescription(): ?string { return $this->description; } @@ -96,7 +130,7 @@ private function setDueDate(DateTime $dueDate): void $this->dueDate = $dueDate; } - public function getDueDate(): DateTime + public function getDueDate(): ?DateTime { return $this->dueDate; } @@ -106,7 +140,7 @@ private function setFullyPaidAt(DateTime $fullyPaidAt): void $this->fullyPaidAt = $fullyPaidAt; } - public function getFullyPaidAt(): DateTime + public function getFullyPaidAt(): ?DateTime { return $this->fullyPaidAt; } @@ -116,7 +150,7 @@ private function setGenerated(DateTime $generated): void $this->generated = $generated; } - public function getGenerated(): DateTime + public function getGenerated(): ?DateTime { return $this->generated; } @@ -129,15 +163,17 @@ private function addHistory(History $history): void /** * @param History[] $history */ - public function setHistory(array $history): void + public function setHistory(array $history): Invoice { $this->history = $history; + + return $this; } /** * @return History[] */ - public function getHistory(): array + public function getHistory(): ?array { return $this->history; } @@ -147,7 +183,7 @@ private function setId(int $id): void $this->id = $id; } - public function getId(): int + public function getId(): ?int { return $this->id; } @@ -157,22 +193,26 @@ private function setIid(string $iid): void $this->iid = $iid; } - public function getIid(): string + public function getIid(): ?string { return $this->iid; } - public function addItem(Item $item): void + public function addItem(Item $item): Invoice { $this->items[] = $item; + + return $this; } /** * @param Item[] $items */ - public function setItems(array $items): void + public function setItems(array $items): Invoice { $this->items = $items; + + return $this; } /** @@ -194,46 +234,43 @@ private function addPayment(Payment $payment): void /** * @return Payment[] */ - public function getPayments(): array + public function getPayments(): ?array { return $this->payments; } - public function setShownRemark(string $shownRemark): void + public function setShownRemark(string $shownRemark): Invoice { $this->shownRemark = $shownRemark; + + return $this; } - public function getShownRemark(): string + public function getShownRemark(): ?string { return $this->shownRemark; } - /** - * @param string $state Possible states are: paid, sent, created - * @todo: valueObject? - */ - public function setState(string $state): void + public function setState(State $state): Invoice { $this->state = $state; + + return $this; } - public function getState(): string + public function getState(): ?State { return $this->state; } - /** - * @param string $paymentMethod Possible payment methods are: - * not_paid, cheque, transfer, bankcontact, cash, direct_debit and paid - * @todo: valueObject - */ - public function setPaymentMethod(string $paymentMethod): void + public function setPaymentMethod(string $paymentMethod): Invoice { $this->paymentMethod = $paymentMethod; + + return $this; } - public function getPaymentMethod(): string + public function getPaymentMethod(): ?string { return $this->paymentMethod; } @@ -243,22 +280,24 @@ private function setTotal(float $total): void $this->total = $total; } - public function getTotal(): float + public function getTotal(): ?float { return $this->total; } - public function setLanguage(string $language): void + public function setLanguage(string $language): Invoice { $this->language = $language; + + return $this; } - public function getLanguage(): string + public function getLanguage(): ?string { return $this->language; } - public function getDiscount(): float + public function getDiscount(): ?float { return $this->discount; } @@ -282,7 +321,7 @@ public function setDiscountIsPercentage(bool $discountIsPercentage): Invoice return $this; } - public function getDiscountDescription(): string + public function getDiscountDescription(): ?string { return $this->discountDescription; } @@ -299,7 +338,7 @@ public function prepareForSending(): void $this->prepareForSending = true; } - public function getVatException(): string + public function getVatException(): ?string { return $this->vatException; } @@ -311,7 +350,7 @@ public function setVatException(string $vatException): Invoice return $this; } - public function getVatDescription(): string + public function getVatDescription(): ?string { return $this->vatDescription; } @@ -335,7 +374,7 @@ public static function initializeWithRawData(array $data): Invoice if(isset($data['id'])) $item->setId($data['id']); if(isset($data['client_id'])) $item->setClientId($data['client_id']); if(isset($data['iid'])) $item->setIid($data['iid']); - if(isset($data['state'])) $item->setState($data['state']); + if(isset($data['state'])) $item->setState(new State($data['state'])); if(isset($data['payment_method'])) $item->setPaymentMethod($data['payment_method']); if(isset($data['generated'])) $item->setGenerated(new DateTime('@' . strtotime($data['generated']))); if(isset($data['description'])) $item->setDescription($data['description']); @@ -375,7 +414,7 @@ public function toArray(bool $forApi = false): array { $data = array(); $data['client_id'] = $this->getClientId(); - $data['state'] = $this->getState(); + $data['state'] = $this->getState()->getValue(); $data['payment_method'] = $this->getPaymentMethod(); $data['description'] = $this->getDescription(); $data['shown_remark'] = $this->getShownRemark(); @@ -413,7 +452,7 @@ public function toArray(bool $forApi = false): array foreach ($this->getHistory() as $history) { $data['history'][] = $history->toArray($forApi); } - } else { + } elseif ($this->prepareForSending) { $data['prepare_for_sending'] = $this->prepareForSending; } diff --git a/src/Invoice/Item.php b/src/Invoice/Item.php index e00130f..0467162 100644 --- a/src/Invoice/Item.php +++ b/src/Invoice/Item.php @@ -11,35 +11,59 @@ class Item { protected string $description; - protected string $externalProductId; - protected float $amount; protected float $price; - protected float $totalWithoutVat; + protected ?int $vat; + + protected ?string $externalProductId; - protected float $totalVat; + protected ?float $totalWithoutVat; - protected float $totalWithVat; + protected ?float $totalVat; - protected float $totalVatOverrule; + protected ?float $totalWithVat; - protected ?int $vat; + protected ?float $totalVatOverrule; - protected int $referenceId; + protected ?int $referenceId; - protected float $discount; + protected ?float $discount; protected bool $discountIsPercentage = false; - protected string $discountDescription; + protected ?string $discountDescription; protected ?int $productId; - public function setAmount(float $amount): void + public function __construct( + string $description, + float $amount, + float $price, + ?int $vat = null + ) { + $this->description = $description; + $this->amount = $amount; + $this->price = $price; + $this->vat = $vat; + + $this->externalProductId = null; + $this->totalWithoutVat = null; + $this->totalVat = null; + $this->totalWithVat = null; + $this->totalVatOverrule = null; + $this->referenceId = null; + $this->discount = null; + $this->discountDescription = null; + $this->productId = null; + } + + public function setAmount(float $amount): Item { $this->amount = $amount; + + return $this; } public function getAmount(): float @@ -47,9 +71,11 @@ public function getAmount(): float return $this->amount; } - public function setDescription(string $description): void + public function setDescription(string $description): Item { $this->description = $description; + + return $this; } public function getDescription(): string @@ -57,9 +83,11 @@ public function getDescription(): string return $this->description; } - public function setPrice(float $price): void + public function setPrice(float $price): Item { $this->price = $price; + + return $this; } public function getPrice(): float @@ -72,7 +100,7 @@ private function setReferenceId(int $referenceId): void $this->referenceId = $referenceId; } - public function getReferenceId(): int + public function getReferenceId(): ?int { return $this->referenceId; } @@ -82,7 +110,7 @@ private function setTotalVat(float $totalVat): void $this->totalVat = $totalVat; } - public function getTotalVat(): float + public function getTotalVat(): ?float { return $this->totalVat; } @@ -92,7 +120,7 @@ private function setTotalWithVat(float $totalWithVat): void $this->totalWithVat = $totalWithVat; } - public function getTotalWithVat(): float + public function getTotalWithVat(): ?float { return $this->totalWithVat; } @@ -102,14 +130,16 @@ private function setTotalWithoutVat(float $totalWithoutVat): void $this->totalWithoutVat = $totalWithoutVat; } - public function getTotalWithoutVat(): float + public function getTotalWithoutVat(): ?float { return $this->totalWithoutVat; } - public function setVat(?int $vat = null): void + public function setVat(?int $vat = null): Item { $this->vat = $vat; + + return $this; } public function getVat(): ?int @@ -117,17 +147,19 @@ public function getVat(): ?int return $this->vat; } - public function setTotalVatOverrule(float $vatAmount): void + public function setTotalVatOverrule(float $vatAmount): Item { $this->totalVatOverrule = $vatAmount; + + return $this; } - public function getTotalVatOverrule(): float + public function getTotalVatOverrule(): ?float { return $this->totalVatOverrule; } - public function getDiscount(): float + public function getDiscount(): ?float { return $this->discount; } @@ -151,7 +183,7 @@ public function setDiscountIsPercentage(bool $discountIsPercentage): Item return $this; } - public function getDiscountDescription(): string + public function getDiscountDescription(): ?string { return $this->discountDescription; } @@ -163,19 +195,23 @@ public function setDiscountDescription(string $discountDescription): Item return $this; } - public function getExternalProductId(): string + public function getExternalProductId(): ?string { return $this->externalProductId; } - public function setExternalProductId(string $externalProductId): void + public function setExternalProductId(string $externalProductId): Item { $this->externalProductId = $externalProductId; + + return $this; } - public function setProductId(?int $productId): void + public function setProductId(?int $productId): Item { $this->productId = $productId; + + return $this; } public function getProductId(): ?int @@ -188,7 +224,12 @@ public function getProductId(): ?int */ public static function initializeWithRawData(array $data): Item { - $item = new Item(); + $item = new Item( + $data['description'], + $data['amount'], + $data['price'], + $data['vat'] ?? null + ); if(isset($data['description'])) $item->setDescription($data['description']); if(isset($data['amount'])) $item->setAmount($data['amount']); diff --git a/src/ValueObject/State.php b/src/ValueObject/State.php new file mode 100644 index 0000000..5da8454 --- /dev/null +++ b/src/ValueObject/State.php @@ -0,0 +1,80 @@ +value = $value; + + $this->validate(); + } + + private function validate(): void + { + if (!in_array($this->value, self::ALLOWED_VALUES)) { + throw new InvalidArgumentException($this->value); + } + } + + public function getValue(): string + { + return $this->value; + } + + public function __toString(): string + { + return $this->value; + } + + public static function paid(): State + { + return new self(self::PAID); + } + + public static function created(): State + { + return new self(self::CREATED); + } + + public static function sent(): State + { + return new self(self::SENT); + } + + public static function generated(): State + { + return new self(self::GENERATED); + } + + public function juridicialProceedings(): State + { + return new self(self::JURIDICIAL_PROCEEDING); + } + + public function irrecoverable(): State + { + return new self(self::IRRECOVERABLE); + } +}