예제 #1
0
        /// <summary>
        /// Save selected Time, if Id is null it will create a new one,
        /// otherwise it will update the selected Time.
        /// </summary>
        /// <returns></returns>
        public override async Tasks.Task <bool> ForcedSave()
        {
            bool            result = false;
            msdyn_timeentry time   = this.Time;

            if (time != null)
            {
                BookableResource bookableResource = await TimeHelper.GetBookableResourceForUser(await this.DataAccess.GetLoggedUserId(true));

                if (TimeHelper.isBookableResourceValid(bookableResource))
                {
                    time.msdyn_bookableresource = new EntityReference(BookableResource.EntityLogicalName, bookableResource.BookableResourceId.GetValueOrDefault());

                    // If Time can't be saved, don't allow the client to save,
                    // return false so user can make the corresponding corrections.
                    if (this.CanTimeBeSaved(time))
                    {
                        // If Time doesn't have an Id, it need to be created
                        if (time.Id == null || time.Id == Guid.Empty)
                        {
                            // Always clear the time entry id when creating a new entry
                            // because CRM validation treats Guid.Empty as an invalid id for a new record.
                            Guid?timeEntryId = await this.DataAccess.Create(time);

                            if (timeEntryId != null && timeEntryId != Guid.Empty)
                            {
                                time.Id = (Guid)timeEntryId;
                                result  = true;
                            }
                            else
                            {
                                result = false;
                            }
                        }
                        else
                        {
                            result = await this.DataAccess.Update(time);
                        }

                        // Update status of Time
                        if (this.HasPendingDataToSave)
                        {
                            this.HasPendingDataToSave = !result;
                        }

                        // If the validation method hasn't thrown an error message but save failed, throw an error message here.
                        if (!result)
                        {
                            await MessageCenter.ShowErrorMessage(AppResources.SaveError);
                        }
                    }
                    else
                    {
                        result = false;
                    }
                }
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Create and return the ConditionExpression to filter by owner.
        /// </summary>
        /// <returns>ConditionExpression to filter Owner by currently logged in user.</returns>
        private async Tasks.Task <ConditionExpression> getOwnerFilter()
        {
            // Create filter for owner of the time entries.
            Guid userId = await this.DataAccess.GetLoggedUserId();

            BookableResource bookableResource = await TimeHelper.GetBookableResourceForUser(userId);

            Guid bookableResourceId = bookableResource != null?bookableResource.BookableResourceId.GetValueOrDefault() : Guid.Empty;

            return(new ConditionExpression(msdyn_timeentry.EntityLogicalName, "msdyn_bookableresource", ConditionOperator.Equal, bookableResourceId));
        }
예제 #3
0
        /// <summary>
        /// Load data for projects
        /// </summary>
        /// <returns></returns>
        public override async Tasks.Task LoadReferenceData()
        {
            this.IsBusy = true;
            this.DataAccess.AccessMode = DataAccessMode.SyncConnection;

            QueryExpression queryExpression = new QueryExpression(msdyn_project.EntityLogicalName);

            queryExpression.ColumnSet = new ColumnSet("msdyn_projectid", "msdyn_subject", "msdyn_description");

            // Retrieve projects based on project team
            LinkEntity projectTeamLink = queryExpression.AddLink(msdyn_projectteam.EntityLogicalName, "msdyn_projectid", msdyn_project.EntityLogicalName, JoinOperator.Inner);

            projectTeamLink.Columns.AddColumn("msdyn_bookableresourceid");
            projectTeamLink.EntityAlias = "msdyn_projectteam";

            Guid userId = await this.DataAccess.GetLoggedUserId(true);

            BookableResource bookableResource = await TimeHelper.GetBookableResourceForUser(userId);

            bool searchAllProjects = true;

            ProjectFilters = new FilterQuery[2];

            if (userId != Guid.Empty && TimeHelper.isBookableResourceValid(bookableResource))
            {
                ConditionExpression crmUserExpression = new ConditionExpression(msdyn_projectteam.EntityLogicalName, "msdyn_bookableresourceid", ConditionOperator.Equal, bookableResource.BookableResourceId.GetValueOrDefault());
                queryExpression.Criteria = new FilterExpression();
                queryExpression.Criteria.AddCondition(crmUserExpression);
                searchAllProjects = !await this.LoadReferenceData <msdyn_project>(queryExpression);

                currentProjectFilter = 0;
                ProjectFilters[currentProjectFilter] = new FilterQuery(AppResources.ShowMyProjects, queryExpression, this.GetReferenceKeys <msdyn_project>());
            }

            if (searchAllProjects)
            {
                // If my projects didn't return values or I don't have the current user id, query all projects.
                queryExpression.Criteria = null;
                await this.LoadReferenceData <msdyn_project>(queryExpression);

                currentProjectFilter = 1;
                ProjectFilters[currentProjectFilter] = new FilterQuery(AppResources.ShowAllProjects, queryExpression, this.GetReferenceKeys <msdyn_project>());
            }
            else
            {
                // Else, store the all projects query for use when the user wants to see all projects.
                queryExpression.Criteria = null;
                ProjectFilters[AllProjectsFilterIndex] = new FilterQuery(AppResources.ShowAllProjects, queryExpression, null);
            }

            this.IsBusy = false;
        }
예제 #4
0
        public static async Tasks.Task <BookableResource> GetBookableResourceForUser(Guid userId)
        {
            BookableResource bookableResource = null;
            DataAccess       dataAccess       = new DataAccess();

            if (userId != null && userId != Guid.Empty)
            {
                QueryExpression queryExpression = new QueryExpression(BookableResource.EntityLogicalName);
                queryExpression.ColumnSet = new ColumnSet("bookableresourceid", "userid");

                ConditionExpression crmUserExpression = new ConditionExpression(BookableResource.EntityLogicalName, "userid", ConditionOperator.Equal, userId);
                queryExpression.Criteria = new FilterExpression();
                queryExpression.Criteria.AddCondition(crmUserExpression);
                List <BookableResource> bookableResourceList = await dataAccess.RetrieveEntities <BookableResource>(queryExpression, null, false);

                if (bookableResourceList != null)
                {
                    bookableResource = bookableResourceList.FirstOrDefault <BookableResource>();
                }
            }

            return(bookableResource);
        }
예제 #5
0
 public static bool isBookableResourceValid(BookableResource bookableResource)
 {
     return(bookableResource != null && bookableResource.BookableResourceId != null && bookableResource.BookableResourceId.GetValueOrDefault() != Guid.Empty);
 }
예제 #6
0
        /// <summary>
        /// Load data for projects, categories and currencies.
        /// </summary>
        /// <returns></returns>
        public override async System.Threading.Tasks.Task LoadReferenceData()
        {
            // Load the data in all cases, otherwise some platforms won't show the controls
            // if data bound to the control is not present.
            this.IsBusy = true;
            this.DataAccess.AccessMode = DataAccessMode.SyncConnection;
            // Retrieve expense categories
            QueryExpression queryExpression = new QueryExpression(msdyn_expensecategory.EntityLogicalName);

            queryExpression.ColumnSet = new ColumnSet("msdyn_expensecategoryuid", "msdyn_expensecategoryid", "msdyn_expensetype", "msdyn_receiptrequired", "msdyn_name");
            await this.LoadReferenceData <msdyn_expensecategory>(queryExpression);

            // Retrieve Currencies
            queryExpression.LinkEntities.Clear();
            queryExpression.EntityName = TransactionCurrency.EntityLogicalName;
            queryExpression.ColumnSet  = new ColumnSet("transactioncurrencyid", "currencyname", "isocurrencycode", "currencysymbol",
                                                       "exchangerate", "currencyprecision");
            await this.LoadReferenceData <TransactionCurrency>(queryExpression);

            queryExpression.EntityName = msdyn_project.EntityLogicalName;
            queryExpression.ColumnSet  = new ColumnSet("msdyn_projectid", "msdyn_subject", "msdyn_description");

            // Retrieve projects based on project team
            LinkEntity projectTeamLink = queryExpression.AddLink(msdyn_projectteam.EntityLogicalName, "msdyn_projectid", "msdyn_project", JoinOperator.Inner);

            projectTeamLink.Columns.AddColumn("msdyn_bookableresourceid");
            projectTeamLink.EntityAlias = "msdyn_projectteam";

            Guid userId = await this.DataAccess.GetLoggedUserId(true);

            BookableResource bookableResource = await ExpenseHelper.GetBookableResourceForUser(userId);

            Guid bookableResourceId = bookableResource != null?bookableResource.BookableResourceId.GetValueOrDefault() : Guid.Empty;

            bool searchAllProjects = true;

            ProjectFilters = new FilterQuery[2];

            if (userId != Guid.Empty)
            {
                ConditionExpression crmUserExpression = new ConditionExpression(msdyn_projectteam.EntityLogicalName, "msdyn_bookableresourceid", ConditionOperator.Equal, bookableResourceId);
                queryExpression.Criteria = new FilterExpression();
                queryExpression.Criteria.AddCondition(crmUserExpression);
                searchAllProjects = !await this.LoadReferenceData <msdyn_project>(queryExpression);

                currentProjectFilter = 0;
                ProjectFilters[currentProjectFilter] = new FilterQuery(AppResources.ShowMyProjects, queryExpression, this.GetReferenceKeys <msdyn_project>());
            }

            if (searchAllProjects)
            {
                // If my projects didn't return values or I don't have the current user id, query all projects
                queryExpression.Criteria = null;
                await this.LoadReferenceData <msdyn_project>(queryExpression);

                currentProjectFilter = 1;
                ProjectFilters[currentProjectFilter] = new FilterQuery(AppResources.ShowAllProjects, queryExpression, this.GetReferenceKeys <msdyn_project>());
            }
            else
            {
                ProjectFilters[1] = new FilterQuery(AppResources.ShowAllProjects, queryExpression, null);
            }
            this.IsBusy = false;
        }
예제 #7
0
        /// <summary>
        /// Get from cache the list of expenses and make an async call to the server for the updated list.
        /// Get first 30 expenses for the "All" list
        /// </summary>
        public async System.Threading.Tasks.Task LoadExpenses()
        {
            this.IsBusy = true;
            this.DataAccess.AccessMode = DataAccessMode.SyncConnection;

            // Prepare Query to Select expenses
            QueryExpression retrieveExpenseCollection = new QueryExpression(msdyn_expense.EntityLogicalName);

            retrieveExpenseCollection.ColumnSet = new ColumnSet("msdyn_expensestatus", "msdyn_expenseid", "msdyn_transactiondate", "msdyn_bookableresource",
                                                                "msdyn_expensecategory", "msdyn_project", "msdyn_name", "msdyn_salestaxamount", "msdyn_amount", "transactioncurrencyid", "modifiedon", "createdon");
            retrieveExpenseCollection.Distinct = true;

            // Filter by owner id
            Guid ownerId = await this.GetOwnerId();

            BookableResource bookableResource = await ExpenseHelper.GetBookableResourceForUser(ownerId);

            Guid bookableResourceId = bookableResource != null?bookableResource.BookableResourceId.GetValueOrDefault() : Guid.Empty;

            ConditionExpression crmUserExpression = new ConditionExpression(msdyn_expense.EntityLogicalName, "msdyn_bookableresource", ConditionOperator.Equal, bookableResourceId);

            retrieveExpenseCollection.Criteria = new FilterExpression();
            retrieveExpenseCollection.Criteria.AddCondition(crmUserExpression);

            // Order by createdon date
            retrieveExpenseCollection.Orders = new DataCollection <OrderExpression>();
            retrieveExpenseCollection.Orders.Add(new OrderExpression()
            {
                AttributeName = "createdon", OrderType = OrderType.Descending
            });

            // Check if the expense has notes
            LinkEntity notesLink = retrieveExpenseCollection.AddLink(Annotation.EntityLogicalName, "msdyn_expenseid", "objectid", JoinOperator.LeftOuter);

            notesLink.Columns.AddColumns("objectid");
            notesLink.EntityAlias = "notes";

            // Check if the expense has receipts
            LinkEntity receiptsLink = retrieveExpenseCollection.AddLink(msdyn_expensereceipt.EntityLogicalName, "msdyn_expenseid", "msdyn_expenseid", JoinOperator.LeftOuter);

            receiptsLink.Columns.AddColumns("msdyn_expensereceiptid");
            receiptsLink.EntityAlias = "receipts";

            // An entry in msdyn_expenseReceipt is not enough to determine if there are receipts, so adding a left outer with annotation
            LinkEntity linkEntity = new LinkEntity()
            {
                LinkToEntityName      = Annotation.EntityLogicalName,
                LinkFromEntityName    = msdyn_expensereceipt.EntityLogicalName,
                LinkFromAttributeName = "msdyn_expensereceiptid",
                LinkToAttributeName   = "objectid",
                JoinOperator          = JoinOperator.LeftOuter,
            };

            linkEntity.Columns.AddColumns("objectid");
            linkEntity.EntityAlias = "receiptsExtended";
            receiptsLink.LinkEntities.Add(linkEntity);

            // Get Currency Symbol currencysymbol
            LinkEntity transactionCurrencyLink = retrieveExpenseCollection.AddLink(TransactionCurrency.EntityLogicalName, "transactioncurrencyid", "transactioncurrencyid", JoinOperator.LeftOuter);

            transactionCurrencyLink.Columns.AddColumns("isocurrencycode");
            transactionCurrencyLink.EntityAlias = "transactioncurrency";

            // Get Expense type
            LinkEntity expenseCategoryLink = retrieveExpenseCollection.AddLink(msdyn_expensecategory.EntityLogicalName, "msdyn_expensecategory", "msdyn_expensecategoryid", JoinOperator.LeftOuter);

            expenseCategoryLink.Columns.AddColumns("msdyn_expensetype", "msdyn_receiptrequired");
            expenseCategoryLink.EntityAlias = msdyn_expensecategory.EntityLogicalName;

            // Clear previous results
            this.ExpensesCollection.Clear();
            this.LastUpdatedDateTime = DateTime.Now;

            // Get all expenses.
            switch (this.currentExpenseStatus)
            {
            // All expenses.
            case ExpenseStatus.All: break;

            // Draft expenses.
            case ExpenseStatus.Draft:
                ConditionExpression statusExpressionDraft = new ConditionExpression(msdyn_expense.EntityLogicalName, "msdyn_expensestatus",
                                                                                    ConditionOperator.Equal, (int)msdyn_expense_msdyn_expensestatus.Draft);
                retrieveExpenseCollection.Criteria.AddCondition(statusExpressionDraft);
                break;

            // Rejected expenses.
            case ExpenseStatus.Rejected:
                ConditionExpression statusExpressionRejected = new ConditionExpression(msdyn_expense.EntityLogicalName, "msdyn_expensestatus",
                                                                                       ConditionOperator.Equal, (int)msdyn_expense_msdyn_expensestatus.Rejected);
                retrieveExpenseCollection.Criteria.AddCondition(statusExpressionRejected);
                break;

            // All "pending" expenses
            case ExpenseStatus.Pending:
                ConditionExpression statusExpressionPending = new ConditionExpression(msdyn_expense.EntityLogicalName, "msdyn_expensestatus", ConditionOperator.In);
                statusExpressionPending.Values.Add((int)msdyn_expense_msdyn_expensestatus.Submitted);
                statusExpressionPending.Values.Add((int)msdyn_expense_msdyn_expensestatus.Approved);
                statusExpressionPending.Values.Add((int)msdyn_expense_msdyn_expensestatus.Posted);
                retrieveExpenseCollection.Criteria.AddCondition(statusExpressionPending);
                break;

            default:
                break;
            }

            List <msdyn_expense> listExpenses = await this.DataAccess.RetrieveEntities <msdyn_expense>(retrieveExpenseCollection, null, true);

            if (listExpenses != null)
            {
                foreach (msdyn_expense expense in listExpenses)
                {
                    this.ExpensesCollection.Add(expense);
                }
            }

            this.OnLoadExpensesCompleted();
            this.IsBusy = false;
        }