├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── examples ├── example_credentials.php ├── files │ └── empty ├── loader.php ├── messages.php ├── orders.php ├── products.php ├── stock.php └── upload.php ├── phpcs.xml ├── src ├── Base │ └── Iterator.php ├── Client.php ├── Client │ └── Rest.php ├── Message │ ├── Handler.php │ ├── Model │ │ └── Message.php │ ├── Tbmessage │ │ └── Iterator.php │ └── Tbmessagelist.php ├── Order │ ├── Handler.php │ ├── Model │ │ ├── Customer.php │ │ ├── History.php │ │ ├── Item.php │ │ └── Order.php │ ├── Tborder │ │ └── Iterator.php │ └── Tborderlist.php ├── Product │ ├── Handler.php │ ├── Model │ │ ├── Article.php │ │ └── Product.php │ ├── Tbcat.php │ └── Tbcat │ │ └── Iterator.php ├── Stock │ ├── Handler.php │ ├── Model │ │ ├── Stock.php │ │ └── StockUpdate.php │ ├── Tbstock.php │ └── Tbstock │ │ └── Iterator.php └── Upload │ └── Handler.php └── tests ├── Base.php ├── Message └── MessageTest.php ├── Order └── OrderTest.php ├── Product └── ProductTest.php ├── Stock ├── StockListTest.php └── StockUpdateTest.php └── files ├── catalog.xml ├── message.xml ├── messagelist.xml ├── order.xml ├── product.xml └── stock.xml /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | 4 | jobs: 5 | build-test: 6 | runs-on: ubuntu-latest 7 | strategy: 8 | matrix: 9 | php-versions: ['7.4.*', '8.0.*', '8.1.*', '8.2.*', '8.3.*'] 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Setup PHP 13 | uses: shivammathur/setup-php@v2 14 | with: 15 | php-version: ${{ matrix.php-versions }} 16 | - name: Install dependencies 17 | run: composer install 18 | - name: Run PSR check on src 19 | run: vendor/bin/phpcs src 20 | - name: Run PSR check on tests 21 | run: vendor/bin/phpcs tests 22 | - name: Run Unit tests 23 | run: vendor/bin/phpunit tests 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .idea 3 | composer.lock 4 | composer.phar 5 | examples/credentials.php 6 | examples/files 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Dominik Meyer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tradebyte SDK 2 | 3 | An SDK that provides multiple ways to interact with the Tradebyte API. For more information, visit [TB.IO](https://tradebyte.io). 4 | 5 | ## Features 6 | 7 | * **Memory Efficiency:** The SDK is designed to consume minimal memory and can efficiently process large XML files - potentially gigabytes in size - through extensive use of iterators and XML readers. 8 | * **Flexible Processing:** Depending on your needs, you can process data "on the fly" or opt for a "download and re-open" approach. 9 | * **Supported Entities:** The SDK supports several entities with multiple endpoints, including: product, order, message, stock, upload 10 | 11 | ## Requirements 12 | 13 | * Credentials (username, password, account-number) 14 | * See https://tb-io.tradebyte.org/how-to/generate-rest-api-credentials-in-tb-one/ for details. 15 | * PHP >= 7.4 16 | * Composer 17 | * cURL 18 | 19 | ## Installation 20 | 21 | 1. download composer (https://getcomposer.org/download) 22 | 2. execute the following: 23 | 24 | ```bash 25 | $ composer require kinimodmeyer/tradebyte-sdk 26 | ``` 27 | 28 | ## Quick Example (message) 29 | 30 | ```php 31 | //only needed if not already included 32 | require './vendor/autoload.php'; 33 | 34 | $client = new Tradebyte\Client([ 35 | 'credentials' => [ 36 | 'account_number' => '', 37 | 'account_user' => '', 38 | 'account_password' => '' 39 | ] 40 | ]); 41 | 42 | //different handler can be used here 43 | $messageHandler = $client->getMessageHandler(); 44 | 45 | //fetch message with message-identifier 5 46 | var_dump($messageHandler->getMessage(5)->getId()); 47 | 48 | //or download/reopen message 49 | $messageHandler->downloadMessage(__DIR__.'/message_5.xml', 5); 50 | var_dump($messageHandler->getMessageFromFile(__DIR__.'/message_5.xml')); 51 | 52 | //see also the other possible methods on the handler for list-handling, acknowledge an many more ... 53 | ``` 54 | 55 | ## Example Files 56 | 57 | Copy the ``vendor/kinimodmeyer/tradebyte-sdk/examples/`` folder to your project-root. 58 | Rename ``examples/example_credentials.php`` to ``examples/credentials.php`` and replace the credentials. 59 | Execute the examples from the cli: 60 | 61 | ```bash 62 | $ php examples/products.php channel=1370 id=123 63 | $ php examples/orders.php 64 | $ php examples/messages.php 65 | $ php examples/stock.php channel=1370 delta=123 66 | ``` 67 | 68 | ## Tests 69 | 70 | Execute the test with the following: 71 | 72 | ```bash 73 | $ ./vendor/bin/phpunit tests 74 | ``` 75 | 76 | ## Code Analysis 77 | 78 | Execute the analysis with the following: 79 | 80 | ```bash 81 | $ ./vendor/bin/phpcs src 82 | $ ./vendor/bin/phpcs tests 83 | ``` 84 | 85 | Fix (if possible) with the following: 86 | 87 | ```bash 88 | $ ./vendor/bin/phpcbf src 89 | $ ./vendor/bin/phpcbf tests 90 | ``` 91 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kinimodmeyer/tradebyte-sdk", 3 | "type": "library", 4 | "description": "Tradebyte SDK", 5 | "homepage": "https://github.com/kinimodmeyer/tradebyte-sdk-php", 6 | "license": "MIT", 7 | "autoload": { 8 | "psr-4": { 9 | "Tradebyte\\": "src/" 10 | } 11 | }, 12 | "autoload-dev": { 13 | "psr-4": { 14 | "Tradebyte\\": "tests/" 15 | } 16 | }, 17 | "require-dev": { 18 | "phpunit/phpunit": "^9", 19 | "squizlabs/php_codesniffer": "3.*" 20 | }, 21 | "require": { 22 | "php": "7.4.* || 8.0.* || 8.1.* || 8.2.* || 8.3.*", 23 | "ext-xmlreader": "*", 24 | "ext-simplexml": "*", 25 | "ext-xmlwriter": "*", 26 | "ext-curl": "*" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/example_credentials.php: -------------------------------------------------------------------------------- 1 | 'XXXX', 5 | 'account_user' => 'XXX', 6 | 'account_password' => 'XXX' 7 | ]; 8 | -------------------------------------------------------------------------------- /examples/files/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinimodmeyer/tradebyte-sdk-php/f78142a056fa19820c293fdccc792aa02a2c85b3/examples/files/empty -------------------------------------------------------------------------------- /examples/loader.php: -------------------------------------------------------------------------------- 1 | $credentials]); 6 | $messageHandler = $client->getMessageHandler(); 7 | $params = []; 8 | 9 | /* 10 | * on the fly mode 11 | */ 12 | $messageList = $messageHandler->getMessageList($params); 13 | 14 | foreach ($messageList->getMessages() as $message) { 15 | echo $message->getId(); 16 | 17 | /* 18 | * acknowledge message received. 19 | * 20 | * try { 21 | * $messageHandler->updateMessageExported($message->getId()); 22 | * } catch (Exception $e) { 23 | * echo $e->getMessage(); 24 | * } 25 | */ 26 | } 27 | 28 | $messageList->close(); 29 | 30 | /* 31 | * download mode 32 | */ 33 | $messageHandler->downloadMessageList(__DIR__ . '/files/messages.xml', $params); 34 | $messageList = $messageHandler->getMessageListFromFile(__DIR__ . '/files/messages.xml'); 35 | 36 | foreach ($messageList->getMessages() as $message) { 37 | echo $message->getId(); 38 | } 39 | 40 | $messageList->close(); 41 | 42 | /* 43 | $message = (new Tradebyte\Message\Model\Message()) 44 | ->setType('SHIP') 45 | ->setOrderId(26) 46 | ->setOrderItemId(34) 47 | ->setQuantity(1); 48 | $messageHandler->addMessages([$message]); 49 | */ 50 | -------------------------------------------------------------------------------- /examples/orders.php: -------------------------------------------------------------------------------- 1 | $credentials]); 6 | $orderHandler = $client->getOrderHandler(); 7 | 8 | /* 9 | * on the fly mode 10 | */ 11 | $orderList = $orderHandler->getOrderList($filter); 12 | 13 | foreach ($orderList->getOrders() as $order) { 14 | echo $order->getId(); 15 | 16 | /* 17 | * acknowledge order received. 18 | * 19 | * try { 20 | * $orderHandler->updateOrderExported($order->getId()); 21 | * } catch (Exception $e) { 22 | * echo $e->getMessage(); 23 | * } 24 | */ 25 | } 26 | 27 | $orderList->close(); 28 | 29 | /* 30 | * download mode 31 | */ 32 | $orderHandler->downloadOrderList(__DIR__ . '/files/orders.xml', $filter); 33 | $orderList = $orderHandler->getOrderListFromFile(__DIR__ . '/files/orders.xml'); 34 | 35 | foreach ($orderList->getOrders() as $order) { 36 | echo $order->getId(); 37 | } 38 | 39 | $orderList->close(); 40 | 41 | /* 42 | if (!empty($filter['channel'])) { 43 | $orderHandler->updateOrder( 44 | $filter['channel'], 45 | (new Tradebyte\Order\Model\Order()) 46 | ->setId('12345') 47 | ->setOrderDate('2018-11-07') 48 | ->setChannelId('test0898418712') 49 | ->setChannelNumber('test0898418712') 50 | ->setIsApproved(true) 51 | ->setChannelSign('cuonerefe1') 52 | ->setItemCount(1) 53 | ->setTotalItemAmount(1.0) 54 | ->setShipTo((new \Tradebyte\Order\Model\Customer()) 55 | ->setFirstname('Test') 56 | ->setLastname('Test') 57 | ->setStreetNumber('Test Street') 58 | ->setCity('Test City') 59 | ->setZip('12345') 60 | ->setCountry('DE')) 61 | ->setItems([(new \Tradebyte\Order\Model\Item()) 62 | ->setChannelId('123') 63 | ->setSku('123') 64 | ->setQuantity(1) 65 | ->setItemPrice(20.0)]) 66 | ); 67 | } 68 | */ 69 | -------------------------------------------------------------------------------- /examples/products.php: -------------------------------------------------------------------------------- 1 | $credentials]); 6 | $productHandler = $client->getProductHandler(); 7 | 8 | if (isset($filter['id'])) { 9 | echo $productHandler->getProduct($filter['id'], $filter['channel'])->getId(); 10 | $productHandler->downloadProduct( 11 | __DIR__ . '/files/product_' . $filter['id'] . '.xml', 12 | $filter['id'], 13 | $filter['channel'] 14 | ); 15 | echo $productHandler->getProductFromFile(__DIR__ . '/files/product_' . $filter['id'] . '.xml')->getId(); 16 | } else { 17 | /* 18 | * on the fly mode 19 | */ 20 | $catalog = $productHandler->getCatalog(['channel' => $filter['channel']]); 21 | echo $catalog->getSupplierName(); 22 | 23 | foreach ($catalog->getProducts() as $product) { 24 | echo $product->getId(); 25 | } 26 | 27 | $catalog->close(); 28 | 29 | /* 30 | * download mode 31 | */ 32 | $productHandler->downloadCatalog(__DIR__ . '/files/products.xml', ['channel' => $filter['channel']]); 33 | $catalog = $productHandler->getCatalogFromFile(__DIR__ . '/files/products.xml'); 34 | echo $catalog->getSupplierName(); 35 | 36 | foreach ($catalog->getProducts() as $product) { 37 | echo $product->getId(); 38 | } 39 | 40 | $catalog->close(); 41 | } 42 | -------------------------------------------------------------------------------- /examples/stock.php: -------------------------------------------------------------------------------- 1 | $credentials]); 6 | $stockHandler = $client->getStockHandler(); 7 | $params = [ 'channel' => $filter['channel'], 'delta' => $filter['delta']]; 8 | 9 | /* 10 | * on the fly mode 11 | */ 12 | $catalog = $stockHandler->getStockList($params); 13 | echo $catalog->getChangeDate(); 14 | 15 | foreach ($catalog->getStock() as $stock) { 16 | echo $stock->getStock(); 17 | } 18 | 19 | $catalog->close(); 20 | 21 | /* 22 | * download mode 23 | */ 24 | $stockHandler->downloadStockList(__DIR__ . '/files/stock.xml', $params); 25 | $catalog = $stockHandler->getStockListFromFile(__DIR__ . '/files/stock.xml'); 26 | echo $catalog->getChangeDate(); 27 | 28 | foreach ($catalog->getStock() as $stock) { 29 | echo $stock->getStock(); 30 | } 31 | 32 | $catalog->close(); 33 | 34 | /* 35 | * one centralised warehouse 36 | */ 37 | $stockHandler->updateStock([ 38 | (new Tradebyte\Stock\Model\StockUpdate()) 39 | ->setArticleNumber('12345') 40 | ->setStock(6) 41 | ]); 42 | 43 | /* 44 | * several warehouses 45 | */ 46 | $stockHandler->updateStock([ 47 | (new Tradebyte\Stock\Model\StockUpdate()) 48 | ->setArticleNumber('12345') 49 | ->addStockForWarehouse('zentrallager', 10) 50 | ->addStockForWarehouse('aussenlager', 5) 51 | ]); -------------------------------------------------------------------------------- /examples/upload.php: -------------------------------------------------------------------------------- 1 | $credentials]); 6 | $uploadHandler = $client->getUploaderHandler(); 7 | $uploadHandler->uploadFile(__DIR__ . '/files/upload.xml', 'test2.xml'); 8 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | The coding standard for Tradebyte SDK. 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Base/Iterator.php: -------------------------------------------------------------------------------- 1 | client = $client; 29 | $this->url = $url; 30 | $this->filter = $filter; 31 | } 32 | 33 | public function setOpenLocalFilepath(bool $openLocalFilepath): void 34 | { 35 | $this->openLocalFilepath = $openLocalFilepath; 36 | } 37 | 38 | public function key(): int 39 | { 40 | return $this->i; 41 | } 42 | 43 | public function rewind(): void 44 | { 45 | $this->i = 0; 46 | $this->isOpen = false; 47 | $this->open(); 48 | $this->next(); 49 | } 50 | 51 | public function getIsOpen(): bool 52 | { 53 | return $this->isOpen; 54 | } 55 | 56 | public function close(): void 57 | { 58 | $this->xmlReader->close(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | options = $options; 28 | $restClient = new Client\Rest(); 29 | 30 | if (isset($this->options['credentials'])) { 31 | $restClient->setAccountNumber((int)$this->options['credentials']['account_number']); 32 | $restClient->setAccountUser($this->options['credentials']['account_user']); 33 | $restClient->setAccountPassword($this->options['credentials']['account_password']); 34 | } 35 | 36 | if (!empty($this->options['base_url'])) { 37 | $restClient->setBaseURL($this->options['base_url']); 38 | } 39 | 40 | $this->setRestClient($restClient); 41 | } 42 | 43 | /** 44 | * @return Client\Rest 45 | */ 46 | public function getRestClient() 47 | { 48 | return $this->restClient; 49 | } 50 | 51 | /** 52 | * @param Client\Rest $client 53 | * @return void 54 | */ 55 | public function setRestClient(Client\Rest $client): void 56 | { 57 | $this->restClient = $client; 58 | } 59 | 60 | /** 61 | * @return Order\Handler 62 | */ 63 | public function getOrderHandler(): Order\Handler 64 | { 65 | return new Order\Handler($this); 66 | } 67 | 68 | /** 69 | * @return Upload\Handler 70 | */ 71 | public function getUploaderHandler(): Upload\Handler 72 | { 73 | return new Upload\Handler($this); 74 | } 75 | 76 | /** 77 | * @return Message\Handler 78 | */ 79 | public function getMessageHandler(): Message\Handler 80 | { 81 | return new Message\Handler($this); 82 | } 83 | 84 | /** 85 | * @return Product\Handler 86 | */ 87 | public function getProductHandler(): Product\Handler 88 | { 89 | return new Product\Handler($this); 90 | } 91 | 92 | /** 93 | * @return Stock\Handler 94 | */ 95 | public function getStockHandler(): Stock\Handler 96 | { 97 | return new Stock\Handler($this); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Client/Rest.php: -------------------------------------------------------------------------------- 1 | accountNumber = $number; 24 | } 25 | 26 | public function setAccountUser(string $user): void 27 | { 28 | $this->accountUser = $user; 29 | } 30 | 31 | public function setAccountPassword(string $password): void 32 | { 33 | $this->accountPassword = $password; 34 | } 35 | 36 | public function setBaseURL(string $baseURL): void 37 | { 38 | $this->baseURL = $baseURL; 39 | } 40 | 41 | private function getAuthHeader(): string 42 | { 43 | $auth = base64_encode($this->accountUser . ':' . $this->accountPassword); 44 | return 'Authorization: Basic ' . $auth; 45 | } 46 | 47 | private function getCreatedURI(string $url, array $filter = []): string 48 | { 49 | $uri = $this->baseURL . '/' . $this->accountNumber . '/' . $url; 50 | 51 | if (!empty($filter)) { 52 | $uri .= '?' . http_build_query($filter); 53 | } 54 | 55 | return $uri; 56 | } 57 | 58 | private function getStatusCode(string $statusLine): int 59 | { 60 | preg_match('{HTTP\/\S*\s(\d{3})}', $statusLine, $match); 61 | return (int)$match[1]; 62 | } 63 | 64 | public function uploadFile(string $localFilePath, string $url): string 65 | { 66 | $localHandle = fopen($localFilePath, 'r'); 67 | $curl = curl_init($this->getCreatedURI($url, [])); 68 | curl_setopt($curl, CURLOPT_PUT, true); 69 | curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 70 | curl_setopt($curl, CURLOPT_USERPWD, $this->accountUser . ':' . $this->accountPassword); 71 | curl_setopt($curl, CURLOPT_INFILE, $localHandle); 72 | curl_setopt($curl, CURLOPT_INFILESIZE, filesize($localFilePath)); 73 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 74 | curl_setopt($curl, CURLOPT_FAILONERROR, true); 75 | curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3600); 76 | $response = (string)curl_exec($curl); 77 | fclose($localHandle); 78 | curl_close($curl); 79 | 80 | return $response; 81 | } 82 | 83 | public function postXMLFile(string $localFilePath, string $url): string 84 | { 85 | $localHandle = fopen($localFilePath, 'r'); 86 | $curl = curl_init($this->getCreatedURI($url, [])); 87 | curl_setopt($curl, CURLOPT_PUT, true); 88 | curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); 89 | curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 90 | curl_setopt($curl, CURLOPT_USERPWD, $this->accountUser . ':' . $this->accountPassword); 91 | curl_setopt($curl, CURLOPT_INFILE, $localHandle); 92 | curl_setopt($curl, CURLOPT_INFILESIZE, filesize($localFilePath)); 93 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 94 | curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3600); 95 | $response = (string)curl_exec($curl); 96 | fclose($localHandle); 97 | curl_close($curl); 98 | 99 | return $response; 100 | } 101 | 102 | public function downloadFile(string $localFilePath, string $url, array $filter = []): bool 103 | { 104 | $context = [ 105 | 'http' => [ 106 | 'header' => $this->getAuthHeader() 107 | . "\r\n" . 'User-Agent: ' . $this->userAgent, 108 | 'ignore_errors' => true, 109 | 'time_out' => 3600, 110 | ] 111 | ]; 112 | 113 | $handle = fopen($this->getCreatedURI($url, $filter), 'rb', false, stream_context_create($context)); 114 | $statusLine = $http_response_header[0]; 115 | 116 | if ($this->getStatusCode($statusLine) !== 200) { 117 | throw new \RuntimeException('unexpected response status: ' . $statusLine); 118 | } 119 | 120 | $localHandle = fopen($localFilePath, 'w+'); 121 | 122 | // 8 mb in one go 123 | $length = 8 * 1024; 124 | 125 | while (!feof($handle)) { 126 | fwrite($localHandle, fread($handle, $length)); 127 | } 128 | 129 | fclose($handle); 130 | fclose($localHandle); 131 | 132 | return true; 133 | } 134 | 135 | public function fileGetContents(string $filename, bool $useIncludePath, array $contextArray): array 136 | { 137 | $content = file_get_contents($filename, $useIncludePath, stream_context_create($contextArray)); 138 | 139 | return [ 140 | 'content' => $content, 141 | 'status_line' => $http_response_header[0] 142 | ]; 143 | } 144 | 145 | public function postXML(string $url, string $postData = ''): string 146 | { 147 | $context = [ 148 | 'http' => [ 149 | 'method' => 'POST', 150 | 'header' => $this->getAuthHeader() 151 | . "\r\n" . 'Content-Type: application/xml' 152 | . "\r\n" . 'Accept: application/xml' 153 | . "\r\n" . 'User-Agent: ' . $this->userAgent, 154 | 'content' => $postData, 155 | 'ignore_errors' => true, 156 | 'time_out' => 3600, 157 | ] 158 | ]; 159 | 160 | $response = $this->fileGetContents($this->getCreatedURI($url, []), false, $context); 161 | $content = $response['content']; 162 | $statusLine = $response['status_line']; 163 | 164 | if (!in_array($this->getStatusCode($statusLine), [200, 201, 204])) { 165 | throw new \RuntimeException($statusLine . ' / ' . $content); 166 | } 167 | 168 | return $content; 169 | } 170 | 171 | public function getXML(string $url, array $filter = []): XMLReader 172 | { 173 | libxml_set_streams_context(stream_context_create([ 174 | 'http' => [ 175 | 'header' => $this->getAuthHeader() 176 | . "\r\n" . 'Accept: application/xml' 177 | . "\r\n" . 'User-Agent: ' . $this->userAgent, 178 | 'ignore_errors' => true, 179 | 'time_out' => 3600, 180 | ] 181 | ])); 182 | 183 | $reader = new XMLReader(); 184 | $reader->open($this->getCreatedURI($url, $filter)); 185 | $statusLine = $http_response_header[0]; 186 | 187 | if ($this->getStatusCode($statusLine) !== 200) { 188 | throw new \RuntimeException('unexpected response status: ' . $statusLine); 189 | } 190 | 191 | return $reader; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/Message/Handler.php: -------------------------------------------------------------------------------- 1 | client = $client; 20 | } 21 | 22 | public function getMessage(int $messageId): Message 23 | { 24 | $catalog = new Tbmessagelist($this->client, 'messages/' . (int)$messageId, []); 25 | $messageIterator = $catalog->getMessages(); 26 | $messageIterator->rewind(); 27 | 28 | return $messageIterator->current(); 29 | } 30 | 31 | public function getMessageFromFile(string $filePath): Message 32 | { 33 | $xmlElement = new SimpleXMLElement(file_get_contents($filePath)); 34 | $model = new Message(); 35 | $model->fillFromSimpleXMLElement($xmlElement); 36 | 37 | return $model; 38 | } 39 | 40 | public function downloadMessage(string $filePath, int $messageId): bool 41 | { 42 | $reader = $this->client->getRestClient()->getXML('messages/' . (int)$messageId, []); 43 | 44 | while ($reader->read()) { 45 | if ( 46 | $reader->nodeType == XMLReader::ELEMENT 47 | && $reader->depth === 1 48 | && $reader->name == 'MESSAGE' 49 | ) { 50 | $filePut = (bool)file_put_contents($filePath, $reader->readOuterXml()); 51 | $reader->close(); 52 | return $filePut; 53 | } 54 | } 55 | 56 | $reader->close(); 57 | 58 | return false; 59 | } 60 | 61 | public function getMessageList(array $filter = []): Tbmessagelist 62 | { 63 | return new Tbmessagelist($this->client, 'messages/', $filter); 64 | } 65 | 66 | public function getMessageListFromFile(string $filePath): Tbmessagelist 67 | { 68 | return new Tbmessagelist($this->client, $filePath, [], true); 69 | } 70 | 71 | public function downloadMessageList(string $filePath, array $filter = []): bool 72 | { 73 | return $this->client->getRestClient()->downloadFile($filePath, 'messages/', $filter); 74 | } 75 | 76 | public function updateMessageProcessed(int $messageId): bool 77 | { 78 | $this->client->getRestClient()->postXML('messages/' . $messageId . '/processed'); 79 | return true; 80 | } 81 | 82 | public function addMessagesFromMessageListFile(string $filePath): string 83 | { 84 | return $this->client->getRestClient()->postXMLFile($filePath, 'messages/'); 85 | } 86 | 87 | public function addMessages(array $stockArray): string 88 | { 89 | $writer = new XMLWriter(); 90 | $writer->openMemory(); 91 | $writer->startElement('MESSAGES_LIST'); 92 | 93 | foreach ($stockArray as $message) { 94 | $writer->startElement('MESSAGE'); 95 | 96 | if ($message->getId() !== null) { 97 | $writer->writeElement('MESSAGE_ID', $message->getId()); 98 | } 99 | 100 | $writer->writeElement('MESSAGE_TYPE', $message->getType()); 101 | $writer->writeElement('TB_ORDER_ID', $message->getOrderId()); 102 | 103 | if ($message->getOrderItemId() !== null) { 104 | $writer->writeElement('TB_ORDER_ITEM_ID', $message->getOrderItemId()); 105 | } 106 | 107 | if ($message->getSku() !== null) { 108 | $writer->writeElement('SKU', $message->getSku()); 109 | } 110 | 111 | if ($message->getChannelSign() !== null) { 112 | $writer->writeElement('CHANNEL_SIGN', $message->getChannelSign()); 113 | } 114 | 115 | if ($message->getChannelOrderId() !== null) { 116 | $writer->writeElement('CHANNEL_ORDER_ID', $message->getChannelOrderId()); 117 | } 118 | 119 | if ($message->getChannelOrderItemId() !== null) { 120 | $writer->writeElement('CHANNEL_ORDER_ITEM_ID', $message->getChannelOrderId()); 121 | } 122 | 123 | if ($message->getSku() !== null) { 124 | $writer->writeElement('SKU', $message->getSku()); 125 | } 126 | 127 | if ($message->getChannelSign() !== null) { 128 | $writer->writeElement('CHANNEL_SIGN', $message->getChannelSign()); 129 | } 130 | 131 | if ($message->getChannelOrderId() !== null) { 132 | $writer->writeElement('CHANNEL_ORDER_ID', $message->getChannelOrderId()); 133 | } 134 | 135 | if ($message->getChannelOrderItemId() !== null) { 136 | $writer->writeElement('CHANNEL_ORDER_ITEM_ID', $message->getChannelOrderItemId()); 137 | } 138 | 139 | if ($message->getChannelSku() !== null) { 140 | $writer->writeElement('CHANNEL_SKU', $message->getChannelSku()); 141 | } 142 | 143 | $writer->writeElement('QUANTITY', $message->getQuantity()); 144 | 145 | if ($message->getCarrierParcelType() !== null) { 146 | $writer->writeElement('CARRIER_PARCEL_TYPE', $message->getCarrierParcelType()); 147 | } 148 | 149 | if ($message->getIdcode() !== null) { 150 | $writer->writeElement('IDCODE', $message->getIdcode()); 151 | } 152 | 153 | if ($message->getIdcodeReturnProposal() !== null) { 154 | $writer->writeElement('IDCODE_RETURN_PROPOSAL', $message->getIdcodeReturnProposal()); 155 | } 156 | 157 | if ($message->getDeduction() !== null) { 158 | $writer->writeElement('DEDUCTION', $message->getDeduction()); 159 | } 160 | 161 | if ($message->getComment() !== null) { 162 | $writer->writeElement('COMMENT', $message->getComment()); 163 | } 164 | 165 | if ($message->getReturnCause() !== null) { 166 | $writer->writeElement('RETURN_CAUSE', $message->getReturnCause()); 167 | } 168 | 169 | if ($message->getReturnState() !== null) { 170 | $writer->writeElement('RETURN_STATE', $message->getReturnState()); 171 | } 172 | 173 | if ($message->getService() !== null) { 174 | $writer->writeElement('SERVICE', $message->getService()); 175 | } 176 | 177 | if ($message->getEstShipDate() !== null) { 178 | $writer->writeElement('EST_SHIP_DATE', $message->getEstShipDate()); 179 | } 180 | 181 | if ($message->isProcessed() !== null) { 182 | $writer->writeElement('PROCESSED', $message->isProcessed()); 183 | } 184 | 185 | if ($message->isExported() !== null) { 186 | $writer->writeElement('EXPORTED', $message->isExported()); 187 | } 188 | 189 | if ($message->getCreatedDate() !== null) { 190 | $writer->writeElement('DATE_CREATED', $message->getCreatedDate()); 191 | } 192 | 193 | if ($message->getDeliveryInformation() !== null) { 194 | $writer->writeElement('DELIVERY_INFORMATION', $message->getDeliveryInformation()); 195 | } 196 | 197 | $writer->endElement(); 198 | } 199 | 200 | $writer->endElement(); 201 | return $this->client->getRestClient()->postXML('messages/', $writer->outputMemory()); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/Message/Model/Message.php: -------------------------------------------------------------------------------- 1 | id; 60 | } 61 | 62 | public function setId(int $id): Message 63 | { 64 | $this->id = $id; 65 | return $this; 66 | } 67 | 68 | public function getType(): ?string 69 | { 70 | return $this->type; 71 | } 72 | 73 | public function setType(string $type): Message 74 | { 75 | $this->type = $type; 76 | return $this; 77 | } 78 | 79 | public function getOrderId(): ?int 80 | { 81 | return $this->orderId; 82 | } 83 | 84 | public function setOrderId(int $orderId): Message 85 | { 86 | $this->orderId = $orderId; 87 | return $this; 88 | } 89 | 90 | public function getOrderItemId(): ?int 91 | { 92 | return $this->orderItemId; 93 | } 94 | 95 | public function setOrderItemId(int $orderItemId): Message 96 | { 97 | $this->orderItemId = $orderItemId; 98 | return $this; 99 | } 100 | 101 | public function getSku(): ?string 102 | { 103 | return $this->sku; 104 | } 105 | 106 | public function setSku(string $sku): Message 107 | { 108 | $this->sku = $sku; 109 | return $this; 110 | } 111 | 112 | public function getChannelSign(): ?string 113 | { 114 | return $this->channelSign; 115 | } 116 | 117 | public function setChannelSign(string $channelSign): Message 118 | { 119 | $this->channelSign = $channelSign; 120 | return $this; 121 | } 122 | 123 | public function getChannelOrderId(): ?string 124 | { 125 | return $this->channelOrderId; 126 | } 127 | 128 | public function setChannelOrderId(string $channelOrderId): Message 129 | { 130 | $this->channelOrderId = $channelOrderId; 131 | return $this; 132 | } 133 | 134 | public function getQuantity(): ?int 135 | { 136 | return $this->quantity; 137 | } 138 | 139 | public function setQuantity(int $quantity): Message 140 | { 141 | $this->quantity = $quantity; 142 | return $this; 143 | } 144 | 145 | public function getCarrierParcelType(): ?string 146 | { 147 | return $this->carrierParcelType; 148 | } 149 | 150 | public function setCarrierParcelType(string $carrierParcelType): Message 151 | { 152 | $this->carrierParcelType = $carrierParcelType; 153 | return $this; 154 | } 155 | 156 | public function getIdcode(): ?string 157 | { 158 | return $this->idcode; 159 | } 160 | 161 | public function setIdcode(string $idcode): Message 162 | { 163 | $this->idcode = $idcode; 164 | return $this; 165 | } 166 | 167 | public function isProcessed(): ?bool 168 | { 169 | return $this->isProcessed; 170 | } 171 | 172 | public function setIsProcessed(bool $isProcessed): Message 173 | { 174 | $this->isProcessed = $isProcessed; 175 | return $this; 176 | } 177 | 178 | public function isExported(): ?bool 179 | { 180 | return $this->isExported; 181 | } 182 | 183 | public function setIsExported(bool $isExported): Message 184 | { 185 | $this->isExported = $isExported; 186 | return $this; 187 | } 188 | 189 | public function getCreatedDate(): ?string 190 | { 191 | return $this->createdDate; 192 | } 193 | 194 | public function setCreatedDate(string $createdDate): Message 195 | { 196 | $this->createdDate = $createdDate; 197 | return $this; 198 | } 199 | 200 | public function getChannelOrderItemId(): ?string 201 | { 202 | return $this->channelOrderItemId; 203 | } 204 | 205 | public function setChannelOrderItemId(string $channelOrderItemId): Message 206 | { 207 | $this->channelOrderItemId = $channelOrderItemId; 208 | return $this; 209 | } 210 | 211 | public function getChannelSku(): ?string 212 | { 213 | return $this->channelSku; 214 | } 215 | 216 | public function setChannelSku(string $channelSku): Message 217 | { 218 | $this->channelSku = $channelSku; 219 | return $this; 220 | } 221 | 222 | public function getIdcodeReturnProposal(): ?string 223 | { 224 | return $this->idcodeReturnProposal; 225 | } 226 | 227 | public function setIdcodeReturnProposal(string $idcodeReturnProposal): Message 228 | { 229 | $this->idcodeReturnProposal = $idcodeReturnProposal; 230 | return $this; 231 | } 232 | 233 | public function getDeduction(): ?float 234 | { 235 | return $this->deduction; 236 | } 237 | 238 | public function setDeduction(float $deduction): Message 239 | { 240 | $this->deduction = $deduction; 241 | return $this; 242 | } 243 | 244 | public function getComment(): ?string 245 | { 246 | return $this->comment; 247 | } 248 | 249 | public function setComment(string $comment): Message 250 | { 251 | $this->comment = $comment; 252 | return $this; 253 | } 254 | 255 | public function getReturnCause(): ?string 256 | { 257 | return $this->returnCause; 258 | } 259 | 260 | public function setReturnCause(string $returnCause): Message 261 | { 262 | $this->returnCause = $returnCause; 263 | return $this; 264 | } 265 | 266 | public function getReturnState(): ?string 267 | { 268 | return $this->returnState; 269 | } 270 | 271 | public function setReturnState(string $returnState): Message 272 | { 273 | $this->returnState = $returnState; 274 | return $this; 275 | } 276 | 277 | public function getService(): ?string 278 | { 279 | return $this->service; 280 | } 281 | 282 | public function setService(string $service): Message 283 | { 284 | $this->service = $service; 285 | return $this; 286 | } 287 | 288 | public function getEstShipDate(): ?string 289 | { 290 | return $this->estShipDate; 291 | } 292 | 293 | public function setEstShipDate(string $estShipDate): Message 294 | { 295 | $this->estShipDate = $estShipDate; 296 | return $this; 297 | } 298 | 299 | public function getDeliveryInformation(): ?string 300 | { 301 | return $this->deliveryInformation; 302 | } 303 | 304 | public function setDeliveryInformation(string $deliveryInformation): Message 305 | { 306 | $this->deliveryInformation = $deliveryInformation; 307 | return $this; 308 | } 309 | 310 | public function fillFromSimpleXMLElement(SimpleXMLElement $xmlElement): void 311 | { 312 | $this->setId((int)$xmlElement->MESSAGE_ID); 313 | $this->setType((string)$xmlElement->MESSAGE_TYPE); 314 | $this->setOrderId((int)$xmlElement->TB_ORDER_ID); 315 | $this->setOrderItemId((int)$xmlElement->TB_ORDER_ITEM_ID); 316 | $this->setSku((string)$xmlElement->SKU); 317 | $this->setChannelSign((string)$xmlElement->CHANNEL_SIGN); 318 | $this->setChannelOrderId((string)$xmlElement->CHANNEL_ORDER_ID); 319 | $this->setChannelOrderItemId((string)$xmlElement->CHANNEL_ORDER_ITEM_ID); 320 | $this->setChannelSku((string)$xmlElement->CHANNEL_SKU); 321 | $this->setQuantity((int)$xmlElement->QUANTITY); 322 | $this->setCarrierParcelType((string)$xmlElement->CARRIER_PARCEL_TYPE); 323 | $this->setIdcode((string)$xmlElement->IDCODE); 324 | $this->setIdcodeReturnProposal((string)$xmlElement->IDCODE_RETURN_PROPOSAL); 325 | $this->setDeduction((float)$xmlElement->DEDUCTION); 326 | $this->setComment((string)$xmlElement->COMMENT); 327 | $this->setReturnCause((string)$xmlElement->RETURN_CAUSE); 328 | $this->setReturnState((string)$xmlElement->RETURN_STATE); 329 | $this->setService((string)$xmlElement->SERVICE); 330 | $this->setEstShipDate((string)$xmlElement->EST_SHIP_DATE); 331 | $this->setIsProcessed((bool)(int)$xmlElement->PROCESSED); 332 | $this->setIsExported((bool)(int)$xmlElement->EXPORTED); 333 | $this->setCreatedDate((string)$xmlElement->DATE_CREATED); 334 | $this->setDeliveryInformation((string)$xmlElement->DELIVERY_INFORMATION); 335 | } 336 | 337 | public function getRawData(): array 338 | { 339 | return [ 340 | 'id' => $this->getId(), 341 | 'type' => $this->getType(), 342 | 'order_id' => $this->getOrderId(), 343 | 'order_item_id' => $this->getOrderItemId(), 344 | 'sku' => $this->getSku(), 345 | 'channel_sign' => $this->getChannelSign(), 346 | 'channel_order_id' => $this->getChannelOrderId(), 347 | 'channel_order_item_id' => $this->getChannelOrderItemId(), 348 | 'channel_sku' => $this->getChannelSku(), 349 | 'quantity' => $this->getQuantity(), 350 | 'carrier_parcel_type' => $this->getCarrierParcelType(), 351 | 'idcode' => $this->getIdcode(), 352 | 'idcode_return_proposal' => $this->getIdcodeReturnProposal(), 353 | 'deduction' => $this->getDeduction(), 354 | 'comment' => $this->getComment(), 355 | 'return_cause' => $this->getReturnCause(), 356 | 'return_state' => $this->getReturnState(), 357 | 'service' => $this->getService(), 358 | 'est_ship_date' => $this->getEstShipDate(), 359 | 'is_processed' => $this->isProcessed(), 360 | 'is_exported' => $this->isExported(), 361 | 'created_date' => $this->getCreatedDate(), 362 | 'delivery_information' => $this->getDeliveryInformation(), 363 | ]; 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /src/Message/Tbmessage/Iterator.php: -------------------------------------------------------------------------------- 1 | current; 19 | } 20 | 21 | public function valid(): bool 22 | { 23 | return !empty($this->current); 24 | } 25 | 26 | public function next(): void 27 | { 28 | while ($this->xmlReader->read()) { 29 | if ( 30 | $this->xmlReader->nodeType == XMLReader::ELEMENT 31 | && $this->xmlReader->depth === 1 32 | && $this->xmlReader->name == 'MESSAGE' 33 | ) { 34 | $xmlElement = new \SimpleXMLElement($this->xmlReader->readOuterXML()); 35 | $model = new Message(); 36 | $model->fillFromSimpleXMLElement($xmlElement); 37 | $this->current = $model; 38 | return; 39 | } 40 | } 41 | 42 | $this->current = null; 43 | } 44 | 45 | public function open(): void 46 | { 47 | if ($this->getIsOpen()) { 48 | $this->close(); 49 | } 50 | 51 | if ($this->openLocalFilepath) { 52 | $this->xmlReader = new XMLReader(); 53 | 54 | if (@$this->xmlReader->open($this->url) === false) { 55 | throw new InvalidArgumentException('can not open file ' . $this->url); 56 | } 57 | } else { 58 | $this->xmlReader = $this->client->getRestClient()->getXML($this->url, $this->filter); 59 | } 60 | 61 | $this->isOpen = true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Message/Tbmessagelist.php: -------------------------------------------------------------------------------- 1 | iterator = new Tbmessage\Iterator($client, $url, $filter); 16 | $this->iterator->setOpenLocalFilepath($localFile); 17 | } 18 | 19 | public function getMessages(): Tbmessage\Iterator 20 | { 21 | if (!$this->iterator->getIsOpen()) { 22 | $this->iterator->open(); 23 | } 24 | 25 | return $this->iterator; 26 | } 27 | 28 | public function close(): void 29 | { 30 | $this->iterator->close(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Order/Handler.php: -------------------------------------------------------------------------------- 1 | client = $client; 23 | } 24 | 25 | public function getOrder(int $orderId): ?Order 26 | { 27 | $catalog = new Tborderlist($this->client, 'orders/' . (int)$orderId, []); 28 | $orderIterator = $catalog->getOrders(); 29 | $orderIterator->rewind(); 30 | 31 | return $orderIterator->current(); 32 | } 33 | 34 | public function getOrderFromFile(string $filePath): Order 35 | { 36 | $xmlElement = new SimpleXMLElement(file_get_contents($filePath)); 37 | $model = new Order(); 38 | $model->fillFromSimpleXMLElement($xmlElement); 39 | 40 | return $model; 41 | } 42 | 43 | public function downloadOrder(string $filePath, int $orderId): bool 44 | { 45 | $reader = $this->client->getRestClient()->getXML('orders/' . $orderId); 46 | 47 | while ($reader->read()) { 48 | if ( 49 | $reader->nodeType == XMLReader::ELEMENT 50 | && $reader->depth === 1 51 | && $reader->name == 'ORDER' 52 | ) { 53 | $filePut = (bool)file_put_contents($filePath, $reader->readOuterXml()); 54 | $reader->close(); 55 | return $filePut; 56 | } 57 | } 58 | 59 | $reader->close(); 60 | 61 | return false; 62 | } 63 | 64 | public function getOrderList($filter = []): Tborderlist 65 | { 66 | return new Tborderlist($this->client, 'orders/', $filter); 67 | } 68 | 69 | public function getOrderListFromFile(string $filePath): Tborderlist 70 | { 71 | return new Tborderlist($this->client, $filePath, [], true); 72 | } 73 | 74 | public function downloadOrderList(string $filePath, array $filter = []): bool 75 | { 76 | return $this->client->getRestClient()->downloadFile($filePath, 'orders/', $filter); 77 | } 78 | 79 | public function updateOrderExported(int $orderId): bool 80 | { 81 | $this->client->getRestClient()->postXML('orders/' . $orderId . '/exported'); 82 | return true; 83 | } 84 | 85 | public function updateOrderFromFile(string $filePath, int $channelId): string 86 | { 87 | return $this->client->getRestClient()->postXML( 88 | 'orders/?channel=' . (int)$channelId, 89 | file_get_contents($filePath) 90 | ); 91 | } 92 | 93 | public function updateOrder(int $channelId, Order $order): string 94 | { 95 | $writer = new XMLWriter(); 96 | $writer->openMemory(); 97 | $writer->startElement('ORDER'); 98 | $writer->startElement('ORDER_DATA'); 99 | $writer->writeElement('ORDER_DATE', $order->getOrderDate()); 100 | 101 | if ($order->getId() !== null) { 102 | $writer->writeElement('TB_ID', $order->getId()); 103 | } 104 | 105 | if ($order->getChannelSign() !== null) { 106 | $writer->writeElement('CHANNEL_SIGN', $order->getChannelSign()); 107 | } 108 | 109 | $writer->writeElement('CHANNEL_ID', $order->getChannelId()); 110 | 111 | if ($order->getChannelNumber() !== null) { 112 | $writer->writeElement('CHANNEL_NO', $order->getChannelNumber()); 113 | } 114 | 115 | if ($order->getBillNumber() !== null) { 116 | $writer->writeElement('BILL_NO', $order->getBillNumber()); 117 | } 118 | 119 | if ($order->isPaid() !== null) { 120 | $writer->writeElement('PAID', $order->isPaid()); 121 | } 122 | 123 | $writer->writeElement('APPROVED', $order->isApproved()); 124 | $writer->writeElement('ITEM_COUNT', $order->getItemCount()); 125 | $writer->writeElement('TOTAL_ITEM_AMOUNT', $order->getTotalItemAmount()); 126 | 127 | if ($order->getOrderCreatedDate() !== null) { 128 | $writer->writeElement('DATE_CREATED', $order->getOrderCreatedDate()); 129 | } 130 | 131 | $writer->endElement(); 132 | 133 | if ($order->getSellTo() !== null) { 134 | $customer = $order->getSellTo(); 135 | $writer->startElement('SELL_TO'); 136 | 137 | if ($customer->getChannelNumber() !== null) { 138 | $writer->writeElement('CHANNEL_NO', $customer->getChannelNumber()); 139 | } 140 | 141 | $writer->writeElement('FIRSTNAME', $customer->getFirstname()); 142 | $writer->writeElement('LASTNAME', $customer->getLastname()); 143 | 144 | if ($customer->getName() !== null) { 145 | $writer->writeElement('NAME', $customer->getName()); 146 | } 147 | 148 | $writer->writeElement('STREET_NO', $customer->getStreetNumber()); 149 | $writer->writeElement('ZIP', $customer->getZip()); 150 | $writer->writeElement('CITY', $customer->getCity()); 151 | $writer->writeElement('COUNTRY', $customer->getCountry()); 152 | $writer->endElement(); 153 | } 154 | 155 | $customer = $order->getShipTo(); 156 | $writer->startElement('SHIP_TO'); 157 | 158 | if ($customer->getChannelNumber() !== null) { 159 | $writer->writeElement('CHANNEL_NO', $customer->getChannelNumber()); 160 | } 161 | 162 | $writer->writeElement('FIRSTNAME', $customer->getFirstname()); 163 | $writer->writeElement('LASTNAME', $customer->getLastname()); 164 | 165 | if ($customer->getName() !== null) { 166 | $writer->writeElement('NAME', $customer->getName()); 167 | } 168 | 169 | $writer->writeElement('STREET_NO', $customer->getStreetNumber()); 170 | $writer->writeElement('ZIP', $customer->getZip()); 171 | $writer->writeElement('CITY', $customer->getCity()); 172 | $writer->writeElement('COUNTRY', $customer->getCountry()); 173 | $writer->endElement(); 174 | 175 | $writer->startElement('ITEMS'); 176 | 177 | foreach ($order->getItems() as $item) { 178 | $writer->startElement('ITEM'); 179 | $writer->writeElement('CHANNEL_ID', $item->getChannelId()); 180 | $writer->writeElement('SKU', $item->getSku()); 181 | $writer->writeElement('QUANTITY', $item->getQuantity()); 182 | 183 | if ($item->getTransferPrice() !== null) { 184 | $writer->writeElement('TRANSFER_PRICE', $item->getTransferPrice()); 185 | } 186 | 187 | $writer->writeElement('ITEM_PRICE', $item->getItemPrice()); 188 | 189 | if ($item->getCreatedDate() !== null) { 190 | $writer->writeElement('DATE_CREATED', $item->getCreatedDate()); 191 | } 192 | 193 | $writer->endElement(); 194 | } 195 | 196 | $writer->endElement(); 197 | $writer->endElement(); 198 | 199 | return $this->client->getRestClient()->postXML('orders/?channel=' . (int)$channelId, $writer->outputMemory()); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/Order/Model/Customer.php: -------------------------------------------------------------------------------- 1 | id; 46 | } 47 | 48 | public function setId(int $id): Customer 49 | { 50 | $this->id = $id; 51 | return $this; 52 | } 53 | 54 | public function getChannelNumber(): ?string 55 | { 56 | return $this->channelNumber; 57 | } 58 | 59 | public function setChannelNumber(string $channelNumber): Customer 60 | { 61 | $this->channelNumber = $channelNumber; 62 | return $this; 63 | } 64 | 65 | public function getFirstname(): ?string 66 | { 67 | return $this->firstname; 68 | } 69 | 70 | public function setFirstname(string $firstname): Customer 71 | { 72 | $this->firstname = $firstname; 73 | return $this; 74 | } 75 | 76 | public function getLastname(): ?string 77 | { 78 | return $this->lastname; 79 | } 80 | 81 | public function setLastname(string $lastname): Customer 82 | { 83 | $this->lastname = $lastname; 84 | return $this; 85 | } 86 | 87 | public function getName(): ?string 88 | { 89 | return $this->name; 90 | } 91 | 92 | public function setName(string $name): Customer 93 | { 94 | $this->name = $name; 95 | return $this; 96 | } 97 | 98 | public function getStreetNumber(): ?string 99 | { 100 | return $this->streetNumber; 101 | } 102 | 103 | public function setStreetNumber(string $streetNumber): Customer 104 | { 105 | $this->streetNumber = $streetNumber; 106 | return $this; 107 | } 108 | 109 | public function getZip(): ?string 110 | { 111 | return $this->zip; 112 | } 113 | 114 | public function setZip(string $zip): Customer 115 | { 116 | $this->zip = $zip; 117 | return $this; 118 | } 119 | 120 | public function getCity(): ?string 121 | { 122 | return $this->city; 123 | } 124 | 125 | public function setCity(string $city): Customer 126 | { 127 | $this->city = $city; 128 | return $this; 129 | } 130 | 131 | public function getCountry(): ?string 132 | { 133 | return $this->country; 134 | } 135 | 136 | public function setCountry(string $country): Customer 137 | { 138 | $this->country = $country; 139 | return $this; 140 | } 141 | 142 | public function getEmail(): ?string 143 | { 144 | return $this->email; 145 | } 146 | 147 | public function setEmail(string $email): Customer 148 | { 149 | $this->email = $email; 150 | return $this; 151 | } 152 | 153 | public function getTitle(): ?string 154 | { 155 | return $this->title; 156 | } 157 | 158 | public function setTitle(string $title): Customer 159 | { 160 | $this->title = $title; 161 | return $this; 162 | } 163 | 164 | public function getNameExtension(): ?string 165 | { 166 | return $this->nameExtension; 167 | } 168 | 169 | public function setNameExtension(string $nameExtension): Customer 170 | { 171 | $this->nameExtension = $nameExtension; 172 | return $this; 173 | } 174 | 175 | public function getStreetExtension(): ?string 176 | { 177 | return $this->streetExtension; 178 | } 179 | 180 | public function setStreetExtension(string $streetExtension): Customer 181 | { 182 | $this->streetExtension = $streetExtension; 183 | return $this; 184 | } 185 | 186 | public function getPhonePrivate(): ?string 187 | { 188 | return $this->phonePrivate; 189 | } 190 | 191 | public function setPhonePrivate(string $phonePrivate): Customer 192 | { 193 | $this->phonePrivate = $phonePrivate; 194 | return $this; 195 | } 196 | 197 | public function getPhoneOffice(): ?string 198 | { 199 | return $this->phoneOffice; 200 | } 201 | 202 | public function setPhoneOffice(string $phoneOffice): Customer 203 | { 204 | $this->phoneOffice = $phoneOffice; 205 | return $this; 206 | } 207 | 208 | public function getPhoneMobile(): ?string 209 | { 210 | return $this->phoneMobile; 211 | } 212 | 213 | public function setPhoneMobile(string $phoneMobile): Customer 214 | { 215 | $this->phoneMobile = $phoneMobile; 216 | return $this; 217 | } 218 | 219 | public function getVatId(): ?string 220 | { 221 | return $this->vatId; 222 | } 223 | 224 | public function setVatId(string $vatId): Customer 225 | { 226 | $this->vatId = $vatId; 227 | return $this; 228 | } 229 | 230 | public function getRawData(): array 231 | { 232 | return [ 233 | 'id' => $this->getId(), 234 | 'channel_number' => $this->getChannelNumber(), 235 | 'zip' => $this->getZip(), 236 | 'city' => $this->getCity(), 237 | 'firstname' => $this->getFirstname(), 238 | 'lastname' => $this->getLastname(), 239 | 'title' => $this->getTitle(), 240 | 'name' => $this->getName(), 241 | 'name_extension' => $this->getNameExtension(), 242 | 'country' => $this->getCountry(), 243 | 'email' => $this->getEmail(), 244 | 'street_number' => $this->getStreetNumber(), 245 | 'street_extension' => $this->getStreetExtension(), 246 | 'phone_mobile' => $this->getPhoneMobile(), 247 | 'phone_office' => $this->getPhoneOffice(), 248 | 'phone_private' => $this->getPhonePrivate(), 249 | 'vat_id' => $this->getVatId(), 250 | ]; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /src/Order/Model/History.php: -------------------------------------------------------------------------------- 1 | id; 18 | } 19 | 20 | public function setId(int $id): History 21 | { 22 | $this->id = $id; 23 | return $this; 24 | } 25 | 26 | public function getType(): ?string 27 | { 28 | return $this->type; 29 | } 30 | 31 | public function setType(string $type): History 32 | { 33 | $this->type = $type; 34 | return $this; 35 | } 36 | 37 | public function getCreatedDate(): ?string 38 | { 39 | return $this->createdDate; 40 | } 41 | 42 | public function setCreatedDate(string $createdDate): History 43 | { 44 | $this->createdDate = $createdDate; 45 | return $this; 46 | } 47 | 48 | public function getRawData(): array 49 | { 50 | return [ 51 | 'id' => $this->getId(), 52 | 'type' => $this->getType(), 53 | 'created_date' => $this->getCreatedDate(), 54 | ]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Order/Model/Item.php: -------------------------------------------------------------------------------- 1 | id; 32 | } 33 | 34 | public function setId(int $id): Item 35 | { 36 | $this->id = $id; 37 | return $this; 38 | } 39 | 40 | public function getChannelId(): ?string 41 | { 42 | return $this->channelId; 43 | } 44 | 45 | public function setChannelId(string $channelId): Item 46 | { 47 | $this->channelId = $channelId; 48 | return $this; 49 | } 50 | 51 | public function getSku(): ?string 52 | { 53 | return $this->sku; 54 | } 55 | 56 | public function getChannelSku(): ?string 57 | { 58 | return $this->channelSku; 59 | } 60 | 61 | public function setSku(string $sku): Item 62 | { 63 | $this->sku = $sku; 64 | return $this; 65 | } 66 | 67 | public function setChannelSku(string $channelSku): Item 68 | { 69 | $this->channelSku = $channelSku; 70 | return $this; 71 | } 72 | 73 | public function getEan(): ?string 74 | { 75 | return $this->ean; 76 | } 77 | 78 | public function setEan(string $ean): Item 79 | { 80 | $this->ean = $ean; 81 | return $this; 82 | } 83 | 84 | public function getQuantity(): ?int 85 | { 86 | return $this->quantity; 87 | } 88 | 89 | public function setQuantity(int $quantity): Item 90 | { 91 | $this->quantity = $quantity; 92 | return $this; 93 | } 94 | 95 | public function getBillingText(): ?string 96 | { 97 | return $this->billingText; 98 | } 99 | 100 | public function setBillingText(string $billingText): Item 101 | { 102 | $this->billingText = $billingText; 103 | return $this; 104 | } 105 | 106 | public function getTransferPrice(): ?float 107 | { 108 | return $this->transferPrice; 109 | } 110 | 111 | public function setTransferPrice(float $transferPrice): Item 112 | { 113 | $this->transferPrice = $transferPrice; 114 | return $this; 115 | } 116 | 117 | public function getItemPrice(): ?float 118 | { 119 | return $this->itemPrice; 120 | } 121 | 122 | public function setItemPrice(float $itemPrice): Item 123 | { 124 | $this->itemPrice = $itemPrice; 125 | return $this; 126 | } 127 | 128 | public function getCreatedDate(): ?string 129 | { 130 | return $this->createdDate; 131 | } 132 | 133 | public function setCreatedDate(string $createdDate): Item 134 | { 135 | $this->createdDate = $createdDate; 136 | return $this; 137 | } 138 | 139 | public function getRawData(): array 140 | { 141 | return [ 142 | 'id' => $this->getId(), 143 | 'created_date' => $this->getCreatedDate(), 144 | 'channel_id' => $this->getChannelId(), 145 | 'ean' => $this->getEan(), 146 | 'item_price' => $this->getItemPrice(), 147 | 'quantity' => $this->getQuantity(), 148 | 'billing_text' => $this->getBillingText(), 149 | 'sku' => $this->getSku(), 150 | 'channel_sku' => $this->getChannelSku(), 151 | 'transfer_price' => $this->getTransferPrice(), 152 | ]; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/Order/Model/Order.php: -------------------------------------------------------------------------------- 1 | id; 66 | } 67 | 68 | public function setId(int $id): Order 69 | { 70 | $this->id = $id; 71 | return $this; 72 | } 73 | 74 | public function getOrderDate(): ?string 75 | { 76 | return $this->orderDate; 77 | } 78 | 79 | public function setOrderDate(string $orderDate): Order 80 | { 81 | $this->orderDate = $orderDate; 82 | return $this; 83 | } 84 | 85 | public function getOrderCreatedDate(): ?string 86 | { 87 | return $this->orderCreatedDate; 88 | } 89 | 90 | public function setOrderCreatedDate(string $orderCreatedDate): Order 91 | { 92 | $this->orderCreatedDate = $orderCreatedDate; 93 | return $this; 94 | } 95 | 96 | public function getChannelSign(): ?string 97 | { 98 | return $this->channelSign; 99 | } 100 | 101 | public function setChannelSign(string $channelSign): Order 102 | { 103 | $this->channelSign = $channelSign; 104 | return $this; 105 | } 106 | 107 | public function getChannelId(): ?string 108 | { 109 | return $this->channelId; 110 | } 111 | 112 | public function setChannelId(string $channelId): Order 113 | { 114 | $this->channelId = $channelId; 115 | return $this; 116 | } 117 | 118 | public function getChannelNumber(): ?string 119 | { 120 | return $this->channelNumber; 121 | } 122 | 123 | public function setChannelNumber(string $channelNumber): Order 124 | { 125 | $this->channelNumber = $channelNumber; 126 | return $this; 127 | } 128 | 129 | public function isPaid(): ?bool 130 | { 131 | return $this->isPaid; 132 | } 133 | 134 | public function setIsPaid(bool $isPaid): Order 135 | { 136 | $this->isPaid = $isPaid; 137 | return $this; 138 | } 139 | 140 | public function isApproved(): ?bool 141 | { 142 | return $this->isApproved; 143 | } 144 | 145 | public function setIsApproved(bool $isApproved): Order 146 | { 147 | $this->isApproved = $isApproved; 148 | return $this; 149 | } 150 | 151 | public function getItemCount(): ?int 152 | { 153 | return $this->itemCount; 154 | } 155 | 156 | public function setItemCount(int $itemCount): Order 157 | { 158 | $this->itemCount = $itemCount; 159 | return $this; 160 | } 161 | 162 | public function getTotalItemAmount(): ?float 163 | { 164 | return $this->totalItemAmount; 165 | } 166 | 167 | public function setTotalItemAmount(float $totalItemAmount): Order 168 | { 169 | $this->totalItemAmount = $totalItemAmount; 170 | return $this; 171 | } 172 | 173 | /** 174 | * @return Item[]|null 175 | */ 176 | public function getItems(): ?array 177 | { 178 | return $this->items; 179 | } 180 | 181 | /** 182 | * @param Item[] $items 183 | */ 184 | public function setItems(array $items): Order 185 | { 186 | $this->items = $items; 187 | return $this; 188 | } 189 | 190 | /** 191 | * @return History[]|null 192 | */ 193 | public function getHistory(): ?array 194 | { 195 | return $this->history; 196 | } 197 | 198 | /** 199 | * @param History[] $history 200 | */ 201 | public function setHistory(array $history): Order 202 | { 203 | $this->history = $history; 204 | return $this; 205 | } 206 | 207 | public function getShipTo(): ?Customer 208 | { 209 | return $this->shipTo; 210 | } 211 | 212 | public function setShipTo(Customer $shipTo): Order 213 | { 214 | $this->shipTo = $shipTo; 215 | return $this; 216 | } 217 | 218 | public function getSellTo(): ?Customer 219 | { 220 | return $this->sellTo; 221 | } 222 | 223 | public function setSellTo(Customer $sellTo): Order 224 | { 225 | $this->sellTo = $sellTo; 226 | return $this; 227 | } 228 | 229 | public function getShipmentPrice(): ?float 230 | { 231 | return $this->shipmentPrice; 232 | } 233 | 234 | public function setShipmentPrice(float $shipmentPrice): Order 235 | { 236 | $this->shipmentPrice = $shipmentPrice; 237 | return $this; 238 | } 239 | 240 | public function getShipmentIdcodeShip(): ?string 241 | { 242 | return $this->shipmentIdcodeShip; 243 | } 244 | 245 | public function setShipmentIdcodeShip(string $shipmentIdcodeShip): Order 246 | { 247 | $this->shipmentIdcodeShip = $shipmentIdcodeShip; 248 | return $this; 249 | } 250 | 251 | public function getShipmentIdcodeReturn(): ?string 252 | { 253 | return $this->shipmentIdcodeReturn; 254 | } 255 | 256 | public function setShipmentIdcodeReturn(string $shipmentIdcodeReturn): Order 257 | { 258 | $this->shipmentIdcodeReturn = $shipmentIdcodeReturn; 259 | return $this; 260 | } 261 | 262 | public function getShipmentRoutingCode(): ?string 263 | { 264 | return $this->shipmentRoutingCode; 265 | } 266 | 267 | public function setShipmentRoutingCode(string $shipmentRoutingCode): Order 268 | { 269 | $this->shipmentRoutingCode = $shipmentRoutingCode; 270 | return $this; 271 | } 272 | 273 | public function getPaymentCosts(): ?float 274 | { 275 | return $this->paymentCosts; 276 | } 277 | 278 | public function setPaymentCosts(float $paymentCosts): Order 279 | { 280 | $this->paymentCosts = $paymentCosts; 281 | return $this; 282 | } 283 | 284 | public function getPaymentType(): ?string 285 | { 286 | return $this->paymentType; 287 | } 288 | 289 | public function setPaymentType(string $paymentType): Order 290 | { 291 | $this->paymentType = $paymentType; 292 | return $this; 293 | } 294 | 295 | public function getPaymentDirectdebit(): ?string 296 | { 297 | return $this->paymentDirectdebit; 298 | } 299 | 300 | public function setPaymentDirectdebit(string $paymentDirectdebit): Order 301 | { 302 | $this->paymentDirectdebit = $paymentDirectdebit; 303 | return $this; 304 | } 305 | 306 | public function getCustomerComment(): ?string 307 | { 308 | return $this->customerComment; 309 | } 310 | 311 | public function setCustomerComment(string $customerComment): Order 312 | { 313 | $this->customerComment = $customerComment; 314 | return $this; 315 | } 316 | 317 | public function getBillNumber(): ?string 318 | { 319 | return $this->billNumber; 320 | } 321 | 322 | public function setBillNumber(string $billNumber): Order 323 | { 324 | $this->billNumber = $billNumber; 325 | return $this; 326 | } 327 | 328 | public function fillFromSimpleXMLElement(SimpleXMLElement $xmlElement): void 329 | { 330 | $this->setId((int)$xmlElement->ORDER_DATA->TB_ID); 331 | $this->setOrderDate((string)$xmlElement->ORDER_DATA->ORDER_DATE); 332 | $this->setOrderCreatedDate((string)$xmlElement->ORDER_DATA->DATE_CREATED); 333 | $this->setChannelSign((string)$xmlElement->ORDER_DATA->CHANNEL_SIGN); 334 | $this->setChannelId((string)$xmlElement->ORDER_DATA->CHANNEL_ID); 335 | $this->setChannelNumber((string)$xmlElement->ORDER_DATA->CHANNEL_NO); 336 | $this->setIsPaid((bool)(int)$xmlElement->ORDER_DATA->PAID); 337 | $this->setIsApproved((bool)(int)$xmlElement->ORDER_DATA->APPROVED); 338 | $this->setCustomerComment((string)$xmlElement->ORDER_DATA->CUSTOMER_COMMENT); 339 | $this->setItemCount((int)$xmlElement->ORDER_DATA->ITEM_COUNT); 340 | $this->setTotalItemAmount((float)$xmlElement->ORDER_DATA->TOTAL_ITEM_AMOUNT); 341 | 342 | if (isset($xmlElement->SHIPMENT)) { 343 | if (isset($xmlElement->SHIPMENT->IDCODE_SHIP)) { 344 | $this->setShipmentIdcodeShip((string)$xmlElement->SHIPMENT->IDCODE_SHIP); 345 | } 346 | 347 | if (isset($xmlElement->SHIPMENT->IDCODE_RETURN)) { 348 | $this->setShipmentIdcodeReturn((string)$xmlElement->SHIPMENT->IDCODE_RETURN); 349 | } 350 | 351 | if (isset($xmlElement->SHIPMENT->ROUTING_CODE)) { 352 | $this->setShipmentRoutingCode((string)$xmlElement->SHIPMENT->ROUTING_CODE); 353 | } 354 | 355 | if (isset($xmlElement->SHIPMENT->PRICE)) { 356 | $this->setShipmentPrice((float)$xmlElement->SHIPMENT->PRICE); 357 | } 358 | } 359 | 360 | if (isset($xmlElement->PAYMENT)) { 361 | if (isset($xmlElement->PAYMENT->TYPE)) { 362 | $this->setPaymentType((string)$xmlElement->PAYMENT->TYPE); 363 | } 364 | 365 | if (isset($xmlElement->PAYMENT->DIRECTDEBIT)) { 366 | $this->setPaymentDirectdebit((string)$xmlElement->PAYMENT->DIRECTDEBIT); 367 | } 368 | 369 | if (isset($xmlElement->PAYMENT->COSTS)) { 370 | $this->setPaymentCosts((float)$xmlElement->PAYMENT->COSTS); 371 | } 372 | } 373 | 374 | foreach (['sell_to', 'ship_to'] as $customerType) { 375 | $upperCustomerType = strtoupper($customerType); 376 | 377 | if (isset($xmlElement->{$upperCustomerType})) { 378 | $customer = new Customer(); 379 | $customer->setId((int)$xmlElement->{$upperCustomerType}->TB_ID); 380 | $customer->setChannelNumber((string)$xmlElement->{$upperCustomerType}->CHANNEL_NO); 381 | $customer->setTitle((string)$xmlElement->{$upperCustomerType}->TITLE); 382 | $customer->setFirstname((string)$xmlElement->{$upperCustomerType}->FIRSTNAME); 383 | $customer->setLastname((string)$xmlElement->{$upperCustomerType}->LASTNAME); 384 | $customer->setName((string)$xmlElement->{$upperCustomerType}->NAME); 385 | $customer->setNameExtension((string)$xmlElement->{$upperCustomerType}->NAME_EXTENSION); 386 | $customer->setStreetNumber((string)$xmlElement->{$upperCustomerType}->STREET_NO); 387 | $customer->setStreetExtension((string)$xmlElement->{$upperCustomerType}->STREET_EXTENSION); 388 | $customer->setZip((string)$xmlElement->{$upperCustomerType}->ZIP); 389 | $customer->setCity((string)$xmlElement->{$upperCustomerType}->CITY); 390 | $customer->setCountry((string)$xmlElement->{$upperCustomerType}->COUNTRY); 391 | $customer->setPhonePrivate((string)$xmlElement->{$upperCustomerType}->PHONE_PRIVATE); 392 | $customer->setPhoneOffice((string)$xmlElement->{$upperCustomerType}->PHONE_OFFICE); 393 | $customer->setPhoneMobile((string)$xmlElement->{$upperCustomerType}->PHONE_MOBILE); 394 | $customer->setEmail((string)$xmlElement->{$upperCustomerType}->EMAIL); 395 | $customer->setVatId((string)$xmlElement->{$upperCustomerType}->VAT_ID); 396 | 397 | if ($customerType == 'sell_to') { 398 | $this->setSellTo($customer); 399 | } else { 400 | $this->setShipTo($customer); 401 | } 402 | } 403 | } 404 | 405 | if (isset($xmlElement->HISTORY)) { 406 | foreach ($xmlElement->HISTORY->EVENT as $event) { 407 | $history = new History(); 408 | $history->setId((int)$event->EVENT_ID); 409 | $history->setType((string)$event->EVENT_TYPE); 410 | $history->setCreatedDate((string)$event->DATE_CREATED); 411 | $this->history[] = $history; 412 | } 413 | } 414 | 415 | if (isset($xmlElement->ITEMS)) { 416 | foreach ($xmlElement->ITEMS->ITEM as $xmlItem) { 417 | $item = new Item(); 418 | $item->setId((int)$xmlItem->TB_ID); 419 | $item->setChannelId((string)$xmlItem->CHANNEL_ID); 420 | $item->setSku((string)$xmlItem->SKU); 421 | $item->setChannelSku((string)$xmlItem->CHANNEL_SKU); 422 | $item->setEan((string)$xmlItem->EAN); 423 | $item->setQuantity((int)$xmlItem->QUANTITY); 424 | $item->setBillingText((string)$xmlItem->BILLING_TEXT); 425 | $item->setTransferPrice((float)$xmlItem->TRANSFER_PRICE); 426 | $item->setItemPrice((float)$xmlItem->ITEM_PRICE); 427 | $item->setCreatedDate((string)$xmlItem->DATE_CREATED); 428 | $this->items[] = $item; 429 | } 430 | } 431 | } 432 | 433 | public function getRawData(): array 434 | { 435 | $data = [ 436 | 'id' => $this->getId(), 437 | 'order_date' => $this->getOrderDate(), 438 | 'order_created_date' => $this->getOrderCreatedDate(), 439 | 'channel_sign' => $this->getChannelSign(), 440 | 'channel_id' => $this->getChannelId(), 441 | 'channel_number' => $this->getChannelNumber(), 442 | 'is_paid' => $this->isPaid(), 443 | 'is_approved' => $this->isApproved(), 444 | 'customer_comment' => $this->getCustomerComment(), 445 | 'item_count' => $this->getItemCount(), 446 | 'total_item_amount' => $this->getTotalItemAmount(), 447 | 'shipment_idcode_return' => $this->getShipmentIdcodeReturn(), 448 | 'shipment_idcode_ship' => $this->getShipmentIdcodeShip(), 449 | 'shipment_routing_code' => $this->getShipmentRoutingCode(), 450 | 'shipment_price' => $this->getShipmentPrice(), 451 | 'payment_costs' => $this->getPaymentCosts(), 452 | 'payment_directdebit' => $this->getPaymentDirectdebit(), 453 | 'payment_type' => $this->getPaymentType(), 454 | 'ship_to' => $this->getShipTo() ? $this->getShipTo()->getRawData() : null, 455 | 'sell_to' => $this->getSellTo() ? $this->getSellTo()->getRawData() : null, 456 | 'history' => null, 457 | 'items' => null 458 | ]; 459 | 460 | $history = $this->getHistory(); 461 | 462 | if ($history) { 463 | foreach ($this->getHistory() as $history) { 464 | $data['history'][] = $history->getRawData(); 465 | } 466 | } 467 | 468 | $items = $this->getItems(); 469 | 470 | if ($items) { 471 | foreach ($this->getItems() as $item) { 472 | $data['items'][] = $item->getRawData(); 473 | } 474 | } 475 | 476 | return $data; 477 | } 478 | } 479 | -------------------------------------------------------------------------------- /src/Order/Tborder/Iterator.php: -------------------------------------------------------------------------------- 1 | current; 19 | } 20 | 21 | public function valid(): bool 22 | { 23 | return !empty($this->current); 24 | } 25 | 26 | public function next(): void 27 | { 28 | while ($this->xmlReader->read()) { 29 | if ( 30 | $this->xmlReader->nodeType == XMLReader::ELEMENT 31 | && $this->xmlReader->depth === 1 32 | && $this->xmlReader->name == 'ORDER' 33 | ) { 34 | $xmlElement = new \SimpleXMLElement($this->xmlReader->readOuterXML()); 35 | $model = new Order(); 36 | $model->fillFromSimpleXMLElement($xmlElement); 37 | $this->current = $model; 38 | return; 39 | } 40 | } 41 | 42 | $this->current = null; 43 | } 44 | 45 | public function open(): void 46 | { 47 | if ($this->getIsOpen()) { 48 | $this->close(); 49 | } 50 | 51 | if ($this->openLocalFilepath) { 52 | $this->xmlReader = new XMLReader(); 53 | 54 | if (@$this->xmlReader->open($this->url) === false) { 55 | throw new InvalidArgumentException('can not open file ' . $this->url); 56 | } 57 | } else { 58 | $this->xmlReader = $this->client->getRestClient()->getXML($this->url, $this->filter); 59 | } 60 | 61 | $this->isOpen = true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Order/Tborderlist.php: -------------------------------------------------------------------------------- 1 | iterator = new Tborder\Iterator($client, $url, $filter); 16 | $this->iterator->setOpenLocalFilepath($localFile); 17 | } 18 | 19 | public function getOrders(): Tborder\Iterator 20 | { 21 | if (!$this->iterator->getIsOpen()) { 22 | $this->iterator->open(); 23 | } 24 | 25 | return $this->iterator; 26 | } 27 | 28 | public function close(): void 29 | { 30 | $this->iterator->close(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Product/Handler.php: -------------------------------------------------------------------------------- 1 | client = $client; 22 | } 23 | 24 | public function getProduct(int $productId, int $channelId): ?Product 25 | { 26 | $catalog = new Tbcat($this->client, 'products/', ['p_id' => $productId, 'channel' => $channelId]); 27 | $productIterator = $catalog->getProducts(); 28 | $productIterator->rewind(); 29 | 30 | return $productIterator->current(); 31 | } 32 | 33 | public function getProductFromFile(string $filePath): Product 34 | { 35 | $xmlElement = new SimpleXMLElement(file_get_contents($filePath)); 36 | $model = new Product(); 37 | $model->fillFromSimpleXMLElement($xmlElement); 38 | 39 | return $model; 40 | } 41 | 42 | public function downloadProduct(string $filePath, int $productId, int $channelId): bool 43 | { 44 | $reader = $this->client->getRestClient()->getXML( 45 | 'products/' . (int)$productId, 46 | ['p_id' => $productId, 'channel' => $channelId] 47 | ); 48 | 49 | while ($reader->read()) { 50 | if ( 51 | $reader->nodeType == XMLReader::ELEMENT 52 | && $reader->depth === 2 53 | && $reader->name == 'PRODUCT' 54 | ) { 55 | $filePut = (bool)file_put_contents($filePath, $reader->readOuterXml()); 56 | $reader->close(); 57 | return $filePut; 58 | } 59 | } 60 | 61 | $reader->close(); 62 | 63 | return false; 64 | } 65 | 66 | public function getCatalog($filter = []): Tbcat 67 | { 68 | return new Tbcat($this->client, 'products/', $filter); 69 | } 70 | 71 | public function getCatalogFromFile(string $filePath): Tbcat 72 | { 73 | return new Tbcat($this->client, $filePath, [], true); 74 | } 75 | 76 | public function downloadCatalog(string $filePath, array $filter = []): bool 77 | { 78 | return $this->client->getRestClient()->downloadFile($filePath, 'products/', $filter); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Product/Model/Article.php: -------------------------------------------------------------------------------- 1 | id; 52 | } 53 | 54 | public function setId(int $id): void 55 | { 56 | $this->id = $id; 57 | } 58 | 59 | public function getNumber(): ?string 60 | { 61 | return $this->number; 62 | } 63 | 64 | public function setNumber(string $number): void 65 | { 66 | $this->number = $number; 67 | } 68 | 69 | public function getChangeDate(): ?int 70 | { 71 | return $this->changeDate; 72 | } 73 | 74 | public function setChangeDate(int $changeDate): void 75 | { 76 | $this->changeDate = $changeDate; 77 | } 78 | 79 | public function getCreatedDate(): ?int 80 | { 81 | return $this->createdDate; 82 | } 83 | 84 | public function setCreatedDate(int $createdDate): void 85 | { 86 | $this->createdDate = $createdDate; 87 | } 88 | 89 | public function isActive(): ?bool 90 | { 91 | return $this->isActive; 92 | } 93 | 94 | public function setIsActive(bool $isActive): void 95 | { 96 | $this->isActive = $isActive; 97 | } 98 | 99 | public function getEan(): ?string 100 | { 101 | return $this->ean; 102 | } 103 | 104 | public function setEan(string $ean): void 105 | { 106 | $this->ean = $ean; 107 | } 108 | 109 | public function getProdNumber(): ?string 110 | { 111 | return $this->prodNumber; 112 | } 113 | 114 | public function setProdNumber(string $prodNumber): void 115 | { 116 | $this->prodNumber = $prodNumber; 117 | } 118 | 119 | public function getUnit(): ?string 120 | { 121 | return $this->unit; 122 | } 123 | 124 | public function setUnit(string $unit): void 125 | { 126 | $this->unit = $unit; 127 | } 128 | 129 | public function getStock(): ?int 130 | { 131 | return $this->stock; 132 | } 133 | 134 | public function setStock(int $stock): void 135 | { 136 | $this->stock = $stock; 137 | } 138 | 139 | public function getDeliveryTime(): ?int 140 | { 141 | return $this->deliveryTime; 142 | } 143 | 144 | public function setDeliveryTime(int $deliveryTime): void 145 | { 146 | $this->deliveryTime = $deliveryTime; 147 | } 148 | 149 | public function getReplacement(): ?int 150 | { 151 | return $this->replacement; 152 | } 153 | 154 | public function setReplacement(int $replacement): void 155 | { 156 | $this->replacement = $replacement; 157 | } 158 | 159 | public function getReplacementTime(): ?int 160 | { 161 | return $this->replacementTime; 162 | } 163 | 164 | public function setReplacementTime(int $replacementTime): void 165 | { 166 | $this->replacementTime = $replacementTime; 167 | } 168 | 169 | public function getOrderMin(): ?int 170 | { 171 | return $this->orderMin; 172 | } 173 | 174 | public function setOrderMin(int $orderMin): void 175 | { 176 | $this->orderMin = $orderMin; 177 | } 178 | 179 | public function getOrderMax(): ?int 180 | { 181 | return $this->orderMax; 182 | } 183 | 184 | public function setOrderMax(int $orderMax): void 185 | { 186 | $this->orderMax = $orderMax; 187 | } 188 | 189 | public function getOrderInterval(): ?int 190 | { 191 | return $this->orderInterval; 192 | } 193 | 194 | public function setOrderInterval(int $orderInterval): void 195 | { 196 | $this->orderInterval = $orderInterval; 197 | } 198 | 199 | public function getSupSupplier(): ?array 200 | { 201 | return $this->supSupplier; 202 | } 203 | 204 | public function setSupSupplier(array $supSupplier): void 205 | { 206 | $this->supSupplier = $supSupplier; 207 | } 208 | 209 | public function getVariants(): ?array 210 | { 211 | return $this->variants; 212 | } 213 | 214 | public function setVariants(array $variants): void 215 | { 216 | $this->variants = $variants; 217 | } 218 | 219 | public function getPrices(): ?array 220 | { 221 | return $this->prices; 222 | } 223 | 224 | public function setPrices(array $prices): void 225 | { 226 | $this->prices = $prices; 227 | } 228 | 229 | public function getParcel(): ?array 230 | { 231 | return $this->parcel; 232 | } 233 | 234 | public function setParcel(array $parcel): void 235 | { 236 | $this->parcel = $parcel; 237 | } 238 | 239 | public function getMedia(): ?array 240 | { 241 | return $this->media; 242 | } 243 | 244 | public function setMedia(array $media): void 245 | { 246 | $this->media = $media; 247 | } 248 | 249 | public function getRawData(): array 250 | { 251 | return [ 252 | 'id' => $this->getId(), 253 | 'number' => $this->getNumber(), 254 | 'sup_supplier' => $this->getSupSupplier(), 255 | 'change_date' => $this->getChangeDate(), 256 | 'created_date' => $this->getCreatedDate(), 257 | 'active' => $this->isActive(), 258 | 'ean' => $this->getEan(), 259 | 'prod_number' => $this->getProdNumber(), 260 | 'variants' => $this->getVariants(), 261 | 'prices' => $this->getPrices(), 262 | 'media' => $this->getMedia(), 263 | 'unit' => $this->getUnit(), 264 | 'stock' => $this->getStock(), 265 | 'delivery_time' => $this->getDeliveryTime(), 266 | 'replacement' => $this->getReplacement(), 267 | 'replacement_time' => $this->getReplacementTime(), 268 | 'order_min' => $this->getOrderMin(), 269 | 'order_max' => $this->getOrderMax(), 270 | 'order_interval' => $this->getOrderInterval(), 271 | 'parcel' => $this->getParcel(), 272 | ]; 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /src/Product/Model/Product.php: -------------------------------------------------------------------------------- 1 | id; 41 | } 42 | 43 | public function setId(int $id): void 44 | { 45 | $this->id = $id; 46 | } 47 | 48 | public function getNumber(): ?string 49 | { 50 | return $this->number; 51 | } 52 | 53 | public function setNumber(string $number): void 54 | { 55 | $this->number = $number; 56 | } 57 | 58 | public function getChangeDate(): ?int 59 | { 60 | return $this->changeDate; 61 | } 62 | 63 | public function setChangeDate(int $changeDate): void 64 | { 65 | $this->changeDate = $changeDate; 66 | } 67 | 68 | public function getCreatedDate(): ?int 69 | { 70 | return $this->createdDate; 71 | } 72 | 73 | public function setCreatedDate(int $createdDate): void 74 | { 75 | $this->createdDate = $createdDate; 76 | } 77 | 78 | public function getBrand(): ?string 79 | { 80 | return $this->brand; 81 | } 82 | 83 | public function setBrand(string $brand): void 84 | { 85 | $this->brand = $brand; 86 | } 87 | 88 | /** 89 | * @return Article[]|null 90 | */ 91 | public function getArticles(): ?array 92 | { 93 | return $this->articles; 94 | } 95 | 96 | /** 97 | * @param Article[] $articles 98 | */ 99 | public function setArticles(array $articles): void 100 | { 101 | $this->articles = $articles; 102 | } 103 | 104 | public function getSupSupplier(): ?array 105 | { 106 | return $this->supSupplier; 107 | } 108 | 109 | public function setSupSupplier(array $supSupplier): void 110 | { 111 | $this->supSupplier = $supSupplier; 112 | } 113 | 114 | public function getActivations(): ?array 115 | { 116 | return $this->activations; 117 | } 118 | 119 | public function setActivations(array $activations): void 120 | { 121 | $this->activations = $activations; 122 | } 123 | 124 | public function getName(): ?array 125 | { 126 | return $this->name; 127 | } 128 | 129 | public function setName(array $name): void 130 | { 131 | $this->name = $name; 132 | } 133 | 134 | public function getText(): ?array 135 | { 136 | return $this->text; 137 | } 138 | 139 | public function setText(array $text): void 140 | { 141 | $this->text = $text; 142 | } 143 | 144 | public function getMedia(): ?array 145 | { 146 | return $this->media; 147 | } 148 | 149 | public function setMedia(array $media): void 150 | { 151 | $this->media = $media; 152 | } 153 | 154 | public function getVariantfields(): ?array 155 | { 156 | return $this->variantfields; 157 | } 158 | 159 | public function setVariantfields(array $variantfields): void 160 | { 161 | $this->variantfields = $variantfields; 162 | } 163 | 164 | public function fillFromSimpleXMLElement(SimpleXMLElement $xmlElement): void 165 | { 166 | $this->setId((int)$xmlElement->P_NR); 167 | $this->setNumber((string)$xmlElement->P_NR_EXTERNAL); 168 | 169 | if (isset($xmlElement->P_SUB_SUPPLIER)) { 170 | $this->setSupSupplier([ 171 | 'identifier' => (string)$xmlElement->P_SUB_SUPPLIER['identifier'], 172 | 'key' => (string)$xmlElement->P_SUB_SUPPLIER['key'], 173 | ]); 174 | } 175 | 176 | $this->setChangeDate((int)$xmlElement->P_CHANGEDATE); 177 | $this->setCreatedDate((int)$xmlElement->P_CREATEDATE); 178 | 179 | if (isset($xmlElement->P_ACTIVEDATA)) { 180 | $activations = []; 181 | 182 | foreach ($xmlElement->P_ACTIVEDATA->P_ACTIVE as $active) { 183 | $activations[(string)$active['channel']] = (int)$active; 184 | } 185 | 186 | $this->setActivations($activations); 187 | } 188 | 189 | if (isset($xmlElement->P_NAME)) { 190 | $name = []; 191 | 192 | foreach ($xmlElement->P_NAME->VALUE as $value) { 193 | $lang = (string)$value->xpath('@xml:lang')[0]['lang']; 194 | $name[$lang] = (string)$value; 195 | } 196 | 197 | $this->setName($name); 198 | } 199 | 200 | if (isset($xmlElement->P_TEXT)) { 201 | $text = []; 202 | 203 | foreach ($xmlElement->P_TEXT->VALUE as $value) { 204 | $lang = (string)$value->xpath('@xml:lang')[0]['lang']; 205 | $text[$lang] = (string)$value; 206 | } 207 | 208 | $this->setText($text); 209 | } 210 | 211 | $this->setBrand((string)$xmlElement->P_BRAND); 212 | 213 | if (isset($xmlElement->P_MEDIADATA)) { 214 | $media = []; 215 | 216 | foreach ($xmlElement->P_MEDIADATA->P_MEDIA as $mediaNode) { 217 | $media[] = [ 218 | 'type' => (string)$mediaNode['type'], 219 | 'sort' => (string)$mediaNode['sort'], 220 | 'origname' => (string)$mediaNode['origname'], 221 | 'url' => (string)$mediaNode 222 | ]; 223 | } 224 | 225 | $this->setMedia($media); 226 | } 227 | 228 | if (isset($xmlElement->P_VARIANTFIELDS)) { 229 | $variantfields = []; 230 | 231 | foreach ($xmlElement->P_VARIANTFIELDS->P_VARIANTFIELD as $variantfield) { 232 | $variantfields[] = [ 233 | 'identifier' => (string)$variantfield['identifier'], 234 | 'key' => (string)$variantfield['key'], 235 | 'value' => (string)$variantfield, 236 | ]; 237 | } 238 | 239 | $this->setVariantfields($variantfields); 240 | } 241 | 242 | if (isset($xmlElement->ARTICLEDATA)) { 243 | foreach ($xmlElement->ARTICLEDATA->ARTICLE as $xmlItem) { 244 | $article = new Article(); 245 | $article->setId((int)$xmlItem->A_ID); 246 | $article->setNumber((string)$xmlItem->A_NR); 247 | 248 | if (isset($xmlItem->A_SUB_SUPPLIER)) { 249 | $article->setSupSupplier([ 250 | 'identifier' => (string)$xmlItem->A_SUB_SUPPLIER['identifier'], 251 | 'key' => (string)$xmlItem->A_SUB_SUPPLIER['key'], 252 | ]); 253 | } 254 | 255 | $article->setChangeDate((int)$xmlItem->A_CHANGEDATE); 256 | $article->setCreatedDate((int)$xmlItem->A_CREATEDATE); 257 | $article->setIsActive((bool)(int)$xmlItem->A_ACTIVE); 258 | $article->setEan((string)$xmlItem->A_EAN); 259 | $article->setProdNumber((string)$xmlItem->A_PROD_NR); 260 | 261 | if (isset($xmlItem->A_VARIANTDATA)) { 262 | $variants = []; 263 | $i = 0; 264 | 265 | foreach ($xmlItem->A_VARIANTDATA->A_VARIANT as $variant) { 266 | $variants[$i] = [ 267 | 'identifier' => (string)$variant['identifier'], 268 | 'key' => (string)$variant['key'], 269 | 'values' => [] 270 | ]; 271 | 272 | foreach ($variant->VALUE as $variant) { 273 | $lang = (string)$variant->xpath('@xml:lang')[0]['lang']; 274 | $variants[$i]['values'][$lang] = (string)$variant; 275 | } 276 | 277 | $i++; 278 | } 279 | 280 | $article->setVariants($variants); 281 | } 282 | 283 | if (isset($xmlItem->A_PRICEDATA)) { 284 | $prices = []; 285 | 286 | foreach ($xmlItem->A_PRICEDATA->A_PRICE as $price) { 287 | $prices[(string)$price['channel']] = [ 288 | 'currency' => (string)$price['currency'], 289 | 'vk' => (float)$price->A_VK, 290 | 'vk_old' => (float)$price->A_VK_OLD, 291 | 'uvp' => (float)$price->UVP, 292 | 'mwst' => (int)$price->A_MWST, 293 | 'ek' => (float)$price->A_EK, 294 | ]; 295 | } 296 | 297 | $article->setPrices($prices); 298 | } 299 | 300 | if (isset($xmlItem->A_MEDIADATA)) { 301 | $media = []; 302 | 303 | foreach ($xmlItem->A_MEDIADATA->A_MEDIA as $mediaNode) { 304 | $media[] = [ 305 | 'type' => (string)$mediaNode['type'], 306 | 'sort' => (string)$mediaNode['sort'], 307 | 'origname' => (string)$mediaNode['origname'], 308 | 'url' => (string)$mediaNode 309 | ]; 310 | } 311 | 312 | $article->setMedia($media); 313 | } 314 | 315 | $article->setUnit((string)$xmlItem->A_UNIT); 316 | $article->setStock((int)$xmlItem->A_STOCK); 317 | $article->setDeliveryTime((int)$xmlItem->A_DELIVERY_TIME); 318 | $article->setReplacement((int)$xmlItem->A_REPLACEMENT); 319 | $article->setReplacementTime((int)$xmlItem->A_REPLACEMENT_TIME); 320 | $article->setOrderMin((int)$xmlItem->A_ORDER_MIN); 321 | $article->setOrderMax((int)$xmlItem->A_ORDER_MAX); 322 | $article->setOrderInterval((int)$xmlItem->A_ORDER_INTERVAL); 323 | 324 | if (isset($xmlItem->A_PARCEL)) { 325 | $article->setParcel([ 326 | 'pieces' => (int)$xmlItem->A_PARCEL->A_PIECES, 327 | 'width' => (float)$xmlItem->A_PARCEL->A_WIDTH, 328 | 'height' => (float)$xmlItem->A_PARCEL->A_HEIGHT, 329 | 'length' => (float)$xmlItem->A_PARCEL->A_LENGTH, 330 | ]); 331 | } 332 | 333 | $this->articles[] = $article; 334 | } 335 | } 336 | } 337 | 338 | public function getRawData(): array 339 | { 340 | $data = [ 341 | 'id' => $this->getId(), 342 | 'number' => $this->getNumber(), 343 | 'change_date' => $this->getChangeDate(), 344 | 'created_date' => $this->getCreatedDate(), 345 | 'sup_supplier' => $this->getSupSupplier(), 346 | 'activations' => $this->getActivations(), 347 | 'name' => $this->getName(), 348 | 'text' => $this->getText(), 349 | 'brand' => $this->getBrand(), 350 | 'media' => $this->getMedia(), 351 | 'variantfields' => $this->getVariantfields(), 352 | 'articles' => null 353 | ]; 354 | 355 | $articles = $this->getArticles(); 356 | 357 | if ($articles) { 358 | foreach ($articles as $article) { 359 | $data['articles'][] = $article->getRawData(); 360 | } 361 | } 362 | 363 | return $data; 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /src/Product/Tbcat.php: -------------------------------------------------------------------------------- 1 | iterator = new Tbcat\Iterator($client, $url, $filter); 16 | $this->iterator->setOpenLocalFilepath($localFile); 17 | } 18 | 19 | public function getSupplierName(): ?string 20 | { 21 | return $this->iterator->getSupplierName(); 22 | } 23 | 24 | public function getProducts(): Tbcat\Iterator 25 | { 26 | if (!$this->iterator->getIsOpen()) { 27 | $this->iterator->open(); 28 | } 29 | 30 | return $this->iterator; 31 | } 32 | 33 | public function close(): void 34 | { 35 | $this->iterator->close(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Product/Tbcat/Iterator.php: -------------------------------------------------------------------------------- 1 | getIsOpen()) { 21 | $this->open(); 22 | } 23 | 24 | return $this->supplierName; 25 | } 26 | 27 | public function current(): ?Product 28 | { 29 | return $this->current; 30 | } 31 | 32 | public function valid(): bool 33 | { 34 | return !empty($this->current); 35 | } 36 | 37 | public function next(): void 38 | { 39 | while ($this->xmlReader->read()) { 40 | if ( 41 | $this->xmlReader->nodeType == XMLReader::ELEMENT 42 | && $this->xmlReader->depth == 2 43 | && $this->xmlReader->name == 'PRODUCT' 44 | ) { 45 | $xmlElement = new SimpleXMLElement($this->xmlReader->readOuterXML()); 46 | $product = new Product(); 47 | $product->fillFromSimpleXMLElement($xmlElement); 48 | $this->current = $product; 49 | return; 50 | } 51 | } 52 | 53 | $this->current = null; 54 | } 55 | 56 | public function open(): void 57 | { 58 | if ($this->getIsOpen()) { 59 | $this->close(); 60 | } 61 | 62 | if ($this->openLocalFilepath) { 63 | $this->xmlReader = new XMLReader(); 64 | 65 | if (@$this->xmlReader->open($this->url) === false) { 66 | throw new InvalidArgumentException('can not open file ' . $this->url); 67 | } 68 | } else { 69 | $this->xmlReader = $this->client->getRestClient()->getXML($this->url, $this->filter); 70 | } 71 | 72 | while ($this->xmlReader->read()) { 73 | if ( 74 | $this->xmlReader->nodeType == XMLReader::ELEMENT 75 | && $this->xmlReader->depth == 1 76 | && $this->xmlReader->name == 'SUPPLIER' 77 | ) { 78 | $xmlElement = new SimpleXMLElement($this->xmlReader->readOuterXML()); 79 | $this->supplierName = (string)$xmlElement->NAME; 80 | break; 81 | } 82 | } 83 | 84 | $this->isOpen = true; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Stock/Handler.php: -------------------------------------------------------------------------------- 1 | client = $client; 19 | } 20 | 21 | public function getStockList(array $filter = []): Tbstock 22 | { 23 | return new Tbstock($this->client, 'stock/', $filter); 24 | } 25 | 26 | public function getStockListFromFile(string $filePath): Tbstock 27 | { 28 | return new Tbstock($this->client, $filePath, [], true); 29 | } 30 | 31 | public function downloadStockList(string $filePath, array $filter = []): bool 32 | { 33 | return $this->client->getRestClient()->downloadFile($filePath, 'stock/', $filter); 34 | } 35 | 36 | /** 37 | * @deprecated Don´t use this method, will be removed in next major release. 38 | */ 39 | public function updateStockFromStockList(string $filePath): string 40 | { 41 | return $this->client->getRestClient()->postXMLFile($filePath, 'articles/stock'); 42 | } 43 | 44 | /** 45 | * Don´t use Stock[] anymore as object-array, support will be removed in next major release. 46 | * 47 | * @param Stock[]|StockUpdate[] $stockArray 48 | */ 49 | public function updateStock(array $stockArray): string 50 | { 51 | $writer = new XMLWriter(); 52 | $writer->openMemory(); 53 | $writer->startElement('TBCATALOG'); 54 | $writer->startElement('ARTICLEDATA'); 55 | 56 | foreach ($stockArray as $stock) { 57 | $writer->startElement('ARTICLE'); 58 | $writer->writeElement('A_NR', $stock->getArticleNumber()); 59 | 60 | if ($stock instanceof StockUpdate) { 61 | if ($stock->getStock() !== null) { 62 | $writer->writeElement('A_STOCK', (string)$stock->getStock()); 63 | } 64 | 65 | foreach ($stock->getStockForWarehouses() as $warehouseStock) { 66 | $writer->startElement('A_STOCK'); 67 | $writer->writeAttribute('identifier', $warehouseStock['identifier']); 68 | $writer->writeAttribute('key', $warehouseStock['key']); 69 | $writer->text((string)$warehouseStock['stock']); 70 | $writer->endElement(); 71 | } 72 | } else { 73 | $writer->writeElement('A_STOCK', (string)$stock->getStock()); 74 | } 75 | 76 | $writer->endElement(); 77 | } 78 | 79 | $writer->endElement(); 80 | $writer->endElement(); 81 | 82 | return $this->client->getRestClient()->postXML('articles/stock', $writer->outputMemory()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Stock/Model/Stock.php: -------------------------------------------------------------------------------- 1 | articleNumber; 18 | } 19 | 20 | public function setArticleNumber(string $articleNumber): Stock 21 | { 22 | $this->articleNumber = $articleNumber; 23 | return $this; 24 | } 25 | 26 | public function getStock(): ?int 27 | { 28 | return $this->stock; 29 | } 30 | 31 | public function setStock(int $stock): Stock 32 | { 33 | $this->stock = $stock; 34 | return $this; 35 | } 36 | 37 | public function fillFromSimpleXMLElement(SimpleXMLElement $xmlElement): void 38 | { 39 | $this->setArticleNumber((string)$xmlElement->A_NR); 40 | $this->setStock((int)$xmlElement->A_STOCK); 41 | } 42 | 43 | public function getRawData(): array 44 | { 45 | return [ 46 | 'article_number' => $this->getArticleNumber(), 47 | 'stock' => $this->getStock(), 48 | ]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Stock/Model/StockUpdate.php: -------------------------------------------------------------------------------- 1 | articleNumber; 18 | } 19 | 20 | public function setArticleNumber(string $articleNumber): StockUpdate 21 | { 22 | $this->articleNumber = $articleNumber; 23 | return $this; 24 | } 25 | 26 | public function getStock(): ?int 27 | { 28 | return $this->stock; 29 | } 30 | 31 | public function setStock(int $stock): StockUpdate 32 | { 33 | $this->stock = $stock; 34 | return $this; 35 | } 36 | 37 | public function getStockForWarehouses(): array 38 | { 39 | return $this->stockForWarehouses; 40 | } 41 | 42 | public function addStockForWarehouse(string $warehouseKey, int $stock): StockUpdate 43 | { 44 | $this->stockForWarehouses[] = [ 45 | 'identifier' => 'key', 46 | 'key' => $warehouseKey, 47 | 'stock' => $stock, 48 | ]; 49 | return $this; 50 | } 51 | 52 | public function getRawData(): array 53 | { 54 | return [ 55 | 'article_number' => $this->getArticleNumber(), 56 | 'stock' => $this->getStock(), 57 | 'stockForWarehouses' => $this->getStockForWarehouses(), 58 | ]; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Stock/Tbstock.php: -------------------------------------------------------------------------------- 1 | iterator = new Tbstock\Iterator($client, $url, $filter); 16 | $this->iterator->setOpenLocalFilepath($localFile); 17 | } 18 | 19 | public function getChangeDate(): ?string 20 | { 21 | return $this->iterator->getChangeDate(); 22 | } 23 | 24 | public function getStock(): Tbstock\Iterator 25 | { 26 | if (!$this->iterator->getIsOpen()) { 27 | $this->iterator->open(); 28 | } 29 | 30 | return $this->iterator; 31 | } 32 | 33 | public function close(): void 34 | { 35 | $this->iterator->close(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Stock/Tbstock/Iterator.php: -------------------------------------------------------------------------------- 1 | getIsOpen()) { 20 | $this->open(); 21 | } 22 | 23 | return $this->changeDate; 24 | } 25 | 26 | public function current(): ?Stock 27 | { 28 | return $this->current; 29 | } 30 | 31 | public function valid(): bool 32 | { 33 | return !empty($this->current); 34 | } 35 | 36 | public function next(): void 37 | { 38 | while ($this->xmlReader->read()) { 39 | if ( 40 | $this->xmlReader->nodeType == XMLReader::ELEMENT 41 | && $this->xmlReader->depth === 1 42 | && $this->xmlReader->name == 'ARTICLE' 43 | ) { 44 | $xmlElement = new \SimpleXMLElement($this->xmlReader->readOuterXML()); 45 | $model = new Stock(); 46 | $model->fillFromSimpleXMLElement($xmlElement); 47 | $this->current = $model; 48 | return; 49 | } 50 | } 51 | 52 | $this->current = null; 53 | } 54 | 55 | public function open(): void 56 | { 57 | if ($this->getIsOpen()) { 58 | $this->close(); 59 | } 60 | 61 | if ($this->openLocalFilepath) { 62 | $this->xmlReader = new XMLReader(); 63 | 64 | if (@$this->xmlReader->open($this->url) === false) { 65 | throw new InvalidArgumentException('can not open file ' . $this->url); 66 | } 67 | } else { 68 | $this->xmlReader = $this->client->getRestClient()->getXML($this->url, $this->filter); 69 | } 70 | 71 | while ($this->xmlReader->read()) { 72 | if ( 73 | $this->xmlReader->nodeType == XMLReader::ELEMENT 74 | && $this->xmlReader->depth == 0 75 | && $this->xmlReader->name == 'TBSTOCK' 76 | ) { 77 | $this->changeDate = $this->xmlReader->getAttribute('changedate'); 78 | break; 79 | } 80 | } 81 | 82 | $this->isOpen = true; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Upload/Handler.php: -------------------------------------------------------------------------------- 1 | client = $client; 16 | } 17 | 18 | public function uploadFile(string $filePath, string $fileName): string 19 | { 20 | return $this->client->getRestClient()->uploadFile($filePath, 'sync/in/' . $fileName); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Base.php: -------------------------------------------------------------------------------- 1 | 1, 17 | 'type' => 'type_test', 18 | 'order_id' => 2, 19 | 'order_item_id' => 3, 20 | 'sku' => 'sku_test', 21 | 'channel_sign' => 'channel_sign_test', 22 | 'channel_order_id' => 'channel_order_id_test', 23 | 'channel_order_item_id' => 'channel_order_item_id_test', 24 | 'channel_sku' => 'channel_sku_test', 25 | 'quantity' => 4, 26 | 'carrier_parcel_type' => 'carrier_test', 27 | 'idcode' => 'idcode_test', 28 | 'idcode_return_proposal' => 'idcode_return_proposal_test', 29 | 'deduction' => 10.0, 30 | 'comment' => 'comment_test', 31 | 'return_cause' => 'return_cause_test', 32 | 'return_state' => 'return_state_test', 33 | 'service' => 'service_test', 34 | 'est_ship_date' => 'est_ship_date_test', 35 | 'is_processed' => false, 36 | 'is_exported' => true, 37 | 'created_date' => '2016-09-09T14:14:17', 38 | 'delivery_information' => 'delivery_information_test', 39 | ]; 40 | } 41 | 42 | public function testGetMessageListFromFile(): void 43 | { 44 | $messageHandler = (new Client())->getMessageHandler(); 45 | $messageList = $messageHandler->getMessageListFromFile(__DIR__ . '/../files/messagelist.xml'); 46 | $messages = $messageList->getMessages(); 47 | $messages->rewind(); 48 | $messageModel = $messages->current(); 49 | 50 | $this->assertSame($this->getMessageFileRawData(), $messageModel->getRawData()); 51 | } 52 | 53 | public function testGetMessageFromFile(): void 54 | { 55 | $messageHandler = (new Client())->getMessageHandler(); 56 | $messageModel = $messageHandler->getMessageFromFile(__DIR__ . '/../files/message.xml'); 57 | $this->assertSame($this->getMessageFileRawData(), $messageModel->getRawData()); 58 | } 59 | 60 | public function testUpdateMessageProcessed(): void 61 | { 62 | $mock = $this->getMockBuilder(Client\Rest::class) 63 | ->disableOriginalConstructor() 64 | ->setMethodsExcept(['postXML', 'setAccountNumber', 'setAccountUser', 'setAccountPassword', 'setBaseURL']) 65 | ->getMock(); 66 | $mock->setAccountNumber(1234); 67 | $mock->setAccountUser('test'); 68 | $mock->setAccountPassword('test'); 69 | $mock->setBaseURL('localhost'); 70 | $mock->expects($this->once()) 71 | ->method('fileGetContents') 72 | ->with( 73 | $this->equalTo('localhost/1234/messages/1/processed'), 74 | $this->equalTo(false), 75 | $this->equalTo([ 76 | 'http' => [ 77 | 'method' => 'POST', 78 | 'header' => 'Authorization: Basic dGVzdDp0ZXN0' . "\r\n" . 79 | 'Content-Type: application/xml' . "\r\n" . 80 | 'Accept: application/xml' . "\r\n" . 81 | 'User-Agent: Tradebyte-SDK-PHP', 82 | 'content' => '', 83 | 'ignore_errors' => true, 84 | 'time_out' => 3600 85 | ] 86 | ]), 87 | ) 88 | ->will($this->returnValue(['content' => 'foo', 'status_line' => 'HTTP/1.0 200'])); 89 | $client = new Client(); 90 | $client->setRestClient($mock); 91 | $this->assertSame(true, $client->getMessageHandler()->updateMessageProcessed(1)); 92 | } 93 | 94 | public function testMessageObjectGetRawData(): void 95 | { 96 | $message = new Message(); 97 | $message->setId(1) 98 | ->setType('type_test') 99 | ->setOrderId(2) 100 | ->setOrderItemId(3) 101 | ->setSku('sku_test') 102 | ->setChannelSign('channel_sign_test') 103 | ->setChannelOrderId('channel_order_id_test') 104 | ->setChannelOrderItemId('channel_order_item_id_test') 105 | ->setChannelSku('channel_sku_test') 106 | ->setQuantity(4) 107 | ->setCarrierParcelType('carrier_test') 108 | ->setIdcode('idcode_test') 109 | ->setIdcodeReturnProposal('idcode_return_proposal_test') 110 | ->setDeduction(20) 111 | ->setComment('comment_test') 112 | ->setReturnState('return_state_test') 113 | ->setReturnCause('return_cause_test') 114 | ->setService('service_test') 115 | ->setEstShipDate('est_ship_date_test') 116 | ->setIsExported(true) 117 | ->setIsProcessed(false) 118 | ->setCreatedDate('2016-09-09T14:14:17') 119 | ->setDeliveryInformation('delivery_infromation_test'); 120 | $this->assertSame([ 121 | 'id' => 1, 122 | 'type' => 'type_test', 123 | 'order_id' => 2, 124 | 'order_item_id' => 3, 125 | 'sku' => 'sku_test', 126 | 'channel_sign' => 'channel_sign_test', 127 | 'channel_order_id' => 'channel_order_id_test', 128 | 'channel_order_item_id' => 'channel_order_item_id_test', 129 | 'channel_sku' => 'channel_sku_test', 130 | 'quantity' => 4, 131 | 'carrier_parcel_type' => 'carrier_test', 132 | 'idcode' => 'idcode_test', 133 | 'idcode_return_proposal' => 'idcode_return_proposal_test', 134 | 'deduction' => 20.0, 135 | 'comment' => 'comment_test', 136 | 'return_cause' => 'return_cause_test', 137 | 'return_state' => 'return_state_test', 138 | 'service' => 'service_test', 139 | 'est_ship_date' => 'est_ship_date_test', 140 | 'is_processed' => false, 141 | 'is_exported' => true, 142 | 'created_date' => '2016-09-09T14:14:17', 143 | 'delivery_information' => 'delivery_infromation_test' 144 | ], $message->getRawData()); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /tests/Order/OrderTest.php: -------------------------------------------------------------------------------- 1 | getOrderHandler(); 19 | $orderModel = $orderHandler->getOrderFromFile(__DIR__ . '/../files/order.xml'); 20 | $expectedSubset = [ 21 | 'id' => 1, 22 | 'order_date' => '2018-11-07', 23 | 'channel_sign' => 'channel_sign_test', 24 | 'channel_id' => 'channel_id_test', 25 | 'channel_number' => 'channel_no_test', 26 | 'is_paid' => true, 27 | 'is_approved' => false, 28 | 'customer_comment' => 'customer_comment_test', 29 | 'item_count' => 1, 30 | 'total_item_amount' => 1.0, 31 | 'order_created_date' => '2018-11-07T10:35:57' 32 | ]; 33 | $actualArray = $orderModel->getRawData(); 34 | 35 | foreach ($expectedSubset as $key => $value) { 36 | $this->assertArrayHasKey($key, $actualArray); 37 | $this->assertSame($value, $actualArray[$key]); 38 | } 39 | } 40 | 41 | public function testOrderGetRawData(): void 42 | { 43 | $order = new Order(); 44 | $order->setId(1) 45 | ->setChannelId('12345') 46 | ->setChannelSign('zade') 47 | ->setChannelNumber('12345') 48 | ->setItemCount(2) 49 | ->setTotalItemAmount(20.0) 50 | ->setOrderCreatedDate('2019') 51 | ->setOrderDate('2019') 52 | ->setIsPaid(true) 53 | ->setIsApproved(false) 54 | ->setCustomerComment('comment') 55 | ->setHistory([(new History())->setId(1) 56 | ->setType('test') 57 | ->setCreatedDate('2019')]) 58 | ->setShipmentPrice(20.0) 59 | ->setShipmentIdcodeShip('ship') 60 | ->setShipmentIdcodeReturn('return') 61 | ->setShipmentRoutingCode('code') 62 | ->setPaymentType('type') 63 | ->setPaymentCosts(20.0) 64 | ->setPaymentDirectdebit('debit'); 65 | 66 | $item = new Item(); 67 | $item->setId(1) 68 | ->setEan('12345') 69 | ->setItemPrice(40.0) 70 | ->setCreatedDate('2019') 71 | ->setQuantity(10) 72 | ->setBillingText('article test') 73 | ->setSku('12345') 74 | ->setChannelSku('54321') 75 | ->setChannelId('12345') 76 | ->setTransferPrice(50.0); 77 | $order->setItems([$item]); 78 | 79 | $customer = new Customer(); 80 | $customer->setId(1) 81 | ->setChannelNumber('12345') 82 | ->setEmail('test@test.de') 83 | ->setFirstname('Test') 84 | ->setLastname('Test 2') 85 | ->setName('Test Test 2') 86 | ->setNameExtension('Ex') 87 | ->setCountry('Germany') 88 | ->setCity('Neuendettelsau') 89 | ->setZip('91564') 90 | ->setTitle('Dr') 91 | ->setVatId('123') 92 | ->setPhoneMobile('1') 93 | ->setPhoneOffice('2') 94 | ->setPhonePrivate('3') 95 | ->setStreetNumber('Muster 24') 96 | ->setStreetExtension('Ext'); 97 | 98 | $order->setShipTo($customer); 99 | 100 | $customer = clone $customer; 101 | $customer->setFirstname('Tester'); 102 | $order->setSellTo($customer); 103 | 104 | $this->assertSame([ 105 | 'id' => 1, 106 | 'order_date' => '2019', 107 | 'order_created_date' => '2019', 108 | 'channel_sign' => 'zade', 109 | 'channel_id' => '12345', 110 | 'channel_number' => '12345', 111 | 'is_paid' => true, 112 | 'is_approved' => false, 113 | 'customer_comment' => 'comment', 114 | 'item_count' => 2, 115 | 'total_item_amount' => 20.0, 116 | 'shipment_idcode_return' => 'return', 117 | 'shipment_idcode_ship' => 'ship', 118 | 'shipment_routing_code' => 'code', 119 | 'shipment_price' => 20.0, 120 | 'payment_costs' => 20.0, 121 | 'payment_directdebit' => 'debit', 122 | 'payment_type' => 'type', 123 | 'ship_to' => [ 124 | 'id' => 1, 125 | 'channel_number' => '12345', 126 | 'zip' => '91564', 127 | 'city' => 'Neuendettelsau', 128 | 'firstname' => 'Test', 129 | 'lastname' => 'Test 2', 130 | 'title' => 'Dr', 131 | 'name' => 'Test Test 2', 132 | 'name_extension' => 'Ex', 133 | 'country' => 'Germany', 134 | 'email' => 'test@test.de', 135 | 'street_number' => 'Muster 24', 136 | 'street_extension' => 'Ext', 137 | 'phone_mobile' => '1', 138 | 'phone_office' => '2', 139 | 'phone_private' => '3', 140 | 'vat_id' => '123' 141 | ], 142 | 'sell_to' => [ 143 | 'id' => 1, 144 | 'channel_number' => '12345', 145 | 'zip' => '91564', 146 | 'city' => 'Neuendettelsau', 147 | 'firstname' => 'Tester', 148 | 'lastname' => 'Test 2', 149 | 'title' => 'Dr', 150 | 'name' => 'Test Test 2', 151 | 'name_extension' => 'Ex', 152 | 'country' => 'Germany', 153 | 'email' => 'test@test.de', 154 | 'street_number' => 'Muster 24', 155 | 'street_extension' => 'Ext', 156 | 'phone_mobile' => '1', 157 | 'phone_office' => '2', 158 | 'phone_private' => '3', 159 | 'vat_id' => '123' 160 | ], 161 | 'history' => [ 162 | [ 163 | 'id' => 1, 164 | 'type' => 'test', 165 | 'created_date' => '2019', 166 | ] 167 | ], 168 | 'items' => [ 169 | [ 170 | 'id' => 1, 171 | 'created_date' => '2019', 172 | 'channel_id' => '12345', 173 | 'ean' => '12345', 174 | 'item_price' => 40.0, 175 | 'quantity' => 10, 176 | 'billing_text' => 'article test', 177 | 'sku' => '12345', 178 | 'channel_sku' => '54321', 179 | 'transfer_price' => 50.0 180 | ] 181 | ], 182 | ], $order->getRawData()); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /tests/Product/ProductTest.php: -------------------------------------------------------------------------------- 1 | 4, 18 | 'number' => 'p_nr_external_test', 19 | 'change_date' => 1602833805, 20 | 'created_date' => 1525245206, 21 | 'sup_supplier' => [ 22 | 'identifier' => 'id', 23 | 'key' => 'w', 24 | ], 25 | 'activations' => [ 26 | 'channel_test' => 1 27 | ], 28 | 'name' => [ 29 | 'x-default' => 'p_name_test' 30 | ], 31 | 'text' => [ 32 | 'x-default' => 'p_text_test' 33 | ], 34 | 'brand' => 'p_brand_test', 35 | 'media' => null, 36 | 'variantfields' => [ 37 | [ 38 | 'identifier' => 'name', 39 | 'key' => 'Farbe', 40 | 'value' => 'Farbe', 41 | ], 42 | [ 43 | 'identifier' => 'name', 44 | 'key' => 'Größe', 45 | 'value' => 'Größe', 46 | ] 47 | ], 48 | 'articles' => [ 49 | [ 50 | 'id' => 4, 51 | 'number' => 'a_nr_test', 52 | 'sup_supplier' => [ 53 | 'identifier' => 'id', 54 | 'key' => 'w', 55 | ], 56 | 'change_date' => 1532602476, 57 | 'created_date' => 1525245321, 58 | 'active' => true, 59 | 'ean' => 'a_ean_test', 60 | 'prod_number' => 'a_prod_nr_test', 61 | 'variants' => [ 62 | [ 63 | 'identifier' => 'name', 64 | 'key' => 'Farbe', 65 | 'values' => [ 66 | 'x-default' => 'weiß' 67 | ] 68 | ], 69 | [ 70 | 'identifier' => 'name', 71 | 'key' => 'Größe', 72 | 'values' => [ 73 | 'x-default' => '40' 74 | ] 75 | ] 76 | ], 77 | 'prices' => [ 78 | 'channel_test' => [ 79 | 'currency' => 'EUR', 80 | 'vk' => 27.0, 81 | 'vk_old' => 0.0, 82 | 'uvp' => 0.0, 83 | 'mwst' => 2, 84 | 'ek' => 12.48 85 | ] 86 | ], 87 | 'media' => [ 88 | [ 89 | 'type' => 'image', 90 | 'sort' => '10000010', 91 | 'origname' => '1.jpg', 92 | 'url' => 'a_media_url_test', 93 | ] 94 | ], 95 | 'unit' => 'ST', 96 | 'stock' => 5, 97 | 'delivery_time' => 1, 98 | 'replacement' => 0, 99 | 'replacement_time' => 0, 100 | 'order_min' => 0, 101 | 'order_max' => 0, 102 | 'order_interval' => 0, 103 | 'parcel' => [ 104 | 'pieces' => 1, 105 | 'width' => 35.0, 106 | 'height' => 5.0, 107 | 'length' => 23.0 108 | ] 109 | ], 110 | ] 111 | ]; 112 | } 113 | 114 | public function testGetCatalogFromFile(): void 115 | { 116 | $productHandler = (new Client())->getProductHandler(); 117 | $catalog = $productHandler->getCatalogFromFile(__DIR__ . '/../files/catalog.xml'); 118 | $products = $catalog->getProducts(); 119 | $products->rewind(); 120 | 121 | $this->assertSame( 122 | [ 123 | 'product' => $this->getProductFileRawData(), 124 | 'supplier_name' => 'supplier_name_test' 125 | ], 126 | [ 127 | 'product' => $products->current()->getRawData(), 128 | 'supplier_name' => $catalog->getSupplierName() 129 | ] 130 | ); 131 | } 132 | 133 | public function testGetProductFromFile(): void 134 | { 135 | $productHandler = (new Client())->getProductHandler(); 136 | $productModel = $productHandler->getProductFromFile(__DIR__ . '/../files/product.xml'); 137 | $this->assertSame($this->getProductFileRawData(), $productModel->getRawData()); 138 | } 139 | 140 | public function testProductObjectGetRawData(): void 141 | { 142 | $product = new Product(); 143 | $product->setId(1); 144 | 145 | $article = new Article(); 146 | $article->setId(1); 147 | $product->setArticles([$article]); 148 | $this->assertSame([ 149 | 'id' => 1, 150 | 'number' => null, 151 | 'change_date' => null, 152 | 'created_date' => null, 153 | 'sup_supplier' => null, 154 | 'activations' => null, 155 | 'name' => null, 156 | 'text' => null, 157 | 'brand' => null, 158 | 'media' => null, 159 | 'variantfields' => null, 160 | 'articles' => [ 161 | [ 162 | 'id' => 1, 163 | 'number' => null, 164 | 'sup_supplier' => null, 165 | 'change_date' => null, 166 | 'created_date' => null, 167 | 'active' => null, 168 | 'ean' => null, 169 | 'prod_number' => null, 170 | 'variants' => null, 171 | 'prices' => null, 172 | 'media' => null, 173 | 'unit' => null, 174 | 'stock' => null, 175 | 'delivery_time' => null, 176 | 'replacement' => null, 177 | 'replacement_time' => null, 178 | 'order_min' => null, 179 | 'order_max' => null, 180 | 'order_interval' => null, 181 | 'parcel' => null, 182 | ] 183 | ], 184 | ], $product->getRawData()); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /tests/Stock/StockListTest.php: -------------------------------------------------------------------------------- 1 | getStockHandler(); 16 | $catalog = $stockHandler->getStockListFromFile(__DIR__ . '/../files/stock.xml'); 17 | $stockIterator = $catalog->getStock(); 18 | $stockIterator->rewind(); 19 | $stockModel = $stockIterator->current(); 20 | 21 | $this->assertSame([ 22 | 'article_number' => 'a_nr_test', 23 | 'stock' => 2, 24 | ], $stockModel->getRawData()); 25 | 26 | $this->assertEquals('1602870040', $catalog->getChangeDate()); 27 | } 28 | 29 | public function testStockObjectGetRawData(): void 30 | { 31 | $stock = new Stock(); 32 | $stock->setStock(20); 33 | $stock->setArticleNumber('123456'); 34 | $this->assertSame([ 35 | 'article_number' => '123456', 36 | 'stock' => 20, 37 | ], $stock->getRawData()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/Stock/StockUpdateTest.php: -------------------------------------------------------------------------------- 1 |
12345' 16 | . '6' 17 | . '7
'; 18 | $mockRestClient = $this->getMockBuilder(Client\Rest::class) 19 | ->disableOriginalConstructor() 20 | ->onlyMethods(['postXML']) 21 | ->getMock(); 22 | $mockRestClient->expects($this->once()) 23 | ->method('postXML') 24 | ->with('articles/stock', $expectedXML); 25 | $mockClient = $this->getMockBuilder(Client::class) 26 | ->disableOriginalConstructor() 27 | ->onlyMethods(['getRestClient']) 28 | ->getMock(); 29 | $mockClient->expects($this->any()) 30 | ->method('getRestClient') 31 | ->willReturn($mockRestClient); 32 | $stockHandler = $mockClient->getStockHandler(); 33 | $stockHandler->updateStock( 34 | [ 35 | (new StockUpdate()) 36 | ->setArticleNumber('1234') 37 | ->setStock(5) 38 | ->addStockForWarehouse('test', 6) 39 | ->addStockForWarehouse('test2', 7) 40 | ] 41 | ); 42 | } 43 | 44 | public function testStockObjectGetRawData(): void 45 | { 46 | $stock = new StockUpdate(); 47 | $stock->setStock(20); 48 | $stock->addStockForWarehouse('warehouse', 20); 49 | $stock->addStockForWarehouse('warehouse2', 40); 50 | $stock->setArticleNumber('123456'); 51 | $this->assertSame([ 52 | 'article_number' => '123456', 53 | 'stock' => 20, 54 | 'stockForWarehouses' => [ 55 | 0 => [ 56 | 'identifier' => 'key', 57 | 'key' => 'warehouse', 58 | 'stock' => 20 59 | ], 60 | 1 => [ 61 | 62 | 'identifier' => 'key', 63 | 'key' => 'warehouse2', 64 | 'stock' => 40 65 | ] 66 | ] 67 | ], $stock->getRawData()); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/files/catalog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | supplier_name_test 8 | 9 | 10 | 11 | 12 | 2 13 | supplier_key_test 14 | supplier_key_name 15 | 4 16 | 17 | 18 | 4 19 | supplier2_key_test 20 | supplier_name_test 21 | 5 22 | 23 | 24 | 25 | 26 | 27 | 28 | 4 29 | p_nr_external_test 30 | 31 | 1602833805 32 | 1525245206 33 | 34 | 1 35 | 36 | 37 | p_name_test 38 | 39 | 40 | p_text_test 41 | 42 | p_brand_test 43 | 44 | Farbe 45 | Größe 46 | 47 | 48 |
49 | a_nr_test 50 | 4 51 | 52 | 1532602476 53 | 1525245321 54 | 1 55 | a_ean_test 56 | a_prod_nr_test 57 | 58 | 59 | weiß 60 | 61 | 62 | 40 63 | 64 | 65 | 66 | 67 | 27.00 68 | 0.00 69 | 0.00 70 | 2 71 | 12.48 72 | 73 | 74 | 75 | a_media_url_test 76 | 77 | ST 78 | 5 79 | 1 80 | 0 81 | 0 82 | 0 83 | 0 84 | 0 85 | 86 | 1 87 | 35 88 | 5 89 | 23 90 | 0.25 91 | 92 |
93 |
94 |
95 |
96 |
97 | -------------------------------------------------------------------------------- /tests/files/message.xml: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | type_test 4 | 2 5 | 3 6 | sku_test 7 | channel_sign_test 8 | channel_order_id_test 9 | channel_order_item_id_test 10 | channel_sku_test 11 | 4 12 | carrier_test 13 | idcode_test 14 | idcode_return_proposal_test 15 | 10 16 | comment_test 17 | return_cause_test 18 | return_state_test 19 | service_test 20 | est_ship_date_test 21 | 0 22 | 1 23 | 2016-09-09T14:14:17 24 | delivery_information_test 25 | 26 | -------------------------------------------------------------------------------- /tests/files/messagelist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | type_test 5 | 2 6 | 3 7 | sku_test 8 | channel_sign_test 9 | channel_order_id_test 10 | channel_order_item_id_test 11 | channel_sku_test 12 | 4 13 | carrier_test 14 | idcode_test 15 | idcode_return_proposal_test 16 | 10 17 | comment_test 18 | return_cause_test 19 | return_state_test 20 | service_test 21 | est_ship_date_test 22 | 0 23 | 1 24 | 2016-09-09T14:14:17 25 | delivery_information_test 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/files/order.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2018-11-07 5 | 1 6 | channel_sign_test 7 | channel_id_test 8 | channel_no_test 9 | 1 10 | 0 11 | customer_comment_test 12 | 1 13 | 1.00 14 | 2018-11-07T10:35:57 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/files/product.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 3 | p_nr_external_test 4 | 5 | 1602833805 6 | 1525245206 7 | 8 | 1 9 | 10 | 11 | p_name_test 12 | 13 | 14 | p_text_test 15 | 16 | p_brand_test 17 | 18 | Farbe 19 | Größe 20 | 21 | 22 |
23 | a_nr_test 24 | 4 25 | 26 | 1532602476 27 | 1525245321 28 | 1 29 | a_ean_test 30 | a_prod_nr_test 31 | 32 | 33 | weiß 34 | 35 | 36 | 40 37 | 38 | 39 | 40 | 41 | 27.00 42 | 0.00 43 | 0.00 44 | 2 45 | 12.48 46 | 47 | 48 | 49 | a_media_url_test 50 | 51 | ST 52 | 5 53 | 1 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 60 | 1 61 | 35 62 | 5 63 | 23 64 | 0.25 65 | 66 |
67 |
68 |
69 | -------------------------------------------------------------------------------- /tests/files/stock.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | a_nr_test 5 | 2 6 |
7 |
8 | --------------------------------------------------------------------------------