Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitexus committed Oct 10, 2023
1 parent 5876dfd commit 7283c9b
Show file tree
Hide file tree
Showing 6 changed files with 374 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
REALPAD_USERNAME=realpad
REALPAD_PASSWORD=realpad
10 changes: 6 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
composer.phar
/vendor/

# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
/nbproject/private/
/.env
/composer.lock
/nbproject/
/tests/.phpunit.result.cache
.vscode/settings.json
183 changes: 181 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,181 @@
# Realpad-Takeout
Realpad Takeout API Client to back up the data stored in the system.
# Realpad Takeout API Client for PHP

//for real estate developer IT / reporting departments, integrators, and
other 3rd parties//

This document describes how to use the Realpad Takeout API to back up the data stored in the
system. Both structured data (such as lists of customers, deals, etc) and files uploaded to the
CRM (unit plans, contract scans, ...) can be automatically retrieved this way. You are
encouraged to implement an automatic backup system that will download the data from our
server at any frequency you prefer, and use the data as a source for a reporting solution, or any
other purpose.

## Request

First of all please contact <[email protected]> to obtain the credentials to use the
Takeout API endpoints. You will perform POST requests over HTTPS and then store the
resulting data. Most of the Takeout endpoints have just 2 parameters, both required: `login`` and
`password`.

Example call in cURL:

```shell
curl \
--data "login=...&password=..." \
--output customers.xls \
https://cms.realpad.eu/ws/v10/list-excel-customers
```

### Response

#### Endpoints with XML payload

**list-resources**
The root element is `<resources>`, sub-elements look like this:

```xml
<resource
uid="bb938c51-891a-48d7-ba86-bea210a55c79"
content-type="image/jpeg"
file-name="some file.jpg"
size="224292"
crc="3826804066"/>
```

● uid is the unique identifier of this resource, by which it can be retrieved using
get-projects.
● content-type is the MIME type of the file, resolved when uploaded to the system (it’s
the best guess).
● file-name is the original file name when it was uploaded to the system.
● size is the file size in bytes.
● crc is the CRC32 checksum of the file.

This endpoint will always return all the resources. It’s up to your system to determine which
ones you haven’t downloaded yet. You may rely on UID as the unique identifier to distinguish
between the files. You can fetch resources using HTTP GET by retrieving a URL in the following
form: `<https://cms.realpad.eu/resource/><UID>`
Example call in cURL:

```shell
curl \
--output cached_resource \
https://cms.realpad.eu/resource/bd5563ae-abc...
```

## Endpoints with a binary payload

All of these endpoints return a single Excel file with a .xls extension, containing all the relevant
data stored in our system. These endpoints behave just like get-resource, in that the HTTP
headers contain a reasonable file name (e.g. when running from a web browser).
If an extra parameter xlsx is sent with a non-empty value, Takeout API will instead provide the
data in the Excel newer .xlsx format.

**list-excel-customers**
The last column contains the unique customer ID from the Realpad database.

**list-excel-products**
The last columns contain the unique unit ID, numeric ID of the unit type, numeric ID of the unit
availability, unique project ID and deal ID from the Realpad database. See the appendix for the
unit type and availability enums.

**list-excel-business-cases**
The last column contains the unique Deal ID from the Realpad database.

**list-excel-projects**
The last column contains the unique project ID from the Realpad database.

**list-excel-deal-documents**
The last three columns contain the unique document ID, customer ID, and sales agent ID from
the Realpad database. The first column is the relevant deal ID.

**list-excel-payments-prescribed**
The last column contains the unique payment ID from the Realpad database. The second
column is the relevant deal ID.

**list-excel-payments-incoming**
The first column contains the unique incoming payment ID from the Realpad database. The
second column is the relevant Deal ID.

**list-excel-additional-products**
The last columns contain the additional product ID, its type ID, and the ID of the associated
prescribed payment from the Realpad database. The first column is the relevant deal ID.

**list-excel-inspections**
Among the columns, there are those representing the deal ID and inspection ID from the
Realpad database.

**list-excel-defects**
Accepts an additional optional parameter mode. By default all the Deal Warranty Claim Defects
are returned. Certain developers will also see the Communal Areas Defects here by default. If
mode is specified, other Defects can be returned. Available modes are: DEAL_DEFECTS,
DEAL_DEFECTS_COMMUNAL_AREA, DEAL_DEFECTS_COMBINED, INSPECTION_DEFECTS,
INSPECTION_DEFECTS_COMMUNAL_AREA, INSPECTION_DEFECTS_COMBINED.
The last column contains the unique defect ID from the Realpad database. The second column
is the relevant deal ID.

**list-excel-tasks**
The last columns contain the task ID, customer ID, and sales agent ID from the Realpad
database.

**list-excel-events**
The last columns contain the event ID, customer ID, unit, and project ID from the Realpad
database.

**list-excel-sales-status**
The last column contains the unit ID from the Realpad database.

**list-excel-unit-history**
Accepts an additional required parameter unitid, which has to be a valid unit Realpad database
ID obtained from some other endpoint.
The first column contains the timestamp of when the given unit started containing the data on
the given row. The second column contains the name of the user who caused that data to be
recorded.

**list-excel-invoices**
Accepts several additional optional parameters:
● `filter_status`` - if left empty, invoices in all statuses are sent. 1 - new invoices. 2 -
invoices in Review #1. 3 - invoices in Review #2. 4 - invoices in approval. 5 - fully
approved invoices. 6 - fully rejected invoices.
`filter_groupcompany` - if left empty, invoices from all the group companies are sent. If
Realpad database IDs of group companies are provided (as a comma-separated list),
then only invoices from these companies are sent.
● `filter_issued_from`` - specify a date in the 2019-12-31 format to only send invoices
issues after that date.
`filter_issued_to` - specify a date in the 2019-12-31 format to only send invoices issues
before that date.
The initial set of columns describes the Invoice itself, and the last set of columns contains the
data of its Lines.

