Skip to content

Commit 0cf1c91

Browse files
committed
🍌 first commit
0 parents  commit 0cf1c91

30 files changed

+1836
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Exbil Bilgisayar
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.

README.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# 💾 Lexoffice PHP API
2+
3+
<div align="center">
4+
<a href="https://www.exbil.net"><img src="https://vweb01.exbil.net/images/logos/ylx31Wjx3YY.png" width="546" alt="discord.js" /></a>
5+
</div>
6+
7+
![visitors](https://visitor-badge.laobi.icu/badge?page_id=exbil.lexoffice-php-api)
8+
![](https://img.shields.io/badge/stable-v.1.0-informational?style=flat&logoColor=white&color=6aa6f8)
9+
![](https://img.shields.io/badge/license-MIT-informational?style=flat&logoColor=white&color=6aa6f8)
10+
11+
# Getting Started
12+
### Requirements
13+
* [**PHP 7.4+**](https://www.php.net/downloads.php)
14+
* Extensions: [Composer](https://getcomposer.org/), [PHP-JSON](https://www.php.net/manual/en/book.json.php)
15+
16+
# ⚒️ Install
17+
```bash
18+
composer require exbil/lexoffice-php-api
19+
```
20+
21+
# 📑 Usage
22+
23+
Search for the official API Documentation [here](https://developers.lexoffice.io/docs/).
24+
You need an [API Key](https://app.lexoffice.de/addons/public-api) for that.
25+
26+
### 🗃️ Basic
27+
28+
```php
29+
$apiKey = getenv('LEX_OFFICE_API_KEY'); // store keys in .env file
30+
$api = new \exbil\LexOffice\LexOfficeClient($apiKey);
31+
```
32+
33+
### 🗃️ set cache
34+
35+
```php
36+
// can be any PSR-6 compatibly cache handler
37+
// in this example we are using symfony/cache
38+
$cacheInterface = new \Symfony\Component\Cache\Adapter\FilesystemAdapter(
39+
'lexoffice',
40+
3600,
41+
__DIR__ . '/cache'
42+
);
43+
44+
$api->setCacheInterface($cacheInterface);
45+
```
46+
47+
### 🔚 Contact Endpoint
48+
49+
```php
50+
51+
// get a page
52+
/** @var \exbil\LexOffice\LexOfficeClient $api */
53+
$client = $api->contact();
54+
55+
$client->size = 100;
56+
$client->sortDirection = 'ASC';
57+
$client->sortProperty = 'name';
58+
59+
// get a page
60+
$response = $client->getPage(0);
61+
62+
//get all
63+
$response = $client->getAll();
64+
65+
// other methods
66+
$response = $client->get($entityId);
67+
$response = $client->create($data);
68+
```
69+
70+
### 🗺️ Country Endpoint
71+
```php
72+
$response = $api->country()->getAll();
73+
```
74+
75+
### 🔚 Invoices Endpoint
76+
```php
77+
$response = $api->invoice()->getAll();
78+
$response = $api->invoice()->get($entityId);
79+
$response = $api->invoice()->create($data);
80+
$response = $api->invoice()->document($entityId); // get document ID
81+
$response = $api->invoice()->document($entityId, true); // get file content
82+
```
83+
84+
### 🔚 Down Payment Invoices Endpoint
85+
```php
86+
$response = $api->downPaymentInvoice()->getAll();
87+
$response = $api->downPaymentInvoice()->get($entityId);
88+
$response = $api->downPaymentInvoice()->create($data);
89+
$response = $api->downPaymentInvoice()->document($entityId); // get document ID
90+
$response = $api->downPaymentInvoice()->document($entityId, true); // get file content
91+
```
92+
93+
### 💵 Order Confirmation Endpoint
94+
```php
95+
$response = $api->orderConfirmation()->getAll();
96+
$response = $api->orderConfirmation()->get($entityId);
97+
$response = $api->orderConfirmation()->create($data);
98+
$response = $api->orderConfirmation()->document($entityId); // get document ID
99+
$response = $api->orderConfirmation()->document($entityId, true); // get file content
100+
```
101+
102+
### 📃 Quotation Endpoint
103+
```php
104+
$response = $api->quotation()->getAll();
105+
$response = $api->quotation()->get($entityId);
106+
$response = $api->quotation()->create($data);
107+
$response = $api->quotation()->document($entityId); // get document ID
108+
$response = $api->quotation()->document($entityId, true); // get file content
109+
```
110+
111+
### 📄 Voucher Endpoint
112+
```php
113+
$response = $api->voucher()->getAll();
114+
$response = $api->voucher()->get($entityId);
115+
$response = $api->voucher()->create($data);
116+
$response = $api->voucher()->update($entityId, $data);
117+
$response = $api->voucher()->document($entityId); // get document ID
118+
$response = $api->voucher()->document($entityId, true); // get file content
119+
```
120+
121+
122+
### 💵 Credit Notes Endpoint
123+
```php
124+
$response = $api->creditNote()->getAll();
125+
$response = $api->creditNote()->get($entityId);
126+
$response = $api->creditNote()->create($data);
127+
$response = $api->creditNote()->document($entityId); // get document ID
128+
$response = $api->creditNote()->document($entityId, true); // get file content
129+
```
130+
131+
### 💵 Payment Endpoint
132+
```php
133+
$response = $api->payment()->get($entityId);
134+
```
135+
136+
### 💵 Payment Conditions Endpoint
137+
```php
138+
$response = $api->paymentCondition()->getAll();
139+
```
140+
141+
### 🗂️ Posting Categories Endpoint
142+
```php
143+
$response = $api->postingCategory()->getAll();
144+
```
145+
146+
### 🧑🏻 Profile Endpoint
147+
```php
148+
$response = $api->profile()->get();
149+
```
150+
151+
### 📜 Recurring Templates Endpoint
152+
```php
153+
154+
// get single entitiy
155+
$response = $api->recurringTemplate()->get($entityId);
156+
157+
// use pagination
158+
$client = $api->recurringTemplate();
159+
$client->size = 100;
160+
161+
162+
// get a page
163+
$response = $client->getPage(0);
164+
165+
//get all
166+
$response = $client->getAll();
167+
```
168+
169+
170+
### 🔚 Voucherlist Endpoint
171+
```php
172+
$client = $api->voucherlist();
173+
174+
$client->size = 100;
175+
$client->sortDirection = 'DESC';
176+
$client->sortColumn = 'voucherNumber';
177+
$client->types = [
178+
'salesinvoice',
179+
'salescreditnote',
180+
'purchaseinvoice',
181+
'purchasecreditnote',
182+
'invoice',
183+
'downpaymentinvoice',
184+
'creditnote',
185+
'orderconfirmation',
186+
'quotation'
187+
];
188+
$client->statuses = [
189+
'draft',
190+
'open',
191+
'paid',
192+
'paidoff',
193+
'voided',
194+
//'overdue', overdue can only be fetched alone
195+
'accepted',
196+
'rejected'
197+
];
198+
199+
// get everything what we can, not recommend:
200+
//$client->setToEverything()
201+
202+
// get a page
203+
$response = $client->getPage(0);
204+
205+
//get all
206+
$response = $client->getAll();
207+
```
208+
209+
### 📁 File Endpoint
210+
```php
211+
$response = $api->file()->upload($filePath, $voucherType);
212+
$response = $api->file()->get($entityId);
213+
```
214+
215+
216+
### ⚒️ Get JSON from Response
217+
218+
```php
219+
$json = $api->*()->getAsJson($response);
220+
```

composer.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "exbil/lexoffice-php-api",
3+
"type": "library",
4+
"description": "Simple API Integration for Lex-Office",
5+
"keywords": [
6+
"lex-office",
7+
"lexoffice",
8+
"rest",
9+
"api"
10+
],
11+
"license": "MIT",
12+
"require": {
13+
"php": "^7.4 | ^8",
14+
"ext-json": "*",
15+
"ext-curl": "*",
16+
"guzzlehttp/guzzle": "^6.2 | ^7.0",
17+
"psr/cache": "^1.0 | ^2.0 | ^3.0"
18+
},
19+
"require-dev": {
20+
"fzaninotto/faker": "^1.9.1",
21+
"phpunit/phpunit": "^9.0",
22+
"symfony/cache": "^5.1"
23+
},
24+
"autoload": {
25+
"psr-4": {
26+
"Exbil\\LexOffice\\": "src/"
27+
}
28+
},
29+
"autoload-dev": {
30+
"psr-4": {
31+
"Exbil\\LexOffice\\Tests\\": "tests/"
32+
}
33+
},
34+
"minimum-stability": "dev",
35+
"prefer-stable": true
36+
}

phpunit.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="true"
3+
colors="true"
4+
executionOrder="random"
5+
failOnRisky="true"
6+
failOnWarning="true"
7+
>
8+
<testsuites>
9+
<testsuite name="Test Suite">
10+
<directory>tests</directory>
11+
</testsuite>
12+
</testsuites>
13+
</phpunit>

src/BaseClient.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
4+
namespace Exbil\LexOffice;
5+
6+
use GuzzleHttp\Psr7\MultipartStream;
7+
use Psr\Http\Message\ResponseInterface;
8+
use Psr\Http\Message\StreamInterface;
9+
10+
abstract class BaseClient implements ClientInterface
11+
{
12+
protected string $resource;
13+
/**
14+
* @var LexOfficeClient $api
15+
*/
16+
protected LexOfficeClient $api;
17+
18+
public function __construct(LexOfficeClient $lexOffice)
19+
{
20+
$this->api = $lexOffice;
21+
}
22+
23+
/**
24+
* @param array $data
25+
* @return ResponseInterface
26+
* @throws Exceptions\CacheException
27+
* @throws Exceptions\LexOfficeApiException
28+
*/
29+
public function create(array $data)
30+
{
31+
$api = $this->api->newRequest('POST', $this->resource);
32+
33+
$api->request = $api->request->withBody($this->createStream($data));
34+
35+
return $api->getResponse();
36+
}
37+
38+
/**
39+
* @param string $id
40+
* @param array $data
41+
* @return void
42+
* @throws Exception
43+
*/
44+
public function update(string $id, array $data)
45+
{
46+
throw new Exceptions\BadMethodCallException('method update is not defined for ' . $this->resource);
47+
}
48+
49+
/**
50+
* @param string $id
51+
* @return ResponseInterface
52+
* @throws Exceptions\CacheException
53+
* @throws Exceptions\LexOfficeApiException
54+
*/
55+
public function get(string $id)
56+
{
57+
return $this->api->newRequest('GET', $this->resource . '/' . $id)
58+
->getResponse();
59+
}
60+
61+
/**
62+
* @param ResponseInterface $response
63+
* @return object
64+
*/
65+
public function getAsJson(ResponseInterface $response)
66+
{
67+
$body = $response->getBody()->__toString();
68+
69+
return Utils::jsonDecode($body);
70+
}
71+
72+
/**
73+
* @param mixed $content
74+
* @return StreamInterface
75+
*/
76+
protected function createStream($content): StreamInterface
77+
{
78+
return Utils::streamFor(
79+
Utils::jsonEncode($content)
80+
);
81+
}
82+
83+
/**
84+
* @param array $content
85+
* @param string|null $boundary
86+
* @return MultipartStream
87+
*/
88+
protected function createMultipartStream(array $content, string $boundary = null): MultipartStream
89+
{
90+
$stream = [];
91+
$boundary = $boundary ?: '--lexoffice';
92+
93+
foreach ($content as $key => $value) {
94+
$stream[] = [
95+
'name' => $key,
96+
'contents' => $value
97+
];
98+
}
99+
100+
return new MultipartStream($stream, $boundary);
101+
}
102+
}

0 commit comments

Comments
 (0)