public void ClearRemovesAllDays() { DateTime dateTime1 = new DateTime(2015, 7, 28, 9, 58, 0); DateTime dateTime2 = new DateTime(2014, 1, 22, 23, 19, 0); msdyn_timeentry timeEntry1 = new msdyn_timeentry(); timeEntry1.msdyn_timeentryId = new Guid(); timeEntry1.msdyn_description = "entry 1"; timeEntry1.msdyn_date = dateTime1; timeEntry1.msdyn_duration = 2; msdyn_timeentry timeEntry2 = new msdyn_timeentry(); timeEntry2.msdyn_timeentryId = new Guid(); timeEntry2.msdyn_description = "entry 2"; timeEntry2.msdyn_date = dateTime2; timeEntry2.msdyn_duration = 2; TimeCollectionViewModel viewModel = new TimeCollectionViewModel(); viewModel.AddTimeEntries(new msdyn_timeentry[] { timeEntry1, timeEntry2 }); viewModel.ClearTimes(); Assert.AreEqual(0, viewModel.Days.Count); }
/// <summary> /// Defaults the msdyn_date_utc field of the time entry provided based off the current date filter. /// </summary> /// <param name="timeEntry">The msdyn_timeentry record to default.</p</param> public void DefaultDateFromCurrentFilter(msdyn_timeentry timeEntry) { DateTime filterLastDate = filter.EndDate; DateTime utcToday = DateTime.UtcNow; timeEntry.msdyn_date_utc = DateTime.Compare(filterLastDate, utcToday) > 0 ? utcToday : filterLastDate; }
/// <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); }
public void LoadTimesFromMultipleDays() { DateTime dateTime1 = new DateTime(2015, 7, 28, 9, 58, 0); DateTime dateTime2 = new DateTime(2014, 1, 22, 23, 19, 0); msdyn_timeentry timeEntry1 = new msdyn_timeentry(); timeEntry1.msdyn_timeentryId = new Guid(); timeEntry1.msdyn_description = "entry 1"; timeEntry1.msdyn_date = dateTime1; timeEntry1.msdyn_duration = 2; msdyn_timeentry timeEntry2 = new msdyn_timeentry(); timeEntry2.msdyn_timeentryId = new Guid(); timeEntry2.msdyn_description = "entry 2"; timeEntry2.msdyn_date = dateTime2; timeEntry2.msdyn_duration = 2; TimeCollectionViewModel viewModel = new TimeCollectionViewModel(); viewModel.AddTimeEntries(new msdyn_timeentry[] { timeEntry1, timeEntry2 }); // Validate IEnumerable <TimeCollection> days = viewModel.Days; Assert.AreEqual(2, days.Count(), "Incorrect number of days"); }
public void CanMarkTimeEntryAsSelected() { msdyn_timeentry timeEntry = new msdyn_timeentry(); timeEntry.Selected = true; Assert.IsTrue(timeEntry.Selected); }
public async Tasks.Task TimeEntryIDsAreConcatenatedForSubmit() { string guid1 = "BF65EFF9-89AF-4961-9C73-C178071A06AE"; string guid2 = "B42423C5-F993-410B-95FC-B3085A91DE4B"; msdyn_timeentry entry1 = new msdyn_timeentry(); entry1.Id = Guid.Parse(guid1); msdyn_timeentry entry2 = new msdyn_timeentry(); entry2.Id = Guid.Parse(guid2); TimeEntrySubmitter submitter = new TimeEntrySubmitter(); submitter.addTimeEntry(entry1); submitter.addTimeEntry(entry2); DataAccessTestable dat = new DataAccessTestable(); submitter.DataAccess = dat; string ids = ""; dat.addExecuteHandler((OrganizationRequest or) => { ids = (string)or.Parameters[TimeEntrySubmitter.TimeEntryIdsParameterName]; }); await submitter.ExecuteAction(); // Validate Assert.AreEqual(string.Format("{0},{1}", entry1.Id, entry2.Id), ids); }
/// <summary> /// Validates if time entry can be saved. /// </summary> /// <param name="Time">The time entry for which to validate.</param> /// <returns>True if the time entry can be saved, false otherwise.</returns> public virtual bool CanTimeBeSaved(msdyn_timeentry timeEntry) { // Check that the date field is filled. if (timeEntry.msdyn_date == null) { MessageCenter.ShowErrorMessage(AppResources.DateInvalidWarning).DoNotAwait(); return(false); } // Check that the total duration (including this new time entry) does not exceed 24 hours for a particular day. Dictionary <DateTime, int> durationsPerDay = TimeCollectionViewModel.DurationPerDay; DateTime date = (DateTime)timeEntry.msdyn_date; // Use msdyn_date since that is the one stored in the entity. if (durationsPerDay.ContainsKey(date)) { // Subtract the selected time entry saved duration for update scenario to prevent double adding the total durations. if (this.Time.msdyn_timeentryId != null || this.Time.msdyn_timeentryId != Guid.Empty) { durationsPerDay[date] -= (int)this.Time.msdyn_duration; } if ((durationsPerDay[date] + timeEntry.msdyn_duration) > (24 * 60)) { MessageCenter.ShowErrorMessage(AppResources.TimeExceeded).DoNotAwait(); return(false); } } return(true); }
private void initDeleteAction() { deleteAction = new MenuItem { Text = AppResources.Delete, IsDestructive = true }; deleteAction.SetBinding(MenuItem.CommandParameterProperty, new Binding(".")); deleteAction.Clicked += async(sender, e) => { MenuItem mi = (MenuItem)sender; msdyn_timeentry time = (msdyn_timeentry)mi.BindingContext; TimeViewModel model = new TimeViewModel(time); BaseViewModel viewModel = (BaseViewModel)this.HostPage.BindingContext; viewModel.IsBusy = true; await model.Delete(); MessagingCenter.Send <Page>(this.HostPage, Message.RefreshMainPage); viewModel.IsBusy = false; }; }
public void TimeEntryDurationValidationTest() { // Prepare the time entries for test purposes. DateTime dateTime = DateTime.Today; msdyn_timeentry timeEntry1 = new msdyn_timeentry(); timeEntry1.msdyn_timeentryId = new Guid(); timeEntry1.msdyn_description = "entry 1"; timeEntry1.msdyn_date = dateTime; timeEntry1.msdyn_duration = 20 * 60; // 20 hours. msdyn_timeentry timeEntry2 = new msdyn_timeentry(); timeEntry2.msdyn_timeentryId = new Guid(); timeEntry2.msdyn_description = "entry 2"; timeEntry2.msdyn_date = dateTime; timeEntry2.msdyn_duration = 4 * 60 + 1; // 4 hours and 1 minute. TimeViewModel entry = new TimeViewModel(timeEntry1); TimeCollectionViewModel viewModel = new TimeCollectionViewModel(); viewModel.AddTimeEntries(new msdyn_timeentry[] { timeEntry1, timeEntry2 }); Assert.IsFalse(entry.CanTimeBeSaved(timeEntry1), "The time entry should not be able to save since the total duration is 24:01"); timeEntry1.msdyn_duration = 19 * 60 + 59; // 19 hours and 59 minutes. Assert.IsTrue(entry.CanTimeBeSaved(timeEntry1), "The time entry should be able to save since the total duration is 24:00"); }
/// <summary> /// Open a new instance of TimeDetailPage. /// </summary> /// <param name="timeEntry">Time entry to show on the detail page.</param> /// <param name="navigation">Navigation to push the page on.</param> /// <returns></returns> public static async System.Threading.Tasks.Task NavigateToTimeDetailsView(msdyn_timeentry timeEntry, INavigation navigation) { TimeDetailsPage timeDetailPage = new TimeDetailsPage(); await navigation.PushAsync(timeDetailPage); await timeDetailPage.Initialize(new TimeViewModel(timeEntry)); }
public void GetNullEntryStatus() { msdyn_timeentry timeEntry = new msdyn_timeentry(); // Value is null by default Assert.IsNull(timeEntry.EntryStatus); }
private void ListView_ItemSelectedMultiSelect(object sender, SelectedItemChangedEventArgs e) { msdyn_timeentry selectedTime = e.SelectedItem as msdyn_timeentry; if (selectedTime != null) { // Switch selection status selectedTime.Selected = !selectedTime.Selected; listView.SelectedItem = null; } }
private void addDurationPerDateToDictionary(msdyn_timeentry entry, DateTime date) { // If an entry for that day doesn't exist already, create and store the duration. if (!DurationPerDay.ContainsKey(date)) { DurationPerDay.Add(date, (int)entry.msdyn_duration); } // Else, add up the duration with the tally of duration for the day. else { DurationPerDay[date] += (int)entry.msdyn_duration; } }
public void SetNullEntryStatus() { msdyn_timeentry timeEntry = new msdyn_timeentry(); //Submitted = 192350003, timeEntry.msdyn_entryStatus = new Microsoft.Xrm.Sdk.Samples.OptionSetValue(192350003); // Change to Null timeEntry.EntryStatus = null; // Validate Assert.IsNull(timeEntry.EntryStatus); }
public void EntryStatusGetTest() { msdyn_timeentry timeEntry = new msdyn_timeentry(); // Check msdyn_timeentry_msdyn_entrystatus.cs for values //Approved = 192350002, //Returned = 192350001, //Draft = 192350000, //Submitted = 192350003, timeEntry.msdyn_entryStatus = new Microsoft.Xrm.Sdk.Samples.OptionSetValue(192350000); Assert.AreEqual(msdyn_timeentry_msdyn_entrystatus.Draft, timeEntry.EntryStatus); }
public void SetDefaultValuesOnlyWorksOnNewEntries() { msdyn_timeentry timeEntry = new msdyn_timeentry(); TimeViewModel entry = new TimeViewModel(timeEntry); timeEntry.Id = Guid.NewGuid(); entry.SetDefaultValues(); Assert.IsNull(timeEntry.msdyn_date); Assert.IsNull(timeEntry.msdyn_duration); Assert.IsNull(timeEntry.msdyn_type); Assert.IsNull(timeEntry.msdyn_entryStatus); }
private async void ListView_ItemSelectedNormal(object sender, SelectedItemChangedEventArgs e) { // async void is OK here, since this is a top level event handler msdyn_timeentry selectedTime = e.SelectedItem as msdyn_timeentry; if (selectedTime != null) { await this.NavigateToTimeDetailsView(selectedTime); // Deselect the item listView.SelectedItem = null; } }
public void SetDefaultValuesTest() { msdyn_timeentry timeEntry = new msdyn_timeentry(); TimeViewModel entry = new TimeViewModel(timeEntry); DateTime todayUTC = DateTime.Today; entry.SetDefaultValues(); // validate entry data Assert.AreEqual(new DateTime(todayUTC.Year, todayUTC.Month, todayUTC.Day, 12, 0, 0), timeEntry.msdyn_date, "Incorrect default date of noon today."); Assert.AreEqual(60, timeEntry.msdyn_duration, "Incorrect default duration"); Assert.AreEqual((int)msdyn_timeentrytype.Work, timeEntry.msdyn_type.Value, "Incorrect default time entry type"); Assert.AreEqual((int)msdyn_timeentry_msdyn_entrystatus.Draft, timeEntry.msdyn_entryStatus.Value, "Incorrect default time entry status"); }
public void CanEditTimeEntryTest() { msdyn_timeentry timeEntry = new msdyn_timeentry(); TimeViewModel entry = new TimeViewModel(timeEntry); Assert.IsTrue(entry.CanEdit(), "A time entry that hasn't been saved (has null values) should be editable."); timeEntry.Id = Guid.NewGuid(); entry.SetDefaultValues(); Assert.IsTrue(entry.CanEdit(), "A time entry that has been saved with values should be editable."); timeEntry.msdyn_entryStatus = new OptionSetValue((int)msdyn_timeentry_msdyn_entrystatus.Submitted); Assert.IsFalse(entry.CanEdit(), "A time entry that has been submitted with values should be editable."); }
public async Tasks.Task DefaultDateFromCurrentFilter() { msdyn_timeentry timeEntry = new msdyn_timeentry(); // Today - the day of the week (gives sunday) + 7 = Sunday next week. DateTime expectedDate = DateTime.Today - TimeSpan.FromDays((int)DateTime.Today.DayOfWeek) + TimeSpan.FromDays(7); // Act. TimeCollectionViewModel viewModel = new TimeCollectionViewModel(); viewModel.DataAccess = new DataAccessTestable(); await viewModel.IncrementDateFilter(); // Assert. viewModel.DefaultDateFromCurrentFilter(timeEntry); }
/// <summary> /// Recall a time entry. /// </summary> /// <returns></returns> public virtual async Tasks.Task <bool> Recall() { msdyn_timeentry time = this.Time; if (!this.IsSubmitted()) { return(false); } TimeEntryRecaller recaller = new TimeEntryRecaller(); recaller.DataAccess = this.DataAccess; recaller.addTimeEntry(time); return(await recaller.ExecuteAction()); }
private void addTimeEntryWithDateToTimeCollection(msdyn_timeentry entry, DateTime date) { TimeCollection timeCollection; // Get or create the correct TimeCollection if (this.timesToDays.ContainsKey(date)) { timeCollection = this.timesToDays[date]; } else { timeCollection = new TimeCollection(date); this.timesToDays.Add(date, timeCollection); } timeCollection.Add(entry); }
/// <summary> /// If the Time is not yet created, just delete from memory. otherwise delete from server /// </summary> /// <param name="omitWarningMessage">True if deletion would happen without a confirmation from the user</param> /// <returns>True if the Time was deleted</returns> public async Tasks.Task <bool> Delete(bool omitWarningMessage = false) { msdyn_timeentry time = this.Time; if (time != null) { if (time.Id != Guid.Empty && this.CanEdit()) { if (omitWarningMessage || await MessageCenter.ShowDialog(AppResources.DeleteWarningTime, null, null)) { return(await this.DataAccess.Delete(time.LogicalName, time.Id)); } return(false); } return(true); } return(false); }
public void EntryStatusSetTest() { // Change a Submitted to Returned and validate // Create a submitted entry msdyn_timeentry timeEntry = new msdyn_timeentry(); //Submitted = 192350003, timeEntry.msdyn_entryStatus = new Microsoft.Xrm.Sdk.Samples.OptionSetValue(192350003); // Change to Returned //Returned = 192350001, timeEntry.EntryStatus = msdyn_timeentry_msdyn_entrystatus.Returned; // Validate //Returned = 192350001, Assert.AreEqual(new Microsoft.Xrm.Sdk.Samples.OptionSetValue(192350001).Value, timeEntry.msdyn_entryStatus.Value); }
/// <summary> /// Returns the title string given the time entry /// </summary> /// <param name="value">msdyn_timeentrytype</param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns>title string</returns> public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { msdyn_timeentry time = value as msdyn_timeentry; if (time == null) { return(string.Empty); } else if (time.msdyn_project != null && time.msdyn_project.Name != null) { return(time.msdyn_project.Name); } else { msdyn_timeentrytype currentValue = (msdyn_timeentrytype)Enum.ToObject(typeof(msdyn_timeentrytype), time.msdyn_type.Value); return(currentValue.ToString()); } }
public async Tasks.Task SubmitMarksEntriesAsSubmitted() { DataAccessTestable dat = new DataAccessTestable(); TimeEntrySubmitter submitter = new TimeEntrySubmitter(); submitter.DataAccess = dat; msdyn_timeentry entry = new msdyn_timeentry(); submitter.addTimeEntry(entry); dat.addExecuteHandler((OrganizationRequest or) => { entry.msdyn_entryStatus = new OptionSetValue((int)msdyn_timeentry_msdyn_entrystatus.Submitted); }); await submitter.ExecuteAction(); Assert.AreEqual((int)msdyn_timeentry_msdyn_entrystatus.Submitted, entry.msdyn_entryStatus.Value); }
/// <summary> /// Returns the icon given the entry type /// </summary> /// <param name="value">msdyn_timeentrytype</param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns>Icon based on expense type</returns> public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Color result = Color.FromHex("7F7F7F"); if (value == null) { return(result); } msdyn_timeentry time = value as msdyn_timeentry; if ((msdyn_timeentrytype)time.msdyn_type.Value == msdyn_timeentrytype.Work && time.msdyn_project != null && time.msdyn_project.Id != null) { result = GetColor(GetIndexWithProjectGUID(time.msdyn_project.Id.Value, culture.NumberFormat)); } return(result); }
/// <summary> /// Submit the time entry. /// </summary> /// <returns>true if the submission succeeded; otherwise, false.</returns> public virtual async Tasks.Task <bool> Submit() { if (this.CanEdit()) { msdyn_timeentry time = this.Time; bool result = await this.Save(); if (result) { TimeEntrySubmitter submitter = new TimeEntrySubmitter(); submitter.DataAccess = this.DataAccess; submitter.addTimeEntry(this.Time); return(await submitter.ExecuteAction()); } else { await MessageCenter.ShowErrorMessage(AppResources.SaveError); } } return(false); }
/// <summary> /// Adds a button to create new time entries. /// </summary> private void addCreateNewTimeButton() { if (null == createNewTimeButton) { createNewTimeButton = ToolbarHelper.createAddTimeEntryButton(); createNewTimeButton.Clicked += async(sender, args) => { msdyn_timeentry timeEntry = new msdyn_timeentry(); // Create a time entry using the current month and navigate to details page. if (this.viewModel != null) { this.viewModel.DefaultDateFromCurrentFilter(timeEntry); } await NavigateToTimeDetailsView(timeEntry); }; } this.ToolbarItems.Add(createNewTimeButton); }
protected override void OnBindingContextChanged() { base.OnBindingContextChanged(); msdyn_timeentry time = (msdyn_timeentry)this.BindingContext; if (time == null) { return; } msdyn_timeentry_msdyn_entrystatus?status = time.EntryStatus; if (status != null) { if (status == msdyn_timeentry_msdyn_entrystatus.Submitted) { moreAction.Text = AppResources.Recall; } else { moreAction.Text = AppResources.Submit; } } if (status == msdyn_timeentry_msdyn_entrystatus.Draft) { if (!this.ContextActions.Contains(deleteAction)) { this.ContextActions.Add(deleteAction); } } else { if (this.ContextActions.Contains(deleteAction)) { this.ContextActions.Remove(deleteAction); } } }