## Appendix

Unit status enumeration
● 0 - free.
● 1 - pre-reserved.
● 2 - reserved.
● 3 - sold.
● 4 - not for sale.
● 5 - delayed.

Unit type enumeration
● 1 - flat.
● 2 - parking.
● 3 - cellar.
● 4 - outdoor parking.
● 5 - garage.
● 6 - commercial space.
● 7 - family house.
● 8 - land.
● 9 - atelier.
● 10 - office.
● 11 - art workshop.
● 12 - non-residential unit.
● 13 - motorbike parking.
● 14 - creative workshop.
● 15 - townhouse.
● 16 - utility room.
● 17 - condominium.
● 18 - storage.
● 19 - apartment.
● 20 - accommodation unit.
● 21 - bike stand.
● 22 - communal area.
24 changes: 24 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "spojenet/realpad-takeout",
"description": "Realpad Takeout API Client",
"type": "library",
"require": {
"vitexsoftware/ease-core": "dev-main"
},
"require-dev": {
"phpunit/phpunit": "10.5.x-dev"
},
"license": "MIT",
"autoload": {
"psr-4": {
"SpojeNet\\Realpad\\": "src/"
}
},
"authors": [
{
"name": "CyberVitexus",
"email": "[email protected]"
}
],
"minimum-stability": "dev"
}
13 changes: 13 additions & 0 deletions examples/listexcelcustomers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

require_once __DIR__ . '/../vendor/autoload.php';


\Ease\Shared::init(['REALPAD_USERNAME','REALPAD_PASSWORD'], '../.env' );

$client = new \SpojeNet\Realpad\ApiClient();

$resources = $client->getResources();

print_r($resources);

148 changes: 148 additions & 0 deletions src/ApiClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php

/**
* Realpad Takeout client class
*
* @author Vítězslav Dvořák <[email protected]>
* @copyright 2023 SpojeNetIT s.r.o.
*/

declare(strict_types=1);

namespace SpojeNet\Realpad;

/**
* Connect to TakeOut
*
* @author vitex
*/
class ApiClient extends \Ease\Molecule
{
/**
* RealPad URI
* @var string
*/
public $baseEndpoint = 'https://cms.realpad.eu/';

private $debug;

private $curl;

private $timeout;

/**
* RealPad Data obtainer
*/
public function __construct()
{
$this->apiUsername = \Ease\Shared::cfg('REALPAD_USERNAME');
$this->apiPassword = \Ease\Shared::cfg('REALPAD_PASSWORD');
}

/**
* Inicializace CURL
*
* @return boolean Online Status
*/
public function curlInit()
{
if ($this->offline === false) {
$this->curl = \curl_init(); // create curl resource
\curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
\curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects
\curl_setopt($this->curl, CURLOPT_HTTPAUTH, true); // HTTP authentication
\curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, true);
\curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
\curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
if (empty($this->authSessionId)) {
\curl_setopt(
$this->curl,
CURLOPT_USERPWD,
$this->user . ':' . $this->password
); // set username and password
}
if (!is_null($this->timeout)) {
\curl_setopt($this->curl, CURLOPT_HTTPHEADER, [
'Connection: Keep-Alive',
'Keep-Alive: ' . $this->timeout
]);
\curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout);
}

\curl_setopt($this->curl, CURLOPT_USERAGENT, 'RealpadTakeout v' . \Ease\Shared::appVer() . ' https://github.com/Spoje-NET/Realpad-Takeout');
}
return !$this->offline;
}

/**
* Vykonej HTTP požadavek
*
* @param string $url URL požadavku
* @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
* @param string $format požadovaný formát komunikace
*
* @return int HTTP Response CODE
*/
public function doCurlRequest($url, $method, $format = null)
{
if (is_null($format)) {
$format = $this->format;
}
curl_setopt($this->curl, CURLOPT_URL, $url);
// Nastavení samotné operace
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
$httpHeaders = $this->defaultHttpHeaders;
$formats = Formats::bySuffix();
if (!isset($httpHeaders['Accept'])) {
$httpHeaders['Accept'] = $formats[$format]['content-type'];
}
if (!isset($httpHeaders['Content-Type'])) {
$httpHeaders['Content-Type'] = $formats[$format]['content-type'];
}

array_walk($httpHeaders, function (&$value, $header) {
$value = $header . ': ' . $value;
});
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeaders);
// Proveď samotnou operaci
$this->lastCurlResponse = curl_exec($this->curl);
$this->curlInfo = curl_getinfo($this->curl);
$this->curlInfo['when'] = microtime();
$this->responseFormat = $this->contentTypeToResponseFormat(strval($this->curlInfo['content_type']), $url);
$this->lastResponseCode = $this->curlInfo['http_code'];
$this->lastCurlError = curl_error($this->curl);
if (strlen($this->lastCurlError)) {
$msg = sprintf('Curl Error (HTTP %d): %s', $this->lastResponseCode, $this->lastCurlError);
$this->addStatusMessage($msg, 'error');
if ($this->throwException) {
throw new Exception($msg, $this);
}
}

if ($this->debug === true) {
$this->saveDebugFiles();
}
return $this->lastResponseCode;
}

/**
* Realpad server disconnect.
*/
public function disconnect()
{
if (is_resource($this->curl)) {
curl_close($this->curl);
}
$this->curl = null;
}

/**
*
*/
public function __destruct()
{
$this->disconnect();
}
}

0 comments on commit 7283c9b

Please sign in to comment.