/// <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);
        }
Exemplo n.º 6
0
        /// <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);
                }
            }
        }