using Newtonsoft.Json; using RetailCrm.Http; using RetailCrm.Response; using System; using System.Collections.Generic; using System.Linq; namespace RetailCrm { public class ApiClient { private const string apiVersion = "v3"; protected Client client; /// /// Site code /// protected string siteCode; /// /// ApiClient creating /// /// /// /// public ApiClient(string url, string apiKey, string site = "") { if ("/" != url.Substring(url.Length - 1, 1)) { url += "/"; } url += "api/" + apiVersion; client = new Client(url, new Dictionary() { { "apiKey", apiKey } }); siteCode = site; } /// /// Create a order /// /// /// /// ApiResponse public ApiResponse ordersCreate(Dictionary order, string site = "") { if (order.Count < 1) { throw new ArgumentException("Parameter `order` must contains a data"); } return client.makeRequest( "/orders/create", Client.METHOD_POST, this.fillSite( site, new Dictionary() { { "order", JsonConvert.SerializeObject(order) } } ) ); } /// /// Edit a order /// /// /// /// /// ApiResponse public ApiResponse ordersEdit(Dictionary order, string by = "externalId", string site = "") { if (order.Count < 1) { throw new ArgumentException("Parameter `order` must contains a data"); } checkIdParameter(by); if (order.ContainsKey(by) == false) { throw new ArgumentException("Order array must contain the \"" + by + "\" parameter"); } return client.makeRequest( "/orders/" + order[by] + "/edit", Client.METHOD_POST, this.fillSite( site, new Dictionary() { { "order", JsonConvert.SerializeObject(order) }, { "by", by } } ) ); } /// /// Upload array of the orders /// /// /// /// ApiResponse public ApiResponse ordersUpload(Dictionary orders, string site = "") { if (orders.Count < 1) { throw new ArgumentException("Parameter `order` must contains a data"); } return client.makeRequest( "/orders/upload", Client.METHOD_POST, this.fillSite( site, new Dictionary() { { "orders", JsonConvert.SerializeObject(orders) } } ) ); } /// /// Get order by id or externalId /// /// /// /// /// ApiResponse public ApiResponse ordersGet(string id, string by = "externalId", string site = "") { checkIdParameter(by); return client.makeRequest( "/orders/" + id, Client.METHOD_GET, this.fillSite( site, new Dictionary() { { "by", by } } ) ); } /// /// Returns a orders history /// /// /// /// /// /// /// ApiResponse public ApiResponse ordersHistory( DateTime? startDate = null, DateTime? endDate = null, int limit = 100, int offset = 0, bool skipMyChanges = true ) { Dictionary parameters = new Dictionary(); if (startDate != null) { parameters.Add("startDate", startDate.Value.ToString("yyyy-MM-dd HH:mm:ss")); } if (endDate != null) { parameters.Add("endDate", endDate.Value.ToString("yyyy-MM-dd HH:mm:ss")); } if (limit > 0) { parameters.Add("limit", limit); } if (offset > 0) { parameters.Add("offset", offset); } if (skipMyChanges == true) { parameters.Add("skipMyChanges", skipMyChanges); } return client.makeRequest("/orders/history", Client.METHOD_GET, parameters); } /// /// Returns filtered orders list /// /// /// /// /// ApiResponse public ApiResponse ordersList(Dictionary filter = null, int page = 0, int limit = 0) { Dictionary parameters = new Dictionary(); if (filter.Count > 0) { parameters.Add("filter", filter); } if (page > 0) { parameters.Add("page", page); } if (limit > 0) { parameters.Add("limit", limit); } return client.makeRequest("/orders", Client.METHOD_GET, parameters); } /// /// Returns statuses of the orders /// /// /// /// ApiResponse public ApiResponse ordersStatuses(Dictionary ids = null, Dictionary externalIds = null) { Dictionary parameters = new Dictionary(); if (ids.Count > 0) { parameters.Add("ids", ids); } if (externalIds.Count > 0) { parameters.Add("externalIds", externalIds); } return client.makeRequest("/orders/statuses", Client.METHOD_GET, parameters); } /// /// Save order IDs' (id and externalId) association in the CRM /// /// /// ApiResponse public ApiResponse ordersFixExternalId(Dictionary ids) { if (ids.Count < 1) { throw new ArgumentException("Method parameter must contains at least one IDs pair"); } return client.makeRequest( "/orders/fix-external-ids", Client.METHOD_POST, new Dictionary() { { "orders", JsonConvert.SerializeObject(ids) } } ); } /// /// Create a customer /// /// /// /// ApiResponse public ApiResponse customersCreate(Dictionary customer, string site = "") { if (customer.Count < 1) { throw new ArgumentException("Parameter `customer` must contains a data"); } return client.makeRequest( "/customers/create", Client.METHOD_POST, this.fillSite( site, new Dictionary() { { "customer", JsonConvert.SerializeObject(customer) } } ) ); } /// /// Edit a customer /// /// /// /// /// ApiResponse public ApiResponse customersEdit(Dictionary customer, string by = "externalId", string site = "") { if (customer.Count < 1) { throw new ArgumentException("Parameter `customer` must contains a data"); } checkIdParameter(by); if (customer.ContainsKey(by) == false) { throw new ArgumentException("Customer array must contain the \"" + by + "\" parameter"); } return client.makeRequest( "/customers/" + customer[by] + "/edit", Client.METHOD_POST, this.fillSite( site, new Dictionary() { { "customer", JsonConvert.SerializeObject(customer) }, { "by", by } } ) ); } /// /// Upload array of the customers /// /// /// /// ApiResponse public ApiResponse customersUpload(Dictionary customers, string site = "") { if (customers.Count < 1) { throw new ArgumentException("Parameter `customers` must contains a data"); } return client.makeRequest( "/customers/upload", Client.METHOD_POST, this.fillSite( site, new Dictionary() { { "customers", JsonConvert.SerializeObject(customers) } } ) ); } /// /// Get customer by id or externalId /// /// /// /// /// ApiResponse public ApiResponse customersGet(string id, string by = "externalId", string site = "") { checkIdParameter(by); return client.makeRequest( "/customers/" + id, Client.METHOD_GET, this.fillSite( site, new Dictionary() { { "by", by } } ) ); } /// /// Returns filtered customers list /// /// /// /// /// ApiResponse public ApiResponse customersList(Dictionary filter = null, int page = 0, int limit = 0) { Dictionary parameters = new Dictionary(); if (filter.Count > 0) { parameters.Add("filter", filter); } if (page > 0) { parameters.Add("page", page); } if (limit > 0) { parameters.Add("limit", limit); } return client.makeRequest("/customers", Client.METHOD_GET, parameters); } /// /// Save customer IDs' (id and externalId) association in the CRM /// /// /// ApiResponse public ApiResponse customersFixExternalIds(Dictionary ids) { if (ids.Count < 1) { throw new ArgumentException("Method parameter must contains at least one IDs pair"); } return client.makeRequest( "/customers/fix-external-ids", Client.METHOD_POST, new Dictionary() { { "customers", JsonConvert.SerializeObject(ids) } } ); } /// /// Returns filtered orders packs list /// /// /// /// /// ApiResponse public ApiResponse packsList(Dictionary filter = null, int page = 0, int limit = 0) { Dictionary parameters = new Dictionary(); if (filter.Count > 0) { parameters.Add("filter", filter); } if (page > 0) { parameters.Add("page", page); } if (limit > 0) { parameters.Add("limit", limit); } return client.makeRequest("/orders/packs", Client.METHOD_GET, parameters); } /// /// Create a order pack /// /// /// ApiResponse public ApiResponse packsCreate(Dictionary pack) { if (pack.Count < 1) { throw new ArgumentException("Parameter `pack` must contains a data"); } return client.makeRequest( "/orders/packs/create", Client.METHOD_POST, new Dictionary() { { "pack", JsonConvert.SerializeObject(pack) } } ); } /// /// Returns a orders history /// /// /// /// /// ApiResponse public ApiResponse packsHistory(Dictionary filter = null, int page = 0, int limit = 0) { Dictionary parameters = new Dictionary(); if (filter.Count > 0) { parameters.Add("filter", filter); } if (page > 0) { parameters.Add("page", page); } if (limit > 0) { parameters.Add("limit", limit); } return client.makeRequest("/orders/packs/history", Client.METHOD_GET, parameters); } /// /// Get order packs by id /// /// /// ApiResponse public ApiResponse packsGet(string id) { return client.makeRequest("/orders/packs/" + id, Client.METHOD_GET); } /// /// Delete order packs by id /// /// /// ApiResponse public ApiResponse packsDelete(string id) { return client.makeRequest("/orders/packs/" + id + "/delete", Client.METHOD_POST); } /// /// Edit a order packs /// /// /// /// ApiResponse public ApiResponse packsEdit(string id, Dictionary pack) { if (pack.Count < 1) { throw new ArgumentException("Parameter `pack` must contains a data"); } return client.makeRequest( "/orders/packs/" + id + "/edit", Client.METHOD_POST, new Dictionary() { { "pack", JsonConvert.SerializeObject(pack) } } ); } /// /// Returns filtered store inventories list /// /// /// /// /// ApiResponse public ApiResponse inventoriesList(Dictionary filter = null, int page = 0, int limit = 0) { Dictionary parameters = new Dictionary(); if (filter.Count > 0) { parameters.Add("filter", filter); } if (page > 0) { parameters.Add("page", page); } if (limit > 0) { parameters.Add("limit", limit); } return client.makeRequest("/store/inventories", Client.METHOD_GET, parameters); } /// /// Upload array of the store inventories /// /// /// /// ApiResponse public ApiResponse inventoriesUpload(Dictionary offers, string site = "") { if (offers.Count < 1) { throw new ArgumentException("Parameter `offers` must contains a data"); } return client.makeRequest( "/store/inventories/upload", Client.METHOD_POST, this.fillSite( site, new Dictionary() { { "offers", JsonConvert.SerializeObject(offers) } } ) ); } /// /// Returns deliveryServices list /// /// ApiResponse public ApiResponse deliveryServicesList() { return client.makeRequest("/reference/delivery-services", Client.METHOD_GET); } /// /// Returns deliveryTypes list /// /// ApiResponse public ApiResponse deliveryTypesList() { return client.makeRequest("/reference/delivery-types", Client.METHOD_GET); } /// /// Returns orderMethods list /// /// ApiResponse public ApiResponse orderMethodsList() { return client.makeRequest("/reference/order-methods", Client.METHOD_GET); } /// /// Returns orderTypes list /// /// ApiResponse public ApiResponse orderTypesList() { return client.makeRequest("/reference/order-types", Client.METHOD_GET); } /// /// Returns paymentStatuses list /// /// ApiResponse public ApiResponse paymentStatusesList() { return client.makeRequest("/reference/payment-statuses", Client.METHOD_GET); } /// /// Returns paymentTypes list /// /// ApiResponse public ApiResponse paymentTypesList() { return client.makeRequest("/reference/payment-types", Client.METHOD_GET); } /// /// Returns productStatuses list /// /// ApiResponse public ApiResponse productStatusesList() { return client.makeRequest("/reference/product-statuses", Client.METHOD_GET); } /// /// Returns statusGroups list /// /// ApiResponse public ApiResponse statusGroupsList() { return client.makeRequest("/reference/status-groups", Client.METHOD_GET); } /// /// Returns statuses list /// /// ApiResponse public ApiResponse statusesList() { return client.makeRequest("/reference/statuses", Client.METHOD_GET); } /// /// Returns sites list /// /// ApiResponse public ApiResponse sitesList() { return client.makeRequest("/reference/sites", Client.METHOD_GET); } /// /// Returns stores list /// /// ApiResponse public ApiResponse storesList() { return client.makeRequest("/reference/stores", Client.METHOD_GET); } /// /// Returns countries list /// /// ApiResponse public ApiResponse countriesList() { return client.makeRequest("/reference/countries", Client.METHOD_GET); } /// /// Edit deliveryService /// /// /// ApiResponse public ApiResponse deliveryServicesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/delivery-services/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "deliveryService", JsonConvert.SerializeObject(data) } } ); } /// /// Edit deliveryType /// /// /// ApiResponse public ApiResponse deliveryTypesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/delivery-types/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "deliveryType", JsonConvert.SerializeObject(data) } } ); } /// /// Edit orderMethod /// /// /// ApiResponse public ApiResponse orderMethodsEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/order-methods/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "orderMethod", JsonConvert.SerializeObject(data) } } ); } /// /// Edit orderType /// /// /// ApiResponse public ApiResponse orderTypesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/order-types/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "orderType", JsonConvert.SerializeObject(data) } } ); } /// /// Edit paymentStatus /// /// /// ApiResponse public ApiResponse paymentStatusesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/payment-statuses/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "paymentStatus", JsonConvert.SerializeObject(data) } } ); } /// /// Edit paymentType /// /// /// ApiResponse public ApiResponse paymentTypesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/payment-types/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "paymentType", JsonConvert.SerializeObject(data) } } ); } /// /// Edit productStatus /// /// /// ApiResponse public ApiResponse productStatusesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/product-statuses/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "productStatus", JsonConvert.SerializeObject(data) } } ); } /// /// Edit order status /// /// /// ApiResponse public ApiResponse statusesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/statuses/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "status", JsonConvert.SerializeObject(data) } } ); } /// /// Edit site /// /// /// ApiResponse public ApiResponse sitesEdit(Dictionary data) { if (data.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/sites/" + data["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "site", JsonConvert.SerializeObject(data) } } ); } /// /// Edit stores /// /// /// ApiResponse public ApiResponse storesEdit(Dictionary store) { if (store.ContainsKey("code") == false) { throw new ArgumentException("Data must contain \"code\" parameter"); } return client.makeRequest( "/reference/stores/" + store["code"] + "/edit", Client.METHOD_POST, new Dictionary() { { "store", JsonConvert.SerializeObject(store) } } ); } /// /// Captures events call for the user /// /// /// /// /// /// ApiResponse public ApiResponse telephonyСallEventCreate(string phone, string type, string code, string hangupStatus) { Dictionary parameters = new Dictionary(); if (string.IsNullOrEmpty(phone)) { throw new ArgumentException("Parameter \"phone\" can not be empty"); } if (string.IsNullOrEmpty(type)) { throw new ArgumentException("Option \"type\" can not be empty. Valid values: in, out, hangup."); } if (string.IsNullOrEmpty(code)) { throw new ArgumentException("Option \"code\" can not be empty."); } parameters.Add("phone", phone); parameters.Add("type", type); parameters.Add("code", code); if (!string.IsNullOrEmpty(hangupStatus)) { parameters.Add("hangupStatus", hangupStatus); } return client.makeRequest("/telephony/call/event", Client.METHOD_POST, parameters); } /// /// It allows you to save your call history /// /// /// ApiResponse public ApiResponse telephonyСallsUpload(Dictionary calls) { return client.makeRequest( "/telephony/calls/upload", Client.METHOD_POST, new Dictionary() { { "calls", JsonConvert.SerializeObject(calls) } } ); } /// /// Returns the responsible manager for the client with the phone /// /// /// /// ApiResponse public ApiResponse telephonyManagerGet(string phone, bool details = false) { if (string.IsNullOrEmpty(phone)) { throw new ArgumentException("Parameter \"phone\" can not be empty"); } return client.makeRequest( "/telephony/manager", Client.METHOD_GET, new Dictionary() { { "phone", phone }, { "details", details } } ); } /// /// Allows you to create/activate/deactivate the phone in the system and specify the necessary settings for the job /// /// /// /// /// /// ApiResponse public ApiResponse telephonySettingEdit(string code, string clientId, string makeCallUrl, bool active = true) { Dictionary parameters = new Dictionary(); if (string.IsNullOrEmpty(code)) { throw new ArgumentException("Parameter \"code\" can not be empty"); } if (string.IsNullOrEmpty(clientId)) { throw new ArgumentException("Option \"clientId\" can not be empty."); } parameters.Add("code", code); parameters.Add("clientId", clientId); parameters.Add("active", active); if (!string.IsNullOrEmpty(makeCallUrl)) { parameters.Add("makeCallUrl", makeCallUrl); } return client.makeRequest("/telephony/setting/" + code, Client.METHOD_POST, parameters); } /// /// Update CRM basic statistic /// /// ApiResponse public ApiResponse statisticUpdate() { return client.makeRequest("/statistic/update", Client.METHOD_GET); } /// /// Return current site /// /// string public string getSite() { return this.siteCode; } /// /// Return current site /// public void setSite(string site) { this.siteCode = site; } /// /// Check ID parameter /// /// protected void checkIdParameter(string by) { string[] allowedForBy = new string[] { "externalId", "id" }; if (allowedForBy.Contains(by) == false) { throw new ArgumentException("Value \"" + by + "\" for parameter \"by\" is not valid. Allowed values are " + String.Join(", ", allowedForBy)); } } /// /// Fill params by site value /// /// /// /// Dictionary protected Dictionary fillSite(string site, Dictionary param) { if (site.Length > 1) { param.Add("site", site); } else if (siteCode.Length > 1) { param.Add("site", siteCode); } return param; } } }