/// <summary> /// Inserts in the Smartsheet project Subtasks defined in the Project Template Task from Acumatica /// </summary> /// <param name="projectEntryGraph"></param> /// <param name="smartsheetClient"></param> /// <param name="sheet"></param> /// <param name="ssRowSet"></param> /// <param name="smartSheetHelperObject"></param> /// <param name="columnMap"></param> /// <param name="ssTaskIDPosition"></param> public void InsertAcumaticaSubTasks(ProjectEntry projectEntryGraph, SmartsheetClient smartsheetClient, Sheet sheet, IList <Row> ssRowSet, SmartsheetHelper smartSheetHelperObject, Dictionary <string, long> columnMap, int ssTaskIDPosition) { if (projectEntryGraph.Project.Current != null && projectEntryGraph.Project.Current.TemplateID != null) { PXResultset <PMTask> templateTasksSet = PXSelect <PMTask, Where <PMTask.projectID, Equal <Required <PMTask.projectID> > > > .Select(projectEntryGraph, projectEntryGraph.Project.Current.TemplateID); foreach (PMTask templateTask in templateTasksSet) { PMTask actualTask = PXSelect <PMTask, Where <PMTask.projectID, Equal <Required <PMTask.projectID> >, And <PMTask.taskCD, Equal <Required <PMTask.taskCD> > > > > .Select(projectEntryGraph, projectEntryGraph.Project.Current.ContractID, templateTask.TaskCD.Trim()); if (actualTask == null) { continue; } PMTaskSSExt pmTemplateTaskSSExtRow = PXCache <PMTask> .GetExtension <PMTaskSSExt>(templateTask); PXResultset <PMSubTask> templateSubTasksSet = PXSelect <PMSubTask, Where <PMSubTask.projectID, Equal <Required <PMSubTask.projectID> >, And <PMSubTask.taskID, Equal <Required <PMSubTask.taskID> > > >, OrderBy <Asc <PMSubTask.position> > > .Select(projectEntryGraph, templateTask.ProjectID, templateTask.TaskID); int dependencyStartDateOffset = 0; long dependencySibling = 0; foreach (Row ssRow in ssRowSet) { if (ssRow.Cells[ssTaskIDPosition].Value != null && string.Equals(ssRow.Cells[ssTaskIDPosition].Value.ToString().Trim(), templateTask.TaskCD.Trim(), StringComparison.OrdinalIgnoreCase)) { foreach (PMSubTask subTaskRow in templateSubTasksSet) { dependencySibling = smartSheetHelperObject.AddSubTasks(smartsheetClient, columnMap, sheet, actualTask, pmTemplateTaskSSExtRow, subTaskRow, ssRow.Id, dependencyStartDateOffset, dependencySibling); dependencyStartDateOffset += (int)subTaskRow.Duration; } } } } } return; }
/// <summary> /// Adds subtasks to the Smartsheet project /// </summary> /// <param name="smartsheetClient"></param> /// <param name="columnMap"></param> /// <param name="sheet"></param> /// <param name="taskRow"></param> /// <param name="pmTemplateTaskSSExtRow"></param> /// <param name="subTaskRow"></param> /// <param name="columnID"></param> /// <param name="dependencyStartDateOffset"></param> /// <param name="dependencySibling"></param> /// <returns></returns> public long AddSubTasks(SmartsheetClient smartsheetClient, Dictionary <string, long> columnMap, Sheet sheet, PMTask taskRow, PMTaskSSExt pmTemplateTaskSSExtRow, PMSubTask subTaskRow, long?columnID, int dependencyStartDateOffset, long dependencySibling) { List <Cell> newCells = new List <Cell>(); Cell currentCell = new Cell.AddCellBuilder(columnMap[SmartsheetConstants.GanttTemplateMapping.TASK_NAME], subTaskRow.SubTaskCD).Build(); currentCell.Format = SmartsheetConstants.CellFormat.LARGE_GRAY_BACKGROUND; newCells.Add(currentCell); if (pmTemplateTaskSSExtRow.UsrEnableSubtaskDependency == true) { DateTime adjustedStartDate = taskRow.StartDate.Value.AddDays((double)dependencyStartDateOffset); currentCell = new Cell.AddCellBuilder(columnMap[SmartsheetConstants.GanttTemplateMapping.START], adjustedStartDate).Build(); newCells.Add(currentCell); } else { currentCell = new Cell.AddCellBuilder(columnMap[SmartsheetConstants.GanttTemplateMapping.START], taskRow.StartDate).Build(); newCells.Add(currentCell); } currentCell = new Cell.AddCellBuilder(columnMap[SmartsheetConstants.GanttTemplateMapping.DURATION], subTaskRow.Duration.ToString()).Build(); newCells.Add(currentCell); currentCell = new Cell.AddCellBuilder(columnMap[SmartsheetConstants.GanttTemplateMapping.COMMENTS], subTaskRow.Description).Build(); newCells.Add(currentCell); Row currentRow = new Row.AddRowBuilder(null, true, null, null, null).SetCells(newCells).Build(); currentRow.ParentId = (long)columnID; currentRow.Format = SmartsheetConstants.CellFormat.GRAY_BACKGROUND; List <Row> newSSRows = new List <Row>(); newSSRows.Add(currentRow); IList <Row> ssRows = smartsheetClient.SheetResources.RowResources.AddRows((long)sheet.Id, newSSRows); return((long)ssRows[0].Id); }
/// <summary> /// Updates SS Project with new Acumatica tasks not yet synced /// </summary> /// <param name="smartsheetClient"></param> /// <param name="columnMap"></param> /// <param name="projectEntryGraph"></param> /// <param name="sheetSelected"></param> /// <param name="smartSheetHelperObject"></param> public void UpdateSSProject(SmartsheetClient smartsheetClient, Dictionary <string, long> columnMap, ProjectEntry projectEntryGraph, long?sheetSelected, SmartsheetHelper smartSheetHelperObject) { //Add newly created rows to Smartsheet List <Row> newRows = smartSheetHelperObject.InsertAcumaticaTasksInSS(projectEntryGraph, null, columnMap, false); IList <Row> ssRows = smartsheetClient.SheetResources.RowResources.AddRows((long)sheetSelected, newRows); int ssTaskIDPosition = 0; if (ssRows.Count > 0 && ssRows[0].Cells != null) { ssTaskIDPosition = smartSheetHelperObject.GetSSTaskPosition(ssRows[0].Cells, columnMap[SmartsheetConstants.ColumnMapping.TASK_ID]); } foreach (Row currentRow in ssRows) { foreach (PMTask acumaticaTask in projectEntryGraph.Tasks.Select()) { PMTaskSSExt pmTaskSSExtRow = PXCache <PMTask> .GetExtension <PMTaskSSExt>(acumaticaTask); if (pmTaskSSExtRow != null && pmTaskSSExtRow.UsrSmartsheetTaskID != null) { continue; } if (currentRow.Cells[ssTaskIDPosition].Value != null && acumaticaTask.TaskCD != null && string.Equals(currentRow.Cells[ssTaskIDPosition].Value.ToString().Trim(), acumaticaTask.TaskCD.Trim(), StringComparison.OrdinalIgnoreCase)) { pmTaskSSExtRow.UsrSmartsheetTaskID = currentRow.Id; projectEntryGraph.Tasks.Update(acumaticaTask); break; } } } return; }
/// <summary> /// Creates/Updates Acumatica Tasks with the Smartsheet modifications /// </summary> /// <param name="projectEntryGraph"></param> /// <param name="pmProjectRow"></param> /// <param name="pmSetupSSExt"></param> /// <param name="updatedSheet"></param> /// <param name="columnPositionMap"></param> public void UpdateAcumaticaTasks(ProjectEntry projectEntryGraph, PMProject pmProjectRow, PMSetupSSExt pmSetupSSExt, Sheet updatedSheet, Dictionary <string, int> columnPositionMap) { bool recordedInAcumatica = false; int primaryColumnPosition = 0; foreach (Column updatedColumn in updatedSheet.Columns) { if (updatedColumn != null && updatedColumn.Primary != null && updatedColumn.Primary == true) { foreach (Row updatedSSRow in updatedSheet.Rows) { if (updatedSSRow != null && updatedSSRow.ParentId != null) //Subtasks are not synced back to Acumatica { continue; } PMTask currentTaskRow = null; PMTaskSSExt pmTaskSSExtRow = null; foreach (PMTask taskRow in projectEntryGraph.Tasks.Select()) { recordedInAcumatica = false; pmTaskSSExtRow = PXCache <PMTask> .GetExtension <PMTaskSSExt>(taskRow); if (pmTaskSSExtRow != null && pmTaskSSExtRow.UsrSmartsheetTaskID == updatedSSRow.Id) { recordedInAcumatica = true; currentTaskRow = taskRow; break; } } if (recordedInAcumatica == false) //New Row in Smartsheet not yet added to Acumatica { //Fields retrieved: Task, Description, Start Date, End Date, % Complete, if (updatedSSRow.Cells[primaryColumnPosition].Value != null) { PMTask pmTaskNewEntry = new PMTask(); pmTaskNewEntry.ProjectID = pmProjectRow.ContractID; pmTaskNewEntry.TaskCD = updatedSSRow.Cells[primaryColumnPosition].Value.ToString(); PMTask taskCDValidation = (PMTask)projectEntryGraph.Tasks.Select() .Where(t => ((PMTask)t).TaskCD.Trim().ToUpper() == updatedSSRow.Cells[primaryColumnPosition].Value.ToString().Trim().ToUpper()).FirstOrDefault(); if (taskCDValidation == null) { pmTaskNewEntry = projectEntryGraph.Tasks.Insert(pmTaskNewEntry); if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.DESCRIPTION]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.DESCRIPTION]].Value != null) { projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.description>(pmTaskNewEntry, updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.DESCRIPTION]].Value.ToString()); } else { projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.description>(pmTaskNewEntry, SmartsheetConstants.Messages.DEFAULT_TASK_DESCRIPTION); } projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.rateTableID>(pmTaskNewEntry, pmSetupSSExt.UsrDefaultRateTableID); projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.status>(pmTaskNewEntry, SmartsheetConstants.SSConstants.ACTIVE); if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]].Value != null) { if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]].Value is DateTime) { DateTime startDate = (DateTime)updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]].Value; projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.startDate>(pmTaskNewEntry, startDate); projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.plannedStartDate>(pmTaskNewEntry, startDate); } } if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]].Value != null) { if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]].Value is DateTime) { DateTime endDate = (DateTime)updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]].Value; projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.endDate>(pmTaskNewEntry, endDate); projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.plannedEndDate>(pmTaskNewEntry, endDate); } } if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.PCT_COMPLETE]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.PCT_COMPLETE]].Value != null && pmTaskNewEntry.Status == SmartsheetConstants.SSConstants.ACTIVE) { projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.completedPercent>(pmTaskNewEntry, (decimal)((double)updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.PCT_COMPLETE]].Value * 100)); } PMTaskSSExt pmTaskExtRow = PXCache <PMTask> .GetExtension <PMTaskSSExt>(pmTaskNewEntry); pmTaskExtRow.UsrSmartsheetTaskID = updatedSSRow.Id; pmTaskNewEntry = projectEntryGraph.Tasks.Update(pmTaskNewEntry); } } } else //Previously existing row in SS { //Fields updated: Description, Start Date, End Date, % complete. if (updatedSSRow.Cells[primaryColumnPosition].Value != null) { if (currentTaskRow != null) { if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.DESCRIPTION]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.DESCRIPTION]].Value != null) { projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.description>(currentTaskRow, updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.DESCRIPTION]].Value.ToString()); } if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]].Value != null) { if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]].Value is DateTime) { DateTime startDate = (DateTime)updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.START_DATE]].Value; projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.startDate>(currentTaskRow, startDate); } } if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]].Value != null) { if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]].Value is DateTime) { DateTime endDate = (DateTime)updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.END_DATE]].Value; projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.endDate>(currentTaskRow, endDate); } } if (updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.PCT_COMPLETE]] != null && updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.PCT_COMPLETE]].Value != null && currentTaskRow.Status == SmartsheetConstants.SSConstants.ACTIVE) { projectEntryGraph.Tasks.Cache.SetValueExt <PMTask.completedPercent>(currentTaskRow, (decimal)((double)updatedSSRow.Cells[columnPositionMap[SmartsheetConstants.ColumnMapping.PCT_COMPLETE]].Value * 100)); } currentTaskRow = projectEntryGraph.Tasks.Update(currentTaskRow); } } } } break; } else { primaryColumnPosition += 1; } } return; }
/// <summary> /// Inserts Acumatica Tasks in Smartsheet /// </summary> /// <param name="projectEntryGraph"></param> /// <param name="originalColumnMap"></param> /// <param name="modifiedColumnMap"></param> /// <param name="firstSync"></param> /// <returns></returns> public List <Row> InsertAcumaticaTasksInSS(ProjectEntry projectEntryGraph, Dictionary <string, long> originalColumnMap, Dictionary <string, long> modifiedColumnMap, bool firstSync) { List <Row> newSSRows = new List <Row>(); Row blankRow = new Row(); if (firstSync) { blankRow = new Row.AddRowBuilder(null, true, null, null, null).Build(); newSSRows.Add(blankRow); } foreach (PMTask taskRow in projectEntryGraph.Tasks.Select()) { PMTaskSSExt pmTaskSSExtRow = PXCache <PMTask> .GetExtension <PMTaskSSExt>(taskRow); if (pmTaskSSExtRow != null && pmTaskSSExtRow.UsrSmartsheetTaskID != null) { continue; } List <Cell> newCells = new List <Cell>(); Cell currentCell = new Cell(); //Task if (firstSync) { currentCell = new Cell.AddCellBuilder(originalColumnMap[SmartsheetConstants.GanttTemplateMapping.TASK_NAME], taskRow.TaskCD).Build(); } else { currentCell = new Cell.AddCellBuilder(modifiedColumnMap[SmartsheetConstants.ColumnMapping.TASK_ID], taskRow.TaskCD).Build(); } currentCell.Format = SmartsheetConstants.CellFormat.LARGE_BOLD_GRAY_BACKGROUND; newCells.Add(currentCell); //Dates if (taskRow.StartDate != null && taskRow.EndDate != null) { if (firstSync) { currentCell = new Cell.AddCellBuilder(originalColumnMap[SmartsheetConstants.GanttTemplateMapping.START], taskRow.StartDate).Build(); } else { currentCell = new Cell.AddCellBuilder(modifiedColumnMap[SmartsheetConstants.ColumnMapping.START_DATE], taskRow.StartDate).Build(); } currentCell.Format = SmartsheetConstants.CellFormat.LARGER_GRAY_BACKGROUND; newCells.Add(currentCell); TimeSpan dateDifference = (TimeSpan)(taskRow.EndDate - taskRow.StartDate); if (firstSync) { currentCell = new Cell.AddCellBuilder(originalColumnMap[SmartsheetConstants.GanttTemplateMapping.DURATION], (dateDifference.Days + 1).ToString()).Build(); } else { currentCell = new Cell.AddCellBuilder(modifiedColumnMap[SmartsheetConstants.ColumnMapping.DURATION], (dateDifference.Days + 1).ToString()).Build(); } currentCell.Format = SmartsheetConstants.CellFormat.LARGER_GRAY_BACKGROUND; newCells.Add(currentCell); } //Completed % if (taskRow.CompletedPercent != null) { if (firstSync) { currentCell = new Cell.AddCellBuilder(originalColumnMap[SmartsheetConstants.GanttTemplateMapping.PCT_COMPLETE], (double)taskRow.CompletedPercent / 100).Build(); } else { currentCell = new Cell.AddCellBuilder(modifiedColumnMap[SmartsheetConstants.ColumnMapping.PCT_COMPLETE], (double)taskRow.CompletedPercent / 100).Build(); } currentCell.Format = SmartsheetConstants.CellFormat.LARGER_GRAY_BACKGROUND_PERCENTAGE; newCells.Add(currentCell); } if (taskRow.Description != null) { if (firstSync) { currentCell = new Cell.AddCellBuilder(originalColumnMap[SmartsheetConstants.GanttTemplateMapping.COMMENTS], taskRow.Description).Build(); } else { currentCell = new Cell.AddCellBuilder(modifiedColumnMap[SmartsheetConstants.ColumnMapping.DESCRIPTION], taskRow.Description).Build(); } currentCell.Format = SmartsheetConstants.CellFormat.LARGE_GRAY_BACKGROUND; newCells.Add(currentCell); } Row currentRow = new Row.AddRowBuilder(null, true, null, null, null).SetCells(newCells).Build(); currentRow.Format = SmartsheetConstants.CellFormat.GRAY_BACKGROUND; newSSRows.Add(currentRow); blankRow = new Row.AddRowBuilder(null, true, null, null, null).Build(); newSSRows.Add(blankRow); } return(newSSRows); }
/// <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); } } }