From 79a43b1b4516a2eb4f8db4b2c5d493ea75a9caa4 Mon Sep 17 00:00:00 2001 From: Alex Komarichev Date: Wed, 12 Nov 2025 17:46:49 +0300 Subject: [PATCH 1/2] Added missed methods, changed version requirement to compatible release --- pyproject.toml | 2 +- retailcrm/versions/base.py | 6 +- retailcrm/versions/v5.py | 600 ++++++++++++++- tests/v5_tests.py | 1495 +++++++++++++++++++++++++++++++----- 4 files changed, 1888 insertions(+), 215 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4fbabed..2200c14 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ readme = "README.md" requires-python = ">=3.8" dependencies = [ "multidimensional-urlencode==0.0.4", - "requests==2.32.4", + "requests~=2.32.5", ] classifiers = [ diff --git a/retailcrm/versions/base.py b/retailcrm/versions/base.py index 302a26f..0021b2c 100644 --- a/retailcrm/versions/base.py +++ b/retailcrm/versions/base.py @@ -59,8 +59,8 @@ def api_credentials(self): """ return self.get('/credentials', False) - def statistic_update(self): + def system_info(self): """ - :return Response + :return: Response """ - return self.get('/statistic/update') + return self.get('/system-info', False) diff --git a/retailcrm/versions/v5.py b/retailcrm/versions/v5.py index 8f961bb..d91ebd8 100644 --- a/retailcrm/versions/v5.py +++ b/retailcrm/versions/v5.py @@ -314,6 +314,24 @@ def customer_edit(self, customer, uid_type='externalId', site=None): return self.post('/customers/' + str(customer[uid_type]) + '/edit') + def customer_subscription(self, uid, subscriptions, uid_type='externalId', site=None): + """ + :param uid: string + :param subscriptions: array of objects + :param uid_type: string + :param site: string + :return: Response + """ + self.parameters['subscriptions'] = json.dumps(subscriptions) + + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + if site is not None: + self.parameters['site'] = site + + return self.post('/customers/' + str(uid) + '/subscriptions') + def customers_corporate(self, filters=None, limit=20, page=1): """ :param filters: object @@ -579,7 +597,15 @@ def customer_corporate_companies_edit(self, if site is not None: self.parameters['site'] = site - return self.post('/customers-corporate/' + str(uid_corporate) + '/companies/' + str(company[entity_by]) + '/edit') + return self.post("".join( + [ + '/customers-corporate/', + str(uid_corporate), + '/companies/', + str(company[entity_by]), + '/edit' + ] + )) def customer_corporate_contacts(self, uid, uid_type='externalId', limit=20, page=1, filters=None, site=None): """ @@ -646,7 +672,15 @@ def customer_corporate_contacts_edit(self, if site is not None: self.parameters['site'] = site - return self.post('/customers-corporate/' + str(uid_corporate) + '/contacts/' + str(contact[entity_by]) + '/edit') + return self.post("".join( + [ + '/customers-corporate/', + str(uid_corporate), + '/contacts/', + str(contact[entity_by]), + '/edit' + ] + )) def customer_corporate_edit(self, customer_corporate, uid_type='externalId', site=None): """ @@ -665,6 +699,116 @@ def customer_corporate_edit(self, customer_corporate, uid_type='externalId', sit return self.post('/customers-corporate/' + str(customer_corporate[uid_type]) + '/edit') + def customer_interaction_cart_clear(self, site, cart, siteBy='code'): + """ + :param site: string + :param cart: object + :param siteBy: string + :return: Response + """ + self.parameters['cart'] = json.dumps(cart) + + if siteBy != 'code': + self.parameters['siteBy'] = siteBy + + return self.post('/customer-interaction/' + str(site) + '/cart/clear') + + def customer_interaction_cart_set(self, site, cart, siteBy='code'): + """ + :param site: string + :param cart: object + :param siteBy: string + :return: Response + """ + self.parameters['cart'] = json.dumps(cart) + + if siteBy != 'code': + self.parameters['siteBy'] = siteBy + + return self.post('/customer-interaction/' + str(site) + '/cart/set') + + def customer_interaction_cart(self, site, customer_id, uid_type='externalId', siteBy='code'): + """ + :param site: string + :param customer_id: string + :param uid_type: string + :param siteBy: string + :return: Response + """ + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + if siteBy != 'code': + self.parameters['siteBy'] = siteBy + + return self.get('/customer-interaction/' + str(site) + '/cart/' + str(customer_id)) + + def customer_interaction_favorites(self, site, customer_id, uid_type='externalId', siteBy='code'): + """ + :param site: string + :param customer_id: string + :param uid_type: string + :param siteBy: string + :return: Response + """ + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + if siteBy != 'code': + self.parameters['siteBy'] = siteBy + + return self.get('/customer-interaction/' + str(site) + '/favorites/' + str(customer_id)) + + def customer_interaction_favorites_add(self, site, customer_id, favorite, uid_type='externalId', siteBy='code'): + """ + :param site: string + :param customer_id: string + :param favorite: object + :param uid_type: string + :param siteBy: string + :return: Response + """ + self.parameters['favorite'] = json.dumps(favorite) + + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + if siteBy != 'code': + self.parameters['siteBy'] = siteBy + + return self.post('/customer-interaction/' + str(site) + '/favorites/' + str(customer_id) + '/add') + + def customer_interaction_favorite_remove(self, site, customer_id, favorite, uid_type='externalId', siteBy='code'): + """ + :param site: string + :param customer_id: string + :param favorite: object + :param uid_type: string + :param siteBy: string + :return: Response + """ + self.parameters['favorite'] = json.dumps(favorite) + + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + if siteBy != 'code': + self.parameters['siteBy'] = siteBy + + return self.post('/customer-interaction/' + str(site) + '/favorites/' + str(customer_id) + '/remove') + + def delivery_calculate(self, deliveryTypeCodes, order): + """ + :param deliveryTypeCodes: array of strings + :param order: object + :return: Response + """ + self.parameters['deliveryTypeCodes'] = json.dumps(deliveryTypeCodes) + + self.parameters['order'] = json.dumps(order) + + return self.post('/delivery/calculate') + def delivery_tracking(self, code, status_update): """ :param code: string @@ -783,7 +927,7 @@ def files_edit(self, file): def integration_module(self, code): """ - :param code: integer + :param code: string :return: Response """ @@ -798,6 +942,184 @@ def integration_module_edit(self, configuration): return self.post('/integration-modules/' + str(configuration['code']) + '/edit') + def integration_module_update_scopes(self, code, requires): + """ + :param code: string + :param requires: object + :return: Response + """ + self.parameters['requires'] = json.dumps(requires) + + return self.post('/integration-modules/' + str(code) + '/update-scopes') + + def loyalty_account_create(self, site, loyalty_account): + """ + :param site: string + :param loyalty_account: object + :return: Response + """ + self.parameters['site'] = site + self.parameters['loyaltyAccount'] = json.dumps(loyalty_account) + + return self.post('/loyalty/account/create') + + def loyalty_account(self, uid): + """ + :param uid: integer + :return: Response + """ + + return self.get('/loyalty/account/' + str(uid)) + + def loyalty_account_activate(self, uid): + """ + :param uid: integer + :return: Response + """ + + return self.post('/loyalty/account/' + str(uid) + '/activate') + + def loyalty_account_bonus_charge(self, uid, amount, comment): + """ + :param uid: integer + :param amount: float + :param comment: string + :return: Response + """ + self.parameters['amount'] = amount + self.parameters['comment'] = comment + + return self.post('/loyalty/account/' + str(uid) + '/bonus/charge') + + def loyalty_account_bonus_credit(self, uid, amount, activation_date, expire_date, comment): + """ + :param uid: integer + :param amount: float + :param activation_date: date (Y-m-d) + :param expire_date: date (Y-m-d) + :param comment: string + :return: Response + """ + self.parameters['amount'] = amount + self.parameters['activationDate'] = activation_date + self.parameters['expireDate'] = expire_date + self.parameters['comment'] = comment + + return self.post('/loyalty/account/' + str(uid) + '/bonus/credit') + + def loyalty_account_bonus_operations(self, uid, filters=None, limit=20, page=1): + """ + :param uid: integer + :param filters: object + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + + return self.get('/loyalty/account/' + str(uid) + '/bonus/operations') + + def loyalty_account_bonus_details(self, uid, status, filters=None, limit=20, page=1): + """ + :param uid: integer + :param status: string + :param filters: object + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + + return self.get('/loyalty/account/' + str(uid) + '/bonus/' + str(status) + '/details') + + def loyalty_account_edit(self, uid, loyalty_account): + """ + :param uid: integer + :param loyalty_account: object + :return: Response + """ + self.parameters['loyaltyAccount'] = json.dumps(loyalty_account) + + return self.post('/loyalty/account/' + str(uid) + '/edit') + + def loyalty_accounts(self, filters=None, limit=20, page=1): + """ + :param filters: object + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + + return self.get('/loyalty/accounts') + + def loyalty_bonus_operations(self, filters=None, limit=20, cursor=None): + """ + :param filters: object + :param limit: integer + :param cursor: string + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + + if cursor: + self.parameters['cursor'] = cursor + + return self.get('/loyalty/bonus/operations') + + def loyalty_calculate(self, order, site=None, bonuses=0): + """ + :param order: object + :param site: string + :param bonuses: float + :return: Response + """ + self.parameters['order'] = json.dumps(order) + + if site is not None: + self.parameters['site'] = site + + self.parameters['bonuses'] = bonuses + + return self.post('/loyalty/calculate') + + def loyalty_loyalties(self, filters=None, limit=20, page=1): + """ + :param filters: object + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + + return self.get('/loyalty/loyalties') + + def loyalty_loyalty(self, uid): + """ + :param uid: integer + :return: Response + """ + + return self.get('/loyalty/loyalties/' + str(uid)) + + def notifications_send(self, notification): + """ + :param notification: object + :return: Response + """ + self.parameters['notification'] = json.dumps(notification) + + return self.post('/notifications/send') + def orders(self, filters=None, limit=20, page=1): """ :param filters: object @@ -876,6 +1198,36 @@ def order_links_create(self, link, site=None): return self.post('/orders/links/create') + def orders_loyalty_apply(self, order, site=None, bonuses=0): + """ + :param order: object + :param site: string + :param bonuses: float + :return: Response + """ + self.parameters['order'] = json.dumps(order) + + if site is not None: + self.parameters['site'] = site + + if bonuses != 0: + self.parameters['bonuses'] = bonuses + + return self.post('/orders/loyalty/apply') + + def orders_loyalty_cancel_bonus_operations(self, order, site=None): + """ + :param order: object + :param site: string + :return: Response + """ + self.parameters['order'] = json.dumps(order) + + if site is not None: + self.parameters['site'] = site + + return self.post('/orders/loyalty/cancel-bonus-operations') + def order_payment_create(self, payment, site=None): """ :param payment: object @@ -951,6 +1303,19 @@ def order(self, uid, uid_type='externalId', site=None): return self.get('/orders/' + str(uid)) + def orders_delivery_cancel(self, uid, uid_type='externalId', force='false'): + """ + :param uid: string + :param uid_type: string + :param force: string + """ + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + self.parameters['force'] = force + + return self.post('/orders/' + str(uid) + '/delivery/cancel') + def order_edit(self, order, uid_type='externalId', site=None): """ :param order: object @@ -968,6 +1333,22 @@ def order_edit(self, order, uid_type='externalId', site=None): return self.post('/orders/' + str(order[uid_type]) + '/edit') + def orders_plates_print(self, uid, plate_id, uid_type='externalId', site=None): + """ + :param uid: string + :param plate_id: integer + :param uid_type: string + :param site: string + :return: Response + """ + if site is not None: + self.parameters['site'] = site + + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + return self.get('/orders/' + str(uid) + '/plates/' + str(plate_id) + '/print') + def packs(self, filters=None, limit=20, page=1): """ :param filters: object @@ -1019,6 +1400,15 @@ def pack_delete(self, uid): return self.post('/orders/packs/' + str(uid) + '/delete') + def pack_edit(self, pack): + """ + :param pack: object + :return: Response + """ + self.parameters['pack'] = json.dumps(pack) + + return self.post('/orders/packs/' + str(pack['id']) + '/edit') + def payment_check(self, check): """ :param check: object @@ -1037,23 +1427,31 @@ def payment_create_invoice(self, create_invoice): return self.post('/payment/create-invoice') - def payment_update_invoice(self, update_invoice): + def payment_invoice_import(self, invoice): """ - :param update_invoice: object + :param invoice: object :return: Response """ - self.parameters['updateInvoice'] = json.dumps(update_invoice) + self.parameters['invoice'] = json.dumps(invoice) - return self.post('/payment/update-invoice') + return self.post('/payment/invoice/import') - def pack_edit(self, pack): + def payment_invoice(self, uid): """ - :param pack: object + :param uid: string :return: Response """ - self.parameters['pack'] = json.dumps(pack) - return self.post('/orders/packs/' + str(pack['id']) + '/edit') + return self.get('/payment/invoice/' + str(uid)) + + def payment_update_invoice(self, update_invoice): + """ + :param update_invoice: object + :return: Response + """ + self.parameters['updateInvoice'] = json.dumps(update_invoice) + + return self.post('/payment/update-invoice') def cost_groups(self): """ @@ -1085,7 +1483,7 @@ def cost_items_edit(self, cost_item): """ self.parameters['costItem'] = json.dumps(cost_item) - return self.post('/reference/cost-groups/' + cost_item['code'] + '/edit') + return self.post('/reference/cost-items/' + cost_item['code'] + '/edit') def countries(self): """ @@ -1119,6 +1517,31 @@ def couriers_edit(self, courier): return self.post('/reference/couriers/' + str(courier['id']) + '/edit') + def currencies(self): + """ + :return: Response + """ + + return self.get('/reference/currencies') + + def currencies_create(self, currency): + """ + :param currency: object + :return: Response + """ + self.parameters['currency'] = json.dumps(currency) + + return self.post('/reference/currencies/create') + + def currencies_edit(self, currency): + """ + :param currency: object + :return: Response + """ + self.parameters['currency'] = json.dumps(currency) + + return self.post('/reference/currencies/' + str(currency['id']) + '/edit') + def delivery_services(self): """ :return: Response @@ -1326,6 +1749,24 @@ def stores_edit(self, store): return self.post('/reference/stores/' + store['code'] + '/edit') + def subscriptions(self): + """ + :return: Response + """ + + return self.get('/reference/subscriptions') + + def subscriptions_edit(self, channel, code, subscription): + """ + :param channel: string + :param code: string + :param subscription: object + :return: Response + """ + self.parameters['subscription'] = json.dumps(subscription) + + return self.post('/reference/subscriptions/' + str(channel) + '/' + str(code) + '/edit') + def units(self): """ :return: Response @@ -1355,6 +1796,13 @@ def segments(self, filters=None, limit=20, page=1): return self.get('/segments') + def settings(self): + """ + :return: Response + """ + + return self.get('/settings') + def inventories(self, filters=None, limit=20, page=1): """ :param filters: object @@ -1416,6 +1864,33 @@ def product_groups(self, filters=None, limit=20, page=1): return self.get('/store/product-groups') + def product_groups_create(self, productGroup): + """ + :param productGroup: object + :return: Response + """ + self.parameters['productGroup'] = json.dumps(productGroup) + + return self.post('/store/product-groups/create') + + def product_groups_edit(self, uid, productGroup, uid_type='externalId', site=None): + """ + :param uid: string + :param productGroup: object + :param uid_type: string + :param site: string + :return: Response + """ + self.parameters['productGroup'] = json.dumps(productGroup) + + if uid_type != 'externalId': + self.parameters['by'] = uid_type + + if site is not None: + self.parameters['site'] = site + + return self.post('/store/product-groups/' + str(uid) + '/edit') + def products(self, filters=None, limit=20, page=1): """ :param filters: object @@ -1429,6 +1904,24 @@ def products(self, filters=None, limit=20, page=1): return self.get('/store/products') + def products_batch_create(self, products): + """ + :param products: array of objects + :return: Response + """ + self.parameters['products'] = json.dumps(products) + + return self.post('/store/products/batch/create') + + def products_batch_edit(self, products): + """ + :param products: array of objects + :return: Response + """ + self.parameters['products'] = json.dumps(products) + + return self.post('/store/products/batch/edit') + def products_properties(self, filters=None, limit=20, page=1): """ :param filters: object @@ -1442,6 +1935,19 @@ def products_properties(self, filters=None, limit=20, page=1): return self.get('/store/products/properties') + def products_properties_values(self, filters=None, limit=20, page=1): + """ + :param filters: object + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + + return self.get('/store/products/properties/values') + def tasks(self, filters=None, limit=20, page=1): """ :param filters: object @@ -1468,6 +1974,19 @@ def task_create(self, task, site=None): return self.post('/tasks/create') + def tasks_history(self, filters=None, limit=20, page=1): + """ + :param filters: object + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['filter'] = filters + self.parameters['limit'] = limit + self.parameters['page'] = page + + return self.get('/tasks/history') + def task(self, uid): """ :param uid: string @@ -1476,6 +1995,18 @@ def task(self, uid): return self.get('/tasks/' + str(uid)) + def tasks_comments(self, uid, limit=20, page=1): + """ + :param uid: string + :param limit: integer + :param page: integer + :return: Response + """ + self.parameters['limit'] = limit + self.parameters['page'] = page + + return self.get('/tasks/' + str(uid) + '/comments') + def task_edit(self, task, site=None): """ :param task: object @@ -1558,11 +2089,54 @@ def user_status(self, uid, status): :param status: string :return: Response """ - self.parameters['status'] = status return self.post('/users/' + str(uid) + '/status') + def verification_sms_confirm(self, verification): + """ + :param verification: object + :return: Response + """ + self.parameters['verification'] = json.dumps(verification) + + return self.post('/verification/sms/confirm') + + def verification_sms_status(self, check_id): + """ + :param check_id: string + :return: Response + """ + + return self.get('/verification/sms/' + str(check_id) + '/status') + + def web_analytics_client_ids_upload(self, client_ids): + """ + :param client_ids: array of objects + :return: Response + """ + self.parameters['clientIds'] = json.dumps(client_ids) + + return self.post('/web-analytics/client-ids/upload') + + def web_analytics_sources_upload(self, sources): + """ + :param sources: array of objects + :return: Response + """ + self.parameters['sources'] = json.dumps(sources) + + return self.post('/web-analytics/sources/upload') + + def web_analytics_visits_upload(self, visits): + """ + :param visits: array of objects + :return: Response + """ + self.parameters['visits'] = json.dumps(visits) + + return self.post('/web-analytics/visits/upload') + def statistic_update(self): """ :return: Response diff --git a/tests/v5_tests.py b/tests/v5_tests.py index dfe72c8..f036ebe 100644 --- a/tests/v5_tests.py +++ b/tests/v5_tests.py @@ -410,7 +410,7 @@ def test_cost(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_costs_delete_v5(self): + def test_costs_delete(self): """ V5 Test method costs_delete """ @@ -1051,6 +1051,29 @@ def test_customers_edit(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_customer_subscription(self): + """ + V5 Test method customer_subscription + """ + + uid = str(self.__customer['externalId']) + subscriptions = [{'channel': 'email', 'active': 'true', 'messageId': 1}] + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/customers/' + uid + '/subscriptions') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('subscriptions', subscriptions)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.customer_subscription(uid, subscriptions) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_customers_corporate(self): """ @@ -1124,14 +1147,14 @@ def test_customer_corporate_create(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def customers_corporate_fix_external_ids(self): + def test_customers_corporate_fix_external_ids(self): """ V5 Test method customers_corporate_fix_external_ids """ (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/customers-corporate/fix-external-ids') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .body(self.dictionaryEncode('customerCorporate', self.__customer_corporate['externalId'])) + .body(self.dictionaryEncode('customersCorporate', self.__customer_corporate['externalId'])) .reply(200) .headers(self.__header) .json({'success': 'true'}) @@ -1144,7 +1167,7 @@ def customers_corporate_fix_external_ids(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_customers_history_v5(self): + def test_customers_history(self): """ V5 Test method customers_corporate_history """ @@ -1642,6 +1665,170 @@ def test_customer_corporate_edit(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_customer_interaction_cart_clear(self): + """ + V5 Test method customer_interaction_cart_clear + """ + + site = 'test-org' + cart = {'customer': {'id': 9717}} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/customer-interaction/' + site + '/cart/clear') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('cart', cart)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.customer_interaction_cart_clear(site, cart) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_customer_interaction_cart_set(self): + """ + V5 Test method customer_interaction_cart_set + """ + + site = 'test-org' + cart = {'customer': {'id': 9717}, 'items': [{"quantity": 1, "offer": {"id": 1}}]} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/customer-interaction/' + site + '/cart/set') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('cart', cart)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.customer_interaction_cart_set(site, cart) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_customer_interaction_cart(self): + """ + V5 Test method customer_interaction_cart + """ + + site = 'test-org' + customer_id = str(self.__customer['externalId']) + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/customer-interaction/' + site + '/cart/' + customer_id) + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'cart': {'customer': {'id': 9717}, 'items': [{"quantity": 1, "offer": {"id": 1}}]}}) + ) + + response = self.client.customer_interaction_cart(site, customer_id) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_customer_interaction_favorites(self): + """ + V5 Test method customer_interaction_favorites + """ + + site = 'test-org' + customer_id = str(self.__customer['externalId']) + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/customer-interaction/' + site + '/favorites/' + customer_id) + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'favorites': []}) + ) + + response = self.client.customer_interaction_favorites(site, customer_id) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_customer_interaction_favorites_add(self): + """ + V5 Test method customer_interaction_favorites_add + """ + + site = 'test-org' + customer_id = str(self.__customer['externalId']) + favorite = {'offer': {'externalId': 'test-offer'}} + + (pook.post( + os.getenv('RETAILCRM_URL') + '/api/v5/customer-interaction/' + site + '/favorites/' + customer_id + '/add') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('favorite', favorite)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.customer_interaction_favorites_add(site, customer_id, favorite) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_customer_interaction_favorite_remove(self): + """ + V5 Test method customer_interaction_favorite_remove + """ + + site = 'test-org' + customer_id = str(self.__customer['externalId']) + favorite = {'offer': {'externalId': 'test-offer'}} + + (pook.post(os.getenv( + 'RETAILCRM_URL') + '/api/v5/customer-interaction/' + site + '/favorites/' + customer_id + '/remove') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('favorite', favorite)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.customer_interaction_favorite_remove(site, customer_id, favorite) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_delivery_calculate(self): + """ + V5 Test method delivery_calculate + """ + + deliveryTypeCodes = ['courier', 'pickup'] + order = {'items': [], 'delivery': {'address': {}}} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/delivery/calculate') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body( + self.dictionaryEncode('deliveryTypeCodes', deliveryTypeCodes) + '&' + self.dictionaryEncode('order', order)) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'deliveries': []}) + ) + + response = self.client.delivery_calculate(deliveryTypeCodes, order) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_delivery_tracking(self): """ @@ -2055,293 +2242,542 @@ def test_integration_module_edit(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders(self): + def test_integration_module_update_scopes(self): """ - V5 Test method orders + V5 Test method integration_module_update_scopes """ - (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders') - .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .params({'filter[city]': 'Moscow', 'filter[contragentType]': 'individual'}) - .reply(200) - .headers(self.__header) - .json( - { - 'success': 'true', - 'pagination': { - 'limit': 20, - 'totalCount': 2464, - 'currentPage': 1, - 'totalPageCount': 50 - }, - 'orders': [self.__order] - } - ) - ) + code = 'xxx' + requires = {'scopes': ['order_write', 'customer_write']} - response = self.client.orders({'city': 'Moscow', 'contragentType': 'individual'}) + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/integration-modules/' + code + '/update-scopes') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('requires', requires)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.integration_module_update_scopes(code, requires) pook.off() self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_combine(self): + def test_loyalty_account_create(self): """ - V5 Test method orders_combine + V5 Test method loyalty_account_create """ - order = {'id': 5604} + site = 'test-org' + loyalty_account = {'customer': {'id': 9717}, 'phoneNumber': '+79999999999'} - (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/combine') + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/create') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body('site=' + site + '&' + self.dictionaryEncode('loyaltyAccount', loyalty_account)) + .reply(201) + .headers(self.__header) + .json({'success': 'true', 'id': 7777}) + ) + + response = self.client.loyalty_account_create(site, loyalty_account) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_loyalty_account(self): + """ + V5 Test method loyalty_account + """ + + uid = '7777' + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/' + uid) + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'loyaltyAccount': {'id': 7777, 'phoneNumber': '+79999999999'}}) + ) + + response = self.client.loyalty_account(uid) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_loyalty_account_activate(self): + """ + V5 Test method loyalty_account_activate + """ + + uid = '7777' + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/' + uid + '/activate') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) .reply(200) .headers(self.__header) .json({'success': 'true'}) ) - response = self.client.orders_combine(order, order, 'merge') + response = self.client.loyalty_account_activate(uid) pook.off() self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_create(self): + def test_loyalty_account_bonus_charge(self): """ - V5 Test method orders_create + V5 Test method loyalty_account_bonus_charge """ - (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/create') + uid = '7777' + amount = 100.0 + comment = 'Test charge' + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/' + uid + '/bonus/charge') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .body(self.dictionaryEncode('order', self.__order)) - .reply(201) + .body('amount=100.0&comment=Test+charge') + .reply(200) .headers(self.__header) - .json({'success': 'true', 'id': 8888, 'order': self.__order}) + .json({'success': 'true'}) ) - response = self.client.order_create(self.__order) + response = self.client.loyalty_account_bonus_charge(uid, amount, comment) pook.off() self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_fix_external_ids(self): + def test_loyalty_account_bonus_credit(self): """ - V5 Test method orders_fix_external_ids + V5 Test method loyalty_account_bonus_credit """ - (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/fix-external-ids') + uid = '7777' + amount = 100.0 + activation_date = '2020-01-01' + expire_date = '2020-12-31' + comment = 'Test credit' + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/' + uid + '/bonus/credit') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .body(self.dictionaryEncode('orders', self.__order['externalId'])) + .body('amount=100.0&activationDate=2020-01-01&expireDate=2020-12-31&comment=Test+credit') .reply(200) .headers(self.__header) .json({'success': 'true'}) ) - response = self.client.orders_fix_external_ids(self.__order['externalId']) + response = self.client.loyalty_account_bonus_credit(uid, amount, activation_date, expire_date, comment) pook.off() self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_history(self): + def test_loyalty_account_bonus_operations(self): """ - V5 Test method orders_history + V5 Test method loyalty_account_bonus_operations """ - (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders/history') - .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .params( - { - 'filter[sinceId]': '1111', - 'filter[startDate]': '2016-01-07', - 'filter[endDate]': '2020-04-12' - } - ) - .reply(200) - .headers(self.__header) - .json( - { - 'success': 'true', - 'generatedAt': '2020-04-16 11:03:00', - 'history': [ - { - 'id': 7887, - 'createdAt': '2018-04-11 09:01:29', - 'created': 'true', - 'source': 'api', - 'field': 'status', - 'apiKey': { - 'current': 'false' - }, - 'oldValue': 'null', - 'newValue': { - 'code': 'new' - }, - 'order': { - 'slug': 9090, - 'summ': 0, - 'id': 9090, - 'number': '9090A', - 'externalId': 'v4321', - 'orderType': 'eshop-individual', - 'orderMethod': 'shopping-cart', - 'createdAt': '2018-04-11 09:01:29', - 'statusUpdatedAt': '2018-04-11 09:01:29', - 'totalSumm': 0, - 'prepaySum': 0, - 'purchaseSumm': 0, - 'markDatetime': '2018-04-11 09:01:29', - 'lastName': 'xxxx', - 'firstName': 'xxxx', - 'patronymic': 'xxxx', - 'email': 'maymayslt@example.com', - 'call': 'false', - 'expired': 'false', - 'customer': { - 'id': 5544, - 'isContact': 'false', - 'createdAt': '2018-04-11 09:01:29', - 'vip': 'false', - 'bad': 'false', - 'site': 'retailcrm-ru', - 'contragent': { - 'contragentType': 'individual' - }, - 'marginSumm': 0, - 'totalSumm': 0, - 'averageSumm': 0, - 'ordersCount': 1, - 'customFields': [], - 'personalDiscount': 0, - 'cumulativeDiscount': 0, - 'address': { - 'id': 3322 - }, - 'lastName': 'xxxx', - 'firstName': 'xxxx', - 'patronymic': 'xxxx', - 'email': 'maymays@example.com', - 'phones': [] - }, - 'contragent': { - 'contragentType': 'individual' - }, - 'delivery': { - 'cost': 0, - 'netCost': 0, - 'address': { - 'id': 2477, - 'countryIso': '' - } - }, - 'site': 'retailcrm-ru', - 'status': 'new', - 'items': [], - 'fromApi': 'true', - 'shipped': 'false', - 'customFields': [] - } - } - ] - } - ) - ) + uid = '7777' - response = self.client.orders_history( - { - 'sinceId': '1111', - 'startDate': '2016-01-07', - 'endDate': '2020-04-12' - } - ) + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/' + uid + '/bonus/operations') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'filter[createdAtFrom]': '2020-01-01'}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'bonusOperations': []}) + ) + + response = self.client.loyalty_account_bonus_operations(uid, {'createdAtFrom': '2020-01-01'}) pook.off() self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_statuses(self): + def test_loyalty_account_bonus_details(self): """ - V5 Test method orders_statuses + V5 Test method loyalty_account_bonus_details """ - (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders/statuses') - .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .params({'ids[]': '5604', 'externalIds[]': '5603'}) - .reply(200) - .headers(self.__header) - .json( - { - 'success': 'true', - 'orders': [ - { - 'id': '5604', - 'externalId': '5603', - 'status': 'new', - 'group': 'new' - } - ] - } - ) - ) + uid = '7777' + status = 'active' - response = self.client.orders_statuses([5604], [5603]) + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/' + uid + '/bonus/' + status + '/details') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'filter[createdAtFrom]': '2020-01-01'}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'bonusDetails': []}) + ) + + response = self.client.loyalty_account_bonus_details(uid, status, {'createdAtFrom': '2020-01-01'}) pook.off() self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_upload(self): + def test_loyalty_account_edit(self): """ - V5 Test method orders_upload + V5 Test method loyalty_account_edit """ - (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/upload') + uid = '7777' + loyalty_account = {'phoneNumber': '+79999999999'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/account/' + uid + '/edit') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('loyaltyAccount', loyalty_account)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.loyalty_account_edit(uid, loyalty_account) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_loyalty_accounts(self): + """ + V5 Test method loyalty_accounts + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/accounts') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'filter[phoneNumber]': '+79999999999'}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'loyaltyAccounts': []}) + ) + + response = self.client.loyalty_accounts({'phoneNumber': '+79999999999'}) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_loyalty_bonus_operations(self): + """ + V5 Test method loyalty_bonus_operations + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/bonus/operations') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'filter[createdAtFrom]': '2020-01-01', 'cursor': 'test-cursor'}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'bonusOperations': []}) + ) + + response = self.client.loyalty_bonus_operations({'createdAtFrom': '2020-01-01'}, cursor='test-cursor') + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_loyalty_calculate(self): + """ + V5 Test method loyalty_calculate + """ + + order = {'items': [], 'customer': {'id': 9717}} + site = 'test-org' + bonuses = 100 + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/calculate') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('order', order) + '&site=test-org&bonuses=100') + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'calculation': {}}) + ) + + response = self.client.loyalty_calculate(order, site, bonuses) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_loyalty_loyalties(self): + """ + V5 Test method loyalty_loyalties + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/loyalties') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'filter[active]': 'true'}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'loyalties': []}) + ) + + response = self.client.loyalty_loyalties({'active': 'true'}) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_loyalty_loyalty(self): + """ + V5 Test method loyalty_loyalty + """ + + uid = '7777' + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/loyalty/loyalties/' + uid) + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'loyalty': {'id': 7777}}) + ) + + response = self.client.loyalty_loyalty(uid) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_notifications_send(self): + """ + V5 Test method notifications_send + """ + + notification = {'type': 'email', 'user': {'id': 15}, 'message': 'Test message'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/notifications/send') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('notification', notification)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.notifications_send(notification) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_orders(self): + """ + V5 Test method orders + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .body(self.dictionaryEncode('orders', self.__order)) - .reply(201) + .params({'filter[city]': 'Moscow', 'filter[contragentType]': 'individual'}) + .reply(200) .headers(self.__header) .json( { 'success': 'true', - 'uploadedOrders': [ - { - 'id': 5604, - 'externalId': '5603' - } - ], + 'pagination': { + 'limit': 20, + 'totalCount': 2464, + 'currentPage': 1, + 'totalPageCount': 50 + }, 'orders': [self.__order] } ) ) - response = self.client.orders_upload(self.__order) + response = self.client.orders({'city': 'Moscow', 'contragentType': 'individual'}) pook.off() self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_order(self): + def test_orders_combine(self): """ - V5 Test method order + V5 Test method orders_combine """ - uid = str(self.__order['externalId']) + order = {'id': 5604} - (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders/' + uid) + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/combine') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) .reply(200) .headers(self.__header) - .json({'success': 'true', 'orders': self.__order}) + .json({'success': 'true'}) + ) + + response = self.client.orders_combine(order, order, 'merge') + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_orders_create(self): + """ + V5 Test method orders_create + """ + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/create') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('order', self.__order)) + .reply(201) + .headers(self.__header) + .json({'success': 'true', 'id': 8888, 'order': self.__order}) ) - response = self.client.order(uid) + response = self.client.order_create(self.__order) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_orders_fix_external_ids(self): + """ + V5 Test method orders_fix_external_ids + """ + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/fix-external-ids') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('orders', self.__order['externalId'])) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.orders_fix_external_ids(self.__order['externalId']) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_orders_history(self): + """ + V5 Test method orders_history + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders/history') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params( + { + 'filter[sinceId]': '1111', + 'filter[startDate]': '2016-01-07', + 'filter[endDate]': '2020-04-12' + } + ) + .reply(200) + .headers(self.__header) + .json( + { + 'success': 'true', + 'generatedAt': '2020-04-16 11:03:00', + 'history': [ + { + 'id': 7887, + 'createdAt': '2018-04-11 09:01:29', + 'created': 'true', + 'source': 'api', + 'field': 'status', + 'apiKey': { + 'current': 'false' + }, + 'oldValue': 'null', + 'newValue': { + 'code': 'new' + }, + 'order': { + 'slug': 9090, + 'summ': 0, + 'id': 9090, + 'number': '9090A', + 'externalId': 'v4321', + 'orderType': 'eshop-individual', + 'orderMethod': 'shopping-cart', + 'createdAt': '2018-04-11 09:01:29', + 'statusUpdatedAt': '2018-04-11 09:01:29', + 'totalSumm': 0, + 'prepaySum': 0, + 'purchaseSumm': 0, + 'markDatetime': '2018-04-11 09:01:29', + 'lastName': 'xxxx', + 'firstName': 'xxxx', + 'patronymic': 'xxxx', + 'email': 'maymayslt@example.com', + 'call': 'false', + 'expired': 'false', + 'customer': { + 'id': 5544, + 'isContact': 'false', + 'createdAt': '2018-04-11 09:01:29', + 'vip': 'false', + 'bad': 'false', + 'site': 'retailcrm-ru', + 'contragent': { + 'contragentType': 'individual' + }, + 'marginSumm': 0, + 'totalSumm': 0, + 'averageSumm': 0, + 'ordersCount': 1, + 'customFields': [], + 'personalDiscount': 0, + 'cumulativeDiscount': 0, + 'address': { + 'id': 3322 + }, + 'lastName': 'xxxx', + 'firstName': 'xxxx', + 'patronymic': 'xxxx', + 'email': 'maymays@example.com', + 'phones': [] + }, + 'contragent': { + 'contragentType': 'individual' + }, + 'delivery': { + 'cost': 0, + 'netCost': 0, + 'address': { + 'id': 2477, + 'countryIso': '' + } + }, + 'site': 'retailcrm-ru', + 'status': 'new', + 'items': [], + 'fromApi': 'true', + 'shipped': 'false', + 'customFields': [] + } + } + ] + } + ) + ) + + response = self.client.orders_history( + { + 'sinceId': '1111', + 'startDate': '2016-01-07', + 'endDate': '2020-04-12' + } + ) pook.off() self.assertTrue(response.is_successful(), True) @@ -2383,6 +2819,53 @@ def test_order_links_create(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_orders_loyalty_apply(self): + """ + V5 Test method orders_loyalty_apply + """ + + order = {'id': 5604, 'items': []} + site = 'test-org' + bonuses = 100 + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/loyalty/apply') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('order', order) + '&site=test-org&bonuses=100') + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.orders_loyalty_apply(order, site, bonuses) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_orders_loyalty_cancel_bonus_operations(self): + """ + V5 Test method orders_loyalty_cancel_bonus_operations + """ + + order = {'id': 5604} + site = 'test-org' + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/loyalty/cancel-bonus-operations') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('order', order) + '&site=test-org') + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.orders_loyalty_cancel_bonus_operations(order, site) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_order_payment_create(self): """ @@ -2460,7 +2943,7 @@ def test_order_payment_edit(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_statuses_v5(self): + def test_orders_statuses(self): """ V5 Test method orders_statuses """ @@ -2475,7 +2958,7 @@ def test_orders_statuses_v5(self): 'success': 'true', 'orders': [ { - 'id': 5604, + 'id': '5604', 'externalId': '5603', 'status': 'new', 'group': 'new' @@ -2492,7 +2975,7 @@ def test_orders_statuses_v5(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_orders_upload_v5(self): + def test_orders_upload(self): """ V5 Test method orders_upload """ @@ -2523,7 +3006,7 @@ def test_orders_upload_v5(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def test_order_v5(self): + def test_order(self): """ V5 Test method order """ @@ -2543,6 +3026,28 @@ def test_order_v5(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_orders_delivery_cancel(self): + """ + V5 Test method orders_delivery_cancel + """ + + uid = str(self.__order['externalId']) + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/' + uid + '/delivery/cancel') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body('force=false') + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.orders_delivery_cancel(uid) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_orders_edit(self): """ @@ -2565,6 +3070,112 @@ def test_orders_edit(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_orders_plates_print(self): + """ + V5 Test method orders_plates_print + """ + + uid = str(self.__order['externalId']) + plate_id = '7777' + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders/' + uid + '/plates/' + plate_id + '/print') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.orders_plates_print(uid, plate_id) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_orders_statuses(self): + """ + V5 Test method orders_statuses + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders/statuses') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'ids[]': '5604', 'externalIds[]': '5603'}) + .reply(200) + .headers(self.__header) + .json( + { + 'success': 'true', + 'orders': [ + { + 'id': 5604, + 'externalId': '5603', + 'status': 'new', + 'group': 'new' + } + ] + } + ) + ) + + response = self.client.orders_statuses([5604], [5603]) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_orders_upload(self): + """ + V5 Test method orders_upload + """ + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/orders/upload') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('orders', self.__order)) + .reply(201) + .headers(self.__header) + .json( + { + 'success': 'true', + 'uploadedOrders': [ + { + 'id': 5604, + 'externalId': '5603' + } + ], + 'orders': [self.__order] + } + ) + ) + + response = self.client.orders_upload(self.__order) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_order(self): + """ + V5 Test method order + """ + + uid = str(self.__order['externalId']) + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/orders/' + uid) + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'orders': self.__order}) + ) + + response = self.client.order(uid) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_packs(self): """ @@ -2772,6 +3383,49 @@ def test_payment_create_invoice(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_payment_invoice_import(self): + """ + V5 Test method payment_invoice_import + """ + + invoice = {'invoiceUuid': '577', 'amount': 1000, 'currency': 'RUB'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/payment/invoice/import') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('invoice', invoice)) + .reply(201) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.payment_invoice_import(invoice) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_payment_invoice(self): + """ + V5 Test method payment_invoice + """ + + uid = '577' + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/payment/invoice/' + uid) + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'invoice': {'invoiceUuid': '577'}}) + ) + + response = self.client.payment_invoice(uid) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_payment_update_invoice(self): """ @@ -2908,7 +3562,7 @@ def test_cost_items_edit(self): item = {'code': 'cost-it-example', 'name': 'CostItem-example', 'ordering': 990, 'active': 'true'} - (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/reference/cost-groups/' + item['code'] + '/edit') + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/reference/cost-items/' + item['code'] + '/edit') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) .body(self.dictionaryEncode('costItem', item)) .reply(200) @@ -3026,15 +3680,78 @@ def test_couriers_edit(self): 'email': 'r9z4o@example.com' } - (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/reference/couriers/' + str(courier['id']) + '/edit') + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/reference/couriers/' + str(courier['id']) + '/edit') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('courier', courier)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.couriers_edit(courier) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_currencies(self): + """ + V5 Test method currencies + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/reference/currencies') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'currencies': [{'code': 'RUB', 'name': 'Рубль'}]}) + ) + + response = self.client.currencies() + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_currencies_create(self): + """ + V5 Test method currencies_create + """ + + currency = {'code': 'EUR', 'name': 'Euro', 'symbol': '€'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/reference/currencies/create') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('currency', currency)) + .reply(201) + .headers(self.__header) + .json({'success': 'true', 'id': 8888}) + ) + + response = self.client.currencies_create(currency) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_currencies_edit(self): + """ + V5 Test method currencies_edit + """ + + currency = {'id': 8888, 'code': 'EUR', 'name': 'Euro', 'symbol': '€'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/reference/currencies/' + str(currency['id']) + '/edit') .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) - .body(self.dictionaryEncode('courier', courier)) + .body(self.dictionaryEncode('currency', currency)) .reply(200) .headers(self.__header) .json({'success': 'true'}) ) - response = self.client.couriers_edit(courier) + response = self.client.currencies_edit(currency) pook.off() self.assertTrue(response.is_successful(), True) @@ -3891,6 +4608,49 @@ def test_stores_edit(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_subscriptions(self): + """ + V5 Test method subscriptions + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/reference/subscriptions') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'subscriptions': {}}) + ) + + response = self.client.subscriptions() + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_subscriptions_edit(self): + """ + V5 Test method subscriptions_edit + """ + + channel = 'email' + code = 'order_created' + subscription = {'active': 'true', 'name': 'marketing'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/reference/subscriptions/' + channel + '/' + code + '/edit') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('subscription', subscription)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.subscriptions_edit(channel, code, subscription) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_units(self): """ @@ -4002,6 +4762,86 @@ def test_segments(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_settings(self): + """ + V5 Test method settings + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/settings') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json( + { + 'success': 'true', + 'settings': { + "default_currency": { + "value": "EUR", + "updated_at": "2025-01-10 06:48:41" + }, + "system_language": { + "value": "EN", + "updated_at": "2025-10-29 18:49:05" + }, + "timezone": { + "value": "Europe/Madrid", + "updated_at": "2025-07-24 01:17:09" + }, + "work_times": [ + { + "day_type": "Tuesday", + "start_time": "08:00", + "end_time": "20:00", + "lunch_start_time": "18:00", + "lunch_end_time": "19:00" + }, + { + "day_type": "Wednesday", + "start_time": "10:00", + "end_time": "21:00" + }, + { + "day_type": "Friday", + "start_time": "10:00", + "end_time": "21:00" + }, + { + "day_type": "Saturday", + "start_time": "12:00", + "end_time": "13:00" + } + ], + "non_working_days": [ + { + "start_date": "05.01", + "end_date": "05.04" + } + ], + "mg": { + "order_creation": { + "default": { + "site": "central", + "order_type": "eshop", + "order_method": "messenger" + }, + "channels": { + "1": { + "site": "central" + }, + } + } + } + } + }) + ) + + response = self.client.settings() + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_inventories(self): """ @@ -4210,6 +5050,51 @@ def test_product_groups(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_product_groups_create(self): + """ + V5 Test method product_groups_create + """ + + product_group = {'name': 'Test Group', 'site': 'test-org', 'externalId': 'group-1'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/store/product-groups/create') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('productGroup', product_group)) + .reply(201) + .headers(self.__header) + .json({'success': 'true', 'id': 7777}) + ) + + response = self.client.product_groups_create(product_group) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_product_groups_edit(self): + """ + V5 Test method product_groups_edit + """ + + uid = 'group-1' + product_group = {'name': 'Test Group Updated', 'externalId': 'group-1'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/store/product-groups/' + uid + '/edit') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('productGroup', product_group)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.product_groups_edit(uid, product_group) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_products(self): """ @@ -4284,6 +5169,50 @@ def test_products(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_products_batch_create(self): + """ + V5 Test method products_batch_create + """ + + products = [{'name': 'Test Product', 'externalId': 'prod-1'}] + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/store/products/batch/create') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('products', products)) + .reply(201) + .headers(self.__header) + .json({'success': 'true', 'processedProductsCount': 1}) + ) + + response = self.client.products_batch_create(products) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_products_batch_edit(self): + """ + V5 Test method products_batch_edit + """ + + products = [{'name': 'Test Product Updated', 'externalId': 'prod-1'}] + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/store/products/batch/edit') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('products', products)) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'processedProductsCount': 1}) + ) + + response = self.client.products_batch_edit(products) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_products_properties(self): """ @@ -4343,6 +5272,26 @@ def test_products_properties(self): self.assertTrue(response.is_successful(), True) + @pook.on + def test_products_properties_values(self): + """ + V5 Test method products_properties_values + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/store/products/properties/values') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'filter[property]': 'color'}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'propertyValues': []}) + ) + + response = self.client.products_properties_values({'property': 'color'}) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_tasks(self): """ @@ -4414,6 +5363,26 @@ def test_task_create(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_tasks_history(self): + """ + V5 Test method tasks_history + """ + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/tasks/history') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .params({'filter[startDate]': '2020-01-01', 'filter[endDate]': '2020-12-31'}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'history': []}) + ) + + response = self.client.tasks_history({'startDate': '2020-01-01', 'endDate': '2020-12-31'}) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_task(self): """ @@ -4435,6 +5404,27 @@ def test_task(self): self.assertTrue(response.is_successful(), True) self.assertTrue(response.get_status_code() < 400, True) + @pook.on + def test_tasks_comments(self): + """ + V5 Test method tasks_comments + """ + + uid = str(self.__task['id']) + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/tasks/' + uid + '/comments') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'comments': []}) + ) + + response = self.client.tasks_comments(uid) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + @pook.on def test_task_edit(self): """ @@ -4708,7 +5698,116 @@ def test_user_status(self): self.assertTrue(response.get_status_code() < 400, True) @pook.on - def statistic_update(self): + def test_verification_sms_confirm(self): + """ + V5 Test method verification_sms_confirm + """ + + verification = {'checkId': '777', 'code': '1234'} + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/verification/sms/confirm') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('verification', verification)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.verification_sms_confirm(verification) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_verification_sms_status(self): + """ + V5 Test method verification_sms_status + """ + + check_id = '777' + + (pook.get(os.getenv('RETAILCRM_URL') + '/api/v5/verification/sms/' + check_id + '/status') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .reply(200) + .headers(self.__header) + .json({'success': 'true', 'status': 'confirmed'}) + ) + + response = self.client.verification_sms_status(check_id) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_web_analytics_client_ids_upload(self): + """ + V5 Test method web_analytics_client_ids_upload + """ + + client_ids = [{'customer': {'id': 9717}, 'clientId': 'test-client-id'}] + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/web-analytics/client-ids/upload') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('clientIds', client_ids)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.web_analytics_client_ids_upload(client_ids) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_web_analytics_sources_upload(self): + """ + V5 Test method web_analytics_sources_upload + """ + + sources = [{'customer': {'id': 9717}, 'source': 'google'}] + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/web-analytics/sources/upload') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('sources', sources)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.web_analytics_sources_upload(sources) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_web_analytics_visits_upload(self): + """ + V5 Test method web_analytics_visits_upload + """ + + visits = [{'customer': {'id': 9717}, 'visitDate': '2020-01-01'}] + + (pook.post(os.getenv('RETAILCRM_URL') + '/api/v5/web-analytics/visits/upload') + .headers({'X-API-KEY': os.getenv('RETAILCRM_KEY')}) + .body(self.dictionaryEncode('visits', visits)) + .reply(200) + .headers(self.__header) + .json({'success': 'true'}) + ) + + response = self.client.web_analytics_visits_upload(visits) + pook.off() + + self.assertTrue(response.is_successful(), True) + self.assertTrue(response.get_status_code() < 400, True) + + @pook.on + def test_statistic_update(self): """ V5 Test method statistic_update """ From 7bd2bf513bdbb51a7ad7710274ef8e65533a726a Mon Sep 17 00:00:00 2001 From: Alex Komarichev Date: Wed, 12 Nov 2025 19:48:31 +0300 Subject: [PATCH 2/2] decreased "requests" version for old python versions --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2200c14..d239cd3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ readme = "README.md" requires-python = ">=3.8" dependencies = [ "multidimensional-urlencode==0.0.4", - "requests~=2.32.5", + "requests~=2.32.4", ] classifiers = [