/// <summary> /// Creates the new OAuth session as well as getting the AccessToken for that Session. /// Here instead of getting the Access Token by exchanging RequestTokens, we are able to just pull it from storage /// </summary> /// <param name="currentBusinessAccount">The current business account.</param> /// <returns> /// Oath Session with the AccessToken held within it /// </returns> public static OAuthSession CreateOAuthSessionAndAccessToken(BusinessAccount currentBusinessAccount) { //Generates the consumer context based on the constants for our IntuitAnywhere App //In this case the Consumer is actually FoundOps var consumerContext = new OAuthConsumerContext { ConsumerKey = OauthConstants.ConsumerKey, SignatureMethod = SignatureMethod.HmacSha1, ConsumerSecret = OauthConstants.ConsumerSecret }; //Generates the OAuth session based on the constants for our IntuitAnywhere App and the ConsumerContext created above OAuthSession oSession = new OAuthSession(consumerContext, OauthConstants.IdFedOAuthBaseUrl + OauthConstants.UrlRequestToken, OauthConstants.AuthorizeUrl, OauthConstants.IdFedOAuthBaseUrl + OauthConstants.UrlAccessToken); oSession.ConsumerContext.UseHeaderForOAuthParameters = true; //Access Token is generated from storage here and saved into the OauthSession oSession.AccessToken = new TokenBase { Token = currentBusinessAccount.QuickBooksAccessToken, ConsumerKey = OauthConstants.ConsumerKey, TokenSecret = currentBusinessAccount.QuickBooksAccessTokenSecret }; return oSession; }
/// <summary> /// Makes a call to the QuickBooks Online Data Services to delete the specified invoice /// </summary> /// <param name="currentBusinessAccount">The current business account.</param> /// <param name="currentInvoice">The current invoice.</param> public static void DeleteInvoice(BusinessAccount currentBusinessAccount, Invoice currentInvoice) { var quickBooksSession = SerializationTools.Deserialize<QuickBooksSession>(currentBusinessAccount.QuickBooksSessionXml); //URL for the QuickBooks DataService for getting the deleting an Invoice //Here we are accessing QuickBooks Online data var serviceEndPoint = String.Format(quickBooksSession.BaseUrl + @"/resource/invoice/v2/" + quickBooksSession.RealmId + "/" + currentInvoice.CustomerId + "?methodx=delete"); var oSession = CreateOAuthSessionAndAccessToken(currentBusinessAccount); //Sets up the Post Request bus does not actually send it out IConsumerRequest consumerRequest = oSession.Request(); consumerRequest = consumerRequest.ForMethod("POST"); consumerRequest = consumerRequest.ForUri(new Uri(serviceEndPoint)); #region Generates the XML body of the Post call var filter = "Name=" + ":EQUALS:" + currentInvoice.Client.Name; var clientXML = GetEntityList(currentBusinessAccount, "customers", filter); var clientId = ""; //Splits the response XML into by line string[] responseArray = clientXML.Split('<'); //Checks each line for the one containing the BaseURL foreach (string s in responseArray) { if (s.Contains(":Id>")) { responseArray = s.Split('>'); clientId = responseArray[1]; break; } } var body = QuickBooksXml.InvoiceXml(currentInvoice, clientId, Operation.Delete); #endregion //Signs the Request consumerRequest = consumerRequest.SignWithToken(); //Sends the request with the body attached consumerRequest.Post().WithRawContentType("application/xml").WithRawContent(Encoding.ASCII.GetBytes((string)body)); //Reads the response XML var responseString = consumerRequest.ReadBody(); }
/// <summary> /// Creates the authorization URL for QuickBooks based on the OAuth session /// </summary> /// <param name="callbackUrl">The callback URL.</param> /// <param name="roleId">The role id.</param> /// <param name="currentBusinessAccount">The current bunsiness account.</param> /// <returns> returns the authorization URL. </returns> public static string GetAuthorizationUrl(string callbackUrl, string roleId, BusinessAccount currentBusinessAccount) { var session = CreateOAuthSession(); //Creates a new instance of the QuickBooksSession class to be later serialized into the Database var quickBooksSession = new QuickBooksSession { Token = (TokenBase)session.GetRequestToken() }; //Serializing the QuickBooks Session class into the Database currentBusinessAccount.QuickBooksSessionXml = SerializationTools.Serialize(quickBooksSession); //Creates the Authorized URL for QuickBooks that is based on the OAuth session created above var authUrl = OauthConstants.AuthorizeUrl + "?oauth_token=" + quickBooksSession.Token.Token + "&oauth_callback=" + UriUtility.UrlEncode(callbackUrl); return authUrl; }
/// <summary> /// Generates a call to the Intuit Partner Platform for get the Users Info /// Reads the response from that call and checks for an error code /// Based on whether there is an error or not, we determine if the user needs to authenticate their QuickBooks login information /// </summary> /// <param name="currentBusinessAccount">The current business account.</param> /// <returns> /// Boolean value that determines if the user needs to authenticate their QuickBooks login information /// </returns> public static bool GetUserInfo(BusinessAccount currentBusinessAccount) { //URL for the QuickBooks API for getting the Users Info //Here we are accessing the Intuit Partner Platform instead of QuickBooks Online data var serviceEndPoint = "https://workplace.intuit.com/db/main?a=API_GetUserInfo"; //Creates OAuth session and generates AccessToken var oSession = CreateOAuthSessionAndAccessToken(currentBusinessAccount); //Sends and signs the request to the Data Service IConsumerRequest conReq = oSession.Request().Get().ForUrl(serviceEndPoint).SignWithToken(); //OAuth parameters are needed in the header for this call conReq.Context.GenerateOAuthParametersForHeader(); //Reads the response XML var txtServiceResponse = conReq.ReadBody(); //Checks for an Error Code in the response XML if (!(txtServiceResponse.Contains("<errcode>0</errcode>"))) { //A return Value of true means that Authorization is needed return true; } #region Used for testing purposes only //GetInvoiceList(currentBusinessAccount); //var invoiceInfo = CreateNewInvoice(currentBusinessAccount); //UpdateInvoice(currentBusinessAccount, invoiceInfo); //var integer = Convert.ToInt32(invoiceInfo[1]); //integer++; //invoiceInfo[1] = integer.ToString(); //DeleteInvoice(currentBusinessAccount, invoiceInfo); #endregion //A return value of false means that the attempt at authorization has succeeded //No further action needs to be taken to access QuickBooks Online data return false; }
/// <summary> /// Makes a call to QuickBooks Data Services to get a list of invoices /// </summary> /// <param name="currentBusinessAccount">The current business account.</param> /// <param name="entityType">The type of QuickBooks Entity you want to get a list of</param> /// <param name="filter">Specifies the filter if one is provided</param> private static string GetEntityList(BusinessAccount currentBusinessAccount, string entityType, string filter = null) { var quickBooksSession = SerializationTools.Deserialize<QuickBooksSession>(currentBusinessAccount.QuickBooksSessionXml); //URL for the QuickBooks DataService for getting the List of Invoices //In this case we are only looking for the first 25 of them //Here we are accessing QuickBooks Online data var serviceEndPoint = String.Format(quickBooksSession.BaseUrl + @"/resource/" + entityType + "/v2/" + quickBooksSession.RealmId); var oSession = CreateOAuthSessionAndAccessToken(currentBusinessAccount); //Sets up the Post Request bus does not actually send it out IConsumerRequest consumerRequest = oSession.Request(); consumerRequest = consumerRequest.ForMethod("POST"); consumerRequest = consumerRequest.ForUrl(serviceEndPoint); //Sets up the filter to send back the first page with 25 results on it String completeFilter = filter; if (filter == null) completeFilter = "PageNum=" + 1 + "&ResultsPerPage=" + 25; //Converts the filter created above from a string to a dictionary //In order to send the filter as part of the request it needs to be a dictionary var paramCollection = new Dictionary<string, string>(); String[] splitParams = completeFilter.Split('&'); for (int i = 0; i < splitParams.Length; i++) { String[] nameValueSplit = splitParams[i].Split('='); paramCollection.Add(nameValueSplit[0], nameValueSplit[1]); } //Adds the parameters of sending back Page 1 with 25 invoices on it consumerRequest = consumerRequest.WithFormParameters(paramCollection); //Signs the Request consumerRequest = consumerRequest.SignWithToken(); //Sends the request with the body attached consumerRequest.Post().WithRawContentType("application/x-www-form-urlencoded").WithBody(completeFilter); //Reads the response XML return consumerRequest.ReadBody(); }
/// <summary> /// Exchanges the request token attained earlier for the access token needed to make calls to QuickBooks /// </summary> /// <param name="currentBusinessAccount">The current business account.</param> /// <param name="coreEntitiesContainer">The current CoreEntitiesContainer</param> public static void GetAccessToken(BusinessAccount currentBusinessAccount, CoreEntitiesContainer coreEntitiesContainer) { //Deserializes QuicBooksSessionXml from the Database to a quickBooksSession Class var quickBooksSession = SerializationTools.Deserialize<QuickBooksSession>(currentBusinessAccount.QuickBooksSessionXml); //Creates the OAuth Session var clientSession = CreateOAuthSession(); //The AccessToken is attained by exchanging the request token and the OAuthVerifier that we attained earlier IToken accessToken = clientSession.ExchangeRequestTokenForAccessToken(quickBooksSession.Token, quickBooksSession.OAuthVerifier); //Saving the Token to private storage currentBusinessAccount.QuickBooksAccessToken = accessToken.Token; currentBusinessAccount.QuickBooksAccessTokenSecret = accessToken.TokenSecret; coreEntitiesContainer.SaveChanges(); }
/// <summary> /// Finds the BaseURL for the current QuickBooks user /// </summary> /// <param name="currentBusinessAccount">The current business account.</param> /// <param name="coreEntitiesContainer">The core entities container.</param> public static void GetBaseUrl(BusinessAccount currentBusinessAccount, CoreEntitiesContainer coreEntitiesContainer) { var quickBooksSession = SerializationTools.Deserialize<QuickBooksSession>(currentBusinessAccount.QuickBooksSessionXml); //URL for the QuickBooks Data Service for getting the BaseURL var serviceEndPoint = String.Format("https://qbo.intuit.com/qbo1/rest/user/v2/" + quickBooksSession.RealmId); var oSession = CreateOAuthSessionAndAccessToken(currentBusinessAccount); //Sends and signs the request to the Data Service IConsumerRequest conReq = oSession.Request().Get().ForUrl(serviceEndPoint).SignWithToken(); //OAuth parameters are needed in the header for this call conReq.Context.GenerateOAuthParametersForHeader(); //Reads the response XML var responseString = conReq.ReadBody(); //Splits the response XML into by line string[] responseArray = responseString.Split('<'); //Checks each line for the one containing the BaseURL foreach (string s in responseArray) { if (s.Contains("qbo:BaseURI>")) { responseArray = s.Split('>'); quickBooksSession.BaseUrl = responseArray[1]; break; } } //Ensures that the BaseURL is saved for later use currentBusinessAccount.QuickBooksSessionXml = SerializationTools.Serialize(quickBooksSession); coreEntitiesContainer.SaveChanges(); }
public TaskStatus GetDefaultTaskStatus(BusinessAccount businessAccount, StatusDetail detail) { return businessAccount.TaskStatuses.FirstOrDefault(ts => ts.StatusDetails.Contains(detail)); }
/// <summary> /// Setup the employee link for a user account. /// If the employeeId is null or Empty, it will create a new Employee. /// Otherwise it will link the existing employee /// </summary> /// <param name="employeeId">The employee Id to link</param> /// <param name="userAccount">The user account</param> /// <param name="businessAccount">The business account</param> /// <param name="currentUserAccountId">For tracking</param> private void SetupEmployee(Guid? employeeId, Core.Models.CoreEntities.UserAccount userAccount, BusinessAccount businessAccount, Guid currentUserAccountId) { //clear any linked employees for this business account foreach (var oldEmployee in userAccount.LinkedEmployees.Where(e => e.EmployerId == businessAccount.Id).ToArray()) oldEmployee.LinkedUserAccountId = null; if (!employeeId.HasValue || employeeId.Value == Guid.Empty) //do not link the employee return; Employee employee; //add a new employee if (employeeId.Value == EntityTools.NewEntityId) { employee = new Employee { FirstName = userAccount.FirstName, LastName = userAccount.LastName, EmployerId = businessAccount.Id, CreatedDate = DateTime.UtcNow }; } //find the existing employee else { employee = CoreEntitiesContainer.Employees.First(e => e.Id == employeeId.Value); } //TODO CR Make extension method on ITrackable to do this employee.LastModified = DateTime.UtcNow; employee.LinkedUserAccountId = currentUserAccountId; employee.LinkedUserAccount = userAccount; }
/// <summary> /// Loads the Region associations from a set of rows. If there is not a region for a name it will create a new one. /// It uses the DataCategory.RegionName to find/create the regions. /// </summary> /// <param name="roleId">The role id.</param> /// <param name="serviceProvider">The service provider (in case this needs to create new regions).</param> /// <param name="rows">The import rows"</param> /// <returns></returns> private Region[] LoadCreateRegionAssociations(Guid roleId, BusinessAccount serviceProvider, IEnumerable<ImportRow> rows) { //Get the distinct region names from the rows' DataCategory.RegionName values var regionNamesToLoad = rows.Select(cvs => { var regionNameCategoryValue = cvs.FirstOrDefault(cv => cv.DataCategory == DataCategory.RegionName); return regionNameCategoryValue == null ? null : regionNameCategoryValue.Value; }).Distinct().Where(cn => cn != null).ToArray(); var loadedRegionsFromName = (from region in GetRegionsForServiceProvider(roleId) where regionNamesToLoad.Contains(region.Name) select region).ToArray(); //Create a new region for any region name that did not exist var newRegions = regionNamesToLoad.Except(loadedRegionsFromName.Select(r => r.Name)).Select(newRegionName => new Region { Id = Guid.NewGuid(), BusinessAccount = serviceProvider, Name = newRegionName }); return loadedRegionsFromName.Union(newRegions).ToArray(); }
/// <summary> /// Loads the client associations and names from a set of rows. /// It uses the DataCategory.ClientName to find the client. /// </summary> /// <param name="roleId">The current role id</param> /// <param name="businessAccount">The current business account</param> /// <param name="importRows">The import rows"</param> /// <param name="includeAvailableServices">if set to <c>true</c> [include client service templates].</param> private Client[] LoadClientAssociations(Guid roleId, BusinessAccount businessAccount, IEnumerable<ImportRow> importRows, bool includeAvailableServices) { //Get the distinct client names from the rows' DataCategory.ClientName values var clientNamesToLoad = importRows.Select(importRow => { var clientNameCategoryValue = importRow.FirstOrDefault(cv => cv.DataCategory == DataCategory.ClientName); return clientNameCategoryValue == null ? null : clientNameCategoryValue.Value; }).Distinct().Where(cn => cn != null).ToArray(); //TODO: When importing people clients, fix the ChildName logic below (probably setup 2 left joins) //Load all the associatedClients var associatedClients = (from client in ObjectContext.Clients.Where(c => c.BusinessAccountId == businessAccount.Id) where clientNamesToLoad.Contains(client.Name) select client).ToArray(); if (includeAvailableServices) { GetServiceProviderServiceTemplates(roleId).Where(st => st.LevelInt == (int)ServiceTemplateLevel.ServiceProviderDefined); } return associatedClients.ToArray(); }
/// <summary> /// Create a new BusinessAccount object. /// </summary> /// <param name="id">Initial value of the Id property.</param> /// <param name="createdDate">Initial value of the CreatedDate property.</param> /// <param name="intId">Initial value of the IntId property.</param> public static BusinessAccount CreateBusinessAccount(global::System.Guid id, global::System.DateTime createdDate, global::System.Int32 intId) { BusinessAccount businessAccount = new BusinessAccount(); businessAccount.Id = id; businessAccount.CreatedDate = createdDate; businessAccount.IntId = intId; return businessAccount; }