public string RefreshSmartsheetToken() { Guid loggedUser = PXAccess.GetUserID(); Users usersRow = PXSelect <Users, Where <Users.pKID, Equal <Required <Users.pKID> > > > .Select(this.Base, loggedUser); UsersSSExt usersSSExtRow = PXCache <Users> .GetExtension <UsersSSExt>(usersRow); PMSetup setupRow = PXSelect <PMSetup> .Select(this.Base); PMSetupSSExt setupSSExtRow = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(setupRow); if (usersSSExtRow != null && usersSSExtRow.UsrSmartsheetRefreshToken != null) { List <string> ssToken = refreshToken(setupSSExtRow.UsrSmartsheetClientID, setupSSExtRow.UsrSmartsheetAppSecret, usersSSExtRow.UsrSmartsheetRefreshToken); if (ssToken.Count == 2) { usersSSExtRow.UsrSmartsheetToken = ssToken[0]; usersSSExtRow.UsrSmartsheetRefreshToken = ssToken[1]; this.Base.UserProfile.Update(usersRow); this.Base.Actions.PressSave(); return(usersSSExtRow.UsrSmartsheetToken); } } return(""); }
protected virtual void RequestSSToken() { PMSetup pmSetupRow = PXSelect <PMSetup> .Select(Base); PMSetupSSExt pmSetupSSExtRow = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(pmSetupRow); string loginScopeCompany = PXDatabase.Companies.Length > 0 ? PXAccess.GetCompanyName() : String.Empty; string currentScope = String.Format(",{0},{1}", Base.Accessinfo.UserName, loginScopeCompany); if (pmSetupSSExtRow != null && pmSetupSSExtRow.UsrSmartsheetClientID != null) { string smartsheetRedirect = SmartsheetConstants.SSCodeRequest.ENDPOINT; smartsheetRedirect += SmartsheetConstants.SSCodeRequest.RESPONSE_TYPE; smartsheetRedirect += SmartsheetConstants.SSCodeRequest.CLIENT_ID + pmSetupSSExtRow.UsrSmartsheetClientID; smartsheetRedirect += SmartsheetConstants.SSCodeRequest.SCOPE; smartsheetRedirect += SmartsheetConstants.SSCodeRequest.STATE + currentScope; throw new PXRedirectToUrlException(smartsheetRedirect, PXBaseRedirectException.WindowMode.InlineWindow, string.Empty, false); } else { throw new PXException(SmartsheetConstants.Messages.SMARTSHEET_ID_MISSING); } }
public virtual void loadTemplateColumnsSS() { PMSetup pmSetupRow = this.Base.Setup.Current; if (pmSetupRow == null) { throw new PXException(SmartsheetConstants.Messages.ERROR_SETUP); } PXCache <PMSSMapping> mappingCache = this.Base.Caches <PMSSMapping>(); if (MappingSetup.Select().Count() == 0) { InsertTemplate(mappingCache); } else { WebDialogResult result = this.Base.Setup.View.Ask(this.Base.Setup.Current, SmartsheetConstants.Messages.CONFIRM_HEADER, SmartsheetConstants.Messages.CONFIRM_RELOAD_VALUES, MessageButtons.YesNoCancel, MessageIcon.Warning); if (result == WebDialogResult.Yes) { foreach (PMSSMapping item in MappingSetup.Select()) { mappingCache.Delete(item); } mappingCache.Persist(PXDBOperation.Delete); InsertTemplate(mappingCache); } } }
protected virtual void PMTemplateListSS_TemplateDefault_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e) { PMTemplateListSS row = e.Row as PMTemplateListSS; if (row == null || row.TemplateDefault == null) { return; } PMSetup setupRecord = this.Base.Setup.Current as PMSetup; PMSetupSSExt pmSetupSSExt = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(setupRecord); if ((bool)row.TemplateDefault) { PMTemplateListSS pmSSMappingRecord = this.TemplateSetup.Select().RowCast <PMTemplateListSS>().Where(_ => (bool)_.TemplateDefault == true && _.TemplateSS != row.TemplateSS).FirstOrDefault(); if (pmSSMappingRecord != null) { pmSSMappingRecord.TemplateDefault = false; } pmSetupSSExt.UsrSSTemplate = row.TemplateSS; } else { pmSetupSSExt.UsrSSTemplate = null; } this.Base.Setup.Update(setupRecord); TemplateSetup.View.RequestRefresh(); }
protected virtual void AutoAllocateTasks(List <PMTask> tasks) { PMSetup setup = PXSelect <PMSetup> .Select(Base); bool autoreleaseAllocation = setup.AutoReleaseAllocation == true; PMAllocator allocator = PXGraph.CreateInstance <PMAllocator>(); allocator.Clear(); allocator.TimeStamp = Base.TimeStamp; allocator.Execute(tasks); allocator.Actions.PressSave(); if (allocator.Document.Current != null && autoreleaseAllocation) { List <PMRegister> list = new List <PMRegister>(); list.Add(allocator.Document.Current); List <ProcessInfo <Batch> > batchList; bool releaseSuccess = RegisterRelease.ReleaseWithoutPost(list, false, out batchList); if (!releaseSuccess) { throw new PXException(PM.Messages.AutoReleaseFailed); } foreach (var item in batchList) { Base.created.AddRange(item.Batches); } } }
protected virtual void PMSetup_RowPersisting(PXCache sender, PXRowPersistingEventArgs e) { if (e.Row == null) { return; } PMSetup pmSetupRow = (PMSetup)e.Row; PMSetupSSExt pmSetupSSExtRow = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(pmSetupRow); if (pmSetupSSExtRow.UsrSmartsheetClientID != null && String.IsNullOrEmpty(pmSetupSSExtRow.UsrDefaultRateTableID)) { throw new PXRowPersistingException(typeof(PMSetupSSExt.usrDefaultRateTableID).Name, null, ErrorMessages.FieldIsEmpty); } }
protected virtual void PMSetup_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { if (e.Row == null) { return; } PMSetup pmSetup = e.Row as PMSetup; Dictionary <string, string> fields = new Dictionary <string, string>(); foreach (PMTemplateListSS templateRow in TemplateSetup.Select()) { fields.Add(templateRow.TemplateSS, templateRow.TemplateName); } PXStringListAttribute.SetList <PMSetupSSExt.usrSSTemplate>(cache, pmSetup, fields.Keys.ToArray(), fields.Values.ToArray()); }
protected virtual IEnumerable PopulateDates(PXAdapter adapter) { PMSetup setupRecord = this.Base.Setup.Select(); PMSetupSSExt setupRecordExt = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(setupRecord); if (!String.IsNullOrEmpty(setupRecordExt.UsrTypeTaskDate) && setupRecordExt.UsrDurationTaskDate != null) { foreach (PMTask filter in this.Base.Tasks.Select()) { PMTaskSSExt pMTaskRecordExt = PXCache <PMTask> .GetExtension <PMTaskSSExt>(filter); if (String.IsNullOrEmpty(filter.StartDate.ToString())) { filter.StartDate = DateTime.Today; } if (String.IsNullOrEmpty(filter.EndDate.ToString())) { switch (setupRecordExt.UsrTypeTaskDate) { case SmartsheetConstants.SSConstants.DAY: SmartsheetHelper smartSheetHelperObject = new SmartsheetHelper(); filter.EndDate = smartSheetHelperObject.CalculateWorkingDays((DateTime)filter.StartDate, (int)setupRecordExt.UsrDurationTaskDate); break; case SmartsheetConstants.SSConstants.MONTH: filter.EndDate = ((DateTime)filter.StartDate).AddMonths((int)setupRecordExt.UsrDurationTaskDate); break; case SmartsheetConstants.SSConstants.YEAR: filter.EndDate = ((DateTime)filter.StartDate).AddYears((int)setupRecordExt.UsrDurationTaskDate); break; } } this.Base.Tasks.Cache.Update(filter); } } else { throw new PXException(SmartsheetConstants.Messages.DURATION_FIELDS_NOT_INDICATED); } return(adapter.Get()); }
public virtual void loadTemplateSS() { PMSetup pmSetupRow = this.Base.Setup.Current; Dictionary <string, string> templateSS = GetTemplateSS(); PXCache <PMTemplateListSS> pmtemplateListCache = this.Base.Caches <PMTemplateListSS>(); foreach (PMTemplateListSS item in TemplateSetup.Select()) { pmtemplateListCache.Delete(item); } foreach (var templateRow in templateSS) { PMTemplateListSS ci = (PMTemplateListSS)pmtemplateListCache.Insert(new PMTemplateListSS { TemplateSS = templateRow.Key.ToString(), TemplateName = templateRow.Value.ToString(), TemplateDefault = false }); } }
public void GetSmartsheetToken(string currentURL) { Guid loggedUser = Base.Accessinfo.UserID; Users usersRow = PXSelect <Users, Where <Users.pKID, Equal <Required <Users.pKID> > > > .Select(this.Base, loggedUser); UsersSSExt usersSSExtRow = PXCache <Users> .GetExtension <UsersSSExt>(usersRow); this.Base.UserProfile.Current = this.Base.UserProfile.Search <Users.pKID>(usersRow.PKID); PMSetup setupRow = PXSelect <PMSetup> .Select(this.Base); PMSetupSSExt setupSSExtRow = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(setupRow); if (currentURL.IndexOf(SmartsheetConstants.SSCodeRequest.STATE, StringComparison.CurrentCultureIgnoreCase) > 0) { string ssCode = getSSCodeString(currentURL); if (ssCode.Trim().Length > 0) { List <string> ssToken = getSSToken(setupSSExtRow.UsrSmartsheetClientID, ssCode, setupSSExtRow.UsrSmartsheetAppSecret); if (ssToken.Count == 2) { usersSSExtRow.UsrSmartsheetToken = ssToken[0]; usersSSExtRow.UsrSmartsheetRefreshToken = ssToken[1]; this.Base.UserProfile.Update(usersRow); this.Base.Actions.PressSave(); } } } SendRefreshCall(); return; }
/// <summary> /// Verifies the connection Token and the existence of the Sheet /// </summary> /// <param name="projectEntryGraph">Project's Graph</param> /// <param name="pmProjectRow">Current PMProject row</param> /// <param name="refreshedToken">Existing token</param> /// <param name="isMassProcess">Indicates if it's used in a processing page</param> /// <returns></returns> public SmartsheetClient CheckTokenSheetSS(ProjectEntry projectEntryGraph, PMProject pmProjectRow, string refreshedToken = "", bool isMassProcess = false) { //Primary Data View is set projectEntryGraph.Project.Current = pmProjectRow; SmartsheetHelper smartSheetHelperObject = new SmartsheetHelper(); string sheetName = pmProjectRow.ContractCD.Trim() + " - " + pmProjectRow.Description.Trim(); sheetName = smartSheetHelperObject.Left(sheetName, SmartsheetConstants.SSConstants.SS_PROJECT_NAME_LENGTH); PMSetup setupRecord = projectEntryGraph.Setup.Select(); PMSetupSSExt pmSetupSSExt = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(setupRecord); PMProjectSSExt pmProjectSSExt = PXCache <PMProject> .GetExtension <PMProjectSSExt>(pmProjectRow); Users userRecord = PXSelect < Users, Where <Users.pKID, Equal <Required <AccessInfo.userID> > > > .Select(projectEntryGraph, projectEntryGraph.Accessinfo.UserID); UsersSSExt userRecordSSExt = PXCache <Users> .GetExtension <UsersSSExt>(userRecord); smartSheetHelperObject.SetupValidation(userRecordSSExt, pmSetupSSExt); smartSheetHelperObject.ProjectValidation(projectEntryGraph); Token token = new Token(); token.AccessToken = (String.IsNullOrEmpty(refreshedToken)) ? userRecordSSExt.UsrSmartsheetToken : refreshedToken; try { SmartsheetClient smartsheetClient = new SmartsheetBuilder() .SetAccessToken(token.AccessToken) .SetDateTimeFixOptOut(true) .Build(); long?sheetSelected; Dictionary <string, long> currentColumnMap = new Dictionary <string, long>(); if (pmProjectSSExt != null && pmProjectSSExt.UsrSmartsheetContractID != null) //Acumatica Project is already linked to SS { sheetSelected = pmProjectSSExt.UsrSmartsheetContractID; Sheet ssProjectSheet = smartsheetClient.SheetResources.GetSheet((long)sheetSelected, null, null, null, null, null, null, null); } return(smartsheetClient); } catch (Exception ex) { if (ex.Message.Contains(SmartsheetConstants.SSConstants.EXPIRED_TOKEN_MESSAGE)) { MyProfileMaint profileMaintGraph = PXGraph.CreateInstance <MyProfileMaint>(); MyProfileMaintExt graphExtended = profileMaintGraph.GetExtension <MyProfileMaintExt>(); string updatedToken = graphExtended.RefreshSmartsheetToken(); CheckTokenSheetSS(projectEntryGraph, pmProjectRow, updatedToken); } if (ex.Message.Contains(SmartsheetConstants.SSConstants.NOTFOUND_PROJECT_MESSAGE)) { if (isMassProcess) { SmartsheetClient smartsheetClient = new SmartsheetBuilder() .SetAccessToken(token.AccessToken) .SetDateTimeFixOptOut(true) .Build(); UnlinkSmartsheetProject(projectEntryGraph); CreateUpdateGanttProject(projectEntryGraph, pmProjectRow, smartsheetClient, true); } else { UnlinkSmartsheetProject(projectEntryGraph); throw new PXException(SmartsheetConstants.Messages.UNLINK_PROJECT); } } else { throw new PXException(ex.Message); } return(null); } }
/// <summary> /// Creates or updates the Smartsheet project with information from Acumatica. /// New Tasks created in Smartsheet will be updated back in Acumatica /// </summary> /// <param name="projectEntryGraph">Project Entry graph</param> /// <param name="pmProjectRow">PMProject record</param> /// <param name="smartsheetClient">Smartsheet's SDK Client</param> /// <param name="isMassProcess">Indicates if it's used in a processing page</param> public void CreateUpdateGanttProject(ProjectEntry projectEntryGraph, PMProject pmProjectRow, SmartsheetClient smartsheetClient, bool isMassProcess = false) { //Primary Data View is set projectEntryGraph.Project.Current = pmProjectRow; PMProjectSSExt pmProjectSSExt = PXCache <PMProject> .GetExtension <PMProjectSSExt>(pmProjectRow); PMSetup setupRecord = projectEntryGraph.Setup.Select(); PMSetupSSExt pmSetupSSExt = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(setupRecord); SmartsheetHelper smartSheetHelperObject = new SmartsheetHelper(); if (String.IsNullOrEmpty(pmProjectSSExt.UsrTemplateSS)) { throw new PXException(SmartsheetConstants.Messages.DEFAULT_TEMPLATE); } string sheetName = pmProjectRow.ContractCD.Trim() + " - " + pmProjectRow.Description.Trim(); sheetName = smartSheetHelperObject.Left(sheetName, SmartsheetConstants.SSConstants.SS_PROJECT_NAME_LENGTH); try { long?sheetSelected; Dictionary <string, long> currentColumnMap = new Dictionary <string, long>(); ////////////////// //Information from Acumatica is updated in Smartsheet ////////////////// PXResultset <PMSSMapping> templateMappingSet = PXSelect < PMSSMapping, Where <PMSSMapping.templateSS, Equal <Required <PMSSMapping.templateSS> > > > .Select(projectEntryGraph, pmProjectSSExt.UsrTemplateSS); if (pmProjectSSExt != null && pmProjectSSExt.UsrSmartsheetContractID != null) //Acumatica Project is already linked to SS { sheetSelected = pmProjectSSExt.UsrSmartsheetContractID; Sheet ssProjectSheet = smartsheetClient.SheetResources.GetSheet((long)sheetSelected, null, null, null, null, null, null, null); //Columns ID Mapping currentColumnMap = new Dictionary <string, long>(); foreach (Column currentColumn in ssProjectSheet.Columns) { currentColumnMap.Add(currentColumn.Title, (long)currentColumn.Id); } smartSheetHelperObject.UpdateSSProject(smartsheetClient, currentColumnMap, projectEntryGraph, sheetSelected, smartSheetHelperObject, templateMappingSet); } else //Acumatica Project has not been linked to Smartsheet { //Sheet is created from a the template selected in the Project Sheet sheet = new Sheet.CreateSheetFromTemplateBuilder(sheetName, Convert.ToInt64(pmProjectSSExt.UsrTemplateSS)).Build(); sheet = smartsheetClient.SheetResources.CreateSheet(sheet); Sheet newlyCreatedSheet = smartsheetClient.SheetResources.GetSheet((long)sheet.Id, null, null, null, null, null, null, null); currentColumnMap = new Dictionary <string, long>(); foreach (Column currentColumn in newlyCreatedSheet.Columns) { currentColumnMap.Add(currentColumn.Title, (long)currentColumn.Id); } //Acumatica Tasks are added as Smartsheet rows List <Row> newSSRows = smartSheetHelperObject.InsertAcumaticaTasksInSS(projectEntryGraph, currentColumnMap, null, true, templateMappingSet); IList <Row> ssRows = smartsheetClient.SheetResources.RowResources.AddRows((long)sheet.Id, newSSRows); int ssTaskIDPosition = 0; if (ssRows.Count > 0 && ssRows[0].Cells != null) { PMSSMapping mappingSS = templateMappingSet.Where(t => ((PMSSMapping)t).NameAcu.Trim().ToUpper() == SmartsheetConstants.ColumnMapping.TASKS_CD.Trim().ToUpper()).FirstOrDefault(); ssTaskIDPosition = smartSheetHelperObject.GetSSTaskPosition(ssRows[0].Cells, currentColumnMap[mappingSS.NameSS]); } // Add SubTasks smartSheetHelperObject.InsertAcumaticaSubTasks(projectEntryGraph, smartsheetClient, sheet, ssRows, smartSheetHelperObject, currentColumnMap, ssTaskIDPosition, templateMappingSet); foreach (Row currentRow in ssRows) { foreach (PMTask rowTask in projectEntryGraph.Tasks.Select()) { if (currentRow.Cells[ssTaskIDPosition].Value != null && rowTask.TaskCD != null && string.Equals(currentRow.Cells[ssTaskIDPosition].Value.ToString().Trim(), rowTask.TaskCD.Trim(), StringComparison.OrdinalIgnoreCase)) { PMTaskSSExt pmTaskSSExtRow = PXCache <PMTask> .GetExtension <PMTaskSSExt>(rowTask); pmTaskSSExtRow.UsrSmartsheetTaskID = currentRow.Id; projectEntryGraph.Tasks.Update(rowTask); break; } } } sheetSelected = (long)sheet.Id; PMProjectSSExt pmProjectSSExtRow = PXCache <PMProject> .GetExtension <PMProjectSSExt>(pmProjectRow); pmProjectSSExtRow.UsrSmartsheetContractID = sheetSelected; projectEntryGraph.Project.Update(pmProjectRow); } ////////////////// //Information from Smartsheet is updated in Acumatica ////////////////// Sheet updatedSheet = smartsheetClient.SheetResources.GetSheet((long)sheetSelected, null, null, null, null, null, null, null); int columnPosition = 0; Dictionary <string, int> columnPositionMap = new Dictionary <string, int>(); foreach (Column currentColumn in updatedSheet.Columns) { columnPositionMap.Add(currentColumn.Title, columnPosition); columnPosition += 1; } smartSheetHelperObject.UpdateAcumaticaTasks(projectEntryGraph, pmProjectRow, pmSetupSSExt, updatedSheet, columnPositionMap, templateMappingSet); projectEntryGraph.Actions.PressSave(); if (isMassProcess) { PXProcessing.SetInfo(String.Format(SmartsheetConstants.Messages.SUCCESSFULLY_SYNCED, pmProjectRow.ContractCD)); } } catch (Exception e) { throw new PXException(e.Message); } }
/// <summary> /// Creates or updates the Smartsheet project with information from Acumatica. /// New Tasks created in Smartsheet will be updated back in Acumatica /// </summary> /// <param name="projectEntryGraph">Project Entry graph</param> /// <param name="pmProjectRow">PMProject record</param> /// <param name="isMassProcess">Indicates if it's used in a processing page</param> public void CreateUpdateGanttProject(ProjectEntry projectEntryGraph, PMProject pmProjectRow, string refreshedToken = "", bool isMassProcess = false) { //Primary Data View is set projectEntryGraph.Project.Current = pmProjectRow; SmartsheetHelper smartSheetHelperObject = new SmartsheetHelper(); string sheetName = pmProjectRow.ContractCD.Trim() + " - " + pmProjectRow.Description.Trim(); sheetName = smartSheetHelperObject.Left(sheetName, SmartsheetConstants.SSConstants.SS_PROJECT_NAME_LENGTH); PMSetup setupRecord = projectEntryGraph.Setup.Select(); PMSetupSSExt pmSetupSSExt = PXCache <PMSetup> .GetExtension <PMSetupSSExt>(setupRecord); PMProjectSSExt pmProjectSSExt = PXCache <PMProject> .GetExtension <PMProjectSSExt>(pmProjectRow); Users userRecord = PXSelect <Users, Where <Users.pKID, Equal <Current <AccessInfo.userID> > > > .Select(projectEntryGraph); UsersSSExt userRecordSSExt = PXCache <Users> .GetExtension <UsersSSExt>(userRecord); smartSheetHelperObject.SetupValidation(userRecordSSExt, pmSetupSSExt); smartSheetHelperObject.ProjectValidation(projectEntryGraph); try { Token token = new Token(); token.AccessToken = (String.IsNullOrEmpty(refreshedToken)) ? userRecordSSExt.UsrSmartsheetToken : refreshedToken; SmartsheetClient smartsheetClient = new SmartsheetBuilder().SetAccessToken(token.AccessToken).Build(); long?sheetSelected; Dictionary <string, long> currentColumnMap = new Dictionary <string, long>(); ////////////////// //Information from Acumatica is updated in Smartsheet ////////////////// if (pmProjectSSExt != null && pmProjectSSExt.UsrSmartsheetContractID != null) //Acumatica Project is already linked to SS { sheetSelected = pmProjectSSExt.UsrSmartsheetContractID; Sheet ssProjectSheet = smartsheetClient.SheetResources.GetSheet((long)sheetSelected, null, null, null, null, null, null, null); //Columns ID Mapping currentColumnMap = new Dictionary <string, long>(); foreach (Column currentColumn in ssProjectSheet.Columns) { currentColumnMap.Add(currentColumn.Title, (long)currentColumn.Id); } smartSheetHelperObject.UpdateSSProject(smartsheetClient, currentColumnMap, projectEntryGraph, sheetSelected, smartSheetHelperObject); } else //Acumatica Project has not been linked to Smartsheet { //Sheet is created from a Gantt Template available in SmartSheet Sheet sheet = new Sheet.CreateSheetFromTemplateBuilder(sheetName, SmartsheetConstants.SSConstants.BASIC_SS_PROJECT_WITH_GANTT).Build(); sheet = smartsheetClient.SheetResources.CreateSheet(sheet); Sheet newlyCreatedSheet = smartsheetClient.SheetResources.GetSheet((long)sheet.Id, null, null, null, null, null, null, null); currentColumnMap = new Dictionary <string, long>(); foreach (Column currentColumn in newlyCreatedSheet.Columns) { currentColumnMap.Add(currentColumn.Title, (long)currentColumn.Id); } smartSheetHelperObject.AdjustGanttSheet(smartsheetClient, sheet, currentColumnMap); //Acumatica Tasks are added as Smartsheet rows List <Row> newSSRows = smartSheetHelperObject.InsertAcumaticaTasksInSS(projectEntryGraph, currentColumnMap, null, true); IList <Row> ssRows = smartsheetClient.SheetResources.RowResources.AddRows((long)sheet.Id, newSSRows); int ssTaskIDPosition = 0; if (ssRows.Count > 0 && ssRows[0].Cells != null) { ssTaskIDPosition = smartSheetHelperObject.GetSSTaskPosition(ssRows[0].Cells, currentColumnMap[SmartsheetConstants.GanttTemplateMapping.TASK_NAME]); } smartSheetHelperObject.InsertAcumaticaSubTasks(projectEntryGraph, smartsheetClient, sheet, ssRows, smartSheetHelperObject, currentColumnMap, ssTaskIDPosition); foreach (Row currentRow in ssRows) { foreach (PMTask rowTask in projectEntryGraph.Tasks.Select()) { if (currentRow.Cells[ssTaskIDPosition].Value != null && rowTask.TaskCD != null && string.Equals(currentRow.Cells[ssTaskIDPosition].Value.ToString().Trim(), rowTask.TaskCD.Trim(), StringComparison.OrdinalIgnoreCase)) { PMTaskSSExt pmTaskSSExtRow = PXCache <PMTask> .GetExtension <PMTaskSSExt>(rowTask); pmTaskSSExtRow.UsrSmartsheetTaskID = currentRow.Id; projectEntryGraph.Tasks.Update(rowTask); break; } } } sheetSelected = (long)sheet.Id; PMProjectSSExt pmProjectSSExtRow = PXCache <PMProject> .GetExtension <PMProjectSSExt>(pmProjectRow); pmProjectSSExtRow.UsrSmartsheetContractID = sheetSelected; projectEntryGraph.Project.Update(pmProjectRow); } ////////////////// //Information from Smartsheet is updated in Acumatica ////////////////// Sheet updatedSheet = smartsheetClient.SheetResources.GetSheet((long)sheetSelected, null, null, null, null, null, null, null); int columnPosition = 0; Dictionary <string, int> columnPositionMap = new Dictionary <string, int>(); foreach (Column currentColumn in updatedSheet.Columns) { columnPositionMap.Add(currentColumn.Title, columnPosition); columnPosition += 1; } smartSheetHelperObject.UpdateAcumaticaTasks(projectEntryGraph, pmProjectRow, pmSetupSSExt, updatedSheet, columnPositionMap); projectEntryGraph.Actions.PressSave(); if (isMassProcess) { PXProcessing.SetInfo(String.Format(SmartsheetConstants.Messages.SUCCESSFULLY_SYNCED, pmProjectRow.ContractCD)); } } catch (Exception e) { if (e.Message.Contains(SmartsheetConstants.SSConstants.EXPIRED_TOKEN_MESSAGE)) { MyProfileMaint profileMaintGraph = PXGraph.CreateInstance <MyProfileMaint>(); MyProfileMaintExt graphExtended = profileMaintGraph.GetExtension <MyProfileMaintExt>(); string updatedToken = graphExtended.RefreshSmartsheetToken(); CreateUpdateGanttProject(projectEntryGraph, pmProjectRow, updatedToken, isMassProcess = false); } else { throw new PXException(e.Message); } } }