diff --git a/README.md b/README.md index fe4e977..933aaca 100755 --- a/README.md +++ b/README.md @@ -30,15 +30,16 @@ The following parameters can be passed to create a contact.

 $contact = array(
-	    		"name" => "CONTACT_NAME",
-	            "tax_id" => "CONTACT_VAT_ID",
-	            "phone" => "CONTACT_PHONE ",
-	            "email" => "CONTACT_EMAIL",
-	            "address" => "CONTACT_ADDRESS",
-	            "town" => "CONTACT_CITY",
-	            "zip_code" => "CONTACT_ZIP_CODE",
-	            "country_code" => "CONTACT_CODE"
-			);
+	"name" => "CONTACT_NAME",
+	"tax_id" => "CONTACT_VAT_ID",
+	"phone" => "CONTACT_PHONE ",
+	"email" => "CONTACT_EMAIL",
+	"address" => "CONTACT_ADDRESS",
+	"town" => "CONTACT_CITY",
+	"zip_code" => "CONTACT_ZIP_CODE",
+	"country_code" => "CONTACT_CODE",
+	"bank_account_number" => "IBAN"
+);
 
Pass the connection class to the contact class, then call "create_contact", with the array above. The contact will either be created or loaded if they already exist. @@ -58,15 +59,15 @@ The following parameters can be passed to create an invoice.

 $order = array(
-	    		"payment_method" => "PAYMENT_METHOD",
-	            "issue_date" => "YYYY-mm-dd",
-	            "items" => array(
-				            	"product" => "PRODUCT_NAME",
-				            	"cost" => "PRODUCT_PRICE",
-				            	"quantity" => "PRODUCT_QUANTITY",
-				            	"vat_per" => "VAT_PERCENTAGE"
-				            );
-	            );
+	"payment_method" => "PAYMENT_METHOD",
+	"issue_date" => "YYYY-mm-dd",
+	"items" => array(
+		"product" => "PRODUCT_NAME",
+		"cost" => "PRODUCT_PRICE",
+		"quantity" => "PRODUCT_QUANTITY",
+		"vat_per" => "VAT_PERCENTAGE"
+	);
+);
 
Pass the connection class to the invoice class: @@ -100,15 +101,15 @@ The following parameters can be passed to create a refund.

 $order = array(
-	    		"invoice_id" => "QUIPU_INVOICE_ID",
-	            "refund_date" => "YYYY-mm-dd",
-	            "items" => array(
-				            	"product" => "PRODUCT_NAME",
-				            	"cost" => "PRODUCT_PRICE",
-				            	"quantity" => "PRODUCT_QUANTITY",
-				            	"vat_per" => "VAT_PERCENTAGE"
-				            );
-	            );
+	"invoice_id" => "QUIPU_INVOICE_ID",
+	"refund_date" => "YYYY-mm-dd",
+	"items" => array(
+		"product" => "PRODUCT_NAME",
+		"cost" => "PRODUCT_PRICE",
+		"quantity" => "PRODUCT_QUANTITY",
+		"vat_per" => "VAT_PERCENTAGE"
+	);
+);
 
Pass the connection class to the invoice class: @@ -126,4 +127,4 @@ Call the 'refund_invoice' function to refund an invoice ### Changelog #### 1.0 -* First public release \ No newline at end of file +* First public release diff --git a/quipu-api/class-quipu-api-connection.php b/quipu-api/class-quipu-api-connection.php index 75aad8c..1098fd0 100644 --- a/quipu-api/class-quipu-api-connection.php +++ b/quipu-api/class-quipu-api-connection.php @@ -1,312 +1,398 @@ is_key_match($api_key, $api_secret)) ) { - self::$_instance = new self($api_key, $api_secret); - } - - return self::$_instance; - } - - /** - * Check is the passed key and secret are the same as the saved ones i.e. same connect. - * - * @param string $api_key, $api_secret - */ - private function is_key_match( $api_key, $api_secret ) { - if( ($this->api_key == $api_key) && ($this->api_secret == $api_secret) ) { - return true; - } else { - return false; - } - } - - /** - * Quipu_Api constructor. - * - * @param string $api_key, $api_secret - */ - private function __construct( $api_key, $api_secret ) { - $this->api_key = $api_key; - $this->api_secret = $api_secret; - } - - // Magic method clone is empty to prevent duplication of connection - private function __clone() { } - - // Stopping unserialize of object - private function __wakeup() { } - - /** - * @return string - */ - protected function get_access_token() { - if( $this->is_access_token_empty() || $this->is_token_expired() ) { - if($this->request_access_token() === false) { - return false; - } - } - - return $this->access_token; - } - - /** - * @param string $access_token - */ - protected function set_access_token( $access_token ) { - $this->access_token = $access_token; - } - - /** - * @return bool - */ - protected function is_access_token_empty() { - return empty($this->access_token); - } - - /** - * Get response - * - * @return array - */ - public function get_response() { - return $this->response; - } - - /** - * Clear the response - * - * @return bool - */ - private function clear_response() { - $this->response = null; - - return true; - } - - /** - * Check if key files exist - * - * @return bool - */ - private function do_keys_exist() { - - // Check keys - if ( empty($this->api_key) || empty($this->api_secret) ) { - $this->error_msg = 'API key or secret NOT set.'; - return false; - } - - return true; - } - - /** - * Get the signed URL. - * The signed URL is fetched by doing an OAuth request. - * - * @throws Exception - * - * @return String - */ - private function is_token_expired() { - if( $this->token_expires < time() ) { - return true; - } else { - return false; - } - } - - /** - * Get the signed URL. - * The signed URL is fetched by doing an OAuth request. - * - * @throws Exception - * - * @return String - */ - private function request_access_token() { - $curl = curl_init( self::API_URL.self::AUTH_URL ); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_USERPWD, $this->api_key . ":" . $this->api_secret); - curl_setopt($curl, CURLOPT_HEADER,'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'); - curl_setopt($curl, CURLOPT_POSTFIELDS, array( - 'grant_type' => 'client_credentials', - 'scope' => 'ecommerce' - ) ); - - $auth = curl_exec( $curl ); - $secret = json_decode($auth); // NOTE: json_decode returns an object here unlike in requests - curl_close($curl); - - if(isset($secret->error)) { - $this->error_msg = $secret->error; - return false; - } else { - // Set token expires time to check if it has expired before making an API call - $this->token_expires = time() + $secret->expires_in; - $this->access_token = $secret->access_token; - return true; - } - } - - private function init_request($url) { - // Check if required settings are set - if ( false === $this->do_keys_exist() ) { - return false; - } - - // Get access token to make API call - $access_token = $this->get_access_token(); - if( $access_token === false ) { - return false; - } - - $this->curl = curl_init( $url ); - curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer ' . $access_token, 'Accept: application/vnd.quipu.v1+json', 'Content-Type: application/vnd.quipu.v1+json' ) ); - - return true; - } - - private function finish_request() { - $response = curl_exec( $this->curl ); - curl_close($this->curl); - - if($response) { - $req_json = json_decode($response, true); - - if(isset($req_json['errors'])) { - $this->error_msg = $req_json['errors'][0]['detail']." => ".$req_json['errors'][0]['source']['pointer']; - return false; - } else { - return $req_json; - } - - } else { - $this->error_msg = 'Empty Response'; - return false; - } - } - - /** - * Do the request - * - * @throws Exception - * @param string $response_type - * @param API endpoint and post data - * - * @return bool - */ - public function post_request($endpoint, $post_data) { - - if($this->init_request(self::API_URL.$endpoint) === false ) { - throw new Exception($this->error_msg); - } - - curl_setopt($this->curl, CURLOPT_POST, true); - curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($post_data) ); - - /* - case "PUT": - curl_setopt($ch, CURLOPT_PUT, true); - curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($attr) ); - break; - case "DELETE": - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); - break; - */ - - $res = $this->finish_request(); - if(!$res) { - throw new Exception("POST: ".$endpoint." - Error: ".$this->error_msg." - Args: ".print_r($post_data,true)); - } - - return $res; - } - - /** - * Do the request - * - * @throws Exception - * @param string $response_type - * @param API endpoint and post data - * - * @return bool - */ - public function get_request($endpoint) { - - if($this->init_request(self::API_URL.$endpoint) === false ) { - throw new Exception($this->error_msg); - } - - $res = $this->finish_request(); - if(!$res) { - throw new Exception("GET: ".$endpoint." - Error: ".$this->error_msg); - } - - return $res; - } +if (!defined('ABSPATH')) { + exit; +} + +/** + * Class Quipu_Api_Connection + * Singleton API connection class + */ +class Quipu_Api_Connection +{ + /** + * @var String API URL + */ + const API_URL = 'https://getquipu.com/'; + /** + * @var String API URL + */ + const AUTH_URL = 'oauth/token'; + /** + * @var Quipu_Api_Connection + */ + private static $_instance; + /** + * @var string + */ + private $api_key; + /** + * @var string + */ + private $api_secret; + /** + * @var string + */ + private $access_token; + /** + * @var resource + */ + private $curl; + /** + * @var time + */ + private $token_expires = 0; + /** + * The single instance + * + * @var string + */ + private $error_msg; + + /** + * Quipu_Api constructor. + * + * @param string $api_key , $api_secret + */ + private function __construct($api_key, $api_secret) + { + $this->api_key = $api_key; + $this->api_secret = $api_secret; + } + + public static function get_instance($api_key, $api_secret) + { + // If no instance then make one, else if the API key and secret are not the same i.e. new account/connection + if ((!self::$_instance)) { + self::$_instance = new self($api_key, $api_secret); + } elseif (!(self::$_instance->is_key_match($api_key, $api_secret))) { + self::$_instance = new self($api_key, $api_secret); + } + + return self::$_instance; + } + + /** + * Check is the passed key and secret are the same as the saved ones i.e. same connect. + * + * @param string $api_key , $api_secret + */ + private function is_key_match($api_key, $api_secret) + { + if (($this->api_key == $api_key) && ($this->api_secret == $api_secret)) { + return true; + } else { + return false; + } + } + + /** + * Get response + * + * @return array + */ + public function get_response() + { + return $this->response; + } + + /** + * Do the request + * + * @throws Exception + * + * @param string $response_type + * @param API endpoint and post data + * + * @return bool + */ + public function post_request($endpoint, $post_data) + { + + if ($this->init_request(self::API_URL.$endpoint) === false) { + throw new Exception($this->error_msg); + } + + curl_setopt($this->curl, CURLOPT_POST, true); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($post_data)); + + $res = $this->finish_request(); + if (!$res) { + throw new Exception("POST: ".$endpoint." - Error: ".$this->error_msg." - Args: ".print_r($post_data, true)); + } + + return $res; + } + + private function init_request($url) + { + // Check if required settings are set + if (false === $this->do_keys_exist()) { + return false; + } + + // Get access token to make API call + $access_token = $this->get_access_token(); + if ($access_token === false) { + return false; + } + + $this->curl = curl_init($url); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt( + $this->curl, + CURLOPT_HTTPHEADER, + [ + 'Authorization: Bearer '.$access_token, + 'Accept: application/vnd.quipu.v1+json', + 'Content-Type: application/vnd.quipu.v1+json', + ] + ); + + return true; + } + + /** + * Check if key files exist + * + * @return bool + */ + private function do_keys_exist() + { + // Check keys + if (empty($this->api_key) || empty($this->api_secret)) { + $this->error_msg = 'API key or secret NOT set.'; + + return false; + } + + return true; + } + + /** + * @return string + */ + protected function get_access_token() + { + if ($this->is_access_token_empty() || $this->is_token_expired()) { + if ($this->request_access_token() === false) { + return false; + } + } + + return $this->access_token; + } + + /** + * @param string $access_token + */ + protected function set_access_token($access_token) + { + $this->access_token = $access_token; + } + + /** + * @return bool + */ + protected function is_access_token_empty() + { + return empty($this->access_token); + } + + /** + * Get the signed URL. + * The signed URL is fetched by doing an OAuth request. + * + * @throws Exception + * + * @return String + */ + private function is_token_expired() + { + if ($this->token_expires < time()) { + return true; + } else { + return false; + } + } + + /** + * Get the signed URL. + * The signed URL is fetched by doing an OAuth request. + * + * @throws Exception + * + * @return String + */ + private function request_access_token() + { + $curl = curl_init(self::API_URL.self::AUTH_URL); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_USERPWD, $this->api_key.":".$this->api_secret); + curl_setopt($curl, CURLOPT_HEADER, 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'); + curl_setopt( + $curl, + CURLOPT_POSTFIELDS, + [ + 'grant_type' => 'client_credentials', + 'scope' => 'ecommerce', + ] + ); + + $auth = curl_exec($curl); + $secret = json_decode($auth); // NOTE: json_decode returns an object here unlike in requests + curl_close($curl); + + if (isset($secret->error)) { + $this->error_msg = $secret->error; + + return false; + } else { + // Set token expires time to check if it has expired before making an API call + $this->token_expires = time() + $secret->expires_in; + $this->access_token = $secret->access_token; + + return true; + } + } + + private function finish_request() + { + $response = curl_exec($this->curl); + curl_close($this->curl); + + if ($response) { + $req_json = json_decode($response, true); + + if (isset($req_json['errors'])) { + $this->error_msg = $req_json['errors'][0]['detail']." => ".$req_json['errors'][0]['source']['pointer']; + + return false; + } else { + return $req_json; + } + + } else { + $this->error_msg = 'Empty Response'; + + return false; + } + } + + /** + * Do the request + * + * @throws Exception + * + * @param string $response_type + * @param API endpoint and post data + * + * @return bool + */ + public function get_request($endpoint) + { + + if ($this->init_request(self::API_URL.$endpoint) === false) { + throw new Exception($this->error_msg); + } + + $res = $this->finish_request(); + if (!$res) { + throw new Exception("GET: ".$endpoint." - Error: ".$this->error_msg); + } + + return $res; + } + + /** + * Do the request + * + * @throws Exception + * + * @param string $response_type + * @param API endpoint and post data + * + * @return bool + */ + public function put_request($endpoint, $post_data) + { + if ($this->init_request(self::API_URL.$endpoint) === false) { + throw new Exception($this->error_msg); + } + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PATCH'); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($post_data)); + $res = $this->finish_request(); + if (!$res) { + throw new Exception("PUT: ".$endpoint." - Error: ".$this->error_msg." - Args: ".print_r($post_data, true)); + } + + return $res; + } + /** + * Do the request to get the invoice pdf + * + * @throws Exception + * @param string API endpoint and post data + * + * @return bool/string + */ + public function get_pdf($endpoint) + { + + // Check if required settings are set + if (false === $this->do_keys_exist()) { + return false; + } + + // Get access token to make API call + $access_token = $this->get_access_token(); + if ($access_token === false) { + return false; + } + + $this->curl = curl_init($endpoint); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt( + $this->curl, + CURLOPT_HTTPHEADER, + [ + 'Authorization: Bearer '.$access_token, + 'Accept: application/pdf', + 'Content-Type: application/pdf', + ] + ); + + $response = curl_exec($this->curl); + curl_close($this->curl); + + return $response; + } + + /** + * Magic method clone is empty to prevent duplication of connection + */ + private function __clone() + { + } + + /** + * Stopping unserialize of object + */ + private function __wakeup() + { + } + + /** + * Clear the response + * + * @return bool + */ + private function clear_response() + { + $this->response = null; + + return true; + } } diff --git a/quipu-api/class-quipu-api-contact.php b/quipu-api/class-quipu-api-contact.php index a318885..b2b872a 100644 --- a/quipu-api/class-quipu-api-contact.php +++ b/quipu-api/class-quipu-api-contact.php @@ -1,77 +1,157 @@ get_contact($contact['tax_id']); + + if (empty($this->id)) { + $this->__create_contact($contact); + } elseif (true === $update) { + $this->__update_contact($contact); + } + } else { + $this->__create_contact($contact); + } + } catch (Exception $e) { + throw $e; + } + } + + public function get_contact($tax_id) + { + if (empty($tax_id)) { + throw new Exception('Get: no tax id passed.'); + } + $this->set_endpoint('contacts'); + + return $this->get_filter_request("?filter[tax_id]=$tax_id"); + } + + private function __create_contact($contact) + { + $this->set_endpoint('contacts'); + // Check if contact name is empty spaces + $trim_contact = trim($contact['name']); + if (empty($trim_contact)) { + throw new Exception('Create: no contact name passed.'); + } + + $contact = $this->validateContactData($contact); + + try { + $postData = [ + "data" => [ + "type" => "contacts", + "attributes" => [ + "name" => "$contact[name]", + "tax_id" => "$contact[tax_id]", + "phone" => "$contact[phone]", + "email" => "$contact[email]", + "address" => "$contact[address]", + "town" => "$contact[town]", + "zip_code" => "$contact[zip_code]", + "country_code" => "$contact[country_code]", + "supplier_number" => null, + "is_supplier_of_direct_goods" => (boolean)$contact['is_supplier_of_direct_goods'], + "bank_account_number" => "$contact[bank_account_number]", + "bank_account_swift_bic" => "$contact[bank_account_swift_bic]", + "sepa_signature_date" => "$contact[sepa_signature_date]", + ], + ], + ]; + + $this->create_request($postData); + } catch (Exception $e) { + throw $e; + } + + } + + /** + * @param $contact + * + * @return mixed + */ + private function validateContactData($contact) + { + $contact['country_code'] = strtolower($contact['country_code']); + $contact['is_supplier_of_direct_goods'] = $contact['is_supplier_of_direct_goods'] ? true : false; + + return $contact; + } -class Quipu_Api_Contact extends Quipu_Api { - - public function __construct( Quipu_Api_Connection $api_connection ) { - parent::__construct( $api_connection ); - - // Set Endpoint - $this->set_endpoint( 'contacts' ); - } - - private function __create_contact($contact) { - - // Check if contact name is empty spaces - $trim_contact = trim($contact['name']); - if( empty( $trim_contact ) ){ - throw new Exception('Create: no contact name passed.'); - } - - $contact['country_code'] = strtolower($contact['country_code']); - - try { - $postData = array( - "data" => array( - "type" => "contacts", - "attributes" => array( - "name" => "$contact[name]", - "tax_id" => "$contact[tax_id]", - "phone" => "$contact[phone]", - "email" => "$contact[email]", - "address" => "$contact[address]", - "town" => "$contact[town]", - "zip_code" => "$contact[zip_code]", - "country_code" => "$contact[country_code]" - ) - ) - ); - - $this->create_request($postData); - } catch (Exception $e) { - throw $e; - } - - } - - public function create_contact($contact) { - try { - if($contact['tax_id']) { - $this->get_contact($contact['tax_id']); - - if(empty($this->id)) { - $this->__create_contact($contact); - } - } else { - $this->__create_contact($contact); - } - } catch (Exception $e) { - throw $e; - } - } - - public function get_contact($tax_id) { - if(empty($tax_id)) { - throw new Exception('Get: no tax id passed.'); - } - return $this->get_filter_request("?filter[tax_id]=$tax_id"); - } + private function __update_contact($contact) + { + $this->set_endpoint('contacts/'.$this->id); + $contact = $this->validateContactData($contact); + try { + $postData = [ + "data" => [ + "type" => "contacts", + "attributes" => [ + ], + ], + ]; + $attributes = []; + if ($contact['name']) { + $attributes["name"] = "$contact[name]"; + } + if ($contact['tax_id']) { + $attributes["tax_id"] = "$contact[tax_id]"; + } + if ($contact['phone']) { + $attributes["phone"] = "$contact[phone]"; + } + if ($contact['email']) { + $attributes["email"] = "$contact[email]"; + } + if ($contact['address']) { + $attributes["address"] = "$contact[address]"; + } + if ($contact['town']) { + $attributes["town"] = "$contact[town]"; + } + if ($contact['zip_code']) { + $attributes["zip_code"] = "$contact[zip_code]"; + } + if ($contact['country_code']) { + $attributes["country_code"] = "$contact[country_code]"; + } + if ($contact['supplier_number']) { + $attributes["supplier_number"] = "$contact[supplier_number]"; + } + if ($contact['is_supplier_of_direct_goods']) { + $attributes["is_supplier_of_direct_goods"] = (boolean)$contact['is_supplier_of_direct_goods']; + } + if ($contact['bank_account_number']) { + $attributes["bank_account_number"] = "$contact[bank_account_number]"; + } + if ($contact['bank_account_swift_bic']) { + $attributes["bank_account_swift_bic"] = "$contact[bank_account_swift_bic]"; + } + if ($contact['sepa_signature_date']) { + $attributes["sepa_signature_date"] = "$contact[sepa_signature_date]"; + } + $postData['data']['attributes'] = $attributes; + $this->update_request($postData); + } catch (Exception $e) { + throw $e; + } + } } diff --git a/quipu-api/class-quipu-api-invoice.php b/quipu-api/class-quipu-api-invoice.php index b9774d5..bc09225 100644 --- a/quipu-api/class-quipu-api-invoice.php +++ b/quipu-api/class-quipu-api-invoice.php @@ -1,12 +1,13 @@ set_endpoint( 'invoices' ); - } - - public function set_contact(Quipu_Api_Contact $contact) { - $this->contact = $contact; - } - - public function set_numeration(Quipu_Api_Numeration $num_series) { - $this->num_series = $num_series; - } - - public function create_invoice($order) { - $contact_id = $this->contact->get_id(); - $num_series_id = $this->num_series->get_id(); - - if(empty($contact_id)){ - throw new Exception('Create: no contact id set.'); - } - - if(empty($order['issue_date'])){ - throw new Exception('Create: no invoice issue date passed.'); - } - - if(empty($order['items'])){ - throw new Exception('Create: no invoice items passed.'); - } - - $postData = array( - "data" => array( - "type" => "invoices", - "attributes" => array( - "kind" => "income", - "issue_date" => "$order[issue_date]", - "paid_at" => "$order[issue_date]", - "payment_method" => "$order[payment_method]" - ), - "relationships" => array( - "contact" => array( - "data" => array( - "id" => "$contact_id", - "type" => "contacts" - ) - ) - ) - ) - ); - - if(!empty($num_series_id)){ - $postData["data"]["relationships"]["numeration"]["data"]["id"] = "$num_series_id"; - $postData["data"]["relationships"]["numeration"]["data"]["type"] = "numbering_series"; - } - - foreach ($order['items'] as $value) { - $item = array( - "type" => "book_entry_items", - "attributes" => array( - "concept" => "$value[product]", - "unitary_amount" => "$value[cost]", - "quantity" => "$value[quantity]", - "vat_percent" => "$value[vat_per]", - "retention_percent" => "0" - ) - ); - - $postData["data"]["relationships"]["items"]["data"][] = $item; - } - - try { - $this->create_request($postData); - } catch (Exception $e) { - throw $e; - } - - } - - public function refund_invoice($refund) { - $num_series_id = $this->num_series->get_id(); - - if(empty($refund['invoice_id'])){ - throw new Exception('Refund: no invoice id passed.'); - } - - if(empty($refund['refund_date'])){ - throw new Exception('Refund: no invoice issue date passed.'); - } - - $postData = array( - "data" => array( - "type" => "invoices", - "attributes" => array( - "paid_at" => "$refund[refund_date]" - ), - "relationships" => array( - "amended_invoice" => array( - "data" => array( - "id" => "$refund[invoice_id]", - "type" => "invoices" - ) - ) - ) - ) - ); - - if(!empty($num_series_id)){ - $postData["data"]["relationships"]["numeration"]["data"]["id"] = "$num_series_id"; - $postData["data"]["relationships"]["numeration"]["data"]["type"] = "numbering_series"; - } - - if(isset($refund['items'])) { - foreach ($refund['items'] as $value) { - $item = array( - "type" => "book_entry_items", - "attributes" => array( - "concept" => "$value[product]", - "unitary_amount" => "$value[cost]", - "quantity" => "$value[quantity]", - "vat_percent" => "$value[vat_per]", - ) - ); - - $postData["data"]["relationships"]["items"]["data"][] = $item; - } - } - - try { - $this->create_request($postData); - } catch (Exception $e) { - throw $e; - } - } +class Quipu_Api_Invoice extends Quipu_Api +{ + + /** + * @var Quipu_Api_Contact + */ + private $contact; + + /** + * @var Quipu_Api_Numeration + */ + private $num_series; + + public function __construct(Quipu_Api_Connection $api_connection) + { + parent::__construct($api_connection); + + // Set Endpoint + $this->set_endpoint('invoices'); + } + + public function set_contact(Quipu_Api_Contact $contact) + { + $this->contact = $contact; + } + + public function set_numeration(Quipu_Api_Numeration $num_series) + { + $this->num_series = $num_series; + } + + public function create_invoice($order) + { + $contact_id = $this->contact->get_id(); + $num_series_id = $this->num_series->get_id(); + + if (empty($contact_id)) { + throw new Exception('Create: no contact id set.'); + } + + if (empty($order['issue_date'])) { + throw new Exception('Create: no invoice issue date passed.'); + } + + if (empty($order['items'])) { + throw new Exception('Create: no invoice items passed.'); + } + + $postData = [ + "data" => [ + "type" => "invoices", + "attributes" => [ + "kind" => "income", + "issue_date" => $order['issue_date'], + "paid_at" => $order['paid_at'], + "due_date" => $order['due_date'], + "payment_method" => $order['payment_method'], + ], + "relationships" => [ + "contact" => [ + "data" => [ + "id" => "$contact_id", + "type" => "contacts", + ], + ], + ], + ], + ]; + + if (!empty($num_series_id)) { + $postData["data"]["relationships"]["numeration"]["data"]["id"] = "$num_series_id"; + $postData["data"]["relationships"]["numeration"]["data"]["type"] = "numbering_series"; + } + + foreach ($order['items'] as $value) { + $item = [ + "type" => "book_entry_items", + "attributes" => [ + "concept" => $value['product'], + "unitary_amount" => $value['cost'], + "quantity" => $value['quantity'], + "vat_percent" => $value['vat_per'], + "retention_percent" => "0", + ], + ]; + + $postData["data"]["relationships"]["items"]["data"][] = $item; + } + + try { + $this->create_request($postData); + } catch (Exception $e) { + throw $e; + } + + } + + public function refund_invoice($refund) + { + $num_series_id = $this->num_series->get_id(); + + if (empty($refund['invoice_id'])) { + throw new Exception('Refund: no invoice id passed.'); + } + + if (empty($refund['refund_date'])) { + throw new Exception('Refund: no invoice issue date passed.'); + } + + $postData = [ + "data" => [ + "type" => "invoices", + "attributes" => [ + "paid_at" => $refund['refund_date'], + ], + "relationships" => [ + "amended_invoice" => [ + "data" => [ + "id" => $refund['invoice_id'], + "type" => "invoices", + ], + ], + ], + ], + ]; + + if (!empty($num_series_id)) { + $postData["data"]["relationships"]["numeration"]["data"]["id"] = "$num_series_id"; + $postData["data"]["relationships"]["numeration"]["data"]["type"] = "numbering_series"; + } + + if (isset($refund['items'])) { + foreach ($refund['items'] as $value) { + $item = [ + "type" => "book_entry_items", + "attributes" => [ + "concept" => "$value[product]", + "unitary_amount" => "$value[cost]", + "quantity" => "$value[quantity]", + "vat_percent" => "$value[vat_per]", + ], + ]; + + $postData["data"]["relationships"]["items"]["data"][] = $item; + } + } + + try { + $this->create_request($postData); + } catch (Exception $e) { + throw $e; + } + } } diff --git a/quipu-api/class-quipu-api.php b/quipu-api/class-quipu-api.php index 94e2336..9a768e9 100644 --- a/quipu-api/class-quipu-api.php +++ b/quipu-api/class-quipu-api.php @@ -1,155 +1,173 @@ api_connection = $api_connection; - } - - /** - * Method to set id - * - * @param $id - */ - public function set_id( $id ) { - $this->id = $id; - } - - /** - * Get the id - * - * @return $id - */ - public function get_id() { - return $this->id; - } - - /** - * Method to set endpoint - * - * @param $endpoint - */ - protected function set_endpoint( $endpoint ) { - $this->endpoint = $endpoint; - } - - /** - * Get the endpoint - * - * @return String - */ - protected function get_endpoint() { - return $this->endpoint; - } - - /** - * @return string - */ - protected function get_query() { - return $this->query; - } - - - /** - * @param string $query - */ - protected function set_query( $query ) { - $this->query = $query; - } - - /** - * Get response - * - * @return array - */ - public function get_response() { - return $this->response; - } - - /** - * Clear the response - * - * @return bool - */ - private function clear_response() { - $this->response = null; - - return true; - } - - public function create_request($post_data) { - try { - $this->response = $this->api_connection->post_request($this->endpoint, $post_data); - - if(isset($this->response['data']['id'])) { - $this->set_id($this->response['data']['id']); - } - } catch (Exception $e) { - throw $e; - } - } - - public function get_request() { - try { - $this->response = $this->api_connection->get_request($this->endpoint); - } catch (Exception $e) { - throw $e; - } - } - - public function get_filter_request($query_string) { - try { - $this->response = $this->api_connection->get_request($this->endpoint.$query_string); - - if(isset($this->response['data'][0]['id'])) { - $this->set_id($this->response['data'][0]['id']); - } - } catch (Exception $e) { - throw $e; - } - } - +include_once('class-quipu-api-connection.php'); + +abstract class Quipu_Api +{ + + /** + * The request response + * + * @var array + */ + protected $response = null; + /** + * @var Integrater + */ + protected $id = ''; + /** + * The request endpoint + * + * @var String + */ + private $endpoint = ''; + /** + * The query string + * + * @var string + */ + private $query = []; + /** + * @var Quipu_Api_Connection + */ + private $api_connection; + + /** + * Quipu_Api constructor. + * + * @param string $api_key , $api_secret + */ + public function __construct(Quipu_Api_Connection $api_connection) + { + $this->api_connection = $api_connection; + } + + /** + * Get the id + * + * @return $id + */ + public function get_id() + { + return $this->id; + } + + /** + * Method to set id + * + * @param $id + */ + public function set_id($id) + { + $this->id = $id; + } + + /** + * Get response + * + * @return array + */ + public function get_response() + { + return $this->response; + } + + public function create_request($post_data) + { + try { + $this->response = $this->api_connection->post_request($this->endpoint, $post_data); + + if (isset($this->response['data']['id'])) { + $this->set_id($this->response['data']['id']); + } + } catch (Exception $e) { + throw $e; + } + } + + public function update_request($post_data) + { + try { + $this->response = $this->api_connection->put_request($this->endpoint, $post_data); + + if (isset($this->response['data']['id'])) { + $this->set_id($this->response['data']['id']); + } + } catch (Exception $e) { + throw $e; + } + } + + public function get_request() + { + try { + $this->response = $this->api_connection->get_request($this->endpoint); + } catch (Exception $e) { + throw $e; + } + } + + public function get_filter_request($query_string) + { + try { + $this->response = $this->api_connection->get_request($this->endpoint.$query_string); + + if (isset($this->response['data'][0]['id'])) { + $this->set_id($this->response['data'][0]['id']); + } + } catch (Exception $e) { + throw $e; + } + } + + /** + * Get the endpoint + * + * @return String + */ + protected function get_endpoint() + { + return $this->endpoint; + } + + /** + * Method to set endpoint + * + * @param $endpoint + */ + protected function set_endpoint($endpoint) + { + $this->endpoint = $endpoint; + } + + /** + * @return string + */ + protected function get_query() + { + return $this->query; + } + + /** + * @param string $query + */ + protected function set_query($query) + { + $this->query = $query; + } + + /** + * Clear the response + * + * @return bool + */ + private function clear_response() + { + $this->response = null; + + return true; + } }