diff --git a/forms-bridge/addons/bigin/class-bigin-addon.php b/forms-bridge/addons/bigin/class-bigin-addon.php index 49f06038..9c17ad95 100644 --- a/forms-bridge/addons/bigin/class-bigin-addon.php +++ b/forms-bridge/addons/bigin/class-bigin-addon.php @@ -101,12 +101,17 @@ public function ping( $backend ) { /** * Performs an introspection of the backend endpoint and returns API fields. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array List of fields and content type of the endpoint. */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { + if ( in_array( $method, array( 'POST', 'PUT' ), true ) ) { + return array(); + } + if ( ! preg_match( '/\/(([A-Z][a-z]+(_[A-Z][a-z])?)(?:\/upsert)?$)/', diff --git a/forms-bridge/addons/brevo/class-brevo-addon.php b/forms-bridge/addons/brevo/class-brevo-addon.php index b6d2b9b3..71d561e3 100644 --- a/forms-bridge/addons/brevo/class-brevo-addon.php +++ b/forms-bridge/addons/brevo/class-brevo-addon.php @@ -25,21 +25,28 @@ class Brevo_Addon extends Addon { * * @var string */ - const TITLE = 'Brevo'; + public const TITLE = 'Brevo'; /** * Handles the addon's name. * * @var string */ - const NAME = 'brevo'; + public const NAME = 'brevo'; /** * Handles the addom's custom bridge class. * * @var string */ - const BRIDGE = '\FORMS_BRIDGE\Brevo_Form_Bridge'; + public const BRIDGE = '\FORMS_BRIDGE\Brevo_Form_Bridge'; + + /** + * Holds the OAS URL. + * + * @var string + */ + public const OAS_URL = 'https://developers.brevo.com/reference/get_companies?json=on'; /** * Performs a request against the backend to check the connexion status. @@ -91,241 +98,99 @@ public function fetch( $endpoint, $backend ) { } /** - * Performs an introspection of the backend endpoint and returns API fields - * and accepted content type. + * Fetch available models from the OAS spec. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param Backend $backend HTTP backend object. * * @return array + * + * @todo Implementar el endpoint de consulta de endpoints disponibles. */ - public function get_endpoint_schema( $endpoint, $backend ) { - $bridge = new Brevo_Form_Bridge( + public function get_endpoints( $backend ) { + $response = wp_remote_get( + self::OAS_URL, array( - 'name' => '__brevo-' . time(), - 'endpoint' => $endpoint, - 'backend' => $backend, - 'method' => 'GET', + 'headers' => array( + 'Accept' => 'application/json', + 'Host' => 'developers.brevo.com', + 'Referer' => 'https://developers.brevo.com/reference/get_companies', + 'Alt-Used' => 'developers.brevo.com', + 'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0', + ), ) ); - if ( strstr( $bridge->endpoint, 'contacts' ) ) { - $response = $bridge - ->patch( - array( - 'name' => 'brevo-contacts-attributes', - 'endpoint' => '/v3/contacts/attributes', - 'method' => 'GET', - ) - ) - ->submit(); - - if ( is_wp_error( $response ) ) { - return array(); - } + if ( is_wp_error( $response ) ) { + return array(); + } - if ( $bridge->endpoint === '/v3/contacts/doubleOptinConfirmation' ) { - $fields = array( - array( - 'name' => 'email', - 'schema' => array( 'type' => 'string' ), - 'required' => true, - ), - array( - 'name' => 'includeListIds', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'integer' ), - ), - 'required' => true, - ), - array( - 'name' => 'excludeListIds', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'integer' ), - ), - ), - array( - 'name' => 'templateId', - 'schema' => array( 'type' => 'integer' ), - 'required' => true, - ), - array( - 'name' => 'redirectionUrl', - 'schema' => array( 'type' => 'string' ), - 'required' => true, - ), - array( - 'name' => 'attributes', - 'schema' => array( - 'type' => 'object', - 'properties' => array(), - ), - ), - ); - } else { - $fields = array( - array( - 'name' => 'email', - 'schema' => array( 'type' => 'string' ), - 'required' => true, - ), - array( - 'name' => 'ext_id', - 'schema' => array( 'type' => 'string' ), - ), - array( - 'name' => 'emailBlacklisted', - 'schema' => array( 'type' => 'boolean' ), - ), - array( - 'name' => 'smsBlacklisted', - 'schema' => array( 'type' => 'boolean' ), - ), - array( - 'name' => 'listIds', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'integer' ), - ), - ), - array( - 'name' => 'updateEnabled', - 'schema' => array( 'type' => 'boolean' ), - ), - array( - 'name' => 'smtpBlacklistSender', - 'schema' => array( 'type' => 'boolean' ), - ), - array( - 'name' => 'attributes', - 'schema' => array( - 'type' => 'object', - 'properties' => array(), - ), - ), - ); - } + $data = json_decode( $response['body'], true ); + $oa_explorer = new OpenAPI( $data['oasDefinition'] ); - foreach ( $response['data']['attributes'] as $attribute ) { - $fields[] = array( - 'name' => 'attributes.' . $attribute['name'], - 'schema' => array( 'type' => 'string' ), - ); - } + $paths = $oa_explorer->paths(); - return $fields; - } else { - if ( ! preg_match( '/\/([a-z]+)$/', $bridge->endpoint, $matches ) ) { - return array(); - } + return array_map( + function ( $path ) { + return '/v3' . $path; + }, + $paths, + ); + } - $module = $matches[1]; - $response = $bridge - ->patch( - array( - 'name' => "brevo-{$module}-attributes", - 'endpoint' => "/v3/crm/attributes/{$module}", - 'method' => 'GET', - ) - ) - ->submit(); + /** + * Performs an introspection of the backend endpoint and returns API fields + * and accepted content type. + * + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. + * + * @return array + */ + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { + $bytes = random_bytes( 16 ); + $bytes[6] = chr( ord( $bytes[6] ) & 0x0f | 0x40 ); // set version to 0100 + $bytes[8] = chr( ord( $bytes[8] ) & 0x3f | 0x80 ); // set bits 6-7 to 10 + $uuid = vsprintf( '%s%s-%s-%s-%s-%s%s%s', str_split( bin2hex( $bytes ), 4 ) ); + + $response = wp_remote_get( + self::OAS_URL, + array( + 'headers' => array( + 'Accept' => 'application/json', + 'Host' => 'developers.brevo.com', + 'Referer' => 'https://developers.brevo.com/reference/get_companies', + 'Alt-Used' => 'developers.brevo.com', + 'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0', + 'X-Requested-With' => 'XMLHttpRequest', + ), + 'cookies' => array( + 'anonymous_id' => $uuid, + 'first_referrer' => 'https://app.brevo.com/', + 'pscd' => 'get.brevo.com', + 'readme_language' => 'shell', + 'readme_library' => '{%22shell%22:%22curl%22}', + ), + ) + ); - if ( is_wp_error( $response ) ) { - return array(); - } + if ( is_wp_error( $response ) ) { + return array(); + } - if ( 'companies' === $module ) { - $fields = array( - array( - 'name' => 'name', - 'schema' => array( 'type' => 'string' ), - 'required' => true, - ), - array( - 'name' => 'countryCode', - 'schema' => array( 'type' => 'integer' ), - ), - array( - 'name' => 'linkedContactsIds', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'integer' ), - ), - ), - array( - 'name' => 'linkedDealsIds', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'integer' ), - ), - ), - array( - 'name' => 'attributes', - 'schema' => array( - 'type' => 'object', - 'properties' => array(), - ), - ), - ); - } elseif ( 'deals' === $module ) { - $fields = array( - array( - 'name' => 'name', - 'schema' => array( 'type' => 'string' ), - 'required' => true, - ), - array( - 'name' => 'linkedDealsIds', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'integer' ), - ), - ), - array( - 'name' => 'linkedCompaniesIds', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'integer' ), - ), - ), - array( - 'name' => 'attributes', - 'schema' => array( - 'type' => 'object', - 'properties' => array(), - ), - ), - ); - } + $data = json_decode( $response['body'], true ); + if ( ! $data ) { + return array(); + } - foreach ( $response['data'] as $attribute ) { - switch ( $attribute['attributeTypeName'] ) { - case 'number': - $type = 'number'; - break; - case 'text': - $type = 'string'; - break; - case 'user': - $type = 'email'; - break; - case 'date': - $type = 'date'; - break; - default: - $type = 'string'; - } + $oa_explorer = new OpenAPI( $data['oasDefinition'] ); - $fields[] = array( - 'name' => 'attributes.' . $attribute['internalName'], - 'schema' => array( 'type' => $type ), - ); - } + $method = strtolower( $method ?? 'post' ); + $path = preg_replace( '/^\/v\d+/', '', $endpoint ); + $source = in_array( $method, array( 'post', 'put', 'patch' ), true ) ? 'body' : 'query'; + $params = $oa_explorer->params( $path, $method, $source ); - return $fields; - } + return $params ?: array(); } } diff --git a/forms-bridge/addons/dolibarr/class-dolibarr-addon.php b/forms-bridge/addons/dolibarr/class-dolibarr-addon.php index 209fbf20..8c9e1f0f 100644 --- a/forms-bridge/addons/dolibarr/class-dolibarr-addon.php +++ b/forms-bridge/addons/dolibarr/class-dolibarr-addon.php @@ -7,6 +7,8 @@ namespace FORMS_BRIDGE; +use FORMS_BRIDGE\OpenAPI; + if ( ! defined( 'ABSPATH' ) ) { exit(); } @@ -21,25 +23,32 @@ class Dolibarr_Addon extends Addon { /** - * Handles the addon's title. + * Holds the addon's title. + * + * @var string + */ + public const TITLE = 'Dolibarr'; + + /** + * Holds the addon's name. * * @var string */ - const TITLE = 'Dolibarr'; + public const NAME = 'dolibarr'; /** - * Handles the addon's name. + * Holds the addom's custom bridge class. * * @var string */ - const NAME = 'dolibarr'; + public const BRIDGE = '\FORMS_BRIDGE\Dolibarr_Form_Bridge'; /** - * Handles the addom's custom bridge class. + * Holds the Dolibarr's REST API swagger.json endpoint. * * @var string */ - const BRIDGE = '\FORMS_BRIDGE\Dolibarr_Form_Bridge'; + public const SWAGGER_ENDPOINT = '/api/index.php/explorer/swagger.json'; /** * Performs a request against the backend to check the connexion status. @@ -101,22 +110,44 @@ public function fetch( $endpoint, $backend ) { * Performs an introspection of the backend endpoint and returns API fields * and accepted content type. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { $bridge = new Dolibarr_Form_Bridge( array( 'name' => '__dolibarr-' . time(), - 'endpoint' => $endpoint, + 'endpoint' => self::SWAGGER_ENDPOINT, 'backend' => $backend, 'method' => 'GET', ) ); - $response = $bridge->submit( array( 'limit' => 1 ) ); + $response = $bridge->submit(); + + if ( is_wp_error( $response ) ) { + return array(); + } + + $version = $response['data']['swagger'] ?? null; + if ( ! $version ) { + return array(); + } + + $oa_explorer = new OpenAPI( $response['data'] ); + + $path = preg_replace( '/.*\/api\/index.php/', '', $endpoint ); + $method = strtolower( $method ?? 'post' ); + $params = $oa_explorer->params( $path, $method ); + if ( empty( $params ) ) { + return array(); + } + + $response = $bridge->patch( array( 'endpoint' => $endpoint ) ) + ->submit( array( 'limit' => '1' ) ); if ( is_wp_error( $response ) ) { return array(); @@ -131,8 +162,6 @@ public function get_endpoint_schema( $endpoint, $backend ) { foreach ( $entry as $field => $value ) { if ( wp_is_numeric_array( $value ) ) { $type = 'array'; - } elseif ( is_array( $value ) ) { - $type = 'object'; } elseif ( is_double( $value ) ) { $type = 'number'; } elseif ( is_int( $value ) ) { diff --git a/forms-bridge/addons/financoop/class-financoop-addon.php b/forms-bridge/addons/financoop/class-financoop-addon.php index 9fd7a111..49cc4dc0 100644 --- a/forms-bridge/addons/financoop/class-financoop-addon.php +++ b/forms-bridge/addons/financoop/class-financoop-addon.php @@ -94,12 +94,17 @@ public function fetch( $endpoint, $backend ) { * Performs an introspection of the backend endpoint and returns API fields * and accepted content type. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { + if ( 'POST' !== $method ) { + return array(); + } + $bridge = new Finan_Coop_Form_Bridge( array( 'name' => '__financoop-' . time(), diff --git a/forms-bridge/addons/gsheets/class-gsheets-addon.php b/forms-bridge/addons/gsheets/class-gsheets-addon.php index be75d4fd..4109b145 100644 --- a/forms-bridge/addons/gsheets/class-gsheets-addon.php +++ b/forms-bridge/addons/gsheets/class-gsheets-addon.php @@ -156,12 +156,17 @@ public function fetch( $endpoint, $backend ) { * Performs an introspection of the backend endpoint and returns API fields * and accepted content type. * - * @param string $endpoint Concatenation of spreadsheet ID and tab name. - * @param string $backend Backend name. + * @param string $endpoint Concatenation of spreadsheet ID and tab name. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array List of fields and content type of the endpoint. */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { + if ( 'POST' !== $method ) { + return array(); + } + $bridges = FBAPI::get_addon_bridges( self::NAME ); foreach ( $bridges as $candidate ) { $data = $candidate->data(); diff --git a/forms-bridge/addons/holded/class-holded-addon.php b/forms-bridge/addons/holded/class-holded-addon.php index 0c2c1f33..409b7f65 100644 --- a/forms-bridge/addons/holded/class-holded-addon.php +++ b/forms-bridge/addons/holded/class-holded-addon.php @@ -23,25 +23,45 @@ class Holded_Addon extends Addon { /** - * Handles the addon's title. + * Holds the addon's title. * * @var string */ - const TITLE = 'Holded'; + public const TITLE = 'Holded'; /** - * Handles the addon's name. + * Holds the addon's name. * * @var string */ - const NAME = 'holded'; + public const NAME = 'holded'; /** - * Handles the addom's custom bridge class. + * Holds the addom's custom bridge class. * * @var string */ - const BRIDGE = '\FORMS_BRIDGE\Holded_Form_Bridge'; + public const BRIDGE = '\FORMS_BRIDGE\Holded_Form_Bridge'; + + /** + * Holds the OAS endpoints base URL. + * + * @var string + */ + public const OAS_BASE_URL = 'https://developers.holded.com/holded/api-next'; + + /** + * Holds the addon OAS URLs map. + * + * @var array + */ + public const OAS_URLS = array( + 'invoicing' => '/v2/branches/1.0/reference/list-contacts-1', + 'crm' => '/v2/branches/1.0/reference/list-leads-1', + 'projects' => '/v2/branches/1.0/reference/list-projects', + 'team' => '/v2/branches/1.0/reference/listemployees', + 'accounting' => '/v2/branches/1.0/reference/listdailyledger', + ); /** * Performs a request against the backend to check the connexion status. @@ -96,12 +116,13 @@ public function fetch( $endpoint, $backend ) { * Performs an introspection of the backend endpoint and returns API fields * and accepted content type. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array List of fields and content type of the endpoint. */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { $chunks = array_values( array_filter( explode( '/', $endpoint ) ) ); if ( empty( $chunks ) ) { return array(); @@ -114,75 +135,42 @@ public function get_endpoint_schema( $endpoint, $backend ) { [, $module, $version, $resource] = $chunks; - if ( - ! in_array( - $module, - array( - 'invoicing', - 'crm', - 'projects', - 'team', - 'accounting', - ), - true - ) || - 'v1' !== $version - ) { + $oas_url = self::OAS_URLS[ $module ] ?? null; + if ( ! $oas_url ) { return array(); } - $path = plugin_dir_path( __FILE__ ) . "/data/swagger/{$module}.json"; - if ( ! is_file( $path ) ) { - return array(); - } + $oas_url = self::OAS_BASE_URL . $oas_url . '?dereference=false&reduce=false'; + $response = wp_remote_get( + $oas_url, + array( + 'headers' => array( + 'Accept' => 'application/json', + 'Host' => 'developers.holded.com', + 'Alt-Used' => 'developers.holded.com', + 'Referer' => 'https://developers.holded.com/reference/list-contacts-1', + 'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0', + ), + ), + ); - $file_content = file_get_contents( $path ); - try { - $paths = json_decode( $file_content, true ); - } catch ( TypeError ) { + if ( is_wp_error( $response ) ) { return array(); } - $path = '/' . $resource; - if ( 'documents' === $resource ) { - $path .= '/{docType}'; - } - - if ( ! isset( $paths[ $path ] ) ) { + $data = json_decode( $response['body'], true ); + if ( ! $data ) { return array(); } - $schema = $paths[ $path ]; - if ( ! isset( $schema['post'] ) ) { - return array(); - } + $oa_explorer = new OpenAPI( $data['data']['api']['schema'] ); - $schema = $schema['post']; - - $fields = array(); - if ( isset( $schema['parameters'] ) ) { - foreach ( $schema['parameters'] as $param ) { - $fields[] = array( - 'name' => $param['name'], - 'schema' => $param['schema'], - ); - } - } elseif ( - isset( - $schema['requestBody']['content']['application/json']['schema']['properties'] - ) - ) { - $properties = - $schema['requestBody']['content']['application/json']['schema']['properties']; - foreach ( $properties as $name => $schema ) { - $fields[] = array( - 'name' => $name, - 'schema' => $schema, - ); - } - } + $method = strtolower( $method ?? 'post' ); + $path = preg_replace( '/\/api\/' . $module . '\/v\d+/', '', $endpoint ); + $source = in_array( $method, array( 'post', 'put', 'patch' ), true ) ? 'body' : 'query'; + $params = $oa_explorer->params( $path, $method, $source ); - return $fields; + return $params ?: array(); } } diff --git a/forms-bridge/addons/holded/data/swagger/accounting.json b/forms-bridge/addons/holded/data/swagger/accounting.json deleted file mode 100644 index 64584962..00000000 --- a/forms-bridge/addons/holded/data/swagger/accounting.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "/dailyledger": { - "get": { - "tags": ["Daily Ledger"], - "summary": "List all your entries", - "operationId": "listDailyLedger", - "description": "List all the entries you have in your daily ledger.\n", - "parameters": [ - { - "in": "query", - "name": "page", - "description": "the response is paginated and limited to 500 entries,", - "required": false, - "schema": { "type": "number" } - }, - { - "name": "starttmp", - "in": "query", - "description": "Starting timestamp", - "schema": { "type": "string" } - }, - { - "name": "endtmp", - "in": "query", - "description": "Ending timestamp", - "schema": { "type": "string" } - } - ], - "responses": { - "200": { "description": "search results matching criteria" }, - "400": { "description": "bad input parameter" } - } - } - }, - "/entry": { - "post": { - "tags": ["Daily Ledger"], - "summary": "Create entry", - "operationId": "createEntry", - "description": "Create a new accounting entry\n", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "date": { - "type": "integer", - "description": "Timestamp for entry date" - }, - "lines": { - "type": "array", - "items": { - "type": "object", - "properties": { - "account": { - "type": "integer", - "description": "Account number for this entry line" - }, - "credit": { "type": "number" }, - "debit": { "type": "number" }, - "description": { "type": "string" }, - "tags": { "type": "array", "items": { "type": "string" } } - }, - "required": ["account"] - } - }, - "notes": { "type": "string", "description": "Entry Note" } - }, - "required": ["date", "lines"] - } - } - } - }, - "responses": { - "200": { - "description": "The output when an entry has successfully been created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "entryGroupId": { "type": "string" } } - } - } - } - } - } - } - }, - "/chartofaccounts": { - "get": { - "tags": ["Chart of Accounts"], - "summary": "List all your accounting accounts", - "operationId": "listaccounts", - "description": "List all your accounting accounts.\n", - "parameters": [ - { - "name": "starttmp", - "in": "query", - "description": "Starting timestamp", - "schema": { "type": "string" } - }, - { - "name": "endtmp", - "in": "query", - "description": "Ending timestamp", - "schema": { "type": "string" } - }, - { - "name": "includeEmpty", - "in": "query", - "description": "Include Empty accounts (0: no include empty, 1: include empty)", - "required": false, - "schema": { "type": "number", "enum": [0, 1] } - } - ], - "responses": { - "200": { "description": "search results matching criteria" }, - "400": { "description": "bad input parameter" } - } - } - }, - "/account": { - "post": { - "tags": ["Chart of Accounts"], - "summary": "Create a new accounting account", - "operationId": "createAccount", - "description": "Create a new accounting account\n", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "prefix": { - "type": "integer", - "description": "4 digit prefix of the account to be created" - }, - "name": { - "type": "string", - "description": "Name of the account to be created (falls back to parent account name if empty)" - }, - "color": { "type": "string", "description": "Hex code" } - }, - "required": ["prefix"] - } - } - } - }, - "responses": { - "200": { - "description": "The output if an account has successfully been created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "accountId": { "type": "string" } } - } - } - } - } - } - } - } -} diff --git a/forms-bridge/addons/holded/data/swagger/crm.json b/forms-bridge/addons/holded/data/swagger/crm.json deleted file mode 100644 index dc9e13a2..00000000 --- a/forms-bridge/addons/holded/data/swagger/crm.json +++ /dev/null @@ -1,1865 +0,0 @@ -{ - "/funnels": { - "get": { - "operationId": "List Funnels", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/funnel-output" } - }, - "examples": { - "response": { - "value": [ - { - "id": "5acb866012d56e00100540e7", - "name": "Marketing funnel", - "stages": [ - { - "stageId": "5acb866012d56e00100540e2", - "key": "leadin", - "name": "Lead In", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e3", - "key": "contacted", - "name": "Contacted", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e4", - "key": "fitting", - "name": "Fitting", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e5", - "key": "proposal", - "name": "Proposal", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e6", - "key": "closing", - "name": "Closing", - "desc": "" - } - ], - "won": { "num": 2, "value": 3490093 }, - "leads": { "num": 1, "value": 2343546 }, - "lost": { "num": 1, "value": 2334454 }, - "recentWon": [ - "5acb866f12d56e000a3b0c23", - "5acb86b112d56e00110130b2" - ], - "recentLeads": ["5acb873c12d56e001d137e62"], - "recentLost": ["5acb86e512d56e0016586e32"], - "labels": [ - { - "labelId": "5acb87b312d56e001b10afa3", - "labelName": "Marketing", - "labelColor": "#33ffff" - } - ], - "preferences": { "emails": [] }, - "customFields": [] - } - ] - } - } - } - } - } - }, - "tags": ["FUNNELS"], - "description": "Get all your funnels." - }, - "post": { - "operationId": "Create Funnel", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "name": { "type": "string" } }, - "required": ["name"] - } - } - }, - "x-examples": { "application/json": { "name": "New funnel" } } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["FUNNELS"], - "description": "Create a new funnel." - } - }, - "/funnels/{funnelId}": { - "parameters": [ - { - "name": "funnelId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Funnel", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "stages": { - "type": "array", - "items": { - "type": "object", - "properties": { - "stageId": { "type": "string" }, - "key": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" } - } - } - }, - "won": { - "type": "object", - "properties": { - "num": { "type": "integer" }, - "value": { "type": "integer" } - } - }, - "leads": { - "type": "object", - "properties": { - "num": { "type": "integer" }, - "value": { "type": "integer" } - } - }, - "lost": { - "type": "object", - "properties": { - "num": { "type": "integer" }, - "value": { "type": "integer" } - } - }, - "recentWon": { - "type": "array", - "items": { "type": "string" } - }, - "recentLeads": { - "type": "array", - "items": { "type": "string" } - }, - "recentLost": { - "type": "array", - "items": { "type": "string" } - }, - "labels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "labelId": { "type": "string" }, - "labelName": { "type": "string" }, - "labelColor": { "type": "string" } - } - } - }, - "preferences": { - "type": "object", - "properties": { - "emails": { - "type": "array", - "items": { "type": "object" } - } - } - }, - "customFields": { - "type": "array", - "items": { "type": "object" } - } - } - }, - "examples": { - "response": { - "value": { - "id": "5acb866012d56e00100540e7", - "name": "Marketing funnel", - "stages": [ - { - "stageId": "5acb866012d56e00100540e2", - "key": "leadin", - "name": "Lead In", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e3", - "key": "contacted", - "name": "Contacted", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e4", - "key": "fitting", - "name": "Fitting", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e5", - "key": "proposal", - "name": "Proposal", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e6", - "key": "closing", - "name": "Closing", - "desc": "" - } - ], - "won": { "num": 2, "value": 3490093 }, - "leads": { "num": 1, "value": 2343546 }, - "lost": { "num": 1, "value": 2334454 }, - "recentWon": [ - "5acb866f12d56e000a3b0c23", - "5acb86b112d56e00110130b2" - ], - "recentLeads": ["5acb873c12d56e001d137e62"], - "recentLost": ["5acb86e512d56e0016586e32"], - "labels": [ - { - "labelId": "5acb87b312d56e001b10afa3", - "labelName": "Marketing", - "labelColor": "#33ffff" - } - ], - "preferences": { "emails": [] }, - "customFields": [] - } - } - } - } - } - } - }, - "tags": ["FUNNELS"], - "description": "Get a specific funnel." - }, - "put": { - "operationId": "Update Funnel", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "stages": { - "type": "array", - "items": { - "type": "object", - "properties": { - "stageId": { "type": "string" }, - "key": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" } - } - } - }, - "labels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "labelId": { "type": "string" }, - "labelName": { "type": "string" }, - "labelColor": { "type": "string" } - } - } - }, - "preferences": { - "type": "object", - "properties": { - "emails": { "type": "array", "items": { "type": "object" } } - } - }, - "customFields": { - "type": "array", - "items": { "type": "object" } - } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Marketing funnel", - "stages": [ - { - "stageId": "5acb866012d56e00100540e2", - "key": "leadin", - "name": "Lead In", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e3", - "key": "contacted", - "name": "Contacted", - "desc": "" - }, - { - "stageId": "5acb866012d56e00100540e4", - "key": "fitting", - "name": "Fitting", - "desc": "" - } - ], - "labels": [ - { - "labelId": "5acb87b312d56e001b10afa3", - "labelName": "Marketing", - "labelColor": "#33ffff" - } - ], - "preferences": { "emails": [] }, - "customFields": [] - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["FUNNELS"], - "description": "Update a specific funnel.\n\nOnly the params included in the operation will update the funnel." - }, - "delete": { - "operationId": "Delete Funnel", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["FUNNELS"], - "description": "Delete a specific funnel." - } - }, - "/leads": { - "get": { - "operationId": "List Leads", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/lead-output" } - }, - "examples": { - "response": { - "value": [ - { - "id": "5ab27cc411aff3003e655fb3", - "userId": "5ab13e373697ac00e305444d", - "funnelId": "5ab13e373697ac00e305333b", - "contactId": "5aaa65e05b706400300ad246", - "contactName": "Gumersindo supply", - "name": "Gumersindo", - "person": 0, - "personName": "", - "value": 48000, - "potential": 100, - "dueDate": 1521646788, - "stageId": "5ab13e373697ac00e3053336", - "createdAt": 1521646788, - "updatedAt": 1521659747, - "customfields": [ - { "field": "New", "value": "custom field" }, - { "field": "other", "value": "custom field" } - ], - "status": 0, - "events": [ - { - "eventId": "5ab2863c11aff300532c40b3", - "type": "note", - "title": "Lunch!", - "desc": "My note", - "createdAt": 1521649212, - "userId": "5a05cc5a60cea100094baf22" - }, - { - "eventId": "5ab294d811aff300587d96c4", - "type": "note", - "title": "Dinner", - "desc": "other event", - "createdAt": 1521652952, - "userId": "" - }, - { - "eventId": "5ab29ba711aff300587d96c5", - "type": "note", - "title": "Skype", - "desc": "with Sindo", - "createdAt": 1521654695, - "userId": "" - } - ], - "tasks": [ - { - "taskId": "5acb8f0112d56e00201fed93", - "taskName": "call", - "taskStatus": 1 - }, - { - "taskId": "5acb8f1212d56e00227196e3", - "taskName": "invite to him a coffee", - "taskStatus": 0 - } - ], - "files": ["config.ini"] - } - ] - } - } - } - } - } - }, - "tags": ["LEADS"], - "description": "Get all your leads." - }, - "post": { - "operationId": "Create Lead", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "funnelId": { "type": "string" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "name": { "type": "string" }, - "value": { "type": "integer" }, - "potential": { "type": "integer" }, - "dueDate": { "type": "integer" }, - "stageId": { - "type": "string", - "description": "Either Stage ID or exact name are accepted. In the latter case, if there are multiple matches the oldest stage created will be selected." - } - } - } - } - }, - "x-examples": { - "application/json": { - "funnelId": "5ab13e373697ac00e305333b", - "contactId": "5aaa65e05b706400300ad246", - "contactName": "Gumersindo supply", - "name": "Gumersindo", - "value": 48000, - "potential": 100, - "dueDate": 1521646788, - "stageId": "5ab13e373697ac00e3053336" - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["LEADS"], - "description": "Create a new lead." - } - }, - "/leads/{leadId}": { - "parameters": [ - { - "name": "leadId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Lead", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "userId": { "type": "string" }, - "funnelId": { "type": "string" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "name": { "type": "string" }, - "person": { "type": "integer" }, - "personName": { "type": "string" }, - "value": { "type": "integer" }, - "potential": { "type": "integer" }, - "dueDate": { "type": "integer" }, - "stageId": { "type": "string" }, - "createdAt": { "type": "integer" }, - "updatedAt": { "type": "integer" }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { "type": "string" }, - "value": { "type": "string" }, - "": { "type": "string" } - } - } - }, - "status": { "type": "integer" }, - "events": { - "type": "array", - "items": { - "type": "object", - "properties": { - "eventId": { "type": "string" }, - "type": { "type": "string" }, - "title": { "type": "string" }, - "desc": { "type": "string" }, - "createdAt": { "type": "integer" }, - "userId": { "type": "string" } - } - } - }, - "tasks": { - "type": "array", - "items": { - "type": "object", - "properties": { - "taskId": { "type": "string" }, - "taskName": { "type": "string" }, - "taskStatus": { "type": "integer" } - } - } - }, - "files": { "type": "array", "items": { "type": "string" } } - } - }, - "examples": { - "response": { - "value": { - "id": "5ab27cc411aff3003e655fb3", - "userId": "5ab13e373697ac00e305444d", - "funnelId": "5ab13e373697ac00e305333b", - "contactId": "5aaa65e05b706400300ad246", - "contactName": "Gumersindo supply", - "name": "Gumersindo", - "person": 0, - "personName": "", - "value": 48000, - "potential": 100, - "dueDate": 1521646788, - "stageId": "5ab13e373697ac00e3053336", - "createdAt": 1521646788, - "updatedAt": 1521659747, - "customFields": [ - { "field": "New", "value": "custom field" }, - { "field": "other", "value": "custom field" } - ], - "status": 0, - "events": [ - { - "eventId": "5ab2863c11aff300532c40b3", - "type": "note", - "title": "Lunch!", - "desc": "My note", - "createdAt": 1521649212, - "userId": "5a05cc5a60cea100094baf22" - }, - { - "eventId": "5ab294d811aff300587d96c4", - "type": "note", - "title": "Dinner", - "desc": "other event", - "createdAt": 1521652952, - "userId": "" - }, - { - "eventId": "5ab29ba711aff300587d96c5", - "type": "note", - "title": "Skype", - "desc": "with Sindo", - "createdAt": 1521654695, - "userId": "" - } - ], - "tasks": [ - { - "taskId": "5acb8f0112d56e00201fed93", - "taskName": "call", - "taskStatus": 1 - }, - { - "taskId": "5acb8f1212d56e00227196e3", - "taskName": "invite to him a coffee", - "taskStatus": 0 - } - ], - "files": ["config.ini"] - } - } - } - } - } - } - }, - "tags": ["LEADS"], - "description": "Get a specific lead." - }, - "put": { - "operationId": "Update Lead", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "value": { "type": "integer" }, - "dueDate": { "type": "integer" }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { "type": "string" }, - "value": { "type": "string" } - } - } - }, - "status": { "type": "integer" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Gumersindo", - "value": 48000, - "dueDate": 1521646788, - "customFields": [ - { "field": "New", "value": "custom field" }, - { "field": "other", "value": "custom field" } - ], - "status": 0 - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["LEADS"], - "description": "Update a specific lead.\n\nOnly the params included in the operation will update the lead." - }, - "delete": { - "operationId": "Delete Lead", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["LEADS"], - "description": "Delete a specific lead." - } - }, - "/leads/{leadId}/notes": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "operationId": "Create Lead Note", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "title": { "type": "string" }, - "desc": { "type": "string" } - }, - "required": ["title"] - } - } - }, - "x-examples": { - "application/json": { - "title": "New note", - "desc": "this note is a reminder" - } - } - }, - "tags": ["LEADS"], - "description": "Create a new lead note." - }, - "parameters": [ - { - "name": "leadId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "put": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "operationId": "Update Lead Note", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "noteId": { "type": "string" }, - "title": { "type": "string" }, - "desc": { "type": "string" } - }, - "required": ["noteId"] - } - } - }, - "x-examples": { - "application/json": { - "noteId": "3on4o2h0u2080282bn", - "title": "Meeting", - "desc": "remionder for the meeting" - } - } - }, - "tags": ["LEADS"], - "description": "Update a specific lead note.\n\nOnly the params included in the operation will update the note." - } - }, - "/leads/{leadId}/tasks": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "operationId": "Create Lead Task", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "name": { "type": "string" } } - } - } - }, - "x-examples": { "application/json": { "name": "Main task" } } - }, - "tags": ["LEADS"], - "description": "Create a new lead task." - }, - "parameters": [ - { - "name": "leadId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "put": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "type": "object", "properties": {} } - } - } - } - }, - "operationId": "Update Lead Task", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "taskId": { "type": "string" }, - "name": { "type": "string" } - }, - "required": ["taskId"] - } - } - }, - "x-examples": { - "application/json": { - "taskId": "4hi5o3357840730857h", - "name": "new task name" - } - } - }, - "tags": ["LEADS"], - "description": "Update a specific lead task.\n\nOnly the params included in the operation will update the task." - }, - "delete": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "operationId": "Delete Lead Task", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "taskId": { "type": "string" } }, - "required": ["taskId"] - } - } - }, - "x-examples": { - "application/json": { "taskId": "5aba68b1c5d438006425ad45" } - } - }, - "tags": ["LEADS"], - "description": "Delete a specific lead task." - } - }, - "/leads/{leadId}/dates": { - "put": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "operationId": "Update Lead Creation Date", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "date": { "type": "integer" } } - } - } - }, - "x-examples": { "application/json": { "date": 11523287868 } } - }, - "tags": ["LEADS"], - "description": "Update a specific lead creation's date." - }, - "parameters": [ - { - "name": "leadId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/leads/{leadId}/stages": { - "put": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "operationId": "Update Lead Stage", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "stageId": { - "type": "string", - "description": "Either Stage ID or exact name are accepted. In the latter case, if there are multiple matches the oldest stage created will be selected." - } - } - } - } - }, - "x-examples": { - "application/json": { "stageId": "5ac4f2cec839ea004e18a463" } - } - }, - "tags": ["LEADS"], - "description": "Update a specific lead stage." - }, - "parameters": [ - { - "name": "leadId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/events": { - "get": { - "operationId": "List Events", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/event-output" } - }, - "examples": { - "response": { - "value": [ - { - "id": "5ab11f1a3697ac00cd0a6423", - "name": "Coffe with P", - "contactId": "5ab11f1a3697ac00cd0a6423", - "contactName": "Patrick", - "kind": "coffee", - "desc": "meeting tot alk about the incoming events", - "startDate": 1522228026, - "endDate": 15222229430, - "status": 0, - "tags": ["tig", "tag"], - "locationDesc": "c/ Llacuna, 12", - "leadId": "5acb873c12d56e001d137e62", - "funnelId": "5acb866012d56e00100540e7" - }, - { - "id": "5ab13ab03697ac00e3053333", - "name": "Dinner with P", - "contactId": "", - "contactName": null, - "kind": "dinner", - "desc": null, - "startDate": 1521564336, - "endDate": 3043132272, - "status": 0, - "tags": [], - "locationDesc": null - } - ] - } - } - } - } - } - }, - "tags": ["EVENTS"], - "description": "Get all your events." - }, - "post": { - "operationId": "Create Event", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "kind": { "type": "string" }, - "desc": { "type": "string" }, - "startDate": { "type": "integer" }, - "duration": { "type": "integer" }, - "status": { "type": "integer" }, - "tags": { "type": "array", "items": { "type": "string" } }, - "locationDesc": { "type": "string" }, - "leadId": { "type": "string" }, - "funnelId": { "type": "string" }, - "userId": { "type": "string" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Coffe with P", - "contactId": "5ab11f1a3697ac00cd0a6423", - "contactName": "Patrick", - "kind": "coffee", - "desc": "meeting to talk about the incoming events", - "startDate": 1522228026, - "duration": 3600, - "status": 0, - "tags": ["tig", "tag"], - "locationDesc": "c/ Llacuna, 12", - "leadId": "5acb873c12d56e001d137e62", - "funnelId": "5acb866012d56e00100540e7" - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["EVENTS"], - "description": "Create a new event." - } - }, - "/events/{eventId}": { - "parameters": [ - { - "name": "eventId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Event", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/event-output-detailed" - }, - "examples": { - "response": { - "value": { - "id": "5ab11f1a3697ac00cd0a6423", - "name": "Coffe with P", - "contactId": "5ab11f1a3697ac00cd0a6423", - "contactName": "Patrick", - "kind": "coffee", - "desc": "meeting tot alk about the incoming events", - "startDate": 1522228026, - "endDate": 15222229430, - "status": 0, - "tags": ["tig", "tag"], - "locationDesc": "c/ Llacuna, 12", - "leadId": "5acb873c12d56e001d137e62", - "funnelId": "5acb866012d56e00100540e7" - } - } - } - } - } - } - }, - "tags": ["EVENTS"], - "description": "Get a specific event." - }, - "put": { - "operationId": "Update Event", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "kind": { "type": "string" }, - "desc": { "type": "string" }, - "startDate": { "type": "integer" }, - "duration": { "type": "integer" }, - "status": { "type": "integer" }, - "tags": { "type": "array", "items": { "type": "string" } }, - "locationDesc": { "type": "string" }, - "leadId": { "type": "string" }, - "funnelId": { "type": "string" }, - "userId": { "type": "string" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Coffe with Patrick", - "contactId": "5ab11f1a3697ac00cd0a6423", - "contactName": "Patrick", - "kind": "coffee", - "desc": "meeting to talk about the incoming events", - "startDate": 1522228026, - "duration": 3600, - "status": 0, - "tags": ["tig", "tag"], - "locationDesc": "c/ Llacuna, 12", - "leadId": "5acb873c12d56e001d137e62", - "funnelId": "5acb866012d56e00100540e7" - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["EVENTS"], - "description": "Update a specific event.\n\nOnly the params included in the operation will update the event." - }, - "delete": { - "operationId": "Delete Event", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["EVENTS"], - "description": "Delete a specific event." - } - }, - "/bookings/locations": { - "get": { - "operationId": "List Locations", - "responses": { - "200": { - "description": "List of account locations", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/location-output" } - }, - "examples": { - "response": { - "value": [ - { - "id": "5ab11f1a3697ac00cd0a6423", - "name": "Tienda en Girona", - "description": "Lorem ipsum dolor sit amet.", - "active": true, - "availableServices": [ - "67167a61f7ce326e820ab569", - "67167a61f7ce326e820ab568" - ] - }, - { - "id": "5ab11f1a3697ac00cd0a6424", - "name": "Tienda en Barcelona", - "description": "Lorem ipsum dolor sit amet.", - "active": false, - "availableServices": [] - } - ] - } - } - } - } - } - }, - "tags": ["BOOKINGS"], - "description": "Get all your locations." - } - }, - "/bookings/locations/{locationId}/slots": { - "parameters": [ - { - "name": "locationId", - "in": "path", - "required": true, - "description": "Specific location ID", - "schema": { "type": "string" } - }, - { - "name": "serviceId", - "in": "query", - "required": true, - "description": "Specific service ID", - "schema": { "type": "string" } - }, - { - "name": "day", - "in": "query", - "required": true, - "description": "Specific day (yyyy-mm-dd)", - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get available slots for location", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/booking-slot" } - }, - "examples": { - "response": { - "value": [ - { - "dateTime": 1732615200, - "from": "2024-11-26T10:00:00+00:00", - "to": "2024-11-26T10:30:00+00:00", - "duration": 1800 - }, - { - "dateTime": 1732616100, - "from": "2024-11-26T10:15:00+00:00", - "to": "2024-11-26T10:45:00+00:00", - "duration": 1800 - }, - { - "dateTime": 1732617000, - "from": "2024-11-26T10:30:00+00:00", - "to": "2024-11-26T11:00:00+00:00", - "duration": 1800 - } - ] - } - } - } - } - } - }, - "tags": ["BOOKINGS"], - "description": "Get a list of available time slots for a location, specifying a service and a date." - } - }, - "/bookings": { - "get": { - "operationId": "List Bookings", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/booking-output" } - }, - "examples": { - "response": { - "value": [ - { - "id": "5ab11f1a3697ac00cd0a6423", - "startTime": 1726124400, - "endTime": 1726125900, - "duration": 1500, - "createdAt": 1725619450, - "updatedAt": 1725619450, - "status": "confirmed", - "service": [ - { - "id": "66704f4a0ace9fc5e30078b5", - "name": "Planchado", - "description": "Planchado de pelo", - "duration": 1500, - "subtotal": [{ "amount": 2.48, "currency": "EUR" }], - "total": [{ "amount": 3, "currency": "EUR" }] - } - ], - "space": [ - { "id": "66ac8cab99b9e2b2310bdd66", "name": "Sala 1A" } - ], - "outcome": [ - { - "documentId": "6717b925f2753f36670594a6", - "type": "salesreceipt", - "exportedAt": 1729607974 - } - ], - "customFields": [ - { - "key": "name", - "label": "Nombre", - "type": "text", - "value": "Jon Snow" - }, - { - "key": "email", - "label": "E-mail", - "type": "email", - "value": "jon.snow@somemail.com" - } - ] - }, - { - "id": "5ab11f1a3697ac00cd0a6422", - "startTime": 1726124400, - "endTime": 1726125900, - "duration": 1500, - "createdAt": 1725619450, - "updatedAt": 1725619450, - "status": "confirmed", - "service": [ - { - "id": "66704f4a0ace9fc5e30078b6", - "name": "Corte", - "description": "Corte de pelo", - "duration": 1500, - "subtotal": [{ "amount": 2.48, "currency": "EUR" }], - "total": [{ "amount": 3, "currency": "EUR" }] - } - ], - "space": [ - { "id": "66ac8cab99b9e2b2310bdd67", "name": "Sala 1B" } - ], - "outcome": [ - { - "documentId": "6717b925f2753f36670594a7", - "type": "salesreceipt", - "exportedAt": 1729607974 - } - ], - "customFields": [ - { - "key": "name", - "label": "Nombre", - "type": "text", - "value": "Arya Stark" - }, - { - "key": "email", - "label": "E-mail", - "type": "email", - "value": "arya.stark@somemail.com" - } - ] - } - ] - } - } - } - } - } - }, - "tags": ["BOOKINGS"], - "description": "Get all your bookings." - }, - "post": { - "operationId": "Create Booking", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "locationId": { "type": "string" }, - "serviceId": { "type": "string" }, - "dateTime": { "type": "integer" }, - "timezone": { "type": "string" }, - "language": { "type": "string" }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "key": { "type": "string" }, - "value": { "type": "string" } - } - } - } - }, - "required": [ - "locationId", - "serviceId", - "dateTime", - "timezone", - "language", - "customFields" - ] - } - } - }, - "x-examples": { - "application/json": { - "locationId": "6710e0b21ab397666906c6f4", - "serviceId": "66704f4a0ace9fc5e30078b5", - "dateTime": 1730109600, - "timezone": "Europe/Luxembourg", - "language": "es", - "customFields": [ - { "key": "name", "value": "Jon Snow" }, - { "key": "email", "value": "jon.snow@somemail.com" } - ] - } - } - }, - "responses": { - "201": { - "description": "Booking created successfully", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "id": { "type": "string" } - } - } - } - } - }, - "410": { - "description": "Unavailable time slot", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - } - } - } - } - }, - "tags": ["BOOKINGS"], - "description": "Create new booking." - } - }, - "/bookings/{bookingId}": { - "parameters": [ - { - "name": "bookingId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Booking", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/booking-output-detailed" - }, - "examples": { "response": { "value": null } } - }, - "id": { - "examples": { - "response": { "value": "5ab11f1a3697ac00cd0a6423" } - } - } - } - } - }, - "tags": ["BOOKINGS"], - "description": "Get a specific booking." - }, - "put": { - "operationId": "Update Booking", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "dateTime": { "type": "integer" }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "key": { "type": "string" }, - "value": { "type": "string" } - } - } - } - } - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { "status": 1, "id": "5ac4f2cec839ea004e18a463" } - } - } - } - } - } - }, - "tags": ["BOOKINGS"], - "description": "Update a specific booking.\n\nOnly the params included in the operation will update the booking." - }, - "delete": { - "operationId": "Cancel Booking", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Booking canceled", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["BOOKINGS"], - "description": "Cancel a specific booking." - } - } -} diff --git a/forms-bridge/addons/holded/data/swagger/invoicing.json b/forms-bridge/addons/holded/data/swagger/invoicing.json deleted file mode 100644 index cf611503..00000000 --- a/forms-bridge/addons/holded/data/swagger/invoicing.json +++ /dev/null @@ -1,4214 +0,0 @@ -{ - "/contacts": { - "get": { - "operationId": "List Contacts", - "parameters": [ - { - "name": "phone", - "in": "query", - "required": false, - "description": "Must be an exact match, including special characters like \"+\", \"#\", and \"-\".", - "schema": { "type": "string" } - }, - { - "name": "mobile", - "in": "query", - "required": false, - "description": "Must be an exact match, including special characters like \"+\", \"#\", and \"-\".", - "schema": { "type": "string" } - }, - { - "name": "customId", - "in": "query", - "required": false, - "description": "Return only the contacts that matches with the provided customId", - "style": "form", - "explode": false, - "schema": { "type": "array", "items": { "type": "string" } } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "customId": { "type": "string" }, - "name": { "type": "string" }, - "code": { "type": "string" }, - "tradeName": { "type": "string" }, - "email": { "type": "string" }, - "mobile": { "type": "string" }, - "phone": { "type": "string" }, - "type": { "type": "string" }, - "iban": { "type": "string" }, - "swift": { "type": "string" }, - "clientRecord": { "type": "integer" }, - "supplierRecord": { "type": "integer" }, - "billAddress": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "integer" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" }, - "info": { "type": "string" } - } - }, - "defaults": { - "type": "object", - "properties": { - "salesChannel": { "type": "integer" }, - "expensesAccount": { "type": "integer" }, - "dueDays": { "type": "integer" }, - "paymentMethod": { "type": "integer" }, - "discount": { "type": "integer" }, - "language": { "type": "string" }, - "currency": { "type": "string" }, - "tax": { "type": "string" }, - "retention": { "type": "string" } - } - }, - "socialNetworks": { - "type": "object", - "properties": { "website": { "type": "string" } } - }, - "tags": { "type": "array", "items": { "type": "string" } }, - "notes": { - "type": "array", - "items": { - "type": "object", - "properties": { - "noteId": { "type": "string" }, - "name": { "type": "string" }, - "description": { "type": "string" }, - "color": { "type": "string" }, - "updatedAt": { "type": "integer" }, - "userId": { "type": "string" } - } - } - }, - "contactPersons": { - "type": "array", - "items": { - "type": "object", - "properties": { - "personId": { "type": "string" }, - "name": { "type": "string" }, - "job": { "type": "string" }, - "phone": { "type": "string" }, - "email": { "type": "string" }, - "sendDocumentsByDefault": { "type": "boolean" }, - "linkedin": { "type": "string" } - } - } - }, - "shippingAddresses": { - "type": "array", - "items": { - "type": "object", - "properties": { - "shippingId": { "type": "string" }, - "name": { "type": "string" }, - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "integer" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" }, - "notes": { "type": "string" }, - "privateNotes": { "type": "string" } - } - } - }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { "type": "string" }, - "value": { "type": "string" } - } - } - } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5aaa43d35b7064002613c048", - "customId": "myReferenceId", - "name": "Custom Tech Inc.", - "code": "B3737387", - "tradeName": "Mapple", - "email": "email@mapple.com", - "mobile": "63738383", - "phone": "3949494", - "type": "client", - "iban": "ES436677378638786", - "swift": "", - "clientRecord": 0, - "supplierRecord": 0, - "billAddress": { - "address": "Carrer del Mar", - "city": "Barcelona", - "postalCode": 8767, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES", - "info": "Random info" - }, - "defaults": { - "salesChannel": 0, - "expensesAccount": 0, - "dueDays": 3, - "paymentMethod": 0, - "discount": 45, - "language": "fr", - "currency": "eur", - "tax": "default", - "retention": "default" - }, - "socialNetworks": { "website": "www.mapple.com" }, - "tags": ["tag", "otherTag"], - "notes": [ - { - "noteId": "5aba2365c5d43800316b2a53", - "name": "My first note", - "description": "An important note", - "color": "primary", - "updatedAt": 1522148197, - "userId": "5a05cc5a60cea100094baf22" - }, - { - "noteId": "5aba26efc5d43800316b2a54", - "name": "Note", - "description": "Another note", - "color": "#ee575d", - "updatedAt": 1522149103, - "userId": "" - } - ], - "contactPersons": [ - { - "personId": "5aba40fdc5d43800316b2a55", - "name": "Pep", - "job": "Ito", - "phone": "966", - "email": "noway@frog.com", - "sendDocumentsByDefault": true, - "linkedin": "no link" - } - ], - "shippingAddresses": [ - { - "shippingId": "5aba4147c5d43800342fc4a3", - "name": "Mapple shipping address", - "address": "c/Lafranch", - "city": "Vilafranca del Monport ", - "postalCode": 899, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES", - "notes": "A public note", - "privateNotes": "This is a private note, don't read it" - } - ], - "customFields": [ - { "field": "FieldOne", "value": "valueOne" } - ] - } - ] - } - } - } - } - } - }, - "tags": ["CONTACTS"], - "summary": "List Contacts", - "description": "Get all your contact." - }, - "post": { - "operationId": "Create Contact", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "CustomId": { "type": "string" }, - "name": { "type": "string" }, - "code": { "type": "string" }, - "email": { "type": "string" }, - "mobile": { "type": "string" }, - "phone": { "type": "string" }, - "type": { - "type": "string", - "description": "Options: supplier, debtor, creditor, client, lead" - }, - "isperson": { - "type": "boolean", - "description": "When true the contact is created as a Contact Person instead of as a Company" - }, - "iban": { "type": "string" }, - "swift": { "type": "string" }, - "sepaRef": { "type": "string" }, - "groupId": { "type": "string" }, - "taxOperation": { - "type": "string", - "description": "options for Spain (general, intra, impexp, nosujeto, receq, exento)" - }, - "sepaDate": { "type": "number" }, - "clientRecord": { "type": "integer" }, - "supplierRecord": { "type": "integer" }, - "billAddress": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" } - } - }, - "numberingSeries": { - "type": "object", - "description": "The value of each document should be a valid ID.", - "properties": { - "invoice": { "type": "string" }, - "receipt": { "type": "string" }, - "salesOrder": { "type": "string" }, - "purchasesOrder": { "type": "string" }, - "proform": { "type": "string" }, - "waybill": { "type": "string" } - } - }, - "shippingAddresses": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "note": { "type": "string" }, - "privateNote": { "type": "string" } - } - } - }, - "defaults": { - "type": "object", - "properties": { - "expensesAccountRecord": { "type": "integer" }, - "expensesAccountName": { "type": "string" }, - "salesAccountRecord": { "type": "integer" }, - "salesAccountName": { "type": "string" }, - "dueDays": { "type": "integer" }, - "salesTax": { "type": "integer" }, - "salesTaxes": { - "type": "array", - "items": { "type": "string" } - }, - "purchasesTax": { "type": "integer" }, - "purchasesTaxes": { - "type": "array", - "items": { "type": "string" } - }, - "accumulateInForm347": { - "type": "string", - "description": "Yes or No" - }, - "paymentMethod": { - "type": "string", - "description": "Should be a valid ID" - }, - "discount": { "type": "integer" }, - "currency": { - "type": "string", - "description": "Currency ISO code in lowercase (e.g., eur = Euro, usd = U.S. Dollar, etc )" - }, - "language": { - "type": "string", - "description": "options (es = spanish, en = english, fr = french, de = german, it = italian, ca = catalan, eu = euskera)" - }, - "showTradeNameOnDocs": { "type": "boolean" }, - "showCountryOnDocs": { "type": "boolean" } - } - }, - "socialNetworks": { - "type": "object", - "properties": { "website": { "type": "string" } } - }, - "tags": { "type": "array", "items": { "type": "string" } }, - "note": { "type": "string" }, - "contactPersons": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "phone": { "type": "string" }, - "email": { "type": "string" } - } - }, - "required": ["name"] - } - } - } - } - }, - "x-examples": { - "application/json": { - "CustomId": "My reference", - "name": "Custom Tech Inc.", - "code": "B3737387", - "email": "email@mapple.com", - "mobile": "63738383", - "phone": "3949494", - "type": "supplier", - "iban": "ES436677378638786", - "swift": "", - "clientRecord": 0, - "supplierRecord": 0, - "billAddress": { - "address": "Carrer del Mar", - "city": "Barcelona", - "postalCode": 8767, - "province": "Barcelona", - "country": "Spain" - }, - "defaults": { - "salesChannel": 0, - "expensesAccount": 0, - "dueDays": 3, - "paymentMethod": 0, - "discount": 45, - "language": "fr", - "currency": "eur", - "tax": "default", - "retention": "default" - }, - "socialNetworks": { "website": "www.mapple.com" }, - "tags": ["tag", "otherTag"], - "notes": "My note", - "contactPersons": { - "name": "Pep", - "phone": "966", - "email": "noway@frog.com" - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["CONTACTS"], - "summary": "Create Contact", - "description": "Create a new contact." - } - }, - "/contacts/{contactId}": { - "parameters": [ - { - "name": "contactId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Contact", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "customId": { "type": "string" }, - "name": { "type": "string" }, - "code": { "type": "string" }, - "tradeName": { "type": "string" }, - "email": { "type": "string" }, - "mobile": { "type": "string" }, - "phone": { "type": "string" }, - "type": { "type": "string" }, - "iban": { "type": "string" }, - "swift": { "type": "string" }, - "clientRecord": { "type": "integer" }, - "supplierRecord": { "type": "integer" }, - "billAddress": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "integer" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" }, - "info": { "type": "string" } - } - }, - "defaults": { - "type": "object", - "properties": { - "salesChannel": { "type": "integer" }, - "expensesAccount": { "type": "integer" }, - "dueDays": { "type": "integer" }, - "paymentMethod": { "type": "integer" }, - "discount": { "type": "integer" }, - "language": { "type": "string" }, - "currency": { "type": "string" }, - "tax": { "type": "string" }, - "retention": { "type": "string" } - } - }, - "socialNetworks": { - "type": "object", - "properties": { "website": { "type": "string" } } - }, - "tags": { "type": "array", "items": { "type": "string" } }, - "notes": { - "type": "array", - "items": { - "type": "object", - "properties": { - "noteId": { "type": "string" }, - "name": { "type": "string" }, - "description": { "type": "string" }, - "color": { "type": "string" }, - "updatedAt": { "type": "integer" }, - "userId": { "type": "string" } - } - } - }, - "contactPersons": { - "type": "array", - "items": { - "type": "object", - "properties": { - "personId": { "type": "string" }, - "name": { "type": "string" }, - "job": { "type": "string" }, - "phone": { "type": "string" }, - "email": { "type": "string" }, - "sendDocumentsByDefault": { "type": "boolean" }, - "linkedin": { "type": "string" } - } - } - }, - "shippingAddresses": { - "type": "array", - "items": { - "type": "object", - "properties": { - "shippingId": { "type": "string" }, - "name": { "type": "string" }, - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "integer" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" }, - "notes": { "type": "string" }, - "privateNotes": { "type": "string" } - } - } - }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { "type": "string" }, - "value": { "type": "string" } - } - } - } - } - }, - "examples": { - "response": { - "value": { - "id": "5aaa43d35b7064002613c048", - "customId": "myReferenceId", - "name": "Custom Tech Inc.", - "code": "B3737387", - "tradeName": "Mapple", - "email": "email@mapple.com", - "mobile": "63738383", - "phone": "3949494", - "type": "client", - "iban": "ES436677378638786", - "swift": "", - "clientRecord": 0, - "supplierRecord": 0, - "billAddress": { - "address": "Carrer del Mar", - "city": "Barcelona", - "postalCode": 8767, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES", - "info": "Random info" - }, - "defaults": { - "salesChannel": 0, - "expensesAccount": 0, - "dueDays": 3, - "paymentMethod": 0, - "discount": 45, - "language": "fr", - "currency": "eur", - "tax": "default", - "retention": "default" - }, - "socialNetworks": { "website": "www.mapple.com" }, - "tags": ["tag", "otherTag"], - "notes": [ - { - "noteId": "5aba2365c5d43800316b2a53", - "name": "My first note", - "description": "An important note", - "color": "primary", - "updatedAt": 1522148197, - "userId": "5a05cc5a60cea100094baf22" - }, - { - "noteId": "5aba26efc5d43800316b2a54", - "name": "Note", - "description": "Another note", - "color": "#ee575d", - "updatedAt": 1522149103, - "userId": "" - } - ], - "contactPersons": [ - { - "personId": "5aba40fdc5d43800316b2a55", - "name": "Pep", - "job": "Ito", - "phone": "966", - "email": "noway@frog.com", - "sendDocumentsByDefault": true, - "linkedin": "no link" - } - ], - "shippingAddresses": [ - { - "shippingId": "5aba4147c5d43800342fc4a3", - "name": "Mapple shipping address", - "address": "c/LLafranch", - "city": "Vilafranca del Monport ", - "postalCode": 899, - "province": "Lleida", - "country": "Spain", - "countryCode": "ES", - "notes": "A public note", - "privateNotes": "This is a private note, don't read it" - } - ], - "customFields": [ - { "field": "FieldOne", "value": "noValue" } - ] - } - } - } - } - } - } - }, - "tags": ["CONTACTS"], - "summary": "Get Contact", - "description": "Get a specific contact." - }, - "put": { - "operationId": "Update Contact", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "code": { "type": "string" }, - "tradeName": { "type": "string" }, - "email": { "type": "string" }, - "mobile": { "type": "string" }, - "phone": { "type": "string" }, - "type": { - "type": "string", - "description": "Options: supplier, debtor, creditor, client, lead" - }, - "isperson": { - "type": "boolean", - "description": "When true the contact is created as a Contact Person instead of as a Company" - }, - "iban": { "type": "string" }, - "swift": { "type": "string" }, - "sepaRef": { "type": "string" }, - "sepaDate": { "type": "number" }, - "clientRecord": { "type": "integer" }, - "supplierRecord": { "type": "integer" }, - "groupId": { "type": "string" }, - "taxOperation": { - "type": "string", - "description": "options for Spain (general, intra, impexp, nosujeto, receq, exento)" - }, - "billAddress": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" } - } - }, - "shippingAddresses": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "notes": { "type": "string" }, - "privateNote": { "type": "string" } - } - } - }, - "defaults": { - "type": "object", - "properties": { - "expensesAccountRecord": { "type": "integer" }, - "expensesAccountName": { "type": "string" }, - "salesAccountRecord": { "type": "integer" }, - "salesAccountName": { "type": "string" }, - "dueDays": { "type": "integer" }, - "salesTax": { "type": "integer" }, - "purchasesTax": { "type": "integer" }, - "accumulateInForm347": { - "type": "string", - "description": "Yes or No" - }, - "paymentMethod": { - "type": "string", - "description": "Should be a valid ID." - }, - "discount": { "type": "integer" }, - "currency": { - "type": "string", - "description": "Currency ISO code in lowercase (e.g., eur = Euro, usd = U.S. Dollar, etc )" - }, - "language": { - "type": "string", - "description": "options (es = spanish, en = english, fr = french, de = german, it = italian, ca = catalan, eu = euskera)" - }, - "showTradeNameOnDocs": { "type": "boolean" }, - "showCountryOnDocs": { "type": "boolean" } - } - }, - "socialNetworks": { - "type": "object", - "properties": { "website": { "type": "string" } } - }, - "numberingSeries": { - "type": "object", - "description": "The value of each document should be a valid ID.", - "properties": { - "invoice": { "type": "string" }, - "receipt": { "type": "string" }, - "salesOrder": { "type": "string" }, - "purchasesOrder": { "type": "string" }, - "proform": { "type": "string" }, - "waybill": { "type": "string" } - } - } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Custom Tech Inc.", - "code": "B3737387", - "tradeName": "Mapple", - "email": "email@mapple.com", - "mobile": "63738383", - "phone": "3949494", - "type": "client", - "iban": "ES436677378638786", - "swift": "UJ45623456", - "clientRecord": 0, - "supplierRecord": 0, - "billAddress": { - "address": "Carrer del Mar", - "city": "Barcelona", - "postalCode": 8767, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES" - }, - "defaults": { - "salesChannel": 0, - "expensesAccount": 0, - "dueDays": 3, - "paymentMethod": 0, - "discount": 45, - "language": "fr" - }, - "socialNetworks": { "website": "www.mapple.com" } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["CONTACTS"], - "summary": "Update Contact", - "description": "Update a specific contact.\n\nOnly the params included in the operation will update the contact." - }, - "delete": { - "operationId": "Delete Contact", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["CONTACTS"], - "summary": "Delete Contact", - "description": "Delete specific contact" - } - }, - "/contacts/{contactId}/attachments/list": { - "parameters": [ - { - "name": "contactId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get attachments list", - "responses": { - "200": { - "description": "Get attachments list for a given contact", - "content": { - "application/json": { - "schema": { "type": "array", "items": { "type": "string" } } - } - } - } - }, - "tags": ["CONTACTS"], - "summary": "Get contact attachments list", - "description": "Get attachments list for a given contact." - } - }, - "/contacts/{contactId}/attachments/get": { - "parameters": [ - { - "name": "contactId", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "filename", - "in": "query", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get attachment", - "responses": { - "200": { - "description": "Get attachment", - "content": { - "application/json": { - "schema": { "type": "string", "format": "binary" } - } - } - } - }, - "tags": ["CONTACTS"], - "summary": "Get attachment", - "description": "Get attachment" - } - }, - "/contacts/groups": { - "get": { - "operationId": "List Contact Groups", - "summary": "List Contact Groups", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" } - } - } - } - } - } - } - }, - "tags": ["CONTACT GROUPS"] - }, - "post": { - "operationId": "Create Contact Group", - "summary": "Create Contact Group", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" } - }, - "required": ["name"] - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - }, - "tags": ["CONTACT GROUPS"] - } - }, - "/contacts/groups/{groupId}": { - "parameters": [ - { - "name": "groupId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Contact Group", - "summary": "Get Contact Group", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" } - } - } - } - } - } - }, - "tags": ["CONTACT GROUPS"] - }, - "put": { - "operationId": "Update Contact Group", - "summary": "Update Contact Group", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" } - } - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - }, - "tags": ["CONTACT GROUPS"] - }, - "delete": { - "operationId": "Delete Contact Group", - "summary": "Delete Contact Group", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["CONTACT GROUPS"] - } - }, - "/products": { - "get": { - "operationId": "List Products", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/product-output" } - }, - "examples": { - "response": { - "value": [ - { - "id": "5abbc9980823dd002b5c36f5", - "kind": "simple", - "name": "Brand new shirt", - "desc": "Black shirt", - "typeId": "5abbc8e40823dd00274ca482", - "contactId": "5aaa51ab5b70640028340186", - "contactName": "Iron Supply", - "price": 95, - "tax": 21, - "total": 119.45, - "rates": [], - "hasStock": 1, - "stock": 2, - "barcode": "45the54", - "sku": "23454657", - "cost": 20, - "purchasePrice": 11.5, - "weight": 0.5, - "tags": ["tig", "tag", "tug"], - "categoryId": "5abbc9110823dd0025411fb4", - "factoryCode": "32435g", - "attributes": [], - "forSale": 1, - "forPurchase": 1, - "salesChannelId": "5abbc324g3vdd002b5c36f3", - "expAccountId": "5abbc9980823d3245b5c36f3", - "warehouseId": "5abbc89e5823dd002b5c36f3", - "variants": [ - { - "id": "5abbc9980823dd002b5c36f3", - "barcode": "35647", - "sku": "34354", - "price": 45, - "cost": 20, - "purchasePrice": 11.5, - "stock": 2 - }, - { - "id": "5abbc9980823dd002b5c36f4", - "barcode": "", - "sku": "", - "price": 45, - "cost": 20, - "purchasePrice": 11.5, - "stock": 0 - } - ] - }, - { - "id": "5abbd1cf0823dd004562b685", - "kind": "simple", - "name": "Tata shoes", - "desc": "brand new shoes", - "typeId": "480yhfn2b3498o243upj2", - "contactId": "2p4hjrnfob3hli2khpn", - "contactName": "Tata industry", - "price": 100, - "tax": 21, - "total": 121, - "rates": [], - "hasStock": 1, - "stock": 234, - "barcode": "232435465", - "sku": "234rwt54", - "cost": 39, - "purchasePrice": 11, - "weight": 0, - "tags": [""], - "categoryId": "5abbd15e0823dd003b085005", - "factoryCode": "324t5f4", - "attributes": [], - "forSale": 1, - "forPurchase": 1, - "salesChannelId": "0", - "expAccountId": "0", - "warehouseId": "0", - "variants": [ - { - "id": "5abbd1cf0823dd004562b683", - "barcode": "123", - "sku": "123", - "price": 2, - "cost": 1, - "purchasePrice": 1, - "stock": 234 - }, - { - "id": "5abbd1cf0823dd004562b684", - "barcode": "", - "sku": "", - "price": 0, - "cost": 0, - "purchasePrice": 2, - "stock": 0 - } - ] - }, - { - "id": "5abbca020823dd00343d0a44", - "kind": "simple", - "name": "new simple product", - "desc": "the best simple product you can buy", - "typeId": "3l4kbn5j3oknl645t574354", - "contactId": "", - "contactName": "", - "price": 0, - "tax": 21, - "total": 0, - "rates": [], - "hasStock": 1, - "stock": 0, - "barcode": "", - "sku": "", - "cost": 0, - "purchasePrice": 0, - "weight": 0, - "tags": [""], - "categoryId": "0", - "factoryCode": "", - "attributes": [], - "forSale": 1, - "forPurchase": 1, - "salesChannelId": "0", - "expAccountId": "0", - "warehouseId": "0", - "variants": [ - { - "id": "5abbca020823dd00343d0a43", - "barcode": "", - "sku": "", - "price": 0, - "cost": 0, - "purchasePrice": 0, - "stock": 0 - } - ] - } - ] - } - } - } - } - } - }, - "tags": ["PRODUCTS"], - "summary": "List Products" - }, - "post": { - "operationId": "Create Product", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "kind": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "price": { "type": "number" }, - "tax": { "type": "number" }, - "cost": { "type": "number" }, - "calculatecost": { "type": "number" }, - "purchasePrice": { "type": "number" }, - "tags": { "type": "array", "items": { "type": "string" } }, - "barcode": { "type": "string" }, - "sku": { "type": "string" }, - "weight": { "type": "number" }, - "stock": { "type": "integer" } - } - } - } - }, - "x-examples": { - "application/json": {}, - "new": { "kind": "simple", "name": "Brand new shirt" } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5aa97e595b706400153f9f94" - } - } - } - } - } - } - }, - "tags": ["PRODUCTS"], - "summary": "Create Product" - } - }, - "/products/{productId}": { - "parameters": [ - { - "name": "productId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "put": { - "operationId": "Update Product", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "kind": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "tax": { "type": "integer" }, - "subtotal": { "type": "number" }, - "barcode": { "type": "string" }, - "sku": { "type": "string" }, - "cost": { "type": "number" }, - "purchasePrice": { "type": "number" }, - "weight": { "type": "number" } - } - } - } - }, - "x-examples": { - "application/json": { - "kind": "simple", - "name": "Brand new shirt", - "desc": "Black shirt", - "tax": 21, - "subtotal": 119.45, - "barcode": "45the54", - "sku": "23454657", - "cost": 20, - "purchasePrice": 10, - "weight": 0.5 - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5aa97e595b706400153f9f94" - } - } - } - } - } - } - }, - "tags": ["PRODUCTS"], - "summary": "Update Product" - }, - "delete": { - "operationId": "Delete Product", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["PRODUCTS"], - "summary": "Delete Product" - }, - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "type": "object", "properties": {} } - } - } - } - }, - "operationId": "Get product", - "summary": "Get Product", - "description": "Get a speccific product", - "tags": ["PRODUCTS"] - } - }, - "/warehouses": { - "get": { - "operationId": "List Warehouses", - "summary": "List Warehouses", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "userId": { "type": "string" }, - "name": { "type": "string" }, - "email": { "type": "string" }, - "phone": { "type": "string" }, - "mobile": { "type": "string" }, - "address": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" } - } - }, - "default": { "type": "boolean" }, - "warehouseRecord": { "type": "integer" } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5a05cc6e60cea100094baf2f", - "userId": "2344000h2o4b5s4n3o45", - "name": "Main Warehouse", - "email": "main@warehouse.com", - "phone": "765837638", - "mobile": "23456673", - "address": { - "address": "Av. Meridiana, 13", - "city": "Barcelona", - "postalCode": 3849, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES" - }, - "default": true, - "warehouseRecord": 30000001 - }, - { - "id": "5aab9ae87bdcef002641e0c3", - "userId": "5a05cc5a60cea100094baf22", - "name": "Second warehouse", - "email": "second@warehouse.com", - "phone": "", - "mobile": "", - "address": { - "address": "Main Street, 3", - "city": "London", - "postalCode": "04747", - "province": "London", - "country": "United Kingdom", - "countryCode": "UK" - }, - "default": false, - "warehouseRecord": null - }, - { - "id": "5aaba5237bdcef002c4979d5", - "userId": "", - "name": "Third warehouse", - "email": "third@warehouse.com", - "phone": "123", - "mobile": "123", - "address": { - "address": "Av. Blasco Ibañez, 34", - "city": "Valencia", - "postalCode": 8054, - "province": "Valencia", - "country": "Spain", - "countryCode": "ES" - }, - "default": false, - "warehouseRecord": null - } - ] - } - } - } - } - } - }, - "tags": ["WAREHOUSES"] - }, - "post": { - "operationId": "Create Warehouse", - "summary": "Create Warehouse", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "email": { "type": "string" }, - "phone": { "type": "string" }, - "mobile": { "type": "string" }, - "address": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" } - } - }, - "default": { "type": "boolean" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Main Warehouse", - "email": "main@warehouse.com", - "phone": "765837638", - "mobile": "23456673", - "address": { - "address": "Av. Meridiana, 13", - "city": "Barcelona", - "postalCode": 3849, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES" - }, - "default": true - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5aa97e595b706400153f9f94" - } - } - } - } - } - } - }, - "tags": ["WAREHOUSES"] - } - }, - "/warehouses/{warehouseId}/stock": { - "parameters": [ - { - "name": "warehouseId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "List products stock", - "summary": "List products stock", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "warehouse": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "color": { "type": "string" }, - "products": { - "type": "array", - "items": { - "type": "object", - "properties": { - "_id": { "type": "string" }, - "stock": { "type": "integer" }, - "variants": { - "type": "object", - "properties": { - "ObjectId": { "type": "integer" } - } - } - } - } - } - } - } - } - } - } - } - } - }, - "tags": ["WAREHOUSES"] - } - }, - "/warehouses/{warehouseId}": { - "parameters": [ - { - "name": "warehouseId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Warehouse", - "summary": "Get Warehouse", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "userId": { "type": "string" }, - "name": { "type": "string" }, - "email": { "type": "string" }, - "phone": { "type": "string" }, - "mobile": { "type": "string" }, - "address": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" } - } - }, - "default": { "type": "boolean" }, - "warehouseRecord": { "type": "integer" } - } - }, - "examples": { - "response": { - "value": { - "id": "5a05cc6e60cea100094baf2f", - "userId": "2344000h2o4b5s4n3o45", - "name": "Main Warehouse", - "email": "main@warehouse.com", - "phone": "765837638", - "mobile": "23456673", - "address": { - "address": "Av. Meridiana, 13", - "city": "Barcelona", - "postalCode": 3849, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES" - }, - "default": true, - "warehouseRecord": 30000001 - } - } - } - } - } - } - }, - "tags": ["WAREHOUSES"] - }, - "put": { - "operationId": "Update Warehouse", - "summary": "Update Warehouse", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/warehouse-input" } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "email": { "type": "string" }, - "phone": { "type": "string" }, - "mobile": { "type": "string" }, - "address": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryCode": { "type": "string" } - } - } - } - }, - "examples": { - "response": { - "value": { - "name": "Main Warehouse", - "email": "main@warehouse.com", - "phone": "765837638", - "mobile": "23456673", - "address": { - "address": "Av. Meridiana, 13", - "city": "Barcelona", - "postalCode": 3849, - "province": "Barcelona", - "country": "Spain", - "countryCode": "ES" - } - } - } - } - } - } - } - }, - "tags": ["WAREHOUSES"] - }, - "delete": { - "operationId": "Delete Warehouse", - "summary": "Delete Warehouse", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["WAREHOUSES"] - } - }, - "/taxes": { - "get": { - "operationId": "getTaxes", - "summary": "Get Taxes", - "description": "Get all the taxes information for a specific account", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "amount": { "type": "string" }, - "scope": { "type": "string" }, - "key": { "type": "string" }, - "group": { "type": "string" }, - "type": { "type": "string" } - } - } - }, - "examples": { - "response": { - "value": [ - { - "name": "IVA 21%", - "amount": "21", - "scope": "sales", - "key": "s_iva_21", - "group": "iva", - "type": "percentage" - }, - { - "name": "IVA 10%", - "amount": "10", - "scope": "sales", - "key": "s_iva_10", - "group": "iva", - "type": "percentage" - } - ] - } - } - } - } - } - }, - "tags": ["TAXES"] - } - }, - "/treasury": { - "get": { - "operationId": "List Treasuries", - "summary": "List Treasuries Accounts", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "type": { "type": "string" }, - "balance": { "type": "integer" }, - "accountNumber": { "type": "integer" }, - "iban": { "type": "string" }, - "swift": { "type": "string" }, - "bank": { "type": "string" }, - "bankname": { "type": "string" } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5aba68b1c5d438006425ad45", - "name": "Abanca bank", - "type": "bank", - "balance": 0, - "accountNumber": 57200003, - "iban": "ES123456789", - "swift": "CAGLESMM", - "bank": "abanca", - "bankname": "Abanca" - }, - { - "id": "5aba68b1c5d2453654ad90", - "name": "ING bank", - "type": "bank", - "balance": 32435, - "accountNumber": 65305004, - "iban": "ES112345678", - "swift": "DSFGT", - "bank": "ing", - "bankname": "ING" - } - ] - } - } - } - } - } - }, - "tags": ["TREASURIES"] - }, - "post": { - "operationId": "Create Treasury", - "summary": "Create Treasury Account", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/bank-input" } - } - } - }, - "responses": { - "201": { - "description": "dddd", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/bank-output-detailed" }, - "examples": { - "response": { "value": { "under": "development" } } - } - } - } - } - }, - "tags": ["TREASURIES"] - } - }, - "/treasury/{treasuryId}": { - "parameters": [ - { - "name": "treasuryId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Treasury", - "summary": "Get Treasury Account", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "type": { "type": "string" }, - "balance": { "type": "integer" }, - "accountNumber": { "type": "integer" }, - "iban": { "type": "string" }, - "swift": { "type": "string" }, - "bank": { "type": "string" }, - "bankname": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "id": "5aba68b1c5d438006425ad45", - "name": "Abanca bank", - "type": "bank", - "balance": 0, - "accountNumber": 57200003, - "iban": "ES123456789", - "swift": "CAGLESMM", - "bank": "abanca", - "bankname": "Abanca" - } - } - } - } - } - } - }, - "tags": ["TREASURIES"] - } - }, - "/numberingseries/{type}": { - "get": { - "operationId": "Get Numbering Series", - "summary": "Get Numbering Series by Type", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "format": { "type": "string" }, - "last": { "type": "integer" }, - "type": { "type": "string" } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5a05cc6e60cea100094baf24", - "name": "Default", - "format": "F17%%%%", - "last": 6, - "type": "invoice" - }, - { - "id": "5ab12cd63697ac00d1489fe3", - "name": "nl SO", - "format": "SO[YY]%%%", - "last": 0, - "type": "salesOrder" - } - ] - } - } - } - } - } - }, - "tags": ["NUMBERING SERIES"] - }, - "post": { - "operationId": "Create Numbering Serie", - "summary": "Create Numbering Serie", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "format": { "type": "string" }, - "last": { "type": "integer" }, - "type": { "type": "string" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Default", - "format": "F17%%%%", - "last": 6, - "type": "invoice" - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "msg": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "msg": "Created", - "id": "4365gqrtg51446tg14f5" - } - } - } - } - } - } - }, - "tags": ["NUMBERING SERIES"] - }, - "parameters": [ - { - "name": "type", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/numberingseries/{type}/{numberingSeriesId}": { - "parameters": [ - { - "name": "type", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "numberingSeriesId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "put": { - "operationId": "Update Numbering Serie", - "summary": "Update Numbering Serie", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "format": { "type": "string" }, - "last": { "type": "string" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Default", - "format": "receipt", - "last": "ff01" - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["NUMBERING SERIES"] - }, - "delete": { - "operationId": "Delete Numbering Serie", - "summary": "Delete Numbering Serie", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "msg": { "type": "string" }, - "id": { "type": "integer" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "msg": "Successfully deleted", - "id": 484 - } - } - } - } - } - } - }, - "tags": ["NUMBERING SERIES"] - } - }, - "/expensesaccounts": { - "get": { - "operationId": "List Expenses Accounts", - "summary": "List Expenses Accounts", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" }, - "accNum": { "type": "integer" } - } - }, - "examples": { - "response": { - "value": { - "id": "5aaf8c5f3697ac001f676082", - "name": "Exp Account main", - "desc": "My main expeses account dude", - "color": "#2C0934", - "accNum": 60000001 - } - } - } - } - } - } - }, - "tags": ["EXPENSES ACCOUNTS"], - "description": "List all your expenses accounts." - }, - "post": { - "operationId": "Create Expenses Account", - "summary": "Create Expenses Account", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "accountNum": { "type": "integer" } - }, - "required": ["name", "desc", "accountNum"] - } - } - }, - "x-examples": { - "application/json": { - "name": "Alt exp account", - "desc": "My second expenses account" - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["EXPENSES ACCOUNTS"], - "description": "Create an expenses account." - } - }, - "/expensesaccounts/{expensesAccountId}": { - "parameters": [ - { - "name": "expensesAccountId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Expenses Account", - "summary": "Get Expenses Account", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" }, - "accNum": { "type": "integer" } - } - }, - "examples": { - "response": { - "value": { - "id": "5aaf8c5f3697ac001f676082", - "name": "Exp Account", - "desc": "My main expenses accoun", - "color": "#2C0934", - "accNum": 60000001 - } - } - } - } - } - } - }, - "tags": ["EXPENSES ACCOUNTS"], - "description": "Get a specific expenses account." - }, - "put": { - "operationId": "Update Expenses Account", - "summary": "Update Expenses Account", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "New Exp Account", - "desc": "My fnew exp account", - "color": "#2C0934" - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["EXPENSES ACCOUNTS"], - "description": "Update a specific expenses account." - }, - "delete": { - "operationId": "Delete Expenses account", - "summary": "Delete Expenses Account", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["EXPENSES ACCOUNTS"], - "description": "Delete a specific expenses account." - } - }, - "/saleschannels": { - "get": { - "operationId": "List Sales Channels", - "summary": "List Sales Channels", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" }, - "accNum": { "type": "integer" } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5aba667fc5d438006425ad44", - "name": "My brand new sales channel", - "desc": "Main income", - "color": "#507C6C", - "accNum": 700002 - }, - { - "id": "5aba667fc5d438006425ad44", - "name": "My second brand new channel", - "desc": "Second income stream", - "color": "#507C6C", - "accNum": null - } - ] - } - } - } - } - } - }, - "tags": ["SALES CHANNELS"] - }, - "post": { - "operationId": "Create Sales Channel", - "summary": "Create Sales Channel", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "accountNum": { "type": "integer" } - }, - "required": ["name", "desc", "accountNum"] - } - } - }, - "x-examples": { - "application/json": { - "name": "My brand new sales channel", - "desc": "Main income" - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["SALES CHANNELS"] - } - }, - "/saleschannels/{salesChannelId}": { - "parameters": [ - { - "name": "salesChannelId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Sales Channel", - "summary": "Get Sales Channel", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" }, - "accNum": { "type": "integer" } - } - }, - "examples": { - "response": { - "value": { - "id": "5aba667fc5d438006425ad44", - "name": "My second brand new channel", - "desc": "Second income stream", - "color": "#507C6C", - "accNum": null - } - } - } - } - } - } - }, - "tags": ["SALES CHANNELS"] - }, - "put": { - "operationId": "Update Sales Channel", - "summary": "Update Sales Channel", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "color": { "type": "string" } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "My second brand new channel", - "desc": "Second income stream modified", - "color": "#507C6C" - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["SALES CHANNELS"] - }, - "delete": { - "operationId": "Delete Sales Channel", - "summary": "Delete Sales Channel", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["SALES CHANNELS"] - } - }, - "/payments": { - "get": { - "parameters": [ - { - "name": "starttmp", - "in": "query", - "description": "Starting timestamp", - "schema": { "type": "string" } - }, - { - "name": "endtmp", - "in": "query", - "description": "Ending timestamp", - "schema": { "type": "string" } - } - ], - "operationId": "List Payments", - "summary": "List Payments", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "bankId": { "type": "string" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "amount": { "type": "integer" }, - "desc": { "type": "string" }, - "date": { "type": "integer" } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5aaa81685b7064004342fd82", - "bankId": "", - "contactId": "", - "contactName": "", - "amount": 100, - "desc": "Gift", - "date": 1521068400 - }, - { - "id": "5aaa82455b7064004e0bbd02", - "bankId": "5aaa82095b70640046270413", - "contactId": "5aaa65e05b706400300ad246", - "contactName": "Benedicto", - "amount": 355, - "desc": "Invoice F17003421", - "date": 1520982000 - }, - { - "id": "5ab4f6f61d6d820023411433", - "bankId": "5aaf71763697ac000a0b34d3", - "contactId": "5aa939a95b70640009653d72", - "contactName": "Bose QC", - "amount": 290, - "desc": "Invoice F170001 ", - "date": 1521759600 - } - ] - } - } - } - } - } - }, - "tags": ["PAYMENTS"] - }, - "post": { - "operationId": "Create Payment", - "summary": "Create Payment", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "bankId": { "type": "string" }, - "contactId": { "type": "string" }, - "amount": { "type": "number" }, - "desc": { "type": "string" }, - "date": { "type": "integer" } - } - } - } - }, - "x-examples": { - "application/json": { - "bankId": "5aaa82095b70640046270413", - "contactId": "5aaa65e05b706400300ad246", - "amount": 355, - "desc": "Invoice F17003421", - "date": 1520982000 - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["PAYMENTS"] - } - }, - "/payments/{paymentId}": { - "parameters": [ - { - "name": "paymentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Payment", - "summary": "Get Payment", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "bankId": { "type": "string" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "amount": { "type": "integer" }, - "desc": { "type": "string" }, - "date": { "type": "integer" } - } - }, - "examples": { - "response": { - "value": { - "id": "5ab4f6f61d6d820023411433", - "bankId": "5aaf71763697ac000a0b34d3", - "contactId": "5aa939a95b70640009653d72", - "contactName": "Bose QC", - "amount": 290, - "desc": "Invoice F170001 ", - "date": 1521759600 - } - } - } - } - } - } - }, - "tags": ["PAYMENTS"] - }, - "put": { - "operationId": "Update Payment", - "summary": "Update Payment", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "bankId": { "type": "string" }, - "contactId": { "type": "string" }, - "amount": { "type": "integer" }, - "desc": { "type": "string" }, - "date": { "type": "integer" } - } - } - } - }, - "x-examples": { - "application/json": { - "bankId": "5aaf71763697ac000a0b34d3", - "contactId": "5aa939a95b70640009653d72", - "amount": 290, - "desc": "Invoice F170001 ", - "date": 1521759600 - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["PAYMENTS"] - }, - "delete": { - "operationId": "Delete Payment", - "summary": "Delete Payment", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["PAYMENTS"] - } - }, - "/documents/{docType}": { - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "description": "docType should be one of: {invoice, salesreceipt, creditnote, salesorder, proform, waybill,estimate, purchase, purchaseorder or purchaserefund}", - "schema": { "type": "string" } - } - ], - "get": { - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "description": "docType should be one of: {invoice, salesreceipt, creditnote, salesorder, proform, waybill,estimate, purchase, purchaseorder or purchaserefund}", - "schema": { "type": "string" } - }, - { - "name": "starttmp", - "in": "query", - "description": "Starting timestamp", - "schema": { "type": "string" } - }, - { - "name": "endtmp", - "in": "query", - "description": "Ending timestamp", - "schema": { "type": "string" } - }, - { - "name": "contactid", - "in": "query", - "description": "Filtering by contact Id", - "schema": { "type": "string" } - }, - { - "name": "paid", - "in": "query", - "description": "Filtering by paid status. 0 = not paid, 1 = paid, 2 = partially paid", - "schema": { "type": "string" } - }, - { - "name": "billed", - "in": "query", - "description": "Filtering by billed status. 0 = not billed, 1 = billed", - "schema": { "type": "string" } - }, - { - "name": "sort", - "in": "query", - "description": "Sort documents. Options: `created-asc` to sort by creation date of documents in ascending order or `created-desc` to sort by creation date of documents in descending order", - "schema": { "type": "string" } - } - ], - "operationId": "List Documents", - "summary": "List Documents", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/document-output" } - }, - "examples": { "response": { "value": {} } } - }, - "new": { - "examples": { - "response": { - "value": [ - { - "id": "5ab391071d6d820034294783", - "contact": "5aa939a95b70640009653d72", - "contactName": "Mapple Inc", - "desc": "description goes here", - "date": 1521673200, - "dueDate": 1521673200, - "notes": "notes go here", - "products": [ - { - "name": "Headphone", - "desc": "Best headphones you can buy", - "price": 299, - "units": 1, - "tax": 21, - "discount": 0, - "retention": 0, - "weight": 200, - "costPrice": 110, - "sku": "21324t1gv", - "productId": "5acccbe412d56e004903a385#5acccbe412d56e004903a384" - } - ], - "tax": 234.61, - "subtotal": 1117.18, - "discount": 0, - "total": 1351.79, - "language": "en", - "status": 2, - "customFields": [ - { "field": "FieldOne", "value": "noValue" } - ], - "docNumber": "F170001", - "currency": "eur", - "currencyChange": 1, - "paymentsTotal": 290, - "paymentsPending": 1061.79, - "paymentsRefunds": 0, - "salesChannelId": "5aba667fc5d438006425ad44" - } - ] - } - } - } - } - } - }, - "tags": ["DOCUMENTS"], - "description": "Get all your documents by type." - }, - "post": { - "operationId": "Create Document", - "summary": "Create Document", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "applyContactDefaults": { - "type": "boolean", - "description": "Contact defaults are applied by default. If you don't want to apply it, set this field to false" - }, - "contactCode": { - "type": "string", - "description": "(NIF / CIF / VAT) Field required if you want to choose an existing contact and contactId field is empty" - }, - "contactId": { - "type": "string", - "description": "(Contact ID) Field required if you want to choose an existing contact and contactCode field is empty" - }, - "contactName": { - "type": "string", - "description": "Field required if contactCode and contactId fields are empty and you want to create a new contact" - }, - "contactEmail": { "type": "string" }, - "contactAddress": { "type": "string" }, - "contactCity": { "type": "string" }, - "contactCp": { "type": "string" }, - "contactProvince": { "type": "string" }, - "contactCountryCode": { "type": "string" }, - "desc": { "type": "string" }, - "date": { "type": "integer" }, - "notes": { "type": "string" }, - "salesChannelId": { - "type": "string", - "description": "Set an existing account id" - }, - "paymentMethodId": { "type": "string" }, - "designId": { "type": "string" }, - "language": { "type": "string" }, - "warehouseId": { - "type": "string", - "description": "Choose the warehouse for your salesorder, purchaseorder or waybill." - }, - "approveDoc": { - "type": "boolean", - "description": "Choose if the document needs to be approved or not. The default option is False." - }, - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "units": { "type": "number" }, - "sku": { "type": "string" }, - "serviceId": { "type": "string" }, - "accountingAccountId": { "type": "string" }, - "subtotal": { "type": "number" }, - "discount": { "type": "number" }, - "tax": { - "type": "integer", - "description": "IVA percentage. In case you need to inform more than one tax, use the field taxes instead" - }, - "taxes": { - "type": "array", - "description": "Comma separated Tax keys. e.g. (s_iva_21,s_ret_19)", - "items": { "type": "string" } - }, - "supplied": { - "type": "string", - "description": "Optional (Yes/No)" - }, - "tags": { "type": "array", "items": { "type": "string" } } - } - } - }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { "type": "string" }, - "value": { "type": "string" } - } - } - }, - "invoiceNum": { "type": "string" }, - "numSerieId": { "type": "string" }, - "currency": { "type": "string" }, - "currencyChange": { "type": "number" }, - "tags": { "type": "array", "items": { "type": "string" } }, - "dueDate": { "type": "integer" }, - "shippingAddress": { "type": "string" }, - "shippingPostalCode": { "type": "string" }, - "shippingCity": { "type": "string" }, - "shippingProvince": { "type": "string" }, - "shippingCountry": { "type": "string" }, - "salesChannel": { "type": "number" } - }, - "required": ["date"] - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/document-output-detailed" - }, - "examples": { - "response": { - "value": { - "status": 1, - "id": "5acce41e12d56e005e0e62d3", - "invoiceNum": "F170009", - "contactId": "5ac3a7b68fbd9d000f07e237" - } - } - } - } - } - } - }, - "tags": ["DOCUMENTS"], - "description": "Create a new document type." - } - }, - "/documents/{docType}/{documentId}": { - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "getDocument", - "summary": "Get Document", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/document-output-detailed" - } - } - } - } - }, - "tags": ["DOCUMENTS"], - "description": "Get a specific document." - }, - "put": { - "operationId": "Update Document", - "summary": "Update Document", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "desc": { "type": "string" }, - "notes": { "type": "string" }, - "language": { "type": "string" }, - "date": { "type": "integer" }, - "paymentMethod": { "type": "string" }, - "warehouseId": { - "type": "string", - "description": "Choose the warehouse for your salesorder, purchaseorder or waybill." - }, - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "subtotal": { "type": "integer" }, - "tax": { "type": "integer" }, - "tags": { - "type": "array", - "items": { "type": "string" } - }, - "units": { "type": "integer" }, - "discount": { "type": "integer" }, - "accountingAccountId": { "type": "string" }, - "kind": { "type": "string" }, - "sku": { "type": "string" }, - "lotSku": { "type": "string" }, - "supplied": { - "type": "string", - "description": "Optional (Yes/No)" - } - } - } - }, - "salesChannelId": { "type": "string" }, - "expAccountId": { "type": "string" }, - "customFields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { "type": "string" }, - "value": { "type": "string" } - } - } - } - } - } - } - }, - "x-examples": { - "application/json": { - "desc": "description goes here", - "notes": "notes goes here", - "language": "es", - "date": 15243534, - "paymentMethod": "3243546", - "products": [ - { - "name": "item name", - "desc": "item desc", - "subtotal": 344, - "tax": 21, - "units": 3, - "discount": 0 - } - ], - "salesChannelId": "345463o5hj432kjb4o23n1l5j5", - "expAccountId": "345463o5hj43n1l5jowr3onb5" - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["DOCUMENTS"], - "description": "Update a specific document. {lotSku} field is only needed when {kind} is lots." - }, - "delete": { - "operationId": "Delete Document", - "summary": "Delete Document", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["DOCUMENTS"], - "description": "Delete specific document type." - } - }, - "/documents/{docType}/{documentId}/pay": { - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "invoiceId": { "type": "string" }, - "invoiceNum": { "type": "string" }, - "paymentId": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "invoiceId": "13f14gl5i46ñ5b64vp1535", - "invoiceNum": "F170007", - "paymentId": "3245bkjblhj3v2k6vl4bhbv145b" - } - } - } - } - } - } - }, - "operationId": "Pay Document", - "summary": "Pay Document", - "tags": ["DOCUMENTS"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "date": { "type": "integer" }, - "treasury": { - "type": "string", - "description": "Your treasury holded's id" - }, - "desc": { "type": "string" }, - "amount": { "type": "number" } - }, - "required": ["date", "amount"] - } - } - }, - "x-examples": { - "application/json": { - "date": 1513245364, - "treasury": "4156257683", - "desc": "description", - "amount": 345 - } - } - }, - "description": "Pay one specific document" - } - }, - "/documents/{docType}/{documentId}/send": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { "status": 1, "info": "Document sent" } - } - } - } - } - } - }, - "operationId": "Send Document", - "summary": "Send Document", - "tags": ["DOCUMENTS"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "required": ["emails"], - "properties": { - "mailTemplateId": { "type": "string" }, - "emails": { "type": "string" }, - "subject": { - "type": "string", - "minLength": 10, - "description": "Minimum 10 characters" - }, - "message": { - "type": "string", - "minLength": 20, - "description": "Minimum 20 characters" - }, - "docIds": { "type": "string" } - } - } - } - }, - "x-examples": { - "application/json": { - "mailTemplateId": "456lkn5er467522115", - "emails": "email@example.com, email2@example.com", - "subject": "subject email", - "message": "email messages goes here", - "docIds": "" - } - } - }, - "description": "Send a specific document by email." - }, - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/documents/{docType}/{documentId}/pdf": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "data": "<>" - } - } - } - } - } - } - }, - "operationId": "GetDocumentPDF", - "summary": "Get Document PDF", - "tags": ["DOCUMENTS"], - "description": "Get a specific document pdf." - }, - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/documents/salesorder/{documentId}/shipall": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { "status": 1, "info": "Items Shipped" } - } - } - } - } - } - }, - "operationId": "Ship all items", - "summary": "Ship All Items", - "tags": ["DOCUMENTS"], - "description": "Ship all the items of a specific sales order." - }, - "parameters": [ - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/documents/salesorder/{documentId}/shipbylines": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { "status": 1, "info": "Items Shipped" } - } - } - } - } - } - }, - "operationId": "Ship items by line", - "summary": "Ship items by line", - "tags": ["DOCUMENTS"], - "description": "Ship a specific item of a specific sales order (itemLinePosition starts at 0).", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "lines": { - "type": "array", - "items": { - "type": "object", - "properties": { - "itemLinePosition": { "type": "integer" }, - "units": { "type": "integer" } - } - } - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/documents/{docType}/{documentId}/shippeditems": { - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "description": "docType should be one of: {salesorder, order}", - "schema": { "type": "string" } - }, - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "sku": { "type": "string" }, - "total": { "type": "number" }, - "sent": { "type": "number" }, - "pending": { "type": "number" } - } - } - } - } - } - } - }, - "operationId": "Shipped units by item", - "summary": "Shipped units by item", - "tags": ["DOCUMENTS"], - "description": "For each item included in a sales or purchase order, get the number of units shipped or recieved." - } - }, - "/documents/{docType}/{documentId}/attach": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "data": "<>" - } - } - } - } - } - } - }, - "operationId": "Attach File", - "summary": "Attach File to a specific document", - "parameters": [ - { - "name": "docType", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "description": "The file to upload.", - "type": "string", - "format": "binary" - }, - "setMain": { "type": "boolean" } - } - } - } - } - }, - "tags": ["DOCUMENTS"], - "description": "Attach File to a specific document." - } - }, - "/documents/{docType}/{documentId}/updatetracking": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - }, - "examples": { - "response": { "value": { "status": 1, "data": "Updated" } } - } - } - } - } - }, - "operationId": "Update tracking info", - "summary": "Update tracking info from specific document.", - "tags": ["DOCUMENTS"], - "description": "Update tracking info from specific document.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "key": { - "type": "string", - "example": "correos", - "description": "key should be one of: {mrw, ups, fedex,tnt, seur, nacex, correos, asm, uspostalservice, dbschenker, royalmail, bluedart, palletways, correosexpress, tourline, other (for custom)}" - }, - "name": { - "type": "string", - "example": "correos", - "description": "name should be one of: {mrw, ups, fedex,tnt, seur, nacex, correos, asm, United States Postal Service, dbschenker, royalmail, bluedart, palletways, correosexpress, tourline, custom name (for custom)}" - }, - "num": { - "type": "string", - "example": "1,2-3", - "description": "Tracking numbers. Can be added more numbers separated by , or -" - }, - "pickUpDate": { - "type": "string", - "example": "01/01/2020", - "description": "pickUpDate should be formated like DD/MM/YYYY" - }, - "deliveryDate": { - "type": "string", - "example": "01/01/2020", - "description": "deliveryDate should be formated like DD/MM/YYYY" - }, - "notes": { - "type": "string", - "example": "note", - "description": "notes for the tracking" - } - } - } - } - } - } - }, - "parameters": [ - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "docType", - "in": "path", - "required": true, - "description": "docType should be one of: {salesorder, waybill}", - "schema": { "type": "string" } - } - ] - }, - "/documents/{docType}/{documentId}/pipeline/set": { - "post": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" } - } - }, - "examples": { - "response": { "value": { "status": 1, "info": "Done" } } - } - } - } - } - }, - "operationId": "Update document pipeline", - "summary": "Update pipeline from specific document.", - "tags": ["DOCUMENTS"], - "description": "Update pipeline from specific document.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "pipeline": { "type": "string" } } - } - } - } - } - }, - "parameters": [ - { - "name": "documentId", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "docType", - "in": "path", - "description": "docType should be one of: {salesorder, waybill}", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/paymentmethods": { - "get": { - "responses": { - "200": { - "description": "List Payment methods", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "dueDays": { "type": "string" }, - "bankId": { "type": "string" } - } - } - } - } - } - }, - "operationId": "List Payment methods", - "summary": "List Payment methods", - "tags": ["DOCUMENTS"], - "description": "List Payment methods" - } - }, - "/remittances": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "type": "object", "properties": {} } - } - } - } - }, - "summary": "List Remittances", - "operationId": "List Remittances", - "tags": ["REMITTANCES"], - "security": [{ "Auth": [] }] - } - }, - "/remittances/{remittanceId}": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "type": "object", "properties": {} } - } - } - } - }, - "operationId": "Get Remittance", - "summary": "Get Remittance", - "tags": ["REMITTANCES"] - }, - "parameters": [ - { - "name": "remittanceId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/products/{productId}/image": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "type": "object", "properties": {} } - } - } - } - }, - "summary": "Get Product Main Image", - "description": "Get the main image of a specific product", - "operationId": "Get Product Image", - "tags": ["PRODUCTS"] - }, - "parameters": [ - { - "name": "productId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/products/{productId}/imagesList": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "type": "object", "properties": {} } - } - } - } - }, - "summary": "List Product Images", - "operationId": "List Product Images", - "tags": ["PRODUCTS"], - "description": "List all secondary product images" - }, - "parameters": [ - { - "name": "productId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/products/{productId}/image/{imageFileName}": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "type": "object", "properties": {} } - } - } - } - }, - "summary": "Get Product Secondary Image", - "tags": ["PRODUCTS"], - "description": "Get a specific secondary Image" - }, - "parameters": [ - { - "name": "productId", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "imageFileName", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - }, - "/products/{productId}/stock": { - "parameters": [ - { - "name": "productId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "put": { - "operationId": "Update Product stock", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "stock": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "WarehouseId's", - "additionalProperties": { - "type": "number", - "description": "ProductId or VariantId followed by stock to update", - "default": { "ProductId": 1 } - } - } - } - } - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5aa97e595b706400153f9f94" - } - } - } - } - } - } - }, - "tags": ["PRODUCTS"], - "summary": "Update Product stock" - } - }, - "/services": { - "get": { - "operationId": "List Services", - "summary": "List Services", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "type": { "type": "string" }, - "balance": { "type": "integer" }, - "accountNumber": { "type": "integer" }, - "iban": { "type": "string" }, - "swift": { "type": "string" }, - "bank": { "type": "string" }, - "bankname": { "type": "string" } - } - } - } - } - } - } - }, - "tags": ["SERVICES"] - }, - "post": { - "operationId": "Create Service", - "summary": "Create Service", - "requestBody": { - "$ref": "#/components/requestBodies/Create_ServiceBody" - }, - "responses": { "201": { "description": "" } }, - "tags": ["SERVICES"] - } - }, - "/services/{serviceId}": { - "parameters": [ - { - "name": "serviceId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Service", - "summary": "Get Service", - "responses": { "200": { "description": "" } }, - "tags": ["SERVICES"] - }, - "put": { - "operationId": "Update Service", - "summary": "Update Service", - "requestBody": { - "$ref": "#/components/requestBodies/Create_ServiceBody" - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/bank-output-detailed" } - } - } - } - }, - "tags": ["SERVICES"] - }, - "delete": { - "operationId": "Delete Service", - "summary": "Delete Service", - "responses": { "200": { "description": "" } }, - "tags": ["SERVICES"] - } - } -} diff --git a/forms-bridge/addons/holded/data/swagger/projects.json b/forms-bridge/addons/holded/data/swagger/projects.json deleted file mode 100644 index 5c6e8476..00000000 --- a/forms-bridge/addons/holded/data/swagger/projects.json +++ /dev/null @@ -1,1286 +0,0 @@ -{ - "/projects": { - "get": { - "operationId": "List Projects", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/project-output" } - }, - "examples": { - "response": { - "value": [ - { - "id": "5ab390311d6d82002432ec5a", - "name": "Building 301", - "desc": "Bulding 301 in Barcelona", - "tags": ["tag", "tog", "tug"], - "category": 0, - "contactId": "5aaa51ab5b70640028340186", - "contactName": "DIvero", - "date": 0, - "dueDate": 0, - "status": 2, - "lists": [ - { - "id": "5ab390311d6d82002432ec52", - "key": "pending", - "name": "Pending", - "desc": "nan" - }, - { - "id": "5ab390311d6d82002432ec53", - "key": "review", - "name": "Review", - "desc": "nan" - }, - { - "id": "5ab390311d6d82002432ec54", - "key": "done", - "name": "Done", - "desc": "nan" - } - ], - "billable": 1, - "expenses": { - "docId": "5ab3d4121d6d820062013ed3", - "type": "purchase", - "subtotal": 200, - "desc": "noooooo", - "invoiceNum": "123", - "total": 242, - "contactId": "5aaa51ab5b70640028340186", - "contactName": "DIvero (Divero)", - "date": 1521673200, - "dueDate": 1521759600 - }, - "estimates": [ - { - "docId": "5ab3d4cc1d6d82007711bba3", - "type": "estimate", - "subtotal": 34433, - "desc": "no desc", - "invoiceNum": "E170001", - "total": 41663.93, - "contactId": "5aaa51ab5b70640028340186", - "contactName": "DIvero (Divero)", - "date": 1517871600, - "dueDate": 1520118000 - } - ], - "sales": [ - { - "docId": "5ab391071d6d820034294783", - "type": "invoice", - "subtotal": 818.18, - "desc": "", - "invoiceNum": "F170001", - "total": 990, - "contactId": "5aa939a95b70640009653d72", - "contactName": "Bose QC", - "date": 1521673200, - "dueDate": 0 - } - ], - "timeTracking": { - "timeId": "5ac4f2cec839ea004e18a463", - "time": 45300, - "desc": "POOOOOSTuuuuuuu eeeee timetracking after refactor", - "costHour": 234, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683", - "total": 2944.5 - }, - "price": 2345, - "numberOfTasks": 6, - "completedTasks": 3, - "labels": [ - { - "id": "5ab390311d6d82002432ec55", - "name": "New", - "color": "#10cf91" - }, - { - "id": "5ab390311d6d82002432ec56", - "name": "Confirmed", - "color": "#10cf91" - }, - { - "id": "5ab390311d6d82002432ec57", - "name": "Pending", - "color": "#f8d053" - }, - { - "id": "5ab390311d6d82002432ec58", - "name": "Fixed", - "color": "#4181f2" - }, - { - "id": "5ab390311d6d82002432ec59", - "name": "Urgent", - "color": "#ee585d" - } - ] - } - ] - } - } - } - } - } - }, - "tags": ["PROJECTS"], - "description": "Get all your projects." - }, - "post": { - "operationId": "Create Project", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "name": { "type": "string" } }, - "required": ["name"] - } - } - }, - "x-examples": { "application/json": { "name": "Project of the month" } } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["PROJECTS"], - "description": "Create a new project." - } - }, - "/projects/{projectId}": { - "parameters": [ - { - "name": "projectId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Project", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "tags": { "type": "array", "items": { "type": "string" } }, - "category": { "type": "integer" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "date": { "type": "integer" }, - "dueDate": { "type": "integer" }, - "status": { "type": "integer" }, - "lists": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "key": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" } - } - } - }, - "billable": { "type": "integer" }, - "expenses": { - "type": "object", - "properties": { - "docId": { "type": "string" }, - "type": { "type": "string" }, - "subtotal": { "type": "integer" }, - "desc": { "type": "string" }, - "invoiceNum": { "type": "string" }, - "total": { "type": "integer" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "date": { "type": "integer" }, - "dueDate": { "type": "integer" } - } - }, - "estimates": { - "type": "array", - "items": { - "type": "object", - "properties": { - "docId": { "type": "string" }, - "type": { "type": "string" }, - "subtotal": { "type": "integer" }, - "desc": { "type": "string" }, - "invoiceNum": { "type": "string" }, - "total": { "type": "number" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "date": { "type": "integer" }, - "dueDate": { "type": "integer" } - } - } - }, - "sales": { - "type": "array", - "items": { - "type": "object", - "properties": { - "docId": { "type": "string" }, - "type": { "type": "string" }, - "subtotal": { "type": "number" }, - "desc": { "type": "string" }, - "invoiceNum": { "type": "string" }, - "total": { "type": "integer" }, - "contactId": { "type": "string" }, - "contactName": { "type": "string" }, - "date": { "type": "integer" }, - "dueDate": { "type": "integer" } - } - } - }, - "timeTracking": { - "type": "object", - "properties": { - "timeId": { "type": "string" }, - "time": { "type": "integer" }, - "desc": { "type": "string" }, - "costHour": { "type": "integer" }, - "userId": { "type": "string" }, - "taskId": { "type": "string" }, - "total": { "type": "number" } - } - }, - "price": { "type": "integer" }, - "numberOfTasks": { "type": "integer" }, - "completedTasks": { "type": "integer" }, - "labels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "color": { "type": "string" } - } - } - } - } - }, - "examples": { - "response": { - "value": { - "id": "5ab390311d6d82002432ec5a", - "name": "Building 301", - "desc": "Bulding 301 in Barcelona", - "tags": ["tag", "tog", "tug"], - "category": 0, - "contactId": "5aaa51ab5b70640028340186", - "contactName": "DIvero", - "date": 0, - "dueDate": 0, - "status": 2, - "lists": [ - { - "id": "5ab390311d6d82002432ec52", - "key": "pending", - "name": "Pending", - "desc": "nan" - }, - { - "id": "5ab390311d6d82002432ec53", - "key": "review", - "name": "Review", - "desc": "nan" - }, - { - "id": "5ab390311d6d82002432ec54", - "key": "done", - "name": "Done", - "desc": "nan" - } - ], - "billable": 1, - "expenses": { - "docId": "5ab3d4121d6d820062013ed3", - "type": "purchase", - "subtotal": 200, - "desc": "noooooo", - "invoiceNum": "123", - "total": 242, - "contactId": "5aaa51ab5b70640028340186", - "contactName": "DIvero (Divero)", - "date": 1521673200, - "dueDate": 1521759600 - }, - "estimates": [ - { - "docId": "5ab3d4cc1d6d82007711bba3", - "type": "estimate", - "subtotal": 34433, - "desc": "no desc", - "invoiceNum": "E170001", - "total": 41663.93, - "contactId": "5aaa51ab5b70640028340186", - "contactName": "DIvero (Divero)", - "date": 1517871600, - "dueDate": 1520118000 - } - ], - "sales": [ - { - "docId": "5ab391071d6d820034294783", - "type": "invoice", - "subtotal": 818.18, - "desc": "", - "invoiceNum": "F170001", - "total": 990, - "contactId": "5aa939a95b70640009653d72", - "contactName": "Bose QC", - "date": 1521673200, - "dueDate": 0 - } - ], - "timeTracking": { - "timeId": "5ac4f2cec839ea004e18a463", - "time": 45300, - "desc": "POOOOOSTuuuuuuu eeeee timetracking after refactor", - "costHour": 234, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683", - "total": 2944.5 - }, - "price": 2345, - "numberOfTasks": 6, - "completedTasks": 3, - "labels": [ - { - "id": "5ab390311d6d82002432ec55", - "name": "New", - "color": "#10cf91" - }, - { - "id": "5ab390311d6d82002432ec56", - "name": "Confirmed", - "color": "#10cf91" - }, - { - "id": "5ab390311d6d82002432ec57", - "name": "Pending", - "color": "#f8d053" - }, - { - "id": "5ab390311d6d82002432ec58", - "name": "Fixed", - "color": "#4181f2" - }, - { - "id": "5ab390311d6d82002432ec59", - "name": "Urgent", - "color": "#ee585d" - } - ] - } - } - } - } - } - } - }, - "tags": ["PROJECTS"], - "description": "Get a specific payment." - }, - "put": { - "operationId": "Update Project", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "tags": { "type": "array", "items": { "type": "string" } }, - "contactName": { "type": "string" }, - "date": { "type": "integer" }, - "dueDate": { "type": "integer" }, - "status": { "type": "integer" }, - "lists": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "key": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" } - } - } - }, - "billable": { "type": "integer" }, - "price": { "type": "integer" }, - "labels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "color": { "type": "string" } - } - } - } - } - } - } - }, - "x-examples": { - "application/json": { - "name": "Building 301", - "desc": "Bulding 301 in Barcelona", - "tags": ["tag", "tog", "tug"], - "contactName": "DIvero", - "date": 1521673200, - "dueDate": 1521759600, - "status": 2, - "lists": [ - { - "id": "5ab390311d6d82002432ec52", - "key": "pending", - "name": "Pending", - "desc": "nan" - }, - { - "id": "5ab390311d6d82002432ec53", - "key": "review", - "name": "Review", - "desc": "nan" - }, - { - "id": "5ab390311d6d82002432ec54", - "key": "done", - "name": "Done", - "desc": "nan" - } - ], - "billable": 1, - "price": 2345, - "labels": [ - { - "id": "5ab390311d6d82002432ec55", - "name": "New", - "color": "#10cf91" - }, - { - "id": "5ab390311d6d82002432ec56", - "name": "Confirmed", - "color": "#10cf91" - }, - { - "id": "5ab390311d6d82002432ec57", - "name": "Pending", - "color": "#f8d053" - }, - { - "id": "5ab390311d6d82002432ec58", - "name": "Fixed", - "color": "#4181f2" - }, - { - "id": "5ab390311d6d82002432ec59", - "name": "Urgent", - "color": "#ee585d" - } - ] - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ab390311d6d82002432ec5a" - } - } - } - } - } - } - }, - "tags": ["PROJECTS"], - "description": "Update a specific project.\n\nOnly the params included in the operation will update the project." - }, - "delete": { - "operationId": "Delete Project", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["PROJECTS"], - "description": "Delete a specific project." - } - }, - "/tasks": { - "get": { - "operationId": "List Tasks", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "projectId": { "type": "string" }, - "listId": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "labels": { - "type": "array", - "items": { "type": "string" } - }, - "comments": { - "type": "array", - "items": { - "type": "object", - "properties": { - "commentId": { "type": "string" }, - "createdAt": { "type": "integer" }, - "userId": { "type": "string" }, - "message": { "type": "string" } - } - } - }, - "date": { "type": "integer" }, - "dueDate": { "type": "integer" }, - "userId": { "type": "string" }, - "createdAt": { "type": "integer" }, - "updatedAt": { "type": "integer" }, - "status": { "type": "integer" }, - "billable": { "type": "integer" }, - "featured": { "type": "integer" } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5ab3df6e1d6d82008c5777a4", - "projectId": "5ab390311d6d82002432ec5a", - "listId": "5ab390311d6d82002432ec53", - "name": "Business plan", - "desc": "business plan for the new project", - "labels": [ - "5ab390311d6d82002432ec58", - "5ab390311d6d82002432ec59" - ], - "comments": [ - { - "commentId": "5ab3df8c1d6d820088525aa3", - "createdAt": 1521737612, - "userId": "5a05cc5a60cea100094baf22", - "message": "no comments" - }, - { - "commentId": "5ab3df971d6d82008c5777a5", - "createdAt": 1521737623, - "userId": "5a05cc5a60cea100094baf22", - "message": "a piece of comment\n" - } - ], - "date": 1521737582, - "dueDate": 1521673200, - "userId": "5a05cc5a60cea100094baf22", - "createdAt": 1521737582, - "updatedAt": 1521737582, - "status": 0, - "billable": 0, - "featured": 1 - } - ] - } - } - } - } - } - }, - "tags": ["TASKS"], - "description": "Get all your tasks." - }, - "post": { - "operationId": "Create Task", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "projectId": { "type": "string" }, - "listId": { "type": "string" }, - "name": { "type": "string" } - }, - "required": ["projectId", "listId", "name"] - } - } - }, - "x-examples": { - "application/json": { - "projectId": "5ab390311d6d82002432ec5a", - "listId": "5ab390311d6d82002432ec52", - "name": "new task" - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["TASKS"], - "description": "Create a new task." - } - }, - "/tasks/{taskId}": { - "parameters": [ - { - "name": "taskId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Task", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "projectId": { "type": "string" }, - "listId": { "type": "string" }, - "name": { "type": "string" }, - "desc": { "type": "string" }, - "labels": { "type": "array", "items": { "type": "string" } }, - "comments": { - "type": "array", - "items": { - "type": "object", - "properties": { - "commentId": { "type": "string" }, - "createdAt": { "type": "integer" }, - "userId": { "type": "string" }, - "message": { "type": "string" } - } - } - }, - "date": { "type": "integer" }, - "dueDate": { "type": "integer" }, - "userId": { "type": "string" }, - "createdAt": { "type": "integer" }, - "updatedAt": { "type": "integer" }, - "status": { "type": "integer" }, - "billable": { "type": "integer" }, - "featured": { "type": "integer" } - } - }, - "examples": { - "response": { - "value": { - "id": "5ab3df6e1d6d82008c5777a4", - "projectId": "5ab390311d6d82002432ec5a", - "listId": "5ab390311d6d82002432ec53", - "name": "Business plan", - "desc": "business plan for the new project", - "labels": [ - "5ab390311d6d82002432ec58", - "5ab390311d6d82002432ec59" - ], - "comments": [ - { - "commentId": "5ab3df8c1d6d820088525aa3", - "createdAt": 1521737612, - "userId": "5a05cc5a60cea100094baf22", - "message": "no comments" - }, - { - "commentId": "5ab3df971d6d82008c5777a5", - "createdAt": 1521737623, - "userId": "5a05cc5a60cea100094baf22", - "message": "a piece of comment\n" - } - ], - "date": 1521737582, - "dueDate": 1521673200, - "userId": "5a05cc5a60cea100094baf22", - "createdAt": 1521737582, - "updatedAt": 1521737582, - "status": 0, - "billable": 0, - "featured": 1 - } - } - } - } - } - } - }, - "tags": ["TASKS"], - "description": "Get a specific task." - }, - "delete": { - "operationId": "Delete Task", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["TASKS"], - "description": "Delete a specific task." - } - }, - "/projects/{projectId}/times": { - "parameters": [ - { - "name": "projectId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "Get Project Times", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/timeTracking-output" } - }, - "examples": { - "response": { - "value": [ - { - "timeId": "5ab3d2611d6d82005c4d2082", - "duration": 45300, - "desc": "timetracking project", - "costHour": 35, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683", - "total": 440.41666666667 - } - ] - } - } - } - } - } - }, - "tags": ["TIME TRACKING"], - "description": "Get all your times tracking by project." - }, - "post": { - "operationId": "Create Project Time", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "duration": { "type": "integer" }, - "desc": { "type": "string" }, - "costHour": { "type": "integer" }, - "userId": { "type": "string" }, - "taskId": { "type": "string" } - }, - "required": ["duration", "costHour"] - } - } - }, - "x-examples": { - "application/json": { - "duration": 45300, - "desc": "new timetracking", - "costHour": 35, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683" - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Created", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["TIME TRACKING"], - "description": "Create a new time tracking." - } - }, - "/projects/{projectId}/times/{timeTrackingId}": { - "parameters": [ - { - "name": "projectId", - "in": "path", - "required": true, - "schema": { "type": "string" } - }, - { - "name": "timeTrackingId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "operationId": "GetProjectTimes", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/timeTracking-output-detailed" - }, - "examples": { - "response": { - "value": { - "timeId": "5ab3d2611d6d82005c4d2082", - "duration": 45300, - "desc": "timetracking new project", - "costHour": 35, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683", - "total": 440.41666666667 - } - } - } - } - } - } - }, - "tags": ["TIME TRACKING"], - "description": "Get a specific time tracking." - }, - "put": { - "operationId": "Update Project Time", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "duration": { "type": "integer" }, - "desc": { "type": "string" }, - "costHour": { "type": "integer" }, - "userId": { "type": "string" }, - "taskId": { "type": "string" } - }, - "required": ["duration", "costHour"] - } - } - }, - "x-examples": { - "application/json": { - "duration": 45300, - "desc": "timetracking new project", - "costHour": 35, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683" - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Updated", - "id": "5ac4f2cec839ea004e18a463" - } - } - } - } - } - } - }, - "tags": ["TIME TRACKING"], - "description": "Update a specific time tracking.\n\nOnly the params included in the operation will update the time tracking." - }, - "delete": { - "operationId": "Delete Project Time", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - }, - "examples": { - "response": { - "value": { - "status": 1, - "info": "Successfully deleted", - "id": "5aba68b1c5d438006425ad45" - } - } - } - } - } - } - }, - "tags": ["TIME TRACKING"], - "description": "Delete a specific time tracking." - } - }, - "/projects/times": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "timeTracking": { - "type": "array", - "items": { - "type": "object", - "properties": { - "timeId": { "type": "string" }, - "duration": { "type": "integer" }, - "desc": { "type": "string" }, - "costHour": { "type": "integer" }, - "userId": { "type": "string" }, - "taskId": { "type": "string" }, - "total": { "type": "number" } - } - } - } - } - } - }, - "examples": { - "response": { - "value": [ - { - "id": "5ab390311d6d82002432ec5a", - "name": "Building", - "timeTracking": [ - { - "timeId": "5ab3d2611d6d82005c4d2082", - "duration": 45300, - "desc": "timetracking test", - "costHour": 35, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683", - "total": 440.41666666667 - }, - { - "timeId": "5ab4bb421d6d820008184163", - "duration": 38760, - "desc": "first timetracking", - "costHour": 0, - "userId": "5a05cc5a60cea100094baf22", - "taskId": "5ab3cb7d1d6d8200440d4683", - "total": 0 - } - ] - } - ] - } - } - } - } - } - }, - "operationId": "List Times", - "parameters": [ - { - "name": "start", - "in": "query", - "required": false, - "schema": { "type": "integer" } - }, - { - "name": "end", - "in": "query", - "required": false, - "schema": { "type": "integer" } - }, - { - "name": "archived", - "in": "query", - "required": false, - "schema": { "type": "boolean" } - } - ], - "tags": ["TIME TRACKING"], - "description": "List time trackings in projects not archived from 18 months on" - } - }, - "/projects/{projectId}/summary": { - "get": { - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "desc": { "type": "string" }, - "projectEvolution": { - "type": "object", - "properties": { - "tasks": { - "type": "object", - "properties": { - "total": { "type": "integer" }, - "completed": { "type": "integer" } - } - }, - "dueDate": { "type": "integer" } - } - }, - "profitability": { - "type": "object", - "properties": { - "sales": { "type": "number" }, - "expenses": { - "type": "object", - "properties": { - "documents": { "type": "integer" }, - "personnel": { "type": "number" }, - "total": { "type": "number" } - } - }, - "profit": { "type": "number" } - } - }, - "economicStatus": { - "type": "object", - "properties": { - "sales": { "type": "number" }, - "quoted": { "type": "integer" }, - "difference": { "type": "number" }, - "estimatePrice": { "type": "integer" }, - "billed": { "type": "number" }, - "collected": { "type": "integer" }, - "remaining": { "type": "number" } - } - } - } - }, - "examples": { - "response": { - "value": { - "name": "Building", - "desc": "Bulding in Barcelona", - "projectEvolution": { - "tasks": { "total": 6, "completed": 3 }, - "dueDate": 0 - }, - "profitability": { - "sales": 1117.18, - "expenses": { - "documents": 200, - "personnel": 15603.333333333, - "total": 15803.333333333 - }, - "profit": -14686.153333333 - }, - "economicStatus": { - "sales": 1117.18, - "quoted": 34433, - "difference": -33315.82, - "estimatePrice": 3453456, - "billed": 1351.79, - "collected": 290, - "remaining": 1061.79 - } - } - } - } - } - } - } - }, - "tags": ["PROJECTS"], - "description": "Get a specific project summary." - }, - "parameters": [ - { - "name": "projectId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ] - } -} diff --git a/forms-bridge/addons/holded/data/swagger/team.json b/forms-bridge/addons/holded/data/swagger/team.json deleted file mode 100644 index f68f7e4a..00000000 --- a/forms-bridge/addons/holded/data/swagger/team.json +++ /dev/null @@ -1,424 +0,0 @@ -{ - "/employees": { - "get": { - "tags": ["Employees"], - "summary": "List all your employees", - "operationId": "listEmployees", - "description": "List all the employees you have in your app.\n", - "parameters": [ - { - "in": "query", - "name": "page", - "description": "the response is paginated and limited to 500 employees,", - "required": false, - "schema": { "type": "number" } - } - ], - "responses": { - "200": { "description": "search results matching criteria" }, - "400": { "description": "bad input parameter" } - } - }, - "post": { - "tags": ["Employees"], - "summary": "Create a new employee", - "operationId": "createEmployee", - "description": "Create a new employee in you app.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "lastName": { "type": "string" }, - "email": { "type": "string" }, - "sendInvite": { "type": "boolean" } - }, - "required": ["name", "lastName", "email"] - } - } - }, - "description": "Employee to add" - }, - "responses": { - "201": { - "description": "employee created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - } - } - }, - "/employees/{employeeId}": { - "parameters": [ - { - "name": "employeeId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "tags": ["Employees"], - "summary": "Get an Employee", - "operationId": "Get a Employee", - "description": "List all the employees you have in your app.\n", - "responses": { - "200": { "description": "search results matching criteria" } - } - }, - "put": { - "tags": ["Employees"], - "summary": "Update an employee", - "operationId": "Update Employee", - "description": "Update an employee.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "lastName": { "type": "string" }, - "mainEmail": { "type": "string" }, - "email": { "type": "string" }, - "nationality": { "type": "string" }, - "phone": { "type": "string" }, - "mobile": { "type": "string" }, - "dateOfBirth": { - "type": "string", - "description": "dd/mm/yyyy" - }, - "gender": { "type": "string", "description": "male or female" }, - "mainLanguage": { - "type": "string", - "description": "options = English, English(UK), English(US), English(Canada), Spanish, Spanish(Spain), Spanish(Mexico), Spanish(Argentina), Spanish(Colombia), Portuguese, Portuguese(Portugal), Portuguese(Brazil), Catalan, Galician, Euskera, French, German(Deutsch), Italian, Greek, Swedish, Dutch, Finnish, Irish, Norwegian, Danish, Czech, Croatian, Russian, Polish" - }, - "iban": { "type": "string" }, - "timeOffPolicyId": { "type": "string" }, - "timeOffSupervisors": { - "type": "array", - "items": { "type": "string" }, - "description": "containing employeesId" - }, - "reportingTo": { - "type": "string", - "description": "should be an employeeId" - }, - "code": { "type": "string", "description": "nif" }, - "socialSecurityNum": { "type": "string" }, - "address": { - "type": "object", - "properties": { - "address": { "type": "string" }, - "city": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" } - } - }, - "fiscalResidence": { "type": "boolean" }, - "fiscalAddress": { - "type": "object", - "description": "You need to set fiscalResidence to false in order to be able to send a fiscalAdress", - "properties": { - "idNum": { "type": "string" }, - "address": { "type": "string" }, - "city": { "type": "string" }, - "cityOfBirth": { "type": "string" }, - "postalCode": { "type": "string" }, - "province": { "type": "string" }, - "country": { "type": "string" }, - "countryOfBirth": { "type": "string" }, - "endSituationDate": { "type": "string" } - } - }, - "workplace": { - "type": "string", - "description": "workplace ID" - }, - "teams": { - "type": "array", - "description": "array of strings containing team ID's", - "items": { "type": "string" } - }, - "holdedUserId": { "type": "string" } - } - } - } - }, - "description": "Employee to update" - }, - "responses": { - "200": { - "description": "employee updated", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - } - }, - "delete": { - "tags": ["Employees"], - "summary": "Delete an Employee", - "operationId": "Delete a Employee", - "description": "Delete an employee.\n", - "responses": { "200": { "description": "Deleted" } } - } - }, - "/employees/times": { - "get": { - "tags": ["Employees' time-tracking"], - "summary": "List all the time-trackings of all your employees", - "operationId": "listTimes", - "description": "List all the time-trackings of all your employees.\n", - "parameters": [ - { - "in": "query", - "name": "page", - "description": "the response is paginated and limited to 500 employees,", - "required": false, - "schema": { "type": "number" } - } - ], - "responses": { - "200": { "description": "search results matching criteria" }, - "400": { "description": "bad input parameter" } - } - } - }, - "/employees/times/{employeeTimeId}": { - "parameters": [ - { - "name": "employeeTimeId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "tags": ["Employees' time-tracking"], - "summary": "Get a specific time-tracking", - "operationId": "getTime", - "description": "Get a specific time-tracking by Id.\n", - "responses": { - "200": { "description": "search results matching criteria" }, - "400": { "description": "bad input parameter" } - } - }, - "put": { - "tags": ["Employees' time-tracking"], - "summary": "Update a time-tracking", - "operationId": "UpdateTime", - "description": "Update a time-tracking.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "startTmp": { "type": "string" }, - "endTmp": { "type": "string" } - }, - "required": ["startTmp", "endTmp"] - } - } - }, - "description": "Employee to update" - }, - "responses": { - "200": { - "description": "time-tracking updated", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - } - }, - "delete": { - "tags": ["Employees' time-tracking"], - "summary": "Delete a time-tracking", - "operationId": "deleteTime", - "description": "Delete a time-tracking.\n", - "responses": { "200": { "description": "Deleted" } } - } - }, - "/employees/{employeeId}/times": { - "parameters": [ - { - "name": "employeeId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "tags": ["Employees' time-tracking"], - "summary": "List all the time-trackings of a single employee", - "operationId": "listemployeeTimes", - "description": "List all the time-trackings of a single employee.\n", - "responses": { - "200": { "description": "search results matching criteria" }, - "400": { "description": "bad input parameter" } - } - }, - "post": { - "tags": ["Employees' time-tracking"], - "summary": "Create a time-tracking for an specific employee", - "operationId": "createEmployeeTime", - "description": "Create a time-tracking for an specific employee.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "startTmp": { "type": "string" }, - "endTmp": { "type": "string" } - }, - "required": ["startTmp", "endTmp"] - } - } - }, - "description": "Employee's time to add" - }, - "responses": { - "201": { - "description": "employee's time-tracking created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - } - } - }, - "/employees/{employeeId}/times/clockin": { - "parameters": [ - { - "name": "employeeId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "post": { - "tags": ["Employees' time-tracking"], - "summary": "Employee clock-in", - "operationId": "employeeClockin", - "description": "Start counting employee time-tracking.\n", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "location": { "type": "string" } } - } - } - }, - "description": "Employee's time to add" - }, - "responses": { - "201": { - "description": "employee's time-tracking starts", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - } - } - }, - "/employees/{employeeId}/times/clockout": { - "parameters": [ - { - "name": "employeeId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "post": { - "tags": ["Employees' time-tracking"], - "summary": "Employee clock-out", - "operationId": "employeeClockout", - "description": "End counting employee time-tracking.\n", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "latitude": { "type": "string", "description": "Eg. -7.45556" }, - "longitude": { "type": "string", "description": "Eg. 55.55765" } - } - } - } - }, - "description": "Employee's time to add" - }, - "responses": { - "201": { - "description": "employee's time-tracking ends", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { "type": "integer" }, - "info": { "type": "string" }, - "id": { "type": "string" } - } - } - } - } - } - } - } - } -} diff --git a/forms-bridge/addons/listmonk/class-listmonk-addon.php b/forms-bridge/addons/listmonk/class-listmonk-addon.php index b9bb33c4..c595c22e 100644 --- a/forms-bridge/addons/listmonk/class-listmonk-addon.php +++ b/forms-bridge/addons/listmonk/class-listmonk-addon.php @@ -20,25 +20,32 @@ class Listmonk_Addon extends Addon { /** - * Handles the addon's title. + * Holds the addon's title. * * @var string */ - const TITLE = 'Listmonk'; + public const TITLE = 'Listmonk'; /** - * Handles the addon's name. + * Holds the addon's name. * * @var string */ - const NAME = 'listmonk'; + public const NAME = 'listmonk'; /** - * Handles the addom's custom bridge class. + * Holds the addom's custom bridge class. * * @var string */ - const BRIDGE = '\FORMS_BRIDGE\Listmonk_Form_Bridge'; + public const BRIDGE = '\FORMS_BRIDGE\Listmonk_Form_Bridge'; + + /** + * Holds the addon's OAS URL. + * + * @var string + */ + public const OAS_URL = 'https://listmonk.app/docs/swagger/collections.yaml'; /** * Performs a request against the backend to check the connexion status. @@ -89,16 +96,69 @@ public function fetch( $endpoint, $backend ) { return $bridge->submit(); } + /** + * Fetch available models from the OAS spec. + * + * @param Backend $backend HTTP backend object. + * + * @return array + * + * @todo Implementar el endpoint de consulta de endpoints disponibles. + */ + public function get_endpoints( $backend ) { + if ( function_exists( 'yaml_parse' ) ) { + $response = wp_remote_get( self::OAS_URL ); + + if ( ! is_wp_error( $response ) ) { + $data = yaml_parse( $response['body'] ); + + $oa_explorer = new OpenAPI( $data ); + $paths = $oa_explorer->paths(); + + return array_map( + function ( $path ) { + return '/api' . $path; + }, + $paths + ); + } + } + + return array( + '/api/subscribers', + ); + } + /** * Performs an introspection of the backend endpoint and returns API fields * and accepted content type. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { + if ( function_exists( 'yaml_parse' ) ) { + $response = wp_remote_get( self::OAS_URL ); + + if ( ! is_wp_error( $response ) ) { + $data = yaml_parse( $response['body'] ); + + if ( $data ) { + $oa_explorer = new OpenAPI( $data ); + + $method = strtolower( $method ?? 'post' ); + $path = preg_replace( '/^\/api/', '', $endpoint ); + $source = in_array( $method, array( 'post', 'put', 'patch' ), true ) ? 'body' : 'query'; + $params = $oa_explorer->params( $path, $method, $source ); + + return $params ?: array(); + } + } + } + if ( '/api/subscribers' === $endpoint ) { return array( array( diff --git a/forms-bridge/addons/mailchimp/class-mailchimp-addon.php b/forms-bridge/addons/mailchimp/class-mailchimp-addon.php index bf7c53dc..a595a2d1 100644 --- a/forms-bridge/addons/mailchimp/class-mailchimp-addon.php +++ b/forms-bridge/addons/mailchimp/class-mailchimp-addon.php @@ -20,25 +20,33 @@ class Mailchimp_Addon extends Addon { /** - * Handles the addon's title. + * Holds the addon's title. * * @var string */ - const TITLE = 'Mailchimp'; + public const TITLE = 'Mailchimp'; /** - * Handles the addon's name. + * Holds the addon's name. * * @var string */ - const NAME = 'mailchimp'; + public const NAME = 'mailchimp'; /** - * Handles the addom's custom bridge class. + * Holds the addom's custom bridge class. * * @var string */ - const BRIDGE = '\FORMS_BRIDGE\Mailchimp_Form_Bridge'; + public const BRIDGE = '\FORMS_BRIDGE\Mailchimp_Form_Bridge'; + + /** + * Holds the mailchimp marketing API swagger URL. + * + * @var string + */ + public const SWAGGER_URL = 'https://mailchimp.com/developer/spec/marketing.json'; + /** * Performs a request against the backend to check the connexion status. @@ -93,128 +101,42 @@ public function fetch( $endpoint, $backend ) { * Performs an introspection of the backend endpoint and returns API fields * and accepted content type. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array */ - public function get_endpoint_schema( $endpoint, $backend ) { - if ( strstr( $endpoint, '/lists/' ) !== false ) { - $fields = array( - array( - 'name' => 'email_address', - 'schema' => array( 'type' => 'string' ), - 'required' => true, - ), - array( - 'name' => 'status', - 'schema' => array( 'type' => 'string' ), - 'required' => true, - ), - array( - 'name' => 'email_type', - 'schema' => array( 'type' => 'string' ), - ), - array( - 'name' => 'interests', - 'schema' => array( - 'type' => 'object', - 'properties' => array(), - ), - ), - array( - 'name' => 'language', - 'schema' => array( 'type' => 'string' ), - ), - array( - 'name' => 'vip', - 'schema' => array( 'type' => 'boolean' ), - ), - array( - 'name' => 'location', - 'schema' => array( - 'type' => 'object', - 'properties' => array( - 'latitude' => array( 'type' => 'number' ), - 'longitude' => array( 'type' => 'number' ), - ), - ), - ), - array( - 'name' => 'marketing_permissions', - 'schema' => array( - 'type' => 'array', - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'marketing_permission_id' => array( - 'type' => 'string', - ), - 'enabled' => array( 'type' => 'boolean' ), - ), - ), - ), - ), - array( - 'name' => 'ip_signup', - 'schema' => array( 'type' => 'string' ), - ), - array( - 'name' => 'ip_opt', - 'schema' => array( 'type' => 'string' ), - ), - array( - 'name' => 'timestamp_opt', - 'schema' => array( 'type' => 'string' ), - ), - array( - 'name' => 'tags', - 'schema' => array( - 'type' => 'array', - 'items' => array( 'type' => 'string' ), - ), - ), - array( - 'name' => 'merge_fields', - 'schema' => array( - 'type' => 'object', - 'properties' => array(), - ), + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { + $response = wp_remote_get( + self::SWAGGER_URL, + array( + 'headers' => array( + 'Accept' => 'application/json', + 'Host' => 'mailchimp.com', + 'Referer' => 'https://mailchimp.com/developer/marketing/api/', + 'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0', ), - ); - - $fields_endpoint = str_replace( - '/members', - '/merge-fields', - $endpoint - ); - - $bridge = new Mailchimp_Form_Bridge( - array( - 'name' => '__mailchimp-' . time(), - 'endpoint' => $fields_endpoint, - 'method' => 'GET', - 'backend' => $backend, - ) - ); - - $response = $bridge->submit(); - - if ( is_wp_error( $response ) ) { - return array(); - } - - foreach ( $response['data']['merge_fields'] as $field ) { - $fields[] = array( - 'name' => 'merge_fields.' . $field['tag'], - 'schema' => array( 'type' => 'string' ), - ); - } - - return $fields; + ), + ); + + if ( is_wp_error( $response ) ) { + return array(); } - return array(); + $data = json_decode( $response['body'], true ); + if ( ! $data ) { + return array(); + } + + $oa_explorer = new OpenAPI( $data ); + + $method = strtolower( $method ?? 'post' ); + $path = preg_replace( '/^\/\d+(\.\d+)?/', '', $endpoint ); + $source = in_array( $method, array( 'post', 'put', 'patch' ), true ) ? 'body' : 'query'; + $params = $oa_explorer->params( $path, $method, $source ); + + return $params ?: array(); } } diff --git a/forms-bridge/addons/nextcloud/class-nextcloud-addon.php b/forms-bridge/addons/nextcloud/class-nextcloud-addon.php index 59cb3dbe..06ec01bb 100644 --- a/forms-bridge/addons/nextcloud/class-nextcloud-addon.php +++ b/forms-bridge/addons/nextcloud/class-nextcloud-addon.php @@ -110,12 +110,17 @@ public function fetch( $endpoint, $backend ) { * Performs an introspection of the backend model and returns API fields * and accepted content type. * - * @param string $filepath Filepath. - * @param string $backend Backend name. + * @param string $filepath Filepath. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array List of fields and content type of the model. */ - public function get_endpoint_schema( $filepath, $backend ) { + public function get_endpoint_schema( $filepath, $backend, $method = null ) { + if ( 'PUT' !== $method ) { + return array(); + } + $bridge = new Nextcloud_Form_Bridge( array( 'name' => '__nextcloud-' . time(), diff --git a/forms-bridge/addons/odoo/class-odoo-addon.php b/forms-bridge/addons/odoo/class-odoo-addon.php index 423ccb3c..824bcde2 100644 --- a/forms-bridge/addons/odoo/class-odoo-addon.php +++ b/forms-bridge/addons/odoo/class-odoo-addon.php @@ -21,25 +21,25 @@ class Odoo_Addon extends Addon { /** - * Handles the addon's title. + * Holds the addon's title. * * @var string */ - const TITLE = 'Odoo'; + public const TITLE = 'Odoo'; /** - * Handles the addon's name. + * Holds the addon's name. * * @var string */ - const NAME = 'odoo'; + public const NAME = 'odoo'; /** - * Handles the addom's custom bridge class. + * Holds the addom's custom bridge class. * * @var string */ - const BRIDGE = '\FORMS_BRIDGE\Odoo_Form_Bridge'; + public const BRIDGE = '\FORMS_BRIDGE\Odoo_Form_Bridge'; /** * Performs a request against the backend to check the connexion status. @@ -90,16 +90,54 @@ public function fetch( $endpoint, $backend ) { return $bridge->submit( array(), array( 'id', 'name' ) ); } + /** + * Fetch available models from the backend + * + * @param Backend $backend HTTP backend object. + * + * @return array + * + * @todo Implementar el endpoint de consulta de endpoints disponibles. + */ + public function get_endpoints( $backend ) { + $bridge = new Odoo_Form_Bridge( + array( + 'name' => '__odoo-' . time(), + 'method' => 'search_read', + 'endpoint' => 'ir.model', + 'backend' => $backend, + ) + ); + + $response = $bridge->submit( array(), array( 'name', 'model' ) ); + + if ( is_wp_error( $response ) ) { + return array(); + } + + return array_map( + function ( $model ) { + return $model['model']; + }, + $response['data']['result'] + ); + } + /** * Performs an introspection of the backend model and returns API fields * and accepted content type. * - * @param string $model Target model name. - * @param string $backend Target backend name. + * @param string $model Target model name. + * @param string $backend Target backend name. + * @param string|null $method HTTP method. * * @return array List of fields and content type of the model. */ - public function get_endpoint_schema( $model, $backend ) { + public function get_endpoint_schema( $model, $backend, $method = null ) { + if ( ! in_array( $method, array( 'write', 'create' ), true ) ) { + return array(); + } + $bridge = new Odoo_Form_Bridge( array( 'name' => '__odoo-' . time(), diff --git a/forms-bridge/addons/zoho/class-zoho-addon.php b/forms-bridge/addons/zoho/class-zoho-addon.php index 56529bf6..db008fd0 100644 --- a/forms-bridge/addons/zoho/class-zoho-addon.php +++ b/forms-bridge/addons/zoho/class-zoho-addon.php @@ -122,12 +122,17 @@ public function fetch( $endpoint, $backend ) { /** * Performs an introspection of the backend endpoint and returns API fields. * - * @param string $endpoint API endpoint. - * @param string $backend Backend name. + * @param string $endpoint API endpoint. + * @param string $backend Backend name. + * @param string|null $method HTTP method. * * @return array List of fields and content type of the endpoint. */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { + if ( in_array( $method, array( 'POST', 'PUT' ), true ) ) { + return array(); + } + if ( ! preg_match( '/\/(([A-Z][a-z]+(_[A-Z][a-z])?)(?:\/upsert)?$)/', diff --git a/forms-bridge/deps/http b/forms-bridge/deps/http index bab9e100..418b5932 160000 --- a/forms-bridge/deps/http +++ b/forms-bridge/deps/http @@ -1 +1 @@ -Subproject commit bab9e100a6bc805fca11921a087e925d65695fac +Subproject commit 418b593220c9babdeeed18c7f78a57d9fadd3bfd diff --git a/forms-bridge/deps/plugin b/forms-bridge/deps/plugin index bccdde34..88c43d2f 160000 --- a/forms-bridge/deps/plugin +++ b/forms-bridge/deps/plugin @@ -1 +1 @@ -Subproject commit bccdde34a97aca13a5118e9e08222d0dd0a17129 +Subproject commit 88c43d2f09f0cdf6d14eac99f14abf80832c20d1 diff --git a/forms-bridge/forms-bridge.php b/forms-bridge/forms-bridge.php index 70a076af..4253287e 100644 --- a/forms-bridge/forms-bridge.php +++ b/forms-bridge/forms-bridge.php @@ -37,6 +37,7 @@ /* Classes */ require_once __DIR__ . '/includes/class-api.php'; require_once __DIR__ . '/includes/class-json-finger.php'; +require_once __DIR__ . '/includes/class-openapi.php'; require_once __DIR__ . '/includes/class-rest-settings-controller.php'; require_once __DIR__ . '/includes/class-settings-store.php'; require_once __DIR__ . '/includes/class-logger.php'; diff --git a/forms-bridge/includes/class-addon.php b/forms-bridge/includes/class-addon.php index 001c950e..ffc9659c 100644 --- a/forms-bridge/includes/class-addon.php +++ b/forms-bridge/includes/class-addon.php @@ -589,12 +589,13 @@ public function fetch( $endpoint, $backend ) { * Performs an introspection of the backend endpoint and returns API fields * and accepted content type. * - * @param string $endpoint Target endpoint name. - * @param string $backend Target backend name. + * @param string $endpoint Target endpoint name. + * @param string $backend Target backend name. + * @param string|null $method HTTP method. * * @return array|WP_Error */ - public function get_endpoint_schema( $endpoint, $backend ) { + public function get_endpoint_schema( $endpoint, $backend, $method = null ) { return array(); } diff --git a/forms-bridge/includes/class-openapi.php b/forms-bridge/includes/class-openapi.php new file mode 100644 index 00000000..420d49c2 --- /dev/null +++ b/forms-bridge/includes/class-openapi.php @@ -0,0 +1,313 @@ + + */ + public const METHODS = array( 'get', 'post', 'put', 'patch', 'delete', 'trace' ); + + /** + * Holds the swagger data. + * + * @var array + */ + public $data; + + /** + * Handles the standard version of the data. + * + * @var string + */ + public $version; + + /** + * Return an OpenAPI parser instance from a filepath to a swagger file. + * + * @param string $path File path. + * + * @return OpenAPI|null + */ + public static function from( $path ) { + if ( ! is_file( $path ) || ! is_readable( $path ) ) { + return; + } + + $content = file_get_contents( $path ); + + try { + $data = json_decode( $content, true, JSON_THROW_ON_ERROR ); + } catch ( Error ) { + return; + } + + return new OpenAPI( $data ); + } + + /** + * Class constructor. + * + * @param array $data Swagger data. + * + * @throws Exception In case data is not a valid swagger condiguration. + */ + public function __construct( $data ) { + if ( ! isset( $data['openapi'] ) && ! isset( $data['swagger'] ) ) { + throw new Exception( 'Invalid OpenAPI data' ); + } + + $this->data = $data; + $this->version = $data['openapi'] ?? $data['swagger']; + } + + /** + * Returns the available list of API endpoints or swagger paths. + * + * @return array + */ + public function paths() { + return array_keys( $this->data['paths'] ); + } + + /** + * Search for a path object in the swagger data. + * + * @param string $path Target path. + * + * @return array|null + */ + public function path_obj( $path ) { + $path = self::parse_path( $path ); + + foreach ( $this->data['paths'] as $name => $obj ) { + if ( preg_match_all( '/{([^}]+)}/', $name, $matches ) ) { + $regexp = $name; + + foreach ( $matches[0] as $match ) { + $regexp = str_replace( $match, '[^\/]+', $regexp ); + } + + if ( preg_match( '#^' . $regexp . '$#', $path ) ) { + return $obj; + } + } elseif ( $path === $name ) { + return $obj; + } + } + } + + /** + * Retrives allowed content type for a path and an HTTP method. + * + * @param string $path Target path. + * @param string $method HTTP method. + * + * @return array|null + */ + public function encoding( $path, $method ) { + $path = $this->path_obj( $path ); + $content = $path[ $method ]['requestBody']['content'] ?? null; + + if ( ! $content ) { + return; + } + + return array_keys( $content ); + } + + /** + * Retrives params for a path and an HTTP method. Optionally, filtered by the + * param source. + * + * @param string $path Target path. + * @param string $method HTTP method. + * @param string|array $source Param source or sources. It could be body, path, query or cookie. + * + * @return array|null + */ + public function params( $path, $method = null, $source = null ) { + $path = self::parse_path( $path ); + + $path_obj = $this->path_obj( $path ); + if ( ! $path_obj ) { + return; + } + + $parameters = $path_obj['parameters'] ?? null; + if ( ! $parameters ) { + if ( ! $method ) { + return; + } + + $parameters = array(); + } + + foreach ( $parameters as &$param ) { + $param['in'] = 'path'; + } + + $method_obj = $path_obj[ $method ] ?? null; + if ( $method && ! $method_obj ) { + return; + } + + $parameters = array_merge( + $parameters, + $method_obj['parameters'] ?? array() + ); + + $c = count( $parameters ); + for ( $i = 0; $i < $c; $i++ ) { + $param = &$parameters[ $i ]; + if ( 'body' === $param['in'] && isset( $param['schema'] ) ) { + if ( isset( $param['schema']['$ref'] ) ) { + $param['schema'] = $this->get_ref( $param['schema']['$ref'] ); + } + + if ( isset( $param['schema']['properties'] ) && is_array( $param['schema']['properties'] ) ) { + array_splice( $parameters, $i, 1 ); + + foreach ( $param['schema']['properties'] as $prop => $prop_schema ) { + $parameters[] = array_merge( + $prop_schema, + array( + 'name' => $prop, + 'in' => 'body', + ), + ); + } + } + } + } + + $body = $method_obj['requestBody'] ?? null; + if ( $body ) { + $parameters = array_merge( $parameters, $this->body_to_params( $body ) ); + } + + if ( $source ) { + $parameters = array_values( + array_filter( + $parameters, + function ( $param ) use ( $source ) { + $in = $param['in'] ?? null; + + if ( is_array( $source ) ) { + return in_array( $in, $source, true ); + } + + return $in === $source; + } + ) + ); + } + + $l = count( $parameters ); + for ( $i = 0; $i < $l; $i++ ) { + $param = &$parameters[ $i ]; + + if ( isset( $param['type'] ) && ! isset( $param['schema'] ) ) { + $param['schema'] = array( 'type' => $param['type'] ); + unset( $param['type'] ); + } + + if ( isset( $param['$ref'] ) ) { + $parameters[ $i ] = $this->get_ref( $param['$ref'] ); + } elseif ( isset( $param['schema']['$ref'] ) ) { + $param['schema'] = $this->get_ref( $param['schema']['$ref'] ); + } + } + + return $parameters; + } + + /** + * Retrives the value of a ref in the swagger data. + * + * @param string $ref Ref absolute path. + * + * @return mixed|null + */ + public function get_ref( $ref ) { + if ( ! str_starts_with( $ref, '#/' ) ) { + return; + } + + $pointer = str_replace( '/', '.', substr( $ref, 2 ) ); + + if ( ! JSON_Finger::validate( $pointer ) ) { + return; + } + + $finger = new JSON_Finger( $this->data ); + return $finger->get( $pointer ); + } + + /** + * Scans a body object and return its attributes as an array of parameters. + * + * @param array $body Body object. + * + * @return array + */ + private function body_to_params( $body ) { + $parameters = array(); + + foreach ( $body['content'] as $encoding => $obj ) { + if ( isset( $obj['schema']['$ref'] ) ) { + $obj['schema'] = $this->get_ref( $obj['schema']['$ref'] ); + } + + foreach ( $obj['schema']['properties'] as $name => $defn ) { + $parameters[] = array_merge( + array( + 'name' => $name, + 'encoding' => $encoding, + 'in' => 'body', + ), + $defn + ); + } + } + + return $parameters; + } + + /** + * URL path normalizer. + * + * @param string $path Target path. + * + * @return string Normalized path. + */ + private static function parse_path( $path ) { + $url = wp_parse_url( $path ); + if ( empty( $url['path'] ) ) { + return '/'; + } else { + $path = $url['path']; + } + + $path = strpos( $path, '/' ) !== 0 ? '/' . $path : $path; + return preg_replace( '/\/+$/', '', $path ); + } +} diff --git a/forms-bridge/includes/class-rest-settings-controller.php b/forms-bridge/includes/class-rest-settings-controller.php index 7c7ff229..789896b1 100644 --- a/forms-bridge/includes/class-rest-settings-controller.php +++ b/forms-bridge/includes/class-rest-settings-controller.php @@ -367,6 +367,13 @@ private static function register_backend_routes() { 'type' => 'string', 'required' => true, ), + 'method' => array( + 'description' => __( + 'HTTP method', + 'forms-bridge', + ), + 'type' => 'string', + ), ), ), ) @@ -584,8 +591,8 @@ private static function reset_template( $addon, $name ) { /** * Callback for POST requests to the templates endpoint. * - * @param string $addon Name of the owner addon of the template. - * @param REST_Request $request CUrrent REST request instance. + * @param string $addon Name of the owner addon of the template. + * @param WP_REST_Request $request Current REST request instance. * * @return array|WP_Error Template use result. */ @@ -775,6 +782,14 @@ private static function prepare_addon_backend_request_handler( return array( $addon, $backend['name'], $credential['name'] ?? null ); } + /** + * Callback to the backend ping endpoint. + * + * @param string $addon Addon name. + * @param WP_REST_Request $request Request object. + * + * @return array|WP_Error + */ private static function ping_backend( $addon, $request ) { $handler = self::prepare_addon_backend_request_handler( $addon, @@ -803,18 +818,27 @@ private static function ping_backend( $addon, $request ) { return array( 'success' => $result ); } + /** + * Backend endpoint schema route callback. + * + * @param string $addon Addon name. + * @param WP_REST_Request $request Request object. + * + * @return array|WP_Error + */ private static function get_endpoint_schema( $addon, $request ) { $handler = self::prepare_addon_backend_request_handler( $addon, $request ); + if ( is_wp_error( $handler ) ) { return $handler; } [$addon, $backend] = $handler; - $schema = $addon->get_endpoint_schema( $request['endpoint'], $backend ); + $schema = $addon->get_endpoint_schema( $request['endpoint'], $backend, $request['method'] ); if ( is_wp_error( $schema ) ) { $error = self::internal_server_error(); @@ -830,11 +854,23 @@ private static function get_endpoint_schema( $addon, $request ) { return $schema; } + /** + * Callback of the addon schemas endpoint. + * + * @param string $name Addon name. + * + * @return array + */ private static function addon_schemas( $name ) { $bridge = FBAPI::get_bridge_schema( $name ); return array( 'bridge' => $bridge ); } + /** + * Callback of the http schemas endpoint. + * + * @return array + */ private static function http_schemas() { $backend = FBAPI::get_backend_schema(); $credential = FBAPI::get_credential_schema(); diff --git a/src/providers/ApiSchema.jsx b/src/providers/ApiSchema.jsx index 7e7f9e3c..ef2e9ca2 100644 --- a/src/providers/ApiSchema.jsx +++ b/src/providers/ApiSchema.jsx @@ -23,10 +23,11 @@ export default function ApiSchemaProvider({ children, bridge }) { const key = useMemo( () => JSON.stringify({ + method: bridge?.method, endpoint: bridge?.endpoint, backend, }), - [bridge?.endpoint, backend] + [bridge?.endpoint, bridge?.method, backend] ); const addSchema = (key, schema) => { @@ -34,13 +35,13 @@ export default function ApiSchemaProvider({ children, bridge }) { updates((i) => i + 1); }; - const fetch = (key, endpoint, backend) => { + const fetch = (key, { endpoint, method }, backend) => { setLoading(true); apiFetch({ path: `forms-bridge/v1/${addon}/backend/endpoint/schema`, method: "POST", - data: { endpoint, backend }, + data: { endpoint, method, backend }, }) .then((schema) => addSchema(key, schema)) .catch(() => addSchema(key, [])) @@ -53,10 +54,7 @@ export default function ApiSchemaProvider({ children, bridge }) { if (!backend || !bridge?.endpoint || loading || schemas.get(key)) return; - timeout.current = setTimeout( - () => fetch(key, bridge.endpoint, backend), - 400 - ); + timeout.current = setTimeout(() => fetch(key, bridge, backend), 400); }, [key, bridge, backend]); const schema = schemas.get(key);