/// <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); }
/// <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)); }
/// <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; }
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); }
public static bool isBookableResourceValid(BookableResource bookableResource) { return(bookableResource != null && bookableResource.BookableResourceId != null && bookableResource.BookableResourceId.GetValueOrDefault() != Guid.Empty); }
/// <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; }
/// <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; }