diff --git a/.gitignore b/.gitignore
index 9f1a478..61f5f59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/xsd/
/vendor/
/nbproject/
+/composer.lock
diff --git a/.phpunit.result.cache b/.phpunit.result.cache
new file mode 100644
index 0000000..5f138a3
--- /dev/null
+++ b/.phpunit.result.cache
@@ -0,0 +1 @@
+C:37:"PHPUnit\Runner\DefaultTestResultCache":4394:{a:2:{s:7:"defects";a:40:{s:40:"Test\mServer\ClientTest::testprocessInit";i:4;s:38:"Test\mServer\ClientTest::testlogBanner";i:4;s:34:"Test\mServer\ClientTest::testsetUp";i:4;s:36:"Test\mServer\ClientTest::testsetAuth";i:3;s:40:"Test\mServer\ClientTest::testsetInstance";i:4;s:43:"Test\mServer\ClientTest::testsetApplication";i:4;s:46:"Test\mServer\ClientTest::testsetCheckDuplicity";i:4;s:37:"Test\mServer\ClientTest::testcurlInit";i:4;s:42:"Test\mServer\ClientTest::testsetPostFields";i:4;s:42:"Test\mServer\ClientTest::testdoCurlRequest";i:4;s:43:"Test\mServer\ClientTest::testperformRequest";i:4;s:44:"Test\mServer\ClientTest::testprocessResponse";i:4;s:38:"Test\mServer\ClientTest::testgetStatus";i:4;s:37:"Test\mServer\ClientTest::testtakeData";i:4;s:35:"Test\mServer\ClientTest::testcreate";i:4;s:40:"Test\mServer\ClientTest::testaddToPohoda";i:2;s:43:"Test\mServer\ClientTest::testupdateInPohoda";i:2;s:39:"Test\mServer\ClientTest::testfilterToMe";i:4;s:49:"Test\mServer\ClientTest::testgetColumnsFromPohoda";i:2;s:37:"Test\mServer\ClientTest::test__wakeup";i:2;s:39:"Test\mServer\AdressbookTest::testcreate";i:4;s:36:"Test\mServer\InvoiceTest::testcreate";i:4;s:37:"Test\mServer\InvoiceTest::testaddItem";i:4;s:35:"Test\mServer\InvoiceTest::testextId";i:4;s:40:"Test\mServer\ResponseTest::testuseCaller";i:4;s:50:"Test\mServer\ResponseTest::testprocessResponsePack";i:4;s:54:"Test\mServer\ResponseTest::testprocessResponsePackItem";i:4;s:53:"Test\mServer\ResponseTest::testprocessProducedDetails";i:4;s:51:"Test\mServer\ResponseTest::testprocessImportDetails";i:4;s:50:"Test\mServer\ResponseTest::testprocessResponseData";i:4;s:43:"Test\mServer\ResponseTest::testtypesToArray";i:4;s:42:"Test\mServer\ResponseTest::testtypeToArray";i:4;s:38:"Test\mServer\ResponseTest::testgetNote";i:4;s:35:"Test\mServer\ResponseTest::testisOk";i:4;s:39:"Test\mServer\ResponseTest::testgetState";i:4;s:44:"Test\mServer\ResponseTest::testgetAgendaData";i:4;s:45:"Test\mServer\ResponseTest::testprepareElement";i:4;s:44:"Test\mServer\ResponseTest::testanyXmlToArray";i:4;s:36:"Test\mServer\ResponseTest::testparse";i:4;s:41:"Test\mServer\ResponseTest::testxmlToArray";i:4;}s:5:"times";a:40:{s:40:"Test\mServer\ClientTest::testprocessInit";d:0.004;s:38:"Test\mServer\ClientTest::testlogBanner";d:0.001;s:34:"Test\mServer\ClientTest::testsetUp";d:0.001;s:36:"Test\mServer\ClientTest::testsetAuth";d:0.001;s:40:"Test\mServer\ClientTest::testsetInstance";d:0.001;s:43:"Test\mServer\ClientTest::testsetApplication";d:0;s:46:"Test\mServer\ClientTest::testsetCheckDuplicity";d:0.001;s:37:"Test\mServer\ClientTest::testcurlInit";d:0;s:42:"Test\mServer\ClientTest::testsetPostFields";d:0;s:42:"Test\mServer\ClientTest::testdoCurlRequest";d:0;s:43:"Test\mServer\ClientTest::testperformRequest";d:0.001;s:44:"Test\mServer\ClientTest::testprocessResponse";d:0.001;s:38:"Test\mServer\ClientTest::testgetStatus";d:26.706;s:37:"Test\mServer\ClientTest::testtakeData";d:37.494;s:35:"Test\mServer\ClientTest::testcreate";d:0.003;s:40:"Test\mServer\ClientTest::testaddToPohoda";d:1.216;s:43:"Test\mServer\ClientTest::testupdateInPohoda";d:1.017;s:39:"Test\mServer\ClientTest::testfilterToMe";d:0.002;s:49:"Test\mServer\ClientTest::testgetColumnsFromPohoda";d:0.975;s:37:"Test\mServer\ClientTest::test__wakeup";d:0.003;s:39:"Test\mServer\AdressbookTest::testcreate";d:0.002;s:36:"Test\mServer\InvoiceTest::testcreate";d:0.001;s:37:"Test\mServer\InvoiceTest::testaddItem";d:0;s:35:"Test\mServer\InvoiceTest::testextId";d:0;s:40:"Test\mServer\ResponseTest::testuseCaller";d:0;s:50:"Test\mServer\ResponseTest::testprocessResponsePack";d:0;s:54:"Test\mServer\ResponseTest::testprocessResponsePackItem";d:0;s:53:"Test\mServer\ResponseTest::testprocessProducedDetails";d:0;s:51:"Test\mServer\ResponseTest::testprocessImportDetails";d:0;s:50:"Test\mServer\ResponseTest::testprocessResponseData";d:0.001;s:43:"Test\mServer\ResponseTest::testtypesToArray";d:0;s:42:"Test\mServer\ResponseTest::testtypeToArray";d:0;s:38:"Test\mServer\ResponseTest::testgetNote";d:0;s:35:"Test\mServer\ResponseTest::testisOk";d:0;s:39:"Test\mServer\ResponseTest::testgetState";d:0;s:44:"Test\mServer\ResponseTest::testgetAgendaData";d:0;s:45:"Test\mServer\ResponseTest::testprepareElement";d:0;s:44:"Test\mServer\ResponseTest::testanyXmlToArray";d:0;s:36:"Test\mServer\ResponseTest::testparse";d:0;s:41:"Test\mServer\ResponseTest::testxmlToArray";d:0;}}}
\ No newline at end of file
diff --git a/README.md b/README.md
index ac11a97..0633699 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,15 @@
+![Project Logo](phpmserver.svg?raw=true)
+
# PHPmServer
-client library for Stormware's Pohoda mServer
+client library for Stormware's [mPohoda mServer](https://www.stormware.cz/pohoda/xml/mserver/)
+
+Features:
+
+ * Create/Update/Delete AddressBook record
+ * Create/Update/Delete Invoice record
+
+Installation:
+-------------
Install using composer:
@@ -7,8 +17,33 @@ Install using composer:
composer require vitexsoftware/pohoda-connector
```
+Or clone https://github.com/VitexSoftware/PHP-Pohoda-Connector.git
+
+Configuration
+-------------
+
+Classess check at startup for this constants or environment variables:
+
+ * POHODA_ICO - company indentificator
+ * POHODA_URL - mServer endpoint
+ * POHODA_USERNAME - Pohoda user's login
+ * POHODA_PASSWORD - Pohoda user's password
+ * POHODA_TIMEOUT - Curl timeout
+ * POHODA_COMPRESS - compress is disabled by default
+ * POHODA_DEBUG - debug mode is disabled by default
+
+
+Usage
+-----
+
+See usage examples in [tests](tests) directory
+
+ * [Check Connection](tests/check-connection.php)
+ * [Add Addressbook record](tests/insert-address.php)
+ * [Create Invoice](tests/insert-invoice.php)
+ * [Addressbook reading](tests/read-address.php)
+ * [Address update](tests/update-address.php)
-See also: https://github.com/Spoje-NET/PohodaSQL , https://github.com/Spoje-NET/php-abraflexi
+See also my other libraries: https://github.com/Spoje-NET/PohodaSQL , https://github.com/Spoje-NET/php-abraflexi
-The Response class was taken from https://github.com/jakubdusek/PohodaResponseParser By @jakubdusek
diff --git a/composer.json b/composer.json
index 219d9f4..3755dec 100644
--- a/composer.json
+++ b/composer.json
@@ -12,11 +12,9 @@
"require": {
"ext-curl": "*",
"ext-iconv": "*",
- "ext-simplexml": "*",
"riesenia/pohoda": ">=1.5 || dev-master",
"vitexsoftware/ease-core": ">=1.9",
- "lightools/xml": "v2.0.0",
- "sabre/xml": "2.2.3"
+ "lightools/xml": "v2.0.0"
},
"autoload": {
"psr-4": {
diff --git a/phpmserver.svg b/phpmserver.svg
new file mode 100644
index 0000000..50a1bbc
--- /dev/null
+++ b/phpmserver.svg
@@ -0,0 +1,203 @@
+
+
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..acaa88a
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ ./tests
+
+
+
+
+
+ src/mServer
+
+
+
+
+
diff --git a/src/mServer/Adressbook.php b/src/mServer/Adressbook.php
index e2e673e..975f1d1 100644
--- a/src/mServer/Adressbook.php
+++ b/src/mServer/Adressbook.php
@@ -1,9 +1,10 @@
+ * @copyright (C) 2020 Vitex Software
*/
namespace mServer;
@@ -13,7 +14,7 @@
*
* @author vitex
*/
-class Adressbook extends Client /* implements \Sabre\Xml\XmlDeserializable */ {
+class Adressbook extends Client {
/**
* Current Object's agenda
@@ -27,45 +28,6 @@ class Adressbook extends Client /* implements \Sabre\Xml\XmlDeserializable */ {
*/
public $requestXml = null;
- /*
- public function getElementMap($extra = []) {
- return
- array_merge(
- [
- '{http://www.stormware.cz/schema/version_2/list_addBook.xsd}listAddressBook' => function(\Sabre\Xml\Reader $reader) {
- return \Sabre\Xml\Deserializer\repeatingElements($reader, '{http://www.stormware.cz/schema/version_2/list_addBook.xsd}addressbook');
- },
- '{http://www.stormware.cz/schema/version_2/list_addBook.xsd}addressbook' => function(\Sabre\Xml\Reader $reader) {
- return \Sabre\Xml\Deserializer\keyValue($reader, 'http://www.stormware.cz/schema/version_2/list_addBook.xsd');
- },
- '{http://www.stormware.cz/schema/version_2/addressbook.xsd}addressbookHeader' => function(\Sabre\Xml\Reader $reader) {
- return \Sabre\Xml\Deserializer\keyValue($reader, 'http://www.stormware.cz/schema/version_2/addressbook.xsd');
- },
- '{http://www.stormware.cz/schema/version_2/type.xsd}address' => function(\Sabre\Xml\Reader $reader) {
- return \Sabre\Xml\Deserializer\keyValue($reader, 'http://www.stormware.cz/schema/version_2/type.xsd');
- },
- '{http://www.stormware.cz/schema/version_2/type.xsd}shipToAddress' => function(\Sabre\Xml\Reader $reader) {
- return \Sabre\Xml\Deserializer\keyValue($reader, 'http://www.stormware.cz/schema/version_2/type.xsd');
- },
- ], parent::getElementMap($extra));
- }
-
- static function xmlDeserialize(\Sabre\Xml\Reader $reader) {
- $addressBook = new self();
- // Borrowing a parser from the KeyValue class.
- $keyValue = \Sabre\Xml\Element\KeyValue::xmlDeserialize($reader);
-
- if (isset($keyValue['{http://example.org/books}title'])) {
- $book->title = $keyValue['{http://example.org/books}title'];
- }
- if (isset($keyValue['{http://example.org/books}author'])) {
- $book->author = $keyValue['{http://example.org/books}author'];
- }
-
- return $addressBook;
- }
- */
-
/**
* Create Agenda document using given data
*
@@ -76,35 +38,9 @@ public function create($data) {
}
/**
- * Convert decimal coordineates to GPS field value
- *
- * @param string $latitude
- * @param string $longitude
- *
- * @return string 50° 04' 58.9781" N 000° 00' 00.0000" E
- */
- public static function LatLongToGPS(string $latitude, string $longitude) {
- return self::DECtoDMS($longitude) . 'N ' . self::DECtoDMS($longitude) . 'E ';
- }
-
- /**
- * Converts decimal longitude / latitude to DMS ( Degrees / minutes / seconds )
- * This is the piece of code which may appear to be inefficient, but to avoid
- * issues with floating point math we extract the integer part and the float
- * part by using a string function.
- *
- * @param string $dec float as string ex. 50.111199
- *
- * @return string 50°06'40.3"
+ * AddressBook records name column
+ * @var string
*/
- public static function DECtoDMS(string $dec) {
- $vars = explode(".", $dec);
- $deg = $vars[0];
- $tempma = "0." . $vars[1];
- $tempma = $tempma * 3600;
- $min = floor($tempma / 60);
- $sec = round($tempma - ($min * 60), 4);
- return $deg . '° ' . $min . "' " . $sec . '" ';
- }
+ public $nameColumn = 'address:company';
}
diff --git a/src/mServer/Client.php b/src/mServer/Client.php
index 6de9ee5..61a32d3 100644
--- a/src/mServer/Client.php
+++ b/src/mServer/Client.php
@@ -1,7 +1,7 @@
* @copyright (C) 2020 Vitex Software
@@ -28,7 +28,7 @@ class Client extends \Ease\Sand {
*
* @var string
*/
- public static $libVersion = '0.1';
+ public static $libVersion = '0.3';
/**
* Curl Handle.
@@ -148,14 +148,21 @@ class Client extends \Ease\Sand {
public $requestXml = null;
/**
- *
+ * Where to find current record name.
+ * @var string column name or path in array address:company
+ */
+ public $nameColumn = null;
+
+ /**
+ * mServer client class
*
- * @param mixed $init default record id or initial data. See processInit()
+ * @param mixed $init default record id or initial data. See processInit()
* @param array $options Connection settings and other options override
*/
public function __construct($init = null, $options = []) {
$this->setUp($options);
$this->curlInit();
+ Pohoda::$encoding = 'UTF-8';
$this->pohoda = new Pohoda($this->ico);
$this->pohoda->setApplicationName(Functions::cfg('APP_NAME') ? Functions::cfg('APP_NAME') : 'PHPmPohoda');
$tmpFile = sys_get_temp_dir() . '/' . Functions::randomString() . '.xml';
@@ -165,6 +172,11 @@ public function __construct($init = null, $options = []) {
}
}
+ /**
+ * Process and use initial value
+ *
+ * @param mixed $init
+ */
public function processInit($init) {
if (is_integer($init)) {
$this->loadFromPohoda($init);
@@ -223,7 +235,7 @@ public function setUp($options = []) {
$this->setCheckDuplicity($options['duplicity']);
}
- $this->setupProperty($options, 'debug');
+ $this->setupProperty($options, 'debug', 'POHODA_DEBUG');
}
/**
@@ -236,14 +248,29 @@ public function setAuth() {
return strlen($this->user) && strlen($this->password);
}
+ /**
+ * Set Instance http header
+ *
+ * @param string $instance
+ */
public function setInstance(string $instance) {
$this->defaultHttpHeaders['STW-Instance'] = $instance;
}
+ /**
+ * Set Application http header
+ *
+ * @param string $application
+ */
public function setApplication(string $application) {
$this->defaultHttpHeaders['STW-Application'] = $application;
}
+ /**
+ * Set "Check Duplicity" http header enabler
+ *
+ * @param bool $flag
+ */
public function setCheckDuplicity(bool $flag) {
if ($flag) {
$this->defaultHttpHeaders['STW-Check-Duplicity'] = 'true';
@@ -341,6 +368,13 @@ public function performRequest($urlSuffix = null, $method = 'POST') {
return $this->processResponse($this->doCurlRequest($url, $method));
}
+ /**
+ * Response processing handler
+ *
+ * @param int $httpCode
+ *
+ * @return boolean
+ */
public function processResponse($httpCode) {
switch ($httpCode) {
@@ -396,7 +430,7 @@ public function processResponse($httpCode) {
}
foreach ($this->response->messages as $type => $messages) {
foreach ($messages as $message) {
- $this->addStatusMessage($message['state'].' '.$message['errno'].': '.$message['note'].(array_key_exists('XPath', $message)?' ('.$message['XPath'].')':''), $type);
+ $this->addStatusMessage($message['state'] . ' ' . $message['errno'] . ': ' . $message['note'] . (array_key_exists('XPath', $message) ? ' (' . $message['XPath'] . ')' : ''), $type);
}
}
}
@@ -412,19 +446,9 @@ public function processResponse($httpCode) {
* @return boolean
*/
public function getStatus() {
- $this->performRequest('/status');
- return ($this->lastResponseCode == 200) && $this->lastCurlResponse == 'Response from POHODA mServer';
- }
-
- public function getElementMap($extra = []) {
- return array_merge(
- [
- '{http://www.stormware.cz/schema/version_2/response.xsd}responsePackItem' => function(\Sabre\Xml\Reader $reader) {
- return \Sabre\Xml\Deserializer\keyValue($reader, 'http://www.stormware.cz/schema/version_2/response.xsd');
- }
- ]
- , $extra
- );
+ $this->responseStats = [];
+ $this->errors = [];
+ return ($this->doCurlRequest($this->url . '/status','POST') == 200) && $this->lastCurlResponse == 'Response from POHODA mServer';
}
/**
@@ -434,7 +458,7 @@ public function getElementMap($extra = []) {
* @param boolean $reset replace current content
*/
public function takeData($data, $reset = false) {
- parent::takeData(\Ease\Functions::recursiveIconv('UTF-8', 'Windows-1250', $data), $reset);
+ parent::takeData($data, $reset);
$this->create($this->getData());
}
@@ -454,20 +478,69 @@ public function create($data) {
*
* @return int
*/
- public function insertToPohoda($data = []) {
- if (count($data)) {
+ public function addToPohoda($data = []) {
+ if (!empty($data)) {
+ $this->takeData($data);
+ }
+ if ($this->requestXml) {
+ if (method_exists($this->requestXml, 'addActionType')) {
+ $this->requestXml->addActionType('add'); // "add", "add/update", "update", "delete"
+ }
+ $this->pohoda->addItem(2, $this->requestXml);
+ }
+
+ $this->setPostFields($this->pohoda->close());
+ return $this->performRequest('/xml');
+ }
+
+ /**
+ * Insert prepared record to Pohoda
+ *
+ * @param array $data extra data
+ *
+ * @return int
+ */
+ public function updateInPohoda($data = [], $filter = null) {
+ if (!empty($data)) {
$this->takeData($data);
}
if ($this->requestXml) {
if (method_exists($this->requestXml, 'addActionType')) {
- $this->requestXml->addActionType('add/update'); // "add", "add/update", "update", "delete"
+ $this->requestXml->addActionType('update', empty($filter) ? $this->filterToMe() : $filter); // "add", "add/update", "update", "delete"
}
$this->pohoda->addItem(2, $this->requestXml);
}
+
$this->setPostFields($this->pohoda->close());
return $this->performRequest('/xml');
}
+ /**
+ * Filter to select only "current" record
+ *
+ * @return array
+ */
+ public function filterToMe() {
+ if ($this->nameColumn) {
+ if (strstr($this->nameColumn, ':')) {
+ $data = $this->getData();
+ foreach (explode(':', $this->nameColumn) as $key) {
+ if (array_key_exists($data, $data)) {
+ $data = $data[$key];
+ } else {
+ throw new \Exception('Data Path ' . $this->nameColumn . 'does not exist');
+ }
+ }
+ $filter = [$key => $data];
+ } else {
+ $filter = [$this->nameColumn => $this->getDataValue($this->nameColumn)];
+ }
+ } else {
+ $filter = [$this->getKeyColumn() => $this->getMyKey()];
+ }
+ return $filter;
+ }
+
/**
*
* @param type $columns
diff --git a/src/mServer/Invoice.php b/src/mServer/Invoice.php
index e4e08e3..ad11dec 100644
--- a/src/mServer/Invoice.php
+++ b/src/mServer/Invoice.php
@@ -1,9 +1,10 @@
+ * @copyright (C) 2020 Vitex Software
*/
namespace mServer;
@@ -13,7 +14,7 @@
*
* @author vitex
*/
-class Invoice extends Client /* implements \Sabre\Xml\XmlDeserializable */ {
+class Invoice extends Client {
/**
* Current Object's agenda
@@ -82,6 +83,37 @@ public function create($data) {
}
}
+ /**
+ * Add Item into invoice
+ *
+ * @param array $itemRecord Item properties
+ *
+ * @return \Riesenia\Pohoda\Invoice Invoice with item added
+ */
+ public function addItem($itemRecord) {
+
+ if (array_key_exists('stockItemIDS', $itemRecord)) { //TODO: Finalize
+ $stockItemIDS = $itemRecord['stockItemIDS'];
+ unset($itemRecord['stockItemIDS']);
+ $itemRecord['stockItem']['stockItem']['ids'] = $stockItemIDS;
+ }
+
+
+// $itemRecord['homeCurrency'];
+// $itemRecord['foreignCurrency'];
+// $itemRecord['stockItem'];
+
+
+ return $this->requestXml->addItem($itemRecord);
+ }
+
+ /**
+ *
+ * @param type $ids
+ * @param type $exSystemName
+ * @param type $exSystemText
+ * @return \SimpleXMLElement
+ */
public static function extId($ids, $exSystemName = '', $exSystemText = '') {
$node = new \SimpleXMLElement('', 0, false, \Riesenia\Pohoda::$namespaces['typ']);
diff --git a/src/mServer/Response.php b/src/mServer/Response.php
index 15dc82e..26483d1 100644
--- a/src/mServer/Response.php
+++ b/src/mServer/Response.php
@@ -1,5 +1,12 @@
+ * @copyright (C) 2020 Vitex Software
+ */
+
namespace mServer;
/**
@@ -22,11 +29,6 @@ class Response extends \Ease\Sand {
*/
const STATE_OK = 'ok';
- /**
- * @var Description\Sabre\Xml\Service XML Reader
- */
- private $service;
-
/**
* Parsed Result
* @var array
@@ -51,13 +53,24 @@ class Response extends \Ease\Sand {
*/
public $producedDetails;
+ /**
+ * Operation status
+ * @var string
+ */
+ private $state;
+
+ /**
+ * Operation status note
+ * @var string
+ */
+ private $note;
+
/**
* Create a new Response Instance
*
* @param string $xml path to file
*/
public function __construct(Client $caller) {
- $this->service = new \Sabre\Xml\Service();
$this->useCaller($caller);
}
@@ -68,38 +81,82 @@ public function __construct(Client $caller) {
public function useCaller(Client $caller) {
$this->caller = $caller;
if ($caller->lastCurlResponse) {
- $this->service->elementMap = $caller->getElementMap();
- $this->parsed = $this->service->parse($caller->lastCurlResponse);
- $addressbookResponse = $this->parsed[0]['value']['{http://www.stormware.cz/schema/version_2/addressbook.xsd}addressbookResponse'];
-
- foreach ($addressbookResponse as $responseData) {
- switch (self::stripNsUri($responseData['name'])) {
- case 'producedDetails' :
- $this->producedDetails = self::typesToArray($responseData['value']);
- if (array_key_exists('extId', $this->producedDetails)) {
- $this->producedDetails['extId'] = self::typesToArray($this->producedDetails['extId']);
- }
- break;
- case 'importDetails':
- foreach ($addressbookResponse[0]['value'] as $response) {
- $importDetails = self::typesToArray($response['value']);
- $this->messages[$importDetails['state']][] = $importDetails;
- }
-
- if (count($this->messages['error'])) {
- $this->parsed[0]['attributes']['state'] = 'error';
- } else if (count($this->messages['warning'])) {
- $this->parsed[0]['attributes']['state'] = 'warning';
- }
- break;
- default:
- $this->addStatusMessage(_('Unknown response section') . ': ' . $responseData['name'], 'debug');
- break;
- }
+ $parsed = $this->parse($this->caller->lastCurlResponse, []);
+ $this->processResponsePack($parsed['responsePack']);
+ } else {
+ $this->state = 'error';
+ $this->note = $caller->lastCurlError;
+ }
+ }
+
+ public function processResponsePack($responsePackData) {
+ if (array_key_exists('rsp:responsePackItem', $responsePackData)) {
+ $this->processResponsePackItem($responsePackData['rsp:responsePackItem']);
+ } else {
+ $this->state = $responsePackData['@state'];
+ $this->note = $responsePackData['@note'];
+ }
+ }
+
+ public function processResponsePackItem($responsePackItem) {
+
+ foreach ($responsePackItem as $name => $responsePackSubitem) {
+
+ switch ($name) {
+ case 'adb:addressbookResponse':
+ $this->processResponseData($responsePackSubitem);
+ break;
+ case '@state':
+ $this->state = $responsePackSubitem;
+ break;
+ case '':
+ break;
+
+ default:
+// throw new Exception('Unknown element to process: ' . $name);
+ break;
}
+ }
+ }
+
+ public function processProducedDetails($productDetails) {
+ $this->producedDetails = self::typeToArray($productDetails);
+ }
+
+ public function processImportDetails($importDetails) {
+ if (array_key_exists('rdc:state', $importDetails['rdc:detail'])) {
+ $importDetail = self::typeToArray($importDetails['rdc:detail']);
+ $this->messages[$importDetail['state']][] = $importDetail;
} else {
- $this->parsed[0]['attributes']['state'] = 'error';
- $this->parsed[0]['attributes']['note'] = $caller->lastCurlError;
+ foreach (self::typesToArray($importDetails['rdc:detail']) as $importDetail) {
+ $this->messages[$importDetail['state']][] = $importDetail;
+ }
+ }
+
+ if (count($this->messages['error'])) {
+ $this->state = 'error';
+ } else if (count($this->messages['warning'])) {
+ $this->state = 'warning';
+ }
+ }
+
+ /**
+ *
+ * @param array $responseData
+ */
+ function processResponseData($responseData) {
+ foreach ($responseData as $key => $value) {
+ switch ($key) {
+ case 'rdc:producedDetails' :
+ $this->processProducedDetails($value);
+ break;
+ case 'rdc:importDetails':
+ $this->processImportDetails($value);
+ break;
+ default:
+// $this->addStatusMessage(_('Unknown response section') . ': ' . $responseData['name'], 'debug');
+ break;
+ }
}
}
@@ -111,8 +168,22 @@ public function useCaller(Client $caller) {
*/
public static function typesToArray(array $source) {
$details = [];
- foreach ($source as $detail) {
- $details[self::stripNsUri($detail['name'])] = $detail['value'];
+ foreach ($source as $did => $detail) {
+ $details[$did] = self::typeToArray($detail);
+ }
+ return $details;
+ }
+
+ /**
+ *
+ * @param array $type
+ *
+ * @return array
+ */
+ public static function typeToArray(array $type) {
+ $details = [];
+ foreach ($type as $key => $value) {
+ $details[str_replace(['rdc:', 'typ:'], '', $key)] = is_array($value) ? (array_key_exists('$', $value) ? $value['$'] : self::typeToArray($value)) : $value;
}
return $details;
}
@@ -122,7 +193,7 @@ public static function typesToArray(array $source) {
* @return string
*/
public function getNote() {
- return isset($this->parsed[0]['attributes']['note']) ? $this->parsed[0]['attributes']['note'] : null;
+ return $this->note;
}
/**
@@ -140,7 +211,7 @@ public function isOk() {
* @return string
*/
public function getState() {
- return (string) $this->parsed[0]['attributes']['state'];
+ return $this->state;
}
public function getAgendaData($agenda) {
@@ -151,32 +222,21 @@ public function getAgendaData($agenda) {
return $data;
}
- static public function stripNsUri($parsedName) {
- return \Sabre\Xml\Service::parseClarkNotation($parsedName)[1];
- }
-
- /**
- * Convert XML to array.
- *
- * @param string $xml
- *
- * @return array
- */
- public static function xml2array($xml) {
- $arr = [];
- if (!empty($xml)) {
- foreach ($xml->attributes() as $a) {
- $arr['@' . $a->getName()] = strval($a);
- }
- foreach ($xml->children() as $r) {
- if (count($r->children()) == 0) {
- $arr[$r->getName()] = strval($r);
+ public static function prepareElement($elementData) {
+ $name = self::stripNsUri($elementData['name']);
+ $data = [];
+ foreach ($elementData['value'] as $subitems) {
+ foreach ($subitems as $subitem) {
+ if (is_array($subitem)) {
+ if (array_key_exists('name', $subitem)) {
+ $data = array_merge($data, self::prepareElement($subitem));
+ }
} else {
- $arr[$r->getName()][] = self::xml2array($r);
+ $data[] = $subitem;
}
}
}
- return $arr;
+ return [$name => $data];
}
/**
@@ -190,4 +250,107 @@ public function anyXmlToArray($xml) {
return self::xml2array(is_string($xml) ? simplexml_load_string($xml) : $xml);
}
+ /**
+ * Convert XML to Array
+ *
+ * @param string $xml
+ * @param array $alwaysArrayElements
+ *
+ * @return array
+ */
+ public static function parse($xml, array $alwaysArrayElements) {
+ $xmlNode = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
+ $arrayData = self::xmlToArray($xmlNode, array(
+ 'alwaysArray' => $alwaysArrayElements,
+ 'autoText' => false,
+ ));
+
+ return $arrayData;
+ }
+
+ /**
+ * @param \SimpleXMLElement $xml
+ * @param array $options
+ *
+ * @return array
+ *
+ * @author Tamlyn Rhodes
+ * @link http://outlandish.com/blog/xml-to-json/
+ */
+ public static function xmlToArray(\SimpleXMLElement $xml, $options = array()) {
+ $defaults = array(
+ 'namespaceSeparator' => ':', //you may want this to be something other than a colon
+ 'attributePrefix' => '@', //to distinguish between attributes and nodes with the same name
+ 'alwaysArray' => array(), //array of xml tag names which should always become arrays
+ 'autoArray' => true, //only create arrays for tags which appear more than once
+ 'textContent' => '$', //key used for the text content of elements
+ 'autoText' => true, //skip textContent key if node has no attributes or child nodes
+ 'keySearch' => false, //optional search and replace on tag and attribute names
+ 'keyReplace' => false //replace values for above search values (as passed to str_replace())
+ );
+ $options = array_merge($defaults, $options);
+ $namespaces = $xml->getDocNamespaces();
+ $namespaces[''] = null; //add base (empty) namespace
+ //get attributes from all namespaces
+ $attributesArray = array();
+ foreach ($namespaces as $prefix => $namespace) {
+ foreach ($xml->attributes($namespace) as $attributeName => $attribute) {
+ //replace characters in attribute name
+ if ($options['keySearch'])
+ $attributeName = str_replace($options['keySearch'], $options['keyReplace'], $attributeName);
+ $attributeKey = $options['attributePrefix']
+ . ($prefix ? $prefix . $options['namespaceSeparator'] : '')
+ . $attributeName;
+ $attributesArray[$attributeKey] = (string) $attribute;
+ }
+ }
+
+ //get child nodes from all namespaces
+ $tagsArray = array();
+ foreach ($namespaces as $prefix => $namespace) {
+ foreach ($xml->children($namespace) as $childXml) {
+ //recurse into child nodes
+ $childArray = self::xmlToArray($childXml, $options);
+ $childTagName = key($childArray);
+ $childProperties = current($childArray);
+
+ //list($childTagName, $childProperties) = each($childArray);
+ //replace characters in tag name
+ if ($options['keySearch'])
+ $childTagName = str_replace($options['keySearch'], $options['keyReplace'], $childTagName);
+ //add namespace prefix, if any
+ if ($prefix)
+ $childTagName = $prefix . $options['namespaceSeparator'] . $childTagName;
+
+ if (!isset($tagsArray[$childTagName])) {
+ //only entry with this key
+ //test if tags of this type should always be arrays, no matter the element count
+ $tagsArray[$childTagName] = in_array($childTagName, $options['alwaysArray']) || !$options['autoArray'] ? array($childProperties) : $childProperties;
+ } elseif (
+ is_array($tagsArray[$childTagName]) && array_keys($tagsArray[$childTagName]) === range(0, count($tagsArray[$childTagName]) - 1)
+ ) {
+ //key already exists and is integer indexed array
+ $tagsArray[$childTagName][] = $childProperties;
+ } else {
+ //key exists so convert to integer indexed array with previous value in position 0
+ $tagsArray[$childTagName] = array($tagsArray[$childTagName], $childProperties);
+ }
+ }
+ }
+
+ //get text content of node
+ $textContentArray = array();
+ $plainText = trim((string) $xml);
+ if ($plainText !== '')
+ $textContentArray[$options['textContent']] = $plainText;
+
+ //stick it all together
+ $propertiesArray = !$options['autoText'] || $attributesArray || $tagsArray || ($plainText === '') ? array_merge($attributesArray, $tagsArray, $textContentArray) : $plainText;
+
+ //return node as array
+ return array(
+ $xml->getName() => $propertiesArray
+ );
+ }
+
}
diff --git a/tests/.env b/tests/.env
index 224b645..a2a2e99 100644
--- a/tests/.env
+++ b/tests/.env
@@ -3,6 +3,7 @@ EASE_LOGGER=console|syslog
POHODA_URL=http://10.11.25.23:2323
POHODA_USERNAME=api
POHODA_PASSWORD=api
-POHODA_ICO=02745976
+POHODA_ICO=12345678
+
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 0000000..159eb4f
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,12 @@
+
+ * @copyright 2015-2020 Spoje.Net
+ */
+
+require_once file_exists('../vendor/autoload.php') ? '../vendor/autoload.php' : 'vendor/autoload.php';
+
+\Ease\Shared::instanced()->loadConfig(__DIR__ . '/.env',true);
diff --git a/tests/insert-address.php b/tests/insert-address.php
index 6c89fbc..643de9a 100644
--- a/tests/insert-address.php
+++ b/tests/insert-address.php
@@ -11,8 +11,6 @@
require_once __DIR__ . '/../vendor/autoload.php';
-
-
$addressBookRecord = [
'GPS' => '', // GPS souřadnice.
'ICQ' => '', // ICQ adresa.
@@ -45,8 +43,6 @@
// 'exSystemName' => 'appslug',
// 'exSystemText' => 'app name'
// ], //
-
-
'shipToAddress' => [// Dodací adresa.
// 'actionType' => '', //Typ práce s dodací adresou. Výchozí hodnota je přidání nového dodací adresy.
// 'extId' => '', //
@@ -82,12 +78,6 @@
'web' => 'https://www.vitexsoftware.cz', //Adresa www stránek.
];
-
-
-
-
-
$addresser = new Adressbook($addressBookRecord, \Ease\Shared::instanced()->loadConfig(__DIR__ . '/.env'));
-$addresser->insertToPohoda();
-
+$addresser->addToPohoda();
diff --git a/tests/insert-invoice.php b/tests/insert-invoice.php
index 71ecc7d..65b3f9a 100644
--- a/tests/insert-invoice.php
+++ b/tests/insert-invoice.php
@@ -96,7 +96,7 @@
$invoicer->addItem($itemRecord);
-$invoicer->insertToPohoda();
+$invoicer->addToPohoda();
$invoicer->getIDS();
diff --git a/tests/src/mServer/AdressbookTest.php b/tests/src/mServer/AdressbookTest.php
new file mode 100644
index 0000000..3da81f5
--- /dev/null
+++ b/tests/src/mServer/AdressbookTest.php
@@ -0,0 +1,43 @@
+object = new Adressbook();
+ }
+
+ /**
+ * Tears down the fixture, for example, closes a network connection.
+ * This method is called after a test is executed.
+ */
+ protected function tearDown(): void {
+
+ }
+
+ /**
+ * @covers mServer\Adressbook::create
+ * @todo Implement testcreate().
+ */
+ public function testcreate() {
+ $this->assertEquals('', $this->object->create());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+}
diff --git a/tests/src/mServer/ClientTest.php b/tests/src/mServer/ClientTest.php
new file mode 100644
index 0000000..458ee44
--- /dev/null
+++ b/tests/src/mServer/ClientTest.php
@@ -0,0 +1,209 @@
+object = new Client();
+ }
+
+ /**
+ * Tears down the fixture, for example, closes a network connection.
+ * This method is called after a test is executed.
+ */
+ protected function tearDown(): void {
+
+ }
+
+ /**
+ * @covers mServer\Client::processInit
+ * @todo Implement testprocessInit().
+ */
+ public function testprocessInit() {
+ $this->assertEquals('', $this->object->processInit());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::logBanner
+ */
+ public function testlogBanner() {
+ $this->object->logBanner();
+ }
+
+ /**
+ * @covers mServer\Client::setUp
+ */
+ public function testsetUp() {
+ $this->object->setUp(['url' => 'http://localhost:12345']);
+ $this->assertEquals('http://localhost:12345', $this->object->url);
+ }
+
+ /**
+ * @covers mServer\Client::setAuth
+ */
+ public function testsetAuth() {
+ $this->assertTrue($this->object->setAuth());
+ }
+
+ /**
+ * @covers mServer\Client::setInstance
+ * @todo Implement testsetInstance().
+ */
+ public function testsetInstance() {
+ $this->assertEquals('', $this->object->setInstance());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::setApplication
+ * @todo Implement testsetApplication().
+ */
+ public function testsetApplication() {
+ $this->assertEquals('', $this->object->setApplication());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::setCheckDuplicity
+ * @todo Implement testsetCheckDuplicity().
+ */
+ public function testsetCheckDuplicity() {
+ $this->assertEquals('', $this->object->setCheckDuplicity());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::curlInit
+ */
+ public function testcurlInit() {
+ $this->assertTrue($this->object->curlInit());
+ }
+
+ /**
+ * @covers mServer\Client::setPostFields
+ */
+ public function testsetPostFields() {
+ $this->object->setPostFields(['test']);
+ $this->assertEquals(['test'], $this->object->postFields,);
+ }
+
+ /**
+ * @covers mServer\Client::doCurlRequest
+ * @todo Implement testdoCurlRequest().
+ */
+ public function testdoCurlRequest() {
+ $this->assertEquals('', $this->object->doCurlRequest());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::performRequest
+ * @todo Implement testperformRequest().
+ */
+ public function testperformRequest() {
+ $this->assertEquals('', $this->object->performRequest());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::processResponse
+ * @todo Implement testprocessResponse().
+ */
+ public function testprocessResponse() {
+ $this->assertEquals('', $this->object->processResponse());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::getStatus
+ */
+ public function testgetStatus() {
+ $this->assertTrue($this->object->getStatus());
+ }
+
+ /**
+ * @covers mServer\Client::takeData
+ */
+ public function testtakeData() {
+ $this->object->takeData(['test' => 'true'], true);
+ $this->assertEquals(['test' => 'true'], $this->object->getData());
+ }
+
+ /**
+ * @covers mServer\Client::create
+ * @todo Implement testcreate().
+ */
+ public function testcreate() {
+ $this->assertEquals('', $this->object->create());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::addToPohoda
+ * @todo Implement testaddToPohoda().
+ */
+ public function testaddToPohoda() {
+ $this->assertEquals('', $this->object->addToPohoda());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::updateInPohoda
+ * @todo Implement testupdateInPohoda().
+ */
+ public function testupdateInPohoda() {
+ $this->assertEquals('', $this->object->updateInPohoda());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::filterToMe
+ */
+ public function testfilterToMe() {
+ $this->assertEquals('id', $this->object->filterToMe());
+ }
+
+ /**
+ * @covers mServer\Client::getColumnsFromPohoda
+ * @todo Implement testgetColumnsFromPohoda().
+ */
+ public function testgetColumnsFromPohoda() {
+ $this->assertEquals('', $this->object->getColumnsFromPohoda());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Client::__wakeup
+ */
+ public function test__wakeup() {
+ $this->assertEquals('', $this->object->__wakeup());
+ }
+
+}
diff --git a/tests/src/mServer/InvoiceTest.php b/tests/src/mServer/InvoiceTest.php
new file mode 100644
index 0000000..fd05ea8
--- /dev/null
+++ b/tests/src/mServer/InvoiceTest.php
@@ -0,0 +1,63 @@
+object = new Invoice();
+ }
+
+ /**
+ * Tears down the fixture, for example, closes a network connection.
+ * This method is called after a test is executed.
+ */
+ protected function tearDown(): void {
+
+ }
+
+ /**
+ * @covers mServer\Invoice::create
+ * @todo Implement testcreate().
+ */
+ public function testcreate() {
+ $this->assertEquals('', $this->object->create());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Invoice::addItem
+ * @todo Implement testaddItem().
+ */
+ public function testaddItem() {
+ $this->assertEquals('', $this->object->addItem());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Invoice::extId
+ * @todo Implement testextId().
+ */
+ public function testextId() {
+ $this->assertEquals('', $this->object->extId());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+}
diff --git a/tests/src/mServer/ResponseTest.php b/tests/src/mServer/ResponseTest.php
new file mode 100644
index 0000000..bcbcc24
--- /dev/null
+++ b/tests/src/mServer/ResponseTest.php
@@ -0,0 +1,193 @@
+object = new Response();
+ }
+
+ /**
+ * Tears down the fixture, for example, closes a network connection.
+ * This method is called after a test is executed.
+ */
+ protected function tearDown(): void {
+
+ }
+
+ /**
+ * @covers mServer\Response::useCaller
+ * @todo Implement testuseCaller().
+ */
+ public function testuseCaller() {
+ $this->assertEquals('', $this->object->useCaller());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::processResponsePack
+ * @todo Implement testprocessResponsePack().
+ */
+ public function testprocessResponsePack() {
+ $this->assertEquals('', $this->object->processResponsePack());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::processResponsePackItem
+ * @todo Implement testprocessResponsePackItem().
+ */
+ public function testprocessResponsePackItem() {
+ $this->assertEquals('', $this->object->processResponsePackItem());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::processProducedDetails
+ * @todo Implement testprocessProducedDetails().
+ */
+ public function testprocessProducedDetails() {
+ $this->assertEquals('', $this->object->processProducedDetails());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::processImportDetails
+ * @todo Implement testprocessImportDetails().
+ */
+ public function testprocessImportDetails() {
+ $this->assertEquals('', $this->object->processImportDetails());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::processResponseData
+ * @todo Implement testprocessResponseData().
+ */
+ public function testprocessResponseData() {
+ $this->assertEquals('', $this->object->processResponseData());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::typesToArray
+ * @todo Implement testtypesToArray().
+ */
+ public function testtypesToArray() {
+ $this->assertEquals('', $this->object->typesToArray());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::typeToArray
+ * @todo Implement testtypeToArray().
+ */
+ public function testtypeToArray() {
+ $this->assertEquals('', $this->object->typeToArray());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::getNote
+ * @todo Implement testgetNote().
+ */
+ public function testgetNote() {
+ $this->assertEquals('', $this->object->getNote());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::isOk
+ * @todo Implement testisOk().
+ */
+ public function testisOk() {
+ $this->assertEquals('', $this->object->isOk());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::getState
+ * @todo Implement testgetState().
+ */
+ public function testgetState() {
+ $this->assertEquals('', $this->object->getState());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::getAgendaData
+ * @todo Implement testgetAgendaData().
+ */
+ public function testgetAgendaData() {
+ $this->assertEquals('', $this->object->getAgendaData());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::prepareElement
+ * @todo Implement testprepareElement().
+ */
+ public function testprepareElement() {
+ $this->assertEquals('', $this->object->prepareElement());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::anyXmlToArray
+ * @todo Implement testanyXmlToArray().
+ */
+ public function testanyXmlToArray() {
+ $this->assertEquals('', $this->object->anyXmlToArray());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::parse
+ * @todo Implement testparse().
+ */
+ public function testparse() {
+ $this->assertEquals('', $this->object->parse());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+ /**
+ * @covers mServer\Response::xmlToArray
+ * @todo Implement testxmlToArray().
+ */
+ public function testxmlToArray() {
+ $this->assertEquals('', $this->object->xmlToArray());
+ // Remove the following lines when you implement this test.
+ $this->markTestIncomplete('This test has not been implemented yet.');
+ }
+
+}
diff --git a/tests/update-address.php b/tests/update-address.php
new file mode 100644
index 0000000..5060169
--- /dev/null
+++ b/tests/update-address.php
@@ -0,0 +1,85 @@
+
+ * @copyright (C) 2020 Vitex Software
+ */
+
+namespace mServer;
+
+require_once __DIR__ . '/../vendor/autoload.php';
+
+$extID = 234;
+
+$addressBookRecord = [
+ 'GPS' => '', // GPS souřadnice.
+ 'ICQ' => '', // ICQ adresa.
+ 'Skype' => '', // Skype adresa.
+ 'activity' => '', // Činnost.
+ 'agreement' => '', // Číslo obchodní smlouvy (nesmí být povoleno v Globálním nastavení - Číslování zákazníků).
+ 'centre' => '', // Středisko.
+ 'contract' => '', // Zakázka.
+ 'credit' => '', // Kredit, tolerovaná výše pohledávek odběratele.
+ 'email' => '', // Email.
+ 'fax' => '', // Fax.
+ 'identity' => [// Základní údaje
+// 'id' => '', //
+ 'address' => [// Adresa.
+ 'company' => 'Vitex Software', //
+ 'division' => '', //
+ 'name' => 'Vítězslav Dvořák', //
+ 'city' => 'Prague', //
+ 'street' => 'Long', //
+ 'zip' => '15800', //
+ 'ico' => '69438676', //
+ 'dic' => 'CZ7808072811', //
+ 'VATPayerType' => '', //Typ plátce DPH: payer Plátce DPH., non-payer Neplátce DPH., "" Neuvedeno (výchozí hodnota)
+ 'icDph' => '', //
+ 'country' => '', //
+ ], //
+ 'addressLinkToAddress' => '', //
+// 'extId' => [
+// 'ids' => 'EXT-001',
+// 'exSystemName' => 'appslug',
+// 'exSystemText' => 'app name'
+// ], //
+ 'shipToAddress' => [// Dodací adresa.
+// 'actionType' => '', //Typ práce s dodací adresou. Výchozí hodnota je přidání nového dodací adresy.
+// 'extId' => '', //
+ 'company' => '', //
+ 'division' => '', //
+ 'name' => '', //
+ 'city' => '', //
+ 'street' => '', //
+ 'zip' => '', //
+ 'country' => '', //
+ 'defaultShipAddress' => '', //Výchozí dodací adresa.
+ ],
+ ],
+ 'intNote' => 'maybe duplicated', // Interní poznámka.
+ 'maturity' => '', // Splatno. Počet dnů splatnosti faktur. Při vložení adresy do faktury se nastaví datum splatnosti přičtením zde uvedeného počtu dnů k datu vystavení faktury.
+ 'message' => 'message for ', // Zpráva.
+ 'mobil' => '739 778 202', // Mobil.
+ 'note' => 'note', // Poznámka.
+ 'number' => '', // Číslo dodavatele/odběratele dle zvolené číselné řady (musí být povoleno v Globálním nastavení - Číslování zákazníků).
+ 'ost1' => '', // Ostatní.
+ 'ost2' => '', // Ostatní. Používá se také u kontaktní osoby.
+// 'funkce' => '', //Název funkce. Používá se jen u kontaktní osoby.
+ 'p1' => false, // Klíč P1 / Dodavatel.
+ 'p2' => true, // Klíč P2 / Odběratel.
+ 'p3' => false, // Klíč P3.
+ 'p4' => false, // Klíč P4.
+ 'p5' => false, // Klíč P5.
+ 'p6' => false, // Klíč P6.
+// 'paymentType' => 'cash', // Forma úhrady: draft, cash, postal, delivery, creditcard, advance, encashment, cheque, compensation
+ 'phone' => '', // Telefon.
+ 'priceIDS' => '', // Cenová hladina odběratele.
+ 'region' => '', // Název kraje.
+ 'web' => 'https://www.vitexsoftware.cz', //Adresa www stránek.
+];
+
+$addresser = new Adressbook($addressBookRecord, \Ease\Shared::instanced()->loadConfig(__DIR__ . '/.env'));
+$addresser->updateInPohoda(null, ['extId' => ['exSystemName' => \Ease\Functions::cfg('APP_NAME'), 'ids' => strval($extID)]]);
+