├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README ├── README.md ├── requirements.txt ├── retailcrm ├── __init__.py ├── response.py └── versions │ ├── __init__.py │ ├── base.py │ ├── v3.py │ ├── v4.py │ └── v5.py ├── setup.py └── tests ├── v3_tests.py ├── v4_tests.py └── v5_tests.py /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | tags-ignore: 8 | - '*.*' 9 | pull_request: 10 | 11 | env: 12 | RETAILCRM_URL: https://test.retailcrm.pro 13 | RETAILCRM_KEY: key 14 | 15 | jobs: 16 | tests: 17 | name: Tests 18 | runs-on: ubuntu-latest 19 | strategy: 20 | matrix: 21 | python-version: ['3.8', '3.9', '3.10', '3.11'] 22 | include: 23 | - python-version: '3.12' 24 | coverage: 1 25 | steps: 26 | - uses: actions/checkout@v2 27 | - name: Set up Python ${{ matrix.python-version }} 28 | uses: actions/setup-python@v2 29 | with: 30 | python-version: ${{ matrix.python-version }} 31 | - name: Cache pip 32 | uses: actions/cache@v2 33 | with: 34 | path: ~/.cache/pip 35 | key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} 36 | restore-keys: | 37 | ${{ runner.os }}-pip- 38 | ${{ runner.os }}- 39 | - name: Install dependencies 40 | run: | 41 | python -m pip install --upgrade pip 42 | pip install flake8 43 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 44 | - name: Lint with flake8 45 | run: | 46 | # stop the build if there are Python syntax errors or undefined names 47 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 48 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 49 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --ignore=F401 50 | - name: Tests 51 | env: 52 | COVERAGE: ${{ matrix.coverage }} 53 | if: env.COVERAGE != 1 54 | run: python -m unittest tests/*.py 55 | - name: Tests with coverage 56 | env: 57 | COVERAGE: ${{ matrix.coverage }} 58 | if: env.COVERAGE == 1 59 | run: | 60 | coverage run -m unittest tests/*.py 61 | - name: Coverage 62 | env: 63 | COVERAGE: ${{ matrix.coverage }} 64 | if: env.COVERAGE == 1 65 | run: | 66 | bash <(curl -s https://codecov.io/bash) 67 | rm .coverage coverage.xml 68 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.pyc 3 | *.nose* 4 | /*.egg-info 5 | /dist/ 6 | /venv/ 7 | /.vscode/ 8 | /build/ 9 | .python-version 10 | .coverage 11 | coverage.xml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2021 RetailDriver LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | RetailCRM python API client 2 | =========================== 3 | 4 | This is python RetailCRM API client. This library allows to use all 5 | available API versions. 6 | 7 | Install 8 | ------- 9 | 10 | :: 11 | 12 | pip3 install retailcrm 13 | 14 | Usage 15 | ----- 16 | 17 | 18 | .. code:: python 19 | 20 | # coding utf-8 21 | 22 | import retailcrm 23 | 24 | 25 | client = retailcrm.v3('https://demo.retailcrm.pro', 'uLxXKBwjQteE9NkO3cJAqTXNwvKktaTc') 26 | 27 | order = { 28 | 'firstName': 'John', 29 | 'lastName': 'Doe', 30 | 'phone': '+79000000000', 31 | 'email': 'john@example.com', 32 | 'orderMethod': 'call-request', 33 | } 34 | 35 | result = client.order_create(order) 36 | 37 | 38 | .. code:: python 39 | 40 | # coding utf-8 41 | 42 | import retailcrm 43 | 44 | 45 | client = retailcrm.v4('https://demo.retailcrm.pro', 'uLxXKBwjQteE9NkO3cJAqTXNwvKktaTc') 46 | 47 | result = client.customers_history(filter={'sinceId': '1500', 'startDate': '2018-03-01'}) 48 | 49 | print(result['pagination']['totalCount']) 50 | 51 | 52 | .. code:: python 53 | 54 | # coding utf-8 55 | 56 | import retailcrm 57 | 58 | 59 | client = retailcrm.v5('https://demo.retailcrm.pro', 'uLxXKBwjQteE9NkO3cJAqTXNwvKktaTc') 60 | site = 'example-com' 61 | task = { 62 | 'text': 'Product availability problem', 63 | 'commentary': 'Take a look ASAP', 64 | 'order': { 65 | 'externalId': '100500' 66 | }, 67 | 'performerId': 1 68 | } 69 | 70 | result = client.task_create(task, site) 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/retailcrm/api-client-python/workflows/ci/badge.svg)](https://github.com/retailcrm/api-client-python/actions) 2 | [![Coverage](https://img.shields.io/codecov/c/gh/retailcrm/api-client-python/master.svg?logo=codecov&logoColor=white)](https://codecov.io/gh/retailcrm/api-client-python) 3 | [![PyPI](https://img.shields.io/pypi/v/retailcrm.svg?logo=pypi&logoColor=white)](https://pypi.python.org/pypi/retailcrm) 4 | [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/retailcrm.svg?logo=python&logoColor=white)](https://pypi.python.org/pypi/retailcrm) 5 | 6 | 7 | RetailCRM python API client 8 | =========================== 9 | 10 | This is Python RetailCRM API client. This library allows to use all available API versions. 11 | 12 | ## Install 13 | 14 | ``` 15 | pip3 install retailcrm 16 | ``` 17 | 18 | ## Usage 19 | 20 | #### API version 3 order create 21 | 22 | ```python 23 | # coding utf-8 24 | 25 | import retailcrm 26 | 27 | 28 | client = retailcrm.v3('https://demo.retailcrm.pro', 'uLxXKBwjQteE9NkO3cJAqTXNwvKktaTc') 29 | 30 | order = { 31 | 'firstName': 'John', 32 | 'lastName': 'Doe', 33 | 'phone': '+79000000000', 34 | 'email': 'john@example.com', 35 | 'orderMethod': 'call-request', 36 | } 37 | 38 | result = client.order_create(order) 39 | ``` 40 | 41 | #### API version 4 customers history 42 | 43 | ```python 44 | # coding utf-8 45 | 46 | import retailcrm 47 | 48 | 49 | client = retailcrm.v4('https://demo.retailcrm.pro', 'uLxXKBwjQteE9NkO3cJAqTXNwvKktaTc') 50 | 51 | result = client.customers_history(filters={'sinceId': '1500', 'startDate': '2018-03-01'}) 52 | 53 | print(result['pagination']['totalCount']) 54 | ``` 55 | 56 | #### API version 5 task create 57 | 58 | ```python 59 | # coding utf-8 60 | 61 | import retailcrm 62 | 63 | 64 | client = retailcrm.v5('https://demo.retailcrm.pro', 'uLxXKBwjQteE9NkO3cJAqTXNwvKktaTc') 65 | site = 'example-com' 66 | task = { 67 | 'text': 'Product availability problem', 68 | 'commentary': 'Take a look ASAP', 69 | 'order': { 70 | 'externalId': '100500' 71 | }, 72 | 'performerId': 1 73 | } 74 | 75 | result = client.task_create(task, site) 76 | ``` 77 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | multidimensional-urlencode==0.0.4 2 | nose==1.3.7 3 | requests==2.32.1 4 | coverage==4.5.4 5 | pook==1.3.0 6 | setuptools==70.0.0 7 | -------------------------------------------------------------------------------- /retailcrm/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | Init 5 | """ 6 | 7 | from retailcrm.versions.v3 import Client as v3 8 | from retailcrm.versions.v4 import Client as v4 9 | from retailcrm.versions.v5 import Client as v5 10 | -------------------------------------------------------------------------------- /retailcrm/response.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | Response class 5 | """ 6 | 7 | 8 | class Response(object): 9 | """ 10 | API response class 11 | """ 12 | 13 | def __init__(self, code, body): 14 | self.__status_code = code 15 | self.__response_body = body 16 | 17 | def get_status_code(self): 18 | """ 19 | :return: integer 20 | """ 21 | return self.__status_code 22 | 23 | def get_response(self): 24 | """ 25 | :return: string 26 | """ 27 | return self.__response_body 28 | 29 | def is_successful(self): 30 | """ 31 | :return: boolean 32 | """ 33 | return int(self.__status_code) < 400 34 | 35 | def get_error_msg(self): 36 | """ 37 | :return: string 38 | """ 39 | return self.__response_body['errorMsg'] 40 | 41 | def get_errors(self): 42 | """ 43 | :return: collection 44 | """ 45 | 46 | errors = self.__response_body.get('errors', {}) 47 | 48 | return errors 49 | -------------------------------------------------------------------------------- /retailcrm/versions/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | Init 5 | """ 6 | -------------------------------------------------------------------------------- /retailcrm/versions/base.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | API Client base class 5 | """ 6 | 7 | import requests 8 | 9 | from multidimensional_urlencode import urlencode as query_builder 10 | from retailcrm.response import Response 11 | 12 | 13 | class Base(object): 14 | """RetailCRM API client""" 15 | 16 | def __init__(self, crm_url, api_key, version): 17 | self.api_url = crm_url + '/api' 18 | self.api_key = api_key 19 | self.api_version = version 20 | self.parameters = {} 21 | 22 | def get(self, url, version=True): 23 | """ 24 | Get request 25 | :param url: string 26 | :param version: boolean 27 | :return: Response 28 | """ 29 | base_url = self.api_url + '/' + self.api_version if version else self.api_url 30 | requests_url = base_url + url if not self.parameters else base_url + url + "?" + query_builder(self.parameters) 31 | response = requests.get(requests_url, headers={ 32 | 'X-API-KEY': self.api_key}) 33 | self.parameters = {} 34 | 35 | return Response(response.status_code, response.json()) 36 | 37 | def post(self, url, version=True): 38 | """ 39 | Post request 40 | :return: Response 41 | """ 42 | base_url = self.api_url + '/' + self.api_version if version else self.api_url 43 | requests_url = base_url + url 44 | response = requests.post(requests_url, data=self.parameters, headers={ 45 | 'X-API-KEY': self.api_key}) 46 | self.parameters = {} 47 | 48 | return Response(response.status_code, response.json()) 49 | 50 | def api_versions(self): 51 | """ 52 | :return: Response 53 | """ 54 | return self.get('/api-versions', False) 55 | 56 | def api_credentials(self): 57 | """ 58 | :return: Response 59 | """ 60 | return self.get('/credentials', False) 61 | 62 | def statistic_update(self): 63 | """ 64 | :return Response 65 | """ 66 | return self.get('/statistic/update') 67 | -------------------------------------------------------------------------------- /retailcrm/versions/v3.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | API Client version 3 5 | """ 6 | 7 | import json 8 | 9 | from retailcrm.versions.base import Base 10 | 11 | 12 | class Client(Base): 13 | """RetailCRM API client""" 14 | 15 | apiVersion = 'v3' 16 | 17 | def __init__(self, crm_url, api_key): 18 | Base.__init__(self, crm_url, api_key, self.apiVersion) 19 | 20 | def customers(self, filters=None, limit=20, page=1): 21 | """ 22 | :param filters: object 23 | :param limit: integer 24 | :param page: integer 25 | :return: Response 26 | """ 27 | self.parameters['filter'] = filters 28 | self.parameters['limit'] = limit 29 | self.parameters['page'] = page 30 | 31 | return self.get('/customers') 32 | 33 | def customer_create(self, customer, site=None): 34 | """ 35 | :param customer: object 36 | :param site: string 37 | :return: Response 38 | """ 39 | self.parameters['customer'] = json.dumps(customer) 40 | 41 | if site is not None: 42 | self.parameters['site'] = site 43 | 44 | return self.post('/customers/create') 45 | 46 | def customers_fix_external_ids(self, customers, site=None): 47 | """ 48 | :param customers: object 49 | :param site: string 50 | :return: Response 51 | """ 52 | self.parameters['customers'] = json.dumps(customers) 53 | 54 | if site is not None: 55 | self.parameters['site'] = site 56 | 57 | return self.post('/customers/fix-external-ids') 58 | 59 | def customers_upload(self, customers, site=None): 60 | """ 61 | :param customers: array of objects 62 | :param site: string 63 | :return: Response 64 | """ 65 | self.parameters['customers'] = json.dumps(customers) 66 | 67 | if site is not None: 68 | self.parameters['site'] = site 69 | 70 | return self.post('/customers/upload') 71 | 72 | def customer(self, uid, uid_type='externalId', site=None): 73 | """ 74 | :param uid: string 75 | :param uid_type: string 76 | :param site: string 77 | :return: Response 78 | """ 79 | if uid_type != 'externalId': 80 | self.parameters['by'] = uid_type 81 | 82 | if site is not None: 83 | self.parameters['site'] = site 84 | 85 | return self.get('/customers/' + str(uid)) 86 | 87 | def customer_edit(self, customer, uid_type='externalId', site=None): 88 | """ 89 | :param customer: object 90 | :param uid_type: string 91 | :param site: string 92 | :return: Response 93 | """ 94 | self.parameters['customer'] = json.dumps(customer) 95 | 96 | if uid_type != 'externalId': 97 | self.parameters['by'] = uid_type 98 | 99 | if site is not None: 100 | self.parameters['site'] = site 101 | 102 | return self.post('/customers/' + customer[uid_type] + '/edit') 103 | 104 | def orders(self, filters=None, limit=20, page=1): 105 | """ 106 | :param filters: object 107 | :param limit: integer 108 | :param page: integer 109 | :return: Response 110 | """ 111 | self.parameters['filter'] = filters 112 | self.parameters['limit'] = limit 113 | self.parameters['page'] = page 114 | 115 | return self.get('/orders') 116 | 117 | def order_create(self, order, site=None): 118 | """ 119 | :param order: object 120 | :param site: string 121 | :return: Response 122 | """ 123 | self.parameters['order'] = json.dumps(order) 124 | 125 | if site is not None: 126 | self.parameters['site'] = site 127 | 128 | return self.post('/orders/create') 129 | 130 | def orders_fix_external_ids(self, orders, site=None): 131 | """ 132 | :param orders: object 133 | :param site: string 134 | :return: Response 135 | """ 136 | self.parameters['orders'] = json.dumps(orders) 137 | 138 | if site is not None: 139 | self.parameters['site'] = site 140 | 141 | return self.post('/orders/fix-external-ids') 142 | 143 | def orders_history(self, start=None, end=None, limit=100, offset=0, skip=True): 144 | """ 145 | :param start: DateTime 146 | :param end: DateTime 147 | :param limit: integer 148 | :param offset: integer 149 | :param skip: boolean 150 | :return: Response 151 | """ 152 | self.parameters['startDate'] = start 153 | self.parameters['endDate'] = end 154 | self.parameters['limit'] = limit 155 | self.parameters['offset'] = offset 156 | self.parameters['skipMyChanges'] = skip 157 | 158 | return self.get('/orders/history') 159 | 160 | def orders_statuses(self, ids, external_ids): 161 | """ 162 | :param ids: array 163 | :param external_ids: array 164 | :return: Response 165 | """ 166 | self.parameters['ids'] = ids 167 | self.parameters['externalIds'] = external_ids 168 | 169 | return self.get('/orders/statuses') 170 | 171 | def orders_upload(self, orders, site=None): 172 | """ 173 | :param orders: object 174 | :param site: string 175 | :return: Response 176 | """ 177 | self.parameters['orders'] = json.dumps(orders) 178 | 179 | if site is not None: 180 | self.parameters['site'] = site 181 | 182 | return self.post('/orders/upload') 183 | 184 | def order(self, uid, uid_type='externalId', site=None): 185 | """ 186 | :param uid: string 187 | :param uid_type: string 188 | :param site: string 189 | :return: Response 190 | """ 191 | if site is not None: 192 | self.parameters['site'] = site 193 | 194 | if uid_type != 'externalId': 195 | self.parameters['by'] = uid_type 196 | 197 | return self.get('/orders/' + str(uid)) 198 | 199 | def order_edit(self, order, uid_type='externalId', site=None): 200 | """ 201 | :param order: object 202 | :param uid_type: string 203 | :param site: string 204 | :return: Response 205 | """ 206 | self.parameters['order'] = json.dumps(order) 207 | 208 | if site is not None: 209 | self.parameters['site'] = site 210 | 211 | if uid_type != 'externalId': 212 | self.parameters['by'] = uid_type 213 | 214 | return self.post('/orders/' + str(order[uid_type]) + '/edit') 215 | 216 | def packs(self, filters=None, limit=20, page=1): 217 | """ 218 | :param filters: object 219 | :param limit: integer 220 | :param page: integer 221 | :return: Response 222 | """ 223 | self.parameters['filter'] = filters 224 | self.parameters['limit'] = limit 225 | self.parameters['page'] = page 226 | 227 | return self.get('/orders/packs') 228 | 229 | def pack_create(self, pack): 230 | """ 231 | :param pack: object 232 | :return: Response 233 | """ 234 | self.parameters['pack'] = json.dumps(pack) 235 | 236 | return self.post('/orders/packs/create') 237 | 238 | def packs_history(self, filters=None, limit=20, page=1): 239 | """ 240 | :param filters: object 241 | :param limit: integer 242 | :param page: integer 243 | :return: Response 244 | """ 245 | self.parameters['filter'] = filters 246 | self.parameters['limit'] = limit 247 | self.parameters['page'] = page 248 | 249 | return self.get('/orders/packs/history') 250 | 251 | def pack(self, uid): 252 | """ 253 | :param uid: integer 254 | :return: Response 255 | """ 256 | 257 | return self.get('/orders/packs/' + str(uid)) 258 | 259 | def pack_delete(self, uid): 260 | """ 261 | :param uid: integer 262 | :return: Response 263 | """ 264 | 265 | return self.post('/orders/packs/' + str(uid) + '/delete') 266 | 267 | def pack_edit(self, pack): 268 | """ 269 | :param pack: object 270 | :return: Response 271 | """ 272 | self.parameters['pack'] = json.dumps(pack) 273 | 274 | return self.post('/orders/packs/' + str(pack['id']) + '/edit') 275 | 276 | def countries(self): 277 | """ 278 | :return: Response 279 | """ 280 | 281 | return self.get('/reference/countries') 282 | 283 | def delivery_services(self): 284 | """ 285 | :return: Response 286 | """ 287 | 288 | return self.get('/reference/delivery-services') 289 | 290 | def delivery_services_edit(self, delivery_service): 291 | """ 292 | :param delivery_service: object 293 | :return: Response 294 | """ 295 | self.parameters['deliveryService'] = json.dumps(delivery_service) 296 | 297 | return self.post('/reference/delivery-services/' + delivery_service['code'] + '/edit') 298 | 299 | def delivery_types(self): 300 | """ 301 | :return: Response 302 | """ 303 | 304 | return self.get('/reference/delivery-types') 305 | 306 | def delivery_types_edit(self, delivery_type): 307 | """ 308 | :param delivery_type: object 309 | :return: Response 310 | """ 311 | self.parameters['deliveryType'] = json.dumps(delivery_type) 312 | 313 | return self.post('/reference/delivery-types/' + delivery_type['code'] + '/edit') 314 | 315 | def order_methods(self): 316 | """ 317 | :return: Response 318 | """ 319 | 320 | return self.get('/reference/order-methods') 321 | 322 | def order_methods_edit(self, order_method): 323 | """ 324 | 325 | :param order_method: object 326 | :return: Response 327 | """ 328 | self.parameters['orderMethod'] = json.dumps(order_method) 329 | 330 | return self.post('/reference/order-methods/' + order_method['code'] + '/edit') 331 | 332 | def order_types(self): 333 | """ 334 | :return: Response 335 | """ 336 | 337 | return self.get('/reference/order-types') 338 | 339 | def order_types_edit(self, order_type): 340 | """ 341 | :param order_type: object 342 | :return: Response 343 | """ 344 | self.parameters['orderType'] = json.dumps(order_type) 345 | 346 | return self.post('/reference/order-types/' + order_type['code'] + '/edit') 347 | 348 | def payment_statuses(self): 349 | """ 350 | :return: Response 351 | """ 352 | 353 | return self.get('/reference/payment-statuses') 354 | 355 | def payment_statuses_edit(self, payment_status): 356 | """ 357 | :param payment_status: object 358 | :return: Response 359 | """ 360 | self.parameters['paymentStatus'] = json.dumps(payment_status) 361 | 362 | return self.post('/reference/payment-statuses/' + payment_status['code'] + '/edit') 363 | 364 | def payment_types(self): 365 | """ 366 | :return: Response 367 | """ 368 | 369 | return self.get('/reference/payment-types') 370 | 371 | def payment_types_edit(self, payment_type): 372 | """ 373 | :param payment_type: object 374 | :return: Response 375 | """ 376 | self.parameters['paymentType'] = json.dumps(payment_type) 377 | 378 | return self.post('/reference/payment-types/' + payment_type['code'] + '/edit') 379 | 380 | def product_statuses(self): 381 | """ 382 | :return: Response 383 | """ 384 | 385 | return self.get('/reference/product-statuses') 386 | 387 | def product_statuses_edit(self, product_status): 388 | """ 389 | :param product_status: object 390 | :return: Response 391 | """ 392 | self.parameters['productStatus'] = json.dumps(product_status) 393 | 394 | return self.post('/reference/product-statuses/' + product_status['code'] + '/edit') 395 | 396 | def sites(self): 397 | """ 398 | :return: Response 399 | """ 400 | 401 | return self.get('/reference/sites') 402 | 403 | def sites_edit(self, site): 404 | """ 405 | :param site: object 406 | :return: Response 407 | """ 408 | self.parameters['site'] = json.dumps(site) 409 | 410 | return self.post('/reference/sites/' + site['code'] + '/edit') 411 | 412 | def status_groups(self): 413 | """ 414 | :return: Response 415 | """ 416 | 417 | return self.get('/reference/status-groups') 418 | 419 | def statuses(self): 420 | """ 421 | :return: Response 422 | """ 423 | 424 | return self.get('/reference/statuses') 425 | 426 | def statuses_edit(self, status): 427 | """ 428 | :param status: object 429 | :return: Response 430 | """ 431 | self.parameters['status'] = json.dumps(status) 432 | 433 | return self.post('/reference/statuses/' + status['code'] + '/edit') 434 | 435 | def stores(self): 436 | """ 437 | :return: Response 438 | """ 439 | 440 | return self.get('/reference/stores') 441 | 442 | def stores_edit(self, store): 443 | """ 444 | :param store: object 445 | :return: Response 446 | """ 447 | self.parameters['store'] = json.dumps(store) 448 | 449 | return self.post('/reference/stores/' + store['code'] + '/edit') 450 | 451 | def inventories(self, filters=None, limit=20, page=1): 452 | """ 453 | :param filters: object 454 | :param limit: integer 455 | :param page: integer 456 | :return: Response 457 | """ 458 | self.parameters['filter'] = filters 459 | self.parameters['limit'] = limit 460 | self.parameters['page'] = page 461 | 462 | return self.get('/store/inventories') 463 | 464 | def inventories_upload(self, offers, site=None): 465 | """ 466 | :param offers: array of objects 467 | :param site: string 468 | :return: Response 469 | """ 470 | if site is not None: 471 | self.parameters['site'] = site 472 | 473 | self.parameters['offers'] = json.dumps(offers) 474 | 475 | return self.post('/store/inventories/upload') 476 | 477 | def telephony_call_event(self, phone, call_type, code, status): 478 | """ 479 | :param phone: string 480 | :param call_type: string 481 | :param code: string 482 | :param status: string 483 | :return: Response 484 | """ 485 | self.parameters['hangupStatus'] = status 486 | self.parameters['phone'] = phone 487 | self.parameters['code'] = code 488 | self.parameters['type'] = call_type 489 | 490 | return self.post('/telephony/call/event') 491 | 492 | def telephony_calls_upload(self, calls): 493 | """ 494 | :param calls: array of objects 495 | :return: Response 496 | """ 497 | self.parameters['calls'] = json.dumps(calls) 498 | 499 | return self.post('/telephony/calls/upload') 500 | 501 | def telephony_manager(self, phone, details=True): 502 | """ 503 | :param phone: string 504 | :param details: string 505 | :return: Response string 506 | """ 507 | self.parameters['phone'] = phone 508 | self.parameters['details'] = details 509 | 510 | return self.get('/telephony/manager') 511 | 512 | def telephony_settings(self, code, client_id, make_call_url, active, name, image): 513 | """ 514 | :param code: string 515 | :param client_id: string 516 | :param make_call_url: string 517 | :param active: string 518 | :param name: string 519 | :param image: string 520 | :return: Response 521 | """ 522 | self.parameters['code'] = code 523 | self.parameters['clientId'] = client_id 524 | self.parameters['makeCallUrl'] = make_call_url 525 | self.parameters['active'] = active 526 | self.parameters['name'] = name 527 | self.parameters['image'] = image 528 | 529 | return self.post('/telephony/settings/' + str(code)) 530 | 531 | def statistic_update(self): 532 | """ 533 | :return: Response 534 | """ 535 | 536 | return self.get('/statistic/update') 537 | -------------------------------------------------------------------------------- /retailcrm/versions/v4.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | API Client version 4 5 | """ 6 | 7 | import json 8 | 9 | from retailcrm.versions.base import Base 10 | 11 | 12 | class Client(Base): 13 | """RetailCRM API client""" 14 | 15 | apiVersion = 'v4' 16 | 17 | def __init__(self, crm_url, api_key): 18 | Base.__init__(self, crm_url, api_key, self.apiVersion) 19 | 20 | def customers(self, filters=None, limit=20, page=1): 21 | """ 22 | :param filters: object 23 | :param limit: integer 24 | :param page: integer 25 | :return: Response 26 | """ 27 | self.parameters['filter'] = filters 28 | self.parameters['limit'] = limit 29 | self.parameters['page'] = page 30 | 31 | return self.get('/customers') 32 | 33 | def customer_create(self, customer, site=None): 34 | """ 35 | :param customer: object 36 | :param site: string 37 | :return: Response 38 | """ 39 | self.parameters['customer'] = json.dumps(customer) 40 | 41 | if site is not None: 42 | self.parameters['site'] = site 43 | 44 | return self.post('/customers/create') 45 | 46 | def customers_fix_external_ids(self, customers, site=None): 47 | """ 48 | :param customers: array of objects 49 | :param site: string 50 | :return: Response 51 | """ 52 | self.parameters['customers'] = json.dumps(customers) 53 | 54 | if site is not None: 55 | self.parameters['site'] = site 56 | 57 | return self.post('/customers/fix-external-ids') 58 | 59 | def customers_history(self, filters=None, limit=20, page=1): 60 | """ 61 | :param filters: object 62 | :param limit: integer 63 | :param page: integer 64 | :return: Response 65 | """ 66 | self.parameters['filter'] = filters 67 | self.parameters['limit'] = limit 68 | self.parameters['page'] = page 69 | 70 | return self.get('/customers/history') 71 | 72 | def customers_upload(self, customers, site=None): 73 | """ 74 | :param customers: array of objects 75 | :param site: string 76 | :return: Response 77 | """ 78 | self.parameters['customers'] = json.dumps(customers) 79 | 80 | if site is not None: 81 | self.parameters['site'] = site 82 | 83 | return self.post('/customers/upload') 84 | 85 | def customer(self, uid, uid_type='externalId', site=None): 86 | """ 87 | :param uid: string 88 | :param uid_type: string 89 | :param site: string 90 | :return: Response 91 | """ 92 | if uid_type != 'externalId': 93 | self.parameters['by'] = uid_type 94 | 95 | if site is not None: 96 | self.parameters['site'] = site 97 | 98 | return self.get('/customers/' + str(uid)) 99 | 100 | def customer_edit(self, customer, uid_type='externalId', site=None): 101 | """ 102 | :param customer: object 103 | :param uid_type: string 104 | :param site: string 105 | :return: Response 106 | """ 107 | self.parameters['customer'] = json.dumps(customer) 108 | 109 | if uid_type != 'externalId': 110 | self.parameters['by'] = uid_type 111 | 112 | if site is not None: 113 | self.parameters['site'] = site 114 | 115 | return self.post('/customers/' + customer[uid_type] + '/edit') 116 | 117 | def delivery_setting(self, code): 118 | """ 119 | :param code: string 120 | :return: Response 121 | """ 122 | 123 | return self.get('/delivery/generic/setting/' + str(code)) 124 | 125 | def delivery_setting_edit(self, configuration): 126 | """ 127 | :param configuration: object 128 | :return: Response 129 | """ 130 | self.parameters['configuration'] = json.dumps(configuration) 131 | 132 | return self.post('/delivery/generic/setting/' + str(configuration['code']) + '/edit') 133 | 134 | def delivery_tracking(self, code, status_update): 135 | """ 136 | :param code: string 137 | :param status_update: array of objects 138 | :return: Response 139 | """ 140 | self.parameters['statusUpdate'] = json.dumps(status_update) 141 | 142 | return self.post('/delivery/generic/' + str(code) + '/tracking') 143 | 144 | def marketplace_setting_edit(self, configuration): 145 | """ 146 | :param configuration: object 147 | :return: Response 148 | """ 149 | self.parameters['configuration'] = json.dumps(configuration) 150 | 151 | return self.post('/marketplace/external/setting/' + str(configuration['code']) + '/edit') 152 | 153 | def orders(self, filters=None, limit=20, page=1): 154 | """ 155 | :param filters: object 156 | :param limit: integer 157 | :param page: integer 158 | :return: Response 159 | """ 160 | self.parameters['filter'] = filters 161 | self.parameters['limit'] = limit 162 | self.parameters['page'] = page 163 | 164 | return self.get('/orders') 165 | 166 | def order_create(self, order, site=None): 167 | """ 168 | :param order: object 169 | :param site: string 170 | :return: Response 171 | """ 172 | self.parameters['order'] = json.dumps(order) 173 | 174 | if site is not None: 175 | self.parameters['site'] = site 176 | 177 | return self.post('/orders/create') 178 | 179 | def orders_fix_external_ids(self, orders, site=None): 180 | """ 181 | :param orders: array of objects 182 | :param site: string 183 | :return: Response 184 | """ 185 | self.parameters['orders'] = json.dumps(orders) 186 | 187 | if site is not None: 188 | self.parameters['site'] = site 189 | 190 | return self.post('/orders/fix-external-ids') 191 | 192 | def orders_history(self, filters=None, limit=20, page=1): 193 | """ 194 | :param filters: object 195 | :param limit: integer 196 | :param page: integer 197 | :return: Response 198 | """ 199 | self.parameters['filter'] = filters 200 | self.parameters['limit'] = limit 201 | self.parameters['page'] = page 202 | 203 | return self.get('/orders/history') 204 | 205 | def orders_statuses(self, ids, external_ids): 206 | """ 207 | :param ids: array 208 | :param external_ids: array 209 | :return: Response 210 | """ 211 | self.parameters['ids'] = ids 212 | self.parameters['externalIds'] = external_ids 213 | 214 | return self.get('/orders/statuses') 215 | 216 | def orders_upload(self, orders, site=None): 217 | """ 218 | :param orders: array of objects 219 | :param site: string 220 | :return: Response 221 | """ 222 | self.parameters['orders'] = json.dumps(orders) 223 | 224 | if site is not None: 225 | self.parameters['site'] = site 226 | 227 | return self.post('/orders/upload') 228 | 229 | def order(self, uid, uid_type='externalId', site=None): 230 | """ 231 | :param uid: string 232 | :param uid_type: string 233 | :param site: string 234 | :return: Response 235 | """ 236 | if site is not None: 237 | self.parameters['site'] = site 238 | 239 | if uid_type != 'externalId': 240 | self.parameters['by'] = uid_type 241 | 242 | return self.get('/orders/' + str(uid)) 243 | 244 | def order_edit(self, order, uid_type='externalId', site=None): 245 | """ 246 | :param order: object 247 | :param uid_type: string 248 | :param site: string 249 | :return: Response 250 | """ 251 | self.parameters['order'] = json.dumps(order) 252 | 253 | if site is not None: 254 | self.parameters['site'] = site 255 | 256 | if uid_type != 'externalId': 257 | self.parameters['by'] = uid_type 258 | 259 | return self.post('/orders/' + str(order[uid_type]) + '/edit') 260 | 261 | def packs(self, filters=None, limit=20, page=1): 262 | """ 263 | :param filters: object 264 | :param limit: integer 265 | :param page: integer 266 | :return: Response 267 | """ 268 | self.parameters['filter'] = filters 269 | self.parameters['limit'] = limit 270 | self.parameters['page'] = page 271 | 272 | return self.get('/orders/packs') 273 | 274 | def pack_create(self, pack): 275 | """ 276 | :param pack: object 277 | :return: Response 278 | """ 279 | self.parameters['pack'] = json.dumps(pack) 280 | 281 | return self.post('/orders/packs/create') 282 | 283 | def packs_history(self, filters=None, limit=20, page=1): 284 | """ 285 | :param filters: object 286 | :param limit: integer 287 | :param page: integer 288 | :return: Response 289 | """ 290 | self.parameters['filter'] = filters 291 | self.parameters['limit'] = limit 292 | self.parameters['page'] = page 293 | 294 | return self.get('/orders/packs/history') 295 | 296 | def pack(self, uid): 297 | """ 298 | :param uid: integer 299 | :return: Response 300 | """ 301 | 302 | return self.get('/orders/packs/' + str(uid)) 303 | 304 | def pack_delete(self, uid): 305 | """ 306 | :param uid: integer 307 | :return: Response 308 | """ 309 | 310 | return self.post('/orders/packs/' + str(uid) + '/delete') 311 | 312 | def pack_edit(self, pack): 313 | """ 314 | :param pack: object 315 | :return: Response 316 | """ 317 | self.parameters['pack'] = json.dumps(pack) 318 | 319 | return self.post('/orders/packs/' + str(pack['id']) + '/edit') 320 | 321 | def countries(self): 322 | """ 323 | :return: Response 324 | """ 325 | 326 | return self.get('/reference/countries') 327 | 328 | def delivery_services(self): 329 | """ 330 | :return: Response 331 | """ 332 | 333 | return self.get('/reference/delivery-services') 334 | 335 | def delivery_services_edit(self, delivery_service): 336 | """ 337 | :param delivery_service: object 338 | :return: Response 339 | """ 340 | self.parameters['deliveryService'] = json.dumps(delivery_service) 341 | 342 | return self.post('/reference/delivery-services/' + delivery_service['code'] + '/edit') 343 | 344 | def delivery_types(self): 345 | """ 346 | :return: Response 347 | """ 348 | 349 | return self.get('/reference/delivery-types') 350 | 351 | def delivery_types_edit(self, delivery_type): 352 | """ 353 | :param delivery_type: object 354 | :return: Response 355 | """ 356 | self.parameters['deliveryType'] = json.dumps(delivery_type) 357 | 358 | return self.post('/reference/delivery-types/' + delivery_type['code'] + '/edit') 359 | 360 | def order_methods(self): 361 | """ 362 | :return: Response 363 | """ 364 | 365 | return self.get('/reference/order-methods') 366 | 367 | def order_methods_edit(self, order_method): 368 | """ 369 | 370 | :param order_method: object 371 | :return: Response 372 | """ 373 | self.parameters['orderMethod'] = json.dumps(order_method) 374 | 375 | return self.post('/reference/order-methods/' + order_method['code'] + '/edit') 376 | 377 | def order_types(self): 378 | """ 379 | :return: Response 380 | """ 381 | 382 | return self.get('/reference/order-types') 383 | 384 | def order_types_edit(self, order_type): 385 | """ 386 | :param order_type: object 387 | :return: Response 388 | """ 389 | self.parameters['orderType'] = json.dumps(order_type) 390 | 391 | return self.post('/reference/order-types/' + order_type['code'] + '/edit') 392 | 393 | def payment_statuses(self): 394 | """ 395 | :return: Response 396 | """ 397 | 398 | return self.get('/reference/payment-statuses') 399 | 400 | def payment_statuses_edit(self, payment_status): 401 | """ 402 | :param payment_status: object 403 | :return: Response 404 | """ 405 | self.parameters['paymentStatus'] = json.dumps(payment_status) 406 | 407 | return self.post('/reference/payment-statuses/' + payment_status['code'] + '/edit') 408 | 409 | def payment_types(self): 410 | """ 411 | :return: Response 412 | """ 413 | 414 | return self.get('/reference/payment-types') 415 | 416 | def payment_types_edit(self, payment_type): 417 | """ 418 | :param payment_type: 419 | :return: Response 420 | """ 421 | self.parameters['paymentType'] = json.dumps(payment_type) 422 | 423 | return self.post('/reference/payment-types/' + payment_type['code'] + '/edit') 424 | 425 | def price_types(self): 426 | """ 427 | :return: Response 428 | """ 429 | 430 | return self.get('/reference/price-types') 431 | 432 | def price_types_edit(self, price_type): 433 | """ 434 | :param price_type: object 435 | :return: Response 436 | """ 437 | self.parameters['priceType'] = json.dumps(price_type) 438 | 439 | return self.post('/reference/price-types/' + price_type['code'] + '/edit') 440 | 441 | def product_statuses(self): 442 | """ 443 | :return: Response 444 | """ 445 | 446 | return self.get('/reference/product-statuses') 447 | 448 | def product_statuses_edit(self, product_status): 449 | """ 450 | :param product_status: object 451 | :return: Response 452 | """ 453 | self.parameters['productStatus'] = json.dumps(product_status) 454 | 455 | return self.post('/reference/product-statuses/' + product_status['code'] + '/edit') 456 | 457 | def sites(self): 458 | """ 459 | :return: Response 460 | """ 461 | 462 | return self.get('/reference/sites') 463 | 464 | def sites_edit(self, site): 465 | """ 466 | :param site: object 467 | :return: Response 468 | """ 469 | self.parameters['site'] = json.dumps(site) 470 | 471 | return self.post('/reference/sites/' + site['code'] + '/edit') 472 | 473 | def status_groups(self): 474 | """ 475 | :return 476 | """ 477 | 478 | return self.get('/reference/status-groups') 479 | 480 | def statuses(self): 481 | """ 482 | :return: Response 483 | """ 484 | 485 | return self.get('/reference/statuses') 486 | 487 | def statuses_edit(self, status): 488 | """ 489 | :param status: object 490 | :return: Response 491 | """ 492 | self.parameters['status'] = json.dumps(status) 493 | 494 | return self.post('/reference/statuses/' + status['code'] + '/edit') 495 | 496 | def stores(self): 497 | """ 498 | :return: Response 499 | """ 500 | 501 | return self.get('/reference/stores') 502 | 503 | def stores_edit(self, store): 504 | """ 505 | :param store: object 506 | :return: Response 507 | """ 508 | self.parameters['store'] = json.dumps(store) 509 | 510 | return self.post('/reference/stores/' + store['code'] + '/edit') 511 | 512 | def inventories(self, filters=None, limit=20, page=1): 513 | """ 514 | :param filters: object 515 | :param limit: integer 516 | :param page: integer 517 | :return: Response 518 | """ 519 | self.parameters['filter'] = filters 520 | self.parameters['limit'] = limit 521 | self.parameters['page'] = page 522 | 523 | return self.get('/store/inventories') 524 | 525 | def inventories_upload(self, offers, site=None): 526 | """ 527 | :param offers: array of objects 528 | :param site: string 529 | :return: Response 530 | """ 531 | if site is not None: 532 | self.parameters['site'] = site 533 | 534 | self.parameters['offers'] = json.dumps(offers) 535 | 536 | return self.post('/store/inventories/upload') 537 | 538 | def prices_upload(self, prices): 539 | """ 540 | :param prices: array of objects 541 | :return: Response 542 | """ 543 | self.parameters['prices'] = json.dumps(prices) 544 | 545 | return self.post('/store/prices/upload') 546 | 547 | def products(self, filters=None, limit=20, page=1): 548 | """ 549 | :param filters: object 550 | :param limit: integer 551 | :param page: integer 552 | :return: Response 553 | """ 554 | self.parameters['filter'] = filters 555 | self.parameters['limit'] = limit 556 | self.parameters['page'] = page 557 | 558 | return self.get('/store/products') 559 | 560 | def store_setting(self, code): 561 | """ 562 | :param code: string 563 | :return: Response 564 | """ 565 | 566 | return self.get('/store/setting/' + str(code)) 567 | 568 | def store_setting_edit(self, configuration): 569 | """ 570 | :param configuration: object 571 | :return: Response 572 | """ 573 | self.parameters['configuration'] = json.dumps(configuration) 574 | 575 | return self.post('/store/setting/' + str(configuration['code']) + '/edit') 576 | 577 | def telephony_call_event(self, event): 578 | """ 579 | :param event: object 580 | :return: Response 581 | """ 582 | self.parameters['event'] = json.dumps(event) 583 | 584 | return self.post('/telephony/call/event') 585 | 586 | def telephony_calls_upload(self, calls): 587 | """ 588 | :param calls: array of objects 589 | :return: Response 590 | """ 591 | self.parameters['calls'] = json.dumps(calls) 592 | 593 | return self.post('/telephony/calls/upload') 594 | 595 | def telephony_manager(self, phone, details=True, ignore_status=False): 596 | """ 597 | :param phone: string 598 | :param details: string 599 | :param ignore_status: string 600 | :return: Response 601 | """ 602 | self.parameters['phone'] = phone 603 | self.parameters['details'] = details 604 | self.parameters['ignoreStatus'] = ignore_status 605 | 606 | return self.get('/telephony/manager') 607 | 608 | def telephony_setting(self, code): 609 | """ 610 | :param code: string 611 | :return: Response 612 | """ 613 | 614 | return self.get('/telephony/setting/' + str(code)) 615 | 616 | def telephony_setting_edit(self, configuration): 617 | """ 618 | :param configuration: object 619 | :return: Response 620 | """ 621 | self.parameters['configuration'] = json.dumps(configuration) 622 | 623 | return self.post('/telephony/setting/' + str(configuration['code']) + '/edit') 624 | 625 | def user_groups(self, limit=20, page=1): 626 | """ 627 | :param limit: integer 628 | :param page: integer 629 | :return: Response 630 | """ 631 | self.parameters['limit'] = limit 632 | self.parameters['page'] = page 633 | 634 | return self.get('/user-groups') 635 | 636 | def users(self, filters=None, limit=20, page=1): 637 | """ 638 | :param filters: object 639 | :param limit: integer 640 | :param page: integer 641 | :return: Response 642 | """ 643 | self.parameters['filter'] = filters 644 | self.parameters['limit'] = limit 645 | self.parameters['page'] = page 646 | 647 | return self.get('/users') 648 | 649 | def user(self, uid): 650 | """ 651 | :param uid: integer 652 | :return: Response 653 | """ 654 | 655 | return self.get('/users/' + str(uid)) 656 | 657 | def statistic_update(self): 658 | """ 659 | :return: Response 660 | """ 661 | 662 | return self.get('/statistic/update') 663 | -------------------------------------------------------------------------------- /retailcrm/versions/v5.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | API Client version 5 5 | """ 6 | 7 | import json 8 | 9 | from retailcrm.versions.base import Base 10 | 11 | 12 | class Client(Base): 13 | """RetailCRM API client""" 14 | 15 | apiVersion = 'v5' 16 | 17 | def __init__(self, crm_url, api_key): 18 | Base.__init__(self, crm_url, api_key, self.apiVersion) 19 | 20 | def costs(self, filters=None, limit=20, page=1): 21 | """ 22 | :param filters: object 23 | :param limit: integer 24 | :param page: integer 25 | :return: Response 26 | """ 27 | self.parameters['filter'] = filters 28 | self.parameters['limit'] = limit 29 | self.parameters['page'] = page 30 | 31 | return self.get('/costs') 32 | 33 | def cost_create(self, cost, site=None): 34 | """ 35 | :param cost: object 36 | :param site: string 37 | :return: Response 38 | """ 39 | self.parameters['cost'] = json.dumps(cost) 40 | 41 | if site is not None: 42 | self.parameters['site'] = site 43 | 44 | return self.post('/costs/create') 45 | 46 | def costs_delete(self, ids): 47 | """ 48 | :param ids: array of integers 49 | :return: Response 50 | """ 51 | self.parameters['ids'] = json.dumps(ids) 52 | 53 | return self.post('/costs/delete') 54 | 55 | def costs_upload(self, costs): 56 | """ 57 | :param costs: array of objects 58 | :return: Response 59 | """ 60 | self.parameters['costs'] = json.dumps(costs) 61 | 62 | return self.post('/costs/upload') 63 | 64 | def cost(self, uid): 65 | """ 66 | :param uid: string 67 | :return: Response 68 | """ 69 | 70 | return self.get('/costs/' + str(uid)) 71 | 72 | def cost_delete(self, uid): 73 | """ 74 | :param uid: string 75 | :return: Response 76 | """ 77 | 78 | return self.post('/costs/' + str(uid) + '/delete') 79 | 80 | def cost_edit(self, cost, site=None): 81 | """ 82 | :param cost: object 83 | :param site: string 84 | :return: Response 85 | """ 86 | self.parameters['cost'] = json.dumps(cost) 87 | 88 | if site is not None: 89 | self.parameters['site'] = site 90 | 91 | return self.post('/costs/' + str(cost['id']) + '/edit') 92 | 93 | def custom_fields(self, filters=None, limit=20, page=1): 94 | """ 95 | :param filters: object 96 | :param limit: integer 97 | :param page: integer 98 | :return: Response 99 | """ 100 | self.parameters['filter'] = filters 101 | self.parameters['limit'] = limit 102 | self.parameters['page'] = page 103 | 104 | return self.get('/custom-fields') 105 | 106 | def custom_dictionaries(self, filters=None, limit=20, page=1): 107 | """ 108 | :param filters: object 109 | :param limit: integer 110 | :param page: integer 111 | :return: Response 112 | """ 113 | self.parameters['filter'] = filters 114 | self.parameters['limit'] = limit 115 | self.parameters['page'] = page 116 | 117 | return self.get('/custom-fields/dictionaries') 118 | 119 | def custom_dictionary_create(self, dictionary): 120 | """ 121 | :param dictionary: object 122 | :return: Response 123 | """ 124 | self.parameters['customDictionary'] = json.dumps(dictionary) 125 | 126 | return self.post('/custom-fields/dictionaries/create') 127 | 128 | def custom_dictionary(self, code): 129 | """ 130 | :param code: string 131 | :return: Response 132 | """ 133 | 134 | return self.get('/custom-fields/dictionaries/' + str(code)) 135 | 136 | def custom_dictionary_edit(self, dictionary): 137 | """ 138 | :param dictionary: object 139 | :return: Response 140 | """ 141 | self.parameters['customDictionary'] = json.dumps(dictionary) 142 | 143 | return self.post('/custom-fields/dictionaries/' + str(dictionary['code']) + '/edit') 144 | 145 | def custom_field_create(self, field): 146 | """ 147 | :param field: object 148 | :return: Response 149 | """ 150 | self.parameters['customField'] = json.dumps(field) 151 | 152 | return self.post('/custom-fields/' + str(field['entity']) + '/create') 153 | 154 | def custom_field(self, code, entity): 155 | """ 156 | :param code: string 157 | :param entity: string 158 | :return: Response 159 | """ 160 | 161 | return self.get('/custom-fields/' + str(entity) + '/' + str(code)) 162 | 163 | def custom_field_edit(self, field): 164 | """ 165 | :param field: object 166 | :return: Response 167 | """ 168 | 169 | entity = str(field['entity']) 170 | code = str(field['code']) 171 | self.parameters['customField'] = json.dumps(field) 172 | 173 | return self.post('/custom-fields/' + entity + '/' + code + '/edit') 174 | 175 | def customers(self, filters=None, limit=20, page=1): 176 | """ 177 | :param filters: object 178 | :param limit: integer 179 | :param page: integer 180 | :return: Response 181 | """ 182 | self.parameters['filter'] = filters 183 | self.parameters['limit'] = limit 184 | self.parameters['page'] = page 185 | 186 | return self.get('/customers') 187 | 188 | def customers_combine(self, customers, result): 189 | """ 190 | :param customers: array of object 191 | :param result: object 192 | :return: Response 193 | """ 194 | self.parameters['customers'] = json.dumps(customers) 195 | self.parameters['resultCustomer'] = json.dumps(result) 196 | 197 | return self.post('/customers/combine') 198 | 199 | def customer_create(self, customer, site=None): 200 | """ 201 | :param customer: object 202 | :param site: string 203 | :return: Response 204 | """ 205 | self.parameters['customer'] = json.dumps(customer) 206 | 207 | if site is not None: 208 | self.parameters['site'] = site 209 | 210 | return self.post('/customers/create') 211 | 212 | def customers_fix_external_ids(self, customers, site=None): 213 | """ 214 | :param customers: array of objects 215 | :param site: string 216 | :return: Response 217 | """ 218 | self.parameters['customers'] = json.dumps(customers) 219 | 220 | if site is not None: 221 | self.parameters['site'] = site 222 | 223 | return self.post('/customers/fix-external-ids') 224 | 225 | def customers_history(self, filters=None, limit=20, page=1): 226 | """ 227 | :param filters: object 228 | :param limit: integer 229 | :param page: integer 230 | :return: Response 231 | """ 232 | self.parameters['filter'] = filters 233 | self.parameters['limit'] = limit 234 | self.parameters['page'] = page 235 | 236 | return self.get('/customers/history') 237 | 238 | def customer_notes(self, filters=None, limit=20, page=1): 239 | """ 240 | :param filters: object 241 | :param limit: integer 242 | :param page: integer 243 | :return: Response 244 | """ 245 | self.parameters['filter'] = filters 246 | self.parameters['limit'] = limit 247 | self.parameters['page'] = page 248 | 249 | return self.get('/customers/notes') 250 | 251 | def customer_note_create(self, note, site=None): 252 | """ 253 | :param note: object 254 | :param site: string 255 | :return: Response 256 | """ 257 | self.parameters['note'] = json.dumps(note) 258 | 259 | if site is not None: 260 | self.parameters['site'] = site 261 | 262 | return self.post('/customers/notes/create') 263 | 264 | def customer_note_delete(self, uid): 265 | """ 266 | :param uid: integer 267 | :return: Response 268 | """ 269 | 270 | return self.post('/customers/notes/' + str(uid) + '/delete') 271 | 272 | def customers_upload(self, customers, site=None): 273 | """ 274 | :param customers: array of objects 275 | :param site: string 276 | :return: Response 277 | """ 278 | self.parameters['customers'] = json.dumps(customers) 279 | 280 | if site is not None: 281 | self.parameters['site'] = site 282 | 283 | return self.post('/customers/upload') 284 | 285 | def customer(self, uid, uid_type='externalId', site=None): 286 | """ 287 | :param uid: string 288 | :param uid_type: string 289 | :param site: string 290 | :return: Response 291 | """ 292 | if uid_type != 'externalId': 293 | self.parameters['by'] = uid_type 294 | 295 | if site is not None: 296 | self.parameters['site'] = site 297 | 298 | return self.get('/customers/' + str(uid)) 299 | 300 | def customer_edit(self, customer, uid_type='externalId', site=None): 301 | """ 302 | :param customer: object 303 | :param uid_type: string 304 | :param site: string 305 | :return: Response 306 | """ 307 | self.parameters['customer'] = json.dumps(customer) 308 | 309 | if uid_type != 'externalId': 310 | self.parameters['by'] = uid_type 311 | 312 | if site is not None: 313 | self.parameters['site'] = site 314 | 315 | return self.post('/customers/' + str(customer[uid_type]) + '/edit') 316 | 317 | def customers_corporate(self, filters=None, limit=20, page=1): 318 | """ 319 | :param filters: object 320 | :param limit: integer 321 | :param page: integer 322 | :return: Response 323 | """ 324 | self.parameters['filter'] = filters 325 | self.parameters['limit'] = limit 326 | self.parameters['page'] = page 327 | 328 | return self.get('/customers-corporate') 329 | 330 | def customers_combine_corporate(self, customers, result): 331 | """ 332 | :param customers: array of object 333 | :param result: object 334 | :return: Response 335 | """ 336 | self.parameters['customers'] = json.dumps(customers) 337 | self.parameters['resultCustomer'] = json.dumps(result) 338 | 339 | return self.post('/customers-corporate/combine') 340 | 341 | def customer_corporate_create(self, customer_corporate, site=None): 342 | """ 343 | :param customer_corporate: object 344 | :param site: string 345 | :return: Response 346 | """ 347 | self.parameters['customerCorporate'] = json.dumps(customer_corporate) 348 | 349 | if site is not None: 350 | self.parameters['site'] = site 351 | 352 | return self.post('/customers-corporate/create') 353 | 354 | def customers_corporate_fix_external_ids(self, customers_corporate, site=None): 355 | """ 356 | :param customers_corporate: array of objects 357 | :param site: string 358 | :return: Response 359 | """ 360 | self.parameters['customersCorporate'] = json.dumps(customers_corporate) 361 | 362 | if site is not None: 363 | self.parameters['site'] = site 364 | 365 | return self.post('/customers-corporate/fix-external-ids') 366 | 367 | def customers_corporate_history(self, filters=None, limit=20, page=1): 368 | """ 369 | :param filters: object 370 | :param limit: integer 371 | :param page: integer 372 | :return: Response 373 | """ 374 | self.parameters['filter'] = filters 375 | self.parameters['limit'] = limit 376 | self.parameters['page'] = page 377 | 378 | return self.get('/customers-corporate/history') 379 | 380 | def customer_corporate_notes(self, filters=None, limit=20, page=1): 381 | """ 382 | :param filters: object 383 | :param limit: integer 384 | :param page: integer 385 | :return: Response 386 | """ 387 | self.parameters['filter'] = filters 388 | self.parameters['limit'] = limit 389 | self.parameters['page'] = page 390 | 391 | return self.get('/customers-corporate/notes') 392 | 393 | def customer_corporate_note_create(self, note, site=None): 394 | """ 395 | :param note: object 396 | :param site: string 397 | :return: Response 398 | """ 399 | self.parameters['note'] = json.dumps(note) 400 | 401 | if site is not None: 402 | self.parameters['site'] = site 403 | 404 | return self.post('/customers-corporate/notes/create') 405 | 406 | def customer_corporate_note_delete(self, uid): 407 | """ 408 | :param uid: integer 409 | :return: Response 410 | """ 411 | 412 | return self.post('/customers-corporate/notes/' + str(uid) + '/delete') 413 | 414 | def customers_corporate_upload(self, customers_corporate, site=None): 415 | """ 416 | :param customers_corporate: array of objects 417 | :param site: string 418 | :return: Response 419 | """ 420 | self.parameters['customersCorporate'] = json.dumps(customers_corporate) 421 | 422 | if site is not None: 423 | self.parameters['site'] = site 424 | 425 | return self.post('/customers-corporate/upload') 426 | 427 | def customer_corporate(self, uid, uid_type='externalId', site=None): 428 | """ 429 | :param uid: string 430 | :param uid_type: string 431 | :param site: string 432 | :return: Response 433 | """ 434 | if uid_type != 'externalId': 435 | self.parameters['by'] = uid_type 436 | 437 | if site is not None: 438 | self.parameters['site'] = site 439 | 440 | return self.get('/customers-corporate/' + str(uid)) 441 | 442 | def customer_corporate_addresses(self, uid, uid_type='externalId', limit=20, page=1, filters=None, site=None): 443 | """ 444 | :param filters: object 445 | :param uid: string 446 | :param uid_type: string 447 | :param site: string 448 | :param limit: integer 449 | :param page: integer 450 | :return: Response 451 | """ 452 | 453 | if uid_type != 'externalId': 454 | self.parameters['by'] = uid_type 455 | 456 | if site is not None: 457 | self.parameters['site'] = site 458 | 459 | self.parameters['filter'] = filters 460 | self.parameters['limit'] = limit 461 | self.parameters['page'] = page 462 | 463 | return self.get('/customers-corporate/' + str(uid) + '/addresses') 464 | 465 | def customer_corporate_addresses_create(self, address, uid_type='externalId', site=None): 466 | """ 467 | :param address: object 468 | :param uid_type: string 469 | :param site: string 470 | :return: Response 471 | """ 472 | self.parameters['address'] = json.dumps(address) 473 | 474 | if uid_type != 'externalId': 475 | self.parameters['by'] = uid_type 476 | 477 | if site is not None: 478 | self.parameters['site'] = site 479 | 480 | return self.post('/customers-corporate/' + str(address[uid_type]) + '/addresses/create') 481 | 482 | def customer_corporate_addresses_edit(self, 483 | uid_corporate, 484 | address, 485 | uid_type='externalId', 486 | entity_by='externalId', 487 | site=None): 488 | """ 489 | :param address: object 490 | :param uid_corporate: string 491 | :param uid_type: string 492 | :param entity_by: string 493 | :param site: string 494 | :return: Response 495 | """ 496 | self.parameters['address'] = json.dumps(address) 497 | 498 | if uid_type != 'externalId': 499 | self.parameters['by'] = uid_type 500 | 501 | if entity_by != 'externalId': 502 | self.parameters['entityBy'] = entity_by 503 | 504 | if site is not None: 505 | self.parameters['site'] = site 506 | 507 | return self.post("".join( 508 | [ 509 | '/customers-corporate/', 510 | str(uid_corporate), 511 | '/addresses/', 512 | str(address[entity_by]), 513 | '/edit' 514 | ] 515 | )) 516 | 517 | def customer_corporate_companies(self, uid, uid_type='externalId', limit=20, page=1, filters=None, site=None): 518 | """ 519 | :param filters: object 520 | :param uid: string 521 | :param uid_type: string 522 | :param site: string 523 | :param limit: integer 524 | :param page: integer 525 | :return: Response 526 | """ 527 | 528 | if uid_type != 'externalId': 529 | self.parameters['by'] = uid_type 530 | 531 | if site is not None: 532 | self.parameters['site'] = site 533 | 534 | self.parameters['filter'] = filters 535 | self.parameters['limit'] = limit 536 | self.parameters['page'] = page 537 | 538 | return self.get('/customers-corporate/' + str(uid) + '/companies') 539 | 540 | def customer_corporate_companies_create(self, company, uid_type='externalId', site=None): 541 | """ 542 | :param company: object 543 | :param uid_type: string 544 | :param site: string 545 | :return: Response 546 | """ 547 | self.parameters['company'] = json.dumps(company) 548 | 549 | if uid_type != 'externalId': 550 | self.parameters['by'] = uid_type 551 | 552 | if site is not None: 553 | self.parameters['site'] = site 554 | 555 | return self.post('/customers-corporate/' + str(company[uid_type]) + '/companies/create') 556 | 557 | def customer_corporate_companies_edit(self, 558 | uid_corporate, 559 | company, 560 | uid_type='externalId', 561 | entity_by='externalId', 562 | site=None): 563 | """ 564 | :param company: object 565 | :param uid_corporate: string 566 | :param uid_type: string 567 | :param entity_by: string 568 | :param site: string 569 | :return: Response 570 | """ 571 | self.parameters['company'] = json.dumps(company) 572 | 573 | if uid_type != 'externalId': 574 | self.parameters['by'] = uid_type 575 | 576 | if entity_by != 'externalId': 577 | self.parameters['entityBy'] = entity_by 578 | 579 | if site is not None: 580 | self.parameters['site'] = site 581 | 582 | return self.post('/customers-corporate/' + str(uid_corporate) + '/companies/' + str(company[entity_by]) + '/edit') 583 | 584 | def customer_corporate_contacts(self, uid, uid_type='externalId', limit=20, page=1, filters=None, site=None): 585 | """ 586 | :param filters: object 587 | :param uid: string 588 | :param uid_type: string 589 | :param site: string 590 | :param limit: integer 591 | :param page: integer 592 | :return: Response 593 | """ 594 | 595 | if uid_type != 'externalId': 596 | self.parameters['by'] = uid_type 597 | 598 | if site is not None: 599 | self.parameters['site'] = site 600 | 601 | self.parameters['filter'] = filters 602 | self.parameters['limit'] = limit 603 | self.parameters['page'] = page 604 | 605 | return self.get('/customers-corporate/' + str(uid) + '/contacts') 606 | 607 | def customer_corporate_contacts_create(self, contact, uid_type='externalId', site=None): 608 | """ 609 | :param contact: object 610 | :param uid_type: string 611 | :param site: string 612 | :return: Response 613 | """ 614 | self.parameters['contact'] = json.dumps(contact) 615 | 616 | if uid_type != 'externalId': 617 | self.parameters['by'] = uid_type 618 | 619 | if site is not None: 620 | self.parameters['site'] = site 621 | 622 | return self.post('/customers-corporate/' + str(contact[uid_type]) + '/contacts/create') 623 | 624 | def customer_corporate_contacts_edit(self, 625 | uid_corporate, 626 | contact, 627 | uid_type='externalId', 628 | entity_by='externalId', 629 | site=None): 630 | """ 631 | :param contact: object 632 | :param uid_corporate: string 633 | :param uid_type: string 634 | :param entity_by: string 635 | :param site: string 636 | :return: Response 637 | """ 638 | self.parameters['contact'] = json.dumps(contact) 639 | 640 | if uid_type != 'externalId': 641 | self.parameters['by'] = uid_type 642 | 643 | if entity_by != 'externalId': 644 | self.parameters['entityBy'] = entity_by 645 | 646 | if site is not None: 647 | self.parameters['site'] = site 648 | 649 | return self.post('/customers-corporate/' + str(uid_corporate) + '/contacts/' + str(contact[entity_by]) + '/edit') 650 | 651 | def customer_corporate_edit(self, customer_corporate, uid_type='externalId', site=None): 652 | """ 653 | :param customer_corporate: object 654 | :param uid_type: string 655 | :param site: string 656 | :return: Response 657 | """ 658 | self.parameters['customersCorporate'] = json.dumps(customer_corporate) 659 | 660 | if uid_type != 'externalId': 661 | self.parameters['by'] = uid_type 662 | 663 | if site is not None: 664 | self.parameters['site'] = site 665 | 666 | return self.post('/customers-corporate/' + str(customer_corporate[uid_type]) + '/edit') 667 | 668 | def delivery_tracking(self, code, status_update): 669 | """ 670 | :param code: string 671 | :param status_update: array of objects 672 | :return: Response 673 | """ 674 | self.parameters['statusUpdate'] = json.dumps(status_update) 675 | 676 | return self.post('/delivery/generic/' + str(code) + '/tracking') 677 | 678 | def delivery_shipments(self, filters=None, limit=20, page=1): 679 | """ 680 | :param filters: object 681 | :param limit: integer 682 | :param page: integer 683 | :return: Response 684 | """ 685 | self.parameters['filter'] = filters 686 | self.parameters['limit'] = limit 687 | self.parameters['page'] = page 688 | 689 | return self.get('/delivery/shipments') 690 | 691 | def delivery_shipment_create(self, shipment, site=None): 692 | """ 693 | :param shipment: object 694 | :param site: string 695 | :return: Response 696 | """ 697 | self.parameters['deliveryShipment'] = json.dumps(shipment) 698 | 699 | if site is not None: 700 | self.parameters['site'] = site 701 | 702 | return self.post('/delivery/shipments/create') 703 | 704 | def delivery_shipment(self, uid): 705 | """ 706 | :param uid: string 707 | :return: Response 708 | """ 709 | 710 | return self.get('/delivery/shipments/' + str(uid)) 711 | 712 | def delivery_shipment_edit(self, shipment, site=None): 713 | """ 714 | :param shipment: object 715 | :param site: string 716 | :return: Response 717 | """ 718 | self.parameters['deliveryShipment'] = json.dumps(shipment) 719 | 720 | if site is not None: 721 | self.parameters['site'] = site 722 | 723 | return self.post('/delivery/shipment/' + str(shipment['id']) + '/edit') 724 | 725 | def files(self, filters=None, limit=20, page=1): 726 | """ 727 | :param filters: object 728 | :param limit: integer 729 | :param page: integer 730 | :return: Response 731 | """ 732 | self.parameters['filter'] = filters 733 | self.parameters['limit'] = limit 734 | self.parameters['page'] = page 735 | 736 | return self.get('/files') 737 | 738 | def files_upload(self, file, site=None): 739 | """ 740 | :param file: objects 741 | :param site: string 742 | :return: Response 743 | """ 744 | 745 | self.parameters['file'] = json.dumps(file) 746 | 747 | if site is not None: 748 | self.parameters['site'] = site 749 | 750 | return self.post('/files/upload') 751 | 752 | def file(self, uid): 753 | """ 754 | :param uid: integer 755 | :return: Response 756 | """ 757 | return self.get('/files/' + str(uid)) 758 | 759 | def files_delete(self, uid): 760 | """ 761 | :param uid: integer 762 | :return: Response 763 | """ 764 | 765 | return self.post('/files/' + str(uid) + '/delete') 766 | 767 | def files_download(self, uid): 768 | """ 769 | :param uid: integer 770 | :return: Response 771 | """ 772 | 773 | return self.get('/files/' + str(uid) + '/download') 774 | 775 | def files_edit(self, file): 776 | """ 777 | :param file: object 778 | :return: Response 779 | """ 780 | self.parameters['file'] = json.dumps(file) 781 | 782 | return self.post('/files/' + str(file['id']) + '/edit') 783 | 784 | def integration_module(self, code): 785 | """ 786 | :param code: integer 787 | :return: Response 788 | """ 789 | 790 | return self.get('/integration-modules/' + str(code)) 791 | 792 | def integration_module_edit(self, configuration): 793 | """ 794 | :param configuration: object 795 | :return: Response 796 | """ 797 | self.parameters['integrationModule'] = json.dumps(configuration) 798 | 799 | return self.post('/integration-modules/' + str(configuration['code']) + '/edit') 800 | 801 | def orders(self, filters=None, limit=20, page=1): 802 | """ 803 | :param filters: object 804 | :param limit: integer 805 | :param page: integer 806 | :return: Response 807 | """ 808 | self.parameters['filter'] = filters 809 | self.parameters['limit'] = limit 810 | self.parameters['page'] = page 811 | 812 | return self.get('/orders') 813 | 814 | def orders_combine(self, order, result_order, technique='ours'): 815 | """ 816 | :param order: object 817 | :param result_order: object 818 | :param technique: string 819 | :return: Response 820 | """ 821 | self.parameters['technique'] = technique 822 | self.parameters['order'] = json.dumps(order) 823 | self.parameters['resultOrder'] = json.dumps(result_order) 824 | 825 | return self.post('/orders/combine') 826 | 827 | def order_create(self, order, site=None): 828 | """ 829 | :param order: object 830 | :param site: string 831 | :return: Response 832 | """ 833 | self.parameters['order'] = json.dumps(order) 834 | 835 | if site is not None: 836 | self.parameters['site'] = site 837 | 838 | return self.post('/orders/create') 839 | 840 | def orders_fix_external_ids(self, orders, site=None): 841 | """ 842 | :param orders: object 843 | :param site: string 844 | :return: Response 845 | """ 846 | self.parameters['orders'] = json.dumps(orders) 847 | 848 | if site is not None: 849 | self.parameters['site'] = site 850 | 851 | return self.post('/orders/fix-external-ids') 852 | 853 | def orders_history(self, filters=None, limit=20, page=1): 854 | """ 855 | :param filters: object 856 | :param limit: integer 857 | :param page: integer 858 | :return: Response 859 | """ 860 | self.parameters['filter'] = filters 861 | self.parameters['limit'] = limit 862 | self.parameters['page'] = page 863 | 864 | return self.get('/orders/history') 865 | 866 | def order_links_create(self, link, site=None): 867 | """ 868 | :param link: object 869 | :param site: string 870 | :return: Response 871 | """ 872 | self.parameters['link'] = json.dumps(link) 873 | 874 | if site is not None: 875 | self.parameters['site'] = site 876 | 877 | return self.post('/orders/links/create') 878 | 879 | def order_payment_create(self, payment, site=None): 880 | """ 881 | :param payment: object 882 | :param site: string 883 | :return: Response 884 | """ 885 | self.parameters['payment'] = json.dumps(payment) 886 | 887 | if site is not None: 888 | self.parameters['site'] = site 889 | 890 | return self.post('/orders/payments/create') 891 | 892 | def order_payment_delete(self, uid): 893 | """ 894 | :param uid: string 895 | :return: Response 896 | """ 897 | 898 | return self.post('/orders/payments/' + str(uid) + '/delete') 899 | 900 | def order_payment_edit(self, payment, uid_type='externalId', site=None): 901 | """ 902 | :param payment: object 903 | :param uid_type: string 904 | :param site: string 905 | :return: Response 906 | """ 907 | self.parameters['payment'] = json.dumps(payment) 908 | if uid_type != 'externalId': 909 | self.parameters['by'] = uid_type 910 | if site is not None: 911 | self.parameters['site'] = site 912 | 913 | return self.post('/orders/payments/' + str(payment[uid_type]) + '/edit') 914 | 915 | def orders_statuses(self, ids, external_ids): 916 | """ 917 | :param ids: array 918 | :param external_ids: array 919 | :return: Response 920 | """ 921 | self.parameters['ids'] = ids 922 | self.parameters['externalIds'] = external_ids 923 | 924 | return self.get('/orders/statuses') 925 | 926 | def orders_upload(self, orders, site=None): 927 | """ 928 | :param orders: object 929 | :param site: string 930 | :return: Response 931 | """ 932 | self.parameters['orders'] = json.dumps(orders) 933 | 934 | if site is not None: 935 | self.parameters['site'] = site 936 | 937 | return self.post('/orders/upload') 938 | 939 | def order(self, uid, uid_type='externalId', site=None): 940 | """ 941 | :param uid: string 942 | :param uid_type: string 943 | :param site: string 944 | :return: Response 945 | """ 946 | if site is not None: 947 | self.parameters['site'] = site 948 | 949 | if uid_type != 'externalId': 950 | self.parameters['by'] = uid_type 951 | 952 | return self.get('/orders/' + str(uid)) 953 | 954 | def order_edit(self, order, uid_type='externalId', site=None): 955 | """ 956 | :param order: object 957 | :param uid_type: string 958 | :param site: string 959 | :return: Response 960 | """ 961 | self.parameters['order'] = json.dumps(order) 962 | 963 | if site is not None: 964 | self.parameters['site'] = site 965 | 966 | if uid_type != 'externalId': 967 | self.parameters['by'] = uid_type 968 | 969 | return self.post('/orders/' + str(order[uid_type]) + '/edit') 970 | 971 | def packs(self, filters=None, limit=20, page=1): 972 | """ 973 | :param filters: object 974 | :param limit: integer 975 | :param page: integer 976 | :return: Response 977 | """ 978 | self.parameters['filter'] = filters 979 | self.parameters['limit'] = limit 980 | self.parameters['page'] = page 981 | 982 | return self.get('/orders/packs') 983 | 984 | def pack_create(self, pack): 985 | """ 986 | :param pack: object 987 | :return: Response 988 | """ 989 | self.parameters['pack'] = json.dumps(pack) 990 | 991 | return self.post('/orders/packs/create') 992 | 993 | def packs_history(self, filters=None, limit=20, page=1): 994 | """ 995 | :param filters: object 996 | :param limit: integer 997 | :param page: integer 998 | :return: Response 999 | """ 1000 | self.parameters['filter'] = filters 1001 | self.parameters['limit'] = limit 1002 | self.parameters['page'] = page 1003 | 1004 | return self.get('/orders/packs/history') 1005 | 1006 | def pack(self, uid): 1007 | """ 1008 | :param uid: integer 1009 | :return: Response 1010 | """ 1011 | 1012 | return self.get('/orders/packs/' + str(uid)) 1013 | 1014 | def pack_delete(self, uid): 1015 | """ 1016 | :param uid: integer 1017 | :return: Response 1018 | """ 1019 | 1020 | return self.post('/orders/packs/' + str(uid) + '/delete') 1021 | 1022 | def payment_check(self, check): 1023 | """ 1024 | :param check: object 1025 | :return: Response 1026 | """ 1027 | self.parameters['check'] = json.dumps(check) 1028 | 1029 | return self.post('/payment/check') 1030 | 1031 | def payment_create_invoice(self, create_invoice): 1032 | """ 1033 | :param create_invoice: object 1034 | :return: Response 1035 | """ 1036 | self.parameters['createInvoice'] = json.dumps(create_invoice) 1037 | 1038 | return self.post('/payment/create-invoice') 1039 | 1040 | def payment_update_invoice(self, update_invoice): 1041 | """ 1042 | :param update_invoice: object 1043 | :return: Response 1044 | """ 1045 | self.parameters['updateInvoice'] = json.dumps(update_invoice) 1046 | 1047 | return self.post('/payment/update-invoice') 1048 | 1049 | def pack_edit(self, pack): 1050 | """ 1051 | :param pack: object 1052 | :return: Response 1053 | """ 1054 | self.parameters['pack'] = json.dumps(pack) 1055 | 1056 | return self.post('/orders/packs/' + str(pack['id']) + '/edit') 1057 | 1058 | def cost_groups(self): 1059 | """ 1060 | :return: Response 1061 | """ 1062 | 1063 | return self.get('/reference/cost-groups') 1064 | 1065 | def cost_groups_edit(self, cost_group): 1066 | """ 1067 | :param cost_group: array of objects 1068 | :return: Response 1069 | """ 1070 | self.parameters['costGroup'] = json.dumps(cost_group) 1071 | 1072 | return self.post('/reference/cost-groups/' + cost_group['code'] + '/edit') 1073 | 1074 | def cost_items(self): 1075 | """ 1076 | :return: Response 1077 | """ 1078 | 1079 | return self.get('/reference/cost-items') 1080 | 1081 | def cost_items_edit(self, cost_item): 1082 | """ 1083 | :param cost_item: array of objects 1084 | :return: Response 1085 | """ 1086 | self.parameters['costItem'] = json.dumps(cost_item) 1087 | 1088 | return self.post('/reference/cost-groups/' + cost_item['code'] + '/edit') 1089 | 1090 | def countries(self): 1091 | """ 1092 | :return: Response 1093 | """ 1094 | 1095 | return self.get('/reference/countries') 1096 | 1097 | def couriers(self): 1098 | """ 1099 | :return: Response 1100 | """ 1101 | 1102 | return self.get('/reference/couriers') 1103 | 1104 | def couriers_create(self, courier): 1105 | """ 1106 | :param courier: array of objects 1107 | :return: Response 1108 | """ 1109 | self.parameters['courier'] = json.dumps(courier) 1110 | 1111 | return self.post('/reference/couriers/create') 1112 | 1113 | def couriers_edit(self, courier): 1114 | """ 1115 | :param courier: object 1116 | :return: Response 1117 | """ 1118 | self.parameters['courier'] = json.dumps(courier) 1119 | 1120 | return self.post('/reference/couriers/' + str(courier['id']) + '/edit') 1121 | 1122 | def delivery_services(self): 1123 | """ 1124 | :return: Response 1125 | """ 1126 | 1127 | return self.get('/reference/delivery-services') 1128 | 1129 | def delivery_services_edit(self, delivery_service): 1130 | """ 1131 | :param delivery_service: 1132 | :return: Response 1133 | """ 1134 | self.parameters['deliveryService'] = json.dumps(delivery_service) 1135 | 1136 | return self.post('/reference/delivery-services/' + delivery_service['code'] + '/edit') 1137 | 1138 | def delivery_types(self): 1139 | """ 1140 | :return: Response 1141 | """ 1142 | 1143 | return self.get('/reference/delivery-types') 1144 | 1145 | def delivery_types_edit(self, delivery_type): 1146 | """ 1147 | :param delivery_type: object 1148 | :return: Response 1149 | """ 1150 | self.parameters['deliveryType'] = json.dumps(delivery_type) 1151 | 1152 | return self.post('/reference/delivery-types/' + delivery_type['code'] + '/edit') 1153 | 1154 | def legal_entities(self): 1155 | """ 1156 | :return: Response 1157 | """ 1158 | 1159 | return self.get('/reference/legal-entities') 1160 | 1161 | def legal_entities_edit(self, legal_entity): 1162 | """ 1163 | :param legal_entity: object 1164 | :return: Response 1165 | """ 1166 | self.parameters['legalEntity'] = json.dumps(legal_entity) 1167 | 1168 | return self.post('/reference/legal-entities/' + legal_entity['code'] + '/edit') 1169 | 1170 | def mg_channels(self): 1171 | """ 1172 | :return: Response 1173 | """ 1174 | 1175 | return self.get('/reference/mg-channels') 1176 | 1177 | def order_methods(self): 1178 | """ 1179 | :return: Response 1180 | """ 1181 | 1182 | return self.get('/reference/order-methods') 1183 | 1184 | def order_methods_edit(self, order_method): 1185 | """ 1186 | 1187 | :param order_method: object 1188 | :return: Response 1189 | """ 1190 | self.parameters['orderMethod'] = json.dumps(order_method) 1191 | 1192 | return self.post('/reference/order-methods/' + order_method['code'] + '/edit') 1193 | 1194 | def order_types(self): 1195 | """ 1196 | :return: Response 1197 | """ 1198 | 1199 | return self.get('/reference/order-types') 1200 | 1201 | def order_types_edit(self, order_type): 1202 | """ 1203 | :param order_type: object 1204 | :return: Response 1205 | """ 1206 | self.parameters['orderType'] = json.dumps(order_type) 1207 | 1208 | return self.post('/reference/order-types/' + order_type['code'] + '/edit') 1209 | 1210 | def payment_statuses(self): 1211 | """ 1212 | :return: Response 1213 | """ 1214 | 1215 | return self.get('/reference/payment-statuses') 1216 | 1217 | def payment_statuses_edit(self, payment_status): 1218 | """ 1219 | :param payment_status: object 1220 | :return: Response 1221 | """ 1222 | self.parameters['paymentStatus'] = json.dumps(payment_status) 1223 | 1224 | return self.post('/reference/payment-statuses/' + payment_status['code'] + '/edit') 1225 | 1226 | def payment_types(self): 1227 | """ 1228 | :return: Response 1229 | """ 1230 | 1231 | return self.get('/reference/payment-types') 1232 | 1233 | def payment_types_edit(self, payment_type): 1234 | """ 1235 | :param payment_type: object 1236 | :return: Response 1237 | """ 1238 | self.parameters['paymentType'] = json.dumps(payment_type) 1239 | 1240 | return self.post('/reference/payment-types/' + payment_type['code'] + '/edit') 1241 | 1242 | def price_types(self): 1243 | """ 1244 | :return: Response 1245 | """ 1246 | 1247 | return self.get('/reference/price-types') 1248 | 1249 | def price_types_edit(self, price_type): 1250 | """ 1251 | :param price_type: object 1252 | :return: Response 1253 | """ 1254 | self.parameters['priceTypes'] = json.dumps(price_type) 1255 | 1256 | return self.post('/reference/price-types/' + price_type['code'] + '/edit') 1257 | 1258 | def product_statuses(self): 1259 | """ 1260 | :return: Response 1261 | """ 1262 | 1263 | return self.get('/reference/product-statuses') 1264 | 1265 | def product_statuses_edit(self, product_status): 1266 | """ 1267 | :param product_status: object 1268 | :return: Response 1269 | """ 1270 | self.parameters['productStatus'] = json.dumps(product_status) 1271 | 1272 | return self.post('/reference/product-statuses/' + product_status['code'] + '/edit') 1273 | 1274 | def sites(self): 1275 | """ 1276 | :return: Response 1277 | """ 1278 | 1279 | return self.get('/reference/sites') 1280 | 1281 | def sites_edit(self, site): 1282 | """ 1283 | :param site: object 1284 | :return: Response 1285 | """ 1286 | self.parameters['site'] = json.dumps(site) 1287 | 1288 | return self.post('/reference/sites/' + site['code'] + '/edit') 1289 | 1290 | def status_groups(self): 1291 | """ 1292 | :return Response 1293 | """ 1294 | 1295 | return self.get('/reference/status-groups') 1296 | 1297 | def statuses(self): 1298 | """ 1299 | :return: Response 1300 | """ 1301 | 1302 | return self.get('/reference/statuses') 1303 | 1304 | def statuses_edit(self, status): 1305 | """ 1306 | :param status: object 1307 | :return: Response 1308 | """ 1309 | self.parameters['status'] = json.dumps(status) 1310 | 1311 | return self.post('/reference/statuses/' + status['code'] + '/edit') 1312 | 1313 | def stores(self): 1314 | """ 1315 | :return: Response 1316 | """ 1317 | 1318 | return self.get('/reference/stores') 1319 | 1320 | def stores_edit(self, store): 1321 | """ 1322 | :param store: object 1323 | :return: Response 1324 | """ 1325 | self.parameters['store'] = json.dumps(store) 1326 | 1327 | return self.post('/reference/stores/' + store['code'] + '/edit') 1328 | 1329 | def units(self): 1330 | """ 1331 | :return: Response 1332 | """ 1333 | 1334 | return self.get('/reference/units') 1335 | 1336 | def units_edit(self, units): 1337 | """ 1338 | :param units: object 1339 | :return: Response 1340 | """ 1341 | self.parameters['units'] = json.dumps(units) 1342 | 1343 | return self.post('/reference/units/' + units['code'] + '/edit') 1344 | 1345 | def segments(self, filters=None, limit=20, page=1): 1346 | """ 1347 | :param filters: object 1348 | :param limit: integer 1349 | :param page: integer 1350 | :return: Response 1351 | """ 1352 | self.parameters['filter'] = filters 1353 | self.parameters['limit'] = limit 1354 | self.parameters['page'] = page 1355 | 1356 | return self.get('/segments') 1357 | 1358 | def inventories(self, filters=None, limit=20, page=1): 1359 | """ 1360 | :param filters: object 1361 | :param limit: integer 1362 | :param page: integer 1363 | :return: Response 1364 | """ 1365 | self.parameters['filter'] = filters 1366 | self.parameters['limit'] = limit 1367 | self.parameters['page'] = page 1368 | 1369 | return self.get('/store/inventories') 1370 | 1371 | def inventories_upload(self, offers, site=None): 1372 | """ 1373 | :param offers: array of objects 1374 | :param site: string 1375 | :return: Response 1376 | """ 1377 | if site is not None: 1378 | self.parameters['site'] = site 1379 | 1380 | self.parameters['offers'] = json.dumps(offers) 1381 | 1382 | return self.post('/store/inventories/upload') 1383 | 1384 | def prices_upload(self, prices): 1385 | """ 1386 | :param prices: array of objects 1387 | :return: Response 1388 | """ 1389 | self.parameters['prices'] = json.dumps(prices) 1390 | 1391 | return self.post('/store/prices/upload') 1392 | 1393 | def product_groups(self, filters=None, limit=20, page=1): 1394 | """ 1395 | :param filters: object 1396 | :param limit: integer 1397 | :param page: integer 1398 | :return: Response 1399 | """ 1400 | self.parameters['filter'] = filters 1401 | self.parameters['limit'] = limit 1402 | self.parameters['page'] = page 1403 | 1404 | return self.get('/store/product-groups') 1405 | 1406 | def products(self, filters=None, limit=20, page=1): 1407 | """ 1408 | :param filters: object 1409 | :param limit: integer 1410 | :param page: integer 1411 | :return: Response 1412 | """ 1413 | self.parameters['filter'] = filters 1414 | self.parameters['limit'] = limit 1415 | self.parameters['page'] = page 1416 | 1417 | return self.get('/store/products') 1418 | 1419 | def products_properties(self, filters=None, limit=20, page=1): 1420 | """ 1421 | :param filters: object 1422 | :param limit: integer 1423 | :param page: integer 1424 | :return: Response 1425 | """ 1426 | self.parameters['filter'] = filters 1427 | self.parameters['limit'] = limit 1428 | self.parameters['page'] = page 1429 | 1430 | return self.get('/store/products/properties') 1431 | 1432 | def tasks(self, filters=None, limit=20, page=1): 1433 | """ 1434 | :param filters: object 1435 | :param limit: integer 1436 | :param page: integer 1437 | :return: Response 1438 | """ 1439 | self.parameters['filter'] = filters 1440 | self.parameters['limit'] = limit 1441 | self.parameters['page'] = page 1442 | 1443 | return self.get('/tasks') 1444 | 1445 | def task_create(self, task, site=None): 1446 | """ 1447 | :param task: object 1448 | :param site: string 1449 | :return: Response 1450 | """ 1451 | self.parameters['task'] = json.dumps(task) 1452 | 1453 | if site is not None: 1454 | self.parameters['site'] = site 1455 | 1456 | return self.post('/tasks/create') 1457 | 1458 | def task(self, uid): 1459 | """ 1460 | :param uid: string 1461 | :return: Response 1462 | """ 1463 | 1464 | return self.get('/tasks/' + str(uid)) 1465 | 1466 | def task_edit(self, task, site=None): 1467 | """ 1468 | :param task: object 1469 | :param site: string 1470 | :return: Response 1471 | """ 1472 | self.parameters['task'] = json.dumps(task) 1473 | 1474 | if site is not None: 1475 | self.parameters['site'] = site 1476 | 1477 | return self.post('/tasks/' + str(task['id']) + '/edit') 1478 | 1479 | def telephony_call_event(self, event): 1480 | """ 1481 | :param event: object 1482 | :return: Response 1483 | """ 1484 | self.parameters['event'] = json.dumps(event) 1485 | 1486 | return self.post('/telephony/call/event') 1487 | 1488 | def telephony_calls_upload(self, calls): 1489 | """ 1490 | :param calls: array of objects 1491 | :return: Response 1492 | """ 1493 | self.parameters['calls'] = json.dumps(calls) 1494 | 1495 | return self.post('/telephony/calls/upload') 1496 | 1497 | def telephony_manager(self, phone, details=True, ignore_status=True): 1498 | """ 1499 | :param phone: string 1500 | :param details: string 1501 | :param ignore_status: string 1502 | :return: Response 1503 | """ 1504 | self.parameters['phone'] = phone 1505 | self.parameters['details'] = details 1506 | self.parameters['ignoreStatus'] = ignore_status 1507 | 1508 | return self.get('/telephony/manager') 1509 | 1510 | def user_groups(self, limit=20, page=1): 1511 | """ 1512 | :param limit: integer 1513 | :param page: integer 1514 | :return: Response 1515 | """ 1516 | self.parameters['limit'] = limit 1517 | self.parameters['page'] = page 1518 | 1519 | return self.get('/user-groups') 1520 | 1521 | def users(self, filters=None, limit=20, page=1): 1522 | """ 1523 | :param filters: object 1524 | :param limit: integer 1525 | :param page: integer 1526 | :return: Response 1527 | """ 1528 | self.parameters['filter'] = filters 1529 | self.parameters['limit'] = limit 1530 | self.parameters['page'] = page 1531 | 1532 | return self.get('/users') 1533 | 1534 | def user(self, uid): 1535 | """ 1536 | :param uid: integer 1537 | :return: Response 1538 | """ 1539 | 1540 | return self.get('/users/' + str(uid)) 1541 | 1542 | def user_status(self, uid, status): 1543 | """ 1544 | :param uid: integer 1545 | :param status: string 1546 | :return: Response 1547 | """ 1548 | 1549 | self.parameters['status'] = status 1550 | 1551 | return self.post('/users/' + str(uid) + '/status') 1552 | 1553 | def statistic_update(self): 1554 | """ 1555 | :return: Response 1556 | """ 1557 | 1558 | return self.get('/statistic/update') 1559 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | """ 4 | Setup file 5 | """ 6 | 7 | import os 8 | from setuptools import setup 9 | 10 | 11 | def read(filename): 12 | """Read readme for long description""" 13 | return open(os.path.join(os.path.dirname(__file__), filename)).read() 14 | 15 | 16 | setup( 17 | name='retailcrm', 18 | version='5.1.2', 19 | description='RetailCRM API client', 20 | long_description=read('README'), 21 | url='https://github.com/retailcrm/api-client-python', 22 | author='RetailCRM', 23 | author_email='support@retailcrm.pro', 24 | keywords='crm saas rest e-commerce', 25 | license='MIT', 26 | packages=['retailcrm', 'retailcrm/versions'], 27 | package_data={}, 28 | install_requires=['requests', 'multidimensional_urlencode', 'nose', 'coverage', 'pook', 'setuptools'], 29 | classifiers=[ 30 | 'Development Status :: 5 - Production/Stable', 31 | 'Environment :: Other Environment', 32 | 'Intended Audience :: Developers', 33 | 'License :: OSI Approved :: MIT License', 34 | 'Operating System :: OS Independent', 35 | 'Programming Language :: Python', 36 | 'Programming Language :: Python :: 3', 37 | 'Programming Language :: Python :: 3.8', 38 | 'Programming Language :: Python :: 3.9', 39 | 'Programming Language :: Python :: 3.10', 40 | 'Programming Language :: Python :: 3.11', 41 | 'Programming Language :: Python :: 3.12', 42 | 'Programming Language :: Python :: 3 :: Only', 43 | 'Topic :: Software Development :: Libraries :: Python Modules', 44 | ] 45 | ) 46 | -------------------------------------------------------------------------------- /tests/v3_tests.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | 4 | """ 5 | RetailCRM API client v3 tests 6 | """ 7 | 8 | from urllib.parse import urlencode 9 | import unittest 10 | import os 11 | import retailcrm 12 | import pook 13 | import json 14 | 15 | 16 | class TestVersion3(unittest.TestCase): 17 | """ 18 | TestClass for v3 19 | """ 20 | 21 | __header = {'Server': 'nginx/1.16.0', 'Content-Type': 'application/json; charset=UTF-8'} 22 | 23 | __customer = { 24 | 'id': 9717, 25 | 'externalId': 'c-111111111', 26 | 'createdAt': '2020-04-09 16:55:59', 27 | 'vip': 'false', 28 | 'bad': 'false', 29 | 'site': 'test-org', 30 | 'marginSumm': 28180, 31 | 'totalSumm': 28180, 32 | 'averageSumm': 28180, 33 | 'ordersCount': 1, 34 | 'customFields': [], 35 | 'personalDiscount': 0, 36 | 'address': { 37 | 'id': 5667, 38 | 'text': 'MAY' 39 | }, 40 | 'firstName': 'Аа', 41 | 'lastName': 'Аа', 42 | 'phones': [], 43 | 'contragentType': 'individual' 44 | } 45 | 46 | __order = { 47 | 'slug': 5604, 48 | 'summ': 0, 49 | 'id': 5604, 50 | 'number': '5604A', 51 | 'externalId': '5603', 52 | 'orderType': 's789', 53 | 'orderMethod': 'shopping-cart', 54 | 'countryIso': 'RU', 55 | 'createdAt': '2020-04-07 15:44:24', 56 | 'statusUpdatedAt': '2020-04-07 15:44:24', 57 | 'totalSumm': 0, 58 | 'prepaySum': 0, 59 | 'purchaseSumm': 0, 60 | 'markDatetime': '2020-04-07 15:44:24', 61 | 'call': 'false', 62 | 'expired': 'false', 63 | 'customer': { 64 | 'id': 9711, 65 | 'createdAt': '2020-04-07 15:44:24', 66 | 'vip': 'false', 67 | 'bad': 'false', 68 | 'site': '127-0-0-1-8080', 69 | 'marginSumm': 0, 70 | 'totalSumm': 0, 71 | 'averageSumm': 0, 72 | 'ordersCount': 1, 73 | 'customFields': [], 74 | 'personalDiscount': 0, 75 | 'email': '', 76 | 'phones': [], 77 | 'contragentType': 'individual' 78 | }, 79 | 'contragentType': 'individual', 80 | 'delivery': { 81 | 'cost': 0, 82 | 'netCost': 0, 83 | 'address': {} 84 | }, 85 | 'site': '127-0-0-1-8080', 86 | 'status': 'new', 87 | 'items': [], 88 | 'fromApi': 'true', 89 | 'shipped': 'false', 90 | 'customFields': [] 91 | } 92 | 93 | __pack = { 94 | 'id': 122, 95 | 'purchasePrice': 0, 96 | 'quantity': 1, 97 | 'store': '7777z', 98 | 'item': { 99 | 'id': 7632, 100 | 'order': { 101 | 'id': 5608 102 | }, 103 | 'offer': { 104 | 'externalId': 's789' 105 | } 106 | } 107 | } 108 | 109 | def setUp(self): 110 | """ 111 | Setup 112 | """ 113 | 114 | self.client = retailcrm.v3(os.getenv('RETAILCRM_URL'), os.getenv('RETAILCRM_KEY')) 115 | 116 | @staticmethod 117 | def dictionaryEncode(key, dictionary): 118 | return urlencode({key: json.dumps(dictionary)}) 119 | 120 | @pook.on 121 | def test_wrong_api_url(self): 122 | """ 123 | V3 Test wrong api url 124 | """ 125 | 126 | (pook.get('https://epoqq.retailcrm.pro' + '/api/v3/statistic/update') 127 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 128 | .reply(404) 129 | .headers(self.__header) 130 | .json( 131 | { 132 | 'success': 'true', 133 | 'errorMsg': 'Account does not exist.' 134 | } 135 | ) 136 | ) 137 | 138 | client = retailcrm.v3('https://epoqq.retailcrm.pro', os.getenv('RETAILCRM_KEY')) 139 | response = client.statistic_update() 140 | pook.off() 141 | 142 | self.assertIsNot(response.is_successful(), True) 143 | self.assertEqual(response.get_error_msg(), 'Account does not exist.') 144 | 145 | @pook.on 146 | def test_wrong_api_key(self): 147 | """ 148 | V3 Test wrong api key 149 | """ 150 | 151 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/statistic/update') 152 | .headers({'X-API-KEY': 'XXXX'}) 153 | .reply(200) 154 | .headers(self.__header) 155 | .json({'errorMsg': 'Wrong "apiKey" value.'}) 156 | ) 157 | 158 | client = retailcrm.v3(os.getenv('RETAILCRM_URL'), 'XXXX') 159 | response = client.statistic_update() 160 | pook.off() 161 | 162 | self.assertEqual(response.get_error_msg(), 'Wrong "apiKey" value.') 163 | 164 | @pook.on 165 | def test_missing_api_key(self): 166 | """ 167 | V3 Test missing api key 168 | """ 169 | 170 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/statistic/update') 171 | .reply(200) 172 | .headers(self.__header) 173 | .json({'errorMsg': '"apiKey" is missing.'}) 174 | ) 175 | 176 | client = retailcrm.v3(os.getenv('RETAILCRM_URL'), None) 177 | response = client.statistic_update() 178 | pook.off() 179 | 180 | self.assertEqual(response.get_error_msg(), '"apiKey" is missing.') 181 | 182 | @pook.on 183 | def test_api_versions(self): 184 | """ 185 | V3 Test api-versions method 186 | """ 187 | 188 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/api-versions') 189 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 190 | .reply(200) 191 | .headers(self.__header) 192 | .json({'success': 'true', 'versions': ['3.0', '4.0', '5.0']}) 193 | ) 194 | 195 | response = self.client.api_versions() 196 | pook.off() 197 | 198 | self.assertTrue(response.is_successful(), True) 199 | 200 | @pook.on 201 | def test_api_credentials(self): 202 | """ 203 | V3 Test api-credentials method 204 | """ 205 | 206 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/credentials') 207 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 208 | .reply(200) 209 | .headers(self.__header) 210 | .json({'success': 'true', 'credentials': [], 'siteAccess': 'access_full'}) 211 | ) 212 | 213 | response = self.client.api_credentials() 214 | pook.off() 215 | 216 | self.assertTrue(response.is_successful(), True) 217 | 218 | @pook.on 219 | def test_customers(self): 220 | """ 221 | V3 Test method customers 222 | """ 223 | 224 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/customers') 225 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 226 | .params({'filter[bad]': 'false', 'filter[contragentType]': 'individual'}) 227 | .reply(200) 228 | .headers(self.__header) 229 | .json( 230 | { 231 | 'success': 'true', 232 | 'pagination': { 233 | 'limit': 20, 234 | 'totalCount': 4342, 235 | 'currentPage': 1, 236 | 'totalPageCount': 87 237 | }, 238 | 'customers': [self.__customer] 239 | } 240 | ) 241 | ) 242 | 243 | response = self.client.customers({'bad': 'false', 'contragentType': 'individual'}) 244 | pook.off() 245 | 246 | self.assertTrue(response.is_successful(), True) 247 | self.assertTrue(response.get_status_code() < 400, True) 248 | 249 | @pook.on 250 | def test_customers_create(self): 251 | """ 252 | V3 Test method customers_create 253 | """ 254 | 255 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/customers/create') 256 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 257 | .body(self.dictionaryEncode('customer', self.__customer)) 258 | .reply(201) 259 | .headers(self.__header) 260 | .json({'success': 'true', 'id': 7777}) 261 | ) 262 | 263 | response = self.client.customer_create(self.__customer) 264 | pook.off() 265 | 266 | self.assertTrue(response.is_successful(), True) 267 | self.assertTrue(response.get_status_code() < 400, True) 268 | 269 | @pook.on 270 | def test_customers_fix_external_ids(self): 271 | """ 272 | V3 Test method customers_fix_external_ids 273 | """ 274 | 275 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/customers/fix-external-ids') 276 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 277 | .body(self.dictionaryEncode('customers', self.__customer['externalId'])) 278 | .reply(200) 279 | .headers(self.__header) 280 | .json({'success': 'true'}) 281 | ) 282 | 283 | response = self.client.customers_fix_external_ids(self.__customer['externalId']) 284 | pook.off() 285 | 286 | self.assertTrue(response.is_successful(), True) 287 | self.assertTrue(response.get_status_code() < 400, True) 288 | 289 | @pook.on 290 | def test_customers_upload(self): 291 | """ 292 | V3 Test method customers_upload 293 | """ 294 | 295 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/customers/upload') 296 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 297 | .body(self.dictionaryEncode('customers', self.__customer)) 298 | .reply(200) 299 | .headers(self.__header) 300 | .json( 301 | { 302 | 'success': 'true', 303 | 'uploadedCustomers': [ 304 | { 305 | 'id': 9717, 306 | 'externalId': 'c-983344770' 307 | } 308 | ] 309 | } 310 | ) 311 | ) 312 | 313 | response = self.client.customers_upload(self.__customer) 314 | pook.off() 315 | 316 | self.assertTrue(response.is_successful(), True) 317 | self.assertTrue(response.get_status_code() < 400, True) 318 | 319 | @pook.on 320 | def test_customer(self): 321 | """ 322 | V3 Test method customer 323 | """ 324 | 325 | uid = str(self.__customer['externalId']) 326 | 327 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/customers/' + uid) 328 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 329 | .reply(200) 330 | .headers(self.__header) 331 | .json({'success': 'true', 'customers': self.__customer}) 332 | ) 333 | 334 | response = self.client.customer(uid) 335 | pook.off() 336 | 337 | self.assertTrue(response.is_successful(), True) 338 | self.assertTrue(response.get_status_code() < 400, True) 339 | 340 | @pook.on 341 | def test_customers_edit(self): 342 | """ 343 | V3 Test method customers_edit 344 | """ 345 | 346 | uid = str(self.__customer['externalId']) 347 | 348 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/customers/' + uid + '/edit') 349 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 350 | .body(self.dictionaryEncode('customer', self.__customer)) 351 | .reply(200) 352 | .headers(self.__header) 353 | .json({'success': 'true', 'id': 9717}) 354 | ) 355 | 356 | response = self.client.customer_edit(self.__customer) 357 | pook.off() 358 | 359 | self.assertTrue(response.is_successful(), True) 360 | self.assertTrue(response.get_status_code() < 400, True) 361 | 362 | @pook.on 363 | def test_orders(self): 364 | """ 365 | V3 Test method orders 366 | """ 367 | 368 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/orders') 369 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 370 | .params({'filter[bad]': 'false', 'filter[contragentType]': 'individual'}) 371 | .reply(200) 372 | .headers(self.__header) 373 | .json( 374 | { 375 | 'success': 'true', 376 | 'pagination': { 377 | 'limit': 20, 378 | 'totalCount': 2444, 379 | 'currentPage': 1, 380 | 'totalPageCount': 49 381 | }, 382 | 'orders': [self.__order] 383 | } 384 | ) 385 | ) 386 | 387 | response = self.client.orders({'bad': 'false', 'contragentType': 'individual'}) 388 | pook.off() 389 | 390 | self.assertTrue(response.is_successful(), True) 391 | self.assertTrue(response.get_status_code() < 400, True) 392 | 393 | @pook.on 394 | def test_orders_create(self): 395 | """ 396 | V3 Test method orders_create 397 | """ 398 | 399 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/orders/create') 400 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 401 | .body(self.dictionaryEncode('order', self.__order)) 402 | .reply(201) 403 | .headers(self.__header) 404 | .json({'success': 'true', 'id': 7777, 'order': self.__order}) 405 | ) 406 | 407 | response = self.client.order_create(self.__order) 408 | pook.off() 409 | 410 | self.assertTrue(response.is_successful(), True) 411 | self.assertTrue(response.get_status_code() < 400, True) 412 | 413 | @pook.on 414 | def test_orders_fix_external_ids(self): 415 | """ 416 | V3 Test method orders_fix_external_ids 417 | """ 418 | 419 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/orders/fix-external-ids') 420 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 421 | .body(self.dictionaryEncode('orders', self.__order['externalId'])) 422 | .reply(200) 423 | .headers(self.__header) 424 | .json({'success': 'true'}) 425 | ) 426 | 427 | response = self.client.orders_fix_external_ids(self.__order['externalId']) 428 | pook.off() 429 | 430 | self.assertTrue(response.is_successful(), True) 431 | self.assertTrue(response.get_status_code() < 400, True) 432 | 433 | @pook.on 434 | def test_orders_history(self): 435 | """ 436 | V3 Test method orders_history 437 | """ 438 | 439 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/orders/history') 440 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 441 | .params({'startDate': '2020-01-07', 'endDate': '2020-04-12'}) 442 | .reply(200) 443 | .headers(self.__header) 444 | .json( 445 | { 446 | 'success': 'true', 447 | 'generatedAt': '2020-04-12 15:44:24', 448 | 'orders': [self.__order] 449 | } 450 | ) 451 | ) 452 | 453 | response = self.client.orders_history('2020-01-07', '2020-04-12') 454 | pook.off() 455 | 456 | self.assertTrue(response.is_successful(), True) 457 | self.assertTrue(response.get_status_code() < 400, True) 458 | 459 | @pook.on 460 | def test_orders_statuses(self): 461 | """ 462 | V3 Test method orders_statuses 463 | """ 464 | 465 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/orders/statuses') 466 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 467 | .params({'ids[]': '5604', 'externalIds[]': '5603'}) 468 | .reply(200) 469 | .headers(self.__header) 470 | .json( 471 | { 472 | 'success': 'true', 473 | 'orders': [ 474 | { 475 | 'id': 5604, 476 | 'externalId': '5603', 477 | 'status': 'new', 478 | 'group': 'new' 479 | } 480 | ] 481 | } 482 | ) 483 | ) 484 | 485 | response = self.client.orders_statuses([5604], [5603]) 486 | pook.off() 487 | 488 | self.assertTrue(response.is_successful(), True) 489 | self.assertTrue(response.get_status_code() < 400, True) 490 | 491 | @pook.on 492 | def test_orders_upload(self): 493 | """ 494 | V3 Test method orders_upload 495 | """ 496 | 497 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/orders/upload') 498 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 499 | .body(self.dictionaryEncode('orders', self.__order)) 500 | .reply(201) 501 | .headers(self.__header) 502 | .json( 503 | { 504 | 'success': 'true', 505 | 'uploadedOrders': [ 506 | { 507 | 'id': 5604, 508 | 'externalId': '5603' 509 | } 510 | ], 511 | 'orders': [self.__order] 512 | } 513 | ) 514 | ) 515 | 516 | response = self.client.orders_upload(self.__order) 517 | pook.off() 518 | 519 | self.assertTrue(response.is_successful(), True) 520 | self.assertTrue(response.get_status_code() < 400, True) 521 | 522 | @pook.on 523 | def test_order(self): 524 | """ 525 | V3 Test method order 526 | """ 527 | 528 | uid = str(self.__order['externalId']) 529 | 530 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/orders/' + uid) 531 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 532 | .reply(200) 533 | .headers(self.__header) 534 | .json({'success': 'true', 'orders': self.__order}) 535 | ) 536 | 537 | response = self.client.order(uid) 538 | pook.off() 539 | 540 | self.assertTrue(response.is_successful(), True) 541 | self.assertTrue(response.get_status_code() < 400, True) 542 | 543 | @pook.on 544 | def test_orders_edit(self): 545 | """ 546 | V3 Test method orders_edit 547 | """ 548 | 549 | uid = str(self.__order['externalId']) 550 | 551 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/orders/' + uid + '/edit') 552 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 553 | .body(self.dictionaryEncode('order', self.__order)) 554 | .reply(200) 555 | .headers(self.__header) 556 | .json({'success': 'true', 'id': 5604, 'order': self.__order}) 557 | ) 558 | 559 | response = self.client.order_edit(self.__order) 560 | pook.off() 561 | 562 | self.assertTrue(response.is_successful(), True) 563 | self.assertTrue(response.get_status_code() < 400, True) 564 | 565 | @pook.on 566 | def test_packs(self): 567 | """ 568 | V3 Test method packs 569 | """ 570 | 571 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/orders/packs') 572 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 573 | .params({'filter[store]': '7777z'}) 574 | .reply(200) 575 | .headers(self.__header) 576 | .json( 577 | { 578 | 'success': 'true', 579 | 'pagination': { 580 | 'limit': 20, 581 | 'totalCount': 1, 582 | 'currentPage': 1, 583 | 'totalPageCount': 1 584 | }, 585 | 'packs': [self.__pack] 586 | } 587 | ) 588 | ) 589 | 590 | response = self.client.packs({'store': '7777z'}) 591 | pook.off() 592 | 593 | self.assertTrue(response.is_successful(), True) 594 | self.assertTrue(response.get_status_code() < 400, True) 595 | 596 | @pook.on 597 | def test_packs_create(self): 598 | """ 599 | V3 Test method packs_create 600 | """ 601 | 602 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/orders/packs/create') 603 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 604 | .body(self.dictionaryEncode('pack', {'store': '7777z', 'quantity': 1, 'itemId': 7632})) 605 | .reply(201) 606 | .headers(self.__header) 607 | .json({'success': 'true', 'id': 7777}) 608 | ) 609 | 610 | response = self.client.pack_create({'store': '7777z', 'quantity': 1, 'itemId': 7632}) 611 | pook.off() 612 | 613 | self.assertTrue(response.is_successful(), True) 614 | self.assertTrue(response.get_status_code() < 400, True) 615 | 616 | @pook.on 617 | def test_packs_history(self): 618 | """ 619 | V3 Test method packs_history 620 | """ 621 | 622 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/orders/packs/history') 623 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 624 | .params({'filter[startDate]': '2016-01-07', 'filter[endDate]': '2020-04-12'}) 625 | .reply(200) 626 | .headers(self.__header) 627 | .json( 628 | { 629 | 'success': 'true', 630 | 'generatedAt': '2020-04-17 13:08:48', 631 | 'history': [ 632 | { 633 | 'id': 777, 634 | 'createdAt': '2018-04-13 15:46:06', 635 | 'created': 'true', 636 | 'field': 'store', 637 | 'newValue': { 638 | 'code': 'zzz' 639 | }, 640 | 'pack': { 641 | 'id': 678, 642 | 'quantity': 1, 643 | 'store': {'code': 'zzz'}, 644 | 'item': { 645 | 'id': 222, 646 | 'order': {'id': 6677}, 647 | 'offer': {'externalId': '333'} 648 | } 649 | }, 650 | 'source': 'api' 651 | } 652 | ] 653 | } 654 | ) 655 | ) 656 | 657 | response = self.client.packs_history({'startDate': '2016-01-07', 'endDate': '2020-04-12'}) 658 | pook.off() 659 | 660 | self.assertTrue(response.is_successful(), True) 661 | self.assertTrue(response.get_status_code() < 400, True) 662 | 663 | @pook.on 664 | def test_pack(self): 665 | """ 666 | V3 Test method pack 667 | """ 668 | 669 | uid = str(self.__pack['id']) 670 | 671 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/orders/packs/' + uid) 672 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 673 | .reply(200) 674 | .headers(self.__header) 675 | .json({'success': 'true', 'pack': self.__pack}) 676 | ) 677 | 678 | response = self.client.pack(uid) 679 | pook.off() 680 | 681 | self.assertTrue(response.is_successful(), True) 682 | self.assertTrue(response.get_status_code() < 400, True) 683 | 684 | @pook.on 685 | def test_packs_delete(self): 686 | """ 687 | V3 Test method packs_delete 688 | """ 689 | 690 | uid = str(self.__pack['id']) 691 | 692 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/orders/packs/' + uid + '/delete') 693 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 694 | .reply(200) 695 | .headers(self.__header) 696 | .json({'success': 'true'}) 697 | ) 698 | 699 | response = self.client.pack_delete(uid) 700 | pook.off() 701 | 702 | self.assertTrue(response.is_successful(), True) 703 | self.assertTrue(response.get_status_code() < 400, True) 704 | 705 | @pook.on 706 | def test_pack_edit(self): 707 | """ 708 | V3 Test method pack_edit 709 | """ 710 | 711 | uid = str(self.__pack['id']) 712 | 713 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/orders/packs/' + uid + '/edit') 714 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 715 | .body(self.dictionaryEncode('pack', self.__pack)) 716 | .reply(200) 717 | .headers(self.__header) 718 | .json({'success': 'true', 'id': 5604}) 719 | ) 720 | 721 | response = self.client.pack_edit(self.__pack) 722 | pook.off() 723 | 724 | self.assertTrue(response.is_successful(), True) 725 | self.assertTrue(response.get_status_code() < 400, True) 726 | 727 | @pook.on 728 | def test_countries(self): 729 | """ 730 | V3 Test method countries 731 | """ 732 | 733 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/countries') 734 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 735 | .reply(200) 736 | .headers(self.__header) 737 | .json({'success': 'true', 'countriesIso': ['RU', 'UA', 'BY', 'KZ']}) 738 | ) 739 | 740 | response = self.client.countries() 741 | pook.off() 742 | 743 | self.assertTrue(response.is_successful(), True) 744 | self.assertTrue(response.get_status_code() < 400, True) 745 | 746 | @pook.on 747 | def test_delivery_services(self): 748 | """ 749 | V3 Test method delivery_services 750 | """ 751 | 752 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/delivery-services') 753 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 754 | .reply(200) 755 | .headers(self.__header) 756 | .json( 757 | { 758 | 'success': 'true', 759 | 'deliveryServices': { 760 | '0tq6d': { 761 | 'name': '57jij', 762 | 'code': '0tq6d' 763 | }, 764 | 'a080k': { 765 | 'name': 's789', 766 | 'code': 'a080k' 767 | }, 768 | 'a6zgf': { 769 | 'name': 'eu8ss', 770 | 'code': 'a6zgf' 771 | } 772 | } 773 | } 774 | ) 775 | ) 776 | 777 | response = self.client.delivery_services() 778 | pook.off() 779 | 780 | self.assertTrue(response.is_successful(), True) 781 | self.assertTrue(response.get_status_code() < 400, True) 782 | 783 | @pook.on 784 | def test_delivery_services_edit(self): 785 | """ 786 | V3 Test method delivery_services_edit 787 | """ 788 | 789 | service = {'code': 'a080k', 'name': 's789'} 790 | 791 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/delivery-services/' + service['code'] + '/edit') 792 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 793 | .body(self.dictionaryEncode('deliveryService', service)) 794 | .reply(200) 795 | .headers(self.__header) 796 | .json({'success': 'true'}) 797 | ) 798 | 799 | response = self.client.delivery_services_edit(service) 800 | pook.off() 801 | 802 | self.assertTrue(response.is_successful(), True) 803 | self.assertTrue(response.get_status_code() < 400, True) 804 | 805 | @pook.on 806 | def test_delivery_types(self): 807 | """ 808 | V3 Test method delivery_types 809 | """ 810 | 811 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/delivery-types') 812 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 813 | .reply(201) 814 | .headers(self.__header) 815 | .json( 816 | { 817 | 'success': 'true', 818 | 'deliveryTypes': { 819 | '1kp52': { 820 | 'name': 's789', 821 | 'code': '1kp52', 822 | 'defaultCost': 300, 823 | 'defaultNetCost': 0, 824 | 'paymentTypes': [ 825 | 'cash', 826 | 'bank-card' 827 | ], 828 | 'deliveryServices': [], 829 | 'defaultForCrm': 'false' 830 | }, 831 | 's789': { 832 | 'name': '1s0ei', 833 | 'code': 's789', 834 | 'defaultCost': 300, 835 | 'defaultNetCost': 0, 836 | 'paymentTypes': [ 837 | 'cash', 838 | 'bank-card' 839 | ], 840 | 'deliveryServices': [], 841 | 'defaultForCrm': 'false' 842 | } 843 | } 844 | } 845 | ) 846 | ) 847 | 848 | response = self.client.delivery_types() 849 | pook.off() 850 | 851 | self.assertTrue(response.is_successful(), True) 852 | self.assertTrue(response.get_status_code() < 400, True) 853 | 854 | @pook.on 855 | def test_delivery_types_edit(self): 856 | """ 857 | V3 Test method delivery_types_edit 858 | """ 859 | 860 | delivery_type = {'code': 's789', 'name': '1s0ei'} 861 | 862 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/delivery-types/' + delivery_type['code'] + '/edit') 863 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 864 | .body(self.dictionaryEncode('deliveryType', delivery_type)) 865 | .reply(200) 866 | .headers(self.__header) 867 | .json({'success': 'true'}) 868 | ) 869 | 870 | response = self.client.delivery_types_edit(delivery_type) 871 | pook.off() 872 | 873 | self.assertTrue(response.is_successful(), True) 874 | self.assertTrue(response.get_status_code() < 400, True) 875 | 876 | @pook.on 877 | def test_order_methods(self): 878 | """ 879 | V3 Test method order_methods 880 | """ 881 | 882 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/order-methods') 883 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 884 | .reply(200) 885 | .headers(self.__header) 886 | .json( 887 | { 888 | 'success': 'true', 889 | 'orderMethods': { 890 | '1b4os': { 891 | 'name': '19le4', 892 | 'code': '1b4os', 893 | 'defaultForCrm': 'false', 894 | 'defaultForApi': 'false', 895 | 'isFromPos': 'false' 896 | }, 897 | '44cmd': { 898 | 'name': '1tdf4', 899 | 'code': '44cmd', 900 | 'defaultForCrm': 'false', 901 | 'defaultForApi': 'false', 902 | 'isFromPos': 'false' 903 | }, 904 | 'zoc5q': { 905 | 'name': '1y0cp', 906 | 'code': 'zoc5q', 907 | 'defaultForCrm': 'false', 908 | 'defaultForApi': 'false', 909 | 'isFromPos': 'false' 910 | } 911 | } 912 | } 913 | ) 914 | ) 915 | 916 | response = self.client.order_methods() 917 | pook.off() 918 | 919 | self.assertTrue(response.is_successful(), True) 920 | self.assertTrue(response.get_status_code() < 400, True) 921 | 922 | @pook.on 923 | def test_order_methods_edit(self): 924 | """ 925 | V3 Test method order_methods_edit 926 | """ 927 | 928 | method = {'code': 'zoc5q', 'name': '1y0cp'} 929 | 930 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/order-methods/' + method['code'] + '/edit') 931 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 932 | .body(self.dictionaryEncode('orderMethod', method)) 933 | .reply(200) 934 | .headers(self.__header) 935 | .json({'success': 'true'}) 936 | ) 937 | 938 | response = self.client.order_methods_edit(method) 939 | pook.off() 940 | 941 | self.assertTrue(response.is_successful(), True) 942 | self.assertTrue(response.get_status_code() < 400, True) 943 | 944 | @pook.on 945 | def test_order_types(self): 946 | """ 947 | V3 Test method order_types 948 | """ 949 | 950 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/order-types') 951 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 952 | .reply(200) 953 | .headers(self.__header) 954 | .json( 955 | { 956 | 'success': 'true', 957 | 'orderTypes': { 958 | 's789': { 959 | 'name': 'test', 960 | 'code': 's789', 961 | 'defaultForCrm': 'true', 962 | 'defaultForApi': 'true', 963 | 'ordering': 990 964 | }, 965 | 'b7e20': { 966 | 'name': 'vwt5f', 967 | 'code': 'b7e20', 968 | 'defaultForCrm': 'false', 969 | 'defaultForApi': 'false', 970 | 'ordering': 990 971 | } 972 | } 973 | } 974 | ) 975 | ) 976 | 977 | response = self.client.order_types() 978 | pook.off() 979 | 980 | self.assertTrue(response.is_successful(), True) 981 | self.assertTrue(response.get_status_code() < 400, True) 982 | 983 | @pook.on 984 | def test_order_types_edit(self): 985 | """ 986 | V3 Test method order_types_edit 987 | """ 988 | 989 | order_type = {'code': 's789', 'name': 'test'} 990 | 991 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/order-types/' + order_type['code'] + '/edit') 992 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 993 | .body(self.dictionaryEncode('orderType', order_type)) 994 | .reply(200) 995 | .headers(self.__header) 996 | .json({'success': 'true'}) 997 | ) 998 | 999 | response = self.client.order_types_edit(order_type) 1000 | pook.off() 1001 | 1002 | self.assertTrue(response.is_successful(), True) 1003 | self.assertTrue(response.get_status_code() < 400, True) 1004 | 1005 | @pook.on 1006 | def test_payment_statuses(self): 1007 | """ 1008 | V3 Test method payment_statuses 1009 | """ 1010 | 1011 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/payment-statuses') 1012 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1013 | .reply(200) 1014 | .headers(self.__header) 1015 | .json( 1016 | { 1017 | 'success': 'true', 1018 | 'paymentStatuses': { 1019 | 'invoice': { 1020 | 'name': 'Выставлен счет', 1021 | 'code': 'invoice', 1022 | 'defaultForCrm': 'false', 1023 | 'defaultForApi': 'false', 1024 | 'paymentComplete': 'false', 1025 | 'ordering': 20, 1026 | 'paymentTypes': [ 1027 | 'bank-card', 1028 | 'bank-transfer', 1029 | 'credit', 1030 | 'cash', 1031 | 'e-money' 1032 | ] 1033 | }, 1034 | 'payment-start': { 1035 | 'name': 'Платеж проведен', 1036 | 'code': 'payment-start', 1037 | 'defaultForCrm': 'false', 1038 | 'defaultForApi': 'false', 1039 | 'paymentComplete': 'false', 1040 | 'ordering': 30, 1041 | 'paymentTypes': [ 1042 | 'bank-card', 1043 | 'bank-transfer', 1044 | 'credit', 1045 | 'cash', 1046 | 'e-money' 1047 | ] 1048 | } 1049 | } 1050 | } 1051 | ) 1052 | ) 1053 | 1054 | response = self.client.payment_statuses() 1055 | pook.off() 1056 | 1057 | self.assertTrue(response.is_successful(), True) 1058 | self.assertTrue(response.get_status_code() < 400, True) 1059 | 1060 | @pook.on 1061 | def test_payment_statuses_edit(self): 1062 | """ 1063 | V3 Test method payment_statuses_edit 1064 | """ 1065 | 1066 | status = {'code': 'payment-start', 'name': 'Платеж проведен'} 1067 | 1068 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/payment-statuses/' + status['code'] + '/edit') 1069 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1070 | .body(self.dictionaryEncode('paymentStatus', status)) 1071 | .reply(200) 1072 | .headers(self.__header) 1073 | .json({'success': 'true'}) 1074 | ) 1075 | 1076 | response = self.client.payment_statuses_edit(status) 1077 | pook.off() 1078 | 1079 | self.assertTrue(response.is_successful(), True) 1080 | self.assertTrue(response.get_status_code() < 400, True) 1081 | 1082 | @pook.on 1083 | def test_payment_types(self): 1084 | """ 1085 | V3 Test method payment_types 1086 | """ 1087 | 1088 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/payment-types') 1089 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1090 | .reply(200) 1091 | .headers(self.__header) 1092 | .json( 1093 | { 1094 | 'success': 'true', 1095 | 'paymentTypes': { 1096 | '056a3e': { 1097 | 'name': 'TestPaymentType-056a3e', 1098 | 'code': '056a3e', 1099 | 'defaultForCrm': 'false', 1100 | 'defaultForApi': 'false', 1101 | 'deliveryTypes': [], 1102 | 'paymentStatuses': [] 1103 | }, 1104 | '238c06': { 1105 | 'name': 'TestPaymentType-238c06', 1106 | 'code': '238c06', 1107 | 'defaultForCrm': 'false', 1108 | 'defaultForApi': 'false', 1109 | 'deliveryTypes': [], 1110 | 'paymentStatuses': [] 1111 | } 1112 | } 1113 | } 1114 | ) 1115 | ) 1116 | 1117 | response = self.client.payment_types() 1118 | pook.off() 1119 | 1120 | self.assertTrue(response.is_successful(), True) 1121 | self.assertTrue(response.get_status_code() < 400, True) 1122 | 1123 | @pook.on 1124 | def test_payment_types_edit(self): 1125 | """ 1126 | V3 Test method payment_types_edit 1127 | """ 1128 | 1129 | payment_type = {'code': '238c06', 'name': 'TestPaymentType-238c06'} 1130 | 1131 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/payment-types/' + payment_type['code'] + '/edit') 1132 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1133 | .body(self.dictionaryEncode('paymentType', payment_type)) 1134 | .reply(200) 1135 | .headers(self.__header) 1136 | .json({'success': 'true'}) 1137 | ) 1138 | 1139 | response = self.client.payment_types_edit(payment_type) 1140 | pook.off() 1141 | 1142 | self.assertTrue(response.is_successful(), True) 1143 | self.assertTrue(response.get_status_code() < 400, True) 1144 | 1145 | @pook.on 1146 | def test_product_statuses(self): 1147 | """ 1148 | V3 Test method product_statuses 1149 | """ 1150 | 1151 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/product-statuses') 1152 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1153 | .reply(200) 1154 | .headers(self.__header) 1155 | .json( 1156 | { 1157 | 'success': 'true', 1158 | 'productStatuses': { 1159 | 'confirming': { 1160 | 'code': 'confirming', 1161 | 'ordering': 20, 1162 | 'createdAt': '2018-04-10 12:33:58', 1163 | 'cancelStatus': 'false', 1164 | 'name': 'Подтверждение наличия' 1165 | }, 1166 | 'in-reserve': { 1167 | 'code': 'in-reserve', 1168 | 'ordering': 30, 1169 | 'createdAt': '2018-04-10 12:33:58', 1170 | 'cancelStatus': 'false', 1171 | 'name': 'В резерве' 1172 | } 1173 | } 1174 | } 1175 | ) 1176 | ) 1177 | 1178 | response = self.client.product_statuses() 1179 | pook.off() 1180 | 1181 | self.assertTrue(response.is_successful(), True) 1182 | self.assertTrue(response.get_status_code() < 400, True) 1183 | 1184 | @pook.on 1185 | def test_product_statuses_edit(self): 1186 | """ 1187 | V3 Test method product_statuses_edit 1188 | """ 1189 | 1190 | status = {'code': 'in-reserve', 'name': 'В резерве'} 1191 | 1192 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/product-statuses/' + status['code'] + '/edit') 1193 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1194 | .body(self.dictionaryEncode('productStatus', status)) 1195 | .reply(200) 1196 | .headers(self.__header) 1197 | .json({'success': 'true'}) 1198 | ) 1199 | 1200 | response = self.client.product_statuses_edit(status) 1201 | pook.off() 1202 | 1203 | self.assertTrue(response.is_successful(), True) 1204 | self.assertTrue(response.get_status_code() < 400, True) 1205 | 1206 | @pook.on 1207 | def test_sites(self): 1208 | """ 1209 | V3 Test method sites 1210 | """ 1211 | 1212 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/sites') 1213 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1214 | .reply(200) 1215 | .headers(self.__header) 1216 | .json( 1217 | { 1218 | 'success': 'true', 1219 | 'sites': { 1220 | 'sites': { 1221 | 'name': 'XXX', 1222 | 'url': 'http://url', 1223 | 'code': 'code', 1224 | 'defaultForCrm': 'false', 1225 | 'ymlUrl': 'http://url', 1226 | 'loadFromYml': 'true', 1227 | 'catalogUpdatedAt': '2020-04-03 13:56:26', 1228 | 'catalogLoadingAt': '2020-04-13 08:50:55', 1229 | 'countryIso': 'RU' 1230 | } 1231 | } 1232 | } 1233 | ) 1234 | ) 1235 | 1236 | response = self.client.sites() 1237 | pook.off() 1238 | 1239 | self.assertTrue(response.is_successful(), True) 1240 | self.assertTrue(response.get_status_code() < 400, True) 1241 | 1242 | @pook.on 1243 | def test_sites_edit(self): 1244 | """ 1245 | V3 Test method sites_edit 1246 | """ 1247 | 1248 | site = {'code': 'code', 'name': 'XXX'} 1249 | 1250 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/sites/' + site['code'] + '/edit') 1251 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1252 | .body(self.dictionaryEncode('site', site)) 1253 | .reply(200) 1254 | .headers(self.__header) 1255 | .json({'success': 'true'}) 1256 | ) 1257 | 1258 | response = self.client.sites_edit(site) 1259 | pook.off() 1260 | 1261 | self.assertTrue(response.is_successful(), True) 1262 | self.assertTrue(response.get_status_code() < 400, True) 1263 | 1264 | @pook.on 1265 | def test_status_groups(self): 1266 | """ 1267 | V3 Test method status_groups 1268 | """ 1269 | 1270 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/status-groups') 1271 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1272 | .reply(200) 1273 | .headers(self.__header) 1274 | .json( 1275 | { 1276 | 'success': 'true', 1277 | 'statusGroups': { 1278 | 'new': { 1279 | 'name': 'Новый', 1280 | 'code': 'new', 1281 | 'ordering': 10, 1282 | 'process': 'false', 1283 | 'statuses': [ 1284 | 'new', 1285 | 'rake-status' 1286 | ] 1287 | }, 1288 | 'approval': { 1289 | 'name': 'Согласование', 1290 | 'code': 'approval', 1291 | 'ordering': 20, 1292 | 'process': 'true', 1293 | 'statuses': [ 1294 | 'availability-confirmed', 1295 | 'offer-analog', 1296 | 'client-confirmed', 1297 | 'prepayed' 1298 | ] 1299 | } 1300 | } 1301 | } 1302 | ) 1303 | ) 1304 | 1305 | response = self.client.status_groups() 1306 | pook.off() 1307 | 1308 | self.assertTrue(response.is_successful(), True) 1309 | self.assertTrue(response.get_status_code() < 400, True) 1310 | 1311 | @pook.on 1312 | def test_statuses(self): 1313 | """ 1314 | V3 Test method statuses 1315 | """ 1316 | 1317 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/statuses') 1318 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1319 | .reply(200) 1320 | .headers(self.__header) 1321 | .json( 1322 | { 1323 | 'success': 'true', 1324 | 'statuses': { 1325 | 'new': { 1326 | 'name': 'Новый', 1327 | 'code': 'new', 1328 | 'ordering': 10, 1329 | 'group': 'new' 1330 | }, 1331 | 'rake-status': { 1332 | 'name': 'Rake status', 1333 | 'code': 'rake-status', 1334 | 'ordering': 990, 1335 | 'group': 'new' 1336 | } 1337 | } 1338 | } 1339 | ) 1340 | ) 1341 | 1342 | response = self.client.statuses() 1343 | pook.off() 1344 | 1345 | self.assertTrue(response.is_successful(), True) 1346 | self.assertTrue(response.get_status_code() < 400, True) 1347 | 1348 | @pook.on 1349 | def test_statuses_edit(self): 1350 | """ 1351 | V3 Test method statuses_edit 1352 | """ 1353 | 1354 | status = {'code': 'new', 'name': 'Новый'} 1355 | 1356 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/statuses/' + status['code'] + '/edit') 1357 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1358 | .body(self.dictionaryEncode('status', status)) 1359 | .reply(200) 1360 | .headers(self.__header) 1361 | .json({'success': 'true'}) 1362 | ) 1363 | 1364 | response = self.client.statuses_edit(status) 1365 | pook.off() 1366 | 1367 | self.assertTrue(response.is_successful(), True) 1368 | self.assertTrue(response.get_status_code() < 400, True) 1369 | 1370 | @pook.on 1371 | def test_stores(self): 1372 | """ 1373 | V3 Test method stores 1374 | """ 1375 | 1376 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/reference/stores') 1377 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1378 | .reply(200) 1379 | .headers(self.__header) 1380 | .json( 1381 | { 1382 | 'success': 'true', 1383 | 'stores': [ 1384 | { 1385 | 'type': 'store-type-warehouse', 1386 | 'inventoryType': 'integer', 1387 | 'code': 'lca46', 1388 | 'name': 'new' 1389 | }, 1390 | { 1391 | 'type': 'store-type-warehouse', 1392 | 'inventoryType': 'integer', 1393 | 'code': 'q6w5i', 1394 | 'name': 's789' 1395 | } 1396 | ] 1397 | } 1398 | ) 1399 | ) 1400 | 1401 | response = self.client.stores() 1402 | pook.off() 1403 | 1404 | self.assertTrue(response.is_successful(), True) 1405 | self.assertTrue(response.get_status_code() < 400, True) 1406 | 1407 | @pook.on 1408 | def test_stores_edit(self): 1409 | """ 1410 | V3 Test method stores_edit 1411 | """ 1412 | 1413 | store = {'code': 'q6w5i', 'name': 's789'} 1414 | 1415 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/reference/stores/' + store['code'] + '/edit') 1416 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1417 | .body(self.dictionaryEncode('store', store)) 1418 | .reply(200) 1419 | .headers(self.__header) 1420 | .json({'success': 'true'}) 1421 | ) 1422 | 1423 | response = self.client.stores_edit(store) 1424 | pook.off() 1425 | 1426 | self.assertTrue(response.is_successful(), True) 1427 | self.assertTrue(response.get_status_code() < 400, True) 1428 | 1429 | @pook.on 1430 | def test_inventories(self): 1431 | """ 1432 | V3 Test method inventories 1433 | """ 1434 | 1435 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/store/inventories') 1436 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1437 | .params({'filter[site]': 'https://help.ru'}) 1438 | .reply(200) 1439 | .headers(self.__header) 1440 | .json( 1441 | { 1442 | 'success': 'true', 1443 | 'pagination': 1444 | { 1445 | 'limit': 20, 1446 | 'totalCount': 34, 1447 | 'currentPage': 1, 1448 | 'totalPageCount': 2 1449 | }, 1450 | 'offers': [ 1451 | { 1452 | 'externalId': 'werew', 1453 | 'quantity': 102 1454 | }, 1455 | { 1456 | 'externalId': '46', 1457 | 'quantity': 0 1458 | }, 1459 | { 1460 | 'externalId': '33', 1461 | 'quantity': 0 1462 | }] 1463 | } 1464 | ) 1465 | ) 1466 | 1467 | response = self.client.inventories({'site': 'https://help.ru'}) 1468 | pook.off() 1469 | 1470 | self.assertTrue(response.is_successful(), True) 1471 | self.assertTrue(response.get_status_code() < 400, True) 1472 | 1473 | @pook.on 1474 | def test_inventories_upload(self): 1475 | """ 1476 | V3 Test method inventories_upload 1477 | """ 1478 | 1479 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/store/inventories/upload') 1480 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1481 | .body(self.dictionaryEncode('offers', {'externalId': 's789', 'id': 5603})) 1482 | .reply(200) 1483 | .headers(self.__header) 1484 | .json( 1485 | { 1486 | 'success': 'true', 1487 | 'processedOffersCount': 0, 1488 | 'notFoundOffers': { 1489 | 'externalId': 's789', 1490 | 'xmlId': 9999 1491 | } 1492 | } 1493 | ) 1494 | ) 1495 | 1496 | response = self.client.inventories_upload({'externalId': 's789', 'id': 5603}) 1497 | pook.off() 1498 | 1499 | self.assertTrue(response.is_successful(), True) 1500 | self.assertTrue(response.get_status_code() < 400, True) 1501 | 1502 | @pook.on 1503 | def test_telephony_call_event(self): 1504 | """ 1505 | V3 Test method telephony_call_event 1506 | """ 1507 | 1508 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/telephony/call/event') 1509 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1510 | .body(urlencode({'hangupStatus': 'busy', 'phone': '+799999999', 'code': 'c2321', 'type': 'hangup'})) 1511 | .reply(200) 1512 | .headers(self.__header) 1513 | .json({'success': 'true'}) 1514 | ) 1515 | 1516 | response = self.client.telephony_call_event('+799999999', 'hangup', 'c2321', 'busy') 1517 | pook.off() 1518 | 1519 | self.assertTrue(response.is_successful(), True) 1520 | self.assertTrue(response.get_status_code() < 400, True) 1521 | 1522 | @pook.on 1523 | def test_telephony_calls_upload(self): 1524 | """ 1525 | V3 Test method telephony_calls_upload 1526 | """ 1527 | 1528 | (pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/telephony/calls/upload') 1529 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1530 | .body(self.dictionaryEncode('calls', {})) 1531 | .reply(200) 1532 | .headers(self.__header) 1533 | .json( 1534 | { 1535 | 'success': 'true', 1536 | 'processedCallsCount': 5555, 1537 | 'duplicateCalls': [] 1538 | } 1539 | ) 1540 | ) 1541 | 1542 | response = self.client.telephony_calls_upload({}) 1543 | pook.off() 1544 | 1545 | self.assertTrue(response.is_successful(), True) 1546 | self.assertTrue(response.get_status_code() < 400, True) 1547 | 1548 | @pook.on 1549 | def test_telephony_manager(self): 1550 | """ 1551 | V3 Test method telephony_manager 1552 | """ 1553 | 1554 | (pook.get(os.getenv('RETAILCRM_URL') + '/api/v3/telephony/manager') 1555 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1556 | .params({'phone': '+79999999999'}) 1557 | .reply(200) 1558 | .headers(self.__header) 1559 | .json( 1560 | { 1561 | 'success': 'true', 1562 | 'manager': { 1563 | 'id': 777, 1564 | 'firstName': 'yyy', 1565 | 'lastName': 'xxxx', 1566 | 'patronymic': 's789', 1567 | 'email': 'mail@retailcrm.pro', 1568 | 'code': 'ccc7' 1569 | }, 1570 | 'customer': { 1571 | 'id': 888, 1572 | 'externalId': '5406', 1573 | 'firstName': 'ccc', 1574 | 'lastName': 's789', 1575 | 'patronymic': 's789', 1576 | 'email': 'mail@retailcrm.pro', 1577 | 'code': 'ccc7', 1578 | 'phones': [{'number': '+71111111111'}] 1579 | }, 1580 | 'links': { 1581 | 'newOrderLink': 'https://newOrderLink.ru', 1582 | 'lastOrderLink': 'https://lastOrderLink.ru', 1583 | 'newCustomerLink': 'https://newCustomerLink.ru', 1584 | 'customerLink': 'https://customerLink.ru', 1585 | } 1586 | } 1587 | ) 1588 | ) 1589 | 1590 | response = self.client.telephony_manager('+79999999999') 1591 | pook.off() 1592 | 1593 | self.assertTrue(response.is_successful(), True) 1594 | self.assertTrue(response.get_status_code() < 400, True) 1595 | 1596 | @pook.on 1597 | def test_telephony_settings(self): 1598 | """ 1599 | V3 Test method telephony_settings 1600 | """ 1601 | 1602 | code = 'xxx' 1603 | 1604 | ( 1605 | pook.post(os.getenv('RETAILCRM_URL') + '/api/v3/telephony/settings/' + code) 1606 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1607 | .body(urlencode({ 1608 | 'code': code, 1609 | 'clientId': '123x', 1610 | 'makeCallUrl': 'url', 1611 | 'active': 'active', 1612 | 'name': 'name', 1613 | 'image': 'url_image'})) 1614 | .reply(201) 1615 | .headers(self.__header) 1616 | .json({'success': 'true'}) 1617 | ) 1618 | 1619 | response = self.client.telephony_settings(code, '123x', 'url', 'active', 'name', 'url_image') 1620 | pook.off() 1621 | 1622 | self.assertTrue(response.is_successful(), True) 1623 | self.assertTrue(response.get_status_code() < 400, True) 1624 | 1625 | @pook.on 1626 | def statistic_update(self): 1627 | """ 1628 | V3 Test method statistic_update 1629 | """ 1630 | 1631 | (pook.get(os.getenv('RETAILCRM_URL') + '/statistic/update') 1632 | .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) 1633 | .reply(200) 1634 | .headers(self.__header) 1635 | .json({'success': 'true'}) 1636 | ) 1637 | 1638 | response = self.client.statistic_update() 1639 | pook.off() 1640 | 1641 | self.assertTrue(response.is_successful(), True) 1642 | self.assertTrue(response.get_status_code() < 400, True) 1643 | --------------------------------------------------------------------------------