Changeset 1861538
- Timestamp:
- 04/20/2018 04:50:52 AM (8 years ago)
- Location:
- smartaccounts/trunk
- Files:
-
- 6 edited
-
SmartAccountsApi.php (modified) (1 diff)
-
SmartAccountsArticle.php (modified) (1 diff)
-
SmartAccountsClient.php (modified) (1 diff)
-
SmartAccountsPayment.php (modified) (1 diff)
-
SmartAccountsSalesInvoice.php (modified) (1 diff)
-
smartaccounts.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
smartaccounts/trunk/SmartAccountsApi.php
r1786015 r1861538 1 1 <?php 2 2 3 if ( ! defined( 'ABSPATH' )) {4 exit;3 if ( ! defined('ABSPATH')) { 4 exit; 5 5 } // Exit if accessed directly 6 6 7 class SmartAccountsApi { 7 class SmartAccountsApi 8 { 8 9 9 public function sendRequest( $body, $apiUrl, $extraParams = null ) { 10 if ( $body == null ) { 11 $body = new stdClass(); 12 } 13 $now = new DateTime(); 14 $now->setTimezone( new DateTimeZone( 'Europe/Tallinn' ) ); 15 $pk = get_option( "sa_api_pk" ); 16 $sk = get_option( "sa_api_sk" ); 10 public function sendRequest($body, $apiUrl, $extraParams = null) 11 { 12 if ($body == null) { 13 $body = new stdClass(); 14 } 15 $now = new DateTime(); 16 $now->setTimezone(new DateTimeZone('Europe/Tallinn')); 17 $pk = get_option("sa_api_pk"); 18 $sk = get_option("sa_api_sk"); 17 19 18 $bodyJson = json_encode( $body);19 $ts = $now->format( "dmYHis");20 $urlParams = "apikey=$pk×tamp=$ts";21 $urlParams = $extraParams == null ? $urlParams : $urlParams . "&$extraParams";20 $bodyJson = json_encode($body); 21 $ts = $now->format("dmYHis"); 22 $urlParams = "apikey=$pk×tamp=$ts"; 23 $urlParams = $extraParams == null ? $urlParams : $urlParams . "&$extraParams"; 22 24 23 $sig = hash_hmac( 'sha256', $urlParams . $bodyJson, $sk);24 $url = "https://sa.smartaccounts.eu/api/$apiUrl?$urlParams&signature=$sig";25 $sig = hash_hmac('sha256', $urlParams . $bodyJson, $sk); 26 $url = "https://sa.smartaccounts.eu/api/$apiUrl?$urlParams&signature=$sig"; 25 27 26 $args = array(27 'body' => $bodyJson,28 'headers' => [ 'Content-Type' => 'application/json']29 );28 $args = array( 29 'body' => $bodyJson, 30 'headers' => ['Content-Type' => 'application/json'] 31 ); 30 32 31 $response = wp_remote_post( $url, $args);32 $response_code = wp_remote_retrieve_response_code( $response);33 $saResponse = wp_remote_retrieve_body( $response);34 $decodedResponse = json_decode( $saResponse, true);33 $response = wp_remote_post($url, $args); 34 $response_code = wp_remote_retrieve_response_code($response); 35 $saResponse = wp_remote_retrieve_body($response); 36 $decodedResponse = json_decode($saResponse, true); 35 37 36 if ( ! in_array( $response_code, array( 200, 201 ) ) || is_wp_error( $saResponse )) {37 throw new Exception( "SmartAccounts call failed: $response_code" . print_r( $response, true ));38 }38 if ( ! in_array($response_code, array(200, 201)) || is_wp_error($saResponse)) { 39 throw new Exception("SmartAccounts call failed: $response_code" . print_r($response, true)); 40 } 39 41 40 return $decodedResponse;41 }42 return $decodedResponse; 43 } 42 44 } -
smartaccounts/trunk/SmartAccountsArticle.php
r1796659 r1861538 1 1 <?php 2 2 3 if ( ! defined( 'ABSPATH' )) {4 exit;3 if ( ! defined('ABSPATH')) { 4 exit; 5 5 } // Exit if accessed directly 6 6 7 class SmartAccountsArticle { 7 class SmartAccountsArticle 8 { 8 9 9 public function __construct() { 10 $this->api = new SmartAccountsApi(); 11 } 10 public function __construct() 11 { 12 $this->api = new SmartAccountsApi(); 13 } 12 14 13 public function ensureAllArticlesExist( $rows ) { 14 $getApiUrl = "purchasesales/articles:get"; 15 $addApiUrl = "purchasesales/articles:add"; 16 foreach ( $rows as $row ) { 17 $body = new stdClass(); 18 $articles = $this->api->sendRequest( $body, $getApiUrl, "code=$row->code" ); 19 if ( ! ( array_key_exists( "articles", $articles ) && count( $articles["articles"] == 1 ) ) ) { 20 $body = new stdClass(); 21 $body->code = $row->code; 22 $body->description = $row->description; 23 $body->type = $row->code == get_option( 'sa_api_shipping_code' ) ? "SERVICE" : "PRODUCT"; 24 $body->activeSales = true; 25 $this->api->sendRequest( $body, $addApiUrl ); 26 } 27 } 28 } 15 public function ensureAllArticlesExist($rows) 16 { 17 $getApiUrl = "purchasesales/articles:get"; 18 $addApiUrl = "purchasesales/articles:add"; 19 foreach ($rows as $row) { 20 $body = new stdClass(); 21 $articles = $this->api->sendRequest($body, $getApiUrl, "code=$row->code"); 22 if ( ! (array_key_exists("articles", $articles) && count($articles["articles"] == 1))) { 23 $body = new stdClass(); 24 $body->code = $row->code; 25 $body->description = $row->description; 26 $body->type = $row->code == get_option('sa_api_shipping_code') ? "SERVICE" : "PRODUCT"; 27 $body->activeSales = true; 28 $this->api->sendRequest($body, $addApiUrl); 29 } 30 } 31 } 29 32 30 33 } -
smartaccounts/trunk/SmartAccountsClient.php
r1796659 r1861538 1 1 <?php 2 2 3 if ( ! defined( 'ABSPATH' )) {4 exit;3 if ( ! defined('ABSPATH')) { 4 exit; 5 5 } // Exit if accessed directly 6 6 7 class SmartAccountsClient { 7 class SmartAccountsClient 8 { 8 9 9 protected $isAnonymous;10 protected $email;11 protected $name;12 protected $country;13 protected $isCompany;14 protected $api;10 protected $isAnonymous; 11 protected $email; 12 protected $name; 13 protected $country; 14 protected $isCompany; 15 protected $api; 15 16 16 17 17 /** 18 * SmartAccountsClient constructor. 19 * 20 * @param $order WooCommerce order object 21 */ 22 public function __construct( $order ) { 23 $this->country = $order->get_billing_country(); 24 $this->email = $order->get_billing_email(); 25 $this->isCompany = strlen( $order->get_billing_company() ) > 0; 26 $firstName = strlen( $order->get_shipping_first_name() ) == 0 ? $order->get_billing_first_name() : $order->get_shipping_first_name(); 27 $lastName = strlen( $order->get_shipping_last_name() ) == 0 ? $order->get_billing_last_name() : $order->get_shipping_last_name(); 28 $this->isAnonymous = ( ! $firstName || ! $lastName ); 18 /** 19 * SmartAccountsClient constructor. 20 * 21 * @param $order WooCommerce order object 22 */ 23 public function __construct($order) 24 { 25 $this->country = $order->get_billing_country(); 26 $this->email = $order->get_billing_email(); 27 $this->isCompany = strlen($order->get_billing_company()) > 0; 28 $firstName = strlen($order->get_shipping_first_name()) == 0 ? $order->get_billing_first_name() : $order->get_shipping_first_name(); 29 $lastName = strlen($order->get_shipping_last_name()) == 0 ? $order->get_billing_last_name() : $order->get_shipping_last_name(); 30 $this->isAnonymous = ( ! $firstName || ! $lastName); 29 31 30 if ( $this->isAnonymous) {31 $this->name = "WooCommerce User $this->country";32 } else if ( $this->isCompany) {33 $this->name = $order->get_billing_company();34 } else {35 $this->name = "$firstName $lastName";36 }32 if ($this->isAnonymous) { 33 $this->name = "WooCommerce User $this->country"; 34 } else if ($this->isCompany) { 35 $this->name = $order->get_billing_company(); 36 } else { 37 $this->name = "$firstName $lastName"; 38 } 37 39 38 $this->api = new SmartAccountsApi();39 }40 $this->api = new SmartAccountsApi(); 41 } 40 42 41 /** 42 * This method will look for SmartAccounts clients and if no customers related to 43 * current WooCommerce order do not exist then will create new client. 44 * Comparison is done with name, country and e-mail 45 * 46 * @return SmartAccountsClass customer array 47 */ 48 public function getClient() { 49 $apiUrl = "purchasesales/clients:get"; 50 $clients = $this->api->sendRequest( null, $apiUrl, 51 "fetchAddresses=true&fetchContacts=true&nameOrRegCode=" . urlencode( $this->name ) ); 52 if ( $this->isAnonymous ) { 53 return $this->getAnonymousClient( $clients["clients"], $this->country, $this->name ); 54 } else { 55 return $this->getLoggedInClient( $clients["clients"], $this->country, $this->name, $this->email ); 56 } 57 } 43 /** 44 * This method will look for SmartAccounts clients and if no customers related to 45 * current WooCommerce order do not exist then will create new client. 46 * Comparison is done with name, country and e-mail 47 * 48 * @return SmartAccountsClass customer array 49 */ 50 public function getClient() 51 { 52 $apiUrl = "purchasesales/clients:get"; 53 $clients = $this->api->sendRequest(null, $apiUrl, 54 "fetchAddresses=true&fetchContacts=true&nameOrRegCode=" . urlencode($this->name)); 55 if ($this->isAnonymous) { 56 return $this->getAnonymousClient($clients["clients"], $this->country, $this->name); 57 } else { 58 return $this->getLoggedInClient($clients["clients"], $this->country, $this->name, $this->email); 59 } 60 } 58 61 59 /** 60 * Returns SmartAccounts general client for this country. Creates new if it does not exist yet. 61 */ 62 private function getAnonymousClient( $clients, $country, $name ) { 63 foreach ( $clients as $client ) { 64 if ( $this->isGeneralCountryClient( $client, $country, $name ) ) { 65 return $client; 66 } 67 } 62 /** 63 * Returns SmartAccounts general client for this country. Creates new if it does not exist yet. 64 */ 65 private function getAnonymousClient($clients, $country, $name) 66 { 67 foreach ($clients as $client) { 68 if ($this->isGeneralCountryClient($client, $country, $name)) { 69 return $client; 70 } 71 } 68 72 69 return $this->addNewSaClient( null, $name, $country);70 }73 return $this->addNewSaClient(null, $name, $country); 74 } 71 75 72 private function isGeneralCountryClient( $client, $country ) { 73 if ( ! array_key_exists( "address", $client ) ) { 74 return false; 75 } 76 private function isGeneralCountryClient($client, $country) 77 { 78 if ( ! array_key_exists("address", $client)) { 79 return false; 80 } 76 81 77 foreach ( $client["address"] as $key => $value) {78 if ( $key == "country" && $value == $country && $this->name == $client["name"]) {79 return true;80 }81 }82 foreach ($client["address"] as $key => $value) { 83 if ($key == "country" && $value == $country && $this->name == $client["name"]) { 84 return true; 85 } 86 } 82 87 83 return false;84 }88 return false; 89 } 85 90 86 private function addNewSaClient( $email, $name, $country ) { 87 $apiUrl = "purchasesales/clients:add"; 91 private function addNewSaClient($email, $name, $country) 92 { 93 $apiUrl = "purchasesales/clients:add"; 88 94 89 $body = new stdClass();90 $body->name = $name;91 $body->address = (object)[92 "country" => $country93 ];94 if ( $email != null) {95 $body->contacts = [96 [97 "type" => "EMAIL",98 "value" => $email99 ]100 ];101 }95 $body = new stdClass(); 96 $body->name = $name; 97 $body->address = (object)[ 98 "country" => $country 99 ]; 100 if ($email != null) { 101 $body->contacts = [ 102 [ 103 "type" => "EMAIL", 104 "value" => $email 105 ] 106 ]; 107 } 102 108 103 $createResponse = $this->api->sendRequest( $body, $apiUrl);104 $clientId = $createResponse["clientId"];105 $client = $this->api->sendRequest( null, "purchasesales/clients:get", "id=$clientId");109 $createResponse = $this->api->sendRequest($body, $apiUrl); 110 $clientId = $createResponse["clientId"]; 111 $client = $this->api->sendRequest(null, "purchasesales/clients:get", "id=$clientId"); 106 112 107 return $client["clients"][0];108 }113 return $client["clients"][0]; 114 } 109 115 110 /** 111 * Returns SmartAccounts client for the logged in user in the order. Creates new if it does not exist yet. 112 */ 113 private function getLoggedInClient( $clients, $country, $name, $email ) { 114 if ( ! is_array( $clients ) || count( $clients ) == 0 ) { 115 return $this->addNewSaClient( $email, $name, $country ); 116 } 116 /** 117 * Returns SmartAccounts client for the logged in user in the order. Creates new if it does not exist yet. 118 */ 119 private function getLoggedInClient($clients, $country, $name, $email) 120 { 121 if ( ! is_array($clients) || count($clients) == 0) { 122 return $this->addNewSaClient($email, $name, $country); 123 } 117 124 118 foreach ( $clients as $client ) { 119 //match client if name matches and is company or email also matches 120 if ( ( $this->isCompany || $this->hasEmail( $client, $email ) ) && strtolower( $this->name ) == strtolower( $client["name"] ) ) { 121 return $client; 122 } 123 } 125 foreach ($clients as $client) { 126 //match client if name matches and is company or email also matches 127 if (($this->isCompany || $this->hasEmail($client, 128 $email)) && strtolower($this->name) == strtolower($client["name"])) { 129 return $client; 130 } 131 } 124 132 125 return $this->addNewSaClient( $email, $name, $country);126 }133 return $this->addNewSaClient($email, $name, $country); 134 } 127 135 128 private function hasEmail( $client, $email ) { 129 if ( ! array_key_exists( "contacts", $client ) ) { 130 return false; 131 } 132 foreach ( $client["contacts"] as $contact ) { 133 if ( $contact["type"] == "EMAIL" && $contact["value"] == $email ) { 134 return true; 135 } 136 } 136 private function hasEmail($client, $email) 137 { 138 if ( ! array_key_exists("contacts", $client)) { 139 return false; 140 } 141 foreach ($client["contacts"] as $contact) { 142 if ($contact["type"] == "EMAIL" && $contact["value"] == $email) { 143 return true; 144 } 145 } 137 146 138 return false;139 }147 return false; 148 } 140 149 141 150 } -
smartaccounts/trunk/SmartAccountsPayment.php
r1786015 r1861538 1 1 <?php 2 2 3 class SmartAccountsPayment { 3 class SmartAccountsPayment 4 { 4 5 5 public function __construct( $order, $invoice ) { 6 $this->api = new SmartAccountsApi(); 7 $this->order = $order; 8 $this->invoice = $invoice["invoice"]; 9 } 6 public function __construct($order, $invoice) 7 { 8 $this->api = new SmartAccountsApi(); 9 $this->order = $order; 10 $this->invoice = $invoice["invoice"]; 11 } 10 12 11 public function createPayment() { 12 $apiUrl = "purchasesales/payments:add"; 13 $body = new stdClass(); 14 $body->date = $this->order->get_date_created()->date( "d.m.Y" ); 15 $body->partnerType = "CLIENT"; 16 $body->clientId = $this->invoice["clientId"]; 17 $body->accountType = "BANK"; 18 $body->accountName = get_option( "sa_api_payment_account" ); 19 $body->currency = $this->order->get_currency(); 20 $body->amount = $this->invoice["totalAmount"]; 21 $body->rows = [ 22 [ 23 "type" => "CLIENT_INVOICE", 24 "id" => $this->invoice["invoiceId"], 25 "amount" => $this->invoice["totalAmount"] 26 ] 27 ]; 28 $this->api->sendRequest( $body, $apiUrl ); 29 } 13 public function createPayment() 14 { 15 $apiUrl = "purchasesales/payments:add"; 16 $body = new stdClass(); 17 $body->date = $this->order->get_date_created()->date("d.m.Y"); 18 $body->partnerType = "CLIENT"; 19 $body->clientId = $this->invoice["clientId"]; 20 $body->accountType = "BANK"; 21 $body->accountName = get_option("sa_api_payment_account"); 22 $body->currency = $this->order->get_currency(); 23 $body->amount = $this->invoice["totalAmount"]; 24 $body->rows = [ 25 [ 26 "type" => "CLIENT_INVOICE", 27 "id" => $this->invoice["invoiceId"], 28 "amount" => $this->invoice["totalAmount"] 29 ] 30 ]; 31 $this->api->sendRequest($body, $apiUrl); 32 } 30 33 } -
smartaccounts/trunk/SmartAccountsSalesInvoice.php
r1796659 r1861538 1 1 <?php 2 2 3 if ( ! defined( 'ABSPATH' )) {4 exit;3 if ( ! defined('ABSPATH')) { 4 exit; 5 5 } // Exit if accessed directly 6 6 7 class SmartAccountsSalesInvoice { 7 class SmartAccountsSalesInvoice 8 { 8 9 9 public function __construct( $order, $client ) { 10 $this->client = $client; 11 $this->order = $order; 12 $this->api = new SmartAccountsApi(); 13 } 10 public function __construct($order, $client) 11 { 12 $this->client = $client; 13 $this->order = $order; 14 $this->api = new SmartAccountsApi(); 15 } 14 16 15 public function saveInvoice() { 16 $apiUrl = "purchasesales/clientinvoices:add"; 17 public function saveInvoice() 18 { 19 $apiUrl = "purchasesales/clientinvoices:add"; 17 20 18 $body = new stdClass();19 $body->clientId = $this->client["id"];20 $body->date = $this->order->get_date_created()->date( "d.m.Y");21 $body->currency = $this->order->get_currency();22 $body->rows = $this->getOrderRows();23 $body->roundAmount = $this->getRoundingAmount( $body->rows);24 $body->amount = number_format( $this->getOrderTotal(), 2);25 $body->invoiceNote = "WooCommerce order #" . $this->order->get_id();21 $body = new stdClass(); 22 $body->clientId = $this->client["id"]; 23 $body->date = $this->order->get_date_created()->date("d.m.Y"); 24 $body->currency = $this->order->get_currency(); 25 $body->rows = $this->getOrderRows(); 26 $body->roundAmount = $this->getRoundingAmount($body->rows); 27 $body->amount = number_format($this->getOrderTotal(), 2); 28 $body->invoiceNote = "WooCommerce order #" . $this->order->get_id(); 26 29 27 $saArticle = new SmartAccountsArticle();28 $saArticle->ensureAllArticlesExist( $body->rows);30 $saArticle = new SmartAccountsArticle(); 31 $saArticle->ensureAllArticlesExist($body->rows); 29 32 30 $salesInvoice = $this->api->sendRequest( $body, $apiUrl);33 $salesInvoice = $this->api->sendRequest($body, $apiUrl); 31 34 32 return [ "invoice" => $salesInvoice, "rows" => $body->rows];33 }35 return ["invoice" => $salesInvoice, "rows" => $body->rows]; 36 } 34 37 35 public function getRoundingAmount( $rows ) { 36 $rowsTotal = 0; 37 foreach ( $rows as $row ) { 38 $rowsTotal += $row->totalCents; 39 $rowsTotal += $row->taxCents; 40 } 38 public function getRoundingAmount($rows) 39 { 40 $rowsTotal = 0; 41 foreach ($rows as $row) { 42 $rowsTotal += $row->totalCents; 43 $rowsTotal += $row->taxCents; 44 } 41 45 42 $roundingAmount = number_format( ( $this->getOrderTotal() * 100 + $this->getTotalTax() * 100 - $rowsTotal ) / 100, 2 ); 46 $roundingAmount = number_format(($this->getOrderTotal() * 100 + $this->getTotalTax() * 100 - $rowsTotal) / 100, 47 2); 43 48 44 return $roundingAmount;45 }49 return $roundingAmount; 50 } 46 51 47 public function getTotalTax() { 48 return floatval( $this->order->get_total_tax() ); 49 } 52 public function getTotalTax() 53 { 54 return floatval($this->order->get_total_tax()); 55 } 50 56 51 public function getOrderTotal() { 52 return $this->order->get_subtotal() + $this->order->get_shipping_total(); 53 } 57 public function getOrderTotal() 58 { 59 return $this->order->get_subtotal() + $this->order->get_shipping_total(); 60 } 54 61 55 private function getOrderRows() { 56 $rows = []; 57 $totalTax = $this->getTotalTax(); 58 $subTotal = $this->getOrderTotal(); 59 $vatPc = round( $totalTax * 100 / $subTotal ); 60 foreach ( $this->order->get_items() as $item ) { 61 $row = new stdClass(); 62 $row->code = $item->get_product()->get_sku(); 63 $row->description = strlen( $item->get_product()->get_description() ) == 0 ? $item->get_product()->get_name() : $item->get_product()->get_description(); 64 $row->quantity = $item->get_quantity(); 62 private function getOrderRows() 63 { 64 $rows = []; 65 $totalTax = $this->getTotalTax(); 66 $subTotal = $this->getOrderTotal(); 67 $vatPc = round($totalTax * 100 / $subTotal); 68 foreach ($this->order->get_items() as $item) { 69 $code = $item->get_product()->get_sku(); 70 if ($code == null || strlen($code) == 0) { 71 $code = "wc_product_" . $item->get_product()->get_id(); 72 } 73 $row = new stdClass(); 74 $row->code = $code; 75 $row->description = strlen($item->get_product()->get_description()) == 0 ? $item->get_product()->get_name() : $item->get_product()->get_description(); 76 $row->quantity = $item->get_quantity(); 65 77 66 $rowPrice = $item->get_total() / $item->get_quantity();78 $rowPrice = $item->get_total() / $item->get_quantity(); 67 79 68 $row->price = number_format( $rowPrice, 2);69 $row->vatPc = $vatPc;70 $row->totalCents = intval( round( floatval( $row->price ) * $row->quantity * 100 ));71 $row->taxCents = intval( round( $row->totalCents * $vatPc / 100 ));72 $rows[] = $row;73 }80 $row->price = number_format($rowPrice, 2); 81 $row->vatPc = $vatPc; 82 $row->totalCents = intval(round(floatval($row->price) * $row->quantity * 100)); 83 $row->taxCents = intval(round($row->totalCents * $vatPc / 100)); 84 $rows[] = $row; 85 } 74 86 75 if ( $this->order->get_shipping_total() > 0) {76 $row = new stdClass();77 $row->code = get_option( 'sa_api_shipping_code');78 $row->description = "Woocommerce Shipping";79 $row->price = $this->order->get_shipping_total();80 $row->quantity = 1;81 $row->vatPc = $vatPc;82 $row->totalCents = intval( round( floatval( $row->price ) * $row->quantity * 100 ));83 $row->taxCents = intval( round( $row->totalCents * $vatPc / 100 ));84 $rows[] = $row;85 }87 if ($this->order->get_shipping_total() > 0) { 88 $row = new stdClass(); 89 $row->code = get_option('sa_api_shipping_code'); 90 $row->description = "Woocommerce Shipping"; 91 $row->price = $this->order->get_shipping_total(); 92 $row->quantity = 1; 93 $row->vatPc = $vatPc; 94 $row->totalCents = intval(round(floatval($row->price) * $row->quantity * 100)); 95 $row->taxCents = intval(round($row->totalCents * $vatPc / 100)); 96 $rows[] = $row; 97 } 86 98 87 return $rows;88 }99 return $rows; 100 } 89 101 90 102 -
smartaccounts/trunk/smartaccounts.php
r1857095 r1861538 4 4 * Plugin URI: https://github.com/smartman/woocommerce_smartaccounts 5 5 * Description: This plugin creates sales invoices in the smartaccounts.ee Online Accounting Software after Woocommerce order creation 6 * Version: 1.2 6 * Version: 1.2.1 7 7 * Author: Margus Pala 8 * Author URI: http ://marguspala.com8 * Author URI: https://marguspala.com 9 9 * License: GPLv2 or later 10 10 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
Note: See TracChangeset
for help on using the changeset viewer